diff --git a/boards/abstracts/settingsmanager.py b/boards/abstracts/settingsmanager.py --- a/boards/abstracts/settingsmanager.py +++ b/boards/abstracts/settingsmanager.py @@ -1,9 +1,7 @@ -from boards import settings +import boards from boards.models import Tag, TagAlias, Attachment from boards.models.attachment import AttachmentSticker -from boards.models.thread import FAV_THREAD_NO_UPDATES from boards.models.user import UserSettings -from boards.settings import SECTION_VIEW MAX_TRIPCODE_COLLISIONS = 50 @@ -20,6 +18,7 @@ SETTING_LAST_NOTIFICATION_ID = 'last_not SETTING_IMAGE_VIEWER = 'image_viewer' SETTING_IMAGES = 'images_aliases' SETTING_ONLY_FAVORITES = 'only_favorites' +SETTING_LAST_POSTS = 'last_posts' DEFAULT_THEME = 'md' @@ -102,31 +101,32 @@ class SettingsManager: tags.remove(tag.get_name()) self.set_setting(SETTING_HIDDEN_TAGS, tags) - def get_fav_threads(self) -> dict: - return self.get_setting(SETTING_FAVORITE_THREADS, default=dict()) - def add_or_read_fav_thread(self, opening_post): - threads = self.get_fav_threads() + last_post_ids = self.get_setting(SETTING_LAST_POSTS) + if not last_post_ids: + last_post_ids = [] - max_fav_threads = settings.get_int(SECTION_VIEW, 'MaxFavoriteThreads') - if (str(opening_post.id) in threads) or (len(threads) < max_fav_threads): - thread = opening_post.get_thread() - # Don't check for new posts if the thread is archived already - if thread.is_archived(): - last_id = FAV_THREAD_NO_UPDATES - else: - last_id = thread.get_replies().last().id - threads[str(opening_post.id)] = last_id - self.set_setting(SETTING_FAVORITE_THREADS, threads) + self.del_fav_thread(opening_post) + + last_post_id = opening_post.get_thread().get_replies().last().id + last_post_ids.append(last_post_id) + + self.set_setting(SETTING_LAST_POSTS, last_post_ids) def del_fav_thread(self, opening_post): - threads = self.get_fav_threads() - if self.thread_is_fav(opening_post): - del threads[str(opening_post.id)] - self.set_setting(SETTING_FAVORITE_THREADS, threads) + last_posts_ids = self.get_setting(SETTING_LAST_POSTS) + + for post in self.get_last_posts(): + if post.get_thread() == opening_post.get_thread(): + last_posts_ids.remove(post.id) + + self.set_setting(SETTING_LAST_POSTS, last_posts_ids) def thread_is_fav(self, opening_post): - return str(opening_post.id) in self.get_fav_threads() + for post in self.get_last_posts(): + if post.get_thread() == opening_post.get_thread(): + return True + return False def get_notification_usernames(self): names = set() @@ -178,6 +178,10 @@ class SettingsManager: hidden_tag_names = self.get_setting(SETTING_HIDDEN_TAGS) return hidden_tag_names is not None and tag.get_name() in hidden_tag_names + def get_last_posts(self): + post_ids = self.get_setting(SETTING_LAST_POSTS) or [] + return [boards.models.Post.objects.get(id=post_id) for post_id in post_ids] + class SessionSettingsManager(SettingsManager): """ @@ -202,6 +206,8 @@ class SessionSettingsManager(SettingsMan class DatabaseSettingsManager(SessionSettingsManager): def __init__(self, session): super().__init__(session) + if not session.session_key: + session.save() self.settings, created = UserSettings.objects.get_or_create(session_key=session.session_key) def add_fav_tag(self, tag): diff --git a/boards/context_processors.py b/boards/context_processors.py --- a/boards/context_processors.py +++ b/boards/context_processors.py @@ -39,14 +39,10 @@ def get_notifications(context, settings_ def get_new_post_count(context, settings_manager): - fav_threads = settings_manager.get_fav_threads() - if fav_threads: - fav_thread_ops = Post.objects.filter(id__in=fav_threads.keys()) \ - .order_by('-pub_time').only('thread_id', 'pub_time') - ops = [{'op': op, 'last_id': fav_threads[str(op.id)]} for op in fav_thread_ops] - count = Thread.objects.get_new_post_count(ops) - if count > 0: - context[CONTEXT_NEW_POST_COUNT] = '(+{})'.format(count) + last_posts = settings_manager.get_last_posts() + count = Thread.objects.get_new_post_count(last_posts) + if count > 0: + context[CONTEXT_NEW_POST_COUNT] = '(+{})'.format(count) def user_and_ui_processor(request): @@ -75,7 +71,7 @@ def user_and_ui_processor(request): default=settings.get(SECTION_VIEW, 'DefaultImageViewer')) context[CONTEXT_HAS_FAV_THREADS] =\ - len(settings_manager.get_fav_threads()) > 0 + len(settings_manager.get_last_posts()) > 0 context[CONTEXT_BANNERS] = Banner.objects.order_by('-id') context[CONTEXT_ONLY_FAVORITES] = settings_manager.get_setting( diff --git a/boards/models/thread.py b/boards/models/thread.py --- a/boards/models/thread.py +++ b/boards/models/thread.py @@ -60,13 +60,11 @@ class ThreadManager(models.Manager): thread.update_posts_time() thread.save(update_fields=['last_edit_time', 'status']) - def get_new_posts(self, datas): + def get_new_posts(self, last_posts): query = None - # TODO Use classes instead of dicts - for data in datas: - if data['last_id'] != FAV_THREAD_NO_UPDATES: - q = (Q(id=data['op'].get_thread_id()) - & Q(replies__id__gt=data['last_id'])) + for post in last_posts: + if not post.get_thread().is_archived(): + q = Q(id=post.thread_id) & Q(replies__id__gt=post.id) if query is None: query = q else: @@ -75,8 +73,8 @@ class ThreadManager(models.Manager): return self.filter(query).annotate( new_post_count=Count('replies')) - def get_new_post_count(self, datas): - new_posts = self.get_new_posts(datas) + def get_new_post_count(self, last_posts): + new_posts = self.get_new_posts(last_posts) return new_posts.aggregate(total_count=Count('replies'))\ ['total_count'] if new_posts else 0 diff --git a/boards/views/api.py b/boards/views/api.py --- a/boards/views/api.py +++ b/boards/views/api.py @@ -290,27 +290,25 @@ def api_get_new_posts(request): include_posts = 'include_posts' in request.GET settings_manager = get_settings_manager(request) - fav_threads = settings_manager.get_fav_threads() - fav_thread_ops = Post.objects.filter(id__in=fav_threads.keys())\ - .order_by('-pub_time').prefetch_related('thread') - ops = [{'op': op, 'last_id': fav_threads[str(op.id)]} for op in fav_thread_ops] + last_posts = settings_manager.get_last_posts() if include_posts: - new_post_threads = Thread.objects.get_new_posts(ops) + new_post_threads = Thread.objects.get_new_posts(last_posts) if new_post_threads: thread_ids = {thread.id: thread for thread in new_post_threads} else: thread_ids = dict() - for op in fav_thread_ops: + for post in last_posts: fav_thread_dict = dict() - op_thread = op.get_thread() - if op_thread.id in thread_ids: - thread = thread_ids[op_thread.id] + thread = post.get_thread() + op = thread.get_opening_post() + if thread.id in thread_ids: + thread = thread_ids[thread.id] new_post_count = thread.new_post_count fav_thread_dict['newest_post_link'] = thread.get_replies()\ - .filter(id__gt=fav_threads[str(op.id)])\ + .filter(id__gt=post.id)\ .first().get_absolute_url(thread=thread) else: new_post_count = 0 @@ -325,7 +323,7 @@ def api_get_new_posts(request): else: fav_thread_dict = dict() fav_thread_dict['new_post_count'] = \ - Thread.objects.get_new_post_count(ops) + Thread.objects.get_new_post_count(last_posts) posts.append(fav_thread_dict) return HttpResponse(content=json.dumps(posts)) diff --git a/boards/views/feed.py b/boards/views/feed.py --- a/boards/views/feed.py +++ b/boards/views/feed.py @@ -53,9 +53,9 @@ class FavoritesFilter(FeedFilter): favorites = 'favorites' in request.GET if favorites: settings_manager = get_settings_manager(request) - fav_thread_ops = Post.objects.filter(id__in=settings_manager.get_fav_threads().keys()) - fav_threads = [op.get_thread() for op in fav_thread_ops] - filtered_posts = filtered_posts.filter(thread__in=fav_threads) + last_posts = settings_manager.get_last_posts() + threads = [post.get_thread() for post in last_posts] + filtered_posts = filtered_posts.filter(thread__in=threads) return filtered_posts