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