##// END OF EJS Templates
Moved all tags view to class-based view
neko259 -
r550:92419f63 1.7-dev
parent child Browse files
Show More
@@ -1,77 +1,78 b''
1 from django.conf.urls import patterns, url, include
1 from django.conf.urls import patterns, url, include
2 from boards import views
2 from boards import views
3 from boards.rss import AllThreadsFeed, TagThreadsFeed, ThreadPostsFeed
3 from boards.rss import AllThreadsFeed, TagThreadsFeed, ThreadPostsFeed
4 from boards.views import api, tag_threads, all_threads, archived_threads, \
4 from boards.views import api, tag_threads, all_threads, archived_threads, \
5 login, settings
5 login, settings, all_tags
6
6
7 js_info_dict = {
7 js_info_dict = {
8 'packages': ('boards',),
8 'packages': ('boards',),
9 }
9 }
10
10
11 urlpatterns = patterns('',
11 urlpatterns = patterns('',
12
12
13 # /boards/
13 # /boards/
14 url(r'^$', all_threads.AllThreadsView.as_view(), name='index'),
14 url(r'^$', all_threads.AllThreadsView.as_view(), name='index'),
15 # /boards/page/
15 # /boards/page/
16 url(r'^page/(?P<page>\w+)/$', all_threads.AllThreadsView.as_view(),
16 url(r'^page/(?P<page>\w+)/$', all_threads.AllThreadsView.as_view(),
17 name='index'),
17 name='index'),
18
18
19 url(r'^archive/$', archived_threads.ArchiveView.as_view(), name='archive'),
19 url(r'^archive/$', archived_threads.ArchiveView.as_view(), name='archive'),
20 url(r'^archive/page/(?P<page>\w+)/$',
20 url(r'^archive/page/(?P<page>\w+)/$',
21 archived_threads.ArchiveView.as_view(), name='archive'),
21 archived_threads.ArchiveView.as_view(), name='archive'),
22
22
23 # login page
23 # login page
24 url(r'^login/$', login.LoginView.as_view(), name='login'),
24 url(r'^login/$', login.LoginView.as_view(), name='login'),
25
25
26 # /boards/tag/tag_name/
26 # /boards/tag/tag_name/
27 url(r'^tag/(?P<tag_name>\w+)/$', tag_threads.TagView.as_view(),
27 url(r'^tag/(?P<tag_name>\w+)/$', tag_threads.TagView.as_view(),
28 name='tag'),
28 name='tag'),
29 # /boards/tag/tag_id/page/
29 # /boards/tag/tag_id/page/
30 url(r'^tag/(?P<tag_name>\w+)/page/(?P<page>\w+)/$',
30 url(r'^tag/(?P<tag_name>\w+)/page/(?P<page>\w+)/$',
31 tag_threads.TagView.as_view(), name='tag'),
31 tag_threads.TagView.as_view(), name='tag'),
32
32
33 # /boards/tag/tag_name/unsubscribe/
33 # /boards/tag/tag_name/unsubscribe/
34 url(r'^tag/(?P<tag_name>\w+)/subscribe/$', views.tag_subscribe,
34 url(r'^tag/(?P<tag_name>\w+)/subscribe/$', views.tag_subscribe,
35 name='tag_subscribe'),
35 name='tag_subscribe'),
36 # /boards/tag/tag_name/unsubscribe/
36 # /boards/tag/tag_name/unsubscribe/
37 url(r'^tag/(?P<tag_name>\w+)/unsubscribe/$', views.tag_unsubscribe,
37 url(r'^tag/(?P<tag_name>\w+)/unsubscribe/$', views.tag_unsubscribe,
38 name='tag_unsubscribe'),
38 name='tag_unsubscribe'),
39
39
40 # /boards/thread/
40 # /boards/thread/
41 url(r'^thread/(?P<post_id>\w+)/$', views.thread.ThreadView.as_view(),
41 url(r'^thread/(?P<post_id>\w+)/$', views.thread.ThreadView.as_view(),
42 name='thread'),
42 name='thread'),
43 url(r'^thread/(?P<post_id>\w+)/(?P<mode>\w+)/$', views.thread.ThreadView
43 url(r'^thread/(?P<post_id>\w+)/(?P<mode>\w+)/$', views.thread.ThreadView
44 .as_view(), name='thread_mode'),
44 .as_view(), name='thread_mode'),
45
45 url(r'^settings/$', settings.SettingsView.as_view(), name='settings'),
46 url(r'^settings/$', settings.SettingsView.as_view(), name='settings'),
46 url(r'^tags/$', views.all_tags, name='tags'),
47 url(r'^tags/$', all_tags.AllTagsView.as_view(), name='tags'),
47 url(r'^captcha/', include('captcha.urls')),
48 url(r'^captcha/', include('captcha.urls')),
48 url(r'^jump/(?P<post_id>\w+)/$', views.jump_to_post, name='jumper'),
49 url(r'^jump/(?P<post_id>\w+)/$', views.jump_to_post, name='jumper'),
49 url(r'^authors/$', views.authors, name='authors'),
50 url(r'^authors/$', views.authors, name='authors'),
50 url(r'^delete/(?P<post_id>\w+)/$', views.delete, name='delete'),
51 url(r'^delete/(?P<post_id>\w+)/$', views.delete, name='delete'),
51 url(r'^ban/(?P<post_id>\w+)/$', views.ban, name='ban'),
52 url(r'^ban/(?P<post_id>\w+)/$', views.ban, name='ban'),
52
53
53 url(r'^banned/$', views.banned.BannedView.as_view(), name='banned'),
54 url(r'^banned/$', views.banned.BannedView.as_view(), name='banned'),
54 url(r'^staticpage/(?P<name>\w+)/$', views.static_page, name='staticpage'),
55 url(r'^staticpage/(?P<name>\w+)/$', views.static_page, name='staticpage'),
55
56
56 # RSS feeds
57 # RSS feeds
57 url(r'^rss/$', AllThreadsFeed()),
58 url(r'^rss/$', AllThreadsFeed()),
58 url(r'^page/(?P<page>\w+)/rss/$', AllThreadsFeed()),
59 url(r'^page/(?P<page>\w+)/rss/$', AllThreadsFeed()),
59 url(r'^tag/(?P<tag_name>\w+)/rss/$', TagThreadsFeed()),
60 url(r'^tag/(?P<tag_name>\w+)/rss/$', TagThreadsFeed()),
60 url(r'^tag/(?P<tag_name>\w+)/page/(?P<page>\w+)/rss/$', TagThreadsFeed()),
61 url(r'^tag/(?P<tag_name>\w+)/page/(?P<page>\w+)/rss/$', TagThreadsFeed()),
61 url(r'^thread/(?P<post_id>\w+)/rss/$', ThreadPostsFeed()),
62 url(r'^thread/(?P<post_id>\w+)/rss/$', ThreadPostsFeed()),
62
63
63 # i18n
64 # i18n
64 url(r'^jsi18n/$', 'boards.views.cached_js_catalog', js_info_dict, name='js_info_dict'),
65 url(r'^jsi18n/$', 'boards.views.cached_js_catalog', js_info_dict, name='js_info_dict'),
65
66
66 # API
67 # API
67 url(r'^api/post/(?P<post_id>\w+)/$', api.get_post, name="get_post"),
68 url(r'^api/post/(?P<post_id>\w+)/$', api.get_post, name="get_post"),
68 url(r'^api/diff_thread/(?P<thread_id>\w+)/(?P<last_update_time>\w+)/$',
69 url(r'^api/diff_thread/(?P<thread_id>\w+)/(?P<last_update_time>\w+)/$',
69 api.api_get_threaddiff, name="get_thread_diff"),
70 api.api_get_threaddiff, name="get_thread_diff"),
70 url(r'^api/threads/(?P<count>\w+)/$', api.api_get_threads,
71 url(r'^api/threads/(?P<count>\w+)/$', api.api_get_threads,
71 name='get_threads'),
72 name='get_threads'),
72 url(r'^api/tags/$', api.api_get_tags, name='get_tags'),
73 url(r'^api/tags/$', api.api_get_tags, name='get_tags'),
73 url(r'^api/thread/(?P<opening_post_id>\w+)/$', api.api_get_thread_posts,
74 url(r'^api/thread/(?P<opening_post_id>\w+)/$', api.api_get_thread_posts,
74 name='get_thread'),
75 name='get_thread'),
75 url(r'^api/add_post/(?P<opening_post_id>\w+)/$', api.api_add_post, name='add_post'),
76 url(r'^api/add_post/(?P<opening_post_id>\w+)/$', api.api_add_post, name='add_post'),
76
77
77 )
78 )
@@ -1,243 +1,234 b''
1 __author__ = 'neko259'
1 __author__ = 'neko259'
2
2
3 import hashlib
3 import hashlib
4
4
5 from django.core import serializers
5 from django.core import serializers
6 from django.core.urlresolvers import reverse
6 from django.core.urlresolvers import reverse
7 from django.http import HttpResponseRedirect
7 from django.http import HttpResponseRedirect
8 from django.http.response import HttpResponse
8 from django.http.response import HttpResponse
9 from django.template import RequestContext
9 from django.template import RequestContext
10 from django.shortcuts import render, redirect, get_object_or_404
10 from django.shortcuts import render, redirect, get_object_or_404
11 from django.utils import timezone
11 from django.utils import timezone
12 from django.db import transaction
12 from django.db import transaction
13 from django.views.decorators.cache import cache_page
13 from django.views.decorators.cache import cache_page
14 from django.views.i18n import javascript_catalog
14 from django.views.i18n import javascript_catalog
15
15
16 import boards
16 import boards
17 from boards.forms import PlainErrorList
17 from boards.forms import PlainErrorList
18 from boards.models import Post, Tag, Ban, User
18 from boards.models import Post, Tag, Ban, User
19 from boards.models.post import SETTING_MODERATE
19 from boards.models.post import SETTING_MODERATE
20 from boards.models.user import RANK_USER
20 from boards.models.user import RANK_USER
21 from boards import authors
21 from boards import authors
22 import neboard
22 import neboard
23
23
24
24
25 BAN_REASON_SPAM = 'Autoban: spam bot'
25 BAN_REASON_SPAM = 'Autoban: spam bot'
26
26
27 DEFAULT_PAGE = 1
27 DEFAULT_PAGE = 1
28
28
29
29
30 def all_tags(request):
31 """All tags list"""
32
33 context = _init_default_context(request)
34 context['all_tags'] = Tag.objects.get_not_empty_tags()
35
36 return render(request, 'boards/tags.html', context)
37
38
39 # TODO Maybe this jumper is not needed any more? Only as a hack to find some
30 # TODO Maybe this jumper is not needed any more? Only as a hack to find some
40 # post without knowing its thread
31 # post without knowing its thread
41 def jump_to_post(request, post_id):
32 def jump_to_post(request, post_id):
42 """Determine thread in which the requested post is and open it's page"""
33 """Determine thread in which the requested post is and open it's page"""
43
34
44 post = get_object_or_404(Post, id=post_id)
35 post = get_object_or_404(Post, id=post_id)
45
36
46 if not post.thread:
37 if not post.thread:
47 return redirect('thread', post_id=post.id)
38 return redirect('thread', post_id=post.id)
48 else:
39 else:
49 return redirect(reverse('thread', kwargs={'post_id': post.thread.id})
40 return redirect(reverse('thread', kwargs={'post_id': post.thread.id})
50 + '#' + str(post.id))
41 + '#' + str(post.id))
51
42
52
43
53 def authors(request):
44 def authors(request):
54 """Show authors list"""
45 """Show authors list"""
55
46
56 context = _init_default_context(request)
47 context = _init_default_context(request)
57 context['authors'] = boards.authors.authors
48 context['authors'] = boards.authors.authors
58
49
59 return render(request, 'boards/authors.html', context)
50 return render(request, 'boards/authors.html', context)
60
51
61
52
62 @transaction.atomic
53 @transaction.atomic
63 def delete(request, post_id):
54 def delete(request, post_id):
64 """Delete post"""
55 """Delete post"""
65
56
66 user = _get_user(request)
57 user = _get_user(request)
67 post = get_object_or_404(Post, id=post_id)
58 post = get_object_or_404(Post, id=post_id)
68
59
69 if user.is_moderator():
60 if user.is_moderator():
70 # TODO Show confirmation page before deletion
61 # TODO Show confirmation page before deletion
71 Post.objects.delete_post(post)
62 Post.objects.delete_post(post)
72
63
73 if not post.thread:
64 if not post.thread:
74 return _redirect_to_next(request)
65 return _redirect_to_next(request)
75 else:
66 else:
76 return redirect('thread', post_id=post.thread.id)
67 return redirect('thread', post_id=post.thread.id)
77
68
78
69
79 @transaction.atomic
70 @transaction.atomic
80 def ban(request, post_id):
71 def ban(request, post_id):
81 """Ban user"""
72 """Ban user"""
82
73
83 user = _get_user(request)
74 user = _get_user(request)
84 post = get_object_or_404(Post, id=post_id)
75 post = get_object_or_404(Post, id=post_id)
85
76
86 if user.is_moderator():
77 if user.is_moderator():
87 # TODO Show confirmation page before ban
78 # TODO Show confirmation page before ban
88 ban, created = Ban.objects.get_or_create(ip=post.poster_ip)
79 ban, created = Ban.objects.get_or_create(ip=post.poster_ip)
89 if created:
80 if created:
90 ban.reason = 'Banned for post ' + str(post_id)
81 ban.reason = 'Banned for post ' + str(post_id)
91 ban.save()
82 ban.save()
92
83
93 return _redirect_to_next(request)
84 return _redirect_to_next(request)
94
85
95
86
96 def page_404(request):
87 def page_404(request):
97 """Show page 404 (not found error)"""
88 """Show page 404 (not found error)"""
98
89
99 context = _init_default_context(request)
90 context = _init_default_context(request)
100 return render(request, 'boards/404.html', context)
91 return render(request, 'boards/404.html', context)
101
92
102
93
103 @transaction.atomic
94 @transaction.atomic
104 def tag_subscribe(request, tag_name):
95 def tag_subscribe(request, tag_name):
105 """Add tag to favorites"""
96 """Add tag to favorites"""
106
97
107 user = _get_user(request)
98 user = _get_user(request)
108 tag = get_object_or_404(Tag, name=tag_name)
99 tag = get_object_or_404(Tag, name=tag_name)
109
100
110 if not tag in user.fav_tags.all():
101 if not tag in user.fav_tags.all():
111 user.add_tag(tag)
102 user.add_tag(tag)
112
103
113 return _redirect_to_next(request)
104 return _redirect_to_next(request)
114
105
115
106
116 @transaction.atomic
107 @transaction.atomic
117 def tag_unsubscribe(request, tag_name):
108 def tag_unsubscribe(request, tag_name):
118 """Remove tag from favorites"""
109 """Remove tag from favorites"""
119
110
120 user = _get_user(request)
111 user = _get_user(request)
121 tag = get_object_or_404(Tag, name=tag_name)
112 tag = get_object_or_404(Tag, name=tag_name)
122
113
123 if tag in user.fav_tags.all():
114 if tag in user.fav_tags.all():
124 user.remove_tag(tag)
115 user.remove_tag(tag)
125
116
126 return _redirect_to_next(request)
117 return _redirect_to_next(request)
127
118
128
119
129 def static_page(request, name):
120 def static_page(request, name):
130 """Show a static page that needs only tags list and a CSS"""
121 """Show a static page that needs only tags list and a CSS"""
131
122
132 context = _init_default_context(request)
123 context = _init_default_context(request)
133 return render(request, 'boards/staticpages/' + name + '.html', context)
124 return render(request, 'boards/staticpages/' + name + '.html', context)
134
125
135
126
136 # TODO This has to be moved under the api module
127 # TODO This has to be moved under the api module
137 def api_get_post(request, post_id):
128 def api_get_post(request, post_id):
138 """
129 """
139 Get the JSON of a post. This can be
130 Get the JSON of a post. This can be
140 used as and API for external clients.
131 used as and API for external clients.
141 """
132 """
142
133
143 post = get_object_or_404(Post, id=post_id)
134 post = get_object_or_404(Post, id=post_id)
144
135
145 json = serializers.serialize("json", [post], fields=(
136 json = serializers.serialize("json", [post], fields=(
146 "pub_time", "_text_rendered", "title", "text", "image",
137 "pub_time", "_text_rendered", "title", "text", "image",
147 "image_width", "image_height", "replies", "tags"
138 "image_width", "image_height", "replies", "tags"
148 ))
139 ))
149
140
150 return HttpResponse(content=json)
141 return HttpResponse(content=json)
151
142
152
143
153 @cache_page(86400)
144 @cache_page(86400)
154 def cached_js_catalog(request, domain='djangojs', packages=None):
145 def cached_js_catalog(request, domain='djangojs', packages=None):
155 return javascript_catalog(request, domain, packages)
146 return javascript_catalog(request, domain, packages)
156
147
157
148
158 # TODO This method is deprecated and should be removed after switching to
149 # TODO This method is deprecated and should be removed after switching to
159 # class-based view
150 # class-based view
160 def _get_theme(request, user=None):
151 def _get_theme(request, user=None):
161 """Get user's CSS theme"""
152 """Get user's CSS theme"""
162
153
163 if not user:
154 if not user:
164 user = _get_user(request)
155 user = _get_user(request)
165 theme = user.get_setting('theme')
156 theme = user.get_setting('theme')
166 if not theme:
157 if not theme:
167 theme = neboard.settings.DEFAULT_THEME
158 theme = neboard.settings.DEFAULT_THEME
168
159
169 return theme
160 return theme
170
161
171
162
172 # TODO This method is deprecated and should be removed after switching to
163 # TODO This method is deprecated and should be removed after switching to
173 # class-based view
164 # class-based view
174 def _init_default_context(request):
165 def _init_default_context(request):
175 """Create context with default values that are used in most views"""
166 """Create context with default values that are used in most views"""
176
167
177 context = RequestContext(request)
168 context = RequestContext(request)
178
169
179 user = _get_user(request)
170 user = _get_user(request)
180 context['user'] = user
171 context['user'] = user
181 context['tags'] = user.get_sorted_fav_tags()
172 context['tags'] = user.get_sorted_fav_tags()
182 context['posts_per_day'] = float(Post.objects.get_posts_per_day())
173 context['posts_per_day'] = float(Post.objects.get_posts_per_day())
183
174
184 theme = _get_theme(request, user)
175 theme = _get_theme(request, user)
185 context['theme'] = theme
176 context['theme'] = theme
186 context['theme_css'] = 'css/' + theme + '/base_page.css'
177 context['theme_css'] = 'css/' + theme + '/base_page.css'
187
178
188 # This shows the moderator panel
179 # This shows the moderator panel
189 moderate = user.get_setting(SETTING_MODERATE)
180 moderate = user.get_setting(SETTING_MODERATE)
190 if moderate == 'True':
181 if moderate == 'True':
191 context['moderator'] = user.is_moderator()
182 context['moderator'] = user.is_moderator()
192 else:
183 else:
193 context['moderator'] = False
184 context['moderator'] = False
194
185
195 return context
186 return context
196
187
197
188
198 # TODO This method is deprecated and should be removed after switching to
189 # TODO This method is deprecated and should be removed after switching to
199 # class-based view
190 # class-based view
200 def _get_user(request):
191 def _get_user(request):
201 """
192 """
202 Get current user from the session. If the user does not exist, create
193 Get current user from the session. If the user does not exist, create
203 a new one.
194 a new one.
204 """
195 """
205
196
206 session = request.session
197 session = request.session
207 if not 'user_id' in session:
198 if not 'user_id' in session:
208 request.session.save()
199 request.session.save()
209
200
210 md5 = hashlib.md5()
201 md5 = hashlib.md5()
211 md5.update(session.session_key)
202 md5.update(session.session_key)
212 new_id = md5.hexdigest()
203 new_id = md5.hexdigest()
213
204
214 while User.objects.filter(user_id=new_id).exists():
205 while User.objects.filter(user_id=new_id).exists():
215 md5.update(str(timezone.now()))
206 md5.update(str(timezone.now()))
216 new_id = md5.hexdigest()
207 new_id = md5.hexdigest()
217
208
218 time_now = timezone.now()
209 time_now = timezone.now()
219 user = User.objects.create(user_id=new_id, rank=RANK_USER,
210 user = User.objects.create(user_id=new_id, rank=RANK_USER,
220 registration_time=time_now)
211 registration_time=time_now)
221
212
222 # TODO This is just a test. This method should be removed
213 # TODO This is just a test. This method should be removed
223 # _delete_old_users()
214 # _delete_old_users()
224
215
225 session['user_id'] = user.id
216 session['user_id'] = user.id
226 else:
217 else:
227 user = User.objects.get(id=session['user_id'])
218 user = User.objects.get(id=session['user_id'])
228
219
229 return user
220 return user
230
221
231
222
232 def _redirect_to_next(request):
223 def _redirect_to_next(request):
233 """
224 """
234 If a 'next' parameter was specified, redirect to the next page. This is
225 If a 'next' parameter was specified, redirect to the next page. This is
235 used when the user is required to return to some page after the current
226 used when the user is required to return to some page after the current
236 view has finished its work.
227 view has finished its work.
237 """
228 """
238
229
239 if 'next' in request.GET:
230 if 'next' in request.GET:
240 next_page = request.GET['next']
231 next_page = request.GET['next']
241 return HttpResponseRedirect(next_page)
232 return HttpResponseRedirect(next_page)
242 else:
233 else:
243 return redirect('index')
234 return redirect('index')
General Comments 0
You need to be logged in to leave comments. Login now