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