123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- from datetime import timedelta
- from django.conf import settings
- from django.utils import timezone
- from misago.models import Thread, ForumRead, ThreadRead
- class ForumsTracker(object):
- def __init__(self, user):
- self.user = user
- self.cutoff = timezone.now() - timedelta(days=settings.READS_TRACKER_LENGTH)
- self.forums = {}
- if user.is_authenticated() and settings.READS_TRACKER_LENGTH > 0:
- if user.join_date > self.cutoff:
- self.cutoff = user.join_date
- for forum in ForumRead.objects.filter(user=user).filter(updated__gte=self.cutoff).values('id', 'forum_id', 'updated', 'cleared'):
- self.forums[forum['forum_id']] = forum
- def is_read(self, forum):
- if not self.user.is_authenticated() or not forum.last_thread_date:
- return True
- try:
- return forum.last_thread_date <= self.cutoff or forum.last_thread_date <= self.forums[forum.pk]['cleared']
- except KeyError:
- return False
- class ThreadsTracker(object):
- def __init__(self, request, forum):
- self.need_create = None
- self.need_update = None
- self.request = request
- self.forum = forum
- self.cutoff = timezone.now() - timedelta(days=settings.READS_TRACKER_LENGTH)
- if request.user.is_authenticated():
- if request.user.join_date > self.cutoff:
- self.cutoff = request.user.join_date
- try:
- self.record = ForumRead.objects.get(user=request.user, forum=forum)
- if self.record.cleared > self.cutoff:
- self.cutoff = self.record.cleared
- except ForumRead.DoesNotExist:
- self.record = ForumRead(user=request.user, forum=forum, cleared=self.cutoff)
- self.threads = self.record.get_threads()
- def read_date(self, thread):
- if not self.request.user.is_authenticated():
- return timezone.now()
- try:
- if self.threads[thread.pk].updated > self.cutoff:
- return self.threads[thread.pk].updated
- except KeyError:
- pass
- return self.cutoff
- def is_read(self, thread):
- if not self.request.user.is_authenticated():
- return True
- try:
- return thread.last <= self.cutoff or thread.last <= self.threads[thread.pk].updated
- except KeyError:
- return False
- def set_read(self, thread, post):
- if self.request.user.is_authenticated() and post.date > self.cutoff:
- try:
- self.threads[thread.pk].updated = post.date
- self.need_update = self.threads[thread.pk]
- except KeyError:
- self.need_create = thread
- def unread_count(self, queryset=None):
- try:
- return self.unread_threads
- except AttributeError:
- self.unread_threads = 0
- if queryset == None:
- queryset = self.default_queryset()
- for thread in queryset.filter(last__gte=self.record.cleared):
- if not self.is_read(thread):
- self.unread_threads += 1
- return self.unread_threads
- def sync(self, queryset=None):
- now = timezone.now()
- if queryset == None:
- queryset = self.default_queryset()
- if self.need_create:
- new_record = ThreadRead(
- user=self.request.user,
- thread=self.need_create,
- forum=self.forum,
- updated=now
- )
- new_record.save(force_insert=True)
- self.threads[new_record.thread_id] = new_record
- if self.need_update:
- self.need_update.updated = now
- self.need_update.save(force_update=True)
- if self.need_create or self.need_update:
- if not self.unread_count(queryset):
- self.record.cleared = now
- self.record.updated = now
- if self.record.pk:
- self.record.save(force_update=True)
- else:
- self.record.save(force_insert=True)
- def default_queryset(self):
- return self.request.acl.threads.filter_threads(self.request, self.forum, self.forum.thread_set)
|