punkweb-bb 0.1.4__py3-none-any.whl → 0.2.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__/forms.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/models.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/tests.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/forms.py +40 -7
- punkweb_bb/models.py +21 -0
- punkweb_bb/static/punkweb_bb/css/category-form.css +24 -0
- punkweb_bb/static/punkweb_bb/css/index.css +6 -0
- punkweb_bb/static/punkweb_bb/css/punkweb.css +61 -5
- punkweb_bb/static/punkweb_bb/css/shoutbox.css +13 -2
- punkweb_bb/static/punkweb_bb/css/subcategory-form.css +24 -0
- punkweb_bb/static/punkweb_bb/css/subcategory.css +12 -0
- punkweb_bb/static/punkweb_bb/css/thread.css +19 -0
- punkweb_bb/static/punkweb_bb/css/variables.css +1 -0
- punkweb_bb/templates/punkweb_bb/category_create.html +50 -0
- punkweb_bb/templates/punkweb_bb/category_update.html +53 -0
- punkweb_bb/templates/punkweb_bb/index.html +27 -1
- punkweb_bb/templates/punkweb_bb/partials/category_delete.html +11 -0
- punkweb_bb/templates/punkweb_bb/partials/shout_delete.html +11 -0
- punkweb_bb/templates/punkweb_bb/partials/subcategory_delete.html +11 -0
- punkweb_bb/templates/punkweb_bb/shoutbox/shout_list.html +14 -4
- punkweb_bb/templates/punkweb_bb/subcategory.html +21 -6
- punkweb_bb/templates/punkweb_bb/subcategory_create.html +53 -0
- punkweb_bb/templates/punkweb_bb/subcategory_update.html +56 -0
- punkweb_bb/templates/punkweb_bb/thread.html +26 -6
- punkweb_bb/templates/punkweb_bb/thread_create.html +1 -0
- punkweb_bb/templatetags/__pycache__/can_delete.cpython-311.pyc +0 -0
- punkweb_bb/templatetags/__pycache__/can_edit.cpython-311.pyc +0 -0
- punkweb_bb/templatetags/__pycache__/can_post.cpython-311.pyc +0 -0
- punkweb_bb/templatetags/can_delete.py +8 -0
- punkweb_bb/templatetags/can_edit.py +8 -0
- punkweb_bb/templatetags/can_post.py +8 -0
- punkweb_bb/tests.py +5 -5
- punkweb_bb/urls.py +27 -0
- punkweb_bb/utils.py +17 -0
- punkweb_bb/views.py +232 -45
- {punkweb_bb-0.1.4.dist-info → punkweb_bb-0.2.0.dist-info}/METADATA +2 -2
- {punkweb_bb-0.1.4.dist-info → punkweb_bb-0.2.0.dist-info}/RECORD +43 -26
- {punkweb_bb-0.1.4.dist-info → punkweb_bb-0.2.0.dist-info}/LICENSE +0 -0
- {punkweb_bb-0.1.4.dist-info → punkweb_bb-0.2.0.dist-info}/WHEEL +0 -0
- {punkweb_bb-0.1.4.dist-info → punkweb_bb-0.2.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{% extends 'punkweb_bb/base.html' %}
|
|
2
|
+
{% load static %}
|
|
3
|
+
|
|
4
|
+
{% block title_prefix %}Edit Subcategory | {% endblock %}
|
|
5
|
+
|
|
6
|
+
{% block extra_head %}
|
|
7
|
+
{{form.media.css}}
|
|
8
|
+
<link rel="stylesheet" href="{% static 'punkweb_bb/css/subcategory-form.css' %}" />
|
|
9
|
+
{% endblock %}
|
|
10
|
+
|
|
11
|
+
{% block content %}
|
|
12
|
+
|
|
13
|
+
<nav>
|
|
14
|
+
<ul class="pw-breadcrumb">
|
|
15
|
+
<li class="pw-breadcrumb-item">
|
|
16
|
+
<a href="{% url 'punkweb_bb:index' %}">Home</a>
|
|
17
|
+
</li>
|
|
18
|
+
<li class="pw-breadcrumb-item">
|
|
19
|
+
<a href="{{subcategory.category.get_absolute_url}}">{{subcategory.category.name}}</a>
|
|
20
|
+
</li>
|
|
21
|
+
<li class="pw-breadcrumb-item">
|
|
22
|
+
<a href="{{subcategory.get_absolute_url}}">{{subcategory.name}}</a>
|
|
23
|
+
</li>
|
|
24
|
+
<li class="pw-breadcrumb-item active">
|
|
25
|
+
Edit
|
|
26
|
+
</li>
|
|
27
|
+
</ul>
|
|
28
|
+
</nav>
|
|
29
|
+
|
|
30
|
+
<div class="pw-card fluid">
|
|
31
|
+
<div class="pw-card-header">Edit Subcategory</div>
|
|
32
|
+
<div class="pw-card-content">
|
|
33
|
+
<form class="subcategoryForm" action="{% url 'punkweb_bb:subcategory_update' subcategory.slug %}" method="post">
|
|
34
|
+
{% csrf_token %}
|
|
35
|
+
{% for field in form %}
|
|
36
|
+
<div class="subcategoryForm__field">
|
|
37
|
+
<label class="pw-input-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
|
|
38
|
+
{{ field }}
|
|
39
|
+
</div>
|
|
40
|
+
{% endfor %}
|
|
41
|
+
{% if form.non_field_errors %}
|
|
42
|
+
{{ form.non_field_errors }}
|
|
43
|
+
{% endif %}
|
|
44
|
+
<div class="subcategoryForm__actions">
|
|
45
|
+
<a class="pw-button default" href="{{subcategory.get_absolute_url}}">Cancel</a>
|
|
46
|
+
<button class="pw-button raised primary" type="submit">Save</button>
|
|
47
|
+
</div>
|
|
48
|
+
</form>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
{% endblock %}
|
|
53
|
+
|
|
54
|
+
{% block extra_script %}
|
|
55
|
+
{{form.media.js}}
|
|
56
|
+
{% endblock %}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{% extends 'punkweb_bb/base.html' %}
|
|
2
|
-
{% load static %}
|
|
2
|
+
{% load static can_delete can_edit can_post %}
|
|
3
3
|
|
|
4
4
|
{% block title_prefix %}{{thread.title}} | {% endblock %}
|
|
5
5
|
|
|
@@ -67,6 +67,13 @@
|
|
|
67
67
|
<div class="thread__user__info__value">{{thread.user.profile.post_count}}</div>
|
|
68
68
|
</div>
|
|
69
69
|
</div>
|
|
70
|
+
{% if thread.user.groups.all|length > 0 %}
|
|
71
|
+
<div class="thread__user__groups">
|
|
72
|
+
{% for group in thread.user.groups.all %}
|
|
73
|
+
<div class="thread__user__group">{{group.name}}</div>
|
|
74
|
+
{% endfor %}
|
|
75
|
+
</div>
|
|
76
|
+
{% endif %}
|
|
70
77
|
</div>
|
|
71
78
|
<div class="thread__main">
|
|
72
79
|
<div class="thread__content">
|
|
@@ -77,13 +84,17 @@
|
|
|
77
84
|
{{thread.user.profile.signature.rendered}}
|
|
78
85
|
</div>
|
|
79
86
|
{% endif %}
|
|
80
|
-
{% if thread.user
|
|
87
|
+
{% if thread|can_delete:request.user or thread|can_edit:request.user %}
|
|
81
88
|
<div class="thread__actions">
|
|
89
|
+
{% if thread|can_edit:request.user %}
|
|
82
90
|
<a class="pw-button ghost sm" href="{% url 'punkweb_bb:thread_update' thread.id %}">Edit</a>
|
|
91
|
+
{% endif %}
|
|
92
|
+
{% if thread|can_delete:request.user %}
|
|
83
93
|
<a class="pw-button ghost danger sm" hx-get="{% url 'punkweb_bb:thread_delete' thread.id %}"
|
|
84
94
|
hx-target="#modal-portal">
|
|
85
95
|
Delete
|
|
86
96
|
</a>
|
|
97
|
+
{% endif %}
|
|
87
98
|
</div>
|
|
88
99
|
{% endif %}
|
|
89
100
|
</div>
|
|
@@ -128,6 +139,13 @@
|
|
|
128
139
|
<div class="thread__user__info__value">{{post.user.profile.post_count}}</div>
|
|
129
140
|
</div>
|
|
130
141
|
</div>
|
|
142
|
+
{% if post.user.groups.all|length > 0 %}
|
|
143
|
+
<div class="thread__user__groups">
|
|
144
|
+
{% for group in post.user.groups.all %}
|
|
145
|
+
<div class="thread__user__group">{{group.name}}</div>
|
|
146
|
+
{% endfor %}
|
|
147
|
+
</div>
|
|
148
|
+
{% endif %}
|
|
131
149
|
</div>
|
|
132
150
|
<div class="thread__main">
|
|
133
151
|
<div class="thread__content">
|
|
@@ -138,13 +156,17 @@
|
|
|
138
156
|
{{post.user.profile.signature.rendered}}
|
|
139
157
|
</div>
|
|
140
158
|
{% endif %}
|
|
141
|
-
{% if post.user
|
|
159
|
+
{% if post|can_delete:request.user or post|can_edit:request.user %}
|
|
142
160
|
<div class="thread__actions">
|
|
161
|
+
{% if post|can_edit:request.user %}
|
|
143
162
|
<a class="pw-button ghost sm" hx-get="{% url 'punkweb_bb:post_update' post.id %}" hx-target="#modal-portal">Edit</a>
|
|
163
|
+
{% endif %}
|
|
164
|
+
{% if post|can_delete:request.user %}
|
|
144
165
|
<a class="pw-button ghost danger sm" hx-get="{% url 'punkweb_bb:post_delete' post.id %}"
|
|
145
166
|
hx-target="#modal-portal">
|
|
146
167
|
Delete
|
|
147
168
|
</a>
|
|
169
|
+
{% endif %}
|
|
148
170
|
</div>
|
|
149
171
|
{% endif %}
|
|
150
172
|
</div>
|
|
@@ -198,8 +220,7 @@
|
|
|
198
220
|
</nav>
|
|
199
221
|
{% endif %}
|
|
200
222
|
|
|
201
|
-
{% if request.user
|
|
202
|
-
{% if not thread.is_closed %}
|
|
223
|
+
{% if thread|can_post:request.user %}
|
|
203
224
|
<div class="pw-card fluid margin">
|
|
204
225
|
<div class="pw-card-header">Reply to thread</div>
|
|
205
226
|
<div class="pw-card-content">
|
|
@@ -229,6 +250,5 @@
|
|
|
229
250
|
</div>
|
|
230
251
|
</div>
|
|
231
252
|
{% endif %}
|
|
232
|
-
{% endif %}
|
|
233
253
|
|
|
234
254
|
{% endblock %}
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
{{ form.non_field_errors }}
|
|
43
43
|
{% endif %}
|
|
44
44
|
<div class="threadForm__actions">
|
|
45
|
+
<a class="pw-button default" href="{{subcategory.get_absolute_url}}" type="submit">Cancel</a>
|
|
45
46
|
<button class="pw-button raised primary" type="submit">Create Thread</button>
|
|
46
47
|
</div>
|
|
47
48
|
</form>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
punkweb_bb/tests.py
CHANGED
|
@@ -474,7 +474,7 @@ class ThreadCreateViewTestCase(TestCase):
|
|
|
474
474
|
self.client.force_login(self.user)
|
|
475
475
|
response = self.client.get(self.staff_only_url)
|
|
476
476
|
|
|
477
|
-
self.
|
|
477
|
+
self.assertEqual(response.status_code, 403)
|
|
478
478
|
|
|
479
479
|
|
|
480
480
|
class ThreadViewTestCase(TestCase):
|
|
@@ -522,7 +522,7 @@ class ThreadUpdateViewTestCase(TestCase):
|
|
|
522
522
|
def test_is_author(self):
|
|
523
523
|
self.client.force_login(self.other_user)
|
|
524
524
|
response = self.client.get(self.url)
|
|
525
|
-
self.assertEqual(response.status_code,
|
|
525
|
+
self.assertEqual(response.status_code, 403)
|
|
526
526
|
|
|
527
527
|
self.client.force_login(self.user)
|
|
528
528
|
response = self.client.get(self.url)
|
|
@@ -571,7 +571,7 @@ class ThreadDeleteViewTestCase(TestCase):
|
|
|
571
571
|
def test_is_author(self):
|
|
572
572
|
self.client.force_login(self.other_user)
|
|
573
573
|
response = self.client.get(self.url)
|
|
574
|
-
self.assertEqual(response.status_code,
|
|
574
|
+
self.assertEqual(response.status_code, 403)
|
|
575
575
|
|
|
576
576
|
self.client.force_login(self.user)
|
|
577
577
|
response = self.client.get(self.url)
|
|
@@ -653,7 +653,7 @@ class PostUpdateViewTestCase(TestCase):
|
|
|
653
653
|
def test_is_author(self):
|
|
654
654
|
self.client.force_login(self.other_user)
|
|
655
655
|
response = self.client.get(self.url)
|
|
656
|
-
self.assertEqual(response.status_code,
|
|
656
|
+
self.assertEqual(response.status_code, 403)
|
|
657
657
|
|
|
658
658
|
self.client.force_login(self.user)
|
|
659
659
|
response = self.client.get(self.url)
|
|
@@ -703,7 +703,7 @@ class PostDeleteViewTestCase(TestCase):
|
|
|
703
703
|
def test_is_author(self):
|
|
704
704
|
self.client.force_login(self.other_user)
|
|
705
705
|
response = self.client.get(self.url)
|
|
706
|
-
self.assertEqual(response.status_code,
|
|
706
|
+
self.assertEqual(response.status_code, 403)
|
|
707
707
|
|
|
708
708
|
self.client.force_login(self.user)
|
|
709
709
|
response = self.client.get(self.url)
|
punkweb_bb/urls.py
CHANGED
|
@@ -11,11 +11,37 @@ urlpatterns = [
|
|
|
11
11
|
path("settings/", views.settings_view, name="settings"),
|
|
12
12
|
path("members/", views.members_view, name="members"),
|
|
13
13
|
path("members/<path:user_id>/", views.profile_view, name="profile"),
|
|
14
|
+
path("create-category/", views.category_create_view, name="category_create"),
|
|
15
|
+
path(
|
|
16
|
+
"category/<str:category_slug>/update/",
|
|
17
|
+
views.category_update_view,
|
|
18
|
+
name="category_update",
|
|
19
|
+
),
|
|
20
|
+
path(
|
|
21
|
+
"category/<str:category_slug>/delete/",
|
|
22
|
+
views.category_delete_view,
|
|
23
|
+
name="category_delete",
|
|
24
|
+
),
|
|
14
25
|
path(
|
|
15
26
|
"subcategory/<str:subcategory_slug>/",
|
|
16
27
|
views.subcategory_view,
|
|
17
28
|
name="subcategory",
|
|
18
29
|
),
|
|
30
|
+
path(
|
|
31
|
+
"category/<str:category_slug>/create-subcategory/",
|
|
32
|
+
views.subcategory_create_view,
|
|
33
|
+
name="subcategory_create",
|
|
34
|
+
),
|
|
35
|
+
path(
|
|
36
|
+
"subcategory/<str:subcategory_slug>/update/",
|
|
37
|
+
views.subcategory_update_view,
|
|
38
|
+
name="subcategory_update",
|
|
39
|
+
),
|
|
40
|
+
path(
|
|
41
|
+
"subcategory/<str:subcategory_slug>/delete/",
|
|
42
|
+
views.subcategory_delete_view,
|
|
43
|
+
name="subcategory_delete",
|
|
44
|
+
),
|
|
19
45
|
path(
|
|
20
46
|
"subcategory/<str:subcategory_slug>/create-thread/",
|
|
21
47
|
views.thread_create_view,
|
|
@@ -37,5 +63,6 @@ urlpatterns = [
|
|
|
37
63
|
path("post/<str:post_id>/update/", views.post_update_view, name="post_update"),
|
|
38
64
|
path("shout-list/", views.shout_list_view, name="shout_list"),
|
|
39
65
|
path("shout-create/", views.shout_create_view, name="shout_create"),
|
|
66
|
+
path("shout/<str:shout_id>/delete/", views.shout_delete_view, name="shout_delete"),
|
|
40
67
|
path("bbcode/", views.bbcode_view, name="bbcode"),
|
|
41
68
|
]
|
punkweb_bb/utils.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from django.utils.text import slugify
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def get_unique_slug(model, field):
|
|
5
|
+
base_slug = slugify(field)
|
|
6
|
+
slug = base_slug
|
|
7
|
+
unique_slug_exists = True
|
|
8
|
+
|
|
9
|
+
counter = 1
|
|
10
|
+
while unique_slug_exists:
|
|
11
|
+
if model.objects.filter(slug=slug).exists():
|
|
12
|
+
slug = f"{base_slug}-{counter}"
|
|
13
|
+
counter += 1
|
|
14
|
+
else:
|
|
15
|
+
unique_slug_exists = False
|
|
16
|
+
|
|
17
|
+
return slug
|
punkweb_bb/views.py
CHANGED
|
@@ -4,54 +4,46 @@ from django.contrib.auth import authenticate, get_user_model, login, logout
|
|
|
4
4
|
from django.contrib.auth.decorators import login_required
|
|
5
5
|
from django.http import HttpResponseForbidden
|
|
6
6
|
from django.shortcuts import get_object_or_404, redirect, render
|
|
7
|
+
from django.urls import reverse
|
|
7
8
|
from django.utils import timezone
|
|
8
9
|
|
|
9
|
-
from punkweb_bb.guests import guest_list
|
|
10
10
|
from punkweb_bb.forms import (
|
|
11
11
|
BoardProfileModelForm,
|
|
12
|
+
CategoryModelForm,
|
|
12
13
|
LoginForm,
|
|
13
14
|
PostModelForm,
|
|
14
15
|
ShoutModelForm,
|
|
15
16
|
SignUpForm,
|
|
17
|
+
SubcategoryModelForm,
|
|
16
18
|
ThreadModelForm,
|
|
17
19
|
)
|
|
20
|
+
from punkweb_bb.guests import guest_list
|
|
18
21
|
from punkweb_bb.models import Category, Post, Shout, Subcategory, Thread
|
|
19
22
|
from punkweb_bb.pagination import paginate_qs
|
|
20
23
|
from punkweb_bb.response import htmx_redirect
|
|
24
|
+
from punkweb_bb.utils import get_unique_slug
|
|
21
25
|
|
|
22
26
|
User = get_user_model()
|
|
23
27
|
|
|
24
28
|
|
|
25
|
-
def
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
recent_threads = Thread.objects.all().order_by("-created_at")[:5]
|
|
29
|
+
def signup_view(request):
|
|
30
|
+
if request.user.is_authenticated:
|
|
31
|
+
return redirect("punkweb_bb:index")
|
|
29
32
|
|
|
30
|
-
|
|
31
|
-
|
|
33
|
+
if request.method == "POST":
|
|
34
|
+
form = SignUpForm(request.POST)
|
|
32
35
|
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
if form.is_valid():
|
|
37
|
+
form.save()
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
guests_online = guest_list.length()
|
|
40
|
-
total_online = len(members_online) + len(staff_online) + guests_online
|
|
39
|
+
return redirect("punkweb_bb:login")
|
|
40
|
+
else:
|
|
41
|
+
form = SignUpForm()
|
|
41
42
|
|
|
42
43
|
context = {
|
|
43
|
-
"
|
|
44
|
-
"recent_threads": recent_threads,
|
|
45
|
-
"thread_count": thread_count,
|
|
46
|
-
"post_count": post_count,
|
|
47
|
-
"users": users,
|
|
48
|
-
"newest_user": newest_user,
|
|
49
|
-
"members_online": members_online,
|
|
50
|
-
"staff_online": staff_online,
|
|
51
|
-
"guests_online": guests_online,
|
|
52
|
-
"total_online": total_online,
|
|
44
|
+
"form": form,
|
|
53
45
|
}
|
|
54
|
-
return render(request, "punkweb_bb/
|
|
46
|
+
return render(request, "punkweb_bb/signup.html", context)
|
|
55
47
|
|
|
56
48
|
|
|
57
49
|
def login_view(request):
|
|
@@ -85,24 +77,36 @@ def logout_view(request):
|
|
|
85
77
|
return redirect("punkweb_bb:login")
|
|
86
78
|
|
|
87
79
|
|
|
88
|
-
def
|
|
89
|
-
|
|
90
|
-
return redirect("punkweb_bb:index")
|
|
80
|
+
def index_view(request):
|
|
81
|
+
categories = Category.objects.all()
|
|
91
82
|
|
|
92
|
-
|
|
93
|
-
form = SignUpForm(request.POST)
|
|
83
|
+
recent_threads = Thread.objects.all().order_by("-created_at")[:5]
|
|
94
84
|
|
|
95
|
-
|
|
96
|
-
|
|
85
|
+
thread_count = Thread.objects.count()
|
|
86
|
+
post_count = Post.objects.count()
|
|
97
87
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
88
|
+
users = User.objects.select_related("profile").all()
|
|
89
|
+
newest_user = users.order_by("-profile__created_at").first()
|
|
90
|
+
|
|
91
|
+
users_online = [user for user in users if user.profile.is_online]
|
|
92
|
+
members_online = [user for user in users_online if not user.is_staff]
|
|
93
|
+
staff_online = [user for user in users_online if user.is_staff]
|
|
94
|
+
guests_online = guest_list.length()
|
|
95
|
+
total_online = len(members_online) + len(staff_online) + guests_online
|
|
101
96
|
|
|
102
97
|
context = {
|
|
103
|
-
"
|
|
98
|
+
"categories": categories,
|
|
99
|
+
"recent_threads": recent_threads,
|
|
100
|
+
"thread_count": thread_count,
|
|
101
|
+
"post_count": post_count,
|
|
102
|
+
"users": users,
|
|
103
|
+
"newest_user": newest_user,
|
|
104
|
+
"members_online": members_online,
|
|
105
|
+
"staff_online": staff_online,
|
|
106
|
+
"guests_online": guests_online,
|
|
107
|
+
"total_online": total_online,
|
|
104
108
|
}
|
|
105
|
-
return render(request, "punkweb_bb/
|
|
109
|
+
return render(request, "punkweb_bb/index.html", context=context)
|
|
106
110
|
|
|
107
111
|
|
|
108
112
|
def profile_view(request, user_id):
|
|
@@ -148,6 +152,72 @@ def settings_view(request):
|
|
|
148
152
|
return render(request, "punkweb_bb/settings.html", context=context)
|
|
149
153
|
|
|
150
154
|
|
|
155
|
+
@login_required(login_url="/login/")
|
|
156
|
+
def category_create_view(request):
|
|
157
|
+
if not request.user.has_perm("punkweb_bb.add_category"):
|
|
158
|
+
return HttpResponseForbidden("You do not have permission to create categories.")
|
|
159
|
+
|
|
160
|
+
if request.method == "POST":
|
|
161
|
+
form = CategoryModelForm(request.POST)
|
|
162
|
+
|
|
163
|
+
if form.is_valid():
|
|
164
|
+
category = form.save(commit=False)
|
|
165
|
+
category.slug = get_unique_slug(Category, category.name)
|
|
166
|
+
category.save()
|
|
167
|
+
|
|
168
|
+
return redirect(category)
|
|
169
|
+
else:
|
|
170
|
+
form = CategoryModelForm()
|
|
171
|
+
|
|
172
|
+
context = {
|
|
173
|
+
"form": form,
|
|
174
|
+
}
|
|
175
|
+
return render(request, "punkweb_bb/category_create.html", context=context)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
@login_required(login_url="/login/")
|
|
179
|
+
def category_update_view(request, category_slug):
|
|
180
|
+
if not request.user.has_perm("punkweb_bb.change_category"):
|
|
181
|
+
return HttpResponseForbidden("You do not have permission to change categories.")
|
|
182
|
+
|
|
183
|
+
category = get_object_or_404(Category, slug=category_slug)
|
|
184
|
+
|
|
185
|
+
if request.method == "POST":
|
|
186
|
+
form = CategoryModelForm(request.POST, instance=category)
|
|
187
|
+
|
|
188
|
+
if form.is_valid():
|
|
189
|
+
category = form.save()
|
|
190
|
+
|
|
191
|
+
return redirect(category)
|
|
192
|
+
else:
|
|
193
|
+
form = CategoryModelForm(instance=category)
|
|
194
|
+
|
|
195
|
+
context = {
|
|
196
|
+
"category": category,
|
|
197
|
+
"form": form,
|
|
198
|
+
}
|
|
199
|
+
return render(request, "punkweb_bb/category_update.html", context=context)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
@login_required(login_url="/login/")
|
|
203
|
+
def category_delete_view(request, category_slug):
|
|
204
|
+
if not request.user.has_perm("punkweb_bb.delete_category"):
|
|
205
|
+
return HttpResponseForbidden("You do not have permission to delete categories.")
|
|
206
|
+
|
|
207
|
+
category = get_object_or_404(Category, slug=category_slug)
|
|
208
|
+
|
|
209
|
+
if request.method == "DELETE":
|
|
210
|
+
category.delete()
|
|
211
|
+
|
|
212
|
+
return htmx_redirect(reverse("punkweb_bb:index"))
|
|
213
|
+
|
|
214
|
+
context = {
|
|
215
|
+
"category": category,
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return render(request, "punkweb_bb/partials/category_delete.html", context=context)
|
|
219
|
+
|
|
220
|
+
|
|
151
221
|
def subcategory_view(request, subcategory_slug):
|
|
152
222
|
subcategory = get_object_or_404(Subcategory, slug=subcategory_slug)
|
|
153
223
|
|
|
@@ -160,12 +230,92 @@ def subcategory_view(request, subcategory_slug):
|
|
|
160
230
|
return render(request, "punkweb_bb/subcategory.html", context=context)
|
|
161
231
|
|
|
162
232
|
|
|
233
|
+
@login_required(login_url="/login/")
|
|
234
|
+
def subcategory_create_view(request, category_slug):
|
|
235
|
+
if not request.user.has_perm("punkweb_bb.add_subcategory"):
|
|
236
|
+
return HttpResponseForbidden(
|
|
237
|
+
"You do not have permission to create subcategories."
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
category = get_object_or_404(Category, slug=category_slug)
|
|
241
|
+
|
|
242
|
+
if request.method == "POST":
|
|
243
|
+
form = SubcategoryModelForm(request.POST)
|
|
244
|
+
|
|
245
|
+
if form.is_valid():
|
|
246
|
+
subcategory = form.save(commit=False)
|
|
247
|
+
subcategory.category = category
|
|
248
|
+
subcategory.slug = get_unique_slug(Subcategory, subcategory.name)
|
|
249
|
+
subcategory.save()
|
|
250
|
+
|
|
251
|
+
return redirect(subcategory)
|
|
252
|
+
else:
|
|
253
|
+
form = SubcategoryModelForm()
|
|
254
|
+
|
|
255
|
+
context = {
|
|
256
|
+
"category": category,
|
|
257
|
+
"form": form,
|
|
258
|
+
}
|
|
259
|
+
return render(request, "punkweb_bb/subcategory_create.html", context=context)
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
@login_required(login_url="/login/")
|
|
263
|
+
def subcategory_update_view(request, subcategory_slug):
|
|
264
|
+
if not request.user.has_perm("punkweb_bb.change_subcategory"):
|
|
265
|
+
return HttpResponseForbidden(
|
|
266
|
+
"You do not have permission to change subcategories."
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
subcategory = get_object_or_404(Subcategory, slug=subcategory_slug)
|
|
270
|
+
|
|
271
|
+
if request.method == "POST":
|
|
272
|
+
form = SubcategoryModelForm(request.POST, instance=subcategory)
|
|
273
|
+
|
|
274
|
+
if form.is_valid():
|
|
275
|
+
subcategory = form.save()
|
|
276
|
+
|
|
277
|
+
return redirect(subcategory)
|
|
278
|
+
else:
|
|
279
|
+
form = SubcategoryModelForm(instance=subcategory)
|
|
280
|
+
|
|
281
|
+
context = {
|
|
282
|
+
"subcategory": subcategory,
|
|
283
|
+
"form": form,
|
|
284
|
+
}
|
|
285
|
+
return render(request, "punkweb_bb/subcategory_update.html", context=context)
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
@login_required(login_url="/login/")
|
|
289
|
+
def subcategory_delete_view(request, subcategory_slug):
|
|
290
|
+
if not request.user.has_perm("punkweb_bb.delete_subcategory"):
|
|
291
|
+
return HttpResponseForbidden(
|
|
292
|
+
"You do not have permission to delete subcategories."
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
subcategory = get_object_or_404(Subcategory, slug=subcategory_slug)
|
|
296
|
+
|
|
297
|
+
if request.method == "DELETE":
|
|
298
|
+
subcategory.delete()
|
|
299
|
+
|
|
300
|
+
return htmx_redirect(subcategory.category.get_absolute_url())
|
|
301
|
+
|
|
302
|
+
context = {
|
|
303
|
+
"subcategory": subcategory,
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
return render(
|
|
307
|
+
request, "punkweb_bb/partials/subcategory_delete.html", context=context
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
|
|
163
311
|
@login_required(login_url="/login/")
|
|
164
312
|
def thread_create_view(request, subcategory_slug):
|
|
165
313
|
subcategory = get_object_or_404(Subcategory, slug=subcategory_slug)
|
|
166
314
|
|
|
167
|
-
if subcategory.
|
|
168
|
-
return
|
|
315
|
+
if not subcategory.can_post(request.user):
|
|
316
|
+
return HttpResponseForbidden(
|
|
317
|
+
"You do not have permission to post in this subcategory."
|
|
318
|
+
)
|
|
169
319
|
|
|
170
320
|
if request.method == "POST":
|
|
171
321
|
form = ThreadModelForm(request.POST)
|
|
@@ -211,7 +361,12 @@ def thread_view(request, thread_id):
|
|
|
211
361
|
|
|
212
362
|
@login_required(login_url="/login/")
|
|
213
363
|
def thread_update_view(request, thread_id):
|
|
214
|
-
thread = get_object_or_404(Thread, pk=thread_id
|
|
364
|
+
thread = get_object_or_404(Thread, pk=thread_id)
|
|
365
|
+
|
|
366
|
+
if not thread.can_edit(request.user):
|
|
367
|
+
return HttpResponseForbidden(
|
|
368
|
+
"You do not have permission to change this thread."
|
|
369
|
+
)
|
|
215
370
|
|
|
216
371
|
if request.method == "POST":
|
|
217
372
|
form = ThreadModelForm(request.POST, instance=thread)
|
|
@@ -232,7 +387,12 @@ def thread_update_view(request, thread_id):
|
|
|
232
387
|
|
|
233
388
|
@login_required(login_url="/login/")
|
|
234
389
|
def thread_delete_view(request, thread_id):
|
|
235
|
-
thread = get_object_or_404(Thread, pk=thread_id
|
|
390
|
+
thread = get_object_or_404(Thread, pk=thread_id)
|
|
391
|
+
|
|
392
|
+
if not thread.can_delete(request.user):
|
|
393
|
+
return HttpResponseForbidden(
|
|
394
|
+
"You do not have permission to delete this thread."
|
|
395
|
+
)
|
|
236
396
|
|
|
237
397
|
if request.method == "DELETE":
|
|
238
398
|
thread.delete()
|
|
@@ -250,8 +410,10 @@ def thread_delete_view(request, thread_id):
|
|
|
250
410
|
def post_create_view(request, thread_id):
|
|
251
411
|
thread = get_object_or_404(Thread, pk=thread_id)
|
|
252
412
|
|
|
253
|
-
if thread.
|
|
254
|
-
return HttpResponseForbidden(
|
|
413
|
+
if not thread.can_post(request.user):
|
|
414
|
+
return HttpResponseForbidden(
|
|
415
|
+
"You do not have permission to post in this thread."
|
|
416
|
+
)
|
|
255
417
|
|
|
256
418
|
form = PostModelForm(request.POST)
|
|
257
419
|
|
|
@@ -266,7 +428,10 @@ def post_create_view(request, thread_id):
|
|
|
266
428
|
|
|
267
429
|
@login_required(login_url="/login/")
|
|
268
430
|
def post_update_view(request, post_id):
|
|
269
|
-
post = get_object_or_404(Post, pk=post_id
|
|
431
|
+
post = get_object_or_404(Post, pk=post_id)
|
|
432
|
+
|
|
433
|
+
if not post.can_edit(request.user):
|
|
434
|
+
return HttpResponseForbidden("You do not have permission to change this post.")
|
|
270
435
|
|
|
271
436
|
if request.method == "POST":
|
|
272
437
|
form = PostModelForm(request.POST, instance=post)
|
|
@@ -288,7 +453,10 @@ def post_update_view(request, post_id):
|
|
|
288
453
|
|
|
289
454
|
@login_required(login_url="/login/")
|
|
290
455
|
def post_delete_view(request, post_id):
|
|
291
|
-
post = get_object_or_404(Post, pk=post_id
|
|
456
|
+
post = get_object_or_404(Post, pk=post_id)
|
|
457
|
+
|
|
458
|
+
if not post.can_delete(request.user):
|
|
459
|
+
return HttpResponseForbidden("You do not have permission to delete this post.")
|
|
292
460
|
|
|
293
461
|
if request.method == "DELETE":
|
|
294
462
|
post.delete()
|
|
@@ -340,6 +508,25 @@ def shout_create_view(request):
|
|
|
340
508
|
)
|
|
341
509
|
|
|
342
510
|
|
|
511
|
+
@login_required(login_url="/login/")
|
|
512
|
+
def shout_delete_view(request, shout_id):
|
|
513
|
+
shout = get_object_or_404(Shout, pk=shout_id)
|
|
514
|
+
|
|
515
|
+
if not shout.can_delete(request.user):
|
|
516
|
+
return HttpResponseForbidden("You do not have permission to delete this shout.")
|
|
517
|
+
|
|
518
|
+
if request.method == "DELETE":
|
|
519
|
+
shout.delete()
|
|
520
|
+
|
|
521
|
+
return htmx_redirect(reverse("punkweb_bb:index"))
|
|
522
|
+
|
|
523
|
+
context = {
|
|
524
|
+
"shout": shout,
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
return render(request, "punkweb_bb/partials/shout_delete.html", context=context)
|
|
528
|
+
|
|
529
|
+
|
|
343
530
|
def bbcode_view(request):
|
|
344
531
|
codes = (
|
|
345
532
|
("Bold", "[b]Bold Text[/b]"),
|