##// END OF EJS Templates
Added replies manytomany field to the post to get its replies more efficiently.
Added replies manytomany field to the post to get its replies more efficiently.

File last commit:

r169:4857f106 default
r169:4857f106 default
Show More
views.py
359 lines | 10.0 KiB | text/x-python | PythonLexer
import hashlib
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.template import RequestContext
from django.shortcuts import render, redirect, get_object_or_404
from django.utils import timezone
from boards import forms
import boards
from boards import utils
from boards.forms import ThreadForm, PostForm, SettingsForm, PlainErrorList, \
ThreadCaptchaForm, PostCaptchaForm, LoginForm
from boards.models import Post, Tag, Ban, User, RANK_USER, NO_PARENT
from boards import authors
import neboard
def index(request, page=0):
context = _init_default_context(request)
if utils.need_include_captcha(request):
threadFormClass = ThreadCaptchaForm
kwargs = {'request': request}
else:
threadFormClass = ThreadForm
kwargs = {}
if request.method == 'POST':
form = threadFormClass(request.POST, request.FILES,
error_class=PlainErrorList, **kwargs)
form.session = request.session
if form.is_valid():
return _new_post(request, form)
else:
form = threadFormClass(error_class=PlainErrorList, **kwargs)
threads = []
for thread in Post.objects.get_threads(page=int(page)):
threads.append({'thread': thread,
'bumpable': thread.can_bump()})
context['threads'] = None if len(threads) == 0 else threads
context['form'] = form
context['pages'] = range(Post.objects.get_thread_page_count())
return render(request, 'boards/posting_general.html',
context)
def _new_post(request, form, thread_id=boards.models.NO_PARENT):
"""Add a new post (in thread or as a reply)."""
ip = _get_client_ip(request)
is_banned = Ban.objects.filter(ip=ip).count() > 0
if is_banned:
return redirect(you_are_banned)
data = form.cleaned_data
title = data['title']
text = data['text']
if 'image' in data.keys():
image = data['image']
else:
image = None
tags = []
new_thread = thread_id == boards.models.NO_PARENT
if new_thread:
tag_strings = data['tags']
if tag_strings:
tag_strings = tag_strings.split(' ')
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)
# TODO Add a possibility to define a link image instead of an image file.
# If a link is given, download the image automatically.
post = Post.objects.create_post(title=title, text=text, ip=ip,
parent_id=thread_id, image=image,
tags=tags)
thread_to_show = (post.id if new_thread else thread_id)
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))
def tag(request, tag_name, page=0):
"""Get all tag threads (posts without a parent)."""
tag = get_object_or_404(Tag, name=tag_name)
threads = []
for thread in Post.objects.get_threads(tag=tag, page=int(page)):
threads.append({'thread': thread,
'bumpable': thread.can_bump()})
if request.method == 'POST':
form = ThreadForm(request.POST, request.FILES,
error_class=PlainErrorList)
if form.is_valid():
return _new_post(request, form)
else:
form = forms.ThreadForm(initial={'tags': tag_name},
error_class=PlainErrorList)
context = _init_default_context(request)
context['threads'] = None if len(threads) == 0 else threads
context['tag'] = tag_name
context['pages'] = range(Post.objects.get_thread_page_count(tag=tag))
context['form'] = form
return render(request, 'boards/posting_general.html',
context)
def thread(request, post_id):
"""Get all thread posts"""
if utils.need_include_captcha(request):
postFormClass = PostCaptchaForm
kwargs = {'request': request}
else:
postFormClass = PostForm
kwargs = {}
if request.method == 'POST':
form = postFormClass(request.POST, request.FILES,
error_class=PlainErrorList, **kwargs)
form.session = request.session
if form.is_valid():
return _new_post(request, form, post_id)
else:
form = postFormClass(error_class=PlainErrorList, **kwargs)
posts = Post.objects.get_thread(post_id)
context = _init_default_context(request)
context['posts'] = posts
context['form'] = form
context['bumpable'] = posts[0].can_bump()
return render(request, 'boards/thread.html', context)
def login(request):
"""Log in with user id"""
context = _init_default_context(request)
if request.method == 'POST':
form = LoginForm(request.POST, request.FILES,
error_class=PlainErrorList)
if form.is_valid():
user = User.objects.get(user_id=form.cleaned_data['user_id'])
request.session['user_id'] = user.id
return redirect(index)
else:
form = LoginForm()
context['form'] = form
return render(request, 'boards/login.html', context)
def settings(request):
"""User's settings"""
context = _init_default_context(request)
if request.method == 'POST':
form = SettingsForm(request.POST)
if form.is_valid():
selected_theme = form.cleaned_data['theme']
user = _get_user(request)
user.save_setting('theme', selected_theme)
return redirect(settings)
else:
selected_theme = _get_theme(request)
form = SettingsForm(initial={'theme': selected_theme})
context['form'] = form
return render(request, 'boards/settings.html', context)
def all_tags(request):
"""All tags list"""
context = _init_default_context(request)
context['all_tags'] = Tag.objects.get_not_empty_tags()
return render(request, 'boards/tags.html', context)
def jump_to_post(request, post_id):
"""Determine thread in which the requested post is and open it's page"""
post = get_object_or_404(Post, id=post_id)
if boards.models.NO_PARENT == post.parent:
return redirect(thread, post_id=post.id)
else:
# TODO Change this code to not use 'parent' field anymore
parent_thread = get_object_or_404(Post, id=post.parent)
return redirect(reverse(thread, kwargs={'post_id': parent_thread.id})
+ '#' + str(post.id))
def authors(request):
context = _init_default_context(request)
context['authors'] = boards.authors.authors
return render(request, 'boards/authors.html', context)
def delete(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 deletion
Post.objects.delete_post(post)
if NO_PARENT == post.parent:
return _redirect_to_next(request)
else:
return redirect(thread, post_id=post.parent)
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)
def you_are_banned(request):
context = _init_default_context(request)
return render(request, 'boards/staticpages/banned.html', context)
def page_404(request):
context = _init_default_context(request)
return render(request, 'boards/404.html', context)
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)
def static_page(request, name):
context = _init_default_context(request)
return render(request, 'boards/staticpages/' + name + '.html', context)
def _get_theme(request, user=None):
"""Get user's CSS theme"""
if not user:
user = _get_user(request)
theme = user.get_setting('theme')
if not theme:
theme = neboard.settings.DEFAULT_THEME
return theme
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')
return ip
def _init_default_context(request):
"""Create context with default values that are used in most views"""
context = RequestContext(request)
user = _get_user(request)
context['user'] = user
context['tags'] = user.get_sorted_fav_tags()
context['theme'] = _get_theme(request, user)
return context
def _get_user(request):
"""Get current user from the session"""
session = request.session
if not 'user_id' in session:
request.session.save()
md5 = hashlib.md5()
md5.update(session.session_key)
new_id = md5.hexdigest()
time_now = timezone.now()
user = User.objects.create(user_id=new_id, rank=RANK_USER,
registration_time=time_now,
last_access_time=time_now)
session['user_id'] = user.id
else:
user = User.objects.get(id=session['user_id'])
user.last_access_time = timezone.now()
user.save()
return user
def _redirect_to_next(request):
if 'next' in request.GET:
next_page = request.GET['next']
return HttpResponseRedirect(next_page)
else:
return redirect(index)