app/soc/modules/ghop/models/task.py
changeset 2679 0ede2f3adbc1
parent 2407 e23fce20ad3a
child 2703 7117c43ccf1b
equal deleted inserted replaced
2678:a525a55833f1 2679:0ede2f3adbc1
    25 
    25 
    26 from google.appengine.ext import db
    26 from google.appengine.ext import db
    27 
    27 
    28 from django.utils.translation import ugettext
    28 from django.utils.translation import ugettext
    29 
    29 
       
    30 from taggable.taggable import Tag
       
    31 from taggable.taggable import Taggable
       
    32 from taggable.taggable import tag_property
       
    33 
    30 import soc.models.linkable
    34 import soc.models.linkable
    31 import soc.models.role
    35 import soc.models.role
    32 import soc.models.student
    36 import soc.models.student
    33 import soc.models.user
    37 import soc.models.user
    34 
    38 
    35 import soc.modules.ghop.models.program
    39 import soc.modules.ghop.models.program
    36 
    40 
    37 
    41 class TaskTag(Tag):
    38 class GHOPTask(soc.models.linkable.Linkable):
    42   """Model for storing all Task tags.
       
    43   """
       
    44   
       
    45   #: Each task_type tag is scoped under the program. 
       
    46   scope = db.ReferenceProperty(reference_class=soc.models.linkable.Linkable,
       
    47                                required=True,
       
    48                                collection_name='task_type_tags')
       
    49   
       
    50   @classmethod
       
    51   def __key_name(cls, scope_path, tag_name):
       
    52     return scope_path + '/' + tag_name
       
    53 
       
    54   @classmethod
       
    55   def get_by_name(cls, tag_name):
       
    56     tags = db.Query(cls).filter('tag =', tag_name).fetch(1000)
       
    57     return tags
       
    58 
       
    59   @classmethod
       
    60   def get_or_create(cls, program, tag_name):
       
    61     "Get the Tag object that has the tag value given by tag_value."
       
    62     tag_key_name = cls.__key_name(program.key().name(), tag_name)
       
    63     existing_tag = cls.get_by_key_name(tag_key_name)
       
    64     if existing_tag is None:
       
    65       # The tag does not yet exist, so create it.
       
    66       def create_tag_txn():
       
    67         new_tag = cls(key_name=tag_key_name, tag=tag_name, scope=program)
       
    68         new_tag.put()
       
    69         return new_tag
       
    70       existing_tag = db.run_in_transaction(create_tag_txn)
       
    71     return existing_tag
       
    72 
       
    73 class TaskTypeTag(TaskTag):
       
    74   "Model for storing of task type tags."
       
    75 
       
    76   pass
       
    77 
       
    78 
       
    79 class TaskDifficultyTag(TaskTag):
       
    80   "Model for storing of task difficulty level tags."
       
    81 
       
    82   pass
       
    83 
       
    84 
       
    85 class GHOPTask(Taggable, soc.models.linkable.Linkable):
    39   """Model for a task used in GHOP workflow.
    86   """Model for a task used in GHOP workflow.
    40 
    87 
    41   The scope property of Linkable will be set to the Organization to which
    88   The scope property of Linkable will be set to the Organization to which
    42   this task belongs to. A link_id will be generated automatically and will
    89   this task belongs to. A link_id will be generated automatically and will
    43   have no specific meaning other than identification.
    90   have no specific meaning other than identification.
    54   description.help_text = ugettext('Complete description of the task')
   101   description.help_text = ugettext('Complete description of the task')
    55 
   102 
    56   #: Field indicating the difficulty level of the Task. This is not
   103   #: Field indicating the difficulty level of the Task. This is not
    57   #: mandatory so the it can be assigned at any later stage. 
   104   #: mandatory so the it can be assigned at any later stage. 
    58   #: The options are configured by a Program Admin.
   105   #: The options are configured by a Program Admin.
    59   difficulty = db.StringProperty(required=False,
   106   difficulty = tag_property('difficulty')
    60                                  verbose_name=ugettext('Difficulty'))
       
    61   difficulty.help_text = ugettext('Difficulty Level of the task')
       
    62 
   107 
    63   #: Required field which contains the type of the task. These types are
   108   #: Required field which contains the type of the task. These types are
    64   #: configured by a Program Admin.
   109   #: configured by a Program Admin.
    65   type = db.StringListProperty(required=True, 
   110   task_type = tag_property('task_type')
    66                                verbose_name=ugettext('Task Type'))
       
    67   type.help_text = ugettext('Type of the task')
       
    68 
   111 
    69   #: A field which contains time allowed for completing the task (in hours)
   112   #: A field which contains time allowed for completing the task (in hours)
    70   #: from the moment that this task has been assigned to a Student
   113   #: from the moment that this task has been assigned to a Student
    71   time_to_complete = db.IntegerProperty(required=True,
   114   time_to_complete = db.IntegerProperty(required=True,
    72                                         verbose_name=('Time to Complete'))
   115                                         verbose_name=('Time to Complete'))
   146   created_on = db.DateTimeProperty(required=True, auto_now_add=True,
   189   created_on = db.DateTimeProperty(required=True, auto_now_add=True,
   147                                    verbose_name=ugettext('Created on'))
   190                                    verbose_name=ugettext('Created on'))
   148 
   191 
   149   #: Required field containing the Mentor/Org Admin who last edited this
   192   #: Required field containing the Mentor/Org Admin who last edited this
   150   #: task. It changes only when Mentor/Org Admin changes title, description,
   193   #: task. It changes only when Mentor/Org Admin changes title, description,
   151   #: difficulty, type, time_to_complete.
   194   #: difficulty, task_type, time_to_complete. If site developer has modified
       
   195   #: the task, it is empty.
   152   modified_by = db.ReferenceProperty(reference_class=soc.models.role.Role,
   196   modified_by = db.ReferenceProperty(reference_class=soc.models.role.Role,
   153                                    required=True,
   197                                    required=True,
   154                                    collection_name='edited_tasks',
   198                                    collection_name='edited_tasks',
   155                                    verbose_name=ugettext('Modified by'))
   199                                    verbose_name=ugettext('Modified by'))
   156 
   200 
   177   #: First dictionary item holds the values for all the properties in this
   221   #: First dictionary item holds the values for all the properties in this
   178   #: model. The subsequent items hold the properties that changed at the
   222   #: model. The subsequent items hold the properties that changed at the
   179   #: timestamp given by the key.
   223   #: timestamp given by the key.
   180   #: Reference properties will be stored by calling str() on their Key.
   224   #: Reference properties will be stored by calling str() on their Key.
   181   history = db.TextProperty(required=True, default='')
   225   history = db.TextProperty(required=True, default='')
       
   226 
       
   227   def __init__(self, parent=None, key_name=None, 
       
   228                app=None, **entity_values):
       
   229     """Constructor for GHOPTask Model.
       
   230     
       
   231     Args:
       
   232         See Google App Engine APIs.
       
   233     """
       
   234 
       
   235     # explicitly call the AppEngine datastore Model constructor
       
   236     db.Model.__init__(self, parent, key_name, app, **entity_values)
       
   237 
       
   238     # call the Taggable constructor to initialize the tags specified as
       
   239     # keyword arguments
       
   240     Taggable.__init__(self, task_type=TaskTypeTag, 
       
   241                       difficulty=TaskDifficultyTag)
       
   242