##// END OF EJS Templates
Added a 'next' attribute to the delete page to return to the current page after deletion.
neko259 -
r155:9ad8583f default
parent child Browse files
Show More
@@ -1,180 +1,180 b''
1 1 {% extends "boards/base.html" %}
2 2
3 3 {% load i18n %}
4 4 {% load markup %}
5 5
6 6 {% block head %}
7 7 {% if tag %}
8 8 <title>Neboard - {{ tag }}</title>
9 9 {% else %}
10 10 <title>Neboard</title>
11 11 {% endif %}
12 12 {% endblock %}
13 13
14 14 {% block content %}
15 15
16 16 {% if tag %}
17 17 <div class="tag_info">
18 18 <h2>{% trans 'Tag: ' %}{{ tag }}</h2>
19 19 </div>
20 20 {% endif %}
21 21
22 22 {% if threads %}
23 23 {% for thread in threads %}
24 24 <div class="thread">
25 25 {% if thread.can_bump %}
26 26 <div class="post" id="{{thread.id}}">
27 27 {% else %}
28 28 <div class="post dead_post" id="{{ thread.id }}">
29 29 {% endif %}
30 30 {% if thread.image %}
31 31 <div class="image">
32 32 <a class="fancy"
33 33 href="{{ thread.image.url }}"><img
34 34 src="{{ thread.image.url_200x150 }}"
35 35 alt="{% trans 'Post image' %}"
36 36 data-width="{{ thread.image_width }}"
37 37 data-height="{{ thread.image_height }}" />
38 38 </a>
39 39 </div>
40 40 {% endif %}
41 41 <div class="message">
42 42 <div class="post-info">
43 43 <span class="title">{{ thread.title }}</span>
44 44 <a class="post_id" href="{% url 'thread' thread.id %}"
45 45 >(#{{ thread.id }})</a>
46 46 [{{ thread.pub_time }}]
47 47 [<a class="link" href="{% url 'thread' thread.id %}#form"
48 48 >{% trans "Reply" %}</a>]
49 49
50 50 {% if user.is_moderator %}
51 51 <span class="moderator_info">
52 52 ({{ thread.poster_ip }})
53 [<a href="{% url 'delete' post_id=thread.id %}"
53 [<a href="{% url 'delete' post_id=thread.id %}?next={{ request.path }}"
54 54 >{% trans 'Delete' %}</a>]
55 55 </span>
56 56 {% endif %}
57 57 </div>
58 58 {% autoescape off %}
59 59 {{ thread.text.rendered|truncatewords_html:50 }}
60 60 {% endautoescape %}
61 61 </div>
62 62 <div class="metadata">
63 63 {{ thread.get_reply_count }} {% trans 'replies' %},
64 64 {{ thread.get_images_count }} {% trans 'images' %}.
65 65 {% if thread.tags.all %}
66 66 <span class="tags">{% trans 'Tags' %}:
67 67 {% for tag in thread.tags.all %}
68 68 <a class="tag" href="
69 69 {% url 'tag' tag_name=tag.name %}">
70 70 {{ tag.name }}</a>
71 71 {% endfor %}
72 72 </span>
73 73 {% endif %}
74 74 </div>
75 75 </div>
76 76 {% if thread.get_last_replies %}
77 77 <div class="last-replies">
78 78 {% for post in thread.get_last_replies %}
79 79 {% if thread.can_bump %}
80 80 <div class="post" id="{{ post.id }}">
81 81 {% else %}
82 82 <div class="post dead_post id="{{ post.id }}"">
83 83 {% endif %}
84 84 {% if post.image %}
85 85 <div class="image">
86 86 <a class="fancy"
87 87 href="{{ post.image.url }}"><img
88 88 src=" {{ post.image.url_200x150 }}"
89 89 alt="{% trans 'Post image' %}"
90 90 data-width="{{ post.image_width }}"
91 91 data-height="{{ post.image_height }}"/>
92 92 </a>
93 93 </div>
94 94 {% endif %}
95 95 <div class="message">
96 96 <div class="post-info">
97 97 <span class="title">{{ post.title }}</span>
98 98 <a class="post_id" href="
99 99 {% url 'thread' thread.id %}#{{ post.id }}">
100 100 (#{{ post.id }})</a>
101 101 [{{ post.pub_time }}]
102 102 </div>
103 103 {% autoescape off %}
104 104 {{ post.text.rendered|truncatewords_html:50 }}
105 105 {% endautoescape %}
106 106 </div>
107 107 </div>
108 108 {% endfor %}
109 109 </div>
110 110 {% endif %}
111 111 </div>
112 112 {% endfor %}
113 113 {% else %}
114 114 <div class="post">
115 115 {% trans 'No threads exist. Create the first one!' %}</div>
116 116 {% endif %}
117 117
118 118 <form enctype="multipart/form-data" method="post">{% csrf_token %}
119 119 <div class="post-form-w">
120 120
121 121 <div class="form-title">{% trans "Create new thread" %}</div>
122 122 <div class="post-form">
123 123 <div class="form-row">
124 124 <div class="form-label">{% trans 'Title' %}</div>
125 125 <div class="form-input">{{ form.title }}</div>
126 126 <div class="form-errors">{{ form.title.errors }}</div>
127 127 </div>
128 128 <div class="form-row">
129 129 <div class="form-label">{% trans 'Text' %}</div>
130 130 <div class="form-input">{{ form.text }}</div>
131 131 <div class="form-errors">{{ form.text.errors }}</div>
132 132 </div>
133 133 <div class="form-row">
134 134 <div class="form-label">{% trans 'Image' %}</div>
135 135 <div class="form-input">{{ form.image }}</div>
136 136 <div class="form-errors">{{ form.image.errors }}</div>
137 137 </div>
138 138 <div class="form-row">
139 139 <div class="form-label">{% trans 'Tags' %}</div>
140 140 <div class="form-input">{{ form.tags }}</div>
141 141 <div class="form-errors">{{ form.tags.errors }}</div>
142 142 </div>
143 143 <div class="form-row">
144 144 {{ form.captcha }}
145 145 <div class="form-errors">{{ form.captcha.errors }}</div>
146 146 </div>
147 147 <div class="form-row">
148 148 <div class="form-errors">{{ form.other.errors }}</div>
149 149 </div>
150 150 </div>
151 151 <div class="form-submit">
152 152 <input type="submit" value="{% trans "Post" %}"/></div>
153 153 <div>
154 154 {% trans 'Tags must be delimited by spaces. Text or image is required.' %}
155 155 </div>
156 156 <div><a href="{% url "staticpage" name="help" %}">
157 157 {% trans 'Text syntax' %}</a></div>
158 158 </div>
159 159 </form>
160 160
161 161 {% endblock %}
162 162
163 163 {% block metapanel %}
164 164
165 165 <span class="metapanel">
166 166 <b><a href="{% url "authors" %}">Neboard</a> 1.1</b>
167 167 {% trans "Pages:" %}
168 168 {% for page in pages %}
169 169 [<a href="
170 170 {% if tag %}
171 171 {% url "tag" tag_name=tag page=page %}
172 172 {% else %}
173 173 {% url "index" page=page %}
174 174 {% endif %}
175 175 ">{{ page }}</a>]
176 176 {% endfor %}
177 177 [<a href="rss/">RSS</a>]
178 178 </span>
179 179
180 180 {% endblock %}
@@ -1,331 +1,337 b''
1 1 import hashlib
2 2 from django.core.urlresolvers import reverse
3 from django.http import HttpResponseRedirect
3 4 from django.template import RequestContext
4 5 from django.shortcuts import render, redirect, get_object_or_404
5 6 from django.utils import timezone
6 7
7 8 from boards import forms
8 9 import boards
9 10 from boards import utils
10 11 from boards.forms import ThreadForm, PostForm, SettingsForm, PlainErrorList, \
11 12 ThreadCaptchaForm, PostCaptchaForm, LoginForm
12 13
13 14 from boards.models import Post, Tag, Ban, User, RANK_USER, NO_PARENT
14 15 from boards import authors
15 16 import neboard
16 17
17 18
18 19 def index(request, page=0):
19 20 context = _init_default_context(request)
20 21
21 22 if utils.need_include_captcha(request):
22 23 threadFormClass = ThreadCaptchaForm
23 24 kwargs = {'request': request}
24 25 else:
25 26 threadFormClass = ThreadForm
26 27 kwargs = {}
27 28
28 29 if request.method == 'POST':
29 30 form = threadFormClass(request.POST, request.FILES,
30 31 error_class=PlainErrorList, **kwargs)
31 32 form.session = request.session
32 33
33 34 if form.is_valid():
34 35 return _new_post(request, form)
35 36 else:
36 37 form = threadFormClass(error_class=PlainErrorList, **kwargs)
37 38
38 39 threads = Post.objects.get_threads(page=int(page))
39 40
40 41 context['threads'] = None if len(threads) == 0 else threads
41 42 context['form'] = form
42 43 context['pages'] = range(Post.objects.get_thread_page_count())
43 44
44 45 return render(request, 'boards/posting_general.html',
45 46 context)
46 47
47 48
48 49 def _new_post(request, form, thread_id=boards.models.NO_PARENT):
49 50 """Add a new post (in thread or as a reply)."""
50 51
51 52 ip = _get_client_ip(request)
52 53 is_banned = Ban.objects.filter(ip=ip).count() > 0
53 54
54 55 if is_banned:
55 56 return redirect(you_are_banned)
56 57
57 58 data = form.cleaned_data
58 59
59 60 title = data['title']
60 61 text = data['text']
61 62
62 63 if 'image' in data.keys():
63 64 image = data['image']
64 65 else:
65 66 image = None
66 67
67 68 tags = []
68 69
69 70 new_thread = thread_id == boards.models.NO_PARENT
70 71 if new_thread:
71 72 tag_strings = data['tags']
72 73
73 74 if tag_strings:
74 75 tag_strings = tag_strings.split(' ')
75 76 for tag_name in tag_strings:
76 77 tag_name = tag_name.strip()
77 78 if len(tag_name) > 0:
78 79 tag, created = Tag.objects.get_or_create(name=tag_name)
79 80 tags.append(tag)
80 81
81 82 # TODO Add a possibility to define a link image instead of an image file.
82 83 # If a link is given, download the image automatically.
83 84
84 85 post = Post.objects.create_post(title=title, text=text, ip=ip,
85 86 parent_id=thread_id, image=image,
86 87 tags=tags)
87 88
88 89 thread_to_show = (post.id if new_thread else thread_id)
89 90
90 91 if new_thread:
91 92 return redirect(thread, post_id=thread_to_show)
92 93 else:
93 94 return redirect(reverse(thread,
94 95 kwargs={'post_id': thread_to_show}) + '#'
95 96 + str(post.id))
96 97
97 98
98 99 def tag(request, tag_name, page=0):
99 100 """Get all tag threads (posts without a parent)."""
100 101
101 102 tag = get_object_or_404(Tag, name=tag_name)
102 103 threads = Post.objects.get_threads(tag=tag, page=int(page))
103 104
104 105 if request.method == 'POST':
105 106 form = ThreadForm(request.POST, request.FILES,
106 107 error_class=PlainErrorList)
107 108 if form.is_valid():
108 109 return _new_post(request, form)
109 110 else:
110 111 form = forms.ThreadForm(initial={'tags': tag_name},
111 112 error_class=PlainErrorList)
112 113
113 114 context = _init_default_context(request)
114 115 context['threads'] = None if len(threads) == 0 else threads
115 116 context['tag'] = tag_name
116 117 context['pages'] = range(Post.objects.get_thread_page_count(tag=tag))
117 118
118 119 context['form'] = form
119 120
120 121 return render(request, 'boards/posting_general.html',
121 122 context)
122 123
123 124
124 125 def thread(request, post_id):
125 126 """Get all thread posts"""
126 127
127 128 if utils.need_include_captcha(request):
128 129 postFormClass = PostCaptchaForm
129 130 kwargs = {'request': request}
130 131 else:
131 132 postFormClass = PostForm
132 133 kwargs = {}
133 134
134 135 if request.method == 'POST':
135 136 form = postFormClass(request.POST, request.FILES,
136 137 error_class=PlainErrorList, **kwargs)
137 138 form.session = request.session
138 139
139 140 if form.is_valid():
140 141 return _new_post(request, form, post_id)
141 142 else:
142 143 form = postFormClass(error_class=PlainErrorList, **kwargs)
143 144
144 145 posts = Post.objects.get_thread(post_id)
145 146
146 147 context = _init_default_context(request)
147 148
148 149 context['posts'] = posts
149 150 context['form'] = form
150 151
151 152 return render(request, 'boards/thread.html', context)
152 153
153 154
154 155 def login(request):
155 156 """Log in with user id"""
156 157
157 158 context = _init_default_context(request)
158 159
159 160 if request.method == 'POST':
160 161 form = LoginForm(request.POST, request.FILES,
161 162 error_class=PlainErrorList)
162 163 if form.is_valid():
163 164 user = User.objects.get(user_id=form.cleaned_data['user_id'])
164 165 request.session['user_id'] = user.id
165 166 return redirect(index)
166 167
167 168 else:
168 169 form = LoginForm()
169 170
170 171 context['form'] = form
171 172
172 173 return render(request, 'boards/login.html', context)
173 174
174 175
175 176 def settings(request):
176 177 """User's settings"""
177 178
178 179 context = _init_default_context(request)
179 180
180 181 if request.method == 'POST':
181 182 form = SettingsForm(request.POST)
182 183 if form.is_valid():
183 184 selected_theme = form.cleaned_data['theme']
184 185
185 186 user = _get_user(request)
186 187 user.save_setting('theme', selected_theme)
187 188
188 189 return redirect(settings)
189 190 else:
190 191 selected_theme = _get_theme(request)
191 192 form = SettingsForm(initial={'theme': selected_theme})
192 193 context['form'] = form
193 194
194 195 return render(request, 'boards/settings.html', context)
195 196
196 197
197 198 def all_tags(request):
198 199 """All tags list"""
199 200
200 201 context = _init_default_context(request)
201 202 context['all_tags'] = Tag.objects.get_not_empty_tags()
202 203
203 204 return render(request, 'boards/tags.html', context)
204 205
205 206
206 207 def jump_to_post(request, post_id):
207 208 """Determine thread in which the requested post is and open it's page"""
208 209
209 210 post = get_object_or_404(Post, id=post_id)
210 211
211 212 if boards.models.NO_PARENT == post.parent:
212 213 return redirect(thread, post_id=post.id)
213 214 else:
214 215 parent_thread = get_object_or_404(Post, id=post.parent)
215 216 return redirect(reverse(thread, kwargs={'post_id': parent_thread.id})
216 217 + '#' + str(post.id))
217 218
218 219
219 220 def authors(request):
220 221 context = _init_default_context(request)
221 222 context['authors'] = boards.authors.authors
222 223
223 224 return render(request, 'boards/authors.html', context)
224 225
225 226
226 227 def delete(request, post_id):
227 228 user = _get_user(request)
228 229 post = get_object_or_404(Post, id=post_id)
229 230
230 231 if user.is_moderator():
231 232 # TODO Show confirmation page before deletion
232 233 Post.objects.delete_post(post)
233 234
234 235 if NO_PARENT == post.parent:
235 return redirect(index)
236 return _redirect_to_next(request)
236 237 else:
237 238 return redirect(thread, post_id=post.parent)
238 239
239 240
240 241 def you_are_banned(request):
241 242 context = _init_default_context(request)
242 243 return render(request, 'boards/staticpages/banned.html', context)
243 244
244 245
245 246 def page_404(request):
246 247 context = _init_default_context(request)
247 248 return render(request, 'boards/404.html', context)
248 249
249 250
250 251 def tag_subscribe(request, tag_name):
251 252 user = _get_user(request)
252 253 tag = get_object_or_404(Tag, name=tag_name)
253 254
254 255 if not tag in user.fav_tags.all():
255 256 user.fav_tags.add(tag)
256 257
257 258 return redirect(all_tags)
258 259
259 260
260 261 def tag_unsubscribe(request, tag_name):
261 262 user = _get_user(request)
262 263 tag = get_object_or_404(Tag, name=tag_name)
263 264
264 265 if tag in user.fav_tags.all():
265 266 user.fav_tags.remove(tag)
266 267
267 268 return redirect(all_tags)
268 269
269 270
270 271 def static_page(request, name):
271 272 context = _init_default_context(request)
272 273 return render(request, 'boards/staticpages/' + name + '.html', context)
273 274
274 275
275 276 def _get_theme(request, user=None):
276 277 """Get user's CSS theme"""
277 278
278 279 if not user:
279 280 user = _get_user(request)
280 281 theme = user.get_setting('theme')
281 282 if not theme:
282 283 theme = neboard.settings.DEFAULT_THEME
283 284
284 285 return theme
285 286
286 287
287 288 def _get_client_ip(request):
288 289 x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
289 290 if x_forwarded_for:
290 291 ip = x_forwarded_for.split(',')[-1].strip()
291 292 else:
292 293 ip = request.META.get('REMOTE_ADDR')
293 294 return ip
294 295
295 296
296 297 def _init_default_context(request):
297 298 """Create context with default values that are used in most views"""
298 299
299 300 context = RequestContext(request)
300 301
301 302 user = _get_user(request)
302 303 context['user'] = user
303 304 context['tags'] = user.get_sorted_fav_tags()
304 305 context['theme'] = _get_theme(request, user)
305 306
306 307 return context
307 308
308 309
309 310 def _get_user(request):
310 311 """Get current user from the session"""
311 312
312 313 session = request.session
313 314 if not 'user_id' in session:
314 315 request.session.save()
315 316
316 317 md5 = hashlib.md5()
317 318 md5.update(session.session_key)
318 319 new_id = md5.hexdigest()
319 320
320 321 time_now = timezone.now()
321 322 user = User.objects.create(user_id=new_id, rank=RANK_USER,
322 323 registration_time=time_now,
323 324 last_access_time=time_now)
324 325
325 326 session['user_id'] = user.id
326 327 else:
327 328 user = User.objects.get(id=session['user_id'])
328 329 user.last_access_time = timezone.now()
329 330 user.save()
330 331
331 332 return user
333
334
335 def _redirect_to_next(request):
336 next_page = request.GET['next']
337 return HttpResponseRedirect(next_page)
@@ -1,202 +1,202 b''
1 1 # Django settings for neboard project.
2 2 import os
3 3 import markdown
4 4 from boards.mdx_neboard import markdown_extended
5 5
6 6 DEBUG = True
7 7 TEMPLATE_DEBUG = DEBUG
8 8
9 9 ADMINS = (
10 10 # ('Your Name', 'your_email@example.com'),
11 11 ('admin', 'admin@example.com')
12 12 )
13 13
14 14 MANAGERS = ADMINS
15 15
16 16 DATABASES = {
17 17 'default': {
18 18 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
19 19 'NAME': 'database.db', # Or path to database file if using sqlite3.
20 20 'USER': '', # Not used with sqlite3.
21 21 'PASSWORD': '', # Not used with sqlite3.
22 22 'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
23 23 'PORT': '', # Set to empty string for default. Not used with sqlite3.
24 24 }
25 25 }
26 26
27 27 # Local time zone for this installation. Choices can be found here:
28 28 # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
29 29 # although not all choices may be available on all operating systems.
30 30 # In a Windows environment this must be set to your system time zone.
31 31 TIME_ZONE = 'Europe/Kiev'
32 32
33 33 # Language code for this installation. All choices can be found here:
34 34 # http://www.i18nguy.com/unicode/language-identifiers.html
35 35 LANGUAGE_CODE = 'en'
36 36
37 37 SITE_ID = 1
38 38
39 39 # If you set this to False, Django will make some optimizations so as not
40 40 # to load the internationalization machinery.
41 41 USE_I18N = True
42 42
43 43 # If you set this to False, Django will not format dates, numbers and
44 44 # calendars according to the current locale.
45 45 USE_L10N = True
46 46
47 47 # If you set this to False, Django will not use timezone-aware datetimes.
48 48 USE_TZ = True
49 49
50 50 # Absolute filesystem path to the directory that will hold user-uploaded files.
51 51 # Example: "/home/media/media.lawrence.com/media/"
52 52 MEDIA_ROOT = './media/'
53 53
54 54 # URL that handles the media served from MEDIA_ROOT. Make sure to use a
55 55 # trailing slash.
56 56 # Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
57 57 MEDIA_URL = '/media/'
58 58
59 59 # Absolute path to the directory static files should be collected to.
60 60 # Don't put anything in this directory yourself; store your static files
61 61 # in apps' "static/" subdirectories and in STATICFILES_DIRS.
62 62 # Example: "/home/media/media.lawrence.com/static/"
63 63 STATIC_ROOT = ''
64 64
65 65 # URL prefix for static files.
66 66 # Example: "http://media.lawrence.com/static/"
67 67 STATIC_URL = '/static/'
68 68
69 69 # Additional locations of static files
70 70 # It is really a hack, put real paths, not related
71 71 STATICFILES_DIRS = (
72 72 os.path.dirname(__file__) + '/boards/static',
73 73
74 74 # '/d/work/python/django/neboard/neboard/boards/static',
75 75 # Put strings here, like "/home/html/static" or "C:/www/django/static".
76 76 # Always use forward slashes, even on Windows.
77 77 # Don't forget to use absolute paths, not relative paths.
78 78 )
79 79
80 80 # List of finder classes that know how to find static files in
81 81 # various locations.
82 82 STATICFILES_FINDERS = (
83 83 'django.contrib.staticfiles.finders.FileSystemFinder',
84 84 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
85 85 # 'django.contrib.staticfiles.finders.DefaultStorageFinder',
86 86 )
87 87
88 88 # Make this unique, and don't share it with anybody.
89 89 SECRET_KEY = '@1rc$o(7=tt#kd+4s$u6wchm**z^)4x90)7f6z(i&amp;55@o11*8o'
90 90
91 91 # List of callables that know how to import templates from various sources.
92 92 TEMPLATE_LOADERS = (
93 93 'django.template.loaders.filesystem.Loader',
94 94 'django.template.loaders.app_directories.Loader',
95 95 # 'django.template.loaders.eggs.Loader',
96 96 )
97 97
98 98 TEMPLATE_CONTEXT_PROCESSORS = (
99 99 'django.core.context_processors.media',
100 100 'django.core.context_processors.static',
101 101 'django.core.context_processors.request',
102 102 'django.contrib.auth.context_processors.auth',
103 103 )
104 104
105 105 MIDDLEWARE_CLASSES = (
106 106 'django.contrib.sessions.middleware.SessionMiddleware',
107 107 'django.middleware.locale.LocaleMiddleware',
108 108 'django.middleware.common.CommonMiddleware',
109 109 # 'django.middleware.csrf.CsrfViewMiddleware',
110 110 'django.contrib.auth.middleware.AuthenticationMiddleware',
111 111 'django.contrib.messages.middleware.MessageMiddleware',
112 112 # Uncomment the next line for simple clickjacking protection:
113 113 # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
114 114 )
115 115
116 116 ROOT_URLCONF = 'neboard.urls'
117 117
118 118 # Python dotted path to the WSGI application used by Django's runserver.
119 119 WSGI_APPLICATION = 'neboard.wsgi.application'
120 120
121 121 TEMPLATE_DIRS = (
122 122 # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
123 123 # Always use forward slashes, even on Windows.
124 124 # Don't forget to use absolute paths, not relative paths.
125 125 'templates',
126 126 )
127 127
128 128 INSTALLED_APPS = (
129 129 'django.contrib.auth',
130 130 'django.contrib.contenttypes',
131 131 'django.contrib.sessions',
132 132 # 'django.contrib.sites',
133 133 'django.contrib.messages',
134 134 'django.contrib.staticfiles',
135 135 # Uncomment the next line to enable the admin:
136 136 'django.contrib.admin',
137 137 # Uncomment the next line to enable admin documentation:
138 138 # 'django.contrib.admindocs',
139 139 'django.contrib.markup',
140 140 'django_cleanup',
141 141 'boards',
142 142 'captcha',
143 143 'south',
144 144 )
145 145
146 146 # TODO: NEED DESIGN FIXES
147 147 CAPTCHA_OUTPUT_FORMAT = (u' %(hidden_field)s '
148 148 u'<div class="form-label">%(image)s</div>'
149 149 u'<div class="form-text">%(text_field)s</div>')
150 150
151 151 # A sample logging configuration. The only tangible logging
152 152 # performed by this configuration is to send an email to
153 153 # the site admins on every HTTP 500 error when DEBUG=False.
154 154 # See http://docs.djangoproject.com/en/dev/topics/logging for
155 155 # more details on how to customize your logging configuration.
156 156 LOGGING = {
157 157 'version': 1,
158 158 'disable_existing_loggers': False,
159 159 'filters': {
160 160 'require_debug_false': {
161 161 '()': 'django.utils.log.RequireDebugFalse'
162 162 }
163 163 },
164 164 'handlers': {
165 165 'mail_admins': {
166 166 'level': 'ERROR',
167 167 'filters': ['require_debug_false'],
168 168 'class': 'django.utils.log.AdminEmailHandler'
169 169 }
170 170 },
171 171 'loggers': {
172 172 'django.request': {
173 173 'handlers': ['mail_admins'],
174 174 'level': 'ERROR',
175 175 'propagate': True,
176 176 },
177 177 }
178 178 }
179 179
180 180 MARKUP_FIELD_TYPES = (
181 181 ('markdown', markdown_extended),
182 182 )
183 183 # Custom imageboard settings
184 184 MAX_POSTS_PER_THREAD = 10 # Thread bumplimit
185 185 MAX_THREAD_COUNT = 500 # Old threads will be deleted to preserve this count
186 186 THREADS_PER_PAGE = 10
187 187 SITE_NAME = 'Neboard'
188 188
189 189 THEMES = [
190 190 ('md', 'Mystic Dark'),
191 191 ('sw', 'Snow White')
192 192 ]
193 193
194 194 DEFAULT_THEME = 'md'
195 195
196 196 POPULAR_TAGS = 10
197 197 LAST_REPLIES_COUNT = 3
198 198
199 199 ENABLE_CAPTCHA = False
200 200 # if user tries to post before CAPTCHA_DEFAULT_SAFE_TIME. Captcha will be shown
201 201 CAPTCHA_DEFAULT_SAFE_TIME = 30 # seconds
202 POSTING_DELAY = 20 # seconds No newline at end of file
202 POSTING_DELAY = 30 # seconds No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now