##// END OF EJS Templates
Views refactoring
neko259 -
r900:ec6d73a4 default
parent child Browse files
Show More
@@ -1,142 +1,143 b''
1 import string
2
3 1 from django.db import transaction
4 2 from django.shortcuts import render, redirect
5 3
6 4 from boards import utils, settings
7 5 from boards.abstracts.paginator import get_paginator
8 6 from boards.abstracts.settingsmanager import get_settings_manager
9 7 from boards.forms import ThreadForm, PlainErrorList
10 8 from boards.models import Post, Thread, Ban, Tag
11 9 from boards.views.banned import BannedView
12 10 from boards.views.base import BaseBoardView, CONTEXT_FORM
13 11 from boards.views.posting_mixin import PostMixin
14 12
13
15 14 FORM_TAGS = 'tags'
16 15 FORM_TEXT = 'text'
17 16 FORM_TITLE = 'title'
18 17 FORM_IMAGE = 'image'
19 18
20 19 TAG_DELIMITER = ' '
21 20
22 21 PARAMETER_CURRENT_PAGE = 'current_page'
23 22 PARAMETER_PAGINATOR = 'paginator'
24 23 PARAMETER_THREADS = 'threads'
25 24
26 25 TEMPLATE = 'boards/posting_general.html'
27 26 DEFAULT_PAGE = 1
28 27
29 28
30 29 class AllThreadsView(PostMixin, BaseBoardView):
31 30
32 31 def __init__(self):
33 32 self.settings_manager = None
34 33 super(AllThreadsView, self).__init__()
35 34
36 35 def get(self, request, page=DEFAULT_PAGE, form=None):
37 36 context = self.get_context_data(request=request)
38 37
39 38 if not form:
40 39 form = ThreadForm(error_class=PlainErrorList)
41 40
42 41 self.settings_manager = get_settings_manager(request)
43 42 paginator = get_paginator(self.get_threads(),
44 43 settings.THREADS_PER_PAGE)
45 44 paginator.current_page = int(page)
46 45
47 46 threads = paginator.page(page).object_list
48 47
49 48 context[PARAMETER_THREADS] = threads
50 49 context[CONTEXT_FORM] = form
51 50
52 51 self._get_page_context(paginator, context, page)
53 52
54 53 # TODO Use dict here
55 54 return render(request, TEMPLATE, context_instance=context)
56 55
57 56 def post(self, request, page=DEFAULT_PAGE):
58 57 form = ThreadForm(request.POST, request.FILES,
59 58 error_class=PlainErrorList)
60 59 form.session = request.session
61 60
62 61 if form.is_valid():
63 62 return self.create_thread(request, form)
64 63 if form.need_to_ban:
65 64 # Ban user because he is suspected to be a bot
66 65 self._ban_current_user(request)
67 66
68 67 return self.get(request, page, form)
69 68
70 69 @staticmethod
71 70 def _get_page_context(paginator, context, page):
72 71 """
73 72 Get pagination context variables
74 73 """
75 74
76 75 context[PARAMETER_PAGINATOR] = paginator
77 76 context[PARAMETER_CURRENT_PAGE] = paginator.page(int(page))
78 77
79 78 @staticmethod
80 79 def parse_tags_string(tag_strings):
81 80 """
82 81 Parses tag list string and returns tag object list.
83 82 """
84 83
85 84 tags = []
86 85
87 86 if tag_strings:
88 87 tag_strings = tag_strings.split(TAG_DELIMITER)
89 88 for tag_name in tag_strings:
90 89 tag_name = tag_name.strip().lower()
91 90 if len(tag_name) > 0:
92 91 tag, created = Tag.objects.get_or_create(name=tag_name)
93 92 tags.append(tag)
94 93
95 94 return tags
96 95
97 96 @transaction.atomic
98 97 def create_thread(self, request, form, html_response=True):
99 98 """
100 99 Creates a new thread with an opening post.
101 100 """
102 101
103 102 ip = utils.get_client_ip(request)
104 103 is_banned = Ban.objects.filter(ip=ip).exists()
105 104
106 105 if is_banned:
107 106 if html_response:
108 107 return redirect(BannedView().as_view())
109 108 else:
110 109 return
111 110
112 111 data = form.cleaned_data
113 112
114 113 title = data[FORM_TITLE]
115 114 text = data[FORM_TEXT]
116 115
117 116 text = self._remove_invalid_links(text)
118 117
119 118 if FORM_IMAGE in list(data.keys()):
120 119 image = data[FORM_IMAGE]
121 120 else:
122 121 image = None
123 122
124 123 tag_strings = data[FORM_TAGS]
125 124
126 125 tags = self.parse_tags_string(tag_strings)
127 126
128 127 post = Post.objects.create_post(title=title, text=text, image=image,
129 128 ip=ip, tags=tags)
130 # FIXME
129
130 # This is required to update the threads to which posts we have replied
131 # when creating this one
131 132 post.send_to_websocket(request)
132 133
133 134 if html_response:
134 135 return redirect(post.get_url())
135 136
136 137 def get_threads(self):
137 138 """
138 139 Gets list of threads that will be shown on a page.
139 140 """
140 141
141 142 return Thread.objects.all().order_by('-bump_time')\
142 143 .exclude(tags__in=self.settings_manager.get_hidden_tags())
@@ -1,35 +1,39 b''
1 1 from django.db import transaction
2 2 from django.template import RequestContext
3 3 from django.views.generic import View
4 4
5 5 from boards import utils
6 6 from boards.models.user import Ban
7 7
8 8
9 9 BAN_REASON_SPAM = 'Autoban: spam bot'
10 10
11 11 CONTEXT_FORM = 'form'
12 12
13 13
14 14 class BaseBoardView(View):
15 15
16 16 def get_context_data(self, **kwargs):
17 """
18 This method is deprecated. You need to use dicts instead of context
19 instances in all places it is used now.
20 """
21
17 22 request = kwargs['request']
18 # context = self._default_context(request)
19 23 context = RequestContext(request)
20 24
21 25 return context
22 26
23 27 @transaction.atomic
24 28 def _ban_current_user(self, request):
25 29 """
26 30 Add current user to the IP ban list
27 31 """
28 32
29 33 ip = utils.get_client_ip(request)
30 34 ban, created = Ban.objects.get_or_create(ip=ip)
31 35 if created:
32 36 ban.can_read = False
33 37 ban.reason = BAN_REASON_SPAM
34 38 ban.save()
35 39
@@ -1,39 +1,40 b''
1 PARAM_NEXT = 'next'
1 2 PARAMETER_METHOD = 'method'
2 3
3 4 from django.shortcuts import redirect
4 5 from django.http import HttpResponseRedirect
5 6
6 7
7 8 class RedirectNextMixin:
8 9
9 10 def redirect_to_next(self, request):
10 11 """
11 12 If a 'next' parameter was specified, redirect to the next page. This
12 13 is used when the user is required to return to some page after the
13 14 current view has finished its work.
14 15 """
15 16
16 if 'next' in request.GET:
17 next_page = request.GET['next']
17 if PARAM_NEXT in request.GET:
18 next_page = request.GET[PARAM_NEXT]
18 19 return HttpResponseRedirect(next_page)
19 20 else:
20 21 return redirect('index')
21 22
22 23
23 24 class DispatcherMixin:
24 25 """
25 26 This class contains a dispather method that can run a method specified by
26 27 'method' request parameter.
27 28 """
28 29
29 30 def dispatch_method(self, *args, **kwargs):
30 31 request = args[0]
31 32
32 33 method_name = None
33 34 if PARAMETER_METHOD in request.GET:
34 35 method_name = request.GET[PARAMETER_METHOD]
35 36 elif PARAMETER_METHOD in request.POST:
36 37 method_name = request.POST[PARAMETER_METHOD]
37 38
38 39 if method_name:
39 40 return getattr(self, method_name)(*args, **kwargs)
@@ -1,39 +1,41 b''
1 1 from django.db import transaction
2 2 from django.shortcuts import render, redirect
3 3
4 4 from boards.abstracts.settingsmanager import get_settings_manager
5 5 from boards.views.base import BaseBoardView, CONTEXT_FORM
6 6 from boards.forms import SettingsForm, PlainErrorList
7 7
8 FORM_THEME = 'theme'
9
8 10 CONTEXT_HIDDEN_TAGS = 'hidden_tags'
9 11
10 12
11 13 class SettingsView(BaseBoardView):
12 14
13 15 def get(self, request):
14 16 context = self.get_context_data(request=request)
15 17 settings_manager = get_settings_manager(request)
16 18
17 19 selected_theme = settings_manager.get_theme()
18 20
19 form = SettingsForm(initial={'theme': selected_theme},
21 form = SettingsForm(initial={FORM_THEME: selected_theme},
20 22 error_class=PlainErrorList)
21 23
22 24 context[CONTEXT_FORM] = form
23 25 context[CONTEXT_HIDDEN_TAGS] = settings_manager.get_hidden_tags()
24 26
25 27 # TODO Use dict here
26 28 return render(request, 'boards/settings.html', context_instance=context)
27 29
28 30 def post(self, request):
29 31 settings_manager = get_settings_manager(request)
30 32
31 33 with transaction.atomic():
32 34 form = SettingsForm(request.POST, error_class=PlainErrorList)
33 35
34 36 if form.is_valid():
35 selected_theme = form.cleaned_data['theme']
37 selected_theme = form.cleaned_data[FORM_THEME]
36 38
37 39 settings_manager.set_theme(selected_theme)
38 40
39 41 return redirect('settings')
@@ -1,92 +1,95 b''
1 1 from django.shortcuts import get_object_or_404
2 2
3 3 from boards.abstracts.settingsmanager import get_settings_manager
4 4 from boards.models import Tag
5 5 from boards.views.all_threads import AllThreadsView, DEFAULT_PAGE
6 6 from boards.views.mixins import DispatcherMixin, RedirectNextMixin
7 7 from boards.forms import ThreadForm, PlainErrorList
8 8
9 PARAM_HIDDEN_TAGS = 'hidden_tags'
10 PARAM_FAV_TAGS = 'fav_tags'
11 PARAM_TAG = 'tag'
9 12
10 13 __author__ = 'neko259'
11 14
12 15
13 16 class TagView(AllThreadsView, DispatcherMixin, RedirectNextMixin):
14 17
15 18 tag_name = None
16 19
17 20 def get_threads(self):
18 21 tag = get_object_or_404(Tag, name=self.tag_name)
19 22
20 23 return tag.threads.all().order_by('-bump_time')
21 24
22 25 def get_context_data(self, **kwargs):
23 26 context = super(TagView, self).get_context_data(**kwargs)
24 27
25 28 settings_manager = get_settings_manager(kwargs['request'])
26 29
27 30 tag = get_object_or_404(Tag, name=self.tag_name)
28 context['tag'] = tag
31 context[PARAM_TAG] = tag
29 32
30 context['fav_tags'] = settings_manager.get_fav_tags()
31 context['hidden_tags'] = settings_manager.get_hidden_tags()
33 context[PARAM_FAV_TAGS] = settings_manager.get_fav_tags()
34 context[PARAM_HIDDEN_TAGS] = settings_manager.get_hidden_tags()
32 35
33 36 return context
34 37
35 38 def get(self, request, tag_name, page=DEFAULT_PAGE, form=None):
36 39 self.tag_name = tag_name
37 40
38 41 dispatch_result = self.dispatch_method(request)
39 42 if dispatch_result:
40 43 return dispatch_result
41 44 else:
42 45 return super(TagView, self).get(request, page, form)
43 46
44 47 def post(self, request, tag_name, page=DEFAULT_PAGE):
45 48 form = ThreadForm(request.POST, request.FILES,
46 49 error_class=PlainErrorList)
47 50 form.session = request.session
48 51
49 52 if form.is_valid():
50 53 return self.create_thread(request, form)
51 54 if form.need_to_ban:
52 55 # Ban user because he is suspected to be a bot
53 56 self._ban_current_user(request)
54 57
55 58 return self.get(request, tag_name, page, form)
56 59
57 60 def subscribe(self, request):
58 61 tag = get_object_or_404(Tag, name=self.tag_name)
59 62
60 63 settings_manager = get_settings_manager(request)
61 64 settings_manager.add_fav_tag(tag)
62 65
63 66 return self.redirect_to_next(request)
64 67
65 68 def unsubscribe(self, request):
66 69 tag = get_object_or_404(Tag, name=self.tag_name)
67 70
68 71 settings_manager = get_settings_manager(request)
69 72 settings_manager.del_fav_tag(tag)
70 73
71 74 return self.redirect_to_next(request)
72 75
73 76 def hide(self, request):
74 77 """
75 78 Adds tag to user's hidden tags. Threads with this tag will not be
76 79 shown.
77 80 """
78 81
79 82 tag = get_object_or_404(Tag, name=self.tag_name)
80 83
81 84 settings_manager = get_settings_manager(request)
82 85 settings_manager.add_hidden_tag(tag)
83 86
84 87 def unhide(self, request):
85 88 """
86 89 Removed tag from user's hidden tags.
87 90 """
88 91
89 92 tag = get_object_or_404(Tag, name=self.tag_name)
90 93
91 94 settings_manager = get_settings_manager(request)
92 95 settings_manager.del_hidden_tag(tag)
@@ -1,157 +1,150 b''
1 1 from django.core.urlresolvers import reverse
2 2 from django.db import transaction
3 3 from django.http import Http404
4 4 from django.shortcuts import get_object_or_404, render, redirect
5 5 from django.views.generic.edit import FormMixin
6 6
7 7 from boards import utils, settings
8 8 from boards.forms import PostForm, PlainErrorList
9 9 from boards.models import Post, Ban
10 10 from boards.views.banned import BannedView
11 11 from boards.views.base import BaseBoardView, CONTEXT_FORM
12 12 from boards.views.posting_mixin import PostMixin
13 13 import neboard
14 14
15 15 TEMPLATE_GALLERY = 'boards/thread_gallery.html'
16 16 TEMPLATE_NORMAL = 'boards/thread.html'
17 17
18 18 CONTEXT_POSTS = 'posts'
19 19 CONTEXT_OP = 'opening_post'
20 20 CONTEXT_BUMPLIMIT_PRG = 'bumplimit_progress'
21 21 CONTEXT_POSTS_LEFT = 'posts_left'
22 22 CONTEXT_LASTUPDATE = "last_update"
23 23 CONTEXT_MAX_REPLIES = 'max_replies'
24 24 CONTEXT_THREAD = 'thread'
25 25 CONTEXT_BUMPABLE = 'bumpable'
26 26 CONTEXT_WS_TOKEN = 'ws_token'
27 27 CONTEXT_WS_PROJECT = 'ws_project'
28 28 CONTEXT_WS_HOST = 'ws_host'
29 29 CONTEXT_WS_PORT = 'ws_port'
30 30
31 31 FORM_TITLE = 'title'
32 32 FORM_TEXT = 'text'
33 33 FORM_IMAGE = 'image'
34 34
35 35 MODE_GALLERY = 'gallery'
36 36 MODE_NORMAL = 'normal'
37 37
38 38
39 39 class ThreadView(BaseBoardView, PostMixin, FormMixin):
40 40
41 41 def get(self, request, post_id, mode=MODE_NORMAL, form=None):
42 42 try:
43 43 opening_post = Post.objects.filter(id=post_id).only('thread_new')[0]
44 44 except IndexError:
45 45 raise Http404
46 46
47 47 # If this is not OP, don't show it as it is
48 48 if not opening_post or not opening_post.is_opening():
49 49 raise Http404
50 50
51 51 if not form:
52 52 form = PostForm(error_class=PlainErrorList)
53 53
54 54 thread_to_show = opening_post.get_thread()
55 55
56 56 context = self.get_context_data(request=request)
57 57
58 58 context[CONTEXT_FORM] = form
59 59 context[CONTEXT_LASTUPDATE] = str(utils.datetime_to_epoch(
60 60 thread_to_show.last_edit_time))
61 61 context[CONTEXT_THREAD] = thread_to_show
62 62 context[CONTEXT_MAX_REPLIES] = settings.MAX_POSTS_PER_THREAD
63 63
64 64 if settings.WEBSOCKETS_ENABLED:
65 65 context[CONTEXT_WS_TOKEN] = utils.get_websocket_token(
66 66 timestamp=context[CONTEXT_LASTUPDATE])
67 67 context[CONTEXT_WS_PROJECT] = neboard.settings.CENTRIFUGE_PROJECT_ID
68 68 context[CONTEXT_WS_HOST] = request.get_host().split(':')[0]
69 69 context[CONTEXT_WS_PORT] = neboard.settings.CENTRIFUGE_PORT
70 70
71 71 # TODO Move this to subclasses: NormalThreadView, GalleryThreadView etc
72 72 if MODE_NORMAL == mode:
73 73 bumpable = thread_to_show.can_bump()
74 74 context[CONTEXT_BUMPABLE] = bumpable
75 75 if bumpable:
76 76 left_posts = settings.MAX_POSTS_PER_THREAD \
77 77 - thread_to_show.get_reply_count()
78 78 context[CONTEXT_POSTS_LEFT] = left_posts
79 79 context[CONTEXT_BUMPLIMIT_PRG] = str(
80 80 float(left_posts) / settings.MAX_POSTS_PER_THREAD * 100)
81 81
82 82 context[CONTEXT_OP] = opening_post
83 83
84 84 document = TEMPLATE_NORMAL
85 85 elif MODE_GALLERY == mode:
86 86 context[CONTEXT_POSTS] = thread_to_show.get_replies_with_images(
87 87 view_fields_only=True)
88 88
89 89 document = TEMPLATE_GALLERY
90 90 else:
91 91 raise Http404
92 92
93 93 # TODO Use dict here
94 94 return render(request, document, context_instance=context)
95 95
96 96 def post(self, request, post_id, mode=MODE_NORMAL):
97 97 opening_post = get_object_or_404(Post, id=post_id)
98 98
99 99 # If this is not OP, don't show it as it is
100 100 if not opening_post.is_opening():
101 101 raise Http404
102 102
103 103 if not opening_post.get_thread().archived:
104 104 form = PostForm(request.POST, request.FILES,
105 105 error_class=PlainErrorList)
106 106 form.session = request.session
107 107
108 108 if form.is_valid():
109 109 return self.new_post(request, form, opening_post)
110 110 if form.need_to_ban:
111 111 # Ban user because he is suspected to be a bot
112 112 self._ban_current_user(request)
113 113
114 114 return self.get(request, post_id, mode, form)
115 115
116 116 @transaction.atomic
117 117 def new_post(self, request, form, opening_post=None, html_response=True):
118 118 """Add a new post (in thread or as a reply)."""
119 119
120 120 ip = utils.get_client_ip(request)
121 is_banned = Ban.objects.filter(ip=ip).exists()
122
123 if is_banned:
124 if html_response:
125 return redirect(BannedView().as_view())
126 else:
127 return None
128 121
129 122 data = form.cleaned_data
130 123
131 124 title = data[FORM_TITLE]
132 125 text = data[FORM_TEXT]
133 126
134 127 text = self._remove_invalid_links(text)
135 128
136 129 if FORM_IMAGE in list(data.keys()):
137 130 image = data[FORM_IMAGE]
138 131 else:
139 132 image = None
140 133
141 134 tags = []
142 135
143 136 post_thread = opening_post.get_thread()
144 137
145 138 post = Post.objects.create_post(title=title, text=text, image=image,
146 139 thread=post_thread, ip=ip, tags=tags)
147 140 post.send_to_websocket(request, recursive=False)
148 141
149 142 thread_to_show = (opening_post.id if opening_post else post.id)
150 143
151 144 if html_response:
152 145 if opening_post:
153 146 return redirect(
154 147 reverse('thread', kwargs={'post_id': thread_to_show})
155 148 + '#' + str(post.id))
156 149 else:
157 150 return post
General Comments 0
You need to be logged in to leave comments. Login now