app/taggable/taggable.py
author Daniel Hans <Daniel.M.Hans@gmail.com>
Sat, 14 Nov 2009 23:27:03 +0100
changeset 3091 a48f4e860f7b
parent 3085 ded7a67e7e0a
permissions -rw-r--r--
Tasks may be deleted by pressing 'Delete' button on the edit view. An organization admin may delete a task entity, if the task is not claimed by anyone. Issue 695 fixed.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
     1
from google.appengine.ext import db
3083
f384c0a42920 'scope' field moved from TaskTag to the parent class.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3081
diff changeset
     2
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
     3
import string
3083
f384c0a42920 'scope' field moved from TaskTag to the parent class.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3081
diff changeset
     4
import soc.models.linkable
3085
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
     5
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
     6
class Tag(db.Model):
3085
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
     7
  """Google AppEngine model for store of tags.
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
     8
  """
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
     9
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    10
  tag = db.StringProperty(required=True)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    11
  "The actual string value of the tag."
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    12
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    13
  added = db.DateTimeProperty(auto_now_add=True)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    14
  "The date and time that the tag was first added to the datastore."
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    15
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    16
  tagged = db.ListProperty(db.Key)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    17
  "A List of db.Key values for the datastore objects that have been tagged with this tag value."
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    18
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    19
  tagged_count = db.IntegerProperty(default=0)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    20
  "The number of entities in tagged."
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    21
3081
14077185c46e Adds a new property to taggable which automatically deletes an empty tag.
Daniel Hans <daniel.m.hans@gmail.com>
parents: 2950
diff changeset
    22
  auto_delete = db.BooleanProperty(required=True, default=False)
14077185c46e Adds a new property to taggable which automatically deletes an empty tag.
Daniel Hans <daniel.m.hans@gmail.com>
parents: 2950
diff changeset
    23
  "If true, a tag instance should be deleted when tagged_count reaches zero."
14077185c46e Adds a new property to taggable which automatically deletes an empty tag.
Daniel Hans <daniel.m.hans@gmail.com>
parents: 2950
diff changeset
    24
3083
f384c0a42920 'scope' field moved from TaskTag to the parent class.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3081
diff changeset
    25
  scope = db.ReferenceProperty(reference_class=soc.models.linkable.Linkable,
f384c0a42920 'scope' field moved from TaskTag to the parent class.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3081
diff changeset
    26
                               required=False,
f384c0a42920 'scope' field moved from TaskTag to the parent class.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3081
diff changeset
    27
                               collection_name='task_type_tags')
f384c0a42920 'scope' field moved from TaskTag to the parent class.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3081
diff changeset
    28
  "Each tag is scoped under some linkable model."
f384c0a42920 'scope' field moved from TaskTag to the parent class.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3081
diff changeset
    29
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    30
  @classmethod
3085
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    31
  def __key_name(cls, scope_path, tag_name):
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    32
    """Create the key_name from program key_name as scope_path and tag_name.
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    33
    """
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    34
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    35
    return scope_path + '/' + tag_name
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    36
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    37
  def remove_tagged(self, key):
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    38
    def remove_tagged_txn():
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    39
      if key in self.tagged:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    40
        self.tagged.remove(key)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    41
        self.tagged_count -= 1
3081
14077185c46e Adds a new property to taggable which automatically deletes an empty tag.
Daniel Hans <daniel.m.hans@gmail.com>
parents: 2950
diff changeset
    42
        if not self.tagged_count and self.auto_delete:
14077185c46e Adds a new property to taggable which automatically deletes an empty tag.
Daniel Hans <daniel.m.hans@gmail.com>
parents: 2950
diff changeset
    43
          self.delete()
14077185c46e Adds a new property to taggable which automatically deletes an empty tag.
Daniel Hans <daniel.m.hans@gmail.com>
parents: 2950
diff changeset
    44
        else:
