punkweb-bb 0.4.2__py3-none-any.whl → 0.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. punkweb_bb/__pycache__/bbcode.cpython-311.pyc +0 -0
  2. punkweb_bb/__pycache__/context_processors.cpython-311.pyc +0 -0
  3. punkweb_bb/__pycache__/decorators.cpython-311.pyc +0 -0
  4. punkweb_bb/__pycache__/forms.cpython-311.pyc +0 -0
  5. punkweb_bb/__pycache__/middleware.cpython-311.pyc +0 -0
  6. punkweb_bb/__pycache__/models.cpython-311.pyc +0 -0
  7. punkweb_bb/__pycache__/pagination.cpython-311.pyc +0 -0
  8. punkweb_bb/__pycache__/searching.cpython-311.pyc +0 -0
  9. punkweb_bb/__pycache__/settings.cpython-311.pyc +0 -0
  10. punkweb_bb/__pycache__/urls.cpython-311.pyc +0 -0
  11. punkweb_bb/__pycache__/utils.cpython-311.pyc +0 -0
  12. punkweb_bb/__pycache__/views.cpython-311.pyc +0 -0
  13. punkweb_bb/__pycache__/widgets.cpython-311.pyc +0 -0
  14. punkweb_bb/bbcode.py +4 -3
  15. punkweb_bb/decorators.py +17 -0
  16. punkweb_bb/forms.py +47 -10
  17. punkweb_bb/middleware.py +26 -1
  18. punkweb_bb/migrations/0001_initial.py +4 -25
  19. punkweb_bb/migrations/0004_groupstyle.py +1 -6
  20. punkweb_bb/migrations/0006_remove_boardprofile__signature_rendered_and_more.py +0 -20
  21. punkweb_bb/migrations/0007_boardprofile_bio.py +18 -0
  22. punkweb_bb/migrations/__pycache__/0001_initial.cpython-311.pyc +0 -0
  23. punkweb_bb/migrations/__pycache__/0001_squashed_0006_remove_boardprofile__signature_rendered_and_more.cpython-311.pyc +0 -0
  24. punkweb_bb/migrations/__pycache__/0004_groupstyle.cpython-311.pyc +0 -0
  25. punkweb_bb/migrations/__pycache__/0006_remove_boardprofile__signature_rendered_and_more.cpython-311.pyc +0 -0
  26. punkweb_bb/migrations/__pycache__/0007_boardprofile_bio.cpython-311.pyc +0 -0
  27. punkweb_bb/models.py +1 -0
  28. punkweb_bb/pagination.py +1 -1
  29. punkweb_bb/searching.py +10 -0
  30. punkweb_bb/settings.py +2 -0
  31. punkweb_bb/static/punkweb_bb/css/bbcode-editor-content.css +108 -0
  32. punkweb_bb/static/punkweb_bb/css/index.css +5 -6
  33. punkweb_bb/static/punkweb_bb/css/members.css +20 -3
  34. punkweb_bb/static/punkweb_bb/css/profile.css +6 -2
  35. punkweb_bb/static/punkweb_bb/css/punkweb.css +25 -687
  36. punkweb_bb/static/punkweb_bb/css/shoutbox.css +1 -9
  37. punkweb_bb/static/punkweb_bb/css/thread.css +4 -28
  38. punkweb_bb/static/punkweb_bb/js/bbcode-editor-tags.js +63 -0
  39. punkweb_bb/static/punkweb_bb/js/bbcode-editor.js +14 -0
  40. punkweb_bb/static/punkweb_bb/js/markdown-editor.js +49 -0
  41. punkweb_bb/static/punkweb_bb/js/punkweb-dialog.js +9 -0
  42. punkweb_bb/static/punkweb_bb/vendor/htmx-2.0.0.min.js +1 -0
  43. punkweb_bb/static/punkweb_bb/vendor/punkweb-ui.min.css +1 -0
  44. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/css/commandbar.css +2 -2
  45. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/css/editor.css +1 -1
  46. punkweb_bb/templates/punkweb_bb/base.html +19 -21
  47. punkweb_bb/templates/punkweb_bb/base_delete_dialog.html +13 -0
  48. punkweb_bb/templates/punkweb_bb/base_delete_modal.html +2 -2
  49. punkweb_bb/templates/punkweb_bb/base_dialog.html +16 -0
  50. punkweb_bb/templates/punkweb_bb/bbcode.html +11 -9
  51. punkweb_bb/templates/punkweb_bb/category_create.html +4 -21
  52. punkweb_bb/templates/punkweb_bb/category_update.html +3 -20
  53. punkweb_bb/templates/punkweb_bb/components/pagination_controls.html +45 -0
  54. punkweb_bb/templates/punkweb_bb/components/profile_image.html +11 -0
  55. punkweb_bb/templates/punkweb_bb/forms/inline_form.html +6 -0
  56. punkweb_bb/templates/punkweb_bb/forms/stacked_form.html +35 -0
  57. punkweb_bb/templates/punkweb_bb/index.html +65 -70
  58. punkweb_bb/templates/punkweb_bb/login.html +5 -11
  59. punkweb_bb/templates/punkweb_bb/members.html +23 -52
  60. punkweb_bb/templates/punkweb_bb/partials/category_delete.html +1 -1
  61. punkweb_bb/templates/punkweb_bb/partials/post_delete.html +1 -1
  62. punkweb_bb/templates/punkweb_bb/partials/post_update.html +4 -11
  63. punkweb_bb/templates/punkweb_bb/partials/shout_delete.html +1 -1
  64. punkweb_bb/templates/punkweb_bb/partials/subcategory_delete.html +1 -1
  65. punkweb_bb/templates/punkweb_bb/partials/thread_delete.html +1 -1
  66. punkweb_bb/templates/punkweb_bb/partials/thread_move.html +5 -13
  67. punkweb_bb/templates/punkweb_bb/profile.html +14 -11
  68. punkweb_bb/templates/punkweb_bb/search.html +27 -0
  69. punkweb_bb/templates/punkweb_bb/settings.html +7 -33
  70. punkweb_bb/templates/punkweb_bb/shoutbox/shout_list.html +2 -2
  71. punkweb_bb/templates/punkweb_bb/shoutbox/shoutbox.html +21 -6
  72. punkweb_bb/templates/punkweb_bb/signup.html +6 -15
  73. punkweb_bb/templates/punkweb_bb/subcategory.html +12 -54
  74. punkweb_bb/templates/punkweb_bb/subcategory_create.html +7 -16
  75. punkweb_bb/templates/punkweb_bb/subcategory_update.html +7 -16
  76. punkweb_bb/templates/punkweb_bb/thread.html +23 -88
  77. punkweb_bb/templates/punkweb_bb/thread_create.html +7 -16
  78. punkweb_bb/templates/punkweb_bb/thread_update.html +7 -16
  79. punkweb_bb/templatetags/__pycache__/can_delete.cpython-311.pyc +0 -0
  80. punkweb_bb/templatetags/__pycache__/punkweb_bb.cpython-311.pyc +0 -0
  81. punkweb_bb/templatetags/__pycache__/render.cpython-311.pyc +0 -0
  82. punkweb_bb/templatetags/__pycache__/settings.cpython-311.pyc +0 -0
  83. punkweb_bb/templatetags/punkweb_bb.py +9 -0
  84. punkweb_bb/urls.py +1 -0
  85. punkweb_bb/views.py +97 -71
  86. punkweb_bb/widgets.py +3 -4
  87. {punkweb_bb-0.4.2.dist-info → punkweb_bb-0.5.0.dist-info}/METADATA +25 -36
  88. {punkweb_bb-0.4.2.dist-info → punkweb_bb-0.5.0.dist-info}/RECORD +91 -67
  89. {punkweb_bb-0.4.2.dist-info → punkweb_bb-0.5.0.dist-info}/LICENSE +0 -0
  90. {punkweb_bb-0.4.2.dist-info → punkweb_bb-0.5.0.dist-info}/WHEEL +0 -0
  91. {punkweb_bb-0.4.2.dist-info → punkweb_bb-0.5.0.dist-info}/top_level.txt +0 -0
