-from base import *\r
-\r
-from django.utils.translation import ugettext as _\r
-\r
-class TagManager(models.Manager):\r
- UPDATE_USED_COUNTS_QUERY = (\r
- 'UPDATE tag '\r
- 'SET used_count = ('\r
- 'SELECT COUNT(*) FROM question_tags '\r
- 'INNER JOIN question ON question_id=question.id '\r
- 'WHERE tag_id = tag.id AND question.deleted=False'\r
- ') '\r
- 'WHERE id IN (%s)')\r
-\r
- def get_valid_tags(self, page_size):\r
- tags = self.all().filter(deleted=False).exclude(used_count=0).order_by("-id")[:page_size]\r
- return tags\r
-\r
- def get_or_create_multiple(self, names, user):\r
- """\r
- Fetches a list of Tags with the given names, creating any Tags\r
- which don't exist when necesssary.\r
- """\r
- tags = list(self.filter(name__in=names))\r
- #Set all these tag visible\r
- for tag in tags:\r
- if tag.deleted:\r
- tag.deleted = False\r
- tag.deleted_by = None\r
- tag.deleted_at = None\r
- tag.save()\r
-\r
- if len(tags) < len(names):\r
- existing_names = set(tag.name for tag in tags)\r
- new_names = [name for name in names if name not in existing_names]\r
- tags.extend([self.create(name=name, created_by=user)\r
- for name in new_names if self.filter(name=name).count() == 0 and len(name.strip()) > 0])\r
-\r
- return tags\r
-\r
- def update_use_counts(self, tags):\r
- """Updates the given Tags with their current use counts."""\r
- if not tags:\r
- return\r
- cursor = connection.cursor()\r
- query = self.UPDATE_USED_COUNTS_QUERY % ','.join(['%s'] * len(tags))\r
- cursor.execute(query, [tag.id for tag in tags])\r
- transaction.commit_unless_managed()\r
-\r
- def get_tags_by_questions(self, questions):\r
- question_ids = []\r
- for question in questions:\r
- question_ids.append(question.id)\r
-\r
- question_ids_str = ','.join([str(id) for id in question_ids])\r
- related_tags = self.extra(\r
- tables=['tag', 'question_tags'],\r
- where=["tag.id = question_tags.tag_id AND question_tags.question_id IN (" + question_ids_str + ")"]\r
- ).distinct()\r
-\r
- return related_tags\r
-\r
-class Tag(DeletableContent):\r
- name = models.CharField(max_length=255, unique=True)\r
- created_by = models.ForeignKey(User, related_name='created_tags')\r
- # Denormalised data\r
- used_count = models.PositiveIntegerField(default=0)\r
-\r
- objects = TagManager()\r
-\r
- class Meta(DeletableContent.Meta):\r
- db_table = u'tag'\r
- ordering = ('-used_count', 'name')\r
-\r
- def __unicode__(self):\r
- return self.name\r
-\r
-class MarkedTag(models.Model):\r
- TAG_MARK_REASONS = (('good',_('interesting')),('bad',_('ignored')))\r
- tag = models.ForeignKey('Tag', related_name='user_selections')\r
- user = models.ForeignKey(User, related_name='tag_selections')\r
- reason = models.CharField(max_length=16, choices=TAG_MARK_REASONS)\r
-\r
- class Meta:\r
- app_label = 'forum'
\ No newline at end of file
+import datetime
+from base import *
+
+from django.conf import settings as django_settings
+from django.core.cache.backends.base import BaseCache
+from django.utils.translation import ugettext as _
+from django.utils.encoding import smart_unicode, force_unicode
+
+from forum import modules
+
+class ActiveTagManager(CachedManager):
+ use_for_related_fields = True
+
+ def get_queryset(self):
+ return super(ActiveTagManager, self).get_queryset().exclude(used_count__lt=1)
+
+class Tag(BaseModel):
+ name = models.CharField(max_length=255, unique=True)
+ created_by = models.ForeignKey(User, related_name='created_tags')
+ created_at = models.DateTimeField(default=datetime.datetime.now, blank=True, null=True)
+ marked_by = models.ManyToManyField(User, related_name="marked_tags", through="MarkedTag")
+ # Denormalised data
+ used_count = models.PositiveIntegerField(default=0)
+
+ active = ActiveTagManager()
+
+ class Meta:
+ ordering = ('-used_count', 'name')
+ app_label = 'forum'
+
+ def __unicode__(self):
+ return force_unicode(self.name)
+
+ def add_to_usage_count(self, value):
+ if self.used_count + value < 0:
+ self.used_count = 0
+ else:
+ self.used_count = models.F('used_count') + value
+
+ def cache_key(self):
+ return self._generate_cache_key(Tag.safe_cache_name(self.name))
+
+ @classmethod
+ def safe_cache_name(cls, name):
+ return "".join([str(ord(c)) for c in name])
+
+ @classmethod
+ def infer_cache_key(cls, querydict):
+ if 'name' in querydict:
+ cache_key = cls._generate_cache_key(cls.safe_cache_name(querydict['name']))
+
+ if len(cache_key) > django_settings.CACHE_MAX_KEY_LENGTH:
+ cache_key = cache_key[:django_settings.CACHE_MAX_KEY_LENGTH]
+
+ return cache_key
+
+ return None
+
+ @classmethod
+ def value_to_list_on_cache_query(cls):
+ return 'name'
+
+ @models.permalink
+ def get_absolute_url(self):
+ return ('tag_questions', (), {'tag': self.name})
+
+class MarkedTag(models.Model):
+ TAG_MARK_REASONS = (('good', _('interesting')), ('bad', _('ignored')))
+ tag = models.ForeignKey(Tag, related_name='user_selections')
+ user = models.ForeignKey(User, related_name='tag_selections')
+ reason = models.CharField(max_length=16, choices=TAG_MARK_REASONS)
+
+ class Meta:
+ app_label = 'forum'
+