punkweb-bb 0.1.3__py3-none-any.whl → 0.1.4__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/guests.py ADDED
@@ -0,0 +1,20 @@
1
+ from expiringdict import ExpiringDict
2
+
3
+
4
+ class GuestList:
5
+ def __init__(self):
6
+ self.__guests = ExpiringDict(max_len=2048, max_age_seconds=60 * 5)
7
+
8
+ def length(self):
9
+ return len(self.__guests)
10
+
11
+ def add(self, ip):
12
+ if not self.__guests.get(ip, None):
13
+ self.__guests[ip] = True
14
+
15
+ def clear_expired(self):
16
+ for key in list(self.__guests.keys()):
17
+ _ = self.__guests.get(key, None)
18
+
19
+
20
+ guest_list = GuestList()
punkweb_bb/middleware.py CHANGED
@@ -1,6 +1,8 @@
1
1
  from django.core.cache import cache
2
2
  from django.utils import timezone
3
3
 
4
+ from punkweb_bb.guests import guest_list
5
+
4
6
 
5
7
  class ProfileOnlineCacheMiddleware:
6
8
  def __init__(self, get_response):
@@ -11,6 +13,11 @@ class ProfileOnlineCacheMiddleware:
11
13
  cache.set(
12
14
  f"profile_online_{request.user.profile.id}", timezone.now(), 60 * 5
13
15
  )
16
+ else:
17
+ ip = request.META.get("REMOTE_ADDR")
18
+ guest_list.add(ip)
19
+
20
+ guest_list.clear_expired()
14
21
 
15
22
  response = self.get_response(request)
16
23
 
punkweb_bb/settings.py CHANGED
@@ -6,3 +6,6 @@ SITE_NAME = PUNKWEB_BB.get("SITE_NAME", "PUNKWEB")
6
6
  SITE_TITLE = PUNKWEB_BB.get("SITE_TITLE", "PunkwebBB")
7
7
  FAVICON = PUNKWEB_BB.get("FAVICON", "punkweb_bb/favicon.ico")
8
8
  SHOUTBOX_ENABLED = PUNKWEB_BB.get("SHOUTBOX_ENABLED", True)
9
+ DISCORD_WIDGET_ENABLED = PUNKWEB_BB.get("DISCORD_WIDGET_ENABLED", False)
10
+ DISCORD_WIDGET_THEME = PUNKWEB_BB.get("DISCORD_WIDGET_THEME", "dark")
11
+ DISCORD_SERVER_ID = PUNKWEB_BB.get("DISCORD_SERVER_ID", None)
@@ -646,3 +646,26 @@ blockquote cite {
646
646
  .pw-breadcrumb-item.active {
647
647
  color: var(--breadcrumb-active);
648
648
  }
649
+
650
+ /* Callout */
651
+
652
+ .pw-callout {
653
+ background-color: var(--oc-gray-1);
654
+ border: 1px solid var(--border);
655
+ border-radius: 0.25rem;
656
+ color: var(--oc-gray-9);
657
+ padding: 0.5rem 1rem;
658
+ width: 100%;
659
+ }
660
+
661
+ .pw-callout.primary {
662
+ background-color: var(--primary-0);
663
+ border-color: 1px solid var(--primary-4);
664
+ color: var(--primary-9);
665
+ }
666
+
667
+ .pw-callout.danger {
668
+ background-color: var(--oc-red-0);
669
+ border-color: 1px solid var(--oc-red-4);
670
+ color: var(--oc-red-9);
671
+ }
@@ -171,16 +171,29 @@
171
171
  </div>
172
172
  {% endif %}
173
173
  <div class="index__statistics__row">
174
- <div class="index__statistics__label">Members online:</div>
175
- <div class="index__statistics__value">{{users_online|length}}</div>
176
- </div>
177
- <div class="index__statistics__row">
178
- <div class="index__statistics__label">Staff online:</div>
179
- <div class="index__statistics__value">{{staff_online|length}}</div>
174
+ <div class="index__statistics__label">Users online:</div>
175
+ <div class="index__statistics__value">{{total_online}} ({{members_online|length}} members, {{staff_online|length}} staff, {{guests_online}} guests)</div>
180
176
  </div>
181
177
  </div>
182
178
  </div>
183
179
  </div>
180
+ {% if punkweb_bb.settings.DISCORD_WIDGET_ENABLED %}
181
+ {% if punkweb_bb.settings.DISCORD_SERVER_ID %}
182
+ <iframe
183
+ src="https://discord.com/widget?id={{ punkweb_bb.settings.DISCORD_SERVER_ID }}&theme={{ punkweb_bb.settings.DISCORD_WIDGET_THEME|default:'dark' }}"
184
+ width="100%"
185
+ height="384"
186
+ allowtransparency="true"
187
+ frameborder="0"
188
+ sandbox="allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts">
189
+ </iframe>
190
+ {% else %}
191
+ <div class="pw-callout danger">
192
+ <h4>Discord Widget Error</h4>
193
+ <p><code>DISCORD_SERVER_ID</code> not configured in settings module.</p>
194
+ </div>
195
+ {% endif %}
196
+ {% endif %}
184
197
  </div>
185
198
  </div>
186
199
  </div>
punkweb_bb/tests.py CHANGED
@@ -299,14 +299,14 @@ class IndexViewTestCase(TestCase):
299
299
  username="staff", password="staff", is_staff=True
300
300
  )
