##// END OF EJS Templates
Even more refactoring
neko259 -
r2005:00eae4e7 default
parent child Browse files
Show More
@@ -1,5 +1,7 b''
1 1 import re
2 2
3 3 FILE_DIRECTORY = 'files/'
4 4 REGEX_TAGS = re.compile(r'^[\w\s\d\']+$', re.UNICODE)
5 REGEX_REPLY = re.compile(r'\[post\](\d+)\[/post\]') No newline at end of file
5 REGEX_REPLY = re.compile(r'\[post\](\d+)\[/post\]')
6
7 PARAM_PAGE = 'page' No newline at end of file
@@ -1,133 +1,137 b''
1 1 from django.core.paginator import EmptyPage
2 2 from django.http import Http404
3 3 from django.shortcuts import render, redirect
4 4 from django.urls import reverse
5 5 from django.utils.decorators import method_decorator
6 6 from django.views.decorators.csrf import csrf_protect
7 7
8 8 from boards import settings
9 from boards.abstracts.constants import PARAM_PAGE
9 10 from boards.abstracts.paginator import get_paginator
10 11 from boards.abstracts.settingsmanager import get_settings_manager, \
11 12 SETTING_ONLY_FAVORITES
12 13 from boards.forms import ThreadForm, PlainErrorList
13 14 from boards.models import Post, Thread
14 15 from boards.views.base import BaseBoardView, CONTEXT_FORM
15 16 from boards.views.mixins import FileUploadMixin, PaginatedMixin, \
16 17 DispatcherMixin, PARAMETER_METHOD
17 18 from boards.settings import SECTION_VIEW, SECTION_FORMS
18 19
20 ORDER_BUMP = 'bump'
21
22 PARAM_ORDER = 'order'
23
19 24 FORM_TAGS = 'tags'
20 25 FORM_TEXT = 'text'
21 26 FORM_TITLE = 'title'
22 27 FORM_IMAGE = 'image'
23 28 FORM_THREADS = 'threads'
24 29
25 30 TAG_DELIMITER = ' '
26 31
27 32 PARAMETER_CURRENT_PAGE = 'current_page'
28 33 PARAMETER_PAGINATOR = 'paginator'
29 34 PARAMETER_THREADS = 'threads'
30 35 PARAMETER_ADDITIONAL = 'additional_params'
31 36 PARAMETER_MAX_FILE_SIZE = 'max_file_size'
32 37 PARAMETER_RSS_URL = 'rss_url'
33 38 PARAMETER_MAX_FILES = 'max_files'
34 39
35 40 TEMPLATE = 'boards/all_threads.html'
36 41 DEFAULT_PAGE = 1
37 42
38 43
39 44 class AllThreadsView(FileUploadMixin, BaseBoardView, PaginatedMixin,
40 45 DispatcherMixin):
41 46
42 47 tag_name = ''
43 48
44 49 def __init__(self):
45 50 self.settings_manager = None
46 51 super(AllThreadsView, self).__init__()
47 52
48 53 @method_decorator(csrf_protect)
49 54 def get(self, request, form: ThreadForm=None):
50 page = request.GET.get('page', DEFAULT_PAGE)
55 page = request.GET.get(PARAM_PAGE, DEFAULT_PAGE)
51 56
52 57 params = self.get_context_data(request=request)
53 58
54 59 if not form:
55 60 form = ThreadForm(error_class=PlainErrorList,
56 initial={FORM_TAGS: self.tag_name})
61 initial={FORM_TAGS: self.tag_name})
57 62
58 63 self.settings_manager = get_settings_manager(request)
59 64
60 65 threads = self.get_threads()
61 66
62 order = request.GET.get('order', 'bump')
63 if order == 'bump':
67 order = request.GET.get(PARAM_ORDER, ORDER_BUMP)
68 if order == ORDER_BUMP:
64 69 threads = threads.order_by('-bump_time')
65 70 else:
66 71 threads = threads.filter(replies__opening=True)\
67 72 .order_by('-replies__pub_time')
68 filter = request.GET.get('filter')
69 73 threads = threads.distinct()
70 74
71 paginator = get_paginator(threads,
72 settings.get_int(SECTION_VIEW, 'ThreadsPerPage'))
75 paginator = get_paginator(threads, settings.get_int(
76 SECTION_VIEW, 'ThreadsPerPage'))
73 77 paginator.current_page = int(page)
74 78
75 79 try:
76 80 threads = paginator.page(page).object_list
77 81 except EmptyPage:
78 82 raise Http404()
79 83
80 84 params[PARAMETER_THREADS] = threads
81 85 params[CONTEXT_FORM] = form
82 86 params[PARAMETER_MAX_FILE_SIZE] = self.get_max_upload_size()
83 87 params[PARAMETER_RSS_URL] = self.get_rss_url()
84 88 params[PARAMETER_MAX_FILES] = settings.get_int(SECTION_FORMS, 'MaxFileCount')
85 89
86 90 paginator.set_url(self.get_reverse_url(), request.GET.dict())
87 91 params.update(self.get_page_context(paginator, page))
88 92
89 93 return render(request, TEMPLATE, params)
90 94
91 95 @method_decorator(csrf_protect)
92 96 def post(self, request):
93 97 if PARAMETER_METHOD in request.POST:
94 98 self.dispatch_method(request)
95 99
96 return redirect('index') # FIXME Different for different modes
100 return self.get_reverse_url()
97 101
98 102 form = ThreadForm(request.POST, request.FILES,
99 103 error_class=PlainErrorList)
100 104 form.session = request.session
101 105
102 106 if form.is_valid():
103 107 return Post.objects.create_from_form(request, form, None)
104 108 if form.need_to_ban:
105 109 # Ban user because he is suspected to be a bot
106 110 self._ban_current_user(request)
107 111
108 112 return self.get(request, form)
109 113
110 114 def get_reverse_url(self):
111 115 return reverse('index')
112 116
113 117 def get_threads(self):
114 118 """
115 119 Gets list of threads that will be shown on a page.
116 120 """
117 121
118 122 threads = Thread.objects\
119 123 .exclude(tags__in=self.settings_manager.get_hidden_tags())
120 124 if self.settings_manager.get_setting(SETTING_ONLY_FAVORITES):
121 125 fav_tags = self.settings_manager.get_fav_tags()
122 126 if len(fav_tags) > 0:
123 127 threads = threads.filter(tags__in=fav_tags)
124 128
125 129 return threads
126 130
127 131 def get_rss_url(self):
128 132 return self.get_reverse_url() + 'rss/'
129 133
130 134 def toggle_fav(self, request):
131 135 settings_manager = get_settings_manager(request)
132 136 settings_manager.set_setting(SETTING_ONLY_FAVORITES,
133 137 not settings_manager.get_setting(SETTING_ONLY_FAVORITES, False))
@@ -1,131 +1,132 b''
1 1 from django.urls import reverse
2 2 from django.shortcuts import render
3 3
4 4 from boards import settings
5 from boards.abstracts.constants import PARAM_PAGE
5 6 from boards.abstracts.paginator import get_paginator
6 7 from boards.abstracts.settingsmanager import get_settings_manager
7 8 from boards.models import Post
8 9 from boards.settings import SECTION_VIEW
9 10 from boards.views.base import BaseBoardView
10 11 from boards.views.mixins import PaginatedMixin
11 12
12 13 POSTS_PER_PAGE = settings.get_int(SECTION_VIEW, 'PostsPerPage')
13 14
14 15 PARAMETER_POSTS = 'posts'
15 16 PARAMETER_QUERIES = 'queries'
16 17
17 18 TEMPLATE = 'boards/feed.html'
18 19 DEFAULT_PAGE = 1
19 20
20 21
21 22 class FeedFilter:
22 23 @staticmethod
23 24 def get_filtered_posts(request, posts):
24 25 return posts
25 26
26 27 @staticmethod
27 28 def get_query(request):
28 29 return None
29 30
30 31
31 32 class TripcodeFilter(FeedFilter):
32 33 @staticmethod
33 34 def get_filtered_posts(request, posts):
34 35 filtered_posts = posts
35 36 tripcode = request.GET.get('tripcode', None)
36 37 if tripcode:
37 38 filtered_posts = filtered_posts.filter(tripcode=tripcode)
38 39 return filtered_posts
39 40
40 41 @staticmethod
41 42 def get_query(request):
42 43 tripcode = request.GET.get('tripcode', None)
43 44 if tripcode:
44 45 return 'Tripcode: {}'.format(tripcode)
45 46
46 47
47 48 class FavoritesFilter(FeedFilter):
48 49 @staticmethod
49 50 def get_filtered_posts(request, posts):
50 51 filtered_posts = posts
51 52
52 53 favorites = 'favorites' in request.GET
53 54 if favorites:
54 55 settings_manager = get_settings_manager(request)
55 56 fav_thread_ops = Post.objects.filter(id__in=settings_manager.get_fav_threads().keys())
56 57 fav_threads = [op.get_thread() for op in fav_thread_ops]
57 58 filtered_posts = filtered_posts.filter(thread__in=fav_threads)
58 59 return filtered_posts
59 60
60 61
61 62 class IpFilter(FeedFilter):
62 63 @staticmethod
63 64 def get_filtered_posts(request, posts):
64 65 filtered_posts = posts
65 66
66 67 ip = request.GET.get('ip', None)
67 68 if ip and request.user.has_perm('post_delete'):
68 69 filtered_posts = filtered_posts.filter(poster_ip=ip)
69 70 return filtered_posts
70 71
71 72 @staticmethod
72 73 def get_query(request):
73 74 ip = request.GET.get('ip', None)
74 75 if ip:
75 76 return 'IP: {}'.format(ip)
76 77
77 78
78 79 class ImageFilter(FeedFilter):
79 80 @staticmethod
80 81 def get_filtered_posts(request, posts):
81 82 filtered_posts = posts
82 83
83 84 image = request.GET.get('image', None)
84 85 if image:
85 86 filtered_posts = filtered_posts.filter(attachments__file=image)
86 87 return filtered_posts
87 88
88 89 @staticmethod
89 90 def get_query(request):
90 91 image = request.GET.get('image', None)
91 92 if image:
92 93 return 'File: {}'.format(image)
93 94
94 95
95 96 class FeedView(PaginatedMixin, BaseBoardView):
96 97 filters = (
97 98 TripcodeFilter,
98 99 FavoritesFilter,
99 100 IpFilter,
100 101 ImageFilter,
101 102 )
102 103
103 104 def get(self, request):
104 page = request.GET.get('page', DEFAULT_PAGE)
105 page = request.GET.get(PARAM_PAGE, DEFAULT_PAGE)
105 106
106 107 params = self.get_context_data(request=request)
107 108
108 109 settings_manager = get_settings_manager(request)
109 110
110 111 posts = Post.objects.exclude(
111 112 thread__tags__in=settings_manager.get_hidden_tags()).order_by(
112 113 '-pub_time').prefetch_related('attachments', 'thread')
113 114 queries = []
114 115 for filter in self.filters:
115 116 posts = filter.get_filtered_posts(request, posts)
116 117 query = filter.get_query(request)
117 118 if query:
118 119 queries.append(query)
119 120 params[PARAMETER_QUERIES] = queries
120 121
121 122 paginator = get_paginator(posts, POSTS_PER_PAGE)
122 123 paginator.current_page = int(page)
123 124
124 125 params[PARAMETER_POSTS] = paginator.page(page).object_list
125 126
126 127 paginator.set_url(reverse('feed'), request.GET.dict())
127 128
128 129 params.update(self.get_page_context(paginator, page))
129 130
130 131 return render(request, TEMPLATE, params)
131 132
@@ -1,60 +1,61 b''
1 1 import boards
2 from boards.settings import SECTION_FORMS
2 3
3 4 PARAM_NEXT = 'next'
4 5 PARAMETER_METHOD = 'method'
5 6
6 7 PARAMETER_CURRENT_PAGE = 'current_page'
7 8 PARAMETER_PAGINATOR = 'paginator'
8 9
9 10 PARAMETER_PREV_LINK = 'prev_page_link'
10 11 PARAMETER_NEXT_LINK = 'next_page_link'
11 12
12 13
13 14 class DispatcherMixin:
14 15 """
15 16 This class contains a dispather method that can run a method specified by
16 17 'method' request parameter.
17 18 """
18 19
19 20 def __init__(self):
20 21 self.user = None
21 22
22 23 def dispatch_method(self, *args, **kwargs):
23 24 request = args[0]
24 25
25 26 self.user = request.user
26 27
27 28 method_name = None
28 29 if PARAMETER_METHOD in request.GET:
29 30 method_name = request.GET[PARAMETER_METHOD]
30 31 elif PARAMETER_METHOD in request.POST:
31 32 method_name = request.POST[PARAMETER_METHOD]
32 33
33 34 if method_name:
34 35 return getattr(self, method_name)(*args, **kwargs)
35 36
36 37
37 38 class FileUploadMixin:
38 39 def get_max_upload_size(self):
39 return boards.settings.get_int('Forms', 'MaxFileSize')
40 return boards.settings.get_int(SECTION_FORMS, 'MaxFileSize')
40 41
41 42
42 43 class PaginatedMixin:
43 44 def get_page_context(self, paginator, page):
44 45 """
45 46 Get pagination context variables
46 47 """
47 48
48 49 params = {}
49 50
50 51 params[PARAMETER_PAGINATOR] = paginator
51 52 current_page = paginator.page(int(page))
52 53 params[PARAMETER_CURRENT_PAGE] = current_page
53 54 if current_page.has_previous():
54 55 params[PARAMETER_PREV_LINK] = paginator.get_page_url(
55 56 current_page.previous_page_number())
56 57 if current_page.has_next():
57 58 params[PARAMETER_NEXT_LINK] = paginator.get_page_url(
58 59 current_page.next_page_number())
59 60
60 61 return params
@@ -1,49 +1,48 b''
1 1 from django.shortcuts import render
2 2
3 from boards.abstracts.constants import PARAM_PAGE
3 4 from boards.abstracts.paginator import get_paginator
4 5 from boards.abstracts.settingsmanager import get_settings_manager, \
5 SETTING_USERNAME, SETTING_LAST_NOTIFICATION_ID
6 SETTING_LAST_NOTIFICATION_ID
6 7 from boards.models.user import Notification
7 8 from boards.views.base import BaseBoardView
8 9
9 10 DEFAULT_PAGE = '1'
10 11
11 12 TEMPLATE = 'boards/notifications.html'
12 PARAM_PAGE = 'page'
13 13 PARAM_USERNAMES = 'notification_usernames'
14 REQUEST_PAGE = 'page'
15 14 RESULTS_PER_PAGE = 10
16 15
17 16
18 17 class NotificationView(BaseBoardView):
19 18
20 19 def get(self, request, username=None):
21 20 params = self.get_context_data()
22 21
23 22 settings_manager = get_settings_manager(request)
24 23
25 24 # If we open our notifications, reset the "new" count
26 25 if username is None:
27 26 notification_usernames = settings_manager.get_notification_usernames()
28 27 else:
29 28 notification_usernames = [username]
30 29
31 30 posts = Notification.objects.get_notification_posts(
32 31 usernames=notification_usernames)
33 32
34 33 if username is None:
35 34 last = posts.first()
36 35 if last is not None:
37 36 last_id = last.id
38 37 settings_manager.set_setting(SETTING_LAST_NOTIFICATION_ID,
39 38 last_id)
40 39
41 40
42 41 paginator = get_paginator(posts, RESULTS_PER_PAGE)
43 42
44 page = int(request.GET.get(REQUEST_PAGE, DEFAULT_PAGE))
43 page = int(request.GET.get(PARAM_PAGE, DEFAULT_PAGE))
45 44
46 45 params[PARAM_PAGE] = paginator.page(page)
47 46 params[PARAM_USERNAMES] = notification_usernames
48 47
49 48 return render(request, TEMPLATE, params)
@@ -1,33 +1,34 b''
1 1 from django.shortcuts import get_object_or_404, render
2 2 from django.urls import reverse
3 3
4 4 from boards import settings
5 from boards.abstracts.constants import PARAM_PAGE
5 6 from boards.abstracts.paginator import get_paginator
6 7 from boards.models import TagAlias
7 8 from boards.settings import SECTION_VIEW
8 9 from boards.views.base import BaseBoardView
9 10 from boards.views.mixins import PaginatedMixin
10 11
11 12 IMAGES_PER_PAGE = settings.get_int(SECTION_VIEW, 'ImagesPerPageGallery')
12 13
13 14 TEMPLATE = 'boards/tag_gallery.html'
14 15
15 16
16 17 class TagGalleryView(BaseBoardView, PaginatedMixin):
17 18
18 19 def get(self, request, tag_name):
19 page = int(request.GET.get('page', 1))
20 page = int(request.GET.get(PARAM_PAGE, 1))
20 21
21 22 params = dict()
22 23 tag_alias = get_object_or_404(TagAlias, name=tag_name)
23 24 tag = tag_alias.parent
24 25 params['tag'] = tag
25 26 paginator = get_paginator(tag.get_images(), IMAGES_PER_PAGE,
26 27 current_page=page)
27 28 params['paginator'] = paginator
28 29 params['images'] = paginator.page(page).object_list
29 30 paginator.set_url(reverse('tag_gallery', kwargs={'tag_name': tag_name}),
30 31 request.GET.dict())
31 32 params.update(self.get_page_context(paginator, page))
32 33
33 34 return render(request, TEMPLATE, params)
@@ -1,31 +1,31 b''
1 from django.contrib.auth.decorators import permission_required
1 2 from django.shortcuts import redirect
2 3 from django.utils.decorators import method_decorator
3 4 from django.views.decorators.csrf import csrf_protect
4 from django.contrib.auth.decorators import permission_required
5 5
6 from boards.views.base import BaseBoardView, CONTEXT_FORM
7 from boards.views.mixins import DispatcherMixin, PARAMETER_METHOD
8 6 from boards.models import Post, Ban
7 from boards.views.base import BaseBoardView
8 from boards.views.mixins import DispatcherMixin
9 9
10 10
11 11 class UtilsView(BaseBoardView, DispatcherMixin):
12 12 @method_decorator(csrf_protect)
13 13 def get(self, request):
14 14 self.dispatch_method(request)
15 15
16 16 return redirect('index')
17 17
18 18 @permission_required('boards.delete_post')
19 19 def ban_and_delete(self, request):
20 20 post = Post.objects.get(id=request.GET['post_id'])
21 21 Ban.objects.get_or_create(ip=post.poster_ip)
22 22 if post.is_opening():
23 23 post.get_thread().delete()
24 24 else:
25 25 post.delete()
26 26
27 27 @permission_required('boards.add_ban')
28 28 def ban(self, request):
29 29 post = Post.objects.get(id=request.GET['post_id'])
30 30 Ban.objects.get_or_create(ip=post.poster_ip)
31 31
General Comments 0
You need to be logged in to leave comments. Login now