punkweb-bb 0.4.3__py3-none-any.whl → 0.5.1__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.
- punkweb_bb/__pycache__/bbcode.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/context_processors.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/decorators.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/forms.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/middleware.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/models.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/pagination.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/searching.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/settings.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/urls.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/utils.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/views.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/widgets.cpython-311.pyc +0 -0
- punkweb_bb/bbcode.py +4 -3
- punkweb_bb/decorators.py +17 -0
- punkweb_bb/forms.py +47 -10
- punkweb_bb/middleware.py +26 -1
- punkweb_bb/migrations/0007_boardprofile_bio.py +18 -0
- punkweb_bb/migrations/__pycache__/0001_squashed_0006_remove_boardprofile__signature_rendered_and_more.cpython-311.pyc +0 -0
- punkweb_bb/migrations/__pycache__/0007_boardprofile_bio.cpython-311.pyc +0 -0
- punkweb_bb/models.py +1 -0
- punkweb_bb/pagination.py +1 -1
- punkweb_bb/searching.py +10 -0
- punkweb_bb/settings.py +2 -0
- punkweb_bb/static/punkweb_bb/css/bbcode-editor-content.css +108 -0
- punkweb_bb/static/punkweb_bb/css/index.css +5 -6
- punkweb_bb/static/punkweb_bb/css/members.css +20 -3
- punkweb_bb/static/punkweb_bb/css/profile.css +5 -2
- punkweb_bb/static/punkweb_bb/css/punkweb.css +25 -687
- punkweb_bb/static/punkweb_bb/css/shoutbox.css +1 -9
- punkweb_bb/static/punkweb_bb/css/thread.css +4 -28
- punkweb_bb/static/punkweb_bb/js/bbcode-editor-tags.js +63 -0
- punkweb_bb/static/punkweb_bb/js/bbcode-editor.js +14 -0
- punkweb_bb/static/punkweb_bb/js/markdown-editor.js +49 -0
- punkweb_bb/static/punkweb_bb/js/punkweb-dialog.js +9 -0
- punkweb_bb/static/punkweb_bb/vendor/htmx-2.0.0.min.js +1 -0
- punkweb_bb/static/punkweb_bb/vendor/punkweb-ui.min.css +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/css/commandbar.css +2 -2
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/css/editor.css +1 -1
- punkweb_bb/templates/punkweb_bb/base.html +19 -21
- punkweb_bb/templates/punkweb_bb/base_delete_dialog.html +13 -0
- punkweb_bb/templates/punkweb_bb/base_dialog.html +16 -0
- punkweb_bb/templates/punkweb_bb/bbcode.html +11 -9
- punkweb_bb/templates/punkweb_bb/category_create.html +4 -21
- punkweb_bb/templates/punkweb_bb/category_update.html +3 -20
- punkweb_bb/templates/punkweb_bb/components/pagination_controls.html +45 -0
- punkweb_bb/templates/punkweb_bb/components/profile_image.html +11 -0
- punkweb_bb/templates/punkweb_bb/forms/inline_form.html +6 -0
- punkweb_bb/templates/punkweb_bb/forms/stacked_form.html +35 -0
- punkweb_bb/templates/punkweb_bb/index.html +65 -70
- punkweb_bb/templates/punkweb_bb/login.html +5 -11
- punkweb_bb/templates/punkweb_bb/members.html +23 -52
- punkweb_bb/templates/punkweb_bb/partials/category_delete.html +1 -1
- punkweb_bb/templates/punkweb_bb/partials/post_delete.html +1 -1
- punkweb_bb/templates/punkweb_bb/partials/post_update.html +4 -11
- punkweb_bb/templates/punkweb_bb/partials/shout_delete.html +1 -1
- punkweb_bb/templates/punkweb_bb/partials/subcategory_delete.html +1 -1
- punkweb_bb/templates/punkweb_bb/partials/thread_delete.html +1 -1
- punkweb_bb/templates/punkweb_bb/partials/thread_move.html +5 -13
- punkweb_bb/templates/punkweb_bb/profile.html +11 -8
- punkweb_bb/templates/punkweb_bb/search.html +27 -0
- punkweb_bb/templates/punkweb_bb/settings.html +7 -33
- punkweb_bb/templates/punkweb_bb/shoutbox/shout_list.html +2 -2
- punkweb_bb/templates/punkweb_bb/shoutbox/shoutbox.html +21 -6
- punkweb_bb/templates/punkweb_bb/signup.html +6 -15
- punkweb_bb/templates/punkweb_bb/subcategory.html +14 -54
- punkweb_bb/templates/punkweb_bb/subcategory_create.html +7 -16
- punkweb_bb/templates/punkweb_bb/subcategory_update.html +7 -16
- punkweb_bb/templates/punkweb_bb/thread.html +24 -87
- punkweb_bb/templates/punkweb_bb/thread_create.html +7 -16
- punkweb_bb/templates/punkweb_bb/thread_update.html +7 -16
- punkweb_bb/templatetags/__pycache__/can_delete.cpython-311.pyc +0 -0
- punkweb_bb/templatetags/__pycache__/punkweb_bb.cpython-311.pyc +0 -0
- punkweb_bb/templatetags/__pycache__/settings.cpython-311.pyc +0 -0
- punkweb_bb/templatetags/punkweb_bb.py +9 -0
- punkweb_bb/urls.py +1 -0
- punkweb_bb/views.py +113 -88
- punkweb_bb/widgets.py +3 -4
- {punkweb_bb-0.4.3.dist-info → punkweb_bb-0.5.1.dist-info}/METADATA +25 -36
- {punkweb_bb-0.4.3.dist-info → punkweb_bb-0.5.1.dist-info}/RECORD +83 -59
- {punkweb_bb-0.4.3.dist-info → punkweb_bb-0.5.1.dist-info}/LICENSE +0 -0
- {punkweb_bb-0.4.3.dist-info → punkweb_bb-0.5.1.dist-info}/WHEEL +0 -0
- {punkweb_bb-0.4.3.dist-info → punkweb_bb-0.5.1.dist-info}/top_level.txt +0 -0
|
@@ -5,7 +5,10 @@
|
|
|
5
5
|
|
|
6
6
|
{% block extra_head %}
|
|
7
7
|
{{form.media.css}}
|
|
8
|
-
|
|
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="
|
|
39
|
+
<form class="pw-form" action="{% url 'punkweb_bb:thread_update' thread.id %}" method="post">
|
|
37
40
|
{% csrf_token %}
|
|
38
|
-
{
|
|
39
|
-
<div class="
|
|
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 %}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
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,16 @@
|
|
|
1
1
|
from django.contrib.auth import authenticate, get_user_model, login, logout
|
|
2
|
-
from django.contrib.auth.decorators import login_required
|
|
3
|
-
from django.
|
|
2
|
+
from django.contrib.auth.decorators import login_required, permission_required
|
|
3
|
+
from django.core.exceptions import PermissionDenied
|
|
4
|
+
from django.db.models import Count
|
|
4
5
|
from django.shortcuts import get_object_or_404, redirect, render
|
|
5
6
|
from django.urls import reverse
|
|
6
7
|
from django.utils import timezone
|
|
7
8
|
|
|
9
|
+
from punkweb_bb.decorators import redirect_if_authenticated
|
|
8
10
|
from punkweb_bb.forms import (
|
|
9
11
|
BoardProfileModelForm,
|
|
10
12
|
CategoryModelForm,
|
|
13
|
+
FilterUsersForm,
|
|
11
14
|
LoginForm,
|
|
12
15
|
PostModelForm,
|
|
13
16
|
ShoutModelForm,
|
|
@@ -18,17 +21,21 @@ from punkweb_bb.forms import (
|
|
|
18
21
|
)
|
|
19
22
|
from punkweb_bb.guests import guest_list
|
|
20
23
|
from punkweb_bb.models import Category, Post, Shout, Subcategory, Thread
|
|
21
|
-
from punkweb_bb.pagination import
|
|
24
|
+
from punkweb_bb.pagination import paginate
|
|
22
25
|
from punkweb_bb.response import htmx_redirect
|
|
26
|
+
from punkweb_bb.searching import search_threads
|
|
23
27
|
from punkweb_bb.utils import get_unique_slug
|
|
24
28
|
|
|
25
29
|
User = get_user_model()
|
|
26
30
|
|
|
27
31
|
|
|
28
|
-
def
|
|
29
|
-
if
|
|
30
|
-
|
|
32
|
+
def check_object_permission(obj, func, user):
|
|
33
|
+
if not getattr(obj, func)(user):
|
|
34
|
+
raise PermissionDenied
|
|
35
|
+
|
|
31
36
|
|
|
37
|
+
@redirect_if_authenticated()
|
|
38
|
+
def signup_view(request):
|
|
32
39
|
if request.method == "POST":
|
|
33
40
|
form = SignUpForm(request.POST)
|
|
34
41
|
|
|
@@ -45,12 +52,10 @@ def signup_view(request):
|
|
|
45
52
|
return render(request, "punkweb_bb/signup.html", context)
|
|
46
53
|
|
|
47
54
|
|
|
55
|
+
@redirect_if_authenticated()
|
|
48
56
|
def login_view(request):
|
|
49
|
-
if request.user.is_authenticated:
|
|
50
|
-
return redirect("punkweb_bb:index")
|
|
51
|
-
|
|
52
57
|
if request.method == "POST":
|
|
53
|
-
form = LoginForm(request, request.POST)
|
|
58
|
+
form = LoginForm(request=request, data=request.POST)
|
|
54
59
|
|
|
55
60
|
if form.is_valid():
|
|
56
61
|
username = form.cleaned_data["username"]
|
|
@@ -111,24 +116,65 @@ def index_view(request):
|
|
|
111
116
|
def profile_view(request, user_id):
|
|
112
117
|
user = get_object_or_404(User, pk=user_id)
|
|
113
118
|
|
|
119
|
+
# Get top threads by post count
|
|
120
|
+
top_threads = user.threads.annotate(count_posts=Count("posts")).order_by(
|
|
121
|
+
"-count_posts"
|
|
122
|
+
)[:5]
|
|
123
|
+
|
|
124
|
+
# Get top subcategories by thread count
|
|
125
|
+
top_subcategories = (
|
|
126
|
+
user.threads.values("subcategory")
|
|
127
|
+
.annotate(count_threads=Count("subcategory"))
|
|
128
|
+
.order_by("-count_threads")
|
|
129
|
+
)
|
|
130
|
+
for subcategory in top_subcategories:
|
|
131
|
+
subcategory["subcategory"] = Subcategory.objects.get(
|
|
132
|
+
pk=subcategory["subcategory"]
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
threads_qs = user.threads.all().order_by("-created_at")
|
|
136
|
+
posts_qs = user.posts.all().order_by("-created_at")
|
|
137
|
+
|
|
138
|
+
threads = paginate(request, threads_qs)
|
|
139
|
+
posts = paginate(request, posts_qs)
|
|
140
|
+
|
|
114
141
|
context = {
|
|
115
142
|
"user": user,
|
|
143
|
+
"top_threads": top_threads,
|
|
144
|
+
"top_subcategories": top_subcategories,
|
|
145
|
+
"threads": threads,
|
|
146
|
+
"posts": posts,
|
|
116
147
|
}
|
|
148
|
+
|
|
117
149
|
return render(request, "punkweb_bb/profile.html", context=context)
|
|
118
150
|
|
|
119
151
|
|
|
120
152
|
def members_view(request):
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
)
|
|
153
|
+
users_qs = User.objects.all()
|
|
154
|
+
|
|
155
|
+
form = FilterUsersForm(request.GET)
|
|
156
|
+
if form.is_valid():
|
|
157
|
+
search = form.cleaned_data["search"]
|
|
158
|
+
sort_by = form.cleaned_data["sort_by"]
|
|
159
|
+
if search:
|
|
160
|
+
users_qs = users_qs.filter(username__icontains=search)
|
|
161
|
+
if sort_by:
|
|
162
|
+
users_qs = users_qs.order_by(sort_by)
|
|
163
|
+
else:
|
|
164
|
+
users_qs = users_qs.order_by("username")
|
|
165
|
+
|
|
166
|
+
users_qs = users_qs.select_related("profile")
|
|
167
|
+
|
|
168
|
+
users = paginate(request, users_qs)
|
|
124
169
|
|
|
125
170
|
context = {
|
|
171
|
+
"form": form,
|
|
126
172
|
"users": users,
|
|
127
173
|
}
|
|
128
174
|
return render(request, "punkweb_bb/members.html", context=context)
|
|
129
175
|
|
|
130
176
|
|
|
131
|
-
@login_required(
|
|
177
|
+
@login_required()
|
|
132
178
|
def settings_view(request):
|
|
133
179
|
if request.method == "POST":
|
|
134
180
|
form = BoardProfileModelForm(
|
|
@@ -151,11 +197,9 @@ def settings_view(request):
|
|
|
151
197
|
return render(request, "punkweb_bb/settings.html", context=context)
|
|
152
198
|
|
|
153
199
|
|
|
154
|
-
@login_required(
|
|
200
|
+
@login_required()
|
|
201
|
+
@permission_required("punkweb_bb.view_category", raise_exception=True)
|
|
155
202
|
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
203
|
if request.method == "POST":
|
|
160
204
|
form = CategoryModelForm(request.POST)
|
|
161
205
|
|
|
@@ -174,11 +218,9 @@ def category_create_view(request):
|
|
|
174
218
|
return render(request, "punkweb_bb/category_create.html", context=context)
|
|
175
219
|
|
|
176
220
|
|
|
177
|
-
@login_required(
|
|
221
|
+
@login_required()
|
|
222
|
+
@permission_required("punkweb_bb.change_category", raise_exception=True)
|
|
178
223
|
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
224
|
category = get_object_or_404(Category, slug=category_slug)
|
|
183
225
|
|
|
184
226
|
if request.method == "POST":
|
|
@@ -198,11 +240,9 @@ def category_update_view(request, category_slug):
|
|
|
198
240
|
return render(request, "punkweb_bb/category_update.html", context=context)
|
|
199
241
|
|
|
200
242
|
|
|
201
|
-
@login_required(
|
|
243
|
+
@login_required()
|
|
244
|
+
@permission_required("punkweb_bb.delete_category", raise_exception=True)
|
|
202
245
|
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
246
|
category = get_object_or_404(Category, slug=category_slug)
|
|
207
247
|
|
|
208
248
|
if request.method == "DELETE":
|
|
@@ -220,7 +260,7 @@ def category_delete_view(request, category_slug):
|
|
|
220
260
|
def subcategory_view(request, subcategory_slug):
|
|
221
261
|
subcategory = get_object_or_404(Subcategory, slug=subcategory_slug)
|
|
222
262
|
|
|
223
|
-
threads =
|
|
263
|
+
threads = paginate(request, subcategory.threads.all())
|
|
224
264
|
|
|
225
265
|
context = {
|
|
226
266
|
"subcategory": subcategory,
|
|
@@ -229,13 +269,9 @@ def subcategory_view(request, subcategory_slug):
|
|
|
229
269
|
return render(request, "punkweb_bb/subcategory.html", context=context)
|
|
230
270
|
|
|
231
271
|
|
|
232
|
-
@login_required(
|
|
272
|
+
@login_required()
|
|
273
|
+
@permission_required("punkweb_bb.add_subcategory", raise_exception=True)
|
|
233
274
|
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
275
|
category = get_object_or_404(Category, slug=category_slug)
|
|
240
276
|
|
|
241
277
|
if request.method == "POST":
|
|
@@ -249,7 +285,7 @@ def subcategory_create_view(request, category_slug):
|
|
|
249
285
|
|
|
250
286
|
return redirect(subcategory)
|
|
251
287
|
else:
|
|
252
|
-
form = SubcategoryModelForm()
|
|
288
|
+
form = SubcategoryModelForm(initial={"category": category})
|
|
253
289
|
|
|
254
290
|
context = {
|
|
255
291
|
"category": category,
|
|
@@ -258,13 +294,9 @@ def subcategory_create_view(request, category_slug):
|
|
|
258
294
|
return render(request, "punkweb_bb/subcategory_create.html", context=context)
|
|
259
295
|
|
|
260
296
|
|
|
261
|
-
@login_required(
|
|
297
|
+
@login_required()
|
|
298
|
+
@permission_required("punkweb_bb.change_subcategory", raise_exception=True)
|
|
262
299
|
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
300
|
subcategory = get_object_or_404(Subcategory, slug=subcategory_slug)
|
|
269
301
|
|
|
270
302
|
if request.method == "POST":
|
|
@@ -284,13 +316,9 @@ def subcategory_update_view(request, subcategory_slug):
|
|
|
284
316
|
return render(request, "punkweb_bb/subcategory_update.html", context=context)
|
|
285
317
|
|
|
286
318
|
|
|
287
|
-
@login_required(
|
|
319
|
+
@login_required()
|
|
320
|
+
@permission_required("punkweb_bb.delete_subcategory", raise_exception=True)
|
|
288
321
|
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
322
|
subcategory = get_object_or_404(Subcategory, slug=subcategory_slug)
|
|
295
323
|
|
|
296
324
|
if request.method == "DELETE":
|
|
@@ -307,14 +335,11 @@ def subcategory_delete_view(request, subcategory_slug):
|
|
|
307
335
|
)
|
|
308
336
|
|
|
309
337
|
|
|
310
|
-
@login_required(
|
|
338
|
+
@login_required()
|
|
311
339
|
def thread_create_view(request, subcategory_slug):
|
|
312
340
|
subcategory = get_object_or_404(Subcategory, slug=subcategory_slug)
|
|
313
341
|
|
|
314
|
-
|
|
315
|
-
return HttpResponseForbidden(
|
|
316
|
-
"You do not have permission to post in this subcategory."
|
|
317
|
-
)
|
|
342
|
+
check_object_permission(subcategory, "can_post", request.user)
|
|
318
343
|
|
|
319
344
|
if request.method == "POST":
|
|
320
345
|
form = ThreadModelForm(request.POST)
|
|
@@ -339,7 +364,7 @@ def thread_create_view(request, subcategory_slug):
|
|
|
339
364
|
def thread_view(request, thread_id):
|
|
340
365
|
thread = get_object_or_404(Thread, pk=thread_id)
|
|
341
366
|
|
|
342
|
-
posts =
|
|
367
|
+
posts = paginate(request, thread.posts.all())
|
|
343
368
|
|
|
344
369
|
post_form = PostModelForm()
|
|
345
370
|
|
|
@@ -358,14 +383,11 @@ def thread_view(request, thread_id):
|
|
|
358
383
|
return render(request, "punkweb_bb/thread.html", context=context)
|
|
359
384
|
|
|
360
385
|
|
|
361
|
-
@login_required(
|
|
386
|
+
@login_required()
|
|
362
387
|
def thread_update_view(request, thread_id):
|
|
363
388
|
thread = get_object_or_404(Thread, pk=thread_id)
|
|
364
389
|
|
|
365
|
-
|
|
366
|
-
return HttpResponseForbidden(
|
|
367
|
-
"You do not have permission to change this thread."
|
|
368
|
-
)
|
|
390
|
+
check_object_permission(thread, "can_edit", request.user)
|
|
369
391
|
|
|
370
392
|
if request.method == "POST":
|
|
371
393
|
form = ThreadModelForm(request.POST, instance=thread)
|
|
@@ -384,14 +406,11 @@ def thread_update_view(request, thread_id):
|
|
|
384
406
|
return render(request, "punkweb_bb/thread_update.html", context=context)
|
|
385
407
|
|
|
386
408
|
|
|
387
|
-
@login_required(
|
|
409
|
+
@login_required()
|
|
388
410
|
def thread_delete_view(request, thread_id):
|
|
389
411
|
thread = get_object_or_404(Thread, pk=thread_id)
|
|
390
412
|
|
|
391
|
-
|
|
392
|
-
return HttpResponseForbidden(
|
|
393
|
-
"You do not have permission to delete this thread."
|
|
394
|
-
)
|
|
413
|
+
check_object_permission(thread, "can_delete", request.user)
|
|
395
414
|
|
|
396
415
|
if request.method == "DELETE":
|
|
397
416
|
thread.delete()
|
|
@@ -405,11 +424,9 @@ def thread_delete_view(request, thread_id):
|
|
|
405
424
|
return render(request, "punkweb_bb/partials/thread_delete.html", context=context)
|
|
406
425
|
|
|
407
426
|
|
|
408
|
-
@login_required(
|
|
427
|
+
@login_required()
|
|
428
|
+
@permission_required("punkweb_bb.pin_thread", raise_exception=True)
|
|
409
429
|
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
430
|
thread = get_object_or_404(Thread, pk=thread_id)
|
|
414
431
|
|
|
415
432
|
thread.is_pinned = not thread.is_pinned
|
|
@@ -418,11 +435,9 @@ def thread_pin_view(request, thread_id):
|
|
|
418
435
|
return htmx_redirect(thread.get_absolute_url())
|
|
419
436
|
|
|
420
437
|
|
|
421
|
-
@login_required(
|
|
438
|
+
@login_required()
|
|
439
|
+
@permission_required("punkweb_bb.close_thread", raise_exception=True)
|
|
422
440
|
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
441
|
thread = get_object_or_404(Thread, pk=thread_id)
|
|
427
442
|
|
|
428
443
|
thread.is_closed = not thread.is_closed
|
|
@@ -431,11 +446,9 @@ def thread_close_view(request, thread_id):
|
|
|
431
446
|
return htmx_redirect(thread.get_absolute_url())
|
|
432
447
|
|
|
433
448
|
|
|
434
|
-
@login_required(
|
|
449
|
+
@login_required()
|
|
450
|
+
@permission_required("punkweb_bb.move_thread", raise_exception=True)
|
|
435
451
|
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
452
|
thread = get_object_or_404(Thread, pk=thread_id)
|
|
440
453
|
|
|
441
454
|
if request.method == "POST":
|
|
@@ -461,14 +474,11 @@ def thread_move_view(request, thread_id):
|
|
|
461
474
|
return render(request, "punkweb_bb/partials/thread_move.html", context=context)
|
|
462
475
|
|
|
463
476
|
|
|
464
|
-
@login_required(
|
|
477
|
+
@login_required()
|
|
465
478
|
def post_create_view(request, thread_id):
|
|
466
479
|
thread = get_object_or_404(Thread, pk=thread_id)
|
|
467
480
|
|
|
468
|
-
|
|
469
|
-
return HttpResponseForbidden(
|
|
470
|
-
"You do not have permission to post in this thread."
|
|
471
|
-
)
|
|
481
|
+
check_object_permission(thread, "can_post", request.user)
|
|
472
482
|
|
|
473
483
|
form = PostModelForm(request.POST)
|
|
474
484
|
|
|
@@ -481,12 +491,11 @@ def post_create_view(request, thread_id):
|
|
|
481
491
|
return redirect(post)
|
|
482
492
|
|
|
483
493
|
|
|
484
|
-
@login_required(
|
|
494
|
+
@login_required()
|
|
485
495
|
def post_update_view(request, post_id):
|
|
486
496
|
post = get_object_or_404(Post, pk=post_id)
|
|
487
497
|
|
|
488
|
-
|
|
489
|
-
return HttpResponseForbidden("You do not have permission to change this post.")
|
|
498
|
+
check_object_permission(post, "can_edit", request.user)
|
|
490
499
|
|
|
491
500
|
if request.method == "POST":
|
|
492
501
|
form = PostModelForm(request.POST, instance=post)
|
|
@@ -506,12 +515,11 @@ def post_update_view(request, post_id):
|
|
|
506
515
|
return render(request, "punkweb_bb/partials/post_update.html", context=context)
|
|
507
516
|
|
|
508
517
|
|
|
509
|
-
@login_required(
|
|
518
|
+
@login_required()
|
|
510
519
|
def post_delete_view(request, post_id):
|
|
511
520
|
post = get_object_or_404(Post, pk=post_id)
|
|
512
521
|
|
|
513
|
-
|
|
514
|
-
return HttpResponseForbidden("You do not have permission to delete this post.")
|
|
522
|
+
check_object_permission(post, "can_delete", request.user)
|
|
515
523
|
|
|
516
524
|
if request.method == "DELETE":
|
|
517
525
|
post.delete()
|
|
@@ -563,12 +571,11 @@ def shout_create_view(request):
|
|
|
563
571
|
)
|
|
564
572
|
|
|
565
573
|
|
|
566
|
-
@login_required(
|
|
574
|
+
@login_required()
|
|
567
575
|
def shout_delete_view(request, shout_id):
|
|
568
576
|
shout = get_object_or_404(Shout, pk=shout_id)
|
|
569
577
|
|
|
570
|
-
|
|
571
|
-
return HttpResponseForbidden("You do not have permission to delete this shout.")
|
|
578
|
+
check_object_permission(shout, "can_delete", request.user)
|
|
572
579
|
|
|
573
580
|
if request.method == "DELETE":
|
|
574
581
|
shout.delete()
|
|
@@ -622,6 +629,7 @@ class ThreadModelForm(forms.ModelForm):
|
|
|
622
629
|
[/code]
|
|
623
630
|
""",
|
|
624
631
|
),
|
|
632
|
+
("Spoiler", "[spoiler=Title]Content[/spoiler]"),
|
|
625
633
|
("Ordered List", "[ol][li]Item 1[/li][li]Item 2[/li][/ol]"),
|
|
626
634
|
("Unordered List", "[ul][li]Item 1[/li][li]Item 2[/li][/ul]"),
|
|
627
635
|
("Escape", "[escape][b]Escaped bbcode[/b][/escape]"),
|
|
@@ -632,3 +640,20 @@ class ThreadModelForm(forms.ModelForm):
|
|
|
632
640
|
}
|
|
633
641
|
|
|
634
642
|
return render(request, "punkweb_bb/bbcode.html", context=context)
|
|
643
|
+
|
|
644
|
+
|
|
645
|
+
def search_view(request):
|
|
646
|
+
query = request.GET.get("q", "")
|
|
647
|
+
|
|
648
|
+
print(query)
|
|
649
|
+
|
|
650
|
+
matching_threads = search_threads(query)
|
|
651
|
+
|
|
652
|
+
print(matching_threads)
|
|
653
|
+
|
|
654
|
+
context = {
|
|
655
|
+
"query": query,
|
|
656
|
+
"threads": matching_threads,
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
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/
|
|
21
|
-
"/static/punkweb_bb/
|
|
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/
|
|
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.
|
|
3
|
+
Version: 0.5.1
|
|
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
|
|
63
|
+
**_Optionally:_** Add the following middleware to your `MIDDLEWARE` setting, at the end of the list:
|
|
76
64
|
|
|
77
65
|
```python
|
|
78
|
-
|
|
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.
|
|
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
|
|
157
|
-
punkweb_bb/
|
|
158
|
-
punkweb_bb/forms.py
|
|
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
|
|
147
|
+
punkweb_bb/middleware.py 27 3 89%
|
|
161
148
|
punkweb_bb/mixins.py 11 0 100%
|
|
162
|
-
punkweb_bb/models.py
|
|
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/
|
|
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/
|
|
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
|
|
178
|
-
punkweb_bb/views.py
|
|
179
|
-
punkweb_bb/widgets.py 16
|
|
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
|
|
170
|
+
TOTAL 1402 232 83%
|
|
182
171
|
```
|