views.py
358 lines
| 9.9 KiB
| text/x-python
|
PythonLexer
/ boards / views.py
|
r110 | import hashlib | ||
|
r41 | from django.core.urlresolvers import reverse | ||
|
r155 | from django.http import HttpResponseRedirect | ||
|
r9 | from django.template import RequestContext | ||
|
r79 | from django.shortcuts import render, redirect, get_object_or_404 | ||
|
r121 | from django.utils import timezone | ||
|
r76 | |||
|
r14 | from boards import forms | ||
|
r20 | import boards | ||
|
r78 | from boards import utils | ||
from boards.forms import ThreadForm, PostForm, SettingsForm, PlainErrorList, \ | ||||
|
r144 | ThreadCaptchaForm, PostCaptchaForm, LoginForm | ||
|
r78 | |||
|
r147 | from boards.models import Post, Tag, Ban, User, RANK_USER, NO_PARENT | ||
|
r103 | from boards import authors | ||
|
r35 | import neboard | ||
|
r0 | |||
|
r22 | |||
|
r46 | def index(request, page=0): | ||
|
r101 | context = _init_default_context(request) | ||
|
r14 | |||
|
r95 | if utils.need_include_captcha(request): | ||
threadFormClass = ThreadCaptchaForm | ||||
kwargs = {'request': request} | ||||
else: | ||||
threadFormClass = ThreadForm | ||||
kwargs = {} | ||||
|
r78 | |||
|
r14 | if request.method == 'POST': | ||
|
r78 | form = threadFormClass(request.POST, request.FILES, | ||
|
r95 | error_class=PlainErrorList, **kwargs) | ||
|
r153 | form.session = request.session | ||
|
r78 | |||
|
r76 | if form.is_valid(): | ||
return _new_post(request, form) | ||||
|
r20 | else: | ||
|
r95 | form = threadFormClass(error_class=PlainErrorList, **kwargs) | ||
|
r76 | |||
|
r163 | threads = [] | ||
for thread in Post.objects.get_threads(page=int(page)): | ||||
threads.append({'thread': thread, | ||||
'bumpable': thread.can_bump()}) | ||||
|
r18 | |||
|
r76 | context['threads'] = None if len(threads) == 0 else threads | ||
context['form'] = form | ||||
context['pages'] = range(Post.objects.get_thread_page_count()) | ||||
|
r9 | |||
|
r84 | return render(request, 'boards/posting_general.html', | ||
|
r76 | context) | ||
|
r18 | |||
|
r14 | |||
|
r76 | def _new_post(request, form, thread_id=boards.models.NO_PARENT): | ||
|
r4 | """Add a new post (in thread or as a reply).""" | ||
|
r116 | ip = _get_client_ip(request) | ||
is_banned = Ban.objects.filter(ip=ip).count() > 0 | ||||
if is_banned: | ||||
return redirect(you_are_banned) | ||||
|
r76 | data = form.cleaned_data | ||
|
r22 | |||
|
r29 | title = data['title'] | ||
text = data['text'] | ||||
|
r0 | |||
|
r29 | if 'image' in data.keys(): | ||
image = data['image'] | ||||
|
r22 | else: | ||
image = None | ||||
|
r24 | tags = [] | ||
|
r41 | |||
new_thread = thread_id == boards.models.NO_PARENT | ||||
if new_thread: | ||||
|
r29 | tag_strings = data['tags'] | ||
|
r0 | |||
|
r24 | if tag_strings: | ||
|
r35 | tag_strings = tag_strings.split(' ') | ||
|
r24 | for tag_name in tag_strings: | ||
tag_name = tag_name.strip() | ||||
if len(tag_name) > 0: | ||||
tag, created = Tag.objects.get_or_create(name=tag_name) | ||||
tags.append(tag) | ||||
|
r6 | |||
|
r24 | # TODO Add a possibility to define a link image instead of an image file. | ||
# If a link is given, download the image automatically. | ||||
|
r4 | |||
|
r22 | post = Post.objects.create_post(title=title, text=text, ip=ip, | ||
|
r24 | parent_id=thread_id, image=image, | ||
tags=tags) | ||||
|
r4 | |||
|
r41 | thread_to_show = (post.id if new_thread else thread_id) | ||
|
r5 | |||
|
r41 | if new_thread: | ||
return redirect(thread, post_id=thread_to_show) | ||||
else: | ||||
return redirect(reverse(thread, | ||||
kwargs={'post_id': thread_to_show}) + '#' | ||||
+ str(post.id)) | ||||
|
r22 | |||
|
r5 | |||
|
r46 | def tag(request, tag_name, page=0): | ||
|
r4 | """Get all tag threads (posts without a parent).""" | ||
|
r79 | tag = get_object_or_404(Tag, name=tag_name) | ||
|
r164 | threads = [] | ||
for thread in Post.objects.get_threads(tag=tag, page=int(page)): | ||||
threads.append({'thread': thread, | ||||
'bumpable': thread.can_bump()}) | ||||
|
r5 | |||
|
r24 | if request.method == 'POST': | ||
|
r76 | form = ThreadForm(request.POST, request.FILES, | ||
error_class=PlainErrorList) | ||||
if form.is_valid(): | ||||
return _new_post(request, form) | ||||
|
r24 | else: | ||
|
r76 | form = forms.ThreadForm(initial={'tags': tag_name}, | ||
error_class=PlainErrorList) | ||||
|
r12 | |||
|
r101 | context = _init_default_context(request) | ||
|
r76 | context['threads'] = None if len(threads) == 0 else threads | ||
context['tag'] = tag_name | ||||
context['pages'] = range(Post.objects.get_thread_page_count(tag=tag)) | ||||
|
r4 | |||
|
r76 | context['form'] = form | ||
|
r84 | return render(request, 'boards/posting_general.html', | ||
|
r76 | context) | ||
|
r22 | |||
|
r4 | |||
|
r24 | def thread(request, post_id): | ||
|
r5 | """Get all thread posts""" | ||
|
r95 | if utils.need_include_captcha(request): | ||
postFormClass = PostCaptchaForm | ||||
kwargs = {'request': request} | ||||
else: | ||||
postFormClass = PostForm | ||||
kwargs = {} | ||||
|
r78 | |||
|
r20 | if request.method == 'POST': | ||
|
r78 | form = postFormClass(request.POST, request.FILES, | ||
|
r95 | error_class=PlainErrorList, **kwargs) | ||
|
r153 | form.session = request.session | ||
|
r76 | if form.is_valid(): | ||
return _new_post(request, form, post_id) | ||||
|
r20 | else: | ||
|
r95 | form = postFormClass(error_class=PlainErrorList, **kwargs) | ||
|
r12 | |||
|
r76 | posts = Post.objects.get_thread(post_id) | ||
|
r5 | |||
|
r101 | context = _init_default_context(request) | ||
|
r12 | |||
|
r76 | context['posts'] = posts | ||
context['form'] = form | ||||
|
r161 | context['bumpable'] = posts[0].can_bump() | ||
|
r76 | |||
|
r84 | return render(request, 'boards/thread.html', context) | ||
|
r9 | |||
def login(request): | ||||
|
r144 | """Log in with user id""" | ||
|
r9 | |||
|
r144 | context = _init_default_context(request) | ||
|
r13 | |||
|
r144 | if request.method == 'POST': | ||
|
r147 | form = LoginForm(request.POST, request.FILES, | ||
error_class=PlainErrorList) | ||||
|
r144 | if form.is_valid(): | ||
user = User.objects.get(user_id=form.cleaned_data['user_id']) | ||||
request.session['user_id'] = user.id | ||||
return redirect(index) | ||||
|
r9 | |||
|
r144 | else: | ||
form = LoginForm() | ||||
|
r22 | |||
|
r144 | context['form'] = form | ||
return render(request, 'boards/login.html', context) | ||||
|
r35 | |||
def settings(request): | ||||
|
r101 | """User's settings""" | ||
|
r110 | context = _init_default_context(request) | ||
|
r35 | |||
if request.method == 'POST': | ||||
form = SettingsForm(request.POST) | ||||
if form.is_valid(): | ||||
selected_theme = form.cleaned_data['theme'] | ||||
|
r110 | |||
user = _get_user(request) | ||||
user.save_setting('theme', selected_theme) | ||||
|
r35 | |||
return redirect(settings) | ||||
else: | ||||
selected_theme = _get_theme(request) | ||||
form = SettingsForm(initial={'theme': selected_theme}) | ||||
context['form'] = form | ||||
|
r84 | return render(request, 'boards/settings.html', context) | ||
|
r35 | |||
|
r57 | def all_tags(request): | ||
|
r101 | """All tags list""" | ||
context = _init_default_context(request) | ||||
|
r57 | context['all_tags'] = Tag.objects.get_not_empty_tags() | ||
|
r84 | return render(request, 'boards/tags.html', context) | ||
|
r57 | |||
|
r98 | def jump_to_post(request, post_id): | ||
|
r101 | """Determine thread in which the requested post is and open it's page""" | ||
|
r98 | post = get_object_or_404(Post, id=post_id) | ||
if boards.models.NO_PARENT == post.parent: | ||||
return redirect(thread, post_id=post.id) | ||||
else: | ||||
parent_thread = get_object_or_404(Post, id=post.parent) | ||||
return redirect(reverse(thread, kwargs={'post_id': parent_thread.id}) | ||||
+ '#' + str(post.id)) | ||||
|
r103 | def authors(request): | ||
context = _init_default_context(request) | ||||
context['authors'] = boards.authors.authors | ||||
return render(request, 'boards/authors.html', context) | ||||
|
r112 | def delete(request, post_id): | ||
user = _get_user(request) | ||||
post = get_object_or_404(Post, id=post_id) | ||||
if user.is_moderator(): | ||||
|
r147 | # TODO Show confirmation page before deletion | ||
|
r112 | Post.objects.delete_post(post) | ||
|
r137 | |||
|
r112 | if NO_PARENT == post.parent: | ||
|
r155 | return _redirect_to_next(request) | ||
|
r112 | else: | ||
return redirect(thread, post_id=post.parent) | ||||
|
r145 | |||
|
r156 | def ban(request, post_id): | ||
user = _get_user(request) | ||||
post = get_object_or_404(Post, id=post_id) | ||||
if user.is_moderator(): | ||||
# TODO Show confirmation page before ban | ||||
Ban.objects.get_or_create(ip=post.poster_ip) | ||||
return _redirect_to_next(request) | ||||
|
r116 | def you_are_banned(request): | ||
context = _init_default_context(request) | ||||
|
r152 | return render(request, 'boards/staticpages/banned.html', context) | ||
|
r116 | |||
|
r130 | def page_404(request): | ||
context = _init_default_context(request) | ||||
return render(request, 'boards/404.html', context) | ||||
|
r145 | def tag_subscribe(request, tag_name): | ||
user = _get_user(request) | ||||
tag = get_object_or_404(Tag, name=tag_name) | ||||
if not tag in user.fav_tags.all(): | ||||
user.fav_tags.add(tag) | ||||
return redirect(all_tags) | ||||
def tag_unsubscribe(request, tag_name): | ||||
user = _get_user(request) | ||||
tag = get_object_or_404(Tag, name=tag_name) | ||||
if tag in user.fav_tags.all(): | ||||
user.fav_tags.remove(tag) | ||||
return redirect(all_tags) | ||||
|
r152 | def static_page(request, name): | ||
context = _init_default_context(request) | ||||
return render(request, 'boards/staticpages/' + name + '.html', context) | ||||
|
r147 | def _get_theme(request, user=None): | ||
|
r101 | """Get user's CSS theme""" | ||
|
r147 | if not user: | ||
user = _get_user(request) | ||||
|
r110 | theme = user.get_setting('theme') | ||
if not theme: | ||||
theme = neboard.settings.DEFAULT_THEME | ||||
return theme | ||||
|
r70 | |||
def _get_client_ip(request): | ||||
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') | ||||
if x_forwarded_for: | ||||
ip = x_forwarded_for.split(',')[-1].strip() | ||||
else: | ||||
ip = request.META.get('REMOTE_ADDR') | ||||
|
r74 | return ip | ||
|
r101 | |||
def _init_default_context(request): | ||||
"""Create context with default values that are used in most views""" | ||||
context = RequestContext(request) | ||||
|
r147 | |||
user = _get_user(request) | ||||
context['user'] = user | ||||
|
r149 | context['tags'] = user.get_sorted_fav_tags() | ||
|
r147 | context['theme'] = _get_theme(request, user) | ||
|
r101 | |||
return context | ||||
|
r110 | |||
def _get_user(request): | ||||
"""Get current user from the session""" | ||||
session = request.session | ||||
|
r112 | if not 'user_id' in session: | ||
|
r110 | request.session.save() | ||
md5 = hashlib.md5() | ||||
md5.update(session.session_key) | ||||
new_id = md5.hexdigest() | ||||
|
r141 | time_now = timezone.now() | ||
|
r121 | user = User.objects.create(user_id=new_id, rank=RANK_USER, | ||
|
r141 | registration_time=time_now, | ||
last_access_time=time_now) | ||||
|
r110 | |||
|
r112 | session['user_id'] = user.id | ||
|
r110 | else: | ||
|
r112 | user = User.objects.get(id=session['user_id']) | ||
|
r147 | user.last_access_time = timezone.now() | ||
|
r121 | user.save() | ||
|
r137 | return user | ||
|
r155 | |||
def _redirect_to_next(request): | ||||
|
r156 | if 'next' in request.GET: | ||
next_page = request.GET['next'] | ||||
return HttpResponseRedirect(next_page) | ||||
else: | ||||
return redirect(index) | ||||