@@ -5,7 +5,10 @@
5
5
 
6
6
  {% block extra_head %}
7
7
  {{form.media.css}}
8
- <link rel="stylesheet" href="{% static 'punkweb_bb/css/thread-form.css' %}" />
8
+ {% endblock %}
9
+
10
+ {% block extra_script %}
11
+ {{form.media.js}}
9
12
  {% endblock %}
10
13
 
11
14
  {% block content %}
@@ -33,18 +36,10 @@
33
36
  <div class="pw-card fluid">
34
37
  <div class="pw-card-header">Edit Thread</div>
35
38
  <div class="pw-card-content">
36
- <form class="threadForm" action="{% url 'punkweb_bb:thread_update' thread.id %}" method="post">
39
+ <form class="pw-form" action="{% url 'punkweb_bb:thread_update' thread.id %}" method="post">
37
40
  {% csrf_token %}
38
- {% for field in form %}
39
- <div class="threadForm__field">
40
- <label class="pw-input-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
41
- {{ field }}
42
- </div>
43
- {% endfor %}
44
- {% if form.non_field_errors %}
45
- {{ form.non_field_errors }}
46
- {% endif %}
47
- <div class="threadForm__actions">
41
+ {{ form }}
42
+ <div class="pw-form-actions end">
48
43
  <a class="pw-button default" href="{{thread.get_absolute_url}}">Cancel</a>
