punkweb-bb 0.1.1__py3-none-any.whl → 0.1.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. punkweb_bb/__pycache__/apps.cpython-311.pyc +0 -0
  2. punkweb_bb/__pycache__/bbcode_tags.cpython-311.pyc +0 -0
  3. punkweb_bb/__pycache__/models.cpython-311.pyc +0 -0
  4. punkweb_bb/__pycache__/parsers.cpython-311.pyc +0 -0
  5. punkweb_bb/__pycache__/settings.cpython-311.pyc +0 -0
  6. punkweb_bb/__pycache__/tests.cpython-311.pyc +0 -0
  7. punkweb_bb/__pycache__/views.cpython-311.pyc +0 -0
  8. punkweb_bb/migrations/0002_thread_view_count.py +18 -0
  9. punkweb_bb/migrations/__pycache__/0001_initial.cpython-311.pyc +0 -0
  10. punkweb_bb/migrations/__pycache__/0002_thread_view_count.cpython-311.pyc +0 -0
  11. punkweb_bb/models.py +4 -0
  12. punkweb_bb/parsers.py +52 -48
  13. punkweb_bb/settings.py +1 -0
  14. punkweb_bb/static/punkweb_bb/css/profile.css +7 -0
  15. punkweb_bb/templates/punkweb_bb/base.html +1 -1
  16. punkweb_bb/templates/punkweb_bb/index.html +2 -0
  17. punkweb_bb/templates/punkweb_bb/subcategory.html +7 -1
  18. punkweb_bb/templates/punkweb_bb/thread.html +5 -2
  19. punkweb_bb/templates/punkweb_bb/thread_create.html +3 -0
  20. punkweb_bb/templates/punkweb_bb/thread_update.html +3 -0
  21. punkweb_bb/templatetags/__pycache__/__init__.cpython-311.pyc +0 -0
  22. punkweb_bb/templatetags/__pycache__/humanize_count.cpython-311.pyc +0 -0
  23. punkweb_bb/templatetags/__pycache__/humanize_int.cpython-311.pyc +0 -0
  24. punkweb_bb/templatetags/__pycache__/shoutbox_bbcode.cpython-311.pyc +0 -0
  25. punkweb_bb/templatetags/humanize_int.py +12 -0
  26. punkweb_bb/templatetags/shoutbox_bbcode.py +2 -2
  27. punkweb_bb/tests.py +518 -2
  28. punkweb_bb/views.py +12 -3
  29. punkweb_bb-0.1.3.dist-info/METADATA +171 -0
  30. {punkweb_bb-0.1.1.dist-info → punkweb_bb-0.1.3.dist-info}/RECORD +33 -45
  31. punkweb_bb/__pycache__/conf.cpython-311.pyc +0 -0
  32. punkweb_bb/__pycache__/fields.cpython-311.pyc +0 -0
  33. punkweb_bb/__pycache__/utils.cpython-311.pyc +0 -0
  34. punkweb_bb/migrations/__pycache__/0002_category_alter_boardprofile_options_subcategory.cpython-311.pyc +0 -0
  35. punkweb_bb/migrations/__pycache__/0002_create_board_profiles.cpython-311.pyc +0 -0
  36. punkweb_bb/migrations/__pycache__/0002_remove_shout__content_rendered_alter_shout_content.cpython-311.pyc +0 -0
  37. punkweb_bb/migrations/__pycache__/0003_thread_post.cpython-311.pyc +0 -0
  38. punkweb_bb/migrations/__pycache__/0004_category_slug_subcategory_slug.cpython-311.pyc +0 -0
  39. punkweb_bb/migrations/__pycache__/0005_alter_category_slug_alter_subcategory_slug.cpython-311.pyc +0 -0
  40. punkweb_bb/migrations/__pycache__/0006_boardprofile_image.cpython-311.pyc +0 -0
  41. punkweb_bb/migrations/__pycache__/0007_alter_boardprofile_image.cpython-311.pyc +0 -0
  42. punkweb_bb/migrations/__pycache__/0008_shout.cpython-311.pyc +0 -0
  43. punkweb_bb/migrations/__pycache__/0009_remove_category__description_rendered_and_more.cpython-311.pyc +0 -0
  44. punkweb_bb/migrations/__pycache__/0010_alter_boardprofile_options_alter_category_options_and_more.cpython-311.pyc +0 -0
  45. punkweb_bb/migrations/__pycache__/0011_alter_thread_options_thread_last_post_created_at.cpython-311.pyc +0 -0
  46. punkweb_bb/migrations/__pycache__/0011_thread_is_closed.cpython-311.pyc +0 -0
  47. punkweb_bb/migrations/__pycache__/0012_subcategory_staff_post_only.cpython-311.pyc +0 -0
  48. punkweb_bb-0.1.1.dist-info/METADATA +0 -72
  49. {punkweb_bb-0.1.1.dist-info → punkweb_bb-0.1.3.dist-info}/LICENSE +0 -0
  50. {punkweb_bb-0.1.1.dist-info → punkweb_bb-0.1.3.dist-info}/WHEEL +0 -0
  51. {punkweb_bb-0.1.1.dist-info → punkweb_bb-0.1.3.dist-info}/top_level.txt +0 -0