301
301
 
302
- def test_users_online(self):
302
+ def test_members_online(self):
303
303
  response = self.client.get(self.url)
304
- self.assertEqual(len(response.context["users_online"]), 0)
304
+ self.assertEqual(len(response.context["members_online"]), 0)
305
305
 
306
306
  self.client.force_login(self.user)
307
307
  response = self.client.get(self.url)
308
308
 
309
- self.assertEqual(len(response.context["users_online"]), 1)
309
+ self.assertEqual(len(response.context["members_online"]), 1)
310
310
 
311
311
  def test_staff_online(self):
312
312
  response = self.client.get(self.url)
@@ -317,6 +317,17 @@ class IndexViewTestCase(TestCase):
317
317
 
318
318
  self.assertEqual(len(response.context["staff_online"]), 1)
319
319
 
320
+ def test_guests_online(self):
321
+ response = self.client.get(self.url)
322
+ self.assertEqual(response.context["guests_online"], 1)
323
+
324
+ def test_total_online(self):
325
+ response = self.client.get(self.url)
326
+ self.client.force_login(self.user)
327
+ response = self.client.get(self.url)
328
+
329
+ self.assertEqual(response.context["total_online"], 2)
330
+
320
331
  def test_newest_user(self):
321
332
  response = self.client.get(self.url)
322
333
  self.assertEqual(response.context["newest_user"], self.staff_user)
punkweb_bb/views.py CHANGED
@@ -6,6 +6,7 @@ from django.http import HttpResponseForbidden
6
6
  from django.shortcuts import get_object_or_404, redirect, render
7
7
  from django.utils import timezone
8
8
 
9
+ from punkweb_bb.guests import guest_list
9
10
  from punkweb_bb.forms import (
10
11
  BoardProfileModelForm,
11
12
  LoginForm,
@@ -31,8 +32,12 @@ def index_view(request):
31
32
 
32
33
  users = User.objects.select_related("profile").all()
33
34
  newest_user = users.order_by("-profile__created_at").first()
35
+
34
36
  users_online = [user for user in users if user.profile.is_online]
37
+ members_online = [user for user in users_online if not user.is_staff]
35
38
  staff_online = [user for user in users_online if user.is_staff]
39
+ guests_online = guest_list.length()
40
+ total_online = len(members_online) + len(staff_online) + guests_online
36
41
 
37
42
  context = {
38
43
  "categories": categories,
@@ -41,8 +46,10 @@ def index_view(request):
41
46
  "post_count": post_count,
42
47
  "users": users,
43
48
  "newest_user": newest_user,
44
- "users_online": users_online,
49
+ "members_online": members_online,
45
50
  "staff_online": staff_online,
51
+ "guests_online": guests_online,
52
+ "total_online": total_online,
46
53
  }
47
54
  return render(request, "punkweb_bb/index.html", context=context)
48
55
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: punkweb-bb
3
- Version: 0.1.3
3
+ Version: 0.1.4
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: expiringdict
20
21
  Requires-Dist: pillow
21
22
 
22
23
  # PunkwebBB
@@ -115,6 +116,9 @@ PUNKWEB_BB = {
115
116
  "SITE_TITLE": "PunkwebBB",
116
117
  "FAVICON": "punkweb_bb/favicon.ico",
117
118
  "SHOUTBOX_ENABLED": True,
119
+ "DISCORD_WIDGET_ENABLED": False,
120
+ "DISCORD_WIDGET_THEME": "dark",
121
+ "DISCORD_SERVER_ID": None, # Found under Server Settings > Widget > Server ID
118
122
  }
119
123
  ```
120
124
 
@@ -5,17 +5,18 @@ punkweb_bb/apps.py,sha256=GCDLy9B9vumeCsaauQ7LN4FOqE02mXWXECIz8G6KZCQ,207
5
5
  punkweb_bb/bbcode_tags.py,sha256=yNayXcZoRcRVZsdVrKIdKOV7bwlApFfq_CVfh1im7SY,4419
6
6
  punkweb_bb/context_processors.py,sha256=BEOGvWVukvxJUxWZBIc32ioB-mGqImSEBuhhZjqI2G0,146
7
7
  punkweb_bb/forms.py,sha256=O1lzmgumdnSEjBKi10c7ODftIqRmvtEIdNj1IODCikk,1977
8
- punkweb_bb/middleware.py,sha256=lF1w7XM07s1kcrOWodzErHop9zpIE5SEE52YLMAbDKg,456
8
+ punkweb_bb/guests.py,sha256=Nvn4ZVJvQSQs_f-GeSwNn79Qp8ap_CAoXpYfRTqSbxg,467
9
+ punkweb_bb/middleware.py,sha256=NrYv6nyAYKGcu-qKRnZmCyLghtJ4MUHvt3m5NS8HJbo,628
9
10
  punkweb_bb/mixins.py,sha256=XfiThPL7rB71IfukS1ikvYQhfg8RwgSVgsm10Ul1ezM,395
10
11
  punkweb_bb/models.py,sha256=Y5w80EQ85Mut71xiDVMALqLXdydlTxOiZEljmnH5g-E,5519
11
12
  punkweb_bb/pagination.py,sha256=OgoZuJsq9MKMvBKYylJVPaNtM9ni3K8OAvOdi-eGr3M,409
12
13
  punkweb_bb/parsers.py,sha256=VjWSPqpVfypHLHP0NrfLqXB-1b0W6oFuGIzoAiPi71I,2732
13
14
  punkweb_bb/response.py,sha256=dETGVC9Xrsq02pQzmIIWbSUt472lJ4fgLwBKrXnP3t4,130
14
- punkweb_bb/settings.py,sha256=rYKMQxbC6rfzOQgcjAoBuMEgKHOITvOX1PrKTweEYKk,312
15
+ punkweb_bb/settings.py,sha256=ebJahIZHt1fYdhxB9wWDlWj5KhzExUtaXyoFLy8uR6k,517
15
16
  punkweb_bb/signals.py,sha256=bVdfg942Mwq-fYDZ1Z52Q0V2BCk1lgzGz8JVZFPnzJ8,365
16
- punkweb_bb/tests.py,sha256=BXkvqtr1JbE2WQYkgjse3wp9ky3cwOzQcVHoqNhHJmw,25989
17
+ punkweb_bb/tests.py,sha256=eMvY9tnOkTd_zWs_Qs0Z6X-MtVSv4TtJSZfTy4beGp4,26368
17
18
  punkweb_bb/urls.py,sha256=_mRAtaZoKzPZ_uuOCFy6_lOwFCavv26p5kMKD9MH4c4,1538
18
- punkweb_bb/views.py,sha256=HDJCM8PgDkQu96UbZLFyjSD2K9WIjLhWEO-QBM3APmk,10723
19
+ punkweb_bb/views.py,sha256=9g9s2rOpgfoGUdPAL9OZrWveudxOG4J5_bd9Mqd_TJI,11036
19
20
  punkweb_bb/widgets.py,sha256=eF6CB5nnh_6XJadpDzDKgd9incd0VIR63Rnzdr8T2n0,840
20
21
  punkweb_bb/__pycache__/__init__.cpython-311.pyc,sha256=3PyxCxoznfadaGt0a7re4j0Ky9z9hblufpcwPB85kK8,161
21
22
  punkweb_bb/__pycache__/admin.cpython-311.pyc,sha256=rAPYqRy7hAVZn3qST3ypYdulvH9IBhzWEgvbbAMIMIY,3679
@@ -24,17 +25,18 @@ punkweb_bb/__pycache__/apps.cpython-311.pyc,sha256=lw328DOwOp1F8FWTFYb3qV1EoBNgR
24
25
  punkweb_bb/__pycache__/bbcode_tags.cpython-311.pyc,sha256=QI4BJt5plqLMiAvlVAxibuNONi69PJFQpotpS50olro,8534
25
26
  punkweb_bb/__pycache__/context_processors.cpython-311.pyc,sha256=P7rEsodXonYexbS5vUaUKVJ9tIx1pOVk6NQWVvWNvS8,392
26
27
  punkweb_bb/__pycache__/forms.cpython-311.pyc,sha256=JRbtAaXyXgG9eDdBjKBkSn8qeZtdxRc7L2_ceE-MpW8,4680
27
- punkweb_bb/__pycache__/middleware.cpython-311.pyc,sha256=gZN0oVrPh9nIUUni_DvPrhMOYPR98SXrYxgHIsUXX-0,1249
28
+ punkweb_bb/__pycache__/guests.cpython-311.pyc,sha256=vgZJcZGyHZkllCAhXHGgajHh7YM1ntXinSed3ojIK6I,1581
29
+ punkweb_bb/__pycache__/middleware.cpython-311.pyc,sha256=KbZ6z2Q7eCRX3dB7mnRUpn58mb_O8sXpOw_sqVfQsgM,1560
28
30
  punkweb_bb/__pycache__/mixins.cpython-311.pyc,sha256=eP1NjqDNYMYXrC45DNkrTqVAUv1vsGBrqPy5U5CB_aw,1478
29
31
  punkweb_bb/__pycache__/models.cpython-311.pyc,sha256=9W03p0j5_dYnQ4YffZUrN_A5-Bvkbpvfmpr5rOkzyAQ,12308
30
32
  punkweb_bb/__pycache__/pagination.cpython-311.pyc,sha256=r54xmtiRp5dm1n2Xa7oElMFFaYFY0RzmMuF3Er4UqEA,990
31
33
  punkweb_bb/__pycache__/parsers.cpython-311.pyc,sha256=pp8JZt9V3HhquQMGrhglwLc53GxgNFWjjSnK3Bpxf8o,5335
32
34
  punkweb_bb/__pycache__/response.cpython-311.pyc,sha256=CEPckYWZkOrdU2Vow-ni0ZrWEUBww0uJzyr_wv---mM,448
33
- punkweb_bb/__pycache__/settings.cpython-311.pyc,sha256=ZjE994_MuSW_9Dn_ufsUH-vrld-BvqEwoCF7YL9tbrA,665
35
+ punkweb_bb/__pycache__/settings.cpython-311.pyc,sha256=earWFaFtg8IPqfOz9I6wdpI9bJtxjxsTwG7LoTCPmtw,947
34
36
  punkweb_bb/__pycache__/signals.cpython-311.pyc,sha256=AHChn7hDdrOmCAwKIKKuFOY-4hyBP9uwTkyb5bnFV-Q,864
35
- punkweb_bb/__pycache__/tests.cpython-311.pyc,sha256=3CM8FL8P1YXVcgShhXqXjg3Yo3T1amKXlVtHRUZ2d7o,50877
37
+ punkweb_bb/__pycache__/tests.cpython-311.pyc,sha256=D5pfsajoulTkeQ4RnDEc_HZZ9AH-ZIo3cPnh6BACaHY,51829
36
38
  punkweb_bb/__pycache__/urls.cpython-311.pyc,sha256=80TvNUws6ip1FCts6bubO3DGQJ2yOlB-WReK-qaTnGY,2304
37
- punkweb_bb/__pycache__/views.cpython-311.pyc,sha256=bjqhbTnN0-pvIygCzh0NXY6lNJUjMpz8B51EIlpay94,15592
39
+ punkweb_bb/__pycache__/views.cpython-311.pyc,sha256=IidhDNPCjZExmP26hujz3nKocJlf4bFlVxgbP2xM6Is,16108
38
40
  punkweb_bb/__pycache__/widgets.cpython-311.pyc,sha256=-RcQ3JapLHw8Bbi4FP05kQJJIa7bnliKPaFpkDCOWvQ,1552
39
41
  punkweb_bb/migrations/0001_initial.py,sha256=3RGsylygBcWx1kIPhSzOb9v_2yvowsxKfxuSinKKuS0,8950
40
42
  punkweb_bb/migrations/0002_thread_view_count.py,sha256=JJZT53Mp8Ofht3oIi67s-0wzCdpYyu8wOeCi_B8q8Yo,388
@@ -50,7 +52,7 @@ punkweb_bb/static/punkweb_bb/css/members.css,sha256=1Fz0uVDbs3RnuXNjOtnGnK2jok3L
50
52
  punkweb_bb/static/punkweb_bb/css/post-form.css,sha256=rEiYplAobLjjUYAcnjNqIjyIVhe9O5hAlPJ3STW-K14,321
51
53
  punkweb_bb/static/punkweb_bb/css/profile.css,sha256=yfNJT_D-05deqiBrdIgPeCSO_DFSL8-fGEEHnGrCIYM,916
52
54
  punkweb_bb/static/punkweb_bb/css/punkweb-modal.css,sha256=ctwo5bgbAW-k0uqrufDbqeQfAh87-BZ-5gPm8aJHeT4,1296
53
- punkweb_bb/static/punkweb_bb/css/punkweb.css,sha256=UZT592v_krB8DPFf6YN1zlKmmFiCAXdS_KqO98GrKNM,11284
55
+ punkweb_bb/static/punkweb_bb/css/punkweb.css,sha256=4-s3mmZa-HMiPS-pNyfMqo7RPaq1KlEewril-tQbmls,11745
54
56
  punkweb_bb/static/punkweb_bb/css/settings.css,sha256=ulQQFTu8slk2rYOmhvci5v-AVnguUuDhKQDhyQOsQNU,308
55
57
  punkweb_bb/static/punkweb_bb/css/shoutbox.css,sha256=-aPkQHelFsy8IYhURqTPEMIsd1ivS9mf-4ha3xHyAms,333
56
58
  punkweb_bb/static/punkweb_bb/css/subcategory.css,sha256=1wjszJbkCJL-UJRFqOWSmX4yr60ekx0YtswZouUsY7s,536
@@ -191,7 +193,7 @@ punkweb_bb/static/punkweb_bb/vendor/sceditor-3.2.0/minified/themes/content/defau
191
193
  punkweb_bb/templates/punkweb_bb/base.html,sha256=Gu2ZVeP0p7GnsfXFxByXRd9LT4DNXx0O1czSGjwYg0w,4037
192
194
  punkweb_bb/templates/punkweb_bb/base_modal.html,sha256=OCbtsMWeNCO0Tl1PmHCcGkwoi1OZjeIK_VhNTzMor7M,460
193
195
  punkweb_bb/templates/punkweb_bb/bbcode.html,sha256=1EGBejsOMZOPi6P39oR6E35VdqnfR6wYWeKDl4Xr_js,396
194
- punkweb_bb/templates/punkweb_bb/index.html,sha256=2y8gS6UzoJkVXvmw5PEuuxyYIarlNjGzTmmNMuNWNJ8,8127
196
+ punkweb_bb/templates/punkweb_bb/index.html,sha256=jflA40dpl9aId0a6E_oE2PBjlvWK25cmbN9OoePzeqM,8703
195
197
  punkweb_bb/templates/punkweb_bb/login.html,sha256=ZUOmbyZREzS7Sw02Lfb9zpRJQQWwJgolnj9lcBKnOtg,1087
196
198
  punkweb_bb/templates/punkweb_bb/members.html,sha256=ceRCRX0AN7V8d7paz9495y8aQByMUKDWVWL2GzoGbus,2729
197
199
  punkweb_bb/templates/punkweb_bb/profile.html,sha256=MW1JWLs_lLpg62DDcvcZJRwrHquYA5nCwQqL1v9ZGCo,2948
@@ -213,8 +215,8 @@ punkweb_bb/templatetags/__pycache__/__init__.cpython-311.pyc,sha256=VEPKwaIhqpKp
213
215
  punkweb_bb/templatetags/__pycache__/humanize_count.cpython-311.pyc,sha256=UKD6_5RX8YpYpg-LPrgGxBkW56THsbYY51cKTYdKwRY,621
214
216
  punkweb_bb/templatetags/__pycache__/humanize_int.cpython-311.pyc,sha256=csY5ek-bevYVeM91hYFKozuKWXCTXb7M-7Bokwdxhrk,619
215
217
  punkweb_bb/templatetags/__pycache__/shoutbox_bbcode.cpython-311.pyc,sha256=Jhg9qW-nQe6IDr45rE0ZgeDYF4E61S7kYAYpbMo5ZQ8,833
216
- punkweb_bb-0.1.3.dist-info/LICENSE,sha256=YYysF07B-kyXSO7IWFB9f49ZXa6LIFUTVsR1Ogmhp8s,1507
217
- punkweb_bb-0.1.3.dist-info/METADATA,sha256=thU9kjReWNpjs73xcTkXgnO0LKX_-g_wELf87WiE-0Q,4930
218
- punkweb_bb-0.1.3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
219
- punkweb_bb-0.1.3.dist-info/top_level.txt,sha256=sWuGdGnk0ejOXiFDzlBqrNs2VbPEx0_i8UwWXn4SuHU,11
220
- punkweb_bb-0.1.3.dist-info/RECORD,,
218
+ punkweb_bb-0.1.4.dist-info/LICENSE,sha256=YYysF07B-kyXSO7IWFB9f49ZXa6LIFUTVsR1Ogmhp8s,1507
219
+ punkweb_bb-0.1.4.dist-info/METADATA,sha256=6ypsD63FEqGSzezKYpfi0ppzLVrsYv4cbGLXcjnGHdE,5107
220
+ punkweb_bb-0.1.4.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
221
+ punkweb_bb-0.1.4.dist-info/top_level.txt,sha256=sWuGdGnk0ejOXiFDzlBqrNs2VbPEx0_i8UwWXn4SuHU,11
222
+ punkweb_bb-0.1.4.dist-info/RECORD,,