Show More
@@ -56,9 +56,9 b' class ThreadAdmin(admin.ModelAdmin):' | |||
|
56 | 56 | def op(self, obj: Thread): |
|
57 | 57 | return obj.get_opening_post_id() |
|
58 | 58 | |
|
59 |
list_display = ('id', 'op', 'title', 'reply_count', ' |
|
|
59 | list_display = ('id', 'op', 'title', 'reply_count', 'status', 'ip', | |
|
60 | 60 | 'display_tags') |
|
61 |
list_filter = ('bump_time', ' |
|
|
61 | list_filter = ('bump_time', 'status') | |
|
62 | 62 | search_fields = ('id', 'title') |
|
63 | 63 | filter_horizontal = ('tags',) |
|
64 | 64 |
@@ -238,7 +238,7 b' class PostForm(NeboardForm):' | |||
|
238 | 238 | for thread_id in threads_id_list: |
|
239 | 239 | try: |
|
240 | 240 | thread = Post.objects.get(id=int(thread_id)) |
|
241 | if not thread.is_opening() or thread.get_thread().archived: | |
|
241 | if not thread.is_opening() or thread.get_thread().is_archived(): | |
|
242 | 242 | raise ObjectDoesNotExist() |
|
243 | 243 | threads.append(thread) |
|
244 | 244 | except (ObjectDoesNotExist, ValueError): |
@@ -27,8 +27,8 b' class PostImageManager(models.Manager):' | |||
|
27 | 27 | |
|
28 | 28 | return post_image |
|
29 | 29 | |
|
30 |
def get_random_images(self, count, |
|
|
31 | images = self.filter(post_images__thread__archived=include_archived) | |
|
30 | def get_random_images(self, count, tags=None): | |
|
31 | images = self | |
|
32 | 32 | if tags is not None: |
|
33 | 33 | images = images.filter(post_images__threads__tags__in=tags) |
|
34 | 34 | return images.order_by('?')[:count] |
@@ -178,7 +178,7 b' class Post(models.Model, Viewable):' | |||
|
178 | 178 | thread = self.get_thread() |
|
179 | 179 | |
|
180 | 180 | css_classes = [CSS_CLS_POST] |
|
181 | if thread.archived: | |
|
181 | if thread.is_archived(): | |
|
182 | 182 | css_classes.append(CSS_CLS_ARCHIVE_POST) |
|
183 | 183 | elif not thread.can_bump(): |
|
184 | 184 | css_classes.append(CSS_CLS_DEAD_POST) |
@@ -283,7 +283,7 b' class Post(models.Model, Viewable):' | |||
|
283 | 283 | for thread in self.get_threads().all(): |
|
284 | 284 | thread.last_edit_time = self.last_edit_time |
|
285 | 285 | |
|
286 |
thread.save(update_fields=['last_edit_time', ' |
|
|
286 | thread.save(update_fields=['last_edit_time', 'status']) | |
|
287 | 287 | |
|
288 | 288 | super().save(force_insert, force_update, using, update_fields) |
|
289 | 289 | |
@@ -335,7 +335,7 b' class Post(models.Model, Viewable):' | |||
|
335 | 335 | thread.update_bump_status() |
|
336 | 336 | |
|
337 | 337 | thread.last_edit_time = self.last_edit_time |
|
338 |
thread.save(update_fields=['last_edit_time', ' |
|
|
338 | thread.save(update_fields=['last_edit_time', 'status']) | |
|
339 | 339 | self.threads.add(opening_post.get_thread()) |
|
340 | 340 | |
|
341 | 341 | def get_tripcode(self): |
@@ -5,6 +5,7 b' from django.db.models import Count' | |||
|
5 | 5 | from django.core.urlresolvers import reverse |
|
6 | 6 | |
|
7 | 7 | from boards.models.base import Viewable |
|
8 | from boards.models.thread import STATUS_ACTIVE, STATUS_BUMPLIMIT, STATUS_ARCHIVE | |
|
8 | 9 | from boards.utils import cached_result |
|
9 | 10 | import boards |
|
10 | 11 | |
@@ -61,22 +62,20 b' class Tag(models.Model, Viewable):' | |||
|
61 | 62 | |
|
62 | 63 | return self.get_thread_count() == 0 |
|
63 | 64 | |
|
64 |
def get_thread_count(self, |
|
|
65 | def get_thread_count(self, status=None) -> int: | |
|
65 | 66 | threads = self.get_threads() |
|
66 |
if |
|
|
67 |
threads = threads.filter( |
|
|
68 | if bumpable is not None: | |
|
69 | threads = threads.filter(bumpable=bumpable) | |
|
67 | if status is not None: | |
|
68 | threads = threads.filter(status=status) | |
|
70 | 69 | return threads.count() |
|
71 | 70 | |
|
72 | 71 | def get_active_thread_count(self) -> int: |
|
73 |
return self.get_thread_count( |
|
|
72 | return self.get_thread_count(status=STATUS_ACTIVE) | |
|
74 | 73 | |
|
75 | 74 | def get_bumplimit_thread_count(self) -> int: |
|
76 |
return self.get_thread_count( |
|
|
75 | return self.get_thread_count(status=STATUS_BUMPLIMIT) | |
|
77 | 76 | |
|
78 | 77 | def get_archived_thread_count(self) -> int: |
|
79 |
return self.get_thread_count( |
|
|
78 | return self.get_thread_count(status=STATUS_ARCHIVE) | |
|
80 | 79 | |
|
81 | 80 | def get_absolute_url(self): |
|
82 | 81 | return reverse('tag', kwargs={'tag_name': self.name}) |
@@ -106,11 +105,11 b' class Tag(models.Model, Viewable):' | |||
|
106 | 105 | def get_description(self): |
|
107 | 106 | return self.description |
|
108 | 107 | |
|
109 |
def get_random_image_post(self, |
|
|
108 | def get_random_image_post(self, status=False): | |
|
110 | 109 | posts = boards.models.Post.objects.annotate(images_count=Count( |
|
111 | 110 | 'images')).filter(images_count__gt=0, threads__tags__in=[self]) |
|
112 |
if |
|
|
113 |
posts = posts.filter(thread__ |
|
|
111 | if status is not None: | |
|
112 | posts = posts.filter(thread__status=status) | |
|
114 | 113 | return posts.order_by('?').first() |
|
115 | 114 | |
|
116 | 115 | def get_first_letter(self): |
@@ -5,6 +5,10 b' from django.db.models import Count, Sum,' | |||
|
5 | 5 | from django.utils import timezone |
|
6 | 6 | from django.db import models |
|
7 | 7 | |
|
8 | STATUS_ACTIVE = 'active' | |
|
9 | STATUS_BUMPLIMIT = 'bumplimit' | |
|
10 | STATUS_ARCHIVE = 'archived' | |
|
11 | ||
|
8 | 12 | from boards import settings |
|
9 | 13 | import boards |
|
10 | 14 | from boards.utils import cached_result, datetime_to_epoch |
@@ -33,7 +37,7 b' class ThreadManager(models.Manager):' | |||
|
33 | 37 | archive or delete the old ones. |
|
34 | 38 | """ |
|
35 | 39 | |
|
36 |
threads = Thread.objects. |
|
|
40 | threads = Thread.objects.exclude(status=STATUS_ARCHIVE).order_by('-bump_time') | |
|
37 | 41 | thread_count = threads.count() |
|
38 | 42 | |
|
39 | 43 | max_thread_count = settings.get_int('Messages', 'MaxThreadCount') |
@@ -50,11 +54,10 b' class ThreadManager(models.Manager):' | |||
|
50 | 54 | logger.info('Processed %d old threads' % num_threads_to_delete) |
|
51 | 55 | |
|
52 | 56 | def _archive_thread(self, thread): |
|
53 | thread.archived = True | |
|
54 | thread.bumpable = False | |
|
57 | thread.status = STATUS_ARCHIVE | |
|
55 | 58 | thread.last_edit_time = timezone.now() |
|
56 | 59 | thread.update_posts_time() |
|
57 |
thread.save(update_fields=[' |
|
|
60 | thread.save(update_fields=['last_edit_time', 'status']) | |
|
58 | 61 | |
|
59 | 62 | def get_new_posts(self, datas): |
|
60 | 63 | query = None |
@@ -90,9 +93,8 b' class Thread(models.Model):' | |||
|
90 | 93 | tags = models.ManyToManyField('Tag', related_name='thread_tags') |
|
91 | 94 | bump_time = models.DateTimeField(db_index=True) |
|
92 | 95 | last_edit_time = models.DateTimeField() |
|
93 | archived = models.BooleanField(default=False) | |
|
94 | bumpable = models.BooleanField(default=True) | |
|
95 | 96 | max_posts = models.IntegerField(default=get_thread_max_posts) |
|
97 | status = models.CharField(max_length=50, default=STATUS_ACTIVE) | |
|
96 | 98 | |
|
97 | 99 | def get_tags(self) -> QuerySet: |
|
98 | 100 | """ |
@@ -118,7 +120,7 b' class Thread(models.Model):' | |||
|
118 | 120 | |
|
119 | 121 | def update_bump_status(self, exclude_posts=None): |
|
120 | 122 | if self.has_post_limit() and self.get_reply_count() >= self.max_posts: |
|
121 | self.bumpable = False | |
|
123 | self.status = STATUS_BUMPLIMIT | |
|
122 | 124 | self.update_posts_time(exclude_posts=exclude_posts) |
|
123 | 125 | |
|
124 | 126 | def _get_cache_key(self): |
@@ -138,7 +140,7 b' class Thread(models.Model):' | |||
|
138 | 140 | Checks if the thread can be bumped by replying to it. |
|
139 | 141 | """ |
|
140 | 142 | |
|
141 | return self.bumpable and not self.is_archived() | |
|
143 | return self.get_status() == STATUS_ACTIVE | |
|
142 | 144 | |
|
143 | 145 | def get_last_replies(self) -> QuerySet: |
|
144 | 146 | """ |
@@ -255,4 +257,7 b' class Thread(models.Model):' | |||
|
255 | 257 | return self.get_replies().filter(id__gt=post_id) |
|
256 | 258 | |
|
257 | 259 | def is_archived(self): |
|
258 | return self.archived | |
|
260 | return self.get_status() == STATUS_ARCHIVE | |
|
261 | ||
|
262 | def get_status(self): | |
|
263 | return self.status |
@@ -3,6 +3,7 b' from django.core.urlresolvers import rev' | |||
|
3 | 3 | from django.shortcuts import get_object_or_404 |
|
4 | 4 | from boards.models import Post, Tag, Thread |
|
5 | 5 | from boards import settings |
|
6 | from boards.models.thread import STATUS_ARCHIVE | |
|
6 | 7 | |
|
7 | 8 | __author__ = 'nekorin' |
|
8 | 9 | |
@@ -18,7 +19,7 b' class AllThreadsFeed(Feed):' | |||
|
18 | 19 | description_template = 'boards/rss/post.html' |
|
19 | 20 | |
|
20 | 21 | def items(self): |
|
21 |
return Thread.objects. |
|
|
22 | return Thread.objects.exclude(status=STATUS_ARCHIVE).order_by('-id')[:MAX_ITEMS] | |
|
22 | 23 | |
|
23 | 24 | def item_title(self, item): |
|
24 | 25 | return item.get_opening_post().title |
@@ -36,7 +37,7 b' class TagThreadsFeed(Feed):' | |||
|
36 | 37 | description_template = 'boards/rss/post.html' |
|
37 | 38 | |
|
38 | 39 | def items(self, obj): |
|
39 |
return obj.get_threads(). |
|
|
40 | return obj.get_threads().exclude(status=STATUS_ARCHIVE).order_by('-id')[:MAX_ITEMS] | |
|
40 | 41 | |
|
41 | 42 | def get_object(self, request, tag_name): |
|
42 | 43 | return get_object_or_404(Tag, name=tag_name) |
@@ -21,14 +21,14 b'' | |||
|
21 | 21 | and this is an opening post (thread death time) or a post for popup |
|
22 | 22 | (we don't see OP here so we show the death time in the post itself). |
|
23 | 23 | {% endcomment %} |
|
24 | {% if thread.archived %} | |
|
24 | {% if thread.is_archived %} | |
|
25 | 25 | {% if is_opening %} |
|
26 | 26 | — <time datetime="{{ thread.bump_time|date:'c' }}">{{ thread.bump_time }}</time> |
|
27 | 27 | {% endif %} |
|
28 | 28 | {% endif %} |
|
29 | 29 | {% if is_opening %} |
|
30 | 30 | {% if need_open_link %} |
|
31 | {% if thread.archived %} | |
|
31 | {% if thread.is_archived %} | |
|
32 | 32 | <a class="link" href="{% url 'thread' post.id %}">{% trans "Open" %}</a> |
|
33 | 33 | {% else %} |
|
34 | 34 | <a class="link" href="{% url 'thread' post.id %}#form">{% trans "Reply" %}</a> |
@@ -41,7 +41,7 b'' | |||
|
41 | 41 | {% endwith %} |
|
42 | 42 | {% endif %} |
|
43 | 43 | {% endif %} |
|
44 | {% if reply_link and not thread.archived %} | |
|
44 | {% if reply_link and not thread.is_archived %} | |
|
45 | 45 | <a href="#form" onclick="addQuickReply('{{ post.id }}'); return false;">{% trans 'Reply' %}</a> |
|
46 | 46 | {% endif %} |
|
47 | 47 |
@@ -38,7 +38,7 b'' | |||
|
38 | 38 | {% endfor %} |
|
39 | 39 | </div> |
|
40 | 40 | |
|
41 | {% if not thread.archived %} | |
|
41 | {% if not thread.is_archived %} | |
|
42 | 42 | <div class="post-form-w"> |
|
43 | 43 | <script src="{% static 'js/panel.js' %}"></script> |
|
44 | 44 | <div class="form-title">{% trans "Reply to thread" %} #{{ opening_post.id }}<span class="reply-to-message"> {% trans "to message " %} #<span id="reply-to-message-id"></span></span></div> |
@@ -31,6 +31,7 b' class ApiTest(TestCase):' | |||
|
31 | 31 | req = MockRequest() |
|
32 | 32 | req.POST['thread'] = opening_post.id |
|
33 | 33 | req.POST['uids'] = ' '.join(uids) |
|
34 | req.user = None | |
|
34 | 35 | # Check the timestamp before post was added |
|
35 | 36 | response = api.api_get_threaddiff(req) |
|
36 | 37 | diff = simplejson.loads(response.content) |
@@ -3,6 +3,7 b' from django.test import TestCase' | |||
|
3 | 3 | |
|
4 | 4 | from boards import settings |
|
5 | 5 | from boards.models import Tag, Post, Thread |
|
6 | from boards.models.thread import STATUS_ARCHIVE | |
|
6 | 7 | |
|
7 | 8 | |
|
8 | 9 | class PostTests(TestCase): |
@@ -96,7 +97,7 b' class PostTests(TestCase):' | |||
|
96 | 97 | self._create_post() |
|
97 | 98 | |
|
98 | 99 | self.assertEqual(settings.get_int('Messages', 'MaxThreadCount'), |
|
99 |
len(Thread.objects. |
|
|
100 | len(Thread.objects.exclude(status=STATUS_ARCHIVE))) | |
|
100 | 101 | |
|
101 | 102 | def test_pages(self): |
|
102 | 103 | """Test that the thread list is properly split into pages""" |
@@ -104,9 +105,9 b' class PostTests(TestCase):' | |||
|
104 | 105 | for i in range(settings.get_int('Messages', 'MaxThreadCount')): |
|
105 | 106 | self._create_post() |
|
106 | 107 | |
|
107 |
all_threads = Thread.objects. |
|
|
108 | all_threads = Thread.objects.exclude(status=STATUS_ARCHIVE) | |
|
108 | 109 | |
|
109 |
paginator = Paginator(Thread.objects. |
|
|
110 | paginator = Paginator(Thread.objects.exclude(status=STATUS_ARCHIVE), | |
|
110 | 111 | settings.get_int('View', 'ThreadsPerPage')) |
|
111 | 112 | posts_in_second_page = paginator.page(2).object_list |
|
112 | 113 | first_post = posts_in_second_page[0] |
@@ -12,6 +12,7 b' from boards.abstracts.settingsmanager im' | |||
|
12 | 12 | |
|
13 | 13 | from boards.forms import PostForm, PlainErrorList |
|
14 | 14 | from boards.models import Post, Thread, Tag |
|
15 | from boards.models.thread import STATUS_ARCHIVE | |
|
15 | 16 | from boards.utils import datetime_to_epoch |
|
16 | 17 | from boards.views.thread import ThreadView |
|
17 | 18 | from boards.models.user import Notification |
@@ -136,9 +137,9 b' def api_get_threads(request, count):' | |||
|
136 | 137 | tag_name = request.GET[PARAMETER_TAG] |
|
137 | 138 | if tag_name is not None: |
|
138 | 139 | tag = get_object_or_404(Tag, name=tag_name) |
|
139 |
threads = tag.get_threads(). |
|
|
140 | threads = tag.get_threads().exclude(status=STATUS_ARCHIVE) | |
|
140 | 141 | else: |
|
141 |
threads = Thread.objects. |
|
|
142 | threads = Thread.objects.exclude(status=STATUS_ARCHIVE) | |
|
142 | 143 | |
|
143 | 144 | if PARAMETER_OFFSET in request.GET: |
|
144 | 145 | offset = request.GET[PARAMETER_OFFSET] |
@@ -155,8 +156,7 b' def api_get_threads(request, count):' | |||
|
155 | 156 | |
|
156 | 157 | # TODO Add tags, replies and images count |
|
157 | 158 | post_data = opening_post.get_post_data(include_last_update=True) |
|
158 |
post_data[' |
|
|
159 | post_data['archived'] = thread.archived | |
|
159 | post_data['status'] = thread.get_status() | |
|
160 | 160 | |
|
161 | 161 | opening_posts.append(post_data) |
|
162 | 162 |
@@ -97,7 +97,7 b' class ThreadView(BaseBoardView, PostMixi' | |||
|
97 | 97 | |
|
98 | 98 | return redirect('thread', post_id) # FIXME Different for different modes |
|
99 | 99 | |
|
100 | if not opening_post.get_thread().archived: | |
|
100 | if not opening_post.get_thread().is_archived(): | |
|
101 | 101 | form = PostForm(request.POST, request.FILES, |
|
102 | 102 | error_class=PlainErrorList) |
|
103 | 103 | form.session = request.session |
General Comments 0
You need to be logged in to leave comments.
Login now