Add first alerts.
authorRadek Czajka <rczajka@rczajka.pl>
Mon, 23 May 2022 09:42:52 +0000 (11:42 +0200)
committerRadek Czajka <rczajka@rczajka.pl>
Mon, 23 May 2022 09:42:52 +0000 (11:42 +0200)
12 files changed:
src/alerts/__init__.py [new file with mode: 0644]
src/alerts/admin.py [new file with mode: 0644]
src/alerts/apps.py [new file with mode: 0644]
src/alerts/migrations/0001_initial.py [new file with mode: 0644]
src/alerts/migrations/__init__.py [new file with mode: 0644]
src/alerts/models.py [new file with mode: 0644]
src/alerts/rules.py [new file with mode: 0644]
src/alerts/templatetags/alerts.py [new file with mode: 0644]
src/alerts/tests.py [new file with mode: 0644]
src/alerts/views.py [new file with mode: 0644]
src/documents/templates/documents/base.html
src/redakcja/settings/__init__.py

diff --git a/src/alerts/__init__.py b/src/alerts/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/alerts/admin.py b/src/alerts/admin.py
new file mode 100644 (file)
index 0000000..3eda708
--- /dev/null
@@ -0,0 +1,5 @@
+from django.contrib import admin
+from .models import Alert
+
+
+admin.site.register(Alert)
diff --git a/src/alerts/apps.py b/src/alerts/apps.py
new file mode 100644 (file)
index 0000000..0a64765
--- /dev/null
@@ -0,0 +1,6 @@
+from django.apps import AppConfig
+
+
+class AlertsConfig(AppConfig):
+    default_auto_field = 'django.db.models.BigAutoField'
+    name = 'alerts'
diff --git a/src/alerts/migrations/0001_initial.py b/src/alerts/migrations/0001_initial.py
new file mode 100644 (file)
index 0000000..2e1230c
--- /dev/null
@@ -0,0 +1,24 @@
+# Generated by Django 3.2.12 on 2022-05-23 11:14
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        ('documents', '0008_book_legimi_id'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Alert',
+            fields=[
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('tag', models.CharField(max_length=32)),
+                ('book', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='documents.book')),
+            ],
+        ),
+    ]
diff --git a/src/alerts/migrations/__init__.py b/src/alerts/migrations/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/alerts/models.py b/src/alerts/models.py
new file mode 100644 (file)
index 0000000..268089a
--- /dev/null
@@ -0,0 +1,32 @@
+from django.db import models
+from django.dispatch import receiver
+from dvcs.models import post_commit
+from .rules import rules, rules_by_tag
+
+
+class Alert(models.Model):
+    book = models.ForeignKey('documents.Book', models.CASCADE)
+    tag = models.CharField(max_length=32)
+
+    @property
+    def rule(self):
+        return rules_by_tag[self.tag]
+
+    @classmethod
+    def validate_book(cls, book):
+        cls.objects.filter(book=book).delete()
+        try:
+            wlbook = book.wldocument(publishable=False, librarian2=True)
+        except:
+            cls.objects.create(book=book, tag='parse')
+            return
+
+        for rule in rules:
+            if rule.check_meta(wlbook.meta):
+                print(rule.tag, book)
+                cls.objects.create(book=book, tag=rule.tag)
+
+
+@receiver(post_commit)
+def validate_post_commit(sender, **kwargs):
+    Alert.validate_book(sender.tree.book)
diff --git a/src/alerts/rules.py b/src/alerts/rules.py
new file mode 100644 (file)
index 0000000..c7903f1
--- /dev/null
@@ -0,0 +1,35 @@
+import re
+from django.utils.translation import gettext_lazy as _
+
+
+class Check:
+    def check_meta(self, meta):
+        return False
+
+
+class CheckParse(Check):
+    tag = 'parse'
+    description = _('Book parse error.')
+
+
+class CheckCoverLocal(Check):
+    tag = 'cover-local'
+    description = _('Cover is not local')
+
+    def check_meta(self, meta):
+        print(meta)
+        if meta.cover_source is None:
+            print('no cover_source')
+            return False
+        return not re.match(r'https?://redakcja.wolnelektury.pl/cover/image/', meta.cover_source)
+
+
+rules = [
+    CheckParse(),
+    CheckCoverLocal(),
+]
+
+rules_by_tag = {
+    r.tag: r
+    for r in rules
+}
diff --git a/src/alerts/templatetags/alerts.py b/src/alerts/templatetags/alerts.py
new file mode 100644 (file)
index 0000000..cbab9de
--- /dev/null
@@ -0,0 +1,12 @@
+from django.template import Library
+from ..models import Alert
+
+
+register = Library()
+
+@register.simple_tag
+def get_alerts():
+    return {
+        'count': Alert.objects.all().count(),
+        'items': Alert.objects.all()[:20],
+    }
diff --git a/src/alerts/tests.py b/src/alerts/tests.py
new file mode 100644 (file)
index 0000000..7ce503c
--- /dev/null
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/src/alerts/views.py b/src/alerts/views.py
new file mode 100644 (file)
index 0000000..91ea44a
--- /dev/null
@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.
index 81af893..2d5fe8e 100644 (file)
@@ -2,6 +2,7 @@
 {% load pipeline i18n %}
 {% load static %}
 {% load documents %}
 {% load pipeline i18n %}
 {% load static %}
 {% load documents %}
+{% load alerts %}
 <!DOCTYPE html>
 <html>
 <head lang="{{ LANGUAGE_CODE }}">
 <!DOCTYPE html>
 <html>
 <head lang="{{ LANGUAGE_CODE }}">
     </ul>
 
     <ul class="navbar-nav">
     </ul>
 
     <ul class="navbar-nav">
-        {% include "registration/head_login.html" %}
+
+      {% get_alerts as alerts %}
+      {% if alerts.count %}
+        <div class="nav-item dropdown">
+          <a class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" title="Alert">
+            ðŸ””
+            <span class="badge badge-danger">{{ alerts.count }}</span>
+          </a>
+          <div class="dropdown-menu dropdown-menu-right">
+            {% for alert in alerts.items %}
+              <a class="dropdown-item" href="{{ alert.book.get_absolute_url }}">
+                {{ alert.book }}<br>
+                {{ alert.rule.description }}
+              </a>
+            {% endfor %}
+          </div>
+        </div>
+      {% endif %}
+      {% include "registration/head_login.html" %}
     </ul>
 </nav>
 
     </ul>
 </nav>
 
index 01fb6ce..1325743 100644 (file)
@@ -102,6 +102,7 @@ INSTALLED_APPS = (
     'apiclient',
     'email_mangler',
     'wlxml.apps.WlxmlConfig',
     'apiclient',
     'email_mangler',
     'wlxml.apps.WlxmlConfig',
+    'alerts',
 )
 
 if DEBUG:
 )
 
 if DEBUG: