access all board data #2

Open
opened 2017-11-11 15:58:00 +00:00 by agp8x · 0 comments

To test:
biodiv2go/games/web/biogames/game2/management/commands/fixes.py

# -*- encoding=utf-8 -*-

from django.core.management.base import BaseCommand, CommandParser
from django.contrib.auth.models import User
from guardian.shortcuts import assign_perm

from game2.models import InstanceConfig, MultipleChoiceAnswer


class Fix():
	def add_subparser(self, subparsers):
		raise NotImplementedError("implement me")

	def handle(self, args, options):
		raise NotImplementedError("implement me")


class AssetUrls(Fix):
	key = "assets"

	def add_subparser(self, subparsers):
		parser = subparsers.add_parser(self.key, help="List asset URLs for an instance config")
		parser.set_defaults(subcommand=self.key)
		parser.add_argument("instance_id", help="InstanceConfig to work on")
		parser.add_argument("--host", help="Host to prepend", default="")

	def handle(self, args, options):
		print(("\n" + options['host'] + "/game2/files").join([""] + [e.file.path for e in InstanceConfig.objects.get(
			id=options['instance_id']).manifest.entries.all()]).strip())

class ListMCAnswers(Fix):
	key = "mcanswers"

	def add_subparser(self, subparsers):
		parser = subparsers.add_parser(self.key, help="List MultipleChoiceAnswers for an instance config")
		parser.set_defaults(subcommand=self.key)
		parser.add_argument("instance_id", help="InstanceConfig to work on")

	def handle(self, args, options):
		print(MultipleChoiceAnswer.objects.filter(question__sequence__instance_config_id=options['instance_id']))

class SeqOrder(Fix):
	"""Sometimes the order of boards in sequences seems mixed up (missing or multiple numbers)
	This resets _order of all boards in a sequence to their current position (index)
	"""
	key = "seq_order"

	def add_subparser(self, subparsers):
		parser = subparsers.add_parser(self.key, help="Fix ordering of boards in a sequence")
		parser.add_argument("instance_id", help="InstanceConfig to work on")
		parser.add_argument("sequence_id", help="Sequence in InstanceConfig to work on")
		parser.add_argument("-d", "--dry-run", action="store_true", help="don't write")
		parser.set_defaults(subcommand=self.key)

	def handle(self, args, options):
		print(self.fix(options['instance_id'], options['sequence_id'], options['dry_run']))

	@staticmethod
	def fix(instance_id, sequence_id, dry_run=False):
		sequence = InstanceConfig.objects.get(id=instance_id).sequences.get(id=sequence_id)
		print(sequence)
		print(list(map(lambda a: (a[0], a[1]._order), enumerate(sequence.boards.all()))))
		results = []
		for i, obj in enumerate(sequence.boards.all()):
			op = False
			if not obj._order == i:
				obj._order = i
				if not dry_run:
					obj.save()
				op = True
			results.append((i, op))
		return results


class AnalysisUser(Fix):
	"""Accessing all board meta data requires special permissions ('read_instanceconfig' for all InstanceConfigs)"""
	key = "analysis_user"
	
	def add_subparser(self, subparsers):
		parser = subparsers.add_parser(self.key, help="Add a user who can read all game data (for analysis")
		parser.set_defaults(subcommand=self.key)
		parser.add_argument("username", default=None, help="Username")
		parser.add_argument("password", nargs="?",default=None, help="password (leave empty for just updating InstanceConfigs)")

	def handle(self, args, options):
		if options['username'] is not None:
			user, created = User.objects.get_or_create(username=options['username'])
			if created:
				if not 'password' in options:
					raise KeyError('password required')
				user.set_password(options['password'])
			assign_perm('game2.read_instanceconfig', user)
			#for inst in InstanceConfig.objects.all():
			#	assign_perm('read_instanceconfig', user, inst)
			user.save()


FIXES = [SeqOrder, AssetUrls, AnalysisUser]


class Command(BaseCommand):
	instances = {}

	def add_arguments(self, parser):
		cmd = self

		class SubParser(CommandParser):
			def __init__(self, **kwargs):
				super(SubParser, self).__init__(cmd, **kwargs)

		subparsers = parser.add_subparsers(parser_class=SubParser, help="subcommands")
		for fix in FIXES:
			instance = fix()
			self.instances[fix.key] = instance
			instance.add_subparser(subparsers)

	def handle(self, *args, **options):
		subcommand = options['subcommand']
		if not subcommand in self.instances:
			raise ValueError("Unknown subcommand {}".format(subcommand))
		self.instances[subcommand].handle(args, options)

To test: biodiv2go/games/web/biogames/game2/management/commands/fixes.py ``` # -*- encoding=utf-8 -*- from django.core.management.base import BaseCommand, CommandParser from django.contrib.auth.models import User from guardian.shortcuts import assign_perm from game2.models import InstanceConfig, MultipleChoiceAnswer class Fix(): def add_subparser(self, subparsers): raise NotImplementedError("implement me") def handle(self, args, options): raise NotImplementedError("implement me") class AssetUrls(Fix): key = "assets" def add_subparser(self, subparsers): parser = subparsers.add_parser(self.key, help="List asset URLs for an instance config") parser.set_defaults(subcommand=self.key) parser.add_argument("instance_id", help="InstanceConfig to work on") parser.add_argument("--host", help="Host to prepend", default="") def handle(self, args, options): print(("\n" + options['host'] + "/game2/files").join([""] + [e.file.path for e in InstanceConfig.objects.get( id=options['instance_id']).manifest.entries.all()]).strip()) class ListMCAnswers(Fix): key = "mcanswers" def add_subparser(self, subparsers): parser = subparsers.add_parser(self.key, help="List MultipleChoiceAnswers for an instance config") parser.set_defaults(subcommand=self.key) parser.add_argument("instance_id", help="InstanceConfig to work on") def handle(self, args, options): print(MultipleChoiceAnswer.objects.filter(question__sequence__instance_config_id=options['instance_id'])) class SeqOrder(Fix): """Sometimes the order of boards in sequences seems mixed up (missing or multiple numbers) This resets _order of all boards in a sequence to their current position (index) """ key = "seq_order" def add_subparser(self, subparsers): parser = subparsers.add_parser(self.key, help="Fix ordering of boards in a sequence") parser.add_argument("instance_id", help="InstanceConfig to work on") parser.add_argument("sequence_id", help="Sequence in InstanceConfig to work on") parser.add_argument("-d", "--dry-run", action="store_true", help="don't write") parser.set_defaults(subcommand=self.key) def handle(self, args, options): print(self.fix(options['instance_id'], options['sequence_id'], options['dry_run'])) @staticmethod def fix(instance_id, sequence_id, dry_run=False): sequence = InstanceConfig.objects.get(id=instance_id).sequences.get(id=sequence_id) print(sequence) print(list(map(lambda a: (a[0], a[1]._order), enumerate(sequence.boards.all())))) results = [] for i, obj in enumerate(sequence.boards.all()): op = False if not obj._order == i: obj._order = i if not dry_run: obj.save() op = True results.append((i, op)) return results class AnalysisUser(Fix): """Accessing all board meta data requires special permissions ('read_instanceconfig' for all InstanceConfigs)""" key = "analysis_user" def add_subparser(self, subparsers): parser = subparsers.add_parser(self.key, help="Add a user who can read all game data (for analysis") parser.set_defaults(subcommand=self.key) parser.add_argument("username", default=None, help="Username") parser.add_argument("password", nargs="?",default=None, help="password (leave empty for just updating InstanceConfigs)") def handle(self, args, options): if options['username'] is not None: user, created = User.objects.get_or_create(username=options['username']) if created: if not 'password' in options: raise KeyError('password required') user.set_password(options['password']) assign_perm('game2.read_instanceconfig', user) #for inst in InstanceConfig.objects.all(): # assign_perm('read_instanceconfig', user, inst) user.save() FIXES = [SeqOrder, AssetUrls, AnalysisUser] class Command(BaseCommand): instances = {} def add_arguments(self, parser): cmd = self class SubParser(CommandParser): def __init__(self, **kwargs): super(SubParser, self).__init__(cmd, **kwargs) subparsers = parser.add_subparsers(parser_class=SubParser, help="subcommands") for fix in FIXES: instance = fix() self.instances[fix.key] = instance instance.add_subparser(subparsers) def handle(self, *args, **options): subcommand = options['subcommand'] if not subcommand in self.instances: raise ValueError("Unknown subcommand {}".format(subcommand)) self.instances[subcommand].handle(args, options) ```
Sign in to join this conversation.
No Label
No Milestone
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: ma/project#2
There is no content yet.