##// END OF EJS Templates
Fixed unicode tags validation. Moved constants from classes to modules. Added error 404 when trying to get the non-existent thread. This fixes #19
neko259 -
r71:e89d805e default
parent child Browse files
Show More
@@ -39,7 +39,7 b' class PostForm(forms.Form):'
39
39
40
40
41 class ThreadForm(PostForm):
41 class ThreadForm(PostForm):
42 regex_tags = re.compile(r'^[\w\s]+$')
42 regex_tags = re.compile(ur'^[\w\s\d]+$', re.UNICODE)
43
43
44 tags = forms.CharField(max_length=100)
44 tags = forms.CharField(max_length=100)
45
45
@@ -1,27 +1,31 b''
1 import os
1 import os
2 from random import random
2 from random import random
3 import re
3 import re
4 from django.db import models
5 from django.utils import timezone
6 import time
4 import time
7 import math
5 import math
8 import markdown
6
9 from markdown.inlinepatterns import Pattern
7 from django.db import models
10 from markdown.util import etree
8 from django.http import Http404
9 from django.utils import timezone
10 from markupfield.fields import MarkupField
11
11
12 from neboard import settings
12 from neboard import settings
13 from markupfield.fields import MarkupField
13 import thumbs
14
14
15 import thumbs
16
15
17 NO_PARENT = -1
16 NO_PARENT = -1
18 NO_IP = '0.0.0.0'
17 NO_IP = '0.0.0.0'
19 UNKNOWN_UA = ''
18 UNKNOWN_UA = ''
19 ALL_PAGES = -1
20 OPENING_POST_WEIGHT = 5
21 IMAGES_DIRECTORY = 'images/'
22 FILE_EXTENSION_DELIMITER = '.'
23
24 REGEX_PRETTY = re.compile(r'^\d(0)+$')
25 REGEX_SAME = re.compile(r'^(.)\1+$')
20
26
21
27
22 class PostManager(models.Manager):
28 class PostManager(models.Manager):
23 ALL_PAGES = -1
24
25 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,
26 ip=NO_IP, tags=None):
30 ip=NO_IP, tags=None):
27 post = self.create(title=title,
31 post = self.create(title=title,
@@ -62,7 +66,7 b' class PostManager(models.Manager):'
62 threads = self.filter(parent=NO_PARENT)
66 threads = self.filter(parent=NO_PARENT)
63 threads = threads.order_by('-last_edit_time')
67 threads = threads.order_by('-last_edit_time')
64
68
65 if page != self.ALL_PAGES:
69 if page != ALL_PAGES:
66 thread_count = len(threads)
70 thread_count = len(threads)
67
71
68 if page < self.get_thread_page_count(tag=tag):
72 if page < self.get_thread_page_count(tag=tag):
@@ -76,6 +80,9 b' class PostManager(models.Manager):'
76 def get_thread(self, opening_post_id):
80 def get_thread(self, opening_post_id):
77 opening_post = self.get(id=opening_post_id)
81 opening_post = self.get(id=opening_post_id)
78
82
83 if not opening_post:
84 raise Http404
85
79 if opening_post.parent == NO_PARENT:
86 if opening_post.parent == NO_PARENT:
80 replies = self.filter(parent=opening_post_id)
87 replies = self.filter(parent=opening_post_id)
81
88
@@ -151,8 +158,6 b' class Tag(models.Model):'
151 section. There can be multiple tags for each message
158 section. There can be multiple tags for each message
152 """
159 """
153
160
154 OPENING_POST_WEIGHT = 5
155
156 objects = TagManager()
161 objects = TagManager()
157
162
158 name = models.CharField(max_length=100)
163 name = models.CharField(max_length=100)
@@ -182,19 +187,16 b' class Tag(models.Model):'
182 class Post(models.Model):
187 class Post(models.Model):
183 """A post is a message."""
188 """A post is a message."""
184
189
185 IMAGES_DIRECTORY = 'images/'
186 FILE_EXTENSION_DELIMITER = '.'
187
188 objects = PostManager()
190 objects = PostManager()
189
191
190 def _update_image_filename(self, filename):
192 def _update_image_filename(self, filename):
191 """Get unique image filename"""
193 """Get unique image filename"""
192
194
193 path = self.IMAGES_DIRECTORY
195 path = IMAGES_DIRECTORY
194 new_name = str(int(time.mktime(time.gmtime())))
196 new_name = str(int(time.mktime(time.gmtime())))
195 new_name += str(int(random() * 1000))
197 new_name += str(int(random() * 1000))
196 new_name += self.FILE_EXTENSION_DELIMITER
198 new_name += FILE_EXTENSION_DELIMITER
197 new_name += filename.split(self.FILE_EXTENSION_DELIMITER)[-1:][0]
199 new_name += filename.split(FILE_EXTENSION_DELIMITER)[-1:][0]
198
200
199 return os.path.join(path, new_name)
201 return os.path.join(path, new_name)
200
202
@@ -209,9 +211,6 b' class Post(models.Model):'
209 tags = models.ManyToManyField(Tag)
211 tags = models.ManyToManyField(Tag)
210 last_edit_time = models.DateTimeField()
212 last_edit_time = models.DateTimeField()
211
213
212 regex_pretty = re.compile(r'^\d(0)+$')
213 regex_same = re.compile(r'^(.)\1+$')
214
215 def __unicode__(self):
214 def __unicode__(self):
216 return self.title + ' (' + self.text.raw + ')'
215 return self.title + ' (' + self.text.raw + ')'
217
216
@@ -243,8 +242,8 b' class Post(models.Model):'
243 first = self.id == 1
242 first = self.id == 1
244
243
245 id_str = str(self.id)
244 id_str = str(self.id)
246 pretty = self.regex_pretty.match(id_str)
245 pretty = REGEX_PRETTY.match(id_str)
247 same_digits = self.regex_same.match(id_str)
246 same_digits = REGEX_SAME.match(id_str)
248
247
249 return first or pretty or same_digits
248 return first or pretty or same_digits
250
249
@@ -1,3 +1,4 b''
1 # coding=utf-8
1 from django.utils.unittest import TestCase
2 from django.utils.unittest import TestCase
2 from django.test.client import Client
3 from django.test.client import Client
3
4
@@ -6,6 +7,11 b' import boards'
6 from boards.models import Post, Admin, Tag
7 from boards.models import Post, Admin, Tag
7 from neboard import settings
8 from neboard import settings
8
9
10 TEST_TEXT = 'test text'
11
12 NEW_THREAD_PAGE = '/'
13 HTTP_CODE_REDIRECT = 302
14
9
15
10 class BoardTests(TestCase):
16 class BoardTests(TestCase):
11 def _create_post(self):
17 def _create_post(self):
@@ -119,8 +125,6 b' class BoardTests(TestCase):'
119 def test_pages(self):
125 def test_pages(self):
120 """Test that the thread list is properly split into pages"""
126 """Test that the thread list is properly split into pages"""
121
127
122 PAGE_NUMBER = 2
123
124 for i in range(settings.MAX_THREAD_COUNT):
128 for i in range(settings.MAX_THREAD_COUNT):
125 self._create_post()
129 self._create_post()
126
130
@@ -130,4 +134,29 b' class BoardTests(TestCase):'
130 first_post = posts_in_second_page[0]
134 first_post = posts_in_second_page[0]
131
135
132 self.assertEqual(all_threads[settings.THREADS_PER_PAGE].id,
136 self.assertEqual(all_threads[settings.THREADS_PER_PAGE].id,
133 first_post.id) No newline at end of file
137 first_post.id)
138
139 def test_post_validation(self):
140 """Test the validation of the post form"""
141
142 Post.objects.all().delete()
143
144 client = Client()
145
146 valid_tags = u'tag1 tag_2 тег_3'
147 invalid_tags = u'$%_356 ---'
148
149 response = client.post(NEW_THREAD_PAGE, {'title': 'test title',
150 'text': TEST_TEXT,
151 'tags': valid_tags})
152 self.assertEqual(response.status_code, HTTP_CODE_REDIRECT,
153 msg='Posting new message failed: got code ' +
154 str(response.status_code))
155
156 self.assertEqual(1, Post.objects.count(),
157 msg='No posts were created')
158
159 response = client.post(NEW_THREAD_PAGE, {'text': TEST_TEXT,
160 'tags': invalid_tags})
161 self.assertEqual(1, Post.objects.count(), msg='The validation passed '
162 'where it should fail') No newline at end of file
@@ -110,7 +110,6 b' def thread(request, post_id):'
110 if request.method == 'POST':
110 if request.method == 'POST':
111 return new_post(request, post_id)
111 return new_post(request, post_id)
112 else:
112 else:
113 # TODO Show 404 if there is no such thread
114 posts = Post.objects.get_thread(post_id)
113 posts = Post.objects.get_thread(post_id)
115
114
116 context = RequestContext(request)
115 context = RequestContext(request)
General Comments 0
You need to be logged in to leave comments. Login now