Merge branch 'feature/webhooks' into 'develop'
Feature: Webhooks See merge request sahkoinsinoorikilta/vtmk/web2.0-backend!53
This commit is contained in:
+1
-1
@@ -54,7 +54,7 @@ lint:py:
|
||||
needs: []
|
||||
script:
|
||||
- pip install black==21.12b0
|
||||
- black --diff .
|
||||
- black --check .
|
||||
|
||||
lint:js:
|
||||
image: node:14
|
||||
|
||||
+1
-2
@@ -1,10 +1,9 @@
|
||||
from django.contrib import admin
|
||||
from modeltranslation.admin import TranslationAdmin
|
||||
|
||||
from kaehmy.models import Application, Comment, CustomRole, PresetRole, TelegramChannel
|
||||
from kaehmy.models import Application, Comment, CustomRole, PresetRole
|
||||
|
||||
admin.site.register(Application)
|
||||
admin.site.register(Comment)
|
||||
admin.site.register(CustomRole)
|
||||
admin.site.register(PresetRole, TranslationAdmin)
|
||||
admin.site.register(TelegramChannel)
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# Generated by Django 2.2.26 on 2022-01-12 20:38
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("kaehmy", "0005_auto_20190312_1458"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.DeleteModel(
|
||||
name="TelegramChannel",
|
||||
),
|
||||
]
|
||||
@@ -162,18 +162,3 @@ class Application(CommentParent):
|
||||
return self.preset_roles.filter(
|
||||
is_board=True
|
||||
).exists() or self.custom_roles.filter(is_board=True)
|
||||
|
||||
|
||||
# Telegram channel entry for Kaehmys
|
||||
class TelegramChannel(models.Model):
|
||||
"""Model containing the channel id of a Telegram chat"""
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Telegram channel")
|
||||
verbose_name_plural = _("Telegram channels")
|
||||
|
||||
name = models.CharField(max_length=255)
|
||||
channel_id = models.CharField(max_length=255, unique=True)
|
||||
|
||||
def __str__(self):
|
||||
return 'Telegram channel: "{}"'.format(self.name)
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
"""
|
||||
A telegram bot api for whatever purposes.
|
||||
TODO: kaehmy app is definitely not correct place for this
|
||||
"""
|
||||
import logging
|
||||
import requests
|
||||
from django.conf import settings
|
||||
from kaehmy.models import TelegramChannel
|
||||
|
||||
|
||||
class TelegramBot:
|
||||
"""
|
||||
A telegram bot api for whatever purposes
|
||||
Currently only able to broadcast stuff to all registered
|
||||
channels using broadcast method.
|
||||
"""
|
||||
|
||||
def __init__(self, api_token=None):
|
||||
|
||||
self.api_token = api_token or settings.TELEGRAM_BOT_TOKEN
|
||||
self.send_message_url = "https://api.telegram.org/bot{}/sendMessage".format(
|
||||
self.api_token
|
||||
)
|
||||
|
||||
def broadcast(self, message):
|
||||
channels_ids = TelegramChannel.objects.values_list("channel_id", flat=True)
|
||||
for id_ in channels_ids:
|
||||
self.send_message(id_, message)
|
||||
|
||||
def send_message(self, channel_id, message):
|
||||
"""
|
||||
Send message to a chat with given channel_id
|
||||
"""
|
||||
data = {"chat_id": channel_id, "text": message, "parse_mode": "Markdown"}
|
||||
resp = requests.post(self.send_message_url, json=data)
|
||||
logging.debug(resp.content)
|
||||
+3
-14
@@ -13,10 +13,11 @@ from dealer.git import git
|
||||
from sikweb.settings import URL
|
||||
|
||||
from members.views.utils import *
|
||||
from kaehmy.models import Application, CustomRole, PresetRole, TelegramChannel
|
||||
from kaehmy.models import Application, CustomRole, PresetRole
|
||||
from kaehmy.forms import ApplicationForm, CommentForm
|
||||
from kaehmy.tables import ExportTable
|
||||
from webapp.utils import send_email
|
||||
from webapp.models import processHooks
|
||||
|
||||
|
||||
@ensure_csrf_cookie
|
||||
@@ -144,19 +145,7 @@ def submit(request, *args, **kwargs):
|
||||
send_email(to_email, subject, email_body)
|
||||
logging.debug(f"Sent kaehmy email to recipient <{to_email}>")
|
||||
|
||||
CHAT_IDS = [channel.channel_id for channel in TelegramChannel.objects.all()]
|
||||
for chat_id in CHAT_IDS:
|
||||
tg_string = (
|
||||
"https://api.telegram.org/bot{}/sendMessage?chat_id={}&text={}".format(
|
||||
settings.TELEGRAM_BOT_TOKEN,
|
||||
chat_id,
|
||||
"Uusi New kaehmy! {} -> {}".format(name, url),
|
||||
)
|
||||
)
|
||||
response = requests.get(tg_string).json()
|
||||
logging.debug("Telegram API response:\n{}".format(response))
|
||||
logging.debug("Sent kaehmy announcement to {} channels.".format(len(CHAT_IDS)))
|
||||
|
||||
processHooks(message=f"Uusi New kaehmy! {name} -> {url}", eventType="kaehmy")
|
||||
else:
|
||||
context = {"error": form.errors}
|
||||
return render(request, "kaehmy:error.html", context)
|
||||
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-01-13 21:55+0200\n"
|
||||
"POT-Creation-Date: 2022-01-13 22:18+0200\n"
|
||||
"PO-Revision-Date: 2017-11-02 23:09+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
@@ -37,7 +37,7 @@ msgstr "Sössö articles"
|
||||
msgid "Today's lunch"
|
||||
msgstr ""
|
||||
|
||||
#: infoscreen/models.py:212 webapp/models.py:70
|
||||
#: infoscreen/models.py:212 webapp/models.py:93
|
||||
msgid "Events"
|
||||
msgstr "Events"
|
||||
|
||||
@@ -113,7 +113,7 @@ msgid "Delete"
|
||||
msgstr "Delete"
|
||||
|
||||
#: infoscreen/templates/tabs/add_remove.html:23 kaehmy/models.py:57
|
||||
#: kaehmy/templates/list.html:36 webapp/models.py:144 webapp/models.py:173
|
||||
#: kaehmy/templates/list.html:36 webapp/models.py:188 webapp/models.py:223
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
@@ -327,7 +327,7 @@ msgstr ""
|
||||
msgid "Custom role name"
|
||||
msgstr ""
|
||||
|
||||
#: kaehmy/models.py:105 webapp/models.py:174
|
||||
#: kaehmy/models.py:105 webapp/models.py:224
|
||||
msgid "Board member"
|
||||
msgstr "Board member"
|
||||
|
||||
@@ -343,14 +343,6 @@ msgstr ""
|
||||
msgid "Official: {}"
|
||||
msgstr ""
|
||||
|
||||
#: kaehmy/models.py:158
|
||||
msgid "Telegram channel"
|
||||
msgstr ""
|
||||
|
||||
#: kaehmy/models.py:159
|
||||
msgid "Telegram channels"
|
||||
msgstr ""
|
||||
|
||||
#: kaehmy/tables.py:13
|
||||
msgid "Roles"
|
||||
msgstr ""
|
||||
@@ -635,6 +627,10 @@ msgid "Hienoa! Jäsenhakemuksesi on nyt lähetetty."
|
||||
msgstr "Amazing! Your membership application has been sent."
|
||||
|
||||
#: members/templates/application_success.html:9
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "Vahvistusviesti on lähetetty sähköpostiisi. Ota yhteyttä "
|
||||
#| "admin@sahkoinsinoorikilta.fi.fi jos viestiä ei näy."
|
||||
msgid ""
|
||||
"Vahvistusviesti on lähetetty sähköpostiisi. Ota yhteyttä "
|
||||
"admin@sahkoinsinoorikilta.fi jos viestiä ei näy."
|
||||
@@ -1104,91 +1100,135 @@ msgstr "Go"
|
||||
msgid "Aalto-yliopiston Sähköinsinöörikilta ry"
|
||||
msgstr "Aalto-yliopiston Sähköinsinöörikilta ry"
|
||||
|
||||
#: webapp/models.py:18
|
||||
#: webapp/models.py:20
|
||||
msgid "Webapp"
|
||||
msgstr "Webapp"
|
||||
|
||||
#: webapp/models.py:26
|
||||
#: webapp/models.py:28
|
||||
msgid "Tag"
|
||||
msgstr "Tag"
|
||||
|
||||
#: webapp/models.py:27
|
||||
#: webapp/models.py:29
|
||||
msgid "Tags"
|
||||
msgstr "Tags"
|
||||
|
||||
#: webapp/models.py:34
|
||||
#: webapp/models.py:36
|
||||
msgid "Tag: {}"
|
||||
msgstr "Tag: {}"
|
||||
|
||||
#: webapp/models.py:52
|
||||
#: webapp/models.py:54
|
||||
msgid "Feed"
|
||||
msgstr ""
|
||||
|
||||
#: webapp/models.py:53
|
||||
#: webapp/models.py:55
|
||||
msgid "Feeds"
|
||||
msgstr ""
|
||||
|
||||
#: webapp/models.py:61 webapp/models.py:80 webapp/models.py:119
|
||||
#: webapp/models.py:152 webapp/models.py:198
|
||||
#: webapp/models.py:63 webapp/models.py:102 webapp/models.py:162
|
||||
#: webapp/models.py:196 webapp/models.py:248
|
||||
msgid "Deleted: "
|
||||
msgstr "Deleted: "
|
||||
|
||||
#: webapp/models.py:62
|
||||
#: webapp/models.py:64
|
||||
msgid "{}Feed: {}"
|
||||
msgstr ""
|
||||
|
||||
#: webapp/models.py:69
|
||||
#: webapp/models.py:92
|
||||
msgid "Event"
|
||||
msgstr ""
|
||||
|
||||
#: webapp/models.py:81
|
||||
#: webapp/models.py:103
|
||||
msgid "{}Event: {}"
|
||||
msgstr ""
|
||||
|
||||
#: webapp/models.py:90
|
||||
#: webapp/models.py:133
|
||||
msgid "Template question"
|
||||
msgstr ""
|
||||
|
||||
#: webapp/models.py:91
|
||||
#: webapp/models.py:134
|
||||
msgid "Template questions"
|
||||
msgstr ""
|
||||
|
||||
#: webapp/models.py:98
|
||||
#: webapp/models.py:141
|
||||
msgid "Template questions: {}"
|
||||
msgstr ""
|
||||
|
||||
#: webapp/models.py:105
|
||||
#: webapp/models.py:148
|
||||
msgid "Signup form"
|
||||
msgstr ""
|
||||
|
||||
#: webapp/models.py:106
|
||||
#: webapp/models.py:149
|
||||
msgid "Signup forms"
|
||||
msgstr ""
|
||||
|
||||
#: webapp/models.py:120
|
||||
#: webapp/models.py:163
|
||||
msgid "#{} {}{}"
|
||||
msgstr ""
|
||||
|
||||
#: webapp/models.py:138
|
||||
#: webapp/models.py:181
|
||||
msgid "Sign-up"
|
||||
msgstr ""
|
||||
|
||||
#: webapp/models.py:139
|
||||
#: webapp/models.py:182
|
||||
msgid "Sign-ups"
|
||||
msgstr ""
|
||||
|
||||
#: webapp/models.py:178
|
||||
#: webapp/models.py:228
|
||||
msgid "board member"
|
||||
msgstr "board member"
|
||||
|
||||
#: webapp/models.py:185
|
||||
#: webapp/models.py:235
|
||||
msgid "JobAd"
|
||||
msgstr ""
|
||||
|
||||
#: webapp/models.py:186
|
||||
#: webapp/models.py:236
|
||||
msgid "JobAds"
|
||||
msgstr ""
|
||||
|
||||
#: webapp/models.py:295
|
||||
#, fuzzy
|
||||
#| msgid "Kaehmy"
|
||||
msgid "Hook Kaehmys"
|
||||
msgstr "Kaehmy"
|
||||
|
||||
#: webapp/models.py:296
|
||||
#, fuzzy
|
||||
#| msgid "Total challenges:"
|
||||
msgid "Hook Ohlhafv challenges"
|
||||
msgstr "Total challenges:"
|
||||
|
||||
#: webapp/models.py:297
|
||||
msgid "Hook published news"
|
||||
msgstr ""
|
||||
|
||||
#: webapp/models.py:298
|
||||
msgid "Hook published Job Ads"
|
||||
msgstr ""
|
||||
|
||||
#: webapp/models.py:299
|
||||
msgid "Hook published events"
|
||||
msgstr ""
|
||||
|
||||
#: webapp/models.py:300
|
||||
msgid "Hook opened signups"
|
||||
msgstr ""
|
||||
|
||||
#: webapp/models.py:325
|
||||
msgid "Webhook"
|
||||
msgstr ""
|
||||
|
||||
#: webapp/models.py:326
|
||||
msgid "Webhooks"
|
||||
msgstr ""
|
||||
|
||||
#: webapp/models.py:339
|
||||
msgid "Telegram channel"
|
||||
msgstr ""
|
||||
|
||||
#: webapp/models.py:340
|
||||
msgid "Telegram channels"
|
||||
msgstr ""
|
||||
|
||||
#: webapp/templates/contact.html:9 webapp/templates/navigation.html:20
|
||||
msgid "Contact"
|
||||
msgstr "Contact"
|
||||
@@ -1232,3 +1272,6 @@ msgstr "Sössö"
|
||||
#: webapp/templates/navigation.html:24
|
||||
msgid "Corporate"
|
||||
msgstr "Corporate"
|
||||
|
||||
#~ msgid "Hallitustyrkkypaneeli"
|
||||
#~ msgstr "Panel for board applicants"
|
||||
|
||||
Binary file not shown.
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-01-13 21:55+0200\n"
|
||||
"POT-Creation-Date: 2022-01-13 22:18+0200\n"
|
||||
"PO-Revision-Date: 2017-11-02 23:04+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
@@ -38,7 +38,7 @@ msgstr "Sössön artikkelit"
|
||||
msgid "Today's lunch"
|
||||
msgstr "Päivän lounas"
|
||||
|
||||
#: infoscreen/models.py:212 webapp/models.py:70
|
||||
#: infoscreen/models.py:212 webapp/models.py:93
|
||||
msgid "Events"
|
||||
msgstr "Tapahtumat"
|
||||
|
||||
@@ -114,7 +114,7 @@ msgid "Delete"
|
||||
msgstr "Poista"
|
||||
|
||||
#: infoscreen/templates/tabs/add_remove.html:23 kaehmy/models.py:57
|
||||
#: kaehmy/templates/list.html:36 webapp/models.py:144 webapp/models.py:173
|
||||
#: kaehmy/templates/list.html:36 webapp/models.py:188 webapp/models.py:223
|
||||
msgid "Name"
|
||||
msgstr "Nimi"
|
||||
|
||||
@@ -328,7 +328,7 @@ msgstr "Teksti"
|
||||
msgid "Custom role name"
|
||||
msgstr "Uusi virka"
|
||||
|
||||
#: kaehmy/models.py:105 webapp/models.py:174
|
||||
#: kaehmy/models.py:105 webapp/models.py:224
|
||||
msgid "Board member"
|
||||
msgstr "Hallituksen jäsen"
|
||||
|
||||
@@ -344,14 +344,6 @@ msgstr "Hallitus: {}"
|
||||
msgid "Official: {}"
|
||||
msgstr "Toimari: {}"
|
||||
|
||||
#: kaehmy/models.py:158
|
||||
msgid "Telegram channel"
|
||||
msgstr "Telegram-kanava"
|
||||
|
||||
#: kaehmy/models.py:159
|
||||
msgid "Telegram channels"
|
||||
msgstr "Telegram-kanavat"
|
||||
|
||||
#: kaehmy/tables.py:13
|
||||
msgid "Roles"
|
||||
msgstr "Roolit"
|
||||
@@ -1014,11 +1006,11 @@ msgstr "Øhlhäfv"
|
||||
|
||||
#: ohlhafv/models.py:22
|
||||
msgid "Ohlhafv challenge"
|
||||
msgstr "Ohlhafv haaste"
|
||||
msgstr "Øhlhäfv-haaste"
|
||||
|
||||
#: ohlhafv/models.py:23
|
||||
msgid "Ohlhafv challenges"
|
||||
msgstr "Ohlhafv haasteet"
|
||||
msgstr "Øhlhäfv-haasteet"
|
||||
|
||||
#: ohlhafv/models.py:29
|
||||
msgid "Team Challenge (1 x 0.33 L, 2 x 0.5 L, 1 x 1.0 L)"
|
||||
@@ -1042,7 +1034,7 @@ msgstr "Sarja"
|
||||
|
||||
#: ohlhafv/models.py:40
|
||||
msgid "Ohlhafv challenge: {} vs. {}"
|
||||
msgstr "Ohlhafv-haaste: {} vs. {}"
|
||||
msgstr "Øhlhäfv-haaste: {} vs. {}"
|
||||
|
||||
#: ohlhafv/templates/email.html:4
|
||||
msgid "on haastanut sinut oluenjuontimittelöön"
|
||||
@@ -1093,91 +1085,131 @@ msgstr "Vaihda"
|
||||
msgid "Aalto-yliopiston Sähköinsinöörikilta ry"
|
||||
msgstr "Aalto-yliopiston Sähköinsinöörikilta ry"
|
||||
|
||||
#: webapp/models.py:18
|
||||
#: webapp/models.py:20
|
||||
msgid "Webapp"
|
||||
msgstr "Nettisivut"
|
||||
|
||||
#: webapp/models.py:26
|
||||
#: webapp/models.py:28
|
||||
msgid "Tag"
|
||||
msgstr "Tunniste"
|
||||
|
||||
#: webapp/models.py:27
|
||||
#: webapp/models.py:29
|
||||
msgid "Tags"
|
||||
msgstr "Tunnisteet"
|
||||
|
||||
#: webapp/models.py:34
|
||||
#: webapp/models.py:36
|
||||
msgid "Tag: {}"
|
||||
msgstr "Tunniste: {}"
|
||||
|
||||
#: webapp/models.py:52
|
||||
#: webapp/models.py:54
|
||||
msgid "Feed"
|
||||
msgstr "Uutinen"
|
||||
|
||||
#: webapp/models.py:53
|
||||
#: webapp/models.py:55
|
||||
msgid "Feeds"
|
||||
msgstr "Uutiset"
|
||||
|
||||
#: webapp/models.py:61 webapp/models.py:80 webapp/models.py:119
|
||||
#: webapp/models.py:152 webapp/models.py:198
|
||||
#: webapp/models.py:63 webapp/models.py:102 webapp/models.py:162
|
||||
#: webapp/models.py:196 webapp/models.py:248
|
||||
msgid "Deleted: "
|
||||
msgstr "Poistettu: "
|
||||
|
||||
#: webapp/models.py:62
|
||||
#: webapp/models.py:64
|
||||
msgid "{}Feed: {}"
|
||||
msgstr "{}Uutinen: {}"
|
||||
|
||||
#: webapp/models.py:69
|
||||
#: webapp/models.py:92
|
||||
msgid "Event"
|
||||
msgstr "Tapahtuma"
|
||||
|
||||
#: webapp/models.py:81
|
||||
#: webapp/models.py:103
|
||||
msgid "{}Event: {}"
|
||||
msgstr "{}Tapahtuma: {}"
|
||||
|
||||
#: webapp/models.py:90
|
||||
#: webapp/models.py:133
|
||||
msgid "Template question"
|
||||
msgstr "Vakiokysymys"
|
||||
|
||||
#: webapp/models.py:91
|
||||
#: webapp/models.py:134
|
||||
msgid "Template questions"
|
||||
msgstr "Vakiokysymykset"
|
||||
|
||||
#: webapp/models.py:98
|
||||
#: webapp/models.py:141
|
||||
msgid "Template questions: {}"
|
||||
msgstr "Vakiokysymykset: {}"
|
||||
|
||||
#: webapp/models.py:105
|
||||
#: webapp/models.py:148
|
||||
msgid "Signup form"
|
||||
msgstr "Ilmoittautumislomake"
|
||||
|
||||
#: webapp/models.py:106
|
||||
#: webapp/models.py:149
|
||||
msgid "Signup forms"
|
||||
msgstr "Ilmoittautumislomakkeet"
|
||||
|
||||
#: webapp/models.py:120
|
||||
#: webapp/models.py:163
|
||||
msgid "#{} {}{}"
|
||||
msgstr ""
|
||||
|
||||
#: webapp/models.py:138
|
||||
#: webapp/models.py:181
|
||||
msgid "Sign-up"
|
||||
msgstr "Ilmoittautuminen"
|
||||
|
||||
#: webapp/models.py:139
|
||||
#: webapp/models.py:182
|
||||
msgid "Sign-ups"
|
||||
msgstr "Ilmoittautumiset"
|
||||
|
||||
#: webapp/models.py:178
|
||||
#: webapp/models.py:228
|
||||
msgid "board member"
|
||||
msgstr "hallituksen jäsen"
|
||||
|
||||
#: webapp/models.py:185
|
||||
#: webapp/models.py:235
|
||||
msgid "JobAd"
|
||||
msgstr "Työpaikkailmoitus"
|
||||
|
||||
#: webapp/models.py:186
|
||||
#: webapp/models.py:236
|
||||
msgid "JobAds"
|
||||
msgstr "Työpaikkailmoitukset"
|
||||
|
||||
#: webapp/models.py:295
|
||||
msgid "Hook Kaehmys"
|
||||
msgstr "Lähetä Kähmyt"
|
||||
|
||||
#: webapp/models.py:296
|
||||
msgid "Hook Ohlhafv challenges"
|
||||
msgstr "Lähetä Øhlhäfv-haasteet"
|
||||
|
||||
#: webapp/models.py:297
|
||||
msgid "Hook published news"
|
||||
msgstr "Lähetä julkaistut uutiset"
|
||||
|
||||
#: webapp/models.py:298
|
||||
msgid "Hook published Job Ads"
|
||||
msgstr "Lähetä työpaikkailmoitukset"
|
||||
|
||||
#: webapp/models.py:299
|
||||
msgid "Hook published events"
|
||||
msgstr "Lähetä julkaistut tapahtumat"
|
||||
|
||||
#: webapp/models.py:300
|
||||
msgid "Hook opened signups"
|
||||
msgstr "Lähetä auenneet ilmot"
|
||||
|
||||
#: webapp/models.py:325
|
||||
msgid "Webhook"
|
||||
msgstr "Webhook"
|
||||
|
||||
#: webapp/models.py:326
|
||||
msgid "Webhooks"
|
||||
msgstr "Webhookit"
|
||||
|
||||
#: webapp/models.py:339
|
||||
msgid "Telegram channel"
|
||||
msgstr "Telegram-kanava"
|
||||
|
||||
#: webapp/models.py:340
|
||||
msgid "Telegram channels"
|
||||
msgstr "Telegram-kanavat"
|
||||
|
||||
#: webapp/templates/contact.html:9 webapp/templates/navigation.html:20
|
||||
msgid "Contact"
|
||||
msgstr "Yhteystiedot"
|
||||
|
||||
+5
-8
@@ -1,5 +1,3 @@
|
||||
"""Ohlhafv views."""
|
||||
|
||||
import logging
|
||||
from django.shortcuts import render
|
||||
from django.views.decorators.http import require_http_methods
|
||||
@@ -8,12 +6,12 @@ from django.http import HttpResponseRedirect
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.template.loader import render_to_string
|
||||
|
||||
from sikweb.settings import URL
|
||||
|
||||
from ohlhafv.models import OhlhafvChallenge
|
||||
from ohlhafv.forms import OhlhafvForm
|
||||
from kaehmy.tgbot import TelegramBot
|
||||
from webapp.utils import send_email
|
||||
from sikweb.settings import URL
|
||||
from webapp.models import processHooks
|
||||
|
||||
|
||||
@require_http_methods(["GET"])
|
||||
@@ -47,12 +45,11 @@ def ohlhafv_submit(request, *args, **kwargs):
|
||||
logging.debug(f"Sent ohlhafv email to recipient <{to_email}>")
|
||||
|
||||
try:
|
||||
tg_message = render_to_string(
|
||||
webhook_message = render_to_string(
|
||||
"ohlhafv:tgmsg.tpl", {"challenge": challenge, "url": url}
|
||||
)
|
||||
bot = TelegramBot()
|
||||
bot.broadcast(tg_message)
|
||||
except Exception: # tg spam is not critical. Ignore on failure
|
||||
processHooks(message=webhook_message, eventType="ohlhafv")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
else:
|
||||
|
||||
Generated
+15
@@ -269,6 +269,17 @@ phonenumbers = {version = ">=7.0.2", optional = true, markers = "extra == \"phon
|
||||
phonenumbers = ["phonenumbers (>=7.0.2)"]
|
||||
phonenumberslite = ["phonenumberslite (>=7.0.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "django-polymorphic"
|
||||
version = "3.1.0"
|
||||
description = "Seamless polymorphic inheritance for Django models"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
Django = ">=2.1"
|
||||
|
||||
[[package]]
|
||||
name = "django-suit"
|
||||
version = "0.2.28"
|
||||
@@ -974,6 +985,10 @@ django-phonenumber-field = [
|
||||
{file = "django-phonenumber-field-4.0.0.tar.gz", hash = "sha256:d4580cc3352f4433962825f9927e6669852c1b40ec484fcb5a74064dabc1201a"},
|
||||
{file = "django_phonenumber_field-4.0.0-py3-none-any.whl", hash = "sha256:2ca3bb0ada0ebc164bd903a981a34f1202a4294006e520b0da961bd7ce9f20a4"},
|
||||
]
|
||||
django-polymorphic = [
|
||||
{file = "django-polymorphic-3.1.0.tar.gz", hash = "sha256:d6955b5308bf6e41dcb22ba7c96f00b51dfa497a8a5ab1e9c06c7951bf417bf8"},
|
||||
{file = "django_polymorphic-3.1.0-py3-none-any.whl", hash = "sha256:08bc4f4f4a773a19b2deced5a56deddd1ef56ebd15207bf4052e2901c25ef57e"},
|
||||
]
|
||||
django-suit = [
|
||||
{file = "django-suit-0.2.28.tar.gz", hash = "sha256:bacd8a079fcc08deb6efd0d7f60241e3c319526939ae1abe8ccfbc1b03e97104"},
|
||||
{file = "django_suit-0.2.28-py2.py3-none-any.whl", hash = "sha256:256412597ac8e9461780542eebb12b37f65ff702bf23de23d07d245510c64ff2"},
|
||||
|
||||
@@ -37,6 +37,7 @@ gunicorn = "^20.1.0"
|
||||
Pillow = "^8.4.0"
|
||||
sendgrid = "^6.7.0"
|
||||
sentry-sdk = "^1.4.3"
|
||||
django-polymorphic = "^3.1.0"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
coverage = "^5.5"
|
||||
|
||||
+14
-1
@@ -1,7 +1,18 @@
|
||||
"""File containing webapp app admin registers."""
|
||||
|
||||
from django.contrib import admin
|
||||
from webapp.models import Feed, Tag, Event, Signup, SignupForm, TemplateQuestion, JobAd
|
||||
from webapp.models import (
|
||||
Feed,
|
||||
Tag,
|
||||
Event,
|
||||
Signup,
|
||||
SignupForm,
|
||||
TemplateQuestion,
|
||||
JobAd,
|
||||
BaseWebhook,
|
||||
GenericWebhook,
|
||||
TelegramHook,
|
||||
)
|
||||
from modeltranslation.admin import TranslationAdmin
|
||||
from django.contrib.auth.models import Permission
|
||||
|
||||
@@ -17,3 +28,5 @@ admin.site.register(SignupForm, TranslationAdmin)
|
||||
admin.site.register(Signup, TranslationAdmin)
|
||||
admin.site.register(TemplateQuestion, TranslationAdmin)
|
||||
admin.site.register(JobAd, TranslationAdmin)
|
||||
admin.site.register(GenericWebhook, TranslationAdmin)
|
||||
admin.site.register(TelegramHook, TranslationAdmin)
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
# Generated by Django 2.2.26 on 2022-01-12 21:32
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("contenttypes", "0002_remove_content_type_name"),
|
||||
("webapp", "0077_templatequestion_deleted"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="BaseWebhook",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("name", models.CharField(max_length=255)),
|
||||
("url", models.URLField()),
|
||||
("kaehmy_submit", models.BooleanField(default=False)),
|
||||
("ohlhafv_submit", models.BooleanField(default=False)),
|
||||
("feed_published", models.BooleanField(default=False)),
|
||||
("jobad_published", models.BooleanField(default=False)),
|
||||
("event_published", models.BooleanField(default=False)),
|
||||
("signup_opened", models.BooleanField(default=False)),
|
||||
(
|
||||
"polymorphic_ctype",
|
||||
models.ForeignKey(
|
||||
editable=False,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
related_name="polymorphic_webapp.basewebhook_set+",
|
||||
to="contenttypes.ContentType",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"abstract": False,
|
||||
"base_manager_name": "objects",
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="TelegramHook",
|
||||
fields=[
|
||||
(
|
||||
"basewebhook_ptr",
|
||||
models.OneToOneField(
|
||||
auto_created=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
parent_link=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
to="webapp.BaseWebhook",
|
||||
),
|
||||
),
|
||||
("channel_id", models.CharField(max_length=255, unique=True)),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "Telegram channel",
|
||||
"verbose_name_plural": "Telegram channels",
|
||||
},
|
||||
bases=("webapp.basewebhook",),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="GenericWebhook",
|
||||
fields=[],
|
||||
options={
|
||||
"verbose_name": "Webhook",
|
||||
"verbose_name_plural": "Webhooks",
|
||||
"proxy": True,
|
||||
"indexes": [],
|
||||
"constraints": [],
|
||||
},
|
||||
bases=("webapp.basewebhook",),
|
||||
),
|
||||
]
|
||||
+153
-9
@@ -1,20 +1,21 @@
|
||||
"""Webapp app models."""
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import models
|
||||
from django.template.loader import render_to_string
|
||||
from django.utils import timezone
|
||||
|
||||
# from datetime import timedelta
|
||||
from django.contrib.auth.models import User
|
||||
from django.db.models.signals import post_save
|
||||
from django.dispatch import receiver
|
||||
from webapp.utils import month_from_now, send_signup_email
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from auditlog.registry import auditlog
|
||||
from phonenumber_field.modelfields import PhoneNumberField
|
||||
from django.contrib.postgres.fields import JSONField
|
||||
|
||||
# from datetime import timedelta
|
||||
import requests
|
||||
from uuid import uuid4
|
||||
import logging
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.contrib.postgres.fields import JSONField
|
||||
from auditlog.registry import auditlog
|
||||
from polymorphic.models import PolymorphicModel
|
||||
from webapp.utils import month_from_now, send_signup_email
|
||||
from sikweb.settings import FRONTEND_URL
|
||||
|
||||
VERBOSE_NAME = _("Webapp")
|
||||
EMAIL_REGEX = r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)"
|
||||
@@ -62,6 +63,27 @@ class Feed(BaseFeed):
|
||||
delete_str = _("Deleted: ") if self.deleted else ""
|
||||
return _("{}Feed: {}").format(delete_str, self.title)
|
||||
|
||||
__previousVisible = False
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Feed, self).__init__(*args, **kwargs)
|
||||
self.__previousVisible = self.visible
|
||||
|
||||
def save(self, force_insert=False, force_update=False, *args, **kwargs):
|
||||
created = self.pk is None
|
||||
super(Feed, self).save(force_insert, force_update, *args, **kwargs)
|
||||
|
||||
if self.visible and (created or not self.__previousVisible):
|
||||
self.refresh_from_db() # Fetch so we can use primary key
|
||||
url = f"https://{FRONTEND_URL}/feed/{self.pk}"
|
||||
processHooks(
|
||||
message=generateMessage(
|
||||
"Uusi uutinen", self.title, self.description, url
|
||||
),
|
||||
eventType="feed",
|
||||
)
|
||||
self.__previousVisible = self.visible
|
||||
|
||||
|
||||
class Event(BaseFeed):
|
||||
"""Model for event in guild calendar"""
|
||||
@@ -80,6 +102,27 @@ class Event(BaseFeed):
|
||||
delete_str = _("Deleted: ") if self.deleted else ""
|
||||
return _("{}Event: {}").format(delete_str, self.title)
|
||||
|
||||
__previousVisible = False
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Event, self).__init__(*args, **kwargs)
|
||||
self.__previousVisible = self.visible
|
||||
|
||||
def save(self, force_insert=False, force_update=False, *args, **kwargs):
|
||||
created = self.pk is None
|
||||
super(Event, self).save(force_insert, force_update, *args, **kwargs)
|
||||
|
||||
if self.visible and (created or not self.__previousVisible):
|
||||
self.refresh_from_db() # Fetch so we can use primary key
|
||||
url = f"https://{FRONTEND_URL}/events/{self.pk}"
|
||||
processHooks(
|
||||
message=generateMessage(
|
||||
"Uusi tapahtuma", self.title, self.description, url
|
||||
),
|
||||
eventType="event",
|
||||
)
|
||||
self.__previousVisible = self.visible
|
||||
|
||||
|
||||
class TemplateQuestion(models.Model):
|
||||
"""
|
||||
@@ -205,6 +248,105 @@ class JobAd(models.Model):
|
||||
delete_str = _("Deleted: ") if self.deleted else ""
|
||||
return f"{delete_str}{self.title}"
|
||||
|
||||
__previousVisible = False
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(JobAd, self).__init__(*args, **kwargs)
|
||||
self.__previousVisible = self.visible
|
||||
|
||||
def save(self, force_insert=False, force_update=False, *args, **kwargs):
|
||||
created = self.pk is None
|
||||
super(JobAd, self).save(force_insert, force_update, *args, **kwargs)
|
||||
|
||||
if self.visible and (created or not self.__previousVisible):
|
||||
self.refresh_from_db() # Fetch so we can use primary key
|
||||
url = f"https://{FRONTEND_URL}/jobads/{self.pk}"
|
||||
processHooks(
|
||||
message=generateMessage(
|
||||
"Uusi työpaikkailmoitus", self.title, self.description, url
|
||||
),
|
||||
eventType="jobad",
|
||||
)
|
||||
self.__previousVisible = self.visible
|
||||
|
||||
|
||||
def generateMessage(heading: str, title: str, description: str, url: str):
|
||||
return render_to_string(
|
||||
"webapp:tg_message.tpl",
|
||||
{"heading": heading, "title": title, "description": description, "url": url},
|
||||
)
|
||||
|
||||
|
||||
def processHooks(message: str, eventType: str):
|
||||
allHooks = BaseWebhook.objects.all()
|
||||
for hook in list(allHooks):
|
||||
if hook.plugs[eventType] is True:
|
||||
hook.broadcast(message)
|
||||
|
||||
|
||||
class BaseWebhook(PolymorphicModel):
|
||||
"""Webhook base class instance"""
|
||||
|
||||
name = models.CharField(max_length=255)
|
||||
url = (
|
||||
models.URLField()
|
||||
) # URL where webhook message is broadcast. For example Telegram webhook API
|
||||
# "Plugs"; which notifications are sent to this specific webhook instance
|
||||
kaehmy_submit = models.BooleanField(_("Hook Kaehmys"), default=False)
|
||||
ohlhafv_submit = models.BooleanField(_("Hook Ohlhafv challenges"), default=False)
|
||||
feed_published = models.BooleanField(_("Hook published news"), default=False)
|
||||
jobad_published = models.BooleanField(_("Hook published Job Ads"), default=False)
|
||||
event_published = models.BooleanField(_("Hook published events"), default=False)
|
||||
signup_opened = models.BooleanField(_("Hook opened signups"), default=False)
|
||||
|
||||
@property
|
||||
def plugs(self):
|
||||
return {
|
||||
"kaehmy": self.kaehmy_submit,
|
||||
"ohlhafv": self.ohlhafv_submit,
|
||||
"feed": self.feed_published,
|
||||
"jobad": self.jobad_published,
|
||||
"event": self.event_published,
|
||||
"signup": self.signup_opened,
|
||||
}
|
||||
|
||||
def parseData(self):
|
||||
pass
|
||||
|
||||
def broadcast(self, message):
|
||||
resp = requests.post(self.url, json=self.parseData(message))
|
||||
logging.debug(f"Webhook API response: HTTP{resp.status_code}")
|
||||
logging.debug(resp.content)
|
||||
|
||||
|
||||
class GenericWebhook(BaseWebhook):
|
||||
class Meta:
|
||||
proxy = True
|
||||
verbose_name = _("Webhook")
|
||||
verbose_name_plural = _("Webhooks")
|
||||
|
||||
def __str__(self):
|
||||
return 'Webhook "{}"'.format(self.name)
|
||||
|
||||
def parseData(self, message):
|
||||
return {"text": message}
|
||||
|
||||
|
||||
class TelegramHook(BaseWebhook):
|
||||
"""Model containing the channel id of a Telegram chat"""
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("Telegram channel")
|
||||
verbose_name_plural = _("Telegram channels")
|
||||
|
||||
channel_id = models.CharField(max_length=255, unique=True)
|
||||
|
||||
def __str__(self):
|
||||
return 'Telegram channel: "{}"'.format(self.name)
|
||||
|
||||
def parseData(self, message):
|
||||
return {"text": message, "chat_id": self.channel_id, "parse_mode": "Markdown"}
|
||||
|
||||
|
||||
auditlog.register(Tag)
|
||||
auditlog.register(Feed)
|
||||
@@ -212,3 +354,5 @@ auditlog.register(Event)
|
||||
auditlog.register(SignupForm)
|
||||
auditlog.register(Signup)
|
||||
auditlog.register(JobAd)
|
||||
auditlog.register(GenericWebhook)
|
||||
auditlog.register(TelegramHook)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
{{ heading }}: {{ title }}
|
||||
====================
|
||||
{{ description }}
|
||||
|
||||
Lisätietoa osoitteessa: {{ url }}
|
||||
@@ -46,3 +46,18 @@ class JobAdTranslationOptions(TranslationOptions):
|
||||
"description",
|
||||
"content",
|
||||
)
|
||||
|
||||
|
||||
@register(BaseWebhook)
|
||||
class BaseWebhookOptions(TranslationOptions):
|
||||
fields = ()
|
||||
|
||||
|
||||
@register(GenericWebhook)
|
||||
class GenericWebhookOptions(TranslationOptions):
|
||||
fields = ()
|
||||
|
||||
|
||||
@register(TelegramHook)
|
||||
class TelegramHookTranslationOptions(TranslationOptions):
|
||||
fields = ()
|
||||
|
||||
Reference in New Issue
Block a user