14077185c46e Adds a new property to taggable which automatically deletes an empty tag.
Daniel Hans <daniel.m.hans@gmail.com>
parents: 2950
diff changeset
    45
          self.put()
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    46
    db.run_in_transaction(remove_tagged_txn)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    47
    self.__class__.expire_cached_tags()
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    48
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    49
  def add_tagged(self, key):
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    50
    def add_tagged_txn():
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    51
      if key not in self.tagged:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    52
        self.tagged.append(key)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    53
        self.tagged_count += 1
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    54
        self.put()
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    55
    db.run_in_transaction(add_tagged_txn)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    56
    self.__class__.expire_cached_tags()
3085
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    57
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    58
  def clear_tagged(self):
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    59
    def clear_tagged_txn():
3081
14077185c46e Adds a new property to taggable which automatically deletes an empty tag.
Daniel Hans <daniel.m.hans@gmail.com>
parents: 2950
diff changeset
    60
      if self.auto_delete:
14077185c46e Adds a new property to taggable which automatically deletes an empty tag.
Daniel Hans <daniel.m.hans@gmail.com>
parents: 2950
diff changeset
    61
        self.delete()
14077185c46e Adds a new property to taggable which automatically deletes an empty tag.
Daniel Hans <daniel.m.hans@gmail.com>
parents: 2950
diff changeset
    62
      else:
14077185c46e Adds a new property to taggable which automatically deletes an empty tag.
Daniel Hans <daniel.m.hans@gmail.com>
parents: 2950
diff changeset
    63
        self.tagged = []
14077185c46e Adds a new property to taggable which automatically deletes an empty tag.
Daniel Hans <daniel.m.hans@gmail.com>
parents: 2950
diff changeset
    64
        self.tagged_count = 0
14077185c46e Adds a new property to taggable which automatically deletes an empty tag.
Daniel Hans <daniel.m.hans@gmail.com>
parents: 2950
diff changeset
    65
        self.put()
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    66
    db.run_in_transaction(clear_tagged_txn)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    67
    self.__class__.expire_cached_tags()
3085
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    68
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    69
  @classmethod
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    70
  def get_by_name(cls, tag_name):
3085
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    71
    """Get the list of tag objects that has the given tag_name.
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    72
    """
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    73
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    74
    tags = db.Query(cls).filter('tag =', tag_name).fetch(1000)
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    75
    return tags
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    76
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    77
  @classmethod
3085
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    78
  def get_by_scope_and_name(cls, scope, tag_name):
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    79
    """Get a tag by scope and name.
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    80
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    81
    There may be only one such tag.
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    82
    """
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    83
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    84
    return db.Query(cls).filter(
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    85
        'scope =', scope).filter('tag =', tag_name).get()
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    86
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    87
  @classmethod
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    88
  def get_tags_for_key(cls, key, limit=1000):
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    89
    """Get the tags for the datastore object represented by key.
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    90
    """
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    91
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    92
    tags = db.Query(cls).filter('tagged =', key).fetch(limit)
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    93
    return tags
3085
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    94
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    95
  @classmethod
3085
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    96
  def get_or_create(cls, scope, tag_name, order=0):
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    97
    """Get the Tag object that has the tag value given by tag_value.
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    98
    """
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
    99
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   100
    tag_key_name = cls.__key_name(scope.key().name(), tag_name)
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   101
    existing_tag = cls.get_by_key_name(tag_key_name)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   102
    if existing_tag is None:
3085
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   103
      # the tag does not yet exist, so create it.
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   104
      if not order:
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   105
        order = cls.get_highest_order(scope=scope) + 1
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   106
      def create_tag_txn():
3085
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   107
        new_tag = cls(key_name=tag_key_name, tag=tag_name,
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   108
                      scope=scope, order=order)
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   109
        new_tag.put()
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   110
        return new_tag
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   111
      existing_tag = db.run_in_transaction(create_tag_txn)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   112
    return existing_tag
3085
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   113
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   114
  @classmethod
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   115
  def get_tags_by_frequency(cls, limit=1000):
