punkweb-bb 0.2.3__py3-none-any.whl → 0.3.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__/admin.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/admin_forms.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/forms.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/models.cpython-311.pyc +0 -0
- punkweb_bb/__pycache__/settings.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/__pycache__/widgets.cpython-311.pyc +0 -0
- punkweb_bb/admin.py +0 -4
- punkweb_bb/admin_forms.py +6 -5
- punkweb_bb/forms.py +13 -5
- punkweb_bb/migrations/0005_alter_thread_options.py +24 -0
- punkweb_bb/migrations/0006_remove_boardprofile__signature_rendered_and_more.py +60 -0
- punkweb_bb/migrations/__pycache__/0005_alter_thread_options.cpython-311.pyc +0 -0
- punkweb_bb/migrations/__pycache__/0006_remove_boardprofile__signature_rendered_and_more.cpython-311.pyc +0 -0
- punkweb_bb/models.py +6 -6
- punkweb_bb/settings.py +1 -0
- punkweb_bb/static/punkweb_bb/css/thread.css +24 -0
- punkweb_bb/static/punkweb_bb/editor/markdown-editor.js +23 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/.eslintrc.json +15 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/.gitignore +108 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/.prettierrc.json +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/LICENSE +21 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/README.md +240 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/babel.config.json +14 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/dist/blank.html +18 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/dist/demo.html +126 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/dist/tiny-mde.css +231 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/dist/tiny-mde.js +3086 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/dist/tiny-mde.min.css +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/dist/tiny-mde.min.js +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/dist/tiny-mde.tiny.js +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/docs/_config.yml +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/docs/_layouts/default.html +50 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/docs/index.md +174 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/globals.d.ts +172 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/gulpfile.mjs +226 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/block.test.js +696 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/commandbar.test.js +84 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/inline.test.js +486 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/interaction.test.js +31 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/setup.test.js +164 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/util/config.js +2 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/util/server.js +9 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/util/setup.js +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/util/test-helpers.js +98 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest-puppeteer.config.js +8 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest.config.js +13 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/package-lock.json +16295 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/package.json +72 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/TinyMDE.js +1926 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/TinyMDECommandBar.js +256 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/css/commandbar.css +72 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/css/editor.css +157 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/css/index.css +3 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/grammar.js +300 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/html/blank.html +18 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/html/demo.html +126 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/index.js +4 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/blockquote.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/bold.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/clear_formatting.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/code.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/h1.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/h2.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/hr.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/image.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/italic.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/link.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/ol.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/strikethrough.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/svg.js +17 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/ul.svg +1 -0
- punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/tiny.js +3 -0
- punkweb_bb/templates/punkweb_bb/base_delete_modal.html +13 -0
- punkweb_bb/templates/punkweb_bb/index.html +2 -2
- punkweb_bb/templates/punkweb_bb/partials/category_delete.html +4 -8
- punkweb_bb/templates/punkweb_bb/partials/post_delete.html +4 -8
- punkweb_bb/templates/punkweb_bb/partials/shout_delete.html +4 -8
- punkweb_bb/templates/punkweb_bb/partials/subcategory_delete.html +4 -8
- punkweb_bb/templates/punkweb_bb/partials/thread_delete.html +4 -8
- punkweb_bb/templates/punkweb_bb/partials/thread_move.html +24 -0
- punkweb_bb/templates/punkweb_bb/profile.html +2 -2
- punkweb_bb/templates/punkweb_bb/shoutbox/shout_list.html +2 -2
- punkweb_bb/templates/punkweb_bb/subcategory.html +1 -1
- punkweb_bb/templates/punkweb_bb/thread.html +24 -14
- punkweb_bb/templates/punkweb_bb/widgets/markdown-editor.html +3 -0
- punkweb_bb/templatetags/__pycache__/markdown.cpython-311.pyc +0 -0
- punkweb_bb/templatetags/__pycache__/render.cpython-311.pyc +0 -0
- punkweb_bb/templatetags/__pycache__/shoutbox_bbcode.cpython-311.pyc +0 -0
- punkweb_bb/templatetags/__pycache__/shoutbox_render.cpython-311.pyc +0 -0
- punkweb_bb/templatetags/render.py +48 -0
- punkweb_bb/templatetags/shoutbox_render.py +22 -0
- punkweb_bb/tests.py +3 -3
- punkweb_bb/urls.py +1 -0
- punkweb_bb/utils.py +19 -3
- punkweb_bb/views.py +35 -4
- punkweb_bb/widgets.py +20 -0
- {punkweb_bb-0.2.3.dist-info → punkweb_bb-0.3.0.dist-info}/METADATA +56 -41
- {punkweb_bb-0.2.3.dist-info → punkweb_bb-0.3.0.dist-info}/RECORD +105 -38
- punkweb_bb/templatetags/shoutbox_bbcode.py +0 -14
- {punkweb_bb-0.2.3.dist-info → punkweb_bb-0.3.0.dist-info}/LICENSE +0 -0
- {punkweb_bb-0.2.3.dist-info → punkweb_bb-0.3.0.dist-info}/WHEEL +0 -0
- {punkweb_bb-0.2.3.dist-info → punkweb_bb-0.3.0.dist-info}/top_level.txt +0 -0
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
{% extends 'punkweb_bb/
|
|
1
|
+
{% extends 'punkweb_bb/base_delete_modal.html' %}
|
|
2
2
|
|
|
3
3
|
{% block title %}Delete Thread{% endblock %}
|
|
4
4
|
|
|
5
|
-
{% block
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
<button class="modal__cancel pw-button default">Cancel</button>
|
|
9
|
-
<button class="pw-button raised danger" hx-delete="{% url 'punkweb_bb:thread_delete' thread.id %}">Delete</button>
|
|
10
|
-
</div>
|
|
11
|
-
{% endblock %}
|
|
5
|
+
{% block object_type %}thread{% endblock %}
|
|
6
|
+
|
|
7
|
+
{% block delete_url %}{% url 'punkweb_bb:thread_delete' thread.id %}{% endblock %}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{% extends 'punkweb_bb/base_modal.html' %}
|
|
2
|
+
|
|
3
|
+
{% block title %}Move Thread{% endblock %}
|
|
4
|
+
|
|
5
|
+
{% block content %}
|
|
6
|
+
<form class="threadMoveForm" action="{% url 'punkweb_bb:thread_move' thread.id %}" method="post">
|
|
7
|
+
{% csrf_token %}
|
|
8
|
+
{% for field in form %}
|
|
9
|
+
<div class="threadMoveForm__field">
|
|
10
|
+
<label class="pw-input-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
|
|
11
|
+
{{ field }}
|
|
12
|
+
</div>
|
|
13
|
+
{% endfor %}
|
|
14
|
+
{% if form.non_field_errors %}
|
|
15
|
+
{{ form.non_field_errors }}
|
|
16
|
+
{% endif %}
|
|
17
|
+
<div class="threadMoveForm__actions">
|
|
18
|
+
<button class="modal__cancel pw-button default">Cancel</button>
|
|
19
|
+
<button class="pw-button raised primary" type="submit">Move</button>
|
|
20
|
+
</div>
|
|
21
|
+
</form>
|
|
22
|
+
{{form.media.css}}
|
|
23
|
+
{{form.media.js}}
|
|
24
|
+
{% endblock %}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{% extends 'punkweb_bb/base.html' %}
|
|
2
|
-
{% load static styled_username %}
|
|
2
|
+
{% load static render styled_username %}
|
|
3
3
|
|
|
4
4
|
{% block title_prefix %}{{ user.username }} | {% endblock%}
|
|
5
5
|
{% block og_title_prefix %}{{ user.username }} | {% endblock %}
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
<a href="{% url 'punkweb_bb:thread' thread.id %}">{{ thread.title }}</a>
|
|
77
77
|
</div>
|
|
78
78
|
<p class="profile__thread__preview">
|
|
79
|
-
{{ thread.content
|
|
79
|
+
{{ thread.content|render|striptags|truncatechars:120 }}
|
|
80
80
|
</p>
|
|
81
81
|
<div class="profile__thread__date">
|
|
82
82
|
<time datetime="{{thread.created_at|date:'c'}}">
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
{% load
|
|
1
|
+
{% load shoutbox_render styled_username can_delete %}
|
|
2
2
|
|
|
3
3
|
{% for shout in shouts %}
|
|
4
4
|
<div class="shoutbox__shout">
|
|
5
5
|
<div class="shoutbox__shout__content">
|
|
6
6
|
<time datetime="{{shout.created_at|date:'c'}}">{{shout.created_at | date:'g:i A'}}</time>
|
|
7
7
|
<span><a href="{% url 'punkweb_bb:profile' shout.user.id %}">{{shout.user|styled_username}}</a>: </span>
|
|
8
|
-
<span>{{ shout.content
|
|
8
|
+
<span>{{ shout.content|shoutbox_render }}</span>
|
|
9
9
|
</div>
|
|
10
10
|
{% if shout|can_delete:request.user %}
|
|
11
11
|
<div class="shoutbox__shout__actions">
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
{{thread.user|styled_username}}
|
|
102
102
|
</a>
|
|
103
103
|
•
|
|
104
|
-
<time datetime="{{thread.created_at|date:'c'}}">{{thread.created_at | date:'
|
|
104
|
+
<time datetime="{{thread.created_at|date:'c'}}">{{thread.created_at | date:'M j, Y'}}</time>
|
|
105
105
|
</td>
|
|
106
106
|
<td>{{thread.post_count}}</td>
|
|
107
107
|
<td>{{thread.view_count | humanize_int}}</td>
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{% extends 'punkweb_bb/base.html' %}
|
|
2
|
-
{% load static can_delete can_edit can_post
|
|
2
|
+
{% load static render styled_username can_delete can_edit can_post %}
|
|
3
3
|
|
|
4
4
|
{% block title_prefix %}{{thread.title}} | {% endblock %}
|
|
5
5
|
{% block og_title_prefix %}{{thread.title}} | {% endblock %}
|
|
6
6
|
|
|
7
7
|
{% block extra_head %}
|
|
8
|
-
<meta name="description" content="{{thread.content
|
|
9
|
-
<meta property="og:description" content="{{thread.content
|
|
8
|
+
<meta name="description" content="{{thread.content|render|striptags|truncatechars:120}}" />
|
|
9
|
+
<meta property="og:description" content="{{thread.content|render|striptags|truncatechars:120}}" />
|
|
10
10
|
<link rel="stylesheet" href="{% static 'punkweb_bb/css/post-form.css' %}" />
|
|
11
11
|
<link rel="stylesheet" href="{% static 'punkweb_bb/css/thread.css' %}" />
|
|
12
12
|
<link rel="stylesheet" href="{% static 'punkweb_bb/css/thread-form.css' %}" />
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
<div class="pw-card fluid margin">
|
|
43
43
|
<div class="pw-card-header">
|
|
44
44
|
<div class="thread__date">
|
|
45
|
-
<time datetime="{{thread.created_at|date:'c'}}">{{thread.created_at | date:'M
|
|
45
|
+
<time datetime="{{thread.created_at|date:'c'}}">{{thread.created_at | date:'M j, Y'}}</time>
|
|
46
46
|
</div>
|
|
47
47
|
</div>
|
|
48
48
|
<div class="thread">
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
<div class="thread__user__details__row">
|
|
76
76
|
<div class="thread__user__details__label">Joined:</div>
|
|
77
77
|
<div class="thread__user__details__value">
|
|
78
|
-
<time datetime="{{thread.user.date_joined|date:'c'}}">{{thread.user.date_joined | date:'M
|
|
78
|
+
<time datetime="{{thread.user.date_joined|date:'c'}}">{{thread.user.date_joined | date:'M j, Y'}}</time>
|
|
79
79
|
</div>
|
|
80
80
|
</div>
|
|
81
81
|
<div class="thread__user__details__row">
|
|
@@ -86,10 +86,20 @@
|
|
|
86
86
|
</div>
|
|
87
87
|
<div class="thread__main">
|
|
88
88
|
<div class="thread__content">
|
|
89
|
-
{{thread.content
|
|
89
|
+
{{thread.content|render}}
|
|
90
90
|
</div>
|
|
91
|
-
{% if thread|can_delete:request.user or thread|can_edit:request.user or perms.punkweb_bb.pin_thread or perms.punkweb_bb.close_thread %}
|
|
91
|
+
{% if thread|can_delete:request.user or thread|can_edit:request.user or perms.punkweb_bb.pin_thread or perms.punkweb_bb.close_thread or perms.punkweb_bb.move_thread %}
|
|
92
92
|
<div class="thread__actions">
|
|
93
|
+
{% if perms.punkweb_bb.move_thread %}
|
|
94
|
+
<a
|
|
95
|
+
class="pw-icon-button default rounded"
|
|
96
|
+
title="Move"
|
|
97
|
+
hx-get="{% url 'punkweb_bb:thread_move' thread.id %}"
|
|
98
|
+
hx-target="#modal-portal"
|
|
99
|
+
>
|
|
100
|
+
<span class="material-symbols-outlined">move_item</span>
|
|
101
|
+
</a>
|
|
102
|
+
{% endif %}
|
|
93
103
|
{% if perms.punkweb_bb.pin_thread %}
|
|
94
104
|
<a
|
|
95
105
|
class="pw-icon-button default rounded"
|
|
@@ -139,9 +149,9 @@
|
|
|
139
149
|
{% endif %}
|
|
140
150
|
</div>
|
|
141
151
|
{% endif %}
|
|
142
|
-
{% if thread.user.profile.signature
|
|
152
|
+
{% if thread.user.profile.signature|render %}
|
|
143
153
|
<div class="thread__signature">
|
|
144
|
-
{{thread.user.profile.signature
|
|
154
|
+
{{thread.user.profile.signature|render}}
|
|
145
155
|
</div>
|
|
146
156
|
{% endif %}
|
|
147
157
|
</div>
|
|
@@ -153,7 +163,7 @@
|
|
|
153
163
|
<div id="post-{{post.id}}" class="pw-card fluid margin">
|
|
154
164
|
<div class="pw-card-header thread__header">
|
|
155
165
|
<div class="thread__date">
|
|
156
|
-
<time datetime="{{post.created_at|date:'c'}}">{{post.created_at | date:'M
|
|
166
|
+
<time datetime="{{post.created_at|date:'c'}}">{{post.created_at | date:'M j, Y'}}</time>
|
|
157
167
|
</div>
|
|
158
168
|
<a class="thread__index" href="{{post.get_absolute_url}}">#{{post.index}}</a>
|
|
159
169
|
</div>
|
|
@@ -191,7 +201,7 @@
|
|
|
191
201
|
<div class="thread__user__details__row">
|
|
192
202
|
<div class="thread__user__details__label">Joined:</div>
|
|
193
203
|
<div class="thread__user__details__value">
|
|
194
|
-
<time datetime="{{post.user.date_joined|date:'c'}}">{{post.user.date_joined | date:'M
|
|
204
|
+
<time datetime="{{post.user.date_joined|date:'c'}}">{{post.user.date_joined | date:'M j, Y'}}</time>
|
|
195
205
|
</div>
|
|
196
206
|
</div>
|
|
197
207
|
<div class="thread__user__details__row">
|
|
@@ -202,7 +212,7 @@
|
|
|
202
212
|
</div>
|
|
203
213
|
<div class="thread__main">
|
|
204
214
|
<div class="thread__content">
|
|
205
|
-
{{post.content
|
|
215
|
+
{{post.content|render}}
|
|
206
216
|
</div>
|
|
207
217
|
{% if post|can_delete:request.user or post|can_edit:request.user %}
|
|
208
218
|
<div class="thread__actions">
|
|
@@ -228,9 +238,9 @@
|
|
|
228
238
|
{% endif %}
|
|
229
239
|
</div>
|
|
230
240
|
{% endif %}
|
|
231
|
-
{% if post.user.profile.signature
|
|
241
|
+
{% if post.user.profile.signature|render %}
|
|
232
242
|
<div class="thread__signature">
|
|
233
|
-
{{post.user.profile.signature
|
|
243
|
+
{{post.user.profile.signature|render}}
|
|
234
244
|
</div>
|
|
235
245
|
{% endif %}
|
|
236
246
|
</div>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import html
|
|
2
|
+
from io import StringIO
|
|
3
|
+
|
|
4
|
+
import markdown as md
|
|
5
|
+
from django import template
|
|
6
|
+
from django.template.defaultfilters import stringfilter
|
|
7
|
+
from django.utils.safestring import mark_safe
|
|
8
|
+
from precise_bbcode.bbcode import get_parser
|
|
9
|
+
|
|
10
|
+
from punkweb_bb.settings import RENDERER
|
|
11
|
+
|
|
12
|
+
register = template.Library()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def unmark_element(element, stream=None):
|
|
16
|
+
if stream is None:
|
|
17
|
+
stream = StringIO()
|
|
18
|
+
if element.text:
|
|
19
|
+
stream.write(element.text)
|
|
20
|
+
for sub in element:
|
|
21
|
+
unmark_element(sub, stream)
|
|
22
|
+
if element.tail:
|
|
23
|
+
stream.write(element.tail)
|
|
24
|
+
return stream.getvalue()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
md.Markdown.output_formats["plain"] = unmark_element
|
|
28
|
+
unmark = md.Markdown(output_format="plain")
|
|
29
|
+
unmark.stripTopLevelTags = False
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@register.filter(is_safe=True)
|
|
33
|
+
@stringfilter
|
|
34
|
+
def render(value):
|
|
35
|
+
if RENDERER == "bbcode":
|
|
36
|
+
parser = get_parser()
|
|
37
|
+
rendered = parser.render(value)
|
|
38
|
+
elif RENDERER == "markdown":
|
|
39
|
+
escaped = html.escape(value, quote=False)
|
|
40
|
+
rendered = md.markdown(escaped, extensions=["markdown.extensions.fenced_code"])
|
|
41
|
+
|
|
42
|
+
return mark_safe(rendered)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@register.filter()
|
|
46
|
+
@stringfilter
|
|
47
|
+
def unmarkdown(value):
|
|
48
|
+
return unmark.convert(value)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import html
|
|
2
|
+
from django import template
|
|
3
|
+
from django.template.defaultfilters import stringfilter
|
|
4
|
+
from django.utils.safestring import mark_safe
|
|
5
|
+
|
|
6
|
+
from punkweb_bb.parsers import get_shoutbox_parser
|
|
7
|
+
from punkweb_bb.settings import RENDERER
|
|
8
|
+
|
|
9
|
+
register = template.Library()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@register.filter(is_safe=True)
|
|
13
|
+
@stringfilter
|
|
14
|
+
def shoutbox_render(value):
|
|
15
|
+
if RENDERER == "bbcode":
|
|
16
|
+
parser = get_shoutbox_parser()
|
|
17
|
+
rendered = parser.render(value)
|
|
18
|
+
elif RENDERER == "markdown":
|
|
19
|
+
escaped = html.escape(value, quote=False)
|
|
20
|
+
rendered = escaped
|
|
21
|
+
|
|
22
|
+
return mark_safe(rendered)
|
punkweb_bb/tests.py
CHANGED
|
@@ -422,7 +422,7 @@ class SettingsViewTestCase(TestCase):
|
|
|
422
422
|
)
|
|
423
423
|
|
|
424
424
|
self.user.profile.refresh_from_db()
|
|
425
|
-
self.assertEqual(self.user.profile.
|
|
425
|
+
self.assertEqual(self.user.profile.signature, "[b]test[/b]")
|
|
426
426
|
|
|
427
427
|
self.assertEqual(response.status_code, 200)
|
|
428
428
|
|
|
@@ -546,7 +546,7 @@ class ThreadUpdateViewTestCase(TestCase):
|
|
|
546
546
|
self.assertRedirects(response, self.thread.get_absolute_url())
|
|
547
547
|
self.thread.refresh_from_db()
|
|
548
548
|
self.assertEqual(self.thread.title, "edit")
|
|
549
|
-
self.assertEqual(self.thread.
|
|
549
|
+
self.assertEqual(self.thread.content, "edit")
|
|
550
550
|
|
|
551
551
|
|
|
552
552
|
class ThreadDeleteViewTestCase(TestCase):
|
|
@@ -675,7 +675,7 @@ class PostUpdateViewTestCase(TestCase):
|
|
|
675
675
|
|
|
676
676
|
self.assertRedirects(response, self.post.get_absolute_url())
|
|
677
677
|
self.post.refresh_from_db()
|
|
678
|
-
self.assertEqual(self.post.
|
|
678
|
+
self.assertEqual(self.post.content, "edit")
|
|
679
679
|
|
|
680
680
|
|
|
681
681
|
class PostDeleteViewTestCase(TestCase):
|
punkweb_bb/urls.py
CHANGED
|
@@ -61,6 +61,7 @@ urlpatterns = [
|
|
|
61
61
|
),
|
|
62
62
|
path("thread/<str:thread_id>/pin/", views.thread_pin_view, name="thread_pin"),
|
|
63
63
|
path("thread/<str:thread_id>/close/", views.thread_close_view, name="thread_close"),
|
|
64
|
+
path("thread/<str:thread_id>/move/", views.thread_move_view, name="thread_move"),
|
|
64
65
|
path("post/<str:post_id>/delete/", views.post_delete_view, name="post_delete"),
|
|
65
66
|
path("post/<str:post_id>/update/", views.post_update_view, name="post_update"),
|
|
66
67
|
path("shout-list/", views.shout_list_view, name="shout_list"),
|
punkweb_bb/utils.py
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
|
-
from django.contrib.auth.models import Group
|
|
2
1
|
from django.utils.text import slugify
|
|
2
|
+
from precise_bbcode.bbcode import get_parser
|
|
3
|
+
from punkweb_bb.settings import RENDERER
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def get_editor_widget():
|
|
7
|
+
if RENDERER == "bbcode":
|
|
8
|
+
from punkweb_bb.widgets import BBCodeEditorWidget
|
|
9
|
+
|
|
10
|
+
return BBCodeEditorWidget()
|
|
11
|
+
elif RENDERER == "markdown":
|
|
12
|
+
from punkweb_bb.widgets import MarkdownEditorWidget
|
|
13
|
+
|
|
14
|
+
return MarkdownEditorWidget()
|
|
15
|
+
else:
|
|
16
|
+
raise ValueError("Invalid renderer")
|
|
3
17
|
|
|
4
18
|
|
|
5
19
|
def get_unique_slug(model, field):
|
|
@@ -31,8 +45,9 @@ def get_styled_username(user):
|
|
|
31
45
|
group = get_highest_priority_group(user)
|
|
32
46
|
|
|
33
47
|
if group:
|
|
48
|
+
parser = get_parser()
|
|
34
49
|
username_style = group.style.username_style
|
|
35
|
-
styled_username = username_style.
|
|
50
|
+
styled_username = parser.render(username_style.replace("{USER}", user.username))
|
|
36
51
|
return styled_username
|
|
37
52
|
else:
|
|
38
53
|
return user.username
|
|
@@ -42,6 +57,7 @@ def get_styled_group_name(group):
|
|
|
42
57
|
if group.style is None:
|
|
43
58
|
return group.name
|
|
44
59
|
else:
|
|
60
|
+
parser = get_parser()
|
|
45
61
|
username_style = group.style.username_style
|
|
46
|
-
styled_group_name = username_style.
|
|
62
|
+
styled_group_name = parser.render(username_style.replace("{USER}", group.name))
|
|
47
63
|
return styled_group_name
|
punkweb_bb/views.py
CHANGED
|
@@ -14,6 +14,7 @@ from punkweb_bb.forms import (
|
|
|
14
14
|
SignUpForm,
|
|
15
15
|
SubcategoryModelForm,
|
|
16
16
|
ThreadModelForm,
|
|
17
|
+
ThreadMoveForm,
|
|
17
18
|
)
|
|
18
19
|
from punkweb_bb.guests import guest_list
|
|
19
20
|
from punkweb_bb.models import Category, Post, Shout, Subcategory, Thread
|
|
@@ -406,11 +407,11 @@ def thread_delete_view(request, thread_id):
|
|
|
406
407
|
|
|
407
408
|
@login_required(login_url="/login/")
|
|
408
409
|
def thread_pin_view(request, thread_id):
|
|
409
|
-
thread = get_object_or_404(Thread, pk=thread_id)
|
|
410
|
-
|
|
411
410
|
if not request.user.has_perm("punkweb_bb.pin_thread"):
|
|
412
411
|
return HttpResponseForbidden("You do not have permission to pin threads.")
|
|
413
412
|
|
|
413
|
+
thread = get_object_or_404(Thread, pk=thread_id)
|
|
414
|
+
|
|
414
415
|
thread.is_pinned = not thread.is_pinned
|
|
415
416
|
thread.save()
|
|
416
417
|
|
|
@@ -419,17 +420,47 @@ def thread_pin_view(request, thread_id):
|
|
|
419
420
|
|
|
420
421
|
@login_required(login_url="/login/")
|
|
421
422
|
def thread_close_view(request, thread_id):
|
|
422
|
-
thread = get_object_or_404(Thread, pk=thread_id)
|
|
423
|
-
|
|
424
423
|
if not request.user.has_perm("punkweb_bb.close_thread"):
|
|
425
424
|
return HttpResponseForbidden("You do not have permission to close threads.")
|
|
426
425
|
|
|
426
|
+
thread = get_object_or_404(Thread, pk=thread_id)
|
|
427
|
+
|
|
427
428
|
thread.is_closed = not thread.is_closed
|
|
428
429
|
thread.save()
|
|
429
430
|
|
|
430
431
|
return htmx_redirect(thread.get_absolute_url())
|
|
431
432
|
|
|
432
433
|
|
|
434
|
+
@login_required(login_url="/login/")
|
|
435
|
+
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
|
+
thread = get_object_or_404(Thread, pk=thread_id)
|
|
440
|
+
|
|
441
|
+
if request.method == "POST":
|
|
442
|
+
form = ThreadMoveForm(request.POST)
|
|
443
|
+
|
|
444
|
+
if form.is_valid():
|
|
445
|
+
thread.subcategory = form.cleaned_data["subcategory"]
|
|
446
|
+
thread.save()
|
|
447
|
+
|
|
448
|
+
return redirect(thread)
|
|
449
|
+
|
|
450
|
+
initial_data = {
|
|
451
|
+
"subcategory": thread.subcategory,
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
form = ThreadMoveForm(data=initial_data)
|
|
455
|
+
|
|
456
|
+
context = {
|
|
457
|
+
"thread": thread,
|
|
458
|
+
"form": form,
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
return render(request, "punkweb_bb/partials/thread_move.html", context=context)
|
|
462
|
+
|
|
463
|
+
|
|
433
464
|
@login_required(login_url="/login/")
|
|
434
465
|
def post_create_view(request, thread_id):
|
|
435
466
|
thread = get_object_or_404(Thread, pk=thread_id)
|
punkweb_bb/widgets.py
CHANGED
|
@@ -20,3 +20,23 @@ class BBCodeEditorWidget(forms.Textarea):
|
|
|
20
20
|
"/static/punkweb_bb/editor/bbcode-editor-tags.js",
|
|
21
21
|
"/static/punkweb_bb/editor/bbcode-editor.js",
|
|
22
22
|
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class MarkdownEditorWidget(forms.Textarea):
|
|
26
|
+
template_name = "punkweb_bb/widgets/markdown-editor.html"
|
|
27
|
+
|
|
28
|
+
def __init__(self, *args, **kwargs):
|
|
29
|
+
super(MarkdownEditorWidget, self).__init__(*args, **kwargs)
|
|
30
|
+
self.attrs["class"] = "markdown-editor"
|
|
31
|
+
|
|
32
|
+
class Media:
|
|
33
|
+
css = {
|
|
34
|
+
"all": (
|
|
35
|
+
"/static/punkweb_bb/vendor/tiny-markdown-editor/dist/tiny-mde.min.css",
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
js = (
|
|
39
|
+
"/static/punkweb_bb/vendor/jquery-3.7.0.min.js",
|
|
40
|
+
"/static/punkweb_bb/vendor/tiny-markdown-editor/dist/tiny-mde.min.js",
|
|
41
|
+
"/static/punkweb_bb/editor/markdown-editor.js",
|
|
42
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: punkweb-bb
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.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
|
|
@@ -17,6 +17,7 @@ Description-Content-Type: text/markdown
|
|
|
17
17
|
License-File: LICENSE
|
|
18
18
|
Requires-Dist: django >=4.0
|
|
19
19
|
Requires-Dist: django-precise-bbcode
|
|
20
|
+
Requires-Dist: markdown
|
|
20
21
|
Requires-Dist: expiringdict
|
|
21
22
|
Requires-Dist: pillow
|
|
22
23
|
|
|
@@ -32,20 +33,35 @@ Check out [punkweb.net](https://punkweb.net/board/) for documentation, support a
|
|
|
32
33
|
|
|
33
34
|
- [Django](https://www.djangoproject.com/)
|
|
34
35
|
- [django-precise-bbcode](https://github.com/ellmetha/django-precise-bbcode)
|
|
36
|
+
- [Markdown](https://python-markdown.github.io/)
|
|
35
37
|
- [HTMX](https://htmx.org/)
|
|
36
38
|
- [jQuery](https://jquery.com/)
|
|
37
39
|
- [SCEditor](https://www.sceditor.com/)
|
|
40
|
+
- [TinyMDE](https://github.com/jefago/tiny-markdown-editor)
|
|
38
41
|
- [PrismJS](https://prismjs.com/)
|
|
39
42
|
|
|
40
43
|
## Requirements
|
|
41
44
|
|
|
42
45
|
- Python 3.9+
|
|
43
|
-
- Django 4.
|
|
46
|
+
- Django 4.0+
|
|
44
47
|
- django-precise-bbcode 1.2+
|
|
48
|
+
- markdown 3.6+
|
|
45
49
|
- Pillow
|
|
46
50
|
|
|
47
51
|
It may work with older versions of Python and Django, but it has not been tested.
|
|
48
52
|
|
|
53
|
+
## BBCode or Markdown?
|
|
54
|
+
|
|
55
|
+
PunkwebBB supports both BBCode and Markdown. You'll want to decide before installing which renderer 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.
|
|
56
|
+
|
|
57
|
+
BBCode is the default renderer, but you can switch to Markdown by setting the following in your Django settings module:
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
PUNKWEB_BB = {
|
|
61
|
+
"RENDERER": "markdown",
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
49
65
|
## Installation
|
|
50
66
|
|
|
51
67
|
```bash
|
|
@@ -62,16 +78,7 @@ INSTALLED_APPS = [
|
|
|
62
78
|
]
|
|
63
79
|
```
|
|
64
80
|
|
|
65
|
-
_Note_: `precise_bbcode` is required
|
|
66
|
-
|
|
67
|
-
Add the following middleware to your `MIDDLEWARE` setting:
|
|
68
|
-
|
|
69
|
-
```python
|
|
70
|
-
MIDDLEWARE = [
|
|
71
|
-
...
|
|
72
|
-
"punkweb_bb.middleware.ProfileOnlineCacheMiddleware",
|
|
73
|
-
]
|
|
74
|
-
```
|
|
81
|
+
_Note_: `precise_bbcode` is required even if using the Markdown renderer! It must be installed before `punkweb_bb`.
|
|
75
82
|
|
|
76
83
|
Add the following context processor to your `TEMPLATES` setting:
|
|
77
84
|
|
|
@@ -114,6 +121,7 @@ These are the default settings for PunkwebBB, which can be overridden in your Dj
|
|
|
114
121
|
PUNKWEB_BB = {
|
|
115
122
|
"SITE_NAME": "PUNKWEB",
|
|
116
123
|
"SITE_TITLE": "PunkwebBB",
|
|
124
|
+
"RENDERER": "bbcode", # "bbcode" or "markdown"
|
|
117
125
|
"FAVICON": "punkweb_bb/favicon.ico",
|
|
118
126
|
"OG_IMAGE": None, # Used for Open Graph meta tags, must be a full URL!
|
|
119
127
|
"SHOUTBOX_ENABLED": True,
|
|
@@ -138,39 +146,46 @@ coverage run && coverage html
|
|
|
138
146
|
```
|
|
139
147
|
|
|
140
148
|
```bash
|
|
141
|
-
Found
|
|
149
|
+
Found 59 test(s).
|
|
142
150
|
Creating test database for alias 'default'...
|
|
143
151
|
System check identified no issues (0 silenced).
|
|
144
|
-
|
|
152
|
+
...........................................................
|
|
145
153
|
----------------------------------------------------------------------
|
|
146
|
-
Ran
|
|
154
|
+
Ran 59 tests in 9.166s
|
|
147
155
|
|
|
148
156
|
OK
|
|
149
157
|
Destroying test database for alias 'default'...
|
|
150
|
-
Name
|
|
151
|
-
|
|
152
|
-
punkweb_bb/__init__.py
|
|
153
|
-
punkweb_bb/admin.py
|
|
154
|
-
punkweb_bb/admin_forms.py
|
|
155
|
-
punkweb_bb/apps.py
|
|
156
|
-
punkweb_bb/
|
|
157
|
-
punkweb_bb/
|
|
158
|
-
punkweb_bb/
|
|
159
|
-
punkweb_bb/middleware.py
|
|
160
|
-
punkweb_bb/mixins.py
|
|
161
|
-
punkweb_bb/models.py
|
|
162
|
-
punkweb_bb/pagination.py
|
|
163
|
-
punkweb_bb/parsers.py
|
|
164
|
-
punkweb_bb/response.py
|
|
165
|
-
punkweb_bb/settings.py
|
|
166
|
-
punkweb_bb/signals.py
|
|
167
|
-
punkweb_bb/templatetags/__init__.py
|
|
168
|
-
punkweb_bb/templatetags/
|
|
169
|
-
punkweb_bb/templatetags/
|
|
170
|
-
punkweb_bb/
|
|
171
|
-
punkweb_bb/
|
|
172
|
-
punkweb_bb/
|
|
173
|
-
punkweb_bb/
|
|
174
|
-
|
|
175
|
-
|
|
158
|
+
Name Stmts Miss Cover
|
|
159
|
+
------------------------------------------------------------------
|
|
160
|
+
punkweb_bb/__init__.py 0 0 100%
|
|
161
|
+
punkweb_bb/admin.py 43 0 100%
|
|
162
|
+
punkweb_bb/admin_forms.py 34 0 100%
|
|
163
|
+
punkweb_bb/apps.py 6 0 100%
|
|
164
|
+
punkweb_bb/context_processors.py 3 0 100%
|
|
165
|
+
punkweb_bb/forms.py 47 0 100%
|
|
166
|
+
punkweb_bb/guests.py 13 0 100%
|
|
167
|
+
punkweb_bb/middleware.py 14 0 100%
|
|
168
|
+
punkweb_bb/mixins.py 11 0 100%
|
|
169
|
+
punkweb_bb/models.py 153 1 99%
|
|
170
|
+
punkweb_bb/pagination.py 11 4 64%
|
|
171
|
+
punkweb_bb/parsers.py 50 36 28%
|
|
172
|
+
punkweb_bb/response.py 3 0 100%
|
|
173
|
+
punkweb_bb/settings.py 11 0 100%
|
|
174
|
+
punkweb_bb/signals.py 9 0 100%
|
|
175
|
+
punkweb_bb/templatetags/__init__.py 0 0 100%
|
|
176
|
+
punkweb_bb/templatetags/can_delete.py 5 0 100%
|
|
177
|
+
punkweb_bb/templatetags/can_edit.py 5 0 100%
|
|
178
|
+
punkweb_bb/templatetags/can_post.py 5 0 100%
|
|
179
|
+
punkweb_bb/templatetags/humanize_int.py 9 5 44%
|
|
180
|
+
punkweb_bb/templatetags/render.py 36 12 67%
|
|
181
|
+
punkweb_bb/templatetags/shoutbox_render.py 18 2 89%
|
|
182
|
+
punkweb_bb/templatetags/styled_group_name.py 7 1 86%
|
|
183
|
+
punkweb_bb/templatetags/styled_username.py 6 0 100%
|
|
184
|
+
punkweb_bb/tests.py 418 0 100%
|
|
185
|
+
punkweb_bb/urls.py 4 0 100%
|
|
186
|
+
punkweb_bb/utils.py 42 24 43%
|
|
187
|
+
punkweb_bb/views.py 304 118 61%
|
|
188
|
+
punkweb_bb/widgets.py 16 0 100%
|
|
189
|
+
------------------------------------------------------------------
|
|
190
|
+
TOTAL 1283 203 84%
|
|
176
191
|
```
|