app/taggable/taggable.py
author Lennard de Rijk <ljvderijk@gmail.com>
Wed, 30 Sep 2009 21:10:36 +0200
changeset 2994 24db4afbc82e
parent 2950 ceec88091db8
child 3081 14077185c46e
permissions -rw-r--r--
Removed order property in the getBatchOfData. This ordering is not possible since you want to go over the entities in order oftheir key and ordering them would prohibit this from happening properly.
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
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
     2
import string
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
     3
    
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
     4
class Tag(db.Model):
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
     5
  "Google AppEngine model for store of tags."
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
     6
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
     7
  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
     8
  "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
     9
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    10
  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
    11
  "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
    12
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    13
  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
    14
  "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
    15
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    16
  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
    17
  "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
    18
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    19
  @classmethod
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    20
  def __key_name(cls, tag_name):
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    21
    return cls.__name__ + '_' + tag_name
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    22
    
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    23
  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
    24
    def remove_tagged_txn():
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    25
      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
    26
        self.tagged.remove(key)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    27
        self.tagged_count -= 1
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    28
        self.put()
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    29
    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
    30
    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
    31
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    32
  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
    33
    def add_tagged_txn():
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    34
      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
    35
        self.tagged.append(key)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    36
        self.tagged_count += 1
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    37
        self.put()
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    38
    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
    39
    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
    40
    
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    41
  def clear_tagged(self):
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    42
    def clear_tagged_txn():
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    43
      self.tagged = []
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    44
      self.tagged_count = 0
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    45
      self.put()
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(clear_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
  @classmethod
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    50
  def get_by_name(cls, tag_name):
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    51
    return cls.get_by_key_name(cls.__key_name(tag_name))
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    52
    
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    53
  @classmethod
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    54
  def get_tags_for_key(cls, key):
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    55
    "Set the tags for the datastore object represented by key."
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    56
    tags = db.Query(cls).filter('tagged =', key).fetch(1000)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    57
    return tags
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    58
    
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    59
  @classmethod
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    60
  def get_or_create(cls, tag_name):
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    61
    "Get the Tag object that has the tag value given by tag_value."
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    62
    tag_key_name = cls.__key_name(tag_name)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    63
    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
    64
    if existing_tag is None:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    65
      # The tag does not yet exist, so create it.
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    66
      def create_tag_txn():
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    67
        new_tag = cls(key_name=tag_key_name, tag=tag_name)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    68
        new_tag.put()
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    69
        return new_tag
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    70
      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
    71
    return existing_tag
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    72
    
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    73
  @classmethod
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    74
  def get_tags_by_frequency(cls, limit=1000):
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    75
    """Return a list of Tags sorted by the number of objects to 
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    76
    which they have been applied, most frequently-used first. 
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    77
    If limit is given, return only that many tags; otherwise,
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    78
    return all."""
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    79
    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
    80
        "-tagged_count").fetch(limit)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    81
            
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    82
    return tag_list
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    83
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    84
  @classmethod
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    85
  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
    86
    """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
    87
    If a limit is given, return only that many tags; otherwise, return all.
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    88
    If ascending is True, sort from a-z; otherwise, sort from z-a."""
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    89
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    90
    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
    91
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    92
    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
    93
    if ascending:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    94
      cache_name += '_asc'
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    95
    else:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    96
      cache_name += '_desc'
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    97
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
    98
    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
    99
    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
   100
      order_by = "tag"
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   101
      if not ascending:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   102
        order_by = "-tag"
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   103
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   104
      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
   105
      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
   106
    else:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   107
      if len(tags) > limit:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   108
        # 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
   109
        tags = tags[:limit]
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   110
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   111
    return tags
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   112
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   113
  @classmethod
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   114
  def popular_tags(cls, limit=5):
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   115
    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
   116
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   117
    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
   118
    if tags is None:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   119
      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
   120
      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
   121
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   122
    return tags
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   123
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   124
  @classmethod
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   125
  def expire_cached_tags(cls):
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   126
    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
   127
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   128
    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
   129
    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
   130
    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
   131
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   132
  def __str__(self):
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   133
    """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
   134
    """
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   135
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   136
    return self.tag
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   137
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   138
def tag_property(tag_name):
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   139
  """Decorator that creates and returns a tag property to be used 
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   140
  in Google AppEngine model.
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   141
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   142
  Args:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   143
    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
   144
  """
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   145
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   146
  def get_tags(self):
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   147
    """"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
   148
    specified entity.
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   149
    """
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   150
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   151
    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
   152
      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
   153
          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
   154
    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
   155
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   156
  def set_tags(self, seed):
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   157
    """Set a list of Tag objects for all Tags that apply to 
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   158
    the specified entity.
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   159
    """
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   160
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   161
    import types
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   162
    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
   163
      # 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
   164
      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
   165
    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
   166
      # 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
   167
      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
   168
    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
   169
      get_tags(self)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   170
      # 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
   171
      # 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
   172
      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
   173
        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
   174
          # 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
   175
          # 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
   176
          # 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
   177
          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
   178
          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
   179
      # 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
   180
      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
   181
        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
   182
        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
   183
          # 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
   184
          # 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
   185
          # 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
   186
          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
   187
              seed['scope'], each_tag)
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   188
          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
   189
          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
   190
    else:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   191
      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
   192
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   193
  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
   194
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   195
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   196
class Taggable(object):
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   197
  """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
   198
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   199
  This is an extended version of Taggable-mixin which allows for 
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   200
  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
   201
  """
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   202
    
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   203
  def __init__(self, **kwargs):
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   204
    """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
   205
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   206
    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
   207
    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
   208
    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
   209
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   210
    Args:
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   211
      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
   212
          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
   213
    """
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
    self._tags = {}
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   216
    self._tag_model = {}
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   217
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   218
    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
   219
      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
   220
      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
   221
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   222
    self.tag_separator = ", "
0ede2f3adbc1 Adds to Melange a tags framework based on taggable-mixin.
Madhusudan C.S <madhusudancs@gmail.com>
parents:
diff changeset
   223
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
   224
  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
   225
    """Create a formatted string version of this entity's tags.
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
   226
    
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
   227
    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
   228
      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
   229
      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
   230
    """
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
   231
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
   232
    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
   233
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
   234
    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
   235
      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
   236
    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
   237
      return self.tag_separator.join(tag_list)