3085
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   116
    """Return a list of Tags sorted by the number of objects to which they
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   117
    have been applied, most frequently-used first. If limit is given, return
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   118
    only return only that many tags; otherwise, return all.
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   119
    """
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   120
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   121
    tag_list = db.Query(cls).filter('tagged_count >', 0).order(
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   122
        "-tagged_count").fetch(limit)
3085
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   123
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   124
    return tag_list
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   125
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   126
  @classmethod
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   127
  def get_tags_by_name(cls, limit=1000, ascending=True):
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   128
    """Return a list of Tags sorted alphabetically by the name of the tag.
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   129
    If a limit is given, return only that many tags; otherwise, return all.
3085
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   130
    If ascending is True, sort from a-z; otherwise, sort from z-a.
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   131
    """
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   132
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   133
    from google.appengine.api import memcache
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   134
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   135
    cache_name = cls.__name__ + '_tags_by_name'
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   136
    if ascending:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   137
      cache_name += '_asc'
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   138
    else:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   139
      cache_name += '_desc'
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   140
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   141
    tags = memcache.get(cache_name)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   142
    if tags is None or len(tags) < limit:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   143
      order_by = "tag"
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   144
      if not ascending:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   145
        order_by = "-tag"
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   146
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   147
      tags = db.Query(cls).order(order_by).fetch(limit)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   148
      memcache.add(cache_name, tags, 3600)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   149
    else:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   150
      if len(tags) > limit:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   151
        # Return only as many as requested.
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   152
        tags = tags[:limit]
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   153
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   154
    return tags
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   155
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   156
  @classmethod
3085
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   157
  def copy_tag(cls, scope, tag_name, new_tag_name):
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   158
    """Copy a tag with a given scope and tag_name to another tag with
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   159
    new tag_name.
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   160
    """
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   161
    tag = cls.get_by_scope_and_name(scope, tag_name)
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   162
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   163
    if tag:
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   164
      tag_key_name = cls.__key_name(scope.key().name(), new_tag_name)
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   165
      existing_tag = cls.get_by_key_name(tag_key_name)
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   166
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   167
      if existing_tag is None:
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   168
        new_tag = cls(key_name=tag_key_name, tag=new_tag_name, scope=scope, 
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   169
                      added=tag.added, tagged=tag.tagged,
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   170
                      tagged_count=tag.tagged_count)
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   171
        new_tag.put()
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   172
        tag.delete()
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   173
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   174
        return new_tag
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   175
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   176
      return existing_tag
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   177
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   178
    return None
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   179
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   180
  @classmethod
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   181
  def delete_tag(cls, scope, tag_name):
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   182
    """Delete a tag with a given scope and tag_name.
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   183
    """
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   184
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   185
    tag = cls.get_by_scope_and_name(scope, tag_name)
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   186
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   187
    if tag:
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   188
      tag.delete()
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   189
      return True
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   190
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   191
    return False
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   192
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   193
  @classmethod
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   194
  def popular_tags(cls, limit=5):
3085
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   195
    """Get the most popular tags from memcache, or if they are not defined
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   196
    there, it retrieves them from datastore and sets in memcache.
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   197
    """
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   198
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   199
    from google.appengine.api import memcache
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   200
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   201
    tags = memcache.get(cls.__name__ + '_popular_tags')
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   202
    if tags is None:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   203
      tags = cls.get_tags_by_frequency(limit)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   204
      memcache.add(cls.__name__ + '_popular_tags', tags, 3600)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   205
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   206
    return tags
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   207
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   208
  @classmethod
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   209
  def expire_cached_tags(cls):
