##// END OF EJS Templates
Compiling regexes for gets. #17 Added pagination. #28 Visually differing the dead (not bumpable) threads.
neko259 -
r46:384df4e1 default
parent child Browse files
Show More
@@ -3,6 +3,7 b' import re'
3 from django.db import models
3 from django.db import models
4 from django.utils import timezone
4 from django.utils import timezone
5 import time
5 import time
6 import math
6
7
7 from neboard import settings
8 from neboard import settings
8 from markupfield.fields import MarkupField
9 from markupfield.fields import MarkupField
@@ -23,6 +24,8 b' def update_image_filename(instance, file'
23
24
24
25
25 class PostManager(models.Manager):
26 class PostManager(models.Manager):
27 ALL_PAGES = -1
28
26 def create_post(self, title, text, image=None, parent_id=NO_PARENT,
29 def create_post(self, title, text, image=None, parent_id=NO_PARENT,
27 ip=NO_IP, tags=None):
30 ip=NO_IP, tags=None):
28 post = self.create(title=title,
31 post = self.create(title=title,
@@ -56,13 +59,22 b' class PostManager(models.Manager):'
56 for post in posts:
59 for post in posts:
57 self.delete_post(post)
60 self.delete_post(post)
58
61
59 def get_threads(self, tag=None):
62 def get_threads(self, tag=None, page=ALL_PAGES):
60 if tag:
63 if tag:
61 threads = self.filter(parent=NO_PARENT, tags=tag)
64 threads = self.filter(parent=NO_PARENT, tags=tag)
62 else:
65 else:
63 threads = self.filter(parent=NO_PARENT)
66 threads = self.filter(parent=NO_PARENT)
64 threads = list(threads.order_by('-last_edit_time'))
67 threads = list(threads.order_by('-last_edit_time'))
65
68
69 if page != self.ALL_PAGES:
70 thread_count = len(threads)
71
72 if page < self.get_thread_page_count(tag=tag):
73 start_thread = page * settings.THREADS_PER_PAGE
74 end_thread = min(start_thread + settings.THREADS_PER_PAGE,
75 thread_count)
76 threads = threads[start_thread:end_thread]
77
66 return threads
78 return threads
67
79
68 def get_thread(self, opening_post_id):
80 def get_thread(self, opening_post_id):
@@ -81,6 +93,15 b' class PostManager(models.Manager):'
81
93
82 return len(posts) > 0
94 return len(posts) > 0
83
95
96 def get_thread_page_count(self, tag=None):
97 if tag:
98 threads = self.filter(parent=NO_PARENT, tags=tag)
99 else:
100 threads = self.filter(parent=NO_PARENT)
101
102 return int(math.ceil(len(threads) / float(settings.THREADS_PER_PAGE)))
103
104
84 def _delete_old_threads(self):
105 def _delete_old_threads(self):
85 """
106 """
86 Preserves maximum thread count. If there are too many threads,
107 Preserves maximum thread count. If there are too many threads,
@@ -106,8 +127,7 b' class PostManager(models.Manager):'
106 def _bump_thread(self, thread_id):
127 def _bump_thread(self, thread_id):
107 thread = self.get(id=thread_id)
128 thread = self.get(id=thread_id)
108
129
109 replies_count = len(self.get_thread(thread_id))
130 if thread.can_bump():
110 if replies_count <= settings.MAX_POSTS_PER_THREAD:
111 thread.last_edit_time = timezone.now()
131 thread.last_edit_time = timezone.now()
112 thread.save()
132 thread.save()
113
133
@@ -162,6 +182,9 b' class Post(models.Model):'
162 tags = models.ManyToManyField(Tag)
182 tags = models.ManyToManyField(Tag)
163 last_edit_time = models.DateTimeField()
183 last_edit_time = models.DateTimeField()
164
184
185 regex_pretty = re.compile(r'^\d(0)+$')
186 regex_same = re.compile(r'^(.)\1+$')
187
165 def __unicode__(self):
188 def __unicode__(self):
166 return self.title + ' (' + self.text.raw + ')'
189 return self.title + ' (' + self.text.raw + ')'
167
190
@@ -192,12 +215,18 b' class Post(models.Model):'
192
215
193 first = self.id == 1
216 first = self.id == 1
194
217
195 # TODO Compile regexes
218 id_str = str(self.id)
219 pretty = self.regex_pretty.match(id_str)
220 same_digits = self.regex_same.match(id_str)
221
222 return first or pretty or same_digits
196
223
197 id_str = str(self.id)
224 def can_bump(self):
198 pretty = re.match(r'^\d(0)+$', id_str)
225 """Check if the thread can be bumped by replying"""
199 same_digits = re.match(r'^(.)\1+$', id_str)
226
200 return first or pretty or same_digits
227 replies_count = len(Post.objects.get_thread(self.id))
228
229 return replies_count <= settings.MAX_POSTS_PER_THREAD
201
230
202
231
203 class Admin(models.Model):
232 class Admin(models.Model):
@@ -42,7 +42,7 b' html {'
42 color: #fff380;
42 color: #fff380;
43 }
43 }
44
44
45 .post {
45 .post, .dead_post{
46 background: #333;
46 background: #333;
47 margin: 5px;
47 margin: 5px;
48 padding: 10px;
48 padding: 10px;
@@ -169,4 +169,8 b' blockquote {'
169
169
170 * {
170 * {
171 text-decoration: none;
171 text-decoration: none;
172 }
173
174 .dead_post {
175 background-color: #442222;
172 } No newline at end of file
176 }
@@ -107,4 +107,27 b' class BoardTests(TestCase):'
107 self._create_post()
107 self._create_post()
108
108
109 self.assertEqual(settings.MAX_THREAD_COUNT,
109 self.assertEqual(settings.MAX_THREAD_COUNT,
110 len(Post.objects.get_threads())) No newline at end of file
110 len(Post.objects.get_threads()))
111
112 def test_get(self):
113 """Test if the get computes properly"""
114
115 post = self._create_post()
116
117 self.assertTrue(post.is_get())
118
119 def test_pages(self):
120 """Test that the thread list is properly split into pages"""
121
122 PAGE_NUMBER = 2
123
124 for i in range(settings.MAX_THREAD_COUNT):
125 self._create_post()
126
127 all_threads = Post.objects.get_threads()
128
129 posts_in_second_page = Post.objects.get_threads(page=1)
130 first_post = posts_in_second_page[0]
131
132 self.assertEqual(all_threads[settings.THREADS_PER_PAGE].id,
133 first_post.id) No newline at end of file
@@ -4,16 +4,20 b' from boards import views'
4 urlpatterns = patterns('',
4 urlpatterns = patterns('',
5
5
6 # /boards/
6 # /boards/
7 url(r'^$', views.index, name = 'index'),
7 url(r'^$', views.index, name='index'),
8 # /boards/page/
9 url(r'^page/(?P<page>\w+)/$', views.index, name='index'),
8
10
9 # login page
11 # login page
10 url(r'^login$', views.login, name='login'),
12 url(r'^login$', views.login, name='login'),
11 # logout page
13 # logout page
12 url(r'^logout$', views.logout, name='logout'),
14 url(r'^logout$', views.logout, name='logout'),
13
15
14 # /boards/tag/
16 # /boards/tag/tag_name/
15 url(r'^tag/(?P<tag_name>\w+)/$', views.tag, name='tag'),
17 url(r'^tag/(?P<tag_name>\w+)/$', views.tag, name='tag'),
16 # /boards/post_id/
18 # /boards/tag/tag_id/page/
19 url(r'^tag/(?P<tag_name>\w+)/page/(?P<page>\w+)/$', views.tag, name='tag'),
20 # /boards/thread/
17 url(r'^thread/(?P<post_id>\w+)/$', views.thread, name='thread'),
21 url(r'^thread/(?P<post_id>\w+)/$', views.thread, name='thread'),
18 # /boards/theme/theme_name/
22 # /boards/theme/theme_name/
19 url(r'^settings$', views.settings, name='settings'),
23 url(r'^settings$', views.settings, name='settings'),
@@ -9,18 +9,20 b' from django.http import HttpResponseRedi'
9 import neboard
9 import neboard
10
10
11
11
12 def index(request):
12 def index(request, page=0):
13 context = RequestContext(request)
13 context = RequestContext(request)
14
14
15 if request.method == 'POST':
15 if request.method == 'POST':
16 return new_post(request)
16 return new_post(request)
17 else:
17 else:
18 threads = Post.objects.get_threads()
18 threads = Post.objects.get_threads(page=int(page))
19
19
20 # TODO Get rid of the duplicate code in index and tag views
20 context['threads'] = None if len(threads) == 0 else threads
21 context['threads'] = None if len(threads) == 0 else threads
21 context['form'] = forms.ThreadForm()
22 context['form'] = forms.ThreadForm()
22 context['tags'] = Tag.objects.get_not_empty_tags()
23 context['tags'] = Tag.objects.get_not_empty_tags()
23 context['theme'] = _get_theme(request)
24 context['theme'] = _get_theme(request)
25 context['pages'] = range(Post.objects.get_thread_page_count())
24
26
25 return render(request, 'posting_general.html',
27 return render(request, 'posting_general.html',
26 context)
28 context)
@@ -80,11 +82,11 b' def new_post(request, thread_id=boards.m'
80 + str(post.id))
82 + str(post.id))
81
83
82
84
83 def tag(request, tag_name):
85 def tag(request, tag_name, page=0):
84 """Get all tag threads (posts without a parent)."""
86 """Get all tag threads (posts without a parent)."""
85
87
86 tag = Tag.objects.get(name=tag_name)
88 tag = Tag.objects.get(name=tag_name)
87 threads = Post.objects.get_threads(tag=tag)
89 threads = Post.objects.get_threads(tag=tag, page=int(page))
88
90
89 if request.method == 'POST':
91 if request.method == 'POST':
90 return new_post(request)
92 return new_post(request)
@@ -94,6 +96,7 b' def tag(request, tag_name):'
94 context['tag'] = tag_name
96 context['tag'] = tag_name
95 context['tags'] = Tag.objects.get_not_empty_tags()
97 context['tags'] = Tag.objects.get_not_empty_tags()
96 context['theme'] = _get_theme(request)
98 context['theme'] = _get_theme(request)
99 context['pages'] = range(Post.objects.get_thread_page_count(tag=tag))
97
100
98 context['form'] = forms.ThreadForm(initial={'tags': tag_name})
101 context['form'] = forms.ThreadForm(initial={'tags': tag_name})
99
102
@@ -168,8 +168,9 b' LOGGING = {'
168 }
168 }
169
169
170 # Custom imageboard settings
170 # Custom imageboard settings
171 MAX_POSTS_PER_THREAD = 500 # Thread bumplimit
171 MAX_POSTS_PER_THREAD = 10 # Thread bumplimit
172 MAX_THREAD_COUNT = 20 # Old threads will be deleted to preserve this count
172 MAX_THREAD_COUNT = 20 # Old threads will be deleted to preserve this count
173 THREADS_PER_PAGE = 2
173 SITE_NAME = 'Neboard'
174 SITE_NAME = 'Neboard'
174
175
175 THEMES = [
176 THEMES = [
@@ -11,7 +11,11 b''
11
11
12 {% if threads %}
12 {% if threads %}
13 {% for thread in threads %}
13 {% for thread in threads %}
14 <div class="post">
14 {% if thread.can_bump %}
15 <div class="post">
16 {% else %}
17 <div class="dead_post">
18 {% endif %}
15 {% if thread.image %}
19 {% if thread.image %}
16 <div class="image">
20 <div class="image">
17 <a href="{{ thread.image.url }}"><img
21 <a href="{{ thread.image.url }}"><img
@@ -87,7 +91,17 b''
87 {% block metapanel %}
91 {% block metapanel %}
88
92
89 <span class="metapanel">
93 <span class="metapanel">
90 Neboard 2013-05 (dev)
94 <b>Neboard 2013-05 (dev)</b>
95 {% trans "Pages:" %}
96 {% for page in pages %}
97 [<a href="
98 {% if tag %}
99 {% url "tag" tag_name=tag page=page %}
100 {% else %}
101 {% url "index" page=page %}
102 {% endif %}
103 ">{{ page }}</a>]
104 {% endfor %}
91 </span>
105 </span>
92
106
93 {% endblock %} No newline at end of file
107 {% endblock %}
General Comments 0
You need to be logged in to leave comments. Login now