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.
- 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/0001_initial.py +4 -25
- punkweb_bb/migrations/0004_groupstyle.py +1 -6
- punkweb_bb/migrations/0006_remove_boardprofile__signature_rendered_and_more.py +0 -20
- punkweb_bb/migrations/0007_boardprofile_bio.py +18 -0
- punkweb_bb/migrations/__pycache__/0001_initial.cpython-311.pyc +0 -0
- punkweb_bb/migrations/__pycache__/0001_squashed_0006_remove_boardprofile__signature_rendered_and_more.cpython-311.pyc +0 -0
- punkweb_bb/migrations/__pycache__/0004_groupstyle.cpython-311.pyc +0 -0
- punkweb_bb/migrations/__pycache__/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 +6 -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_delete_modal.html +2 -2
- 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 +14 -11
- 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 +12 -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 +23 -88
- 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__/render.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 +97 -71
- punkweb_bb/widgets.py +3 -4
- {punkweb_bb-0.4.2.dist-info → punkweb_bb-0.5.0.dist-info}/METADATA +25 -36
- {punkweb_bb-0.4.2.dist-info → punkweb_bb-0.5.0.dist-info}/RECORD +91 -67
- {punkweb_bb-0.4.2.dist-info → punkweb_bb-0.5.0.dist-info}/LICENSE +0 -0
- {punkweb_bb-0.4.2.dist-info → punkweb_bb-0.5.0.dist-info}/WHEEL +0 -0
- {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
|
-
|
|
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
|
|
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,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.
|
|
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
|
|
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
|
|
29
|
-
if
|
|
30
|
-
|
|
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
|
-
|
|
122
|
-
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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/
|
|
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.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
|
|
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
|
```
|