mirror of
https://github.com/Lynnesbian/FediBooks/
synced 2024-11-25 16:48:58 +00:00
Compare commits
No commits in common. "8f476ca9818f45711fc707afa9a7fe474472e650" and "c060f8d7caa2820ecba58fb32ed9758fdabc479c" have entirely different histories.
8f476ca981
...
c060f8d7ca
11 changed files with 69 additions and 217 deletions
16
setup.sql
16
setup.sql
|
@ -15,9 +15,10 @@ CREATE TABLE IF NOT EXISTS `credentials` (
|
|||
`secret` VARCHAR(128) NOT NULL
|
||||
) ENGINE=INNODB;
|
||||
CREATE TABLE IF NOT EXISTS `bots` (
|
||||
`handle` VARCHAR(128) PRIMARY KEY,
|
||||
`id` BINARY(64) PRIMARY KEY,
|
||||
`user_id` INT NOT NULL,
|
||||
`credentials_id` INT NOT NULL,
|
||||
`handle` VARCHAR(128) NOT NULL,
|
||||
`enabled` BOOLEAN DEFAULT 1,
|
||||
`replies_enabled` BOOLEAN DEFAULT 1,
|
||||
`post_frequency` SMALLINT UNSIGNED DEFAULT 30,
|
||||
|
@ -36,16 +37,15 @@ CREATE TABLE IF NOT EXISTS `bots` (
|
|||
CREATE TABLE IF NOT EXISTS `fedi_accounts` (
|
||||
`handle` VARCHAR(128) PRIMARY KEY,
|
||||
`outbox` VARCHAR(256),
|
||||
`credentials_id` INT,
|
||||
`credentials_id` INT NOT NULL,
|
||||
`icon` VARCHAR(512),
|
||||
`icon_update_time` DATETIME DEFAULT 0,
|
||||
FOREIGN KEY (`credentials_id`) REFERENCES credentials(id) ON DELETE CASCADE
|
||||
) ENGINE=INNODB;
|
||||
CREATE TABLE IF NOT EXISTS `bot_learned_accounts` (
|
||||
`bot_id` VARCHAR(128) NOT NULL,
|
||||
`bot_id` BINARY(64) NOT NULL,
|
||||
`fedi_id` VARCHAR(128) NOT NULL,
|
||||
`enabled` BOOLEAN DEFAULT 1,
|
||||
FOREIGN KEY (`bot_id`) REFERENCES bots(handle) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`bot_id`) REFERENCES bots(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`fedi_id`) REFERENCES fedi_accounts(handle) ON DELETE CASCADE
|
||||
) ENGINE=INNODB;
|
||||
CREATE TABLE IF NOT EXISTS `posts` (
|
||||
|
@ -54,14 +54,14 @@ CREATE TABLE IF NOT EXISTS `posts` (
|
|||
`post_id` VARCHAR(64) NOT NULL,
|
||||
`content` TEXT NOT NULL,
|
||||
`cw` BOOLEAN NOT NULL,
|
||||
FOREIGN KEY (`fedi_id`) REFERENCES fedi_accounts(handle) ON DELETE CASCADE
|
||||
FOREIGN KEY (`fedi_id`) REFERENCES fedi_account(handle) ON DELETE CASCADE
|
||||
) ENGINE=INNODB;
|
||||
CREATE TABLE IF NOT EXISTS `word_blacklist` (
|
||||
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||
`bot_id` VARCHAR(128) NOT NULL,
|
||||
`bot_id` BINARY(64) NOT NULL,
|
||||
`phrase` VARCHAR(128) NOT NULL,
|
||||
`whole_word` BOOLEAN NOT NULL,
|
||||
FOREIGN KEY (`bot_id`) REFERENCES bots(handle) ON DELETE CASCADE
|
||||
FOREIGN KEY (`bot_id`) REFERENCES bots(id) ON DELETE CASCADE
|
||||
) ENGINE=INNODB;
|
||||
CREATE TABLE IF NOT EXISTS `contact_history` (
|
||||
`user_id` INT NOT NULL,
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 3.8 KiB |
|
@ -10,7 +10,7 @@ body {
|
|||
|
||||
.container {
|
||||
background-color: #444a5c;
|
||||
padding: 10px;
|
||||
padding:10px;
|
||||
}
|
||||
.light {
|
||||
background-color: #4d5366;
|
||||
|
@ -26,9 +26,6 @@ body {
|
|||
.small {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
.tiny {
|
||||
font-size: 0.5em;
|
||||
}
|
||||
.centred {
|
||||
text-align: center;
|
||||
}
|
||||
|
@ -48,11 +45,7 @@ body {
|
|||
.panel-icon {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: center/contain url("/img/bot_generic.png");
|
||||
}
|
||||
.panel-icon.large {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
background: center/contain url("https://cloud.lynnesbian.space/s/JZCPTs3DzMLAspC/preview");
|
||||
}
|
||||
.panel-icon.online, .panel-icon.offline {
|
||||
width: 105px;
|
||||
|
@ -81,20 +74,20 @@ body {
|
|||
|
||||
.button {
|
||||
color: white;
|
||||
line-height: 1.2em;
|
||||
padding: 10px;
|
||||
line-height:1.2em;
|
||||
padding:10px;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
margin: 5px 0;
|
||||
transition: 0.2s linear;
|
||||
border: none;
|
||||
border:none;
|
||||
}
|
||||
.button:visited {
|
||||
color: white;
|
||||
color:white;
|
||||
}
|
||||
input.button, button.button {
|
||||
font-size: 1em;
|
||||
cursor: pointer;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
|
@ -129,7 +122,7 @@ a {
|
|||
text-decoration: none;
|
||||
}
|
||||
a:visited {
|
||||
color: mediumpurple;
|
||||
color: white;
|
||||
}
|
||||
|
||||
h1 {
|
||||
|
@ -142,17 +135,17 @@ h1, h2, h3, h4, h5, h6 {
|
|||
}
|
||||
|
||||
form {
|
||||
display: inline-block;
|
||||
display:inline-block;
|
||||
}
|
||||
label.important {
|
||||
font-size: 1.4em;
|
||||
margin: 10px 0;
|
||||
font-weight: 300;
|
||||
display: block;
|
||||
display:block;
|
||||
}
|
||||
input, select {
|
||||
font-size: 1.2em;
|
||||
line-height: 1.4em;
|
||||
line-height:1.4em;
|
||||
border: 3px grey solid;
|
||||
border-radius: none;
|
||||
padding: 3px;
|
||||
|
@ -171,10 +164,3 @@ label {
|
|||
form .row {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.coming-soon {
|
||||
height: 200px;
|
||||
width: 200px;
|
||||
background: center/contain url("https://lynnesbian.space/img/bune.png");
|
||||
display: inline-block;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<body>
|
||||
<div class="container centred">
|
||||
<h1 class="thin centred">Set accounts to learn from</h1>
|
||||
<p class="large centred">{{ handle }}</p>
|
||||
<p class="large centred">@botname@example.com</p>
|
||||
<p class="centred" style="margin: 50px 0;">
|
||||
<a class="button btn-primary btn-large" href="/bot/accounts/add" role="button"><i class="fas fa-plus"></i> Add account</a>
|
||||
<a class="button btn-secondary btn-large" href="/" role="button"><i class="fas fa-arrow-left"></i> Back</a>
|
||||
|
@ -17,19 +17,16 @@
|
|||
</div>
|
||||
|
||||
<div class="container" style="min-height: 300px;">
|
||||
{% for user in users %}
|
||||
<div class="row light">
|
||||
<div class="panel-icon {{ "online" if user['enabled'] else "offline" }}"></div>
|
||||
<div class="panel-icon"></div>
|
||||
<div class="panel-text">
|
||||
{% set handle_list = user['fedi_id'].split('@') %}
|
||||
<div class="panel-name">@{{ handle_list[1] }}<span class="subtle tiny">@{{ handle_list[2] }}</span></div>
|
||||
<div class="panel-status">{{ "Active" if user['enabled'] else "Inactive" }}</div>
|
||||
<div class="panel-name">@user<span class="subtle">@instan.ce</span></div>
|
||||
<div class="panel-status">12345 posts stored</div>
|
||||
</div>
|
||||
<div class="panel-actions">
|
||||
<a class="button btn-secondary" href="/bot/accounts/toggle/{{ user['fedi_id'] }}" title="Turn on/off"><i class="fas fa-power-off"></i></a><a class="button btn-dangerous" href="/bot/accounts/delete/{{ user['fedi_id'] }}" title="Delete"><i class="fas fa-trash"></i></a>
|
||||
<a class="button btn-secondary" href="/bot/accounts/toggle/insert id here" title="Turn on/off"><i class="fas fa-power-off"></i></a><a class="button btn-dangerous" href="/bot/accounts/delete/insert id here" title="Delete"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% include 'footer.html' %}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
<body>
|
||||
<div class="container">
|
||||
<h1 class="thin centred">Add account</h1>
|
||||
<p class="large thin centred">Step {{ session['step'] }}</p>
|
||||
</div>
|
||||
|
||||
<div class="container centred">
|
||||
|
@ -37,7 +38,7 @@
|
|||
<div class="container centred">
|
||||
<a href="/" class="button btn-secondary"><i class="fas fa-times"></i> Cancel</a>
|
||||
{% if session['step'] != 1 %}
|
||||
<a href="/bot/accounts/add/back" class="button btn-secondary"><i class="fas fa-arrow-left"></i> Back</a>
|
||||
<button class="button btn-secondary"><i class="fas fa-arrow-left"></i> Back</button>
|
||||
{% endif %}
|
||||
<button class="button btn-primary"><i class="fas fa-arrow-right"></i> Next</button>
|
||||
</div>
|
||||
|
|
|
@ -40,9 +40,9 @@
|
|||
<div class="container centred">
|
||||
<a href="/" class="button btn-secondary"><i class="fas fa-times"></i> Cancel</a>
|
||||
{% if session['step'] != 1 %}
|
||||
<a href="/bot/create/back" class="button btn-secondary"><i class="fas fa-arrow-left"></i> Back</a>
|
||||
<button class="button btn-secondary"><i class="fas fa-arrow-left"></i> Back</button>
|
||||
{% endif %}
|
||||
{% if session['step'] < 4 %}
|
||||
{% if session['step'] < 5 %}
|
||||
<button class="button btn-primary"><i class="fas fa-arrow-right"></i> Next</button>
|
||||
{% else %}
|
||||
<a href="/" class="button btn-primary"><i class="fas fa-check"></i> Finish</a>
|
||||
|
|
|
@ -9,14 +9,14 @@
|
|||
<body>
|
||||
<div class="container centred">
|
||||
<h1 class="thin centred">Delete bot</h1>
|
||||
<div class="panel-icon"></div>
|
||||
</div>
|
||||
|
||||
<div class="container centred">
|
||||
<form method='POST'>
|
||||
<div class="panel-icon large"></div>
|
||||
<form>
|
||||
<div class="container centred">
|
||||
<p>Are you sure you want to <strong>permanently</strong> delete this bot?</p>
|
||||
<p>The account on {{ instance }} will remain open, but your bot will stop posting from it.</p>
|
||||
<p>Are you sure you want to <strong>permanently</strong> delete bot name?</p>
|
||||
<p>The account on instan.ce will remain open, but your bot will stop posting from it.</p>
|
||||
<a class="button btn-secondary" href="/"><i class="fas fa-times"></i> Cancel</a>
|
||||
<button class="button btn-dangerous"><i class="fas fa-trash"></i> Delete bot</button>
|
||||
</div>
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>FediBooks</title>
|
||||
{% include 'imports.html' %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container centred light">
|
||||
<h1 class="thin centred">Coming soon!</h1>
|
||||
<div class="coming-soon"></div>
|
||||
<br>
|
||||
<a href="/" class="button btn-primary large"><i class="fas fa-home"></i> Home</a>
|
||||
</div>
|
||||
|
||||
{% include 'footer.html' %}
|
||||
</body>
|
||||
</html>
|
|
@ -19,14 +19,13 @@
|
|||
<div class="container" style="min-height: 300px;">
|
||||
{% for bot in bots %}
|
||||
<div class="row light">
|
||||
<div class="panel-icon {{ "online" if bot['enabled'] else "offline"}}"></div>
|
||||
<div class="panel-icon {% if bot['enabled'] %}online{% else %}offline{% endif %}"></div>
|
||||
<div class="panel-text">
|
||||
{% set handle_list = bot['handle'].split('@') %}
|
||||
<div class="panel-name">@{{ handle_list[1] }}<span class="subtle tiny">@{{ handle_list[2] }}</span></div>
|
||||
<div class="panel-status">{{ "Online" if bot['enabled'] else "Offline"}}, learning from {{ bot_users[bot['handle']] }} accounts</div>
|
||||
<div class="panel-name">{{ bot['handle'] }}</div>
|
||||
<div class="panel-status">{% if bot['enabled'] %}Online{% else %}Offline{% endif %}, learning from {{ bot_users[bot['id']] }} accounts</div>
|
||||
</div>
|
||||
<div class="panel-actions">
|
||||
<a class="button btn-secondary" href="/bot/toggle/{{ bot['handle'] }}" title="Turn on/off"><i class="fas fa-power-off"></i></a><a class="button btn-secondary" href="/bot/edit/{{ bot['handle'] }}" title="Configure"><i class="fas fa-cog"></i></a><a class="button btn-secondary" href="/bot/accounts/{{ bot['handle'] }}" title="Accounts learned from"><i class="fas fa-users"></i></a><a class="button btn-secondary" href="/bot/blacklist/{{ bot['handle'] }}" title="Banned words"><i class="fas fa-strikethrough"></i></a><a class="button btn-secondary" href="/bot/chat/{{ bot['handle'] }}" title="Chat"><i class="fas fa-comment"></i></a><a class="button btn-dangerous" href="/bot/delete/{{ bot['handle'] }}" title="Delete"><i class="fas fa-trash"></i></a>
|
||||
<a class="button btn-secondary" href="/bot/toggle/{{ bot['id'] }}" title="Turn on/off"><i class="fas fa-power-off"></i></a><a class="button btn-secondary" href="/bot/edit/{{ bot['id'] }}" title="Configure"><i class="fas fa-cog"></i></a><a class="button btn-secondary" href="/bot/accounts/{{ bot['id'] }}" title="Accounts learned from"><i class="fas fa-users"></i></a><a class="button btn-secondary" href="/bot/blacklist/{{ bot['id'] }}" title="Banned words"><i class="fas fa-strikethrough"></i></a><a class="button btn-secondary" href="/bot/chat/{{ bot['id'] }}" title="Chat"><i class="fas fa-comment"></i></a><a class="button btn-dangerous" href="/bot/delete/{{ bot['id'] }}" title="Delete"><i class="fas fa-trash"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
<div class="row">
|
||||
<label for="email" class="large">Email address</label>
|
||||
<input type="email" name="email" value="{{ user['email'] }}">
|
||||
<input type="email" name="email" value="me@my.site">
|
||||
</div>
|
||||
<div class="row">
|
||||
<label for="password" class="large">Password</label>
|
||||
|
@ -33,35 +33,35 @@
|
|||
</div>
|
||||
|
||||
<div class="row">
|
||||
<label for="fetch-error" class="large">When my bot(s) can't get new posts</label>
|
||||
<select name="fetch-error">
|
||||
<option value="always" {{ 'selected' if user['fetch'] == "always"}}>Always</option>
|
||||
<option value="once" {{ 'selected' if user['fetch'] == "once"}}>Once</option>
|
||||
<option value="never" {{ 'selected' if user['fetch'] == "never"}}>Never</option>
|
||||
<label for="download-error" class="large">When my bot(s) can't get new posts</label>
|
||||
<select name="download-error">
|
||||
<option value="once">Once</option>
|
||||
<option value="every-time">Every time</option>
|
||||
<option value="never">Never</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label for="submit-error" class="large">When my bot(s) can't submit new posts</label>
|
||||
<select name="submit-error">
|
||||
<option value="always" {{ 'selected' if user['submit'] == "always"}}>Always</option>
|
||||
<option value="once" {{ 'selected' if user['submit'] == "once"}}>Once</option>
|
||||
<option value="never" {{ 'selected' if user['submit'] == "never"}}>Never</option>
|
||||
<label for="post-error" class="large">When my bot(s) can't submit new posts</label>
|
||||
<select name="post-error">
|
||||
<option value="once">Once</option>
|
||||
<option value="every-time">Every time</option>
|
||||
<option value="never">Never</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label for="generation-error" class="large">When my bot(s) encounter an error generating new posts</label>
|
||||
<select name="generation-error">
|
||||
<option value="always" {{ 'selected' if user['generation'] == "always"}}>Always</option>
|
||||
<option value="once" {{ 'selected' if user['generation'] == "once"}}>Once</option>
|
||||
<option value="never" {{ 'selected' if user['generation'] == "never"}}>Never</option>
|
||||
<option value="once">Once</option>
|
||||
<option value="every-time">Every time</option>
|
||||
<option value="never">Never</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label for="reply-error" class="large">When my bot(s) can't send replies</label>
|
||||
<select name="reply-error">
|
||||
<option value="always" {{ 'selected' if user['reply'] == "always"}}>Always</option>
|
||||
<option value="once" {{ 'selected' if user['reply'] == "once"}}>Once</option>
|
||||
<option value="never" {{ 'selected' if user['reply'] == "never"}}>Never</option>
|
||||
<option value="once">Once</option>
|
||||
<option value="every-time">Every time</option>
|
||||
<option value="never">Never</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
|
144
webui.py
144
webui.py
|
@ -1,4 +1,4 @@
|
|||
from flask import Flask, render_template, session, request, redirect, url_for, send_file
|
||||
from flask import Flask, render_template, session, request, redirect, url_for
|
||||
from flask_mysqldb import MySQL
|
||||
from mastodon import Mastodon
|
||||
import requests
|
||||
|
@ -28,22 +28,21 @@ def home():
|
|||
c.execute("SELECT COUNT(*) FROM `bots` WHERE user_id = %s", (session['user_id'],))
|
||||
bot_count = c.fetchone()[0]
|
||||
active_count = None
|
||||
bots = {}
|
||||
bots = None
|
||||
bot_users = None
|
||||
|
||||
if bot_count > 0:
|
||||
c.execute("SELECT COUNT(*) FROM `bots` WHERE user_id = %s AND enabled = TRUE", (session['user_id'],))
|
||||
active_count = c.fetchone()[0]
|
||||
dc = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
|
||||
dc.execute("SELECT `handle`, `enabled` FROM `bots` WHERE user_id = %s", (session['user_id'],))
|
||||
dc.execute("SELECT * FROM `bots` WHERE user_id = %s", (session['user_id'],))
|
||||
bots = dc.fetchall()
|
||||
dc.close()
|
||||
bot_users = {}
|
||||
|
||||
for bot in bots:
|
||||
# multiple SELECTS is slow, maybe SELECT all at once and filter with python?
|
||||
c.execute("SELECT COUNT(*) FROM `bot_learned_accounts` WHERE bot_id = %s", (bot['handle'],))
|
||||
bot_users[bot['handle']] = c.fetchone()[0]
|
||||
c.execute("SELECT COUNT(*) FROM `bot_learned_accounts` WHERE bot_id = %s", (bot['id'],))
|
||||
bot_users[bot['id']] = c.fetchone()[0]
|
||||
|
||||
c.close()
|
||||
return render_template("home.html", bot_count = bot_count, active_count = active_count, bots = bots, bot_users = bot_users)
|
||||
|
@ -69,122 +68,24 @@ def show_signup_page(error = None):
|
|||
|
||||
@app.route("/settings")
|
||||
def settings():
|
||||
return render_template("coming_soon.html")
|
||||
dc = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
|
||||
dc.execute("SELECT * FROM `users` WHERE id = %s", (session['user_id'],))
|
||||
user = dc.fetchone()
|
||||
dc.close()
|
||||
return render_template("settings.html", user = user)
|
||||
return render_template("settings.html")
|
||||
|
||||
@app.route("/bot/edit/<id>")
|
||||
def bot_edit(id):
|
||||
return render_template("coming_soon.html")
|
||||
return render_template("bot_edit.html")
|
||||
|
||||
@app.route("/bot/delete/<id>", methods=['GET', 'POST'])
|
||||
@app.route("/bot/delete/<id>")
|
||||
def bot_delete(id):
|
||||
if bot_check(id):
|
||||
if request.method == 'GET':
|
||||
instance = id.split("@")[2]
|
||||
return render_template("bot_delete.html", instance = instance)
|
||||
else:
|
||||
# delete bot by deleting its credentials
|
||||
# FK constraint will delete bot
|
||||
c = mysql.connection.cursor()
|
||||
c.execute("SELECT `credentials_id` FROM `bots` WHERE `handle` = %s", (id,))
|
||||
credentials_id = c.fetchone()[0]
|
||||
c.execute("DELETE FROM `credentials` WHERE `id` = %s", (credentials_id,))
|
||||
c.close()
|
||||
mysql.connection.commit()
|
||||
|
||||
return redirect(url_for("home"), 303)
|
||||
|
||||
@app.route("/bot/toggle/<id>")
|
||||
def bot_toggle(id):
|
||||
if bot_check(id):
|
||||
c = mysql.connection.cursor()
|
||||
c.execute("UPDATE `bots` SET `enabled` = NOT `enabled` WHERE `handle` = %s", (id,))
|
||||
mysql.connection.commit()
|
||||
c.close()
|
||||
return redirect(url_for("home"), 303)
|
||||
|
||||
@app.route("/bot/chat/<id>")
|
||||
def bot_chat(id):
|
||||
return render_template("coming_soon.html")
|
||||
|
||||
@app.route("/bot/blacklist/<id>")
|
||||
def bot_blacklist(id):
|
||||
return render_template("coming_soon.html")
|
||||
return render_template("bot_delete.html")
|
||||
|
||||
@app.route("/bot/accounts/<id>")
|
||||
def bot_accounts(id):
|
||||
if bot_check(id):
|
||||
session['bot'] = id
|
||||
c = mysql.connection.cursor()
|
||||
c.execute("SELECT COUNT(*) FROM `bot_learned_accounts` WHERE `bot_id` = %s", (id,))
|
||||
user_count = c.fetchone()[0]
|
||||
users = {}
|
||||
return render_template("bot_accounts.html")
|
||||
|
||||
if user_count > 0:
|
||||
dc = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
|
||||
dc.execute("SELECT `fedi_id`, `enabled` FROM `bot_learned_accounts` WHERE `bot_id` = %s", (id,))
|
||||
users = dc.fetchall()
|
||||
dc.close()
|
||||
|
||||
c.close()
|
||||
|
||||
return render_template("bot_accounts.html", users = users)
|
||||
|
||||
@app.route("/bot/accounts/add", methods = ['GET', 'POST'])
|
||||
@app.route("/bot/accounts/add")
|
||||
def bot_accounts_add():
|
||||
if request.method == 'POST':
|
||||
if session['step'] == 1:
|
||||
# look up user
|
||||
handle_list = request.form['account'].split('@')
|
||||
username = handle_list[1]
|
||||
instance = handle_list[2]
|
||||
|
||||
# 1. download host-meta to find webfinger URL
|
||||
r = requests.get("https://{}/.well-known/host-meta".format(instance), timeout=10)
|
||||
# 2. use webfinger to find user's info page
|
||||
#TODO: use more reliable method
|
||||
uri = re.search(r'template="([^"]+)"', r.text).group(1)
|
||||
uri = uri.format(uri = "{}@{}".format(username, instance))
|
||||
r = requests.get(uri, headers={"Accept": "application/json"}, timeout=10)
|
||||
j = r.json()
|
||||
found = False
|
||||
for link in j['links']:
|
||||
if link['rel'] == 'self':
|
||||
#this is a link formatted like "https://instan.ce/users/username", which is what we need
|
||||
uri = link['href']
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
return "Couldn't find a valid ActivityPub outbox URL."
|
||||
|
||||
# 3. format as outbox URL and check to make sure it works
|
||||
outbox = "{}/outbox?page=true".format(uri)
|
||||
r = requests.get(uri, headers={"Accept": "application/json"}, timeout=10)
|
||||
if r.status_code == 200:
|
||||
# success!!
|
||||
c = mysql.connection.cursor()
|
||||
c.execute("INSERT INTO `fedi_accounts` (`handle`, `outbox`) VALUES (%s, %s)", (request.form['account'], outbox))
|
||||
c.execute("INSERT INTO `bot_learned_accounts` (`bot_id`, `fedi_id`) VALUES (%s, %s)", (session['bot'], request.form['account']))
|
||||
c.close()
|
||||
mysql.connection.commit()
|
||||
|
||||
return redirect("/bot/accounts/{}".format(session['bot']), 303)
|
||||
|
||||
return render_template("bot_accounts_add.html")
|
||||
|
||||
@app.route("/bot/accounts/toggle/<id>")
|
||||
def bot_accounts_toggle(id):
|
||||
c = mysql.connection.cursor()
|
||||
c.execute("UPDATE `bot_learned_accounts` SET `enabled` = NOT `enabled` WHERE `fedi_id` = %s AND `bot_id` = %s", (id, session['bot']))
|
||||
mysql.connection.commit()
|
||||
c.close()
|
||||
return redirect("/bot/accounts/{}".format(session['bot']), 303)
|
||||
|
||||
|
||||
@app.route("/bot/create/", methods=['GET', 'POST'])
|
||||
def bot_create():
|
||||
#TODO: error handling
|
||||
|
@ -194,7 +95,7 @@ def bot_create():
|
|||
session['instance'] = re.match(r"^(?:https?:\/\/)?(.*)", request.form['instance']).group(1)
|
||||
|
||||
# check for mastodon/pleroma
|
||||
r = requests.get("https://{}/api/v1/instance".format(session['instance']), timeout=10)
|
||||
r = requests.get("https://{}/api/v1/instance".format(session['instance']))
|
||||
if r.status_code == 200:
|
||||
j = r.json()
|
||||
if "Pleroma" in j['version']:
|
||||
|
@ -254,8 +155,7 @@ def bot_create():
|
|||
session['step'] = 1
|
||||
return bot_create()
|
||||
|
||||
else:
|
||||
if session['step'] == 4:
|
||||
elif session['step'] == 4:
|
||||
try:
|
||||
# test authentication
|
||||
client = Mastodon(client_id=session['client_id'], client_secret=session['client_secret'], api_base_url=session['instance'])
|
||||
|
@ -272,8 +172,10 @@ def bot_create():
|
|||
credentials_id = c.lastrowid
|
||||
mysql.connection.commit()
|
||||
|
||||
c.execute("INSERT INTO `bots` (handle, user_id, credentials_id) VALUES (%s, %s, %s)", (handle, session['user_id'], credentials_id))
|
||||
bot_id = hashlib.sha256(handle.encode('utf-8')).digest()
|
||||
c.execute("INSERT INTO `bots` (id, user_id, credentials_id, handle) VALUES (%s, %s, %s, %s)", (bot_id, session['user_id'], credentials_id, handle))
|
||||
mysql.connection.commit()
|
||||
|
||||
c.close()
|
||||
|
||||
# clean up unneeded variables
|
||||
|
@ -285,11 +187,6 @@ def bot_create():
|
|||
|
||||
return render_template("bot_create.html")
|
||||
|
||||
@app.route("/bot/create/back")
|
||||
def bot_create_back():
|
||||
session['step'] -= 1
|
||||
return redirect(url_for("bot_create"), 303)
|
||||
|
||||
@app.route("/do/authenticate_bot")
|
||||
def do_authenticate_bot():
|
||||
session['code'] = request.args.get('code')
|
||||
|
@ -338,12 +235,3 @@ def do_login():
|
|||
|
||||
else:
|
||||
return "invalid login"
|
||||
|
||||
@app.route("/img/bot_generic.png")
|
||||
def img_bot_generic():
|
||||
return send_file("static/bot_generic.png", mimetype="image/png")
|
||||
|
||||
def bot_check(bot):
|
||||
c = mysql.connection.cursor()
|
||||
c.execute("SELECT COUNT(*) FROM `bots` WHERE `handle` = %s AND `user_id` = %s", (bot, session['user_id']))
|
||||
return c.fetchone()[0] == 1
|
||||
|
|
Loading…
Reference in a new issue