3085
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   210
    """Expire all tag lists which exist in memcache.
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   211
    """
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   212
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   213
    from google.appengine.api import memcache
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   214
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   215
    memcache.delete(cls.__name__ + '_popular_tags')
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   216
    memcache.delete(cls.__name__ + '_tags_by_name_asc')
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   217
    memcache.delete(cls.__name__ + '_tags_by_name_desc')
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   218
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   219
  def __str__(self):
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   220
    """Returns the string representation of the entity's tag name.
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   221
    """
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   222
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   223
    return self.tag
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   224
3085
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   225
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   226
def tag_property(tag_name):
3085
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   227
  """Decorator that creates and returns a tag property to be used
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   228
  in Google AppEngine model.
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   229
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   230
  Args:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   231
    tag_name: name of the tag to be created.
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   232
  """
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   233
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   234
  def get_tags(self):
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   235
    """"Get a list of Tag objects for all Tags that apply to the
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   236
    specified entity.
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   237
    """
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   238
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   239
    if self._tags[tag_name] is None or len(self._tags[tag_name]) == 0:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   240
      self._tags[tag_name] = self._tag_model[
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   241
          tag_name].get_tags_for_key(self.key())
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   242
    return self._tags[tag_name]
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   243
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   244
  def set_tags(self, seed):
3085
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   245
    """Set a list of Tag objects for all Tags that apply to
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   246
    the specified entity.
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   247
    """
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   248
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   249
    import types
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   250
    if type(seed['tags']) is types.UnicodeType:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   251
      # Convert unicode to a plain string
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   252
      seed['tags'] = str(seed['tags'])
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   253
    if type(seed['tags']) is types.StringType:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   254
      # Tags is a string, split it on tag_seperator into a list
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   255
      seed['tags'] = string.split(seed['tags'], self.tag_separator)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   256
    if type(seed['tags']) is types.ListType:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   257
      get_tags(self)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   258
      # Firstly, we will check to see if any tags have been removed.
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   259
      # Iterate over a copy of _tags, as we may need to modify _tags
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   260
      for each_tag in self._tags[tag_name][:]:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   261
        if each_tag not in seed['tags']:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   262
          # A tag that was previously assigned to this entity is
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   263
          # missing in the list that is being assigned, so we
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   264
          # disassocaite this entity and the tag.
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   265
          each_tag.remove_tagged(self.key())
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   266
          self._tags[tag_name].remove(each_tag)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   267
      # Secondly, we will check to see if any tags have been added.
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   268
      for each_tag in seed['tags']:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   269
        each_tag = string.strip(each_tag)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   270
        if len(each_tag) > 0 and each_tag not in self._tags[tag_name]:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   271
          # A tag that was not previously assigned to this entity
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   272
          # is present in the list that is being assigned, so we
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   273
          # associate this entity with the tag.
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   274
          tag = self._tag_model[tag_name].get_or_create(
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   275
              seed['scope'], each_tag)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   276
          tag.add_tagged(self.key())
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   277
          self._tags[tag_name].append(tag)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   278
    else:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   279
      raise Exception, "tags must be either a unicode, a string or a list"
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   280
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   281
  return property(get_tags, set_tags)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   282
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   283
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   284
class Taggable(object):
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   285
  """A mixin class that is used for making GAE Model classes taggable.
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   286
3085
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   287
  This is an extended version of Taggable-mixin which allows for
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   288
  multiple tag properties in the same AppEngine Model class.
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   289
  """
3085
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   290
2679
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   291
  def __init__(self, **kwargs):
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   292
    """The constructor class for Taggable, that creates a dictionary of tags.
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   293
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   294
    The difference from the original taggable in terms of interface is
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   295
    that, tag class is not used as the default tag model, since we don't
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   296
    have a default tag property created in this class now.
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   297
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   298
    Args:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   299
      kwargs: keywords containing the name of the tags and arguments
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   300
          containing tag model to be used.
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   301
    """
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   302
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   303
    self._tags = {}
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   304
    self._tag_model = {}
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   305
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   306
    for tag_name in kwargs:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   307
      self._tags[tag_name] = None
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   308
      self._tag_model[tag_name] = kwargs[tag_name]
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   309
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   310
    self.tag_separator = ", "
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   311
2950
ceec88091db8 ret_list keyword argument is added to tags_strings method to enable returning lists also instead of strings.
Madhusudan.C.S <madhusudancs@gmail.com>
parents: 2679
diff changeset
   312
  def tags_string(self, tag_name, ret_list=False):