Binary file
@@ -0,0 +1,18 @@
1
+ # Generated by Django 4.2.11 on 2024-05-07 04:24
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ("punkweb_bb", "0001_initial"),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AddField(
14
+ model_name="thread",
15
+ name="view_count",
16
+ field=models.PositiveIntegerField(default=0),
17
+ ),
18
+ ]
punkweb_bb/models.py CHANGED
@@ -5,6 +5,7 @@ import os
5
5
  from django.contrib.auth import get_user_model
6
6
  from django.core.cache import cache
7
7
  from django.db import models
8
+ from django.forms import ValidationError
8
9
  from django.urls import reverse
9
10
  from django.utils import timezone
10
11
  from precise_bbcode.fields import BBCodeTextField
@@ -107,6 +108,7 @@ class Thread(UUIDPrimaryKeyMixin, TimestampMixin):
107
108
  is_pinned = models.BooleanField(default=False)
108
109
  is_closed = models.BooleanField(default=False)
109
110
  last_post_created_at = models.DateTimeField(auto_now_add=True)
111
+ view_count = models.PositiveIntegerField(default=0)
110
112
 
111
113
  class Meta:
112
114
  ordering = (
@@ -161,6 +163,8 @@ class Post(UUIDPrimaryKeyMixin, TimestampMixin):
161
163
  return thread_url
162
164
 
163
165
  def save(self, *args, **kwargs):
166
+ if self.thread.is_closed:
167
+ raise ValidationError("Cannot add posts to a closed thread.")
164
168
  if self._state.adding:
165
169
  self.thread.last_post_created_at = timezone.now()
166
170
  self.thread.save()
punkweb_bb/parsers.py CHANGED
@@ -1,66 +1,70 @@
1
1
  from django.apps import apps
2
- from precise_bbcode.bbcode.defaults.tag import (
3
- ColorBBCodeTag,
4
- ItalicBBCodeTag,
5
- StrikeBBCodeTag,
6
- StrongBBCodeTag,
7
- UnderlineBBCodeTag,
8
- UrlBBCodeTag,
9
- )
10
2
  from precise_bbcode.bbcode.parser import BBCodeParser
11
3
  from precise_bbcode.bbcode.placeholder import BBCodePlaceholder
12
4
  from precise_bbcode.core.loading import get_subclasses
13
5
 
14
- from punkweb_bb.bbcode_tags import (
15
- FontBBCodeTag,
16
- ShadowBBCodeTag,
17
- SubscriptBBCodeTag,
18
- SuperscriptBBCodeTag,
19
- )
6
+ _shoutbox_parser = None
20
7
 
21
- shoutbox_parser = BBCodeParser()
22
8
 
9
+ def get_shoutbox_parser():
10
+ if not _shoutbox_parser:
11
+ loader = ShoutboxParserLoader()
12
+ loader.load_parser()
13
+ return _shoutbox_parser
23
14
 
24
- def init_default_bbcode_placeholders():
25
- import precise_bbcode.bbcode.defaults.placeholder
26
15
 
27
- for placeholder_klass in get_subclasses(
28
- precise_bbcode.bbcode.defaults.placeholder, BBCodePlaceholder
29
- ):
30
- setattr(placeholder_klass, "default_placeholder", True)
31
- shoutbox_parser.add_placeholder(placeholder_klass)
16
+ class ShoutboxParserLoader(object):
17
+ def __init__(self, *args, **kwargs):
18
+ global _shoutbox_parser
19
+ _shoutbox_parser = BBCodeParser()
20
+ self.parser = _shoutbox_parser
32
21
 
22
+ def load_parser(self):
23
+ self.init_default_bbcode_placeholders()
24
+ self.init_bbcode_placeholders()
25
+ self.init_default_bbcode_tags()
26
+ self.init_bbcode_tags()
27
+ self.init_bbcode_smilies()
33
28
 
34
- def init_bbcode_placeholders():
35
- from precise_bbcode.placeholder_pool import placeholder_pool
29
+ def init_default_bbcode_placeholders(self):
30
+ import precise_bbcode.bbcode.defaults.placeholder
36
31
 
37
- placeholders = placeholder_pool.get_placeholders()
38
- for placeholder in placeholders:
39
- shoutbox_parser.add_placeholder(placeholder)
32
+ for placeholder_klass in get_subclasses(
33
+ precise_bbcode.bbcode.defaults.placeholder, BBCodePlaceholder
34
+ ):
35
+ setattr(placeholder_klass, "default_placeholder", True)
36
+ self.parser.add_placeholder(placeholder_klass)
40
37
 
38
+ def init_bbcode_placeholders(self):
39
+ from precise_bbcode.placeholder_pool import placeholder_pool
41
40
 
42
- def init_bbcode_tags():
43
- shoutbox_parser.add_bbcode_tag(StrongBBCodeTag)
44
- shoutbox_parser.add_bbcode_tag(ItalicBBCodeTag)
45
- shoutbox_parser.add_bbcode_tag(UnderlineBBCodeTag)
46
- shoutbox_parser.add_bbcode_tag(StrikeBBCodeTag)
47
- shoutbox_parser.add_bbcode_tag(ColorBBCodeTag)
48
- shoutbox_parser.add_bbcode_tag(UrlBBCodeTag)
49
- shoutbox_parser.add_bbcode_tag(FontBBCodeTag)
50
- shoutbox_parser.add_bbcode_tag(ShadowBBCodeTag)
51
- shoutbox_parser.add_bbcode_tag(SubscriptBBCodeTag)
52
- shoutbox_parser.add_bbcode_tag(SuperscriptBBCodeTag)
41
+ placeholders = placeholder_pool.get_placeholders()
42
+ for placeholder in placeholders:
43
+ self.parser.add_placeholder(placeholder)
53
44
 
45
+ def init_default_bbcode_tags(self):
46
+ import precise_bbcode.bbcode.defaults.tag
54
47
 
55
- def init_bbcode_smilies():
56
- SmileyTag = apps.get_model("precise_bbcode", "SmileyTag")
57
- if SmileyTag:
58
- custom_smilies = SmileyTag.objects.all()
59
- for smiley in custom_smilies:
60
- shoutbox_parser.add_smiley(smiley.code, smiley.html_code)
48
+ self.parser.add_bbcode_tag(precise_bbcode.bbcode.defaults.tag.StrongBBCodeTag)
49
+ self.parser.add_bbcode_tag(precise_bbcode.bbcode.defaults.tag.ItalicBBCodeTag)
50
+ self.parser.add_bbcode_tag(
51
+ precise_bbcode.bbcode.defaults.tag.UnderlineBBCodeTag
52
+ )
53
+ self.parser.add_bbcode_tag(precise_bbcode.bbcode.defaults.tag.StrikeBBCodeTag)
54
+ self.parser.add_bbcode_tag(precise_bbcode.bbcode.defaults.tag.ColorBBCodeTag)
55
+ self.parser.add_bbcode_tag(precise_bbcode.bbcode.defaults.tag.UrlBBCodeTag)
61
56
 
57
+ def init_bbcode_tags(self):
58
+ import punkweb_bb.bbcode_tags
62
59
 
63
- init_default_bbcode_placeholders()
64
- init_bbcode_placeholders()
65
- init_bbcode_tags()
66
- init_bbcode_smilies()
60
+ self.parser.add_bbcode_tag(punkweb_bb.bbcode_tags.FontBBCodeTag)
61
+ self.parser.add_bbcode_tag(punkweb_bb.bbcode_tags.ShadowBBCodeTag)
62
+ self.parser.add_bbcode_tag(punkweb_bb.bbcode_tags.SubscriptBBCodeTag)
63
+ self.parser.add_bbcode_tag(punkweb_bb.bbcode_tags.SuperscriptBBCodeTag)
64
+
65
+ def init_bbcode_smilies(self):
66
+ SmileyTag = apps.get_model("precise_bbcode", "SmileyTag")
67
+ if SmileyTag:
68
+ custom_smilies = SmileyTag.objects.all()
69
+ for smiley in custom_smilies:
70
+ self.parser.add_smiley(smiley.code, smiley.html_code)
punkweb_bb/settings.py CHANGED
@@ -4,4 +4,5 @@ PUNKWEB_BB = getattr(settings, "PUNKWEB_BB", {})
4
4
 
5
5
  SITE_NAME = PUNKWEB_BB.get("SITE_NAME", "PUNKWEB")
6
6
  SITE_TITLE = PUNKWEB_BB.get("SITE_TITLE", "PunkwebBB")
7
+ FAVICON = PUNKWEB_BB.get("FAVICON", "punkweb_bb/favicon.ico")
7
8
  SHOUTBOX_ENABLED = PUNKWEB_BB.get("SHOUTBOX_ENABLED", True)
@@ -53,3 +53,10 @@
53
53
  .profile__thread:not(:last-of-type) {
54
54
  border-bottom: 1px solid var(--border);
55
55
  }
56
+
57
+ @media screen and (max-width: 768px) {
58
+ .profile__info {
59
+ align-items: start;
60
+ flex-direction: column;
61
+ }
62
+ }
@@ -6,7 +6,7 @@
6
6
  <meta charset="UTF-8" />
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
8
  <title>{% block title_prefix %}{% endblock %}{{ punkweb_bb.settings.SITE_TITLE|default:"PunkwebBB" }}</title>
9
- <link rel="icon" href="{% static 'punkweb_bb/favicon.ico' %}" />
9
+ <link rel="icon" href="{% static punkweb_bb.settings.FAVICON %}" />
10
10
  <link rel="stylesheet" href="{% static 'punkweb_bb/vendor/open-color.css' %}" />
11
11
  <link rel="stylesheet" href="{% static 'punkweb_bb/vendor/prism.css' %}" />
12
12
  <link rel="stylesheet" href="{% static 'punkweb_bb/css/defaults.css' %}" />
@@ -160,6 +160,7 @@
160
160
  <div class="index__statistics__label">Total members:</div>
161
161
  <div class="index__statistics__value">{{users|length}}</div>
162
162
  </div>
163
+ {% if newest_user %}
163
164
  <div class="index__statistics__row">
164
165
  <div class="index__statistics__label">Newest member:</div>
165
166
  <div class="index__statistics__value">
@@ -168,6 +169,7 @@
168
169
  </a>
169
170
  </div>
170
171
  </div>
172
+ {% endif %}
171
173
  <div class="index__statistics__row">
172
174
  <div class="index__statistics__label">Members online:</div>
173
175
  <div class="index__statistics__value">{{users_online|length}}</div>
@@ -1,5 +1,5 @@
1
1
  {% extends 'punkweb_bb/base.html' %}
2
- {% load static %}
2
+ {% load static humanize_int %}
3
3
 
4
4
  {% block title_prefix %}{{subcategory.name}} | {% endblock%}
5
5
 
@@ -14,6 +14,9 @@
14
14
  <li class="pw-breadcrumb-item">
15
15
  <a href="{% url 'punkweb_bb:index' %}">Home</a>
16
16
  </li>
17
+ <li class="pw-breadcrumb-item">
18
+ <a href="{{subcategory.category.get_absolute_url}}">{{subcategory.category.name}}</a>
19
+ </li>
17
20
  <li class="pw-breadcrumb-item active">
18
21
  {{subcategory.name}}
19
22
  </li>
@@ -44,12 +47,14 @@
44
47
  <colgroup>
45
48
  <col span="1">
46
49
  <col span="1" width="96px">
50
+ <col span="1" width="96px">
47
51
  <col span="1" width="160px">
48
52
  </colgroup>
49
53
  <thead>
50
54
  <tr>
51
55
  <th>Title</th>
52
56
  <th>Posts</th>
57
+ <th>Views</th>
53
58
  <th></th>
54
59
  </tr>
55
60
  </thead>
@@ -74,6 +79,7 @@
74
79
  {{thread.created_at|date:'M j, Y'}}</div>
75
80
  </td>
76
81
  <td>{{thread.post_count}}</td>
82
+ <td>{{thread.view_count | humanize_int}}</td>
77
83
  <td>
78
84
  {% if thread.latest_post %}
79
85
  <div class="thread__latestPost">
@@ -21,6 +21,9 @@
21
21
  <li class="pw-breadcrumb-item">
22
22
  <a href="{% url 'punkweb_bb:index' %}">Home</a>
23
23
  </li>
24
+ <li class="pw-breadcrumb-item">
25
+ <a href="{{thread.subcategory.category.get_absolute_url}}">{{thread.subcategory.category.name}}</a>
26
+ </li>
24
27
  <li class="pw-breadcrumb-item">
25
28
  <a href="{{thread.subcategory.get_absolute_url}}">{{thread.subcategory.name}}</a>
26
29
  </li>
@@ -56,7 +59,7 @@
56
59
  <div class="thread__user__info__row">
57
60
  <div class="thread__user__info__label">Joined:</div>
58
61
  <div class="thread__user__info__value">
59
- {{thread.user.profile.created_at|date:"M d, Y"}}
62
+ {{thread.user.date_joined|date:"M d, Y"}}
60
63
  </div>
61
64
  </div>
62
65
  <div class="thread__user__info__row">
@@ -117,7 +120,7 @@
117
120
  <div class="thread__user__info__row">
118
121
  <div class="thread__user__info__label">Joined:</div>
119
122
  <div class="thread__user__info__value">
120
- {{post.user.profile.created_at|date:"M d, Y"}}
123
+ {{post.user.date_joined|date:"M d, Y"}}
121
124
  </div>
122
125
  </div>
123
126
  <div class="thread__user__info__row">
@@ -15,6 +15,9 @@
15
15
  <li class="pw-breadcrumb-item">
16
16
  <a href="{% url 'punkweb_bb:index' %}">Home</a>
17
17
  </li>
18
+ <li class="pw-breadcrumb-item">
19
+ <a href="{{subcategory.category.get_absolute_url}}">{{subcategory.category.name}}</a>
20
+ </li>
18
21
  <li class="pw-breadcrumb-item">
19
22
  <a href="{{subcategory.get_absolute_url}}">{{subcategory.name}}</a>
20
23
  </li>
@@ -15,6 +15,9 @@
15
15
  <li class="pw-breadcrumb-item">
16
16
  <a href="{% url 'punkweb_bb:index' %}">Home</a>
17
17
  </li>
18
+ <li class="pw-breadcrumb-item">
19
+ <a href="{{thread.subcategory.category.get_absolute_url}}">{{thread.subcategory.category.name}}</a>
20
+ </li>
18
21
  <li class="pw-breadcrumb-item">
19
22
  <a href="{{thread.subcategory.get_absolute_url}}">{{thread.subcategory.name}}</a>
20
23
  </li>
@@ -0,0 +1,12 @@
1
+ from django import template
2
+
3
+ register = template.Library()
4
+
5
+
6
+ @register.filter
7
+ def humanize_int(value):
8
+ if value >= 1000000:
9
+ return f"{value / 1000000:.1f}M"
10
+ elif value >= 1000:
11
+ return f"{value / 1000:.1f}K"
12
+ return value
@@ -1,7 +1,7 @@
1
1
  from django import template
2
2
  from django.template.defaultfilters import stringfilter
3
3
 
4
- from punkweb_bb.parsers import shoutbox_parser
4
+ from punkweb_bb.parsers import get_shoutbox_parser
5
5
 
6
6
  register = template.Library()
7
7
 
@@ -9,6 +9,6 @@ register = template.Library()
9
9
  @register.filter(is_safe=True)
10
10
  @stringfilter
11
11
  def shoutbox_bbcode(value):
12
- parser = shoutbox_parser
12
+ parser = get_shoutbox_parser()
13
13
 
14
14
  return parser.render(value)