49
44
  <button class="pw-button raised primary" type="submit">Save</button>
50
45
  </div>
@@ -52,8 +47,4 @@
52
47
  </div>
53
48
  </div>
54
49
 
55
- {% endblock %}
56
-
57
- {% block extra_script %}
58
- {{form.media.js}}
59
50
  {% endblock %}
@@ -0,0 +1,9 @@
1
+ from django import template
2
+ from punkweb_bb import settings
3
+
4
+ register = template.Library()
5
+
6
+
7
+ @register.simple_tag
8
+ def punkweb_bb(setting_name, default=None):
9
+ return getattr(settings, setting_name, default)
punkweb_bb/urls.py CHANGED
@@ -68,4 +68,5 @@ urlpatterns = [
68
68
  path("shout-create/", views.shout_create_view, name="shout_create"),
69
69
  path("shout/<str:shout_id>/delete/", views.shout_delete_view, name="shout_delete"),
70
70
  path("bbcode/", views.bbcode_view, name="bbcode"),
71
+ path("search/", views.search_view, name="search"),
71
72
  ]
punkweb_bb/views.py CHANGED
@@ -1,13 +1,17 @@
1
+ from django import forms
1
2
  from django.contrib.auth import authenticate, get_user_model, login, logout
2
- from django.contrib.auth.decorators import login_required
3
- from django.http import HttpResponseForbidden
3
+ from django.contrib.auth.decorators import login_required, permission_required
4
+ from django.core.exceptions import PermissionDenied
5
+ from django.db.models import Count
4
6
  from django.shortcuts import get_object_or_404, redirect, render
5
7
  from django.urls import reverse
6
8
  from django.utils import timezone
7
9
 