ceec88091db8 ret_list keyword argument is added to tags_strings method to enable returning lists also instead of strings.
Madhusudan.C.S <madhusudancs@gmail.com>
parents: 2679
diff changeset
   313
    """Create a formatted string version of this entity's tags.
3085
ded7a67e7e0a Some functions which applies to scoped tags in general moved from TaskTag to Task model.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3083
diff changeset
   314
2950
ceec88091db8 ret_list keyword argument is added to tags_strings method to enable returning lists also instead of strings.
Madhusudan.C.S <madhusudancs@gmail.com>
parents: 2679
diff changeset
   315
    Args:
ceec88091db8 ret_list keyword argument is added to tags_strings method to enable returning lists also instead of strings.
Madhusudan.C.S <madhusudancs@gmail.com>
parents: 2679
diff changeset
   316
      tag_name: the name of the tag which must be formatted
ceec88091db8 ret_list keyword argument is added to tags_strings method to enable returning lists also instead of strings.
Madhusudan.C.S <madhusudancs@gmail.com>
parents: 2679
diff changeset
   317
      ret_list: if False sends a string, otherwise sends a Python list
ceec88091db8 ret_list keyword argument is added to tags_strings method to enable returning lists also instead of strings.
Madhusudan.C.S <madhusudancs@gmail.com>
parents: 2679
diff changeset
   318
    """
ceec88091db8 ret_list keyword argument is added to tags_strings method to enable returning lists also instead of strings.
Madhusudan.C.S <madhusudancs@gmail.com>
parents: 2679
diff changeset
   319
ceec88091db8 ret_list keyword argument is added to tags_strings method to enable returning lists also instead of strings.
Madhusudan.C.S <madhusudancs@gmail.com>
parents: 2679
diff changeset
   320
    tag_list = [each_tag.tag for each_tag in tag_name]
ceec88091db8 ret_list keyword argument is added to tags_strings method to enable returning lists also instead of strings.
Madhusudan.C.S <madhusudancs@gmail.com>
parents: 2679
diff changeset
   321
ceec88091db8 ret_list keyword argument is added to tags_strings method to enable returning lists also instead of strings.
Madhusudan.C.S <madhusudancs@gmail.com>
parents: 2679
diff changeset
   322
    if ret_list:
ceec88091db8 ret_list keyword argument is added to tags_strings method to enable returning lists also instead of strings.
Madhusudan.C.S <madhusudancs@gmail.com>
parents: 2679
diff changeset
   323
      return tag_list
ceec88091db8 ret_list keyword argument is added to tags_strings method to enable returning lists also instead of strings.
Madhusudan.C.S <madhusudancs@gmail.com>
parents: 2679
diff changeset
   324
    else:
ceec88091db8 ret_list keyword argument is added to tags_strings method to enable returning lists also instead of strings.
Madhusudan.C.S <madhusudancs@gmail.com>
parents: 2679
diff changeset
   325
      return self.tag_separator.join(tag_list)
3091
a48f4e860f7b Tasks may be deleted by pressing 'Delete' button on the edit view.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3085
diff changeset
   326
a48f4e860f7b Tasks may be deleted by pressing 'Delete' button on the edit view.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3085
diff changeset
   327
  def tags_class(self, tag_name):
a48f4e860f7b Tasks may be deleted by pressing 'Delete' button on the edit view.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3085
diff changeset
   328
    """Return a class instance object for a given tag name.
a48f4e860f7b Tasks may be deleted by pressing 'Delete' button on the edit view.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3085
diff changeset
   329
    """
a48f4e860f7b Tasks may be deleted by pressing 'Delete' button on the edit view.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3085
diff changeset
   330
a48f4e860f7b Tasks may be deleted by pressing 'Delete' button on the edit view.
Daniel Hans <Daniel.M.Hans@gmail.com>
parents: 3085
diff changeset
   331
    return self._tag_model[tag_name]