##// END OF EJS Templates
Thread status field instead of bumpable and archived fields (per BB-73)
neko259 -
r1414:cbf56940 default
parent child Browse files
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', 'archived', 'ip',
59 list_display = ('id', 'op', 'title', 'reply_count', 'status', 'ip',
60 60 'display_tags')
61 list_filter = ('bump_time', 'archived', 'bumpable')
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, include_archived=False, tags=None):
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', 'bumpable'])
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', 'bumpable'])
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, archived=None, bumpable=None) -> int:
65 def get_thread_count(self, status=None) -> int:
65 66 threads = self.get_threads()
66 if archived is not None:
67 threads = threads.filter(archived=archived)
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(archived=False, bumpable=True)
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(archived=False, bumpable=False)
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(archived=True)
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, archived=False):
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 archived is not None:
113 posts = posts.filter(thread__archived=archived)
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.filter(archived=False).order_by('-bump_time')
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=['archived', 'last_edit_time', 'bumpable'])
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.filter(archived=False).order_by('-id')[:MAX_ITEMS]
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().filter(archived=False).order_by('-id')[:MAX_ITEMS]
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.filter(archived=False)))
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.filter(archived=False)
108 all_threads = Thread.objects.exclude(status=STATUS_ARCHIVE)
108 109
109 paginator = Paginator(Thread.objects.filter(archived=False),
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().filter(archived=False)
140 threads = tag.get_threads().exclude(status=STATUS_ARCHIVE)
140 141 else:
141 threads = Thread.objects.filter(archived=False)
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['bumpable'] = thread.can_bump()
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