10
+ from punkweb_bb.decorators import redirect_if_authenticated
8
11
  from punkweb_bb.forms import (
9
12
  BoardProfileModelForm,
10
13
  CategoryModelForm,
14
+ FilterUsersForm,
11
15
  LoginForm,
12
16
  PostModelForm,
13
17
  ShoutModelForm,
@@ -18,17 +22,21 @@ from punkweb_bb.forms import (
18
22
  )
19
23
  from punkweb_bb.guests import guest_list
20
24
  from punkweb_bb.models import Category, Post, Shout, Subcategory, Thread
21
- from punkweb_bb.pagination import paginate_qs
25
+ from punkweb_bb.pagination import paginate
22
26
  from punkweb_bb.response import htmx_redirect
27
+ from punkweb_bb.searching import search_threads
23
28
  from punkweb_bb.utils import get_unique_slug
24
29
 
25
30
  User = get_user_model()
26
31
 
27
32
 
28
- def signup_view(request):
29
- if request.user.is_authenticated:
30
- return redirect("punkweb_bb:index")
33
+ def check_object_permission(obj, func, user):
34
+ if not getattr(obj, func)(user):
35
+ raise PermissionDenied
36
+
31
37
 
38
+ @redirect_if_authenticated()
39
+ def signup_view(request):
32
40
  if request.method == "POST":
33
41
  form = SignUpForm(request.POST)
34
42
 
@@ -45,12 +53,10 @@ def signup_view(request):
45
53
  return render(request, "punkweb_bb/signup.html", context)
46
54
 
47
55
 
56
+ @redirect_if_authenticated()
48
57
  def login_view(request):
49
- if request.user.is_authenticated:
50
- return redirect("punkweb_bb:index")
51
-
52
58
  if request.method == "POST":
53
- form = LoginForm(request, request.POST)
59
+ form = LoginForm(request=request, data=request.POST)
54
60
 
55
61
  if form.is_valid():
56
62
  username = form.cleaned_data["username"]
@@ -111,18 +117,59 @@ def index_view(request):
111
117
  def profile_view(request, user_id):
112
118
  user = get_object_or_404(User, pk=user_id)
113
119
 
120
+ # Get top threads by post count
121
+ top_threads = user.threads.annotate(count_posts=Count("posts")).order_by(
122
+ "-count_posts"
123
+ )[:5]
124
+
125
+ # Get top subcategories by thread count
126
+ top_subcategories = (
127
+ user.threads.values("subcategory")
128
+ .annotate(count_threads=Count("subcategory"))
129
+ .order_by("-count_threads")
130
+ )
131
+ for subcategory in top_subcategories:
132
+ subcategory["subcategory"] = Subcategory.objects.get(
133
+ pk=subcategory["subcategory"]
134
+ )
135
+
136
+ threads_qs = user.threads.all().order_by("-created_at")
137
+ posts_qs = user.posts.all().order_by("-created_at")
138
+
139
+ threads = paginate(request, threads_qs)
140
+ posts = paginate(request, posts_qs)
141
+
114
142
  context = {
115
143
  "user": user,
144
+ "top_threads": top_threads,
145
+ "top_subcategories": top_subcategories,
146
+ "threads": threads,
147
+ "posts": posts,
116
148
  }
149
+
117
150
  return render(request, "punkweb_bb/profile.html", context=context)
118
151
 
119
152
 
120
153
  def members_view(request):
121
- users = paginate_qs(
122
- request, User.objects.select_related("profile").order_by("username")
123
- )
154
+ users_qs = User.objects.all()
155
+
156
+ form = FilterUsersForm(request.GET)
157
+ if form.is_valid():
158
+ search = form.cleaned_data["search"]
159
+ sort_by = form.cleaned_data["sort_by"]
160
+ if search:
161
+ users_qs = users_qs.filter(username__icontains=search)
162
+ if sort_by:
163
+ users_qs = users_qs.order_by(sort_by)
164
+ else:
165
+ users_qs = users_qs.order_by("username")
166
+
167
+ users_qs = users_qs.select_related("profile")
168
+
169
+ users = paginate(request, users_qs)
124
170
 
125
171
  context = {
172
+ "form": form,
126
173
  "users": users,
127
174
  }
128
175
  return render(request, "punkweb_bb/members.html", context=context)
@@ -152,10 +199,8 @@ def settings_view(request):
152
199
 
153
200
 
154
201
  @login_required(login_url="/login/")
202
+ @permission_required("punkweb_bb.view_category", raise_exception=True)
155
203
  def category_create_view(request):
156
- if not request.user.has_perm("punkweb_bb.add_category"):
157
- return HttpResponseForbidden("You do not have permission to create categories.")
158
-
159
204
  if request.method == "POST":
160
205
  form = CategoryModelForm(request.POST)
161
206
 
@@ -175,10 +220,8 @@ def category_create_view(request):
175
220
 
176
221
 
177
222
  @login_required(login_url="/login/")
223
+ @permission_required("punkweb_bb.change_category", raise_exception=True)
178
224
  def category_update_view(request, category_slug):
179
- if not request.user.has_perm("punkweb_bb.change_category"):
180
- return HttpResponseForbidden("You do not have permission to change categories.")
181
-
182
225
  category = get_object_or_404(Category, slug=category_slug)
183
226
 
184
227
  if request.method == "POST":
@@ -199,10 +242,8 @@ def category_update_view(request, category_slug):
199
242
 
200
243
 
201
244
  @login_required(login_url="/login/")
245
+ @permission_required("punkweb_bb.delete_category", raise_exception=True)
202
246
  def category_delete_view(request, category_slug):
203
- if not request.user.has_perm("punkweb_bb.delete_category"):
204
- return HttpResponseForbidden("You do not have permission to delete categories.")
205
-
206
247
  category = get_object_or_404(Category, slug=category_slug)
207
248
 
208
249
  if request.method == "DELETE":
@@ -220,7 +261,7 @@ def category_delete_view(request, category_slug):
220
261
  def subcategory_view(request, subcategory_slug):
221
262
  subcategory = get_object_or_404(Subcategory, slug=subcategory_slug)
222
263
 
223
- threads = paginate_qs(request, subcategory.threads.all())
264
+ threads = paginate(request, subcategory.threads.all())
224
265
 
225
266
  context = {
226
267
  "subcategory": subcategory,
@@ -230,12 +271,8 @@ def subcategory_view(request, subcategory_slug):
230
271
 
231
272
 
232
273
  @login_required(login_url="/login/")
274
+ @permission_required("punkweb_bb.add_subcategory", raise_exception=True)
233
275
  def subcategory_create_view(request, category_slug):
234
- if not request.user.has_perm("punkweb_bb.add_subcategory"):
235
- return HttpResponseForbidden(
236
- "You do not have permission to create subcategories."
237
- )
238
-
239
276
  category = get_object_or_404(Category, slug=category_slug)
240
277
 
241
278
  if request.method == "POST":
@@ -249,7 +286,7 @@ def subcategory_create_view(request, category_slug):
249
286
 
250
287
  return redirect(subcategory)
251
288
  else:
252
- form = SubcategoryModelForm()
289
+ form = SubcategoryModelForm(initial={"category": category})
253
290
 
254
291
  context = {
255
292
  "category": category,
@@ -259,12 +296,8 @@ def subcategory_create_view(request, category_slug):
259
296
 
260
297
 
261
298
  @login_required(login_url="/login/")
299
+ @permission_required("punkweb_bb.change_subcategory", raise_exception=True)
262
300
  def subcategory_update_view(request, subcategory_slug):
263
- if not request.user.has_perm("punkweb_bb.change_subcategory"):
264
- return HttpResponseForbidden(
265
- "You do not have permission to change subcategories."
266
- )
267
-
268
301
  subcategory = get_object_or_404(Subcategory, slug=subcategory_slug)
269
302
 
270
303
  if request.method == "POST":
@@ -285,12 +318,8 @@ def subcategory_update_view(request, subcategory_slug):
285
318
 
286
319
 
287
320
  @login_required(login_url="/login/")
321
+ @permission_required("punkweb_bb.delete_subcategory", raise_exception=True)
288
322
  def subcategory_delete_view(request, subcategory_slug):
289
- if not request.user.has_perm("punkweb_bb.delete_subcategory"):
290
- return HttpResponseForbidden(
291
- "You do not have permission to delete subcategories."
292
- )
293
-
294
323
  subcategory = get_object_or_404(Subcategory, slug=subcategory_slug)
295
324
 
296
325
  if request.method == "DELETE":
@@ -311,10 +340,7 @@ def subcategory_delete_view(request, subcategory_slug):
311
340
  def thread_create_view(request, subcategory_slug):
312
341
  subcategory = get_object_or_404(Subcategory, slug=subcategory_slug)
313
342
 
314
- if not subcategory.can_post(request.user):
315
- return HttpResponseForbidden(
316
- "You do not have permission to post in this subcategory."
317
- )
343
+ check_object_permission(subcategory, "can_post", request.user)
318
344
 
319
345
  if request.method == "POST":
320
346
  form = ThreadModelForm(request.POST)
@@ -339,7 +365,7 @@ def thread_create_view(request, subcategory_slug):
339
365
  def thread_view(request, thread_id):
340
366
  thread = get_object_or_404(Thread, pk=thread_id)
341
367
 
342
- posts = paginate_qs(request, thread.posts.all())
368
+ posts = paginate(request, thread.posts.all())
343
369
 
344
370
  post_form = PostModelForm()
345
371
 
@@ -362,10 +388,7 @@ def thread_view(request, thread_id):
362
388
  def thread_update_view(request, thread_id):
363
389
  thread = get_object_or_404(Thread, pk=thread_id)
364
390
 
365
- if not thread.can_edit(request.user):
366
- return HttpResponseForbidden(
367
- "You do not have permission to change this thread."
368
- )
391
+ check_object_permission(thread, "can_edit", request.user)
369
392
 
370
393
  if request.method == "POST":
371
394
  form = ThreadModelForm(request.POST, instance=thread)
@@ -388,10 +411,7 @@ def thread_update_view(request, thread_id):
388
411
  def thread_delete_view(request, thread_id):
389
412
  thread = get_object_or_404(Thread, pk=thread_id)
390
413
 
391
- if not thread.can_delete(request.user):
392
- return HttpResponseForbidden(
393
- "You do not have permission to delete this thread."
394
- )
414
+ check_object_permission(thread, "can_delete", request.user)
395
415
 
396
416
  if request.method == "DELETE":
397
417
  thread.delete()
@@ -406,10 +426,8 @@ def thread_delete_view(request, thread_id):
406
426
 
407
427
 
408
428
  @login_required(login_url="/login/")
429
+ @permission_required("punkweb_bb.pin_thread", raise_exception=True)
409
430
  def thread_pin_view(request, thread_id):
410
- if not request.user.has_perm("punkweb_bb.pin_thread"):
411
- return HttpResponseForbidden("You do not have permission to pin threads.")
412
-
413
431
  thread = get_object_or_404(Thread, pk=thread_id)
414
432
 
415
433
  thread.is_pinned = not thread.is_pinned
@@ -419,10 +437,8 @@ def thread_pin_view(request, thread_id):
419
437
 
420
438
 
421
439
  @login_required(login_url="/login/")
440
+ @permission_required("punkweb_bb.close_thread", raise_exception=True)
422
441
  def thread_close_view(request, thread_id):
423
- if not request.user.has_perm("punkweb_bb.close_thread"):
424
- return HttpResponseForbidden("You do not have permission to close threads.")
425
-
426
442
  thread = get_object_or_404(Thread, pk=thread_id)
427
443
 
428
444
  thread.is_closed = not thread.is_closed
@@ -432,10 +448,8 @@ def thread_close_view(request, thread_id):
432
448
 
433
449
 
434
450
  @login_required(login_url="/login/")
451
+ @permission_required("punkweb_bb.move_thread", raise_exception=True)
435
452
  def thread_move_view(request, thread_id):
436
- if not request.user.has_perm("punkweb_bb.move_thread"):
437
- return HttpResponseForbidden("You do not have permission to move threads.")
438
-
439
453
  thread = get_object_or_404(Thread, pk=thread_id)
440
454
 
441
455
  if request.method == "POST":
@@ -465,10 +479,7 @@ def thread_move_view(request, thread_id):
465
479
  def post_create_view(request, thread_id):
466
480
  thread = get_object_or_404(Thread, pk=thread_id)
467
481
 
468
- if not thread.can_post(request.user):
469
- return HttpResponseForbidden(
470
- "You do not have permission to post in this thread."
471
- )
482
+ check_object_permission(thread, "can_post", request.user)
472
483
 
473
484
  form = PostModelForm(request.POST)
474
485
 
@@ -485,8 +496,7 @@ def post_create_view(request, thread_id):
485
496
  def post_update_view(request, post_id):
486
497
  post = get_object_or_404(Post, pk=post_id)
487
498
 
488
- if not post.can_edit(request.user):
489
- return HttpResponseForbidden("You do not have permission to change this post.")
499
+ check_object_permission(post, "can_edit", request.user)
490
500
 
491
501
  if request.method == "POST":
492
502
  form = PostModelForm(request.POST, instance=post)
@@ -510,8 +520,7 @@ def post_update_view(request, post_id):
510
520
  def post_delete_view(request, post_id):
511
521
  post = get_object_or_404(Post, pk=post_id)
512
522
 
513
- if not post.can_delete(request.user):
514
- return HttpResponseForbidden("You do not have permission to delete this post.")
523
+ check_object_permission(post, "can_delete", request.user)
515
524
 
516
525
  if request.method == "DELETE":
517
526
  post.delete()
@@ -567,8 +576,7 @@ def shout_create_view(request):
567
576
  def shout_delete_view(request, shout_id):
568
577
  shout = get_object_or_404(Shout, pk=shout_id)
569
578
 
570
- if not shout.can_delete(request.user):
571
- return HttpResponseForbidden("You do not have permission to delete this shout.")
579
+ check_object_permission(shout, "can_delete", request.user)
572
580
 
573
581
  if request.method == "DELETE":
574
582
  shout.delete()
@@ -622,6 +630,7 @@ class ThreadModelForm(forms.ModelForm):
622
630
  [/code]
623
631
  """,
624
632
  ),
633
+ ("Spoiler", "[spoiler=Title]Content[/spoiler]"),
625
634
  ("Ordered List", "[ol][li]Item 1[/li][li]Item 2[/li][/ol]"),
626
635
  ("Unordered List", "[ul][li]Item 1[/li][li]Item 2[/li][/ul]"),
627
636
  ("Escape", "[escape][b]Escaped bbcode[/b][/escape]"),
@@ -632,3 +641,20 @@ class ThreadModelForm(forms.ModelForm):
632
641
  }
633
642
 
634
643
  return render(request, "punkweb_bb/bbcode.html", context=context)
644
+
645
+
646
+ def search_view(request):
647
+ query = request.GET.get("q", "")
648
+
649
+ print(query)
650
+
651
+ matching_threads = search_threads(query)
652
+
653
+ print(matching_threads)
654
+
655
+ context = {
656
+ "query": query,
657
+ "threads": matching_threads,
658
+ }
659
+
660
+ return render(request, "punkweb_bb/search.html", context=context)
punkweb_bb/widgets.py CHANGED
@@ -10,15 +10,14 @@ class BBCodeEditorWidget(forms.Textarea):
10
10
  css = {
11
11
  "all": (
12
12
  "/static/punkweb_bb/vendor/sceditor-3.2.0/minified/themes/square.min.css",
13
- "/static/punkweb_bb/editor/bbcode-editor.css",
14
13
  )
15
14
  }
16
15
  js = (
17
16
  "/static/punkweb_bb/vendor/jquery-3.7.0.min.js",
18
17
  "/static/punkweb_bb/vendor/sceditor-3.2.0/minified/jquery.sceditor.bbcode.min.js",
19
18
  "/static/punkweb_bb/vendor/sceditor-3.2.0/minified/icons/material.js",
20
- "/static/punkweb_bb/editor/bbcode-editor-tags.js",
21
- "/static/punkweb_bb/editor/bbcode-editor.js",
19
+ "/static/punkweb_bb/js/bbcode-editor-tags.js",
20
+ "/static/punkweb_bb/js/bbcode-editor.js",
22
21
  )
23
22
 
24
23
 
@@ -38,5 +37,5 @@ class MarkdownEditorWidget(forms.Textarea):
38
37
  js = (
39
38
  "/static/punkweb_bb/vendor/jquery-3.7.0.min.js",
40
39
  "/static/punkweb_bb/vendor/tiny-markdown-editor/dist/tiny-mde.min.js",
41
- "/static/punkweb_bb/editor/markdown-editor.js",
40
+ "/static/punkweb_bb/js/markdown-editor.js",
42
41
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: punkweb-bb
3
- Version: 0.4.2
3
+ Version: 0.5.0
4
4
  Summary: Django application that provides a simple and modern forum board software for your Django website.
5
5
  Home-page: https://github.com/Punkweb/PunkwebBB
6
6
  Author: Punkweb
@@ -45,18 +45,6 @@ Check out [punkweb.net](https://punkweb.net/board/) for documentation, support a
45
45
 
46
46
  It may work with older versions of Python and Django, but it has not been tested.
47
47
 
48
- ## BBCode or Markdown?
49
-
50
- PunkwebBB supports both BBCode and Markdown. You'll want to decide before installing which parser you want to use, as switching between them will cause existing threads, posts, signatures, etc. to render incorrectly! Switching will not affect the database schema, but it will affect the content.
51
-
52
- BBCode is the default parser, but you can switch to Markdown by setting the following in your Django settings module:
53
-
54
- ```python
55
- PUNKWEB_BB = {
56
- "PARSER": "markdown",
57
- }
58
- ```
59
-
60
48
  ## Installation
61
49
 
62
50
  ```bash
@@ -72,19 +60,12 @@ INSTALLED_APPS = [
72
60
  ]
73
61
  ```
74
62
 
75
- Add the following context processor to your `TEMPLATES` setting:
63
+ **_Optionally:_** Add the following middleware to your `MIDDLEWARE` setting, at the end of the list:
76
64
 
77
65
  ```python
78
- TEMPLATES = [
79
- {
80
- ...
81
- "OPTIONS": {
82
- "context_processors": [
83
- ...
84
- "punkweb_bb.context_processors.punkweb_bb",
85
- ],
86
- },
87
- },
66
+ MIDDLEWARE = [
67
+ ...
68
+ "punkweb_bb.middleware.ProfileOnlineCacheMiddleware",
88
69
  ]
89
70
  ```
90
71
 
@@ -105,6 +86,10 @@ And finally, install the models:
105
86
  python manage.py migrate
106
87
  ```
107
88
 
89
+ ## Deprecated notice (v0.5.0)
90
+
91
+ If you were using the package before v0.5.0, there was a step in the README to add a context processor. This is no longer necessary, as it's been removed, so you may get an error that it doesn't exist. If you see this error, you can safely remove the context processor from your settings.
92
+
108
93
  ## Configuration
109
94
 
110
95
  These are the default settings for PunkwebBB, which can be overridden in your Django settings module:
@@ -117,6 +102,8 @@ PUNKWEB_BB = {
117
102
  "FAVICON": "punkweb_bb/favicon.ico",
118
103
  "OG_IMAGE": None, # Used for Open Graph meta tags, must be a full URL!
119
104
  "SHOUTBOX_ENABLED": True,
105
+ "SHOUTBOX_POLLING_ENABLED": True,
106
+ "SHOUTBOX_POLLING_INTERVAL": 30, # in seconds
120
107
  "DISCORD_WIDGET_ENABLED": False,
121
108
  "DISCORD_WIDGET_THEME": "dark",
122
109
  "DISCORD_SERVER_ID": None, # Found under Server Settings > Widget > Server ID
@@ -143,7 +130,7 @@ Creating test database for alias 'default'...
143
130
  System check identified no issues (0 silenced).
144
131
  ...........................................................
145
132
  ----------------------------------------------------------------------
146
- Ran 59 tests in 8.994s
133
+ Ran 59 tests in 8.594s
147
134
 
148
135
  OK
149
136
  Destroying test database for alias 'default'...
@@ -153,30 +140,32 @@ punkweb_bb/__init__.py 0 0 100%
153
140
  punkweb_bb/admin.py 42 0 100%
154
141
  punkweb_bb/admin_forms.py 34 0 100%
155
142
  punkweb_bb/apps.py 6 0 100%
156
- punkweb_bb/bbcode.py 82 68 17%
157
- punkweb_bb/context_processors.py 3 0 100%
158
- punkweb_bb/forms.py 47 0 100%
143
+ punkweb_bb/bbcode.py 118 46 61%
144
+ punkweb_bb/decorators.py 12 0 100%
145
+ punkweb_bb/forms.py 59 0 100%
159
146
  punkweb_bb/guests.py 13 0 100%
160
- punkweb_bb/middleware.py 14 0 100%
147
+ punkweb_bb/middleware.py 27 3 89%
161
148
  punkweb_bb/mixins.py 11 0 100%
162
- punkweb_bb/models.py 153 1 99%
149
+ punkweb_bb/models.py 154 1 99%
163
150
  punkweb_bb/pagination.py 11 4 64%
164
151
  punkweb_bb/response.py 3 0 100%
165
- punkweb_bb/settings.py 11 0 100%
152
+ punkweb_bb/searching.py 8 5 38%
153
+ punkweb_bb/settings.py 13 0 100%
166
154
  punkweb_bb/signals.py 9 0 100%
167
155
  punkweb_bb/templatetags/__init__.py 0 0 100%
168
156
  punkweb_bb/templatetags/can_delete.py 5 0 100%
169
157
  punkweb_bb/templatetags/can_edit.py 5 0 100%
170
158
  punkweb_bb/templatetags/can_post.py 5 0 100%
171
159
  punkweb_bb/templatetags/humanize_int.py 9 5 44%
172
- punkweb_bb/templatetags/render.py 28 7 75%
160
+ punkweb_bb/templatetags/punkweb_bb.py 6 0 100%
161
+ punkweb_bb/templatetags/render.py 38 16 58%
173
162
  punkweb_bb/templatetags/styled_group_name.py 7 1 86%
174
163
  punkweb_bb/templatetags/styled_username.py 6 0 100%
175
164
  punkweb_bb/tests.py 418 0 100%
176
165
  punkweb_bb/urls.py 4 0 100%
177
- punkweb_bb/utils.py 42 23 45%
178
- punkweb_bb/views.py 304 118 61%
179
- punkweb_bb/widgets.py 16 0 100%
166
+ punkweb_bb/utils.py 44 26 41%
167
+ punkweb_bb/views.py 319 123 61%
168
+ punkweb_bb/widgets.py 16 2 88%
180
169
  ------------------------------------------------------------------
181
- TOTAL 1288 227 82%
170
+ TOTAL 1402 232 83%
182
171
  ```