Show More
@@ -0,0 +1,3 b'' | |||||
|
1 | from boards.views.thread.thread import ThreadView | |||
|
2 | from boards.views.thread.normal import NormalThreadView | |||
|
3 | from boards.views.thread.gallery import GalleryThreadView |
@@ -0,0 +1,19 b'' | |||||
|
1 | from boards.views.thread import ThreadView | |||
|
2 | ||||
|
3 | TEMPLATE_GALLERY = 'boards/thread_gallery.html' | |||
|
4 | ||||
|
5 | CONTEXT_POSTS = 'posts' | |||
|
6 | ||||
|
7 | ||||
|
8 | class GalleryThreadView(ThreadView): | |||
|
9 | ||||
|
10 | def get_template(self): | |||
|
11 | return TEMPLATE_GALLERY | |||
|
12 | ||||
|
13 | def get_data(self, thread): | |||
|
14 | params = dict() | |||
|
15 | ||||
|
16 | params[CONTEXT_POSTS] = thread.get_replies_with_images( | |||
|
17 | view_fields_only=True) | |||
|
18 | ||||
|
19 | return params |
@@ -0,0 +1,38 b'' | |||||
|
1 | from boards import settings | |||
|
2 | from boards.views.thread import ThreadView | |||
|
3 | ||||
|
4 | TEMPLATE_NORMAL = 'boards/thread.html' | |||
|
5 | ||||
|
6 | CONTEXT_OP = 'opening_post' | |||
|
7 | CONTEXT_BUMPLIMIT_PRG = 'bumplimit_progress' | |||
|
8 | CONTEXT_POSTS_LEFT = 'posts_left' | |||
|
9 | CONTEXT_BUMPABLE = 'bumpable' | |||
|
10 | ||||
|
11 | FORM_TITLE = 'title' | |||
|
12 | FORM_TEXT = 'text' | |||
|
13 | FORM_IMAGE = 'image' | |||
|
14 | ||||
|
15 | MODE_GALLERY = 'gallery' | |||
|
16 | MODE_NORMAL = 'normal' | |||
|
17 | ||||
|
18 | ||||
|
19 | class NormalThreadView(ThreadView): | |||
|
20 | ||||
|
21 | def get_template(self): | |||
|
22 | return TEMPLATE_NORMAL | |||
|
23 | ||||
|
24 | def get_data(self, thread): | |||
|
25 | params = dict() | |||
|
26 | ||||
|
27 | bumpable = thread.can_bump() | |||
|
28 | params[CONTEXT_BUMPABLE] = bumpable | |||
|
29 | if bumpable: | |||
|
30 | left_posts = settings.MAX_POSTS_PER_THREAD \ | |||
|
31 | - thread.get_reply_count() | |||
|
32 | params[CONTEXT_POSTS_LEFT] = left_posts | |||
|
33 | params[CONTEXT_BUMPLIMIT_PRG] = str( | |||
|
34 | float(left_posts) / settings.MAX_POSTS_PER_THREAD * 100) | |||
|
35 | ||||
|
36 | params[CONTEXT_OP] = thread.get_opening_post() | |||
|
37 | ||||
|
38 | return params |
@@ -0,0 +1,135 b'' | |||||
|
1 | from django.core.urlresolvers import reverse | |||
|
2 | from django.db import transaction | |||
|
3 | from django.http import Http404 | |||
|
4 | from django.shortcuts import get_object_or_404, render, redirect | |||
|
5 | from django.views.generic.edit import FormMixin | |||
|
6 | ||||
|
7 | from boards import utils, settings | |||
|
8 | from boards.forms import PostForm, PlainErrorList | |||
|
9 | from boards.models import Post, Ban | |||
|
10 | from boards.views.banned import BannedView | |||
|
11 | from boards.views.base import BaseBoardView, CONTEXT_FORM | |||
|
12 | from boards.views.posting_mixin import PostMixin | |||
|
13 | import neboard | |||
|
14 | ||||
|
15 | TEMPLATE_GALLERY = 'boards/thread_gallery.html' | |||
|
16 | TEMPLATE_NORMAL = 'boards/thread.html' | |||
|
17 | ||||
|
18 | CONTEXT_POSTS = 'posts' | |||
|
19 | CONTEXT_OP = 'opening_post' | |||
|
20 | CONTEXT_BUMPLIMIT_PRG = 'bumplimit_progress' | |||
|
21 | CONTEXT_POSTS_LEFT = 'posts_left' | |||
|
22 | CONTEXT_LASTUPDATE = "last_update" | |||
|
23 | CONTEXT_MAX_REPLIES = 'max_replies' | |||
|
24 | CONTEXT_THREAD = 'thread' | |||
|
25 | CONTEXT_BUMPABLE = 'bumpable' | |||
|
26 | CONTEXT_WS_TOKEN = 'ws_token' | |||
|
27 | CONTEXT_WS_PROJECT = 'ws_project' | |||
|
28 | CONTEXT_WS_HOST = 'ws_host' | |||
|
29 | CONTEXT_WS_PORT = 'ws_port' | |||
|
30 | ||||
|
31 | FORM_TITLE = 'title' | |||
|
32 | FORM_TEXT = 'text' | |||
|
33 | FORM_IMAGE = 'image' | |||
|
34 | ||||
|
35 | ||||
|
36 | class ThreadView(BaseBoardView, PostMixin, FormMixin): | |||
|
37 | ||||
|
38 | def get(self, request, post_id, form=None): | |||
|
39 | try: | |||
|
40 | opening_post = Post.objects.filter(id=post_id).only('thread_new')[0] | |||
|
41 | except IndexError: | |||
|
42 | raise Http404 | |||
|
43 | ||||
|
44 | # If this is not OP, don't show it as it is | |||
|
45 | if not opening_post or not opening_post.is_opening(): | |||
|
46 | raise Http404 | |||
|
47 | ||||
|
48 | if not form: | |||
|
49 | form = PostForm(error_class=PlainErrorList) | |||
|
50 | ||||
|
51 | thread_to_show = opening_post.get_thread() | |||
|
52 | ||||
|
53 | params = dict() | |||
|
54 | ||||
|
55 | params[CONTEXT_FORM] = form | |||
|
56 | params[CONTEXT_LASTUPDATE] = str(utils.datetime_to_epoch( | |||
|
57 | thread_to_show.last_edit_time)) | |||
|
58 | params[CONTEXT_THREAD] = thread_to_show | |||
|
59 | params[CONTEXT_MAX_REPLIES] = settings.MAX_POSTS_PER_THREAD | |||
|
60 | ||||
|
61 | if settings.WEBSOCKETS_ENABLED: | |||
|
62 | params[CONTEXT_WS_TOKEN] = utils.get_websocket_token( | |||
|
63 | timestamp=params[CONTEXT_LASTUPDATE]) | |||
|
64 | params[CONTEXT_WS_PROJECT] = neboard.settings.CENTRIFUGE_PROJECT_ID | |||
|
65 | params[CONTEXT_WS_HOST] = request.get_host().split(':')[0] | |||
|
66 | params[CONTEXT_WS_PORT] = neboard.settings.CENTRIFUGE_PORT | |||
|
67 | ||||
|
68 | params.update(self.get_data(thread_to_show)) | |||
|
69 | ||||
|
70 | return render(request, self.get_template(), params) | |||
|
71 | ||||
|
72 | def post(self, request, post_id): | |||
|
73 | opening_post = get_object_or_404(Post, id=post_id) | |||
|
74 | ||||
|
75 | # If this is not OP, don't show it as it is | |||
|
76 | if not opening_post.is_opening(): | |||
|
77 | raise Http404 | |||
|
78 | ||||
|
79 | if not opening_post.get_thread().archived: | |||
|
80 | form = PostForm(request.POST, request.FILES, | |||
|
81 | error_class=PlainErrorList) | |||
|
82 | form.session = request.session | |||
|
83 | ||||
|
84 | if form.is_valid(): | |||
|
85 | return self.new_post(request, form, opening_post) | |||
|
86 | if form.need_to_ban: | |||
|
87 | # Ban user because he is suspected to be a bot | |||
|
88 | self._ban_current_user(request) | |||
|
89 | ||||
|
90 | return self.get(request, post_id, form) | |||
|
91 | ||||
|
92 | def new_post(self, request, form, opening_post=None, html_response=True): | |||
|
93 | """ | |||
|
94 | Adds a new post (in thread or as a reply). | |||
|
95 | """ | |||
|
96 | ||||
|
97 | ip = utils.get_client_ip(request) | |||
|
98 | ||||
|
99 | data = form.cleaned_data | |||
|
100 | ||||
|
101 | title = data[FORM_TITLE] | |||
|
102 | text = data[FORM_TEXT] | |||
|
103 | image = data.get(FORM_IMAGE) | |||
|
104 | ||||
|
105 | text = self._remove_invalid_links(text) | |||
|
106 | ||||
|
107 | post_thread = opening_post.get_thread() | |||
|
108 | ||||
|
109 | post = Post.objects.create_post(title=title, text=text, image=image, | |||
|
110 | thread=post_thread, ip=ip) | |||
|
111 | post.send_to_websocket(request) | |||
|
112 | ||||
|
113 | thread_to_show = (opening_post.id if opening_post else post.id) | |||
|
114 | ||||
|
115 | if html_response: | |||
|
116 | if opening_post: | |||
|
117 | return redirect( | |||
|
118 | reverse('thread', kwargs={'post_id': thread_to_show}) | |||
|
119 | + '#' + str(post.id)) | |||
|
120 | else: | |||
|
121 | return post | |||
|
122 | ||||
|
123 | def get_data(self, thread): | |||
|
124 | """ | |||
|
125 | Returns context params for the view. | |||
|
126 | """ | |||
|
127 | ||||
|
128 | pass | |||
|
129 | ||||
|
130 | def get_template(self): | |||
|
131 | """ | |||
|
132 | Gets template to show the thread mode on. | |||
|
133 | """ | |||
|
134 | ||||
|
135 | pass |
@@ -1,60 +1,60 b'' | |||||
1 | {% load staticfiles %} |
|
1 | {% load staticfiles %} | |
2 | {% load i18n %} |
|
2 | {% load i18n %} | |
3 | {% load l10n %} |
|
3 | {% load l10n %} | |
4 | {% load static from staticfiles %} |
|
4 | {% load static from staticfiles %} | |
5 |
|
5 | |||
6 | <!DOCTYPE html> |
|
6 | <!DOCTYPE html> | |
7 | <html> |
|
7 | <html> | |
8 | <head> |
|
8 | <head> | |
9 | <link rel="stylesheet" type="text/css" href="{% static 'css/base.css' %}" media="all"/> |
|
9 | <link rel="stylesheet" type="text/css" href="{% static 'css/base.css' %}" media="all"/> | |
10 | <link rel="stylesheet" type="text/css" href="{% static 'css/3party/highlight.css' %}" media="all"/> |
|
10 | <link rel="stylesheet" type="text/css" href="{% static 'css/3party/highlight.css' %}" media="all"/> | |
11 | <link rel="stylesheet" type="text/css" href="{% static theme_css %}" media="all"/> |
|
11 | <link rel="stylesheet" type="text/css" href="{% static theme_css %}" media="all"/> | |
12 |
|
12 | |||
13 | <link rel="alternate" type="application/rss+xml" href="rss/" title="{% trans 'Feed' %}"/> |
|
13 | <link rel="alternate" type="application/rss+xml" href="rss/" title="{% trans 'Feed' %}"/> | |
14 |
|
14 | |||
15 | <link rel="icon" type="image/png" |
|
15 | <link rel="icon" type="image/png" | |
16 | href="{% static 'favicon.png' %}"> |
|
16 | href="{% static 'favicon.png' %}"> | |
17 |
|
17 | |||
18 | <meta name="viewport" content="width=device-width, initial-scale=1"/> |
|
18 | <meta name="viewport" content="width=device-width, initial-scale=1"/> | |
19 | <meta charset="utf-8"/> |
|
19 | <meta charset="utf-8"/> | |
20 |
|
20 | |||
21 | {% block head %}{% endblock %} |
|
21 | {% block head %}{% endblock %} | |
22 | </head> |
|
22 | </head> | |
23 | <body> |
|
23 | <body> | |
24 | <script src="{% static 'js/jquery-2.0.1.min.js' %}"></script> |
|
24 | <script src="{% static 'js/jquery-2.0.1.min.js' %}"></script> | |
25 | <script src="{% static 'js/jquery-ui-1.10.3.custom.min.js' %}"></script> |
|
25 | <script src="{% static 'js/jquery-ui-1.10.3.custom.min.js' %}"></script> | |
26 | <script src="{% static 'js/jquery.mousewheel.js' %}"></script> |
|
26 | <script src="{% static 'js/jquery.mousewheel.js' %}"></script> | |
27 | <script src="{% url 'js_info_dict' %}"></script> |
|
27 | <script src="{% url 'js_info_dict' %}"></script> | |
28 |
|
28 | |||
29 | <div class="navigation_panel header"> |
|
29 | <div class="navigation_panel header"> | |
30 | <a class="link" href="{% url 'index' %}">{% trans "All threads" %}</a> |
|
30 | <a class="link" href="{% url 'index' %}">{% trans "All threads" %}</a> | |
31 | {% for tag in tags %} |
|
31 | {% for tag in tags %} | |
32 | {% autoescape off %} |
|
32 | {% autoescape off %} | |
33 |
{{ tag.get_view }} |
|
33 | {{ tag.get_view }}, | |
34 | {% endautoescape %} |
|
34 | {% endautoescape %} | |
35 | {% endfor %} |
|
35 | {% endfor %} | |
36 | <a href="{% url 'tags' %}" title="{% trans 'Tag management' %}" |
|
36 | <a href="{% url 'tags' %}" title="{% trans 'Tag management' %}" | |
37 | >[...]</a>, |
|
37 | >[...]</a>, | |
38 | <a href="{% url 'search' %}" title="{% trans 'Search' %}">[S]</a> |
|
38 | <a href="{% url 'search' %}" title="{% trans 'Search' %}">[S]</a> | |
39 | <a class="link" href="{% url 'settings' %}">{% trans 'Settings' %}</a> |
|
39 | <a class="link" href="{% url 'settings' %}">{% trans 'Settings' %}</a> | |
40 | </div> |
|
40 | </div> | |
41 |
|
41 | |||
42 | {% block content %}{% endblock %} |
|
42 | {% block content %}{% endblock %} | |
43 |
|
43 | |||
44 | <script src="{% static 'js/3party/highlight.min.js' %}"></script> |
|
44 | <script src="{% static 'js/3party/highlight.min.js' %}"></script> | |
45 | <script src="{% static 'js/popup.js' %}"></script> |
|
45 | <script src="{% static 'js/popup.js' %}"></script> | |
46 | <script src="{% static 'js/image.js' %}"></script> |
|
46 | <script src="{% static 'js/image.js' %}"></script> | |
47 | <script src="{% static 'js/refpopup.js' %}"></script> |
|
47 | <script src="{% static 'js/refpopup.js' %}"></script> | |
48 | <script src="{% static 'js/main.js' %}"></script> |
|
48 | <script src="{% static 'js/main.js' %}"></script> | |
49 |
|
49 | |||
50 | <div class="navigation_panel footer"> |
|
50 | <div class="navigation_panel footer"> | |
51 | {% block metapanel %}{% endblock %} |
|
51 | {% block metapanel %}{% endblock %} | |
52 | [<a href="{% url 'admin:index' %}">{% trans 'Admin' %}</a>] |
|
52 | [<a href="{% url 'admin:index' %}">{% trans 'Admin' %}</a>] | |
53 | {% with ppd=posts_per_day|floatformat:2 %} |
|
53 | {% with ppd=posts_per_day|floatformat:2 %} | |
54 | {% blocktrans %}Speed: {{ ppd }} posts per day{% endblocktrans %} |
|
54 | {% blocktrans %}Speed: {{ ppd }} posts per day{% endblocktrans %} | |
55 | {% endwith %} |
|
55 | {% endwith %} | |
56 | <a class="link" href="#top">{% trans 'Up' %}</a> |
|
56 | <a class="link" href="#top">{% trans 'Up' %}</a> | |
57 | </div> |
|
57 | </div> | |
58 |
|
58 | |||
59 | </body> |
|
59 | </body> | |
60 | </html> |
|
60 | </html> |
@@ -1,96 +1,96 b'' | |||||
1 | {% extends "boards/base.html" %} |
|
1 | {% extends "boards/base.html" %} | |
2 |
|
2 | |||
3 | {% load i18n %} |
|
3 | {% load i18n %} | |
4 | {% load cache %} |
|
4 | {% load cache %} | |
5 | {% load static from staticfiles %} |
|
5 | {% load static from staticfiles %} | |
6 | {% load board %} |
|
6 | {% load board %} | |
7 |
|
7 | |||
8 | {% block head %} |
|
8 | {% block head %} | |
9 | <title>{{ opening_post.get_title|striptags|truncatewords:10 }} |
|
9 | <title>{{ opening_post.get_title|striptags|truncatewords:10 }} | |
10 | - {{ site_name }}</title> |
|
10 | - {{ site_name }}</title> | |
11 | {% endblock %} |
|
11 | {% endblock %} | |
12 |
|
12 | |||
13 | {% block content %} |
|
13 | {% block content %} | |
14 | {% get_current_language as LANGUAGE_CODE %} |
|
14 | {% get_current_language as LANGUAGE_CODE %} | |
15 |
|
15 | |||
16 | {% cache 600 thread_view thread.id thread.last_edit_time moderator LANGUAGE_CODE %} |
|
16 | {% cache 600 thread_view thread.id thread.last_edit_time moderator LANGUAGE_CODE %} | |
17 |
|
17 | |||
18 | <div class="image-mode-tab"> |
|
18 | <div class="image-mode-tab"> | |
19 | <a class="current_mode" href="{% url 'thread' opening_post.id %}">{% trans 'Normal mode' %}</a>, |
|
19 | <a class="current_mode" href="{% url 'thread' opening_post.id %}">{% trans 'Normal mode' %}</a>, | |
20 |
<a href="{% url 'thread_ |
|
20 | <a href="{% url 'thread_gallery' opening_post.id %}">{% trans 'Gallery mode' %}</a> | |
21 | </div> |
|
21 | </div> | |
22 |
|
22 | |||
23 | {% if bumpable %} |
|
23 | {% if bumpable %} | |
24 | <div class="bar-bg"> |
|
24 | <div class="bar-bg"> | |
25 | <div class="bar-value" style="width:{{ bumplimit_progress }}%" id="bumplimit_progress"> |
|
25 | <div class="bar-value" style="width:{{ bumplimit_progress }}%" id="bumplimit_progress"> | |
26 | </div> |
|
26 | </div> | |
27 | <div class="bar-text"> |
|
27 | <div class="bar-text"> | |
28 | <span id="left_to_limit">{{ posts_left }}</span> {% trans 'posts to bumplimit' %} |
|
28 | <span id="left_to_limit">{{ posts_left }}</span> {% trans 'posts to bumplimit' %} | |
29 | </div> |
|
29 | </div> | |
30 | </div> |
|
30 | </div> | |
31 | {% endif %} |
|
31 | {% endif %} | |
32 |
|
32 | |||
33 | <div class="thread"> |
|
33 | <div class="thread"> | |
34 | {% with can_bump=thread.can_bump %} |
|
34 | {% with can_bump=thread.can_bump %} | |
35 | {% for post in thread.get_replies %} |
|
35 | {% for post in thread.get_replies %} | |
36 | {% with is_opening=forloop.first %} |
|
36 | {% with is_opening=forloop.first %} | |
37 | {% post_view post moderator=moderator is_opening=is_opening thread=thread bumpable=can_bump opening_post_id=opening_post.id %} |
|
37 | {% post_view post moderator=moderator is_opening=is_opening thread=thread bumpable=can_bump opening_post_id=opening_post.id %} | |
38 | {% endwith %} |
|
38 | {% endwith %} | |
39 | {% endfor %} |
|
39 | {% endfor %} | |
40 | {% endwith %} |
|
40 | {% endwith %} | |
41 | </div> |
|
41 | </div> | |
42 |
|
42 | |||
43 | {% if not thread.archived %} |
|
43 | {% if not thread.archived %} | |
44 | <div class="post-form-w" id="form"> |
|
44 | <div class="post-form-w" id="form"> | |
45 | <script src="{% static 'js/panel.js' %}"></script> |
|
45 | <script src="{% static 'js/panel.js' %}"></script> | |
46 | <div class="form-title">{% trans "Reply to thread" %} #{{ opening_post.id }}</div> |
|
46 | <div class="form-title">{% trans "Reply to thread" %} #{{ opening_post.id }}</div> | |
47 | <div class="post-form" id="compact-form"> |
|
47 | <div class="post-form" id="compact-form"> | |
48 | <div class="swappable-form-full"> |
|
48 | <div class="swappable-form-full"> | |
49 | <form enctype="multipart/form-data" method="post" |
|
49 | <form enctype="multipart/form-data" method="post" | |
50 | >{% csrf_token %} |
|
50 | >{% csrf_token %} | |
51 | <div class="compact-form-text"></div> |
|
51 | <div class="compact-form-text"></div> | |
52 | {{ form.as_div }} |
|
52 | {{ form.as_div }} | |
53 | <div class="form-submit"> |
|
53 | <div class="form-submit"> | |
54 | <input type="submit" value="{% trans "Post" %}"/> |
|
54 | <input type="submit" value="{% trans "Post" %}"/> | |
55 | </div> |
|
55 | </div> | |
56 | </form> |
|
56 | </form> | |
57 | </div> |
|
57 | </div> | |
58 | <a onclick="swapForm(); return false;" href="#"> |
|
58 | <a onclick="swapForm(); return false;" href="#"> | |
59 | {% trans 'Switch mode' %} |
|
59 | {% trans 'Switch mode' %} | |
60 | </a> |
|
60 | </a> | |
61 | <div><a href="{% url "staticpage" name="help" %}"> |
|
61 | <div><a href="{% url "staticpage" name="help" %}"> | |
62 | {% trans 'Text syntax' %}</a></div> |
|
62 | {% trans 'Text syntax' %}</a></div> | |
63 | </div> |
|
63 | </div> | |
64 | </div> |
|
64 | </div> | |
65 |
|
65 | |||
66 | <script src="{% static 'js/jquery.form.min.js' %}"></script> |
|
66 | <script src="{% static 'js/jquery.form.min.js' %}"></script> | |
67 | <script src="{% static 'js/thread_update.js' %}"></script> |
|
67 | <script src="{% static 'js/thread_update.js' %}"></script> | |
68 | <script src="{% static 'js/3party/centrifuge.js' %}"></script> |
|
68 | <script src="{% static 'js/3party/centrifuge.js' %}"></script> | |
69 | {% endif %} |
|
69 | {% endif %} | |
70 |
|
70 | |||
71 | <script src="{% static 'js/form.js' %}"></script> |
|
71 | <script src="{% static 'js/form.js' %}"></script> | |
72 | <script src="{% static 'js/thread.js' %}"></script> |
|
72 | <script src="{% static 'js/thread.js' %}"></script> | |
73 |
|
73 | |||
74 | {% endcache %} |
|
74 | {% endcache %} | |
75 | {% endblock %} |
|
75 | {% endblock %} | |
76 |
|
76 | |||
77 | {% block metapanel %} |
|
77 | {% block metapanel %} | |
78 |
|
78 | |||
79 | {% get_current_language as LANGUAGE_CODE %} |
|
79 | {% get_current_language as LANGUAGE_CODE %} | |
80 |
|
80 | |||
81 | <span class="metapanel" |
|
81 | <span class="metapanel" | |
82 | data-last-update="{{ last_update }}" |
|
82 | data-last-update="{{ last_update }}" | |
83 | data-ws-token="{{ ws_token }}" |
|
83 | data-ws-token="{{ ws_token }}" | |
84 | data-ws-project="{{ ws_project }}" |
|
84 | data-ws-project="{{ ws_project }}" | |
85 | data-ws-host="{{ ws_host }}" |
|
85 | data-ws-host="{{ ws_host }}" | |
86 | data-ws-port="{{ ws_port }}"> |
|
86 | data-ws-port="{{ ws_port }}"> | |
87 | {% cache 600 thread_meta thread.last_edit_time moderator LANGUAGE_CODE %} |
|
87 | {% cache 600 thread_meta thread.last_edit_time moderator LANGUAGE_CODE %} | |
88 | <span id="autoupdate">[-]</span> |
|
88 | <span id="autoupdate">[-]</span> | |
89 | <span id="reply-count">{{ thread.get_reply_count }}</span>/{{ max_replies }} {% trans 'messages' %}, |
|
89 | <span id="reply-count">{{ thread.get_reply_count }}</span>/{{ max_replies }} {% trans 'messages' %}, | |
90 | <span id="image-count">{{ thread.get_images_count }}</span> {% trans 'images' %}. |
|
90 | <span id="image-count">{{ thread.get_images_count }}</span> {% trans 'images' %}. | |
91 | {% trans 'Last update: ' %}<span id="last-update">{{ thread.last_edit_time }}</span> |
|
91 | {% trans 'Last update: ' %}<span id="last-update">{{ thread.last_edit_time }}</span> | |
92 | [<a href="rss/">RSS</a>] |
|
92 | [<a href="rss/">RSS</a>] | |
93 | {% endcache %} |
|
93 | {% endcache %} | |
94 | </span> |
|
94 | </span> | |
95 |
|
95 | |||
96 | {% endblock %} |
|
96 | {% endblock %} |
@@ -1,66 +1,66 b'' | |||||
1 | {% extends "boards/base.html" %} |
|
1 | {% extends "boards/base.html" %} | |
2 |
|
2 | |||
3 | {% load i18n %} |
|
3 | {% load i18n %} | |
4 | {% load cache %} |
|
4 | {% load cache %} | |
5 | {% load static from staticfiles %} |
|
5 | {% load static from staticfiles %} | |
6 | {% load board %} |
|
6 | {% load board %} | |
7 |
|
7 | |||
8 | {% block head %} |
|
8 | {% block head %} | |
9 | <title>{{ thread.get_opening_post.get_title|striptags|truncatewords:10 }} |
|
9 | <title>{{ thread.get_opening_post.get_title|striptags|truncatewords:10 }} | |
10 | - {{ site_name }}</title> |
|
10 | - {{ site_name }}</title> | |
11 | {% endblock %} |
|
11 | {% endblock %} | |
12 |
|
12 | |||
13 | {% block content %} |
|
13 | {% block content %} | |
14 | {% spaceless %} |
|
14 | {% spaceless %} | |
15 | {% get_current_language as LANGUAGE_CODE %} |
|
15 | {% get_current_language as LANGUAGE_CODE %} | |
16 |
|
16 | |||
17 | {% cache 600 thread_gallery_view thread.id thread.last_edit_time LANGUAGE_CODE request.get_host %} |
|
17 | {% cache 600 thread_gallery_view thread.id thread.last_edit_time LANGUAGE_CODE request.get_host %} | |
18 | <div class="image-mode-tab"> |
|
18 | <div class="image-mode-tab"> | |
19 | <a href="{% url 'thread' thread.get_opening_post.id %}">{% trans 'Normal mode' %}</a>, |
|
19 | <a href="{% url 'thread' thread.get_opening_post.id %}">{% trans 'Normal mode' %}</a>, | |
20 |
<a class="current_mode" href="{% url 'thread_ |
|
20 | <a class="current_mode" href="{% url 'thread_gallery' thread.get_opening_post.id %}">{% trans 'Gallery mode' %}</a> | |
21 | </div> |
|
21 | </div> | |
22 |
|
22 | |||
23 | <div id="posts-table"> |
|
23 | <div id="posts-table"> | |
24 | {% for post in posts %} |
|
24 | {% for post in posts %} | |
25 | <div class="gallery_image"> |
|
25 | <div class="gallery_image"> | |
26 | {% with post.get_first_image as image %} |
|
26 | {% with post.get_first_image as image %} | |
27 | <div> |
|
27 | <div> | |
28 | <a |
|
28 | <a | |
29 | class="thumb" |
|
29 | class="thumb" | |
30 | href="{{ image.image.url }}"><img |
|
30 | href="{{ image.image.url }}"><img | |
31 | src="{{ image.image.url_200x150 }}" |
|
31 | src="{{ image.image.url_200x150 }}" | |
32 | alt="{{ post.id }}" |
|
32 | alt="{{ post.id }}" | |
33 | width="{{ image.pre_width }}" |
|
33 | width="{{ image.pre_width }}" | |
34 | height="{{ image.pre_height }}" |
|
34 | height="{{ image.pre_height }}" | |
35 | data-width="{{ image.width }}" |
|
35 | data-width="{{ image.width }}" | |
36 | data-height="{{ image.height }}"/> |
|
36 | data-height="{{ image.height }}"/> | |
37 | </a> |
|
37 | </a> | |
38 | </div> |
|
38 | </div> | |
39 | <div class="gallery_image_metadata"> |
|
39 | <div class="gallery_image_metadata"> | |
40 | {{ image.width }}x{{ image.height }} |
|
40 | {{ image.width }}x{{ image.height }} | |
41 | {% image_actions image.image.url request.get_host %} |
|
41 | {% image_actions image.image.url request.get_host %} | |
42 | </div> |
|
42 | </div> | |
43 | {% endwith %} |
|
43 | {% endwith %} | |
44 | </div> |
|
44 | </div> | |
45 | {% endfor %} |
|
45 | {% endfor %} | |
46 | </div> |
|
46 | </div> | |
47 | {% endcache %} |
|
47 | {% endcache %} | |
48 |
|
48 | |||
49 | {% endspaceless %} |
|
49 | {% endspaceless %} | |
50 | {% endblock %} |
|
50 | {% endblock %} | |
51 |
|
51 | |||
52 | {% block metapanel %} |
|
52 | {% block metapanel %} | |
53 |
|
53 | |||
54 | {% get_current_language as LANGUAGE_CODE %} |
|
54 | {% get_current_language as LANGUAGE_CODE %} | |
55 |
|
55 | |||
56 | <span class="metapanel" data-last-update="{{ last_update }}"> |
|
56 | <span class="metapanel" data-last-update="{{ last_update }}"> | |
57 | {% cache 600 thread_meta thread.last_edit_time moderator LANGUAGE_CODE %} |
|
57 | {% cache 600 thread_meta thread.last_edit_time moderator LANGUAGE_CODE %} | |
58 | <span id="reply-count">{{ thread.get_reply_count }}</span>/{{ max_replies }} |
|
58 | <span id="reply-count">{{ thread.get_reply_count }}</span>/{{ max_replies }} | |
59 | {% trans 'messages' %}, |
|
59 | {% trans 'messages' %}, | |
60 | <span id="image-count">{{ thread.get_images_count }}</span> {% trans 'images' %}. |
|
60 | <span id="image-count">{{ thread.get_images_count }}</span> {% trans 'images' %}. | |
61 | {% trans 'Last update: ' %}{{ thread.last_edit_time }} |
|
61 | {% trans 'Last update: ' %}{{ thread.last_edit_time }} | |
62 | [<a href="rss/">RSS</a>] |
|
62 | [<a href="rss/">RSS</a>] | |
63 | {% endcache %} |
|
63 | {% endcache %} | |
64 | </span> |
|
64 | </span> | |
65 |
|
65 | |||
66 | {% endblock %} |
|
66 | {% endblock %} |
@@ -1,75 +1,75 b'' | |||||
1 | from django.conf.urls import patterns, url, include |
|
1 | from django.conf.urls import patterns, url, include | |
2 | from django.contrib import admin |
|
2 | from django.contrib import admin | |
3 | from boards import views |
|
3 | from boards import views | |
4 | from boards.rss import AllThreadsFeed, TagThreadsFeed, ThreadPostsFeed |
|
4 | from boards.rss import AllThreadsFeed, TagThreadsFeed, ThreadPostsFeed | |
5 | from boards.views import api, tag_threads, all_threads, \ |
|
5 | from boards.views import api, tag_threads, all_threads, \ | |
6 | settings, all_tags |
|
6 | settings, all_tags | |
7 | from boards.views.authors import AuthorsView |
|
7 | from boards.views.authors import AuthorsView | |
8 | from boards.views.ban import BanUserView |
|
8 | from boards.views.ban import BanUserView | |
9 | from boards.views.search import BoardSearchView |
|
9 | from boards.views.search import BoardSearchView | |
10 | from boards.views.static import StaticPageView |
|
10 | from boards.views.static import StaticPageView | |
11 | from boards.views.preview import PostPreviewView |
|
11 | from boards.views.preview import PostPreviewView | |
12 |
|
12 | |||
13 | js_info_dict = { |
|
13 | js_info_dict = { | |
14 | 'packages': ('boards',), |
|
14 | 'packages': ('boards',), | |
15 | } |
|
15 | } | |
16 |
|
16 | |||
17 | urlpatterns = patterns('', |
|
17 | urlpatterns = patterns('', | |
18 | # /boards/ |
|
18 | # /boards/ | |
19 | url(r'^$', all_threads.AllThreadsView.as_view(), name='index'), |
|
19 | url(r'^$', all_threads.AllThreadsView.as_view(), name='index'), | |
20 | # /boards/page/ |
|
20 | # /boards/page/ | |
21 | url(r'^page/(?P<page>\w+)/$', all_threads.AllThreadsView.as_view(), |
|
21 | url(r'^page/(?P<page>\w+)/$', all_threads.AllThreadsView.as_view(), | |
22 | name='index'), |
|
22 | name='index'), | |
23 |
|
23 | |||
24 | # /boards/tag/tag_name/ |
|
24 | # /boards/tag/tag_name/ | |
25 | url(r'^tag/(?P<tag_name>\w+)/$', tag_threads.TagView.as_view(), |
|
25 | url(r'^tag/(?P<tag_name>\w+)/$', tag_threads.TagView.as_view(), | |
26 | name='tag'), |
|
26 | name='tag'), | |
27 | # /boards/tag/tag_id/page/ |
|
27 | # /boards/tag/tag_id/page/ | |
28 | url(r'^tag/(?P<tag_name>\w+)/page/(?P<page>\w+)/$', |
|
28 | url(r'^tag/(?P<tag_name>\w+)/page/(?P<page>\w+)/$', | |
29 | tag_threads.TagView.as_view(), name='tag'), |
|
29 | tag_threads.TagView.as_view(), name='tag'), | |
30 |
|
30 | |||
31 | # /boards/thread/ |
|
31 | # /boards/thread/ | |
32 | url(r'^thread/(?P<post_id>\w+)/$', views.thread.ThreadView.as_view(), |
|
32 | url(r'^thread/(?P<post_id>\w+)/$', views.thread.normal.NormalThreadView.as_view(), | |
33 | name='thread'), |
|
33 | name='thread'), | |
34 |
url(r'^thread/(?P<post_id>\w+)/mode/ |
|
34 | url(r'^thread/(?P<post_id>\w+)/mode/gallery/$', views.thread.gallery.GalleryThreadView.as_view(), | |
35 |
|
|
35 | name='thread_gallery'), | |
36 |
|
36 | |||
37 | url(r'^settings/$', settings.SettingsView.as_view(), name='settings'), |
|
37 | url(r'^settings/$', settings.SettingsView.as_view(), name='settings'), | |
38 | url(r'^tags/$', all_tags.AllTagsView.as_view(), name='tags'), |
|
38 | url(r'^tags/$', all_tags.AllTagsView.as_view(), name='tags'), | |
39 | url(r'^authors/$', AuthorsView.as_view(), name='authors'), |
|
39 | url(r'^authors/$', AuthorsView.as_view(), name='authors'), | |
40 | url(r'^ban/(?P<post_id>\w+)/$', BanUserView.as_view(), name='ban'), |
|
40 | url(r'^ban/(?P<post_id>\w+)/$', BanUserView.as_view(), name='ban'), | |
41 |
|
41 | |||
42 | url(r'^banned/$', views.banned.BannedView.as_view(), name='banned'), |
|
42 | url(r'^banned/$', views.banned.BannedView.as_view(), name='banned'), | |
43 | url(r'^staticpage/(?P<name>\w+)/$', StaticPageView.as_view(), |
|
43 | url(r'^staticpage/(?P<name>\w+)/$', StaticPageView.as_view(), | |
44 | name='staticpage'), |
|
44 | name='staticpage'), | |
45 |
|
45 | |||
46 | # RSS feeds |
|
46 | # RSS feeds | |
47 | url(r'^rss/$', AllThreadsFeed()), |
|
47 | url(r'^rss/$', AllThreadsFeed()), | |
48 | url(r'^page/(?P<page>\w+)/rss/$', AllThreadsFeed()), |
|
48 | url(r'^page/(?P<page>\w+)/rss/$', AllThreadsFeed()), | |
49 | url(r'^tag/(?P<tag_name>\w+)/rss/$', TagThreadsFeed()), |
|
49 | url(r'^tag/(?P<tag_name>\w+)/rss/$', TagThreadsFeed()), | |
50 | url(r'^tag/(?P<tag_name>\w+)/page/(?P<page>\w+)/rss/$', TagThreadsFeed()), |
|
50 | url(r'^tag/(?P<tag_name>\w+)/page/(?P<page>\w+)/rss/$', TagThreadsFeed()), | |
51 | url(r'^thread/(?P<post_id>\w+)/rss/$', ThreadPostsFeed()), |
|
51 | url(r'^thread/(?P<post_id>\w+)/rss/$', ThreadPostsFeed()), | |
52 |
|
52 | |||
53 | # i18n |
|
53 | # i18n | |
54 | url(r'^jsi18n/$', 'boards.views.cached_js_catalog', js_info_dict, |
|
54 | url(r'^jsi18n/$', 'boards.views.cached_js_catalog', js_info_dict, | |
55 | name='js_info_dict'), |
|
55 | name='js_info_dict'), | |
56 |
|
56 | |||
57 | # API |
|
57 | # API | |
58 | url(r'^api/post/(?P<post_id>\w+)/$', api.get_post, name="get_post"), |
|
58 | url(r'^api/post/(?P<post_id>\w+)/$', api.get_post, name="get_post"), | |
59 | url(r'^api/diff_thread/(?P<thread_id>\w+)/(?P<last_update_time>\w+)/$', |
|
59 | url(r'^api/diff_thread/(?P<thread_id>\w+)/(?P<last_update_time>\w+)/$', | |
60 | api.api_get_threaddiff, name="get_thread_diff"), |
|
60 | api.api_get_threaddiff, name="get_thread_diff"), | |
61 | url(r'^api/threads/(?P<count>\w+)/$', api.api_get_threads, |
|
61 | url(r'^api/threads/(?P<count>\w+)/$', api.api_get_threads, | |
62 | name='get_threads'), |
|
62 | name='get_threads'), | |
63 | url(r'^api/tags/$', api.api_get_tags, name='get_tags'), |
|
63 | url(r'^api/tags/$', api.api_get_tags, name='get_tags'), | |
64 | url(r'^api/thread/(?P<opening_post_id>\w+)/$', api.api_get_thread_posts, |
|
64 | url(r'^api/thread/(?P<opening_post_id>\w+)/$', api.api_get_thread_posts, | |
65 | name='get_thread'), |
|
65 | name='get_thread'), | |
66 | url(r'^api/add_post/(?P<opening_post_id>\w+)/$', api.api_add_post, |
|
66 | url(r'^api/add_post/(?P<opening_post_id>\w+)/$', api.api_add_post, | |
67 | name='add_post'), |
|
67 | name='add_post'), | |
68 |
|
68 | |||
69 | # Search |
|
69 | # Search | |
70 | url(r'^search/$', BoardSearchView.as_view(), name='search'), |
|
70 | url(r'^search/$', BoardSearchView.as_view(), name='search'), | |
71 |
|
71 | |||
72 | # Post preview |
|
72 | # Post preview | |
73 | url(r'^preview/$', PostPreviewView.as_view(), name='preview') |
|
73 | url(r'^preview/$', PostPreviewView.as_view(), name='preview') | |
74 |
|
74 | |||
75 | ) |
|
75 | ) |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now