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 |