PageRenderTime 69ms CodeModel.GetById 40ms RepoModel.GetById 0ms app.codeStats 1ms

/mobile/apps/forum/models.py

https://github.com/alexliyu/mobilesystem
Python | 269 lines | 240 code | 25 blank | 4 comment | 9 complexity | d7cc2fb38f5265246eb4d8c26a952b40 MD5 | raw file
  1. #!/usr/bin/env python
  2. # -*- coding: UTF-8 -*-
  3. from base64 import b64encode, b64decode
  4. import pickle
  5. from django.db import models
  6. from django.contrib.auth.models import User
  7. from django.db.models.signals import post_save
  8. from django.utils.translation import ugettext_lazy as _
  9. from django.db.models import Sum
  10. from django.conf import settings
  11. from attachments.models import Attachment
  12. from onlineuser.models import Online
  13. from userena.models import UserProfile
  14. class Config(models.Model):
  15. key = models.CharField(max_length=255)#PK
  16. value = models.CharField(max_length=255)
  17. class Category(models.Model):
  18. name = models.CharField(max_length=100)
  19. description = models.TextField(default='')
  20. ordering = models.PositiveIntegerField(default=1)
  21. created_on = models.DateTimeField(auto_now_add=True)
  22. updated_on = models.DateTimeField(blank=True, null=True)
  23. class Meta:
  24. verbose_name = _("Category")
  25. verbose_name_plural = _("Categories")
  26. ordering = ('-ordering', 'created_on')
  27. def __unicode__(self):
  28. return self.name
  29. class Forum(models.Model):
  30. name = models.CharField(max_length=100)
  31. slug = models.SlugField(max_length=110)
  32. description = models.TextField(default='')
  33. ordering = models.PositiveIntegerField(default=1)
  34. category = models.ForeignKey(Category)
  35. created_on = models.DateTimeField(auto_now_add=True)
  36. updated_on = models.DateTimeField(blank=True, null=True)
  37. num_topics = models.IntegerField(default=0)
  38. num_posts = models.IntegerField(default=0)
  39. last_post = models.CharField(max_length=255, blank=True)#pickle obj
  40. class Meta:
  41. verbose_name = _("Forum")
  42. verbose_name_plural = _("Forums")
  43. ordering = ('ordering', '-created_on')
  44. def count_nums_topic(self):
  45. return self.topic_set.all().count()
  46. def count_nums_post(self):
  47. return self.topic_set.all().aggregate(Sum('num_replies'))['num_replies__sum'] or 0
  48. def get_last_post(self):
  49. if not self.last_post:
  50. return {}
  51. return pickle.loads(b64decode(self.last_post))
  52. @models.permalink
  53. def get_absolute_url(self):
  54. return ('forum:forum_forum', (), {'forum_slug': self.slug})
  55. def __unicode__(self):
  56. return self.name
  57. class TopicType(models.Model):
  58. forum = models.ForeignKey(Forum, verbose_name=_('Forum'))
  59. name = models.CharField(max_length=100)
  60. slug = models.SlugField(max_length=100)
  61. description = models.TextField(blank=True, default='')
  62. def __unicode__(self):
  63. return self.name
  64. class Meta:
  65. verbose_name = u"话题类型"
  66. verbose_name_plural = u"话题类型"
  67. class TopicManager(models.Manager):
  68. def get_query_set(self):
  69. return super(TopicManager, self).get_query_set().filter(hidden=False)
  70. LEVEL_CHOICES = (
  71. (30, _('Default')),
  72. (60, _('Distillate')),
  73. )
  74. class Topic(models.Model):
  75. forum = models.ForeignKey(Forum, verbose_name=_('Forum'))
  76. topic_type = models.ForeignKey(TopicType, verbose_name=_('Topic Type'),
  77. blank=True, null=True)
  78. posted_by = models.ForeignKey(User)
  79. #TODO ADD TOPIC POST.
  80. post = models.ForeignKey('Post', verbose_name=_('Post'), related_name='topics_',
  81. blank=True, null=True)
  82. subject = models.CharField(max_length=999)
  83. num_views = models.IntegerField(default=0)
  84. num_replies = models.PositiveSmallIntegerField(default=0)#posts...
  85. created_on = models.DateTimeField(auto_now_add=True)
  86. updated_on = models.DateTimeField(blank=True, null=True)
  87. last_reply_on = models.DateTimeField(auto_now_add=True)
  88. last_post = models.CharField(max_length=255, blank=True)#pickle obj
  89. has_imgs = models.BooleanField(default=False)
  90. has_attachments = models.BooleanField(default=False)
  91. need_replay = models.BooleanField(default=False)#need_reply :-)
  92. need_reply_attachments = models.BooleanField(default=False)
  93. #Moderation features
  94. closed = models.BooleanField(default=False)
  95. sticky = models.BooleanField(default=False)
  96. hidden = models.BooleanField(default=False)
  97. level = models.SmallIntegerField(choices=LEVEL_CHOICES, default=30)
  98. objects = TopicManager()
  99. class Meta:
  100. ordering = ('-last_reply_on',)#'-sticky'
  101. get_latest_by = ('created_on')
  102. verbose_name = _("Topic")
  103. verbose_name_plural = _("Topics")
  104. def __unicode__(self):
  105. return self.subject
  106. def count_nums_replies(self):
  107. return self.posts.all().count()
  108. @models.permalink
  109. def get_absolute_url(self):
  110. return ('forum:forum_topic', (), {'topic_id': self.id})
  111. def get_last_post(self):
  112. if not self.last_post:
  113. return {}
  114. return pickle.loads(b64decode(self.last_post))
  115. def has_replied(self, user):
  116. if user.is_anonymous():
  117. return False
  118. return Post.objects.filter(posted_by=user, topic=self).count()
  119. FORMAT_CHOICES = (
  120. ('bbcode', _('BBCode')),
  121. ('html', _('Html')),
  122. )
  123. # Create Replies for a topic
  124. class Post(models.Model):#can't edit...
  125. topic = models.ForeignKey(Topic, verbose_name=_('Topic'), related_name='posts')
  126. posted_by = models.ForeignKey(User)
  127. poster_ip = models.IPAddressField()
  128. topic_post = models.BooleanField(default=False)
  129. format = models.CharField(max_length=20, default='bbcode')#user name
  130. message = models.TextField()
  131. attachments = models.ManyToManyField(Attachment, blank=True)
  132. has_imgs = models.BooleanField(default=False)
  133. has_attachments = models.BooleanField(default=False)
  134. created_on = models.DateTimeField(auto_now_add=True)
  135. updated_on = models.DateTimeField(blank=True, null=True)
  136. edited_by = models.CharField(max_length=255, blank=True)#user name
  137. class Meta:
  138. verbose_name = _("Post")
  139. verbose_name_plural = _("Posts")
  140. ordering = ('-created_on',)
  141. get_latest_by = ('created_on',)
  142. def __unicode__(self):
  143. return self.message[:80]
  144. def subject(self):
  145. if self.topic_post:
  146. return _('Topic: %s') % self.topic.subject
  147. return _('Re: %s') % self.topic.subject
  148. def file_attachments(self):
  149. return self.attachments.filter(is_img=False)
  150. def img_attachments(self):
  151. return self.attachments.filter(is_img=True)
  152. def update_attachments_flag(self):
  153. self.has_attachments = self.file_attachments().count() > 0
  154. self.has_imgs = self.img_attachments().count() > 0
  155. self.save()
  156. if self.topic_post:
  157. t = self.topic
  158. t.has_attachments = self.has_attachments
  159. t.has_imgs = self.has_imgs
  160. t.save()
  161. def update_attachments(self, attachment_ids):
  162. self.attachments.clear()
  163. for attachment_id in attachment_ids:
  164. try:
  165. attachment = Attachment.objects.get(pk=attachment_id)
  166. except:
  167. continue
  168. attachment.activated = True
  169. attachment.save()
  170. self.attachments.add(attachment)
  171. self.update_attachments_flag()
  172. @models.permalink
  173. def get_absolute_url(self):
  174. return ('forum_post', (), { 'post_id': self.pk })
  175. def get_absolute_url_ext(self):
  176. topic = self.topic
  177. post_idx = topic.posts.filter(created_on__lte=self.created_on).count()
  178. page = (post_idx - 1) / settings.CTX_CONFIG['TOPIC_PAGE_SIZE'] + 1
  179. return '%s?page=%s#p%s' % (topic.get_absolute_url(), page, self.pk)
  180. #### smoe function ###
  181. #### do smoe connect ###
  182. def gen_last_post_info(post):
  183. last_post = {'posted_by': post.posted_by.username, 'update': post.created_on}
  184. return b64encode(pickle.dumps(last_post, pickle.HIGHEST_PROTOCOL))
  185. def create_user_profile(sender, instance, created, **kwargs):
  186. if created:
  187. UserProfile.objects.create(user=instance)
  188. def update_topic_on_post(sender, instance, created, **kwargs):
  189. if created:
  190. t = instance.topic
  191. t.last_post = gen_last_post_info(instance)
  192. t.last_reply_on = instance.created_on
  193. t.num_replies += 1
  194. t.save()
  195. p = instance.posted_by.get_profile()
  196. p.last_posttime = instance.created_on
  197. p.save()
  198. def update_forum_on_post(sender, instance, created, **kwargs):
  199. if created:
  200. instance.topic.forum.last_post = gen_last_post_info(instance)
  201. instance.topic.forum.num_posts += 1
  202. instance.topic.forum.save()
  203. def update_forum_on_topic(sender, instance, created, **kwargs):
  204. if created:
  205. instance.forum.num_topics += 1
  206. instance.forum.save()
  207. def update_user_last_activity(sender, instance, created, **kwargs):
  208. if instance.user:
  209. p = instance.user.get_profile()
  210. p.last_activity = instance.updated_on
  211. p.save()
  212. post_save.connect(create_user_profile, sender=User)
  213. post_save.connect(update_topic_on_post, sender=Post)
  214. post_save.connect(update_forum_on_post, sender=Post)
  215. post_save.connect(update_forum_on_topic, sender=Topic)
  216. post_save.connect(update_user_last_activity, sender=Online)