##// END OF EJS Templates
Fixed bug with creating thread from tag view
Pavel Ryapolov -
r278:21d89568 default
parent child Browse files
Show More
@@ -1,448 +1,450 b''
1 1 import hashlib
2 2 import string
3 3 from django.core import serializers
4 4 from django.core.urlresolvers import reverse
5 5 from django.http import HttpResponseRedirect
6 6 from django.http.response import HttpResponse
7 7 from django.template import RequestContext
8 8 from django.shortcuts import render, redirect, get_object_or_404
9 9 from django.utils import timezone
10 10
11 11 from boards import forms
12 12 import boards
13 13 from boards import utils
14 14 from boards.forms import ThreadForm, PostForm, SettingsForm, PlainErrorList, \
15 15 ThreadCaptchaForm, PostCaptchaForm, LoginForm, ModeratorSettingsForm
16 16
17 17 from boards.models import Post, Tag, Ban, User, RANK_USER, SETTING_MODERATE
18 18 from boards import authors
19 19 from boards.utils import get_client_ip
20 20 import neboard
21 21
22 22
23 23 def index(request, page=0):
24 24 context = _init_default_context(request)
25 25
26 26 if utils.need_include_captcha(request):
27 27 threadFormClass = ThreadCaptchaForm
28 28 kwargs = {'request': request}
29 29 else:
30 30 threadFormClass = ThreadForm
31 31 kwargs = {}
32 32
33 33 if request.method == 'POST':
34 34 form = threadFormClass(request.POST, request.FILES,
35 35 error_class=PlainErrorList, **kwargs)
36 36 form.session = request.session
37 37
38 38 if form.is_valid():
39 39 return _new_post(request, form)
40 40 if form.need_to_ban:
41 41 # Ban user because he is suspected to be a bot
42 42 _ban_current_user(request)
43 43 else:
44 44 form = threadFormClass(error_class=PlainErrorList, **kwargs)
45 45
46 46 threads = []
47 47 for thread in Post.objects.get_threads(page=int(page)):
48 48 threads.append({'thread': thread,
49 49 'bumpable': thread.can_bump()})
50 50
51 51 context['threads'] = None if len(threads) == 0 else threads
52 52 context['form'] = form
53 53 context['pages'] = range(Post.objects.get_thread_page_count())
54 54
55 55 return render(request, 'boards/posting_general.html',
56 56 context)
57 57
58 58
59 59 def _new_post(request, form, thread_id=boards.models.NO_PARENT):
60 60 """Add a new post (in thread or as a reply)."""
61 61
62 62 ip = get_client_ip(request)
63 63 is_banned = Ban.objects.filter(ip=ip).exists()
64 64
65 65 if is_banned:
66 66 return redirect(you_are_banned)
67 67
68 68 data = form.cleaned_data
69 69
70 70 title = data['title']
71 71 text = data['text']
72 72
73 73 if 'image' in data.keys():
74 74 image = data['image']
75 75 else:
76 76 image = None
77 77
78 78 tags = []
79 79
80 80 new_thread = thread_id == boards.models.NO_PARENT
81 81 if new_thread:
82 82 tag_strings = data['tags']
83 83
84 84 if tag_strings:
85 85 tag_strings = tag_strings.split(' ')
86 86 for tag_name in tag_strings:
87 87 tag_name = string.lower(tag_name.strip())
88 88 if len(tag_name) > 0:
89 89 tag, created = Tag.objects.get_or_create(name=tag_name)
90 90 tags.append(tag)
91 91
92 92 op = None if thread_id == boards.models.NO_PARENT else \
93 93 get_object_or_404(Post, id=thread_id)
94 94 post = Post.objects.create_post(title=title, text=text, ip=ip,
95 95 thread=op, image=image,
96 96 tags=tags, user=_get_user(request))
97 97
98 98 thread_to_show = (post.id if new_thread else thread_id)
99 99
100 100 if new_thread:
101 101 return redirect(thread, post_id=thread_to_show)
102 102 else:
103 103 return redirect(reverse(thread, kwargs={'post_id': thread_to_show}) +
104 104 '#' + str(post.id))
105 105
106 106
107 107 def tag(request, tag_name, page=0):
108 108 """
109 109 Get all tag threads. Threads are split in pages, so some page is
110 110 requested. Default page is 0.
111 111 """
112 112
113 113 tag = get_object_or_404(Tag, name=tag_name)
114 114 threads = []
115 115 for thread in Post.objects.get_threads(tag=tag, page=int(page)):
116 116 threads.append({'thread': thread,
117 117 'bumpable': thread.can_bump()})
118 118
119 119 if request.method == 'POST':
120 120 form = ThreadForm(request.POST, request.FILES,
121 121 error_class=PlainErrorList)
122 form.session = request.session
123
122 124 if form.is_valid():
123 125 return _new_post(request, form)
124 126 if form.need_to_ban:
125 127 # Ban user because he is suspected to be a bot
126 128 _ban_current_user(request)
127 129 else:
128 130 form = forms.ThreadForm(initial={'tags': tag_name},
129 131 error_class=PlainErrorList)
130 132
131 133 context = _init_default_context(request)
132 134 context['threads'] = None if len(threads) == 0 else threads
133 135 context['tag'] = tag
134 136 context['pages'] = range(Post.objects.get_thread_page_count(tag=tag))
135 137
136 138 context['form'] = form
137 139
138 140 return render(request, 'boards/posting_general.html',
139 141 context)
140 142
141 143
142 144 def thread(request, post_id):
143 145 """Get all thread posts"""
144 146
145 147 if utils.need_include_captcha(request):
146 148 postFormClass = PostCaptchaForm
147 149 kwargs = {'request': request}
148 150 else:
149 151 postFormClass = PostForm
150 152 kwargs = {}
151 153
152 154 if request.method == 'POST':
153 155 form = postFormClass(request.POST, request.FILES,
154 156 error_class=PlainErrorList, **kwargs)
155 157 form.session = request.session
156 158
157 159 if form.is_valid():
158 160 return _new_post(request, form, post_id)
159 161 if form.need_to_ban:
160 162 # Ban user because he is suspected to be a bot
161 163 _ban_current_user(request)
162 164 else:
163 165 form = postFormClass(error_class=PlainErrorList, **kwargs)
164 166
165 167 posts = Post.objects.get_thread(post_id)
166 168
167 169 context = _init_default_context(request)
168 170
169 171 context['posts'] = posts
170 172 context['form'] = form
171 173 context['bumpable'] = posts[0].can_bump()
172 174
173 175 return render(request, 'boards/thread.html', context)
174 176
175 177
176 178 def login(request):
177 179 """Log in with user id"""
178 180
179 181 context = _init_default_context(request)
180 182
181 183 if request.method == 'POST':
182 184 form = LoginForm(request.POST, request.FILES,
183 185 error_class=PlainErrorList)
184 186 form.session = request.session
185 187
186 188 if form.is_valid():
187 189 user = User.objects.get(user_id=form.cleaned_data['user_id'])
188 190 request.session['user_id'] = user.id
189 191 return redirect(index)
190 192
191 193 else:
192 194 form = LoginForm()
193 195
194 196 context['form'] = form
195 197
196 198 return render(request, 'boards/login.html', context)
197 199
198 200
199 201 def settings(request):
200 202 """User's settings"""
201 203
202 204 context = _init_default_context(request)
203 205 user = _get_user(request)
204 206 is_moderator = user.is_moderator()
205 207
206 208 if request.method == 'POST':
207 209 if is_moderator:
208 210 form = ModeratorSettingsForm(request.POST,
209 211 error_class=PlainErrorList)
210 212 else:
211 213 form = SettingsForm(request.POST, error_class=PlainErrorList)
212 214
213 215 if form.is_valid():
214 216 selected_theme = form.cleaned_data['theme']
215 217
216 218 user.save_setting('theme', selected_theme)
217 219
218 220 if is_moderator:
219 221 moderate = form.cleaned_data['moderate']
220 222 user.save_setting(SETTING_MODERATE, moderate)
221 223
222 224 return redirect(settings)
223 225 else:
224 226 selected_theme = _get_theme(request)
225 227
226 228 if is_moderator:
227 229 form = ModeratorSettingsForm(initial={'theme': selected_theme,
228 230 'moderate': context['moderator']},
229 231 error_class=PlainErrorList)
230 232 else:
231 233 form = SettingsForm(initial={'theme': selected_theme},
232 234 error_class=PlainErrorList)
233 235
234 236 context['form'] = form
235 237
236 238 return render(request, 'boards/settings.html', context)
237 239
238 240
239 241 def all_tags(request):
240 242 """All tags list"""
241 243
242 244 context = _init_default_context(request)
243 245 context['all_tags'] = Tag.objects.get_not_empty_tags()
244 246
245 247 return render(request, 'boards/tags.html', context)
246 248
247 249
248 250 def jump_to_post(request, post_id):
249 251 """Determine thread in which the requested post is and open it's page"""
250 252
251 253 post = get_object_or_404(Post, id=post_id)
252 254
253 255 if not post.thread:
254 256 return redirect(thread, post_id=post.id)
255 257 else:
256 258 return redirect(reverse(thread, kwargs={'post_id': post.thread.id})
257 259 + '#' + str(post.id))
258 260
259 261
260 262 def authors(request):
261 263 """Show authors list"""
262 264
263 265 context = _init_default_context(request)
264 266 context['authors'] = boards.authors.authors
265 267
266 268 return render(request, 'boards/authors.html', context)
267 269
268 270
269 271 def delete(request, post_id):
270 272 """Delete post"""
271 273
272 274 user = _get_user(request)
273 275 post = get_object_or_404(Post, id=post_id)
274 276
275 277 if user.is_moderator():
276 278 # TODO Show confirmation page before deletion
277 279 Post.objects.delete_post(post)
278 280
279 281 if not post.thread:
280 282 return _redirect_to_next(request)
281 283 else:
282 284 return redirect(thread, post_id=post.thread.id)
283 285
284 286
285 287 def ban(request, post_id):
286 288 """Ban user"""
287 289
288 290 user = _get_user(request)
289 291 post = get_object_or_404(Post, id=post_id)
290 292
291 293 if user.is_moderator():
292 294 # TODO Show confirmation page before ban
293 295 Ban.objects.get_or_create(ip=post.poster_ip)
294 296
295 297 return _redirect_to_next(request)
296 298
297 299
298 300 def you_are_banned(request):
299 301 """Show the page that notifies that user is banned"""
300 302
301 303 context = _init_default_context(request)
302 304 return render(request, 'boards/staticpages/banned.html', context)
303 305
304 306
305 307 def page_404(request):
306 308 """Show page 404 (not found error)"""
307 309
308 310 context = _init_default_context(request)
309 311 return render(request, 'boards/404.html', context)
310 312
311 313
312 314 def tag_subscribe(request, tag_name):
313 315 """Add tag to favorites"""
314 316
315 317 user = _get_user(request)
316 318 tag = get_object_or_404(Tag, name=tag_name)
317 319
318 320 if not tag in user.fav_tags.all():
319 321 user.fav_tags.add(tag)
320 322
321 323 return _redirect_to_next(request)
322 324
323 325
324 326 def tag_unsubscribe(request, tag_name):
325 327 """Remove tag from favorites"""
326 328
327 329 user = _get_user(request)
328 330 tag = get_object_or_404(Tag, name=tag_name)
329 331
330 332 if tag in user.fav_tags.all():
331 333 user.fav_tags.remove(tag)
332 334
333 335 return _redirect_to_next(request)
334 336
335 337
336 338 def static_page(request, name):
337 339 """Show a static page that needs only tags list and a CSS"""
338 340
339 341 context = _init_default_context(request)
340 342 return render(request, 'boards/staticpages/' + name + '.html', context)
341 343
342 344
343 345 def api_get_post(request, post_id):
344 346 """
345 347 Get the JSON of a post. This can be
346 348 used as and API for external clients.
347 349 """
348 350
349 351 post = get_object_or_404(Post, id=post_id)
350 352
351 353 json = serializers.serialize("json", [post], fields=(
352 354 "pub_time", "_text_rendered", "title", "text", "image",
353 355 "image_width", "image_height", "replies", "tags"
354 356 ))
355 357
356 358 return HttpResponse(content=json)
357 359
358 360
359 361 def get_post(request, post_id):
360 362 """Get the html of a post. Used for popups."""
361 363
362 364 post = get_object_or_404(Post, id=post_id)
363 365
364 366 context = RequestContext(request)
365 367 context["post"] = post
366 368
367 369 return render(request, 'boards/post.html', context)
368 370
369 371
370 372 def _get_theme(request, user=None):
371 373 """Get user's CSS theme"""
372 374
373 375 if not user:
374 376 user = _get_user(request)
375 377 theme = user.get_setting('theme')
376 378 if not theme:
377 379 theme = neboard.settings.DEFAULT_THEME
378 380
379 381 return theme
380 382
381 383
382 384 def _init_default_context(request):
383 385 """Create context with default values that are used in most views"""
384 386
385 387 context = RequestContext(request)
386 388
387 389 user = _get_user(request)
388 390 context['user'] = user
389 391 context['tags'] = user.get_sorted_fav_tags()
390 392
391 393 theme = _get_theme(request, user)
392 394 context['theme'] = theme
393 395 context['theme_css'] = 'css/' + theme + '/base_page.css'
394 396
395 397 # This shows the moderator panel
396 398 moderate = user.get_setting(SETTING_MODERATE)
397 399 if moderate == 'True':
398 400 context['moderator'] = user.is_moderator()
399 401 else:
400 402 context['moderator'] = False
401 403
402 404 return context
403 405
404 406
405 407 def _get_user(request):
406 408 """
407 409 Get current user from the session. If the user does not exist, create
408 410 a new one.
409 411 """
410 412
411 413 session = request.session
412 414 if not 'user_id' in session:
413 415 request.session.save()
414 416
415 417 md5 = hashlib.md5()
416 418 md5.update(session.session_key)
417 419 new_id = md5.hexdigest()
418 420
419 421 time_now = timezone.now()
420 422 user = User.objects.create(user_id=new_id, rank=RANK_USER,
421 423 registration_time=time_now)
422 424
423 425 session['user_id'] = user.id
424 426 else:
425 427 user = User.objects.get(id=session['user_id'])
426 428
427 429 return user
428 430
429 431
430 432 def _redirect_to_next(request):
431 433 """
432 434 If a 'next' parameter was specified, redirect to the next page. This is
433 435 used when the user is required to return to some page after the current
434 436 view has finished its work.
435 437 """
436 438
437 439 if 'next' in request.GET:
438 440 next_page = request.GET['next']
439 441 return HttpResponseRedirect(next_page)
440 442 else:
441 443 return redirect(index)
442 444
443 445
444 446 def _ban_current_user(request):
445 447 """Add current user to the IP ban list"""
446 448
447 449 ip = utils.get_client_ip(request)
448 450 Ban.objects.get_or_create(ip=ip)
@@ -1,13 +1,13 b''
1 1 = Features =
2 2 [NOT STARTED] Connecting tags to each other
3 3 [NOT STARTED] Tree view (JS)
4 4 [NOT STARTED] Adding tags to images filename
5 5 [NOT STARTED] Federative network for s2s communication
6 6 [NOT STARTED] XMPP gate
7 7 [NOT STARTED] Bitmessage gate
8 8 [NOT STARTED] Notification engine
9 9 [NOT STARTED] Javascript disabling engine
10 10 [NOT STARTED] Thread autoupdate (JS + API)
11 11
12 12 = Bugs =
13 [NOT STARTED] Fix bug with creating threads from tag view
13 [DONE] Fix bug with creating threads from tag view
General Comments 0
You need to be logged in to leave comments. Login now