threadprefixmodel.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. from django.core.cache import cache
  2. from django.db import models
  3. from django.utils.datastructures import SortedDict
  4. from misago.signals import (merge_thread, move_forum_content,
  5. move_thread, remove_thread_prefix)
  6. from misago.thread import local
  7. _thread_local = local()
  8. class ThreadPrefixManager(models.Manager):
  9. def flush_cache(self):
  10. cache.delete('threads_prefixes')
  11. def make_cache(self):
  12. prefixes = cache.get('threads_prefixes', 'nada')
  13. if prefixes == 'nada':
  14. prefixes = []
  15. for prefix in ThreadPrefix.objects.order_by('name').iterator():
  16. prefix.forums_pks = [f.pk for f in prefix.forums.iterator()]
  17. prefixes.append(prefix)
  18. cache.set('threads_prefixes', prefixes, None)
  19. dict_result = SortedDict()
  20. for prefix in prefixes:
  21. dict_result[prefix.pk] = prefix
  22. return dict_result
  23. def all_prefixes(self):
  24. try:
  25. return _thread_local.misago_thread_prefixes
  26. except AttributeError:
  27. _thread_local.misago_thread_prefixes = self.make_cache()
  28. return _thread_local.misago_thread_prefixes
  29. def forum_prefixes(self, forum):
  30. forum_prefixes = []
  31. for prefix in self.all_prefixes().values():
  32. if forum.pk in prefix.forums_pks:
  33. forum_prefixes.append((prefix.pk, prefix))
  34. return SortedDict(forum_prefixes)
  35. def prefix_in_forum(self, prefix, forum):
  36. forum_prefixes = self.forum_prefixes(forum)
  37. return prefix in forum_prefixes
  38. class ThreadPrefix(models.Model):
  39. forums = models.ManyToManyField('Forum')
  40. name = models.CharField(max_length=255)
  41. slug = models.SlugField(max_length=255)
  42. style = models.CharField(max_length=255)
  43. objects = ThreadPrefixManager()
  44. class Meta:
  45. app_label = 'misago'
  46. def save(self, *args, **kwargs):
  47. ThreadPrefix.objects.flush_cache()
  48. super(ThreadPrefix, self).save(*args, **kwargs)
  49. def delete(self, *args, **kwargs):
  50. ThreadPrefix.objects.flush_cache()
  51. super(ThreadPrefix, self).delete(*args, **kwargs)
  52. def update_forums(self, new_forums):
  53. current_forums = self.forums.all()
  54. removed_forums = []
  55. for forum in current_forums:
  56. if not forum in new_forums:
  57. removed_forums.append(forum)
  58. if removed_forums:
  59. remove_thread_prefix.send(sender=self, forums=removed_forums)
  60. self.forums.clear()
  61. for forum in new_forums:
  62. self.forums.add(forum)
  63. def move_forum_content_handler(sender, **kwargs):
  64. old_forum_prefixes = ThreadPrefix.objects.forum_prefixes(sender)
  65. new_forum_prefixes = ThreadPrefix.objects.forum_prefixes(kwargs['move_to'])
  66. bad_prefixes = list(set(new_forum_prefixes) - set(old_forum_prefixes))
  67. if bad_prefixes:
  68. sender.thread_set.filter(prefix__in=bad_prefixes).update(prefix=None)
  69. move_forum_content.connect(move_forum_content_handler, dispatch_uid="move_forum_threads_prefixes")
  70. def move_thread_handler(sender, **kwargs):
  71. if sender.prefix and not ThreadPrefix.objects.prefix_in_forum(sender.prefix, kwargs['move_to']):
  72. sender.prefix = None
  73. move_thread.connect(move_thread_handler, dispatch_uid="move_thread_prefixes")
  74. def merge_thread_handler(sender, **kwargs):
  75. if kwargs['new_thread'].prefix and not ThreadPrefix.objects.prefix_in_forum(kwargs['new_thread'].prefix, kwargs['new_thread'].forum):
  76. kwargs['new_thread'].prefix = None
  77. merge_thread.connect(merge_thread_handler, dispatch_uid="merge_threads_prefixes")