signal backend, app cleanup

This commit is contained in:
j 2023-07-24 12:05:45 +01:00
commit 6f18890739
43 changed files with 695 additions and 124 deletions

View file

@ -0,0 +1,47 @@
# Generated by Django 4.2.3 on 2023-07-24 14:07
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
("item", "0002_initial"),
]
operations = [
migrations.AlterModelOptions(
name="comment",
options={
"permissions": [
("can_post_comment", "Can post comments without moderation")
]
},
),
migrations.AlterField(
model_name="comment",
name="user",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="comments",
to=settings.AUTH_USER_MODEL,
),
),
migrations.AlterField(
model_name="item",
name="announced",
field=models.DateTimeField(blank=True, default=None, null=True),
),
migrations.AlterField(
model_name="item",
name="published",
field=models.DateTimeField(
blank=True, default=django.utils.timezone.now, null=True
),
),
]

View file

@ -0,0 +1,17 @@
# Generated by Django 4.2.3 on 2023-07-24 17:04
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("item", "0003_alter_comment_options_alter_comment_user_and_more"),
]
operations = [
migrations.AddField(
model_name="comment",
name="session_key",
field=models.CharField(blank=True, default=None, max_length=60, null=True),
),
]

View file

@ -13,6 +13,7 @@ from django.urls import reverse
User = get_user_model()
class Settings(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
@ -37,6 +38,7 @@ class Item(models.Model):
if self.url and not self.data:
self.update_data()
super().save(*args, **kwargs)
def __str__(self):
return '%s (%s)' % (self.title, self.url)
@ -60,14 +62,15 @@ class Item(models.Model):
cal = now.date().isocalendar()
monday = now.date() - timedelta(days=now.date().isocalendar().weekday - 1)
monday = timezone.datetime(monday.year, monday.month, monday.day, tzinfo=now.tzinfo)
print(now.tzinfo)
first_post = qs.filter(published__gt=monday).first()
print('!!', first_post.published, now, first_post.published > now)
if first_post.published < now:
print('only this week')
if first_post and first_post.published < now:
week = qs.filter(published__gt=monday)
elif not first_post:
while qs.exists() and not first_post:
monday = monday - timedelta(days=7)
first_post = qs.filter(published__gt=monday).first()
week = qs.filter(published__gt=monday)
else:
print('only last week')
last_monday = monday - timedelta(days=7)
week = qs.filter(published__gt=last_monday)
archive = qs.exclude(id__in=week)
@ -102,6 +105,7 @@ class Comment(models.Model):
item = models.ForeignKey(Item, related_name='comments', on_delete=models.CASCADE)
user = models.ForeignKey(User, null=True, related_name='comments', on_delete=models.CASCADE, blank=True)
session_key = models.CharField(max_length=60, null=True, default=None, blank=True)
name = models.CharField(max_length=1024)
email = models.CharField(max_length=1024)
@ -109,6 +113,11 @@ class Comment(models.Model):
data = models.JSONField(default=dict, editable=False)
published = models.DateTimeField(null=True, default=None)
class Meta:
permissions = [
("can_post_comment", "Can post comments without moderation")
]
@property
def is_published(self):
return bool(self.published)
@ -128,7 +137,11 @@ class Comment(models.Model):
def json(self):
data = {}
data['name'] = self.name
if not self.user:
data['name'] = '%s (guest)' % self.name
else:
data['name'] = self.name
data['date'] = self.date
data['text'] = self.text
return data

28
app/item/tasks.py Normal file
View file

@ -0,0 +1,28 @@
from celery.schedules import crontab
from django.conf import settings
from ..signalbot import rpc
from ..celery import app
from . import models
@app.task(queue="default")
def announce_items():
pass
@app.task(queue="default")
def notify_moderators(id, link):
comment = models.Comment.objects.filter(id=id).first()
if comment:
message = "%s commnented on %s\n\n%s" % (comment.name, link, comment.text)
r = rpc.send(message, group=settings.SIGNAL_MODERATORS_GROUP)
if r and "timestamp" in r:
comment.data["moderator_ts"] = r["timestamp"]
comment.save()
else:
print("failed to notify", r)
@app.on_after_finalize.connect
def setup_periodic_tasks(sender, **kwargs):
sender.add_periodic_task(crontab(minute="*/2"), announce_items.s())

8
app/item/utils.py Normal file
View file

@ -0,0 +1,8 @@
import json
from django.http import Http404, HttpResponse
def render_to_json(response):
content = json.dumps(response)
return HttpResponse(content, 'application/json; charset=utf-8')

View file

@ -1,7 +1,16 @@
from datetime import date, datetime, timedelta
import json
from django.utils import timezone
from django.shortcuts import render
from django.db.models import Q
from django.utils.html import mark_safe
from django.conf import settings
from . import models
from . import tasks
from ..signalbot.rpc import send_reaction
from .utils import render_to_json
def index(request):
@ -19,33 +28,74 @@ def archive(request):
context['items'] = archive
return render(request, 'archive.html', context)
def item(request, id):
context = {}
item = models.Item.objects.get(id=id)
context['item'] = item
qs = item.comments.order_by('created')
if not request.user.is_staff:
q = ~Q(published=None)
if request.user.is_authenticated:
q |= Q(user=request.user)
if request.session and request.session.session_key:
q |= Q(session_key=request.session.session_key)
qs = qs.filter(q)
comments = []
for comment in qs:
comments.append({
"id": comment.id,
"name": comment.name,
"date": comment.date,
"text": comment.text,
"published": comment.is_published,
})
context['comments'] = mark_safe(json.dumps(comments))
user = {}
if request.user.is_staff:
user['is_moderator'] = True
if request.user.is_authenticated:
user['username'] = request.user.username
context['user'] = mark_safe(json.dumps(user))
request.session['item'] = id
return render(request, 'item.html', context)
import json
from django.http import Http404, HttpResponse
def render_to_json(response):
content = json.dumps(response)
return HttpResponse(content, 'application/json; charset=utf-8')
def comment(request):
response = {}
data = json.loads(request.body)
print(data)
comment = models.Comment()
comment.item = models.Item.objects.get(id=data['item'])
if request.user.is_authenticated:
comment.user = request.user
comment.published = datetime.now()
if comment.user.has_perm('app.item.can_post_comment'):
comment.published = timezone.now()
else:
comment.name = data['name']
comment.email = data['email']
comment.session_key = request.session.session_key
comment.text = data['text']
comment.save()
if not comment.published:
link = request.build_absolute_uri(comment.item.get_absolute_url())
tasks.notify_moderators.delay(comment.id, link)
response = comment.json()
return render_to_json(response)
def publish_comment(request):
response = {}
data = json.loads(request.body)
if request.user.is_staff:
comment = models.Comment.objects.get(id=data['comment'])
comment.published = timezone.now()
comment.save()
if comment.data.get("moderator_ts"):
account = settings.SIGNAL_ACCOUNT
group = settings.SIGNAL_MODERATORS_GROUP
send_reaction(account, comment.data["moderator_ts"], "🎉", group=group)
response['status'] = 'ok'
else:
response['error'] = 'permission denied'
return render_to_json(response)