aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--apioforum/db.py9
-rw-r--r--apioforum/forum.py4
-rw-r--r--apioforum/thread.py7
-rw-r--r--apioforum/webhooks.py134
4 files changed, 152 insertions, 2 deletions
diff --git a/apioforum/db.py b/apioforum/db.py
index c0c8c7e..e0d9056 100644
--- a/apioforum/db.py
+++ b/apioforum/db.py
@@ -206,9 +206,18 @@ ALTER TABLE forums ADD COLUMN unlisted NOT NULL DEFAULT 0;
""",
"""
ALTER TABLE role_config ADD COLUMN p_view_forum INT NOT NULL DEFAULT 1;
+""",
"""
+CREATE TABLE webhooks (
+ id INTEGER PRIMARY KEY,
+ type TEXT NOT NULL,
+ url TEXT NOT NULL,
+ forum INTEGER NOT NULL REFERENCES forums(id),
+ inherits INTEGER NOT NULL DEFAULT 0
+);""",
]
+
def init_db():
db = get_db()
version = db.execute("PRAGMA user_version;").fetchone()[0]
diff --git a/apioforum/forum.py b/apioforum/forum.py
index 87d4022..3d7611b 100644
--- a/apioforum/forum.py
+++ b/apioforum/forum.py
@@ -225,6 +225,10 @@ def create_thread(forum):
(thread_id,g.user,content)
)
db.commit()
+
+ from . import webhooks
+ thread = db.execute("select * from threads where id = ?",(thread_id,)).fetchone()
+ webhooks.do_webhooks_thread(forum['id'],thread)
return redirect(url_for('thread.view_thread',thread_id=thread_id))
flash(err)
diff --git a/apioforum/thread.py b/apioforum/thread.py
index f3bcc59..05abce2 100644
--- a/apioforum/thread.py
+++ b/apioforum/thread.py
@@ -8,6 +8,7 @@ from flask import (
)
from .db import get_db
from .roles import has_permission
+from . import webhooks
from .forum import get_avail_tags
bp = Blueprint("thread", __name__, url_prefix="/thread")
@@ -38,9 +39,9 @@ def which_page(post_id,return_thread_id=False):
else:
return page
-def post_jump(post_id):
+def post_jump(post_id,*,external=False):
page,thread_id=which_page(post_id,True)
- return url_for("thread.view_thread",thread_id=thread_id,page=page)+"#post_"+str(post_id)
+ return url_for("thread.view_thread",thread_id=thread_id,page=page,_external=external)+"#post_"+str(post_id)
@bp.route("/<int:thread_id>")
@bp.route("/<int:thread_id>/page/<int:page>")
@@ -255,6 +256,8 @@ def create_post(thread_id):
(thread_id,)
)
db.commit()
+ post = db.execute("select * from posts where id = ?",(post_id,)).fetchone()
+ webhooks.do_webhooks_post(thread['forum'],post)
flash("post posted postfully")
return redirect(post_jump(post_id))
return redirect(url_for('thread.view_thread',thread_id=thread_id))
diff --git a/apioforum/webhooks.py b/apioforum/webhooks.py
new file mode 100644
index 0000000..2407039
--- /dev/null
+++ b/apioforum/webhooks.py
@@ -0,0 +1,134 @@
+import urllib
+import json
+from .db import get_db
+from flask import url_for, flash
+
+def abridge_post(text):
+ MAXLEN = 20
+ if len(text) > MAXLEN+3:
+ return text[:MAXLEN]+"..."
+ else:
+ return text
+
+def send_discord_webhook(url,payload):
+ headers = {
+ "User-Agent":"apioforum (https://f.gh0.pw/apioforum/, v0.0)",
+ "Content-Type":"application/json",
+ }
+ req = urllib.request.Request(
+ url,
+ json.dumps(payload).encode("utf-8"),
+ headers
+ )
+ # todo: read response and things
+ urllib.request.urlopen(req)
+ #try:
+ # res = urllib.request.urlopen(req)
+ #except urllib.error.HTTPError as e:
+ # print(f"error {e.code} {e.read()}")
+ #else:
+ # print(f"succ {res.read()}")
+
+# todo: object oriented thing for different kinds of webhook (not just discord)
+
+def f(name,value):
+ # discord embed field
+ return {"name":name,"value":value,"inline":True}
+
+def discord_on_new_thread(wh_url, thread):
+ db = get_db()
+ forum = db.execute("select * from forums where id = ?",(thread['forum'],)).fetchone()
+ username = thread['creator']
+ userpage = url_for('user.view_user',username=username,_external=True)
+
+ forumpage = url_for('forum.view_forum',forum_id=forum['id'],_external=True)
+
+ post = db.execute("select * from posts where thread = ? order by id asc limit 1",(thread['id'],)).fetchone()
+
+
+ payload = {
+ "username":"apioforum",
+ "avatar_url":"https://d.gh0.pw/lib/exe/fetch.php?media=wiki:logo.png",
+ "embeds":[
+ {
+ "title":thread['title'],
+ "description":abridge_post(post['content']),
+ "url": url_for('thread.view_thread',thread_id=thread['id'],_external=True),
+ "color": 0xff00ff,
+ "fields":[
+ f('author',f"[{username}]({userpage})"),
+ f('forum',f"[{forum['name']}]({forumpage})"),
+ ],
+ "footer":{
+ "text":thread['created'].isoformat(' '),
+ },
+ },
+ ],
+ }
+ send_discord_webhook(wh_url,payload)
+
+def discord_on_new_post(wh_url, post):
+ from .thread import post_jump
+ db = get_db()
+
+ thread = db.execute("select * from threads where id = ?",(post['thread'],)).fetchone()
+ threadpage = url_for('thread.view_thread',thread_id=thread['id'],_external=True)
+
+ forum = db.execute("select * from forums where id = ?",(thread['forum'],)).fetchone()
+ forumpage = url_for('forum.view_forum',forum_id=forum['id'],_external=True)
+
+ username = post['author']
+ userpage = url_for('user.view_user',username=username,_external=True)
+
+ payload = {
+ "username":"apioforum",
+ "avatar_url":"https://d.gh0.pw/lib/exe/fetch.php?media=wiki:logo.png",
+ "embeds":[
+ {
+ "title":"re: "+thread['title'],
+ "description":abridge_post(post['content']),
+ "url": post_jump(post['id'],external=True),
+ "color": 0x00ffff,
+ "fields":[
+ f('author',f"[{username}]({userpage})"),
+ f('thread',f"[{thread['title']}]({threadpage})"),
+ f('forum',f"[{forum['name']}]({forumpage})"),
+ ],
+ "footer":{
+ "text":post['created'].isoformat(' '),
+ },
+ },
+ ],
+ }
+ send_discord_webhook(wh_url,payload)
+
+def _do_webhooks(forum_id,thing,fn):
+ db = get_db()
+ # todo inheritance
+ webhooks = db.execute("""
+ WITH RECURSIVE fs AS
+ (SELECT * FROM forums WHERE id = ?
+ UNION ALL
+ SELECT forums.* FROM forums, fs WHERE fs.parent=forums.id)
+ SELECT * from webhooks
+ WHERE
+ webhooks.forum = ?
+ OR
+ webhooks.inherits AND webhooks.forum IN (SELECT id FROM fS);
+
+ """,(forum_id,forum_id)).fetchall()
+ for wh in webhooks:
+ wh_url = wh['url']
+ try:
+ fn(wh_url,thing)
+ except:
+ pass # handle probably
+ flash(f"wh {wh['id']}")
+
+def do_webhooks_thread(forum_id,thread):
+ _do_webhooks(forum_id,thread,discord_on_new_thread)
+
+def do_webhooks_post(forum_id,post):
+ _do_webhooks(forum_id,post,discord_on_new_post)
+
+