diff --git a/boards/models.py b/boards/models.py --- a/boards/models.py +++ b/boards/models.py @@ -3,6 +3,7 @@ import re from django.db import models from django.utils import timezone import time +import math from neboard import settings from markupfield.fields import MarkupField @@ -23,6 +24,8 @@ def update_image_filename(instance, file class PostManager(models.Manager): + ALL_PAGES = -1 + def create_post(self, title, text, image=None, parent_id=NO_PARENT, ip=NO_IP, tags=None): post = self.create(title=title, @@ -56,13 +59,22 @@ class PostManager(models.Manager): for post in posts: self.delete_post(post) - def get_threads(self, tag=None): + def get_threads(self, tag=None, page=ALL_PAGES): if tag: threads = self.filter(parent=NO_PARENT, tags=tag) else: threads = self.filter(parent=NO_PARENT) threads = list(threads.order_by('-last_edit_time')) + if page != self.ALL_PAGES: + thread_count = len(threads) + + if page < self.get_thread_page_count(tag=tag): + start_thread = page * settings.THREADS_PER_PAGE + end_thread = min(start_thread + settings.THREADS_PER_PAGE, + thread_count) + threads = threads[start_thread:end_thread] + return threads def get_thread(self, opening_post_id): @@ -81,6 +93,15 @@ class PostManager(models.Manager): return len(posts) > 0 + def get_thread_page_count(self, tag=None): + if tag: + threads = self.filter(parent=NO_PARENT, tags=tag) + else: + threads = self.filter(parent=NO_PARENT) + + return int(math.ceil(len(threads) / float(settings.THREADS_PER_PAGE))) + + def _delete_old_threads(self): """ Preserves maximum thread count. If there are too many threads, @@ -106,8 +127,7 @@ class PostManager(models.Manager): def _bump_thread(self, thread_id): thread = self.get(id=thread_id) - replies_count = len(self.get_thread(thread_id)) - if replies_count <= settings.MAX_POSTS_PER_THREAD: + if thread.can_bump(): thread.last_edit_time = timezone.now() thread.save() @@ -162,6 +182,9 @@ class Post(models.Model): tags = models.ManyToManyField(Tag) last_edit_time = models.DateTimeField() + regex_pretty = re.compile(r'^\d(0)+$') + regex_same = re.compile(r'^(.)\1+$') + def __unicode__(self): return self.title + ' (' + self.text.raw + ')' @@ -192,12 +215,18 @@ class Post(models.Model): first = self.id == 1 - # TODO Compile regexes + id_str = str(self.id) + pretty = self.regex_pretty.match(id_str) + same_digits = self.regex_same.match(id_str) + + return first or pretty or same_digits - id_str = str(self.id) - pretty = re.match(r'^\d(0)+$', id_str) - same_digits = re.match(r'^(.)\1+$', id_str) - return first or pretty or same_digits + def can_bump(self): + """Check if the thread can be bumped by replying""" + + replies_count = len(Post.objects.get_thread(self.id)) + + return replies_count <= settings.MAX_POSTS_PER_THREAD class Admin(models.Model): diff --git a/boards/static/css/md/base_page.css b/boards/static/css/md/base_page.css --- a/boards/static/css/md/base_page.css +++ b/boards/static/css/md/base_page.css @@ -42,7 +42,7 @@ html { color: #fff380; } -.post { +.post, .dead_post{ background: #333; margin: 5px; padding: 10px; @@ -169,4 +169,8 @@ blockquote { * { text-decoration: none; +} + +.dead_post { + background-color: #442222; } \ No newline at end of file diff --git a/boards/tests.py b/boards/tests.py --- a/boards/tests.py +++ b/boards/tests.py @@ -107,4 +107,27 @@ class BoardTests(TestCase): self._create_post() self.assertEqual(settings.MAX_THREAD_COUNT, - len(Post.objects.get_threads())) \ No newline at end of file + len(Post.objects.get_threads())) + + def test_get(self): + """Test if the get computes properly""" + + post = self._create_post() + + self.assertTrue(post.is_get()) + + def test_pages(self): + """Test that the thread list is properly split into pages""" + + PAGE_NUMBER = 2 + + for i in range(settings.MAX_THREAD_COUNT): + self._create_post() + + all_threads = Post.objects.get_threads() + + posts_in_second_page = Post.objects.get_threads(page=1) + first_post = posts_in_second_page[0] + + self.assertEqual(all_threads[settings.THREADS_PER_PAGE].id, + first_post.id) \ No newline at end of file diff --git a/boards/urls.py b/boards/urls.py --- a/boards/urls.py +++ b/boards/urls.py @@ -4,16 +4,20 @@ from boards import views urlpatterns = patterns('', # /boards/ - url(r'^$', views.index, name = 'index'), + url(r'^$', views.index, name='index'), + # /boards/page/ + url(r'^page/(?P\w+)/$', views.index, name='index'), # login page url(r'^login$', views.login, name='login'), # logout page url(r'^logout$', views.logout, name='logout'), - # /boards/tag/ + # /boards/tag/tag_name/ url(r'^tag/(?P\w+)/$', views.tag, name='tag'), - # /boards/post_id/ + # /boards/tag/tag_id/page/ + url(r'^tag/(?P\w+)/page/(?P\w+)/$', views.tag, name='tag'), + # /boards/thread/ url(r'^thread/(?P\w+)/$', views.thread, name='thread'), # /boards/theme/theme_name/ url(r'^settings$', views.settings, name='settings'), diff --git a/boards/views.py b/boards/views.py --- a/boards/views.py +++ b/boards/views.py @@ -9,18 +9,20 @@ from django.http import HttpResponseRedi import neboard -def index(request): +def index(request, page=0): context = RequestContext(request) if request.method == 'POST': return new_post(request) else: - threads = Post.objects.get_threads() + threads = Post.objects.get_threads(page=int(page)) + # TODO Get rid of the duplicate code in index and tag views context['threads'] = None if len(threads) == 0 else threads context['form'] = forms.ThreadForm() context['tags'] = Tag.objects.get_not_empty_tags() context['theme'] = _get_theme(request) + context['pages'] = range(Post.objects.get_thread_page_count()) return render(request, 'posting_general.html', context) @@ -80,11 +82,11 @@ def new_post(request, thread_id=boards.m + str(post.id)) -def tag(request, tag_name): +def tag(request, tag_name, page=0): """Get all tag threads (posts without a parent).""" tag = Tag.objects.get(name=tag_name) - threads = Post.objects.get_threads(tag=tag) + threads = Post.objects.get_threads(tag=tag, page=int(page)) if request.method == 'POST': return new_post(request) @@ -94,6 +96,7 @@ def tag(request, tag_name): context['tag'] = tag_name context['tags'] = Tag.objects.get_not_empty_tags() context['theme'] = _get_theme(request) + context['pages'] = range(Post.objects.get_thread_page_count(tag=tag)) context['form'] = forms.ThreadForm(initial={'tags': tag_name}) diff --git a/neboard/settings.py b/neboard/settings.py --- a/neboard/settings.py +++ b/neboard/settings.py @@ -168,8 +168,9 @@ LOGGING = { } # Custom imageboard settings -MAX_POSTS_PER_THREAD = 500 # Thread bumplimit +MAX_POSTS_PER_THREAD = 10 # Thread bumplimit MAX_THREAD_COUNT = 20 # Old threads will be deleted to preserve this count +THREADS_PER_PAGE = 2 SITE_NAME = 'Neboard' THEMES = [ diff --git a/templates/posting_general.html b/templates/posting_general.html --- a/templates/posting_general.html +++ b/templates/posting_general.html @@ -11,7 +11,11 @@ {% if threads %} {% for thread in threads %} -
+ {% if thread.can_bump %} +
+ {% else %} +
+ {% endif %} {% if thread.image %}