app/soc/modules/ghop/models/task.py
changeset 2858 9b59d89e6707
parent 2788 78d02dcd8eb0
child 3082 da8cc38cabe9
equal deleted inserted replaced
2857:bc793800116e 2858:9b59d89e6707
    45   
    45   
    46   #: Each task_type tag is scoped under the program. 
    46   #: Each task_type tag is scoped under the program. 
    47   scope = db.ReferenceProperty(reference_class=soc.models.linkable.Linkable,
    47   scope = db.ReferenceProperty(reference_class=soc.models.linkable.Linkable,
    48                                required=True,
    48                                required=True,
    49                                collection_name='task_type_tags')
    49                                collection_name='task_type_tags')
    50   
    50 
       
    51   order = db.IntegerProperty(required=True, default=0)
       
    52 
    51   @classmethod
    53   @classmethod
    52   def __key_name(cls, scope_path, tag_name):
    54   def __key_name(cls, scope_path, tag_name):
    53     """Create the key_name from program key_name as scope_path and tag_name.
    55     """Create the key_name from program key_name as scope_path and tag_name.
    54     """
    56     """
    55     return scope_path + '/' + tag_name
    57     return scope_path + '/' + tag_name
    60     """
    62     """
    61     tags = db.Query(cls).filter('tag =', tag_name).fetch(1000)
    63     tags = db.Query(cls).filter('tag =', tag_name).fetch(1000)
    62     return tags
    64     return tags
    63 
    65 
    64   @classmethod
    66   @classmethod
    65   def get_or_create(cls, program, tag_name):
    67   def get_by_scope(cls, scope):
       
    68     """Get the list of tag objects that has the given scope.
       
    69     """
       
    70     tags = db.Query(cls).filter('scope =', scope).order('order').fetch(1000)
       
    71     return tags
       
    72 
       
    73   @classmethod
       
    74   def get_highest_order(cls, scope):
       
    75     """Get a tag with highest order.
       
    76     """
       
    77     tags = db.Query(cls).filter('scope =', scope).order('-order').fetch(1)
       
    78     if tags:
       
    79       return tags[0].order
       
    80     else:
       
    81       return -1
       
    82 
       
    83   @classmethod
       
    84   def get_by_scope_and_name(cls, scope, tag_name):
       
    85     """Get a tag by scope and name.
       
    86 
       
    87     There can be only one such tag.
       
    88     """
       
    89 
       
    90     tags = db.Query(cls).filter(
       
    91         'scope =', scope).filter('tag =', tag_name).fetch(1)
       
    92     if tags:
       
    93       return tags[0]
       
    94     else:
       
    95       return None
       
    96 
       
    97   @classmethod
       
    98   def update_order(cls, scope, tag_name, order):
       
    99     """Updates the order of the tag.
       
   100     """
       
   101 
       
   102     tag = cls.get_by_scope_and_name(scope, tag_name)
       
   103     if tag:
       
   104       tag.order = order
       
   105       tag.put()
       
   106 
       
   107     return tag
       
   108 
       
   109   @classmethod
       
   110   def copy_tag(cls, scope, tag_name, new_tag_name):
       
   111     """Copy a tag with a given scope and tag_name to another tag with
       
   112     new tag_name.
       
   113     """
       
   114     tag = cls.get_by_scope_and_name(scope, tag_name)
       
   115 
       
   116     if tag:
       
   117       tag_key_name = cls.__key_name(scope.key().name(), new_tag_name)
       
   118       existing_tag = cls.get_by_key_name(tag_key_name)
       
   119 
       
   120       if existing_tag is None:
       
   121         new_tag = cls(key_name=tag_key_name, tag=new_tag_name, scope=scope, 
       
   122                       added=tag.added, tagged=tag.tagged,
       
   123                       tagged_count=tag.tagged_count)
       
   124         new_tag.put()
       
   125         tag.delete()
       
   126 
       
   127         return new_tag
       
   128 
       
   129       return existing_tag
       
   130 
       
   131     return None
       
   132 
       
   133   @classmethod
       
   134   def delete_tag(cls, scope, tag_name):
       
   135     """Copy a tag with a given scope and tag_name to another tag with
       
   136     new tag_name.
       
   137     """
       
   138     tag = cls.get_by_scope_and_name(scope, tag_name)
       
   139 
       
   140     if tag:
       
   141       tag.delete()
       
   142       return True
       
   143 
       
   144     return False
       
   145 
       
   146   @classmethod
       
   147   def get_or_create(cls, scope, tag_name, order=0):
    66     """Get the Tag object that has the tag value given by tag_value.
   148     """Get the Tag object that has the tag value given by tag_value.
    67     """
   149     """
    68     tag_key_name = cls.__key_name(program.key().name(), tag_name)
   150     tag_key_name = cls.__key_name(scope.key().name(), tag_name)
    69     existing_tag = cls.get_by_key_name(tag_key_name)
   151     existing_tag = cls.get_by_key_name(tag_key_name)
    70     if existing_tag is None:
   152     if existing_tag is None:
    71       # the tag does not yet exist, so create it.
   153       # the tag does not yet exist, so create it.
       
   154       if not order:
       
   155         order = cls.get_highest_order(scope=scope) + 1
    72       def create_tag_txn():
   156       def create_tag_txn():
    73         new_tag = cls(key_name=tag_key_name, tag=tag_name, scope=program)
   157         new_tag = cls(key_name=tag_key_name, tag=tag_name,
       
   158                       scope=scope, order=order)
    74         new_tag.put()
   159         new_tag.put()
    75         return new_tag
   160         return new_tag
    76       existing_tag = db.run_in_transaction(create_tag_txn)
   161       existing_tag = db.run_in_transaction(create_tag_txn)
    77     return existing_tag
   162     return existing_tag
    78 
   163 
    89   """
   174   """
    90 
   175 
    91   pass
   176   pass
    92 
   177 
    93 
   178 
       
   179 class TaskArbitraryTag(TaskTag):
       
   180   """Model for storing of arbitrary tags.
       
   181   """
       
   182 
       
   183   pass
       
   184 
       
   185 
    94 class GHOPTask(Taggable, soc.models.linkable.Linkable):
   186 class GHOPTask(Taggable, soc.models.linkable.Linkable):
    95   """Model for a task used in GHOP workflow.
   187   """Model for a task used in GHOP workflow.
    96 
   188 
    97   The scope property of Linkable will be set to the Organization to which
   189   The scope property of Linkable will be set to the Organization to which
    98   this task belongs to. A link_id will be generated automatically and will
   190   this task belongs to. A link_id will be generated automatically and will
   115   difficulty = tag_property('difficulty')
   207   difficulty = tag_property('difficulty')
   116 
   208 
   117   #: Required field which contains the type of the task. These types are
   209   #: Required field which contains the type of the task. These types are
   118   #: configured by a Program Admin.
   210   #: configured by a Program Admin.
   119   task_type = tag_property('task_type')
   211   task_type = tag_property('task_type')
       
   212 
       
   213   #: Field which contains the arbitrary tags for the task. These tags can
       
   214   #: be assigned by Org Admins and mentors.
       
   215   arbit_tag = tag_property('arbit_tag')
   120 
   216 
   121   #: A field which contains time allowed for completing the task (in hours)
   217   #: A field which contains time allowed for completing the task (in hours)
   122   #: from the moment that this task has been assigned to a Student
   218   #: from the moment that this task has been assigned to a Student
   123   time_to_complete = db.IntegerProperty(required=True,
   219   time_to_complete = db.IntegerProperty(required=True,
   124                                         verbose_name=('Time to Complete'))
   220                                         verbose_name=('Time to Complete'))
   241     db.Model.__init__(self, parent, key_name, app, **entity_values)
   337     db.Model.__init__(self, parent, key_name, app, **entity_values)
   242 
   338 
   243     # call the Taggable constructor to initialize the tags specified as
   339     # call the Taggable constructor to initialize the tags specified as
   244     # keyword arguments
   340     # keyword arguments
   245     Taggable.__init__(self, task_type=TaskTypeTag, 
   341     Taggable.__init__(self, task_type=TaskTypeTag, 
   246                       difficulty=TaskDifficultyTag)
   342                       difficulty=TaskDifficultyTag,
   247 
   343                       arbit_tag=TaskArbitraryTag)