mirror of
https://github.com/Lynnesbian/FediBooks/
synced 2024-11-25 16:48:58 +00:00
Compare commits
8 commits
a981c7a171
...
382ef00f85
Author | SHA1 | Date | |
---|---|---|---|
382ef00f85 | |||
0df53877ab | |||
34c88984e8 | |||
6d6b975fc0 | |||
b688186c28 | |||
63722bb7a2 | |||
f982e54a2d | |||
8fceadf93d |
5 changed files with 32 additions and 11 deletions
|
@ -1,7 +1,7 @@
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
import MySQLdb
|
import MySQLdb
|
||||||
import markovify
|
import markovify
|
||||||
from mastodon import Mastodon
|
from mastodon import Mastodon, MastodonUnauthorizedError
|
||||||
import html, re, json
|
import html, re, json
|
||||||
|
|
||||||
cfg = json.load(open('config.json'))
|
cfg = json.load(open('config.json'))
|
||||||
|
@ -138,7 +138,12 @@ def make_post(args):
|
||||||
# ensure post isn't longer than bot['length']
|
# ensure post isn't longer than bot['length']
|
||||||
post = post[:bot['length']]
|
post = post[:bot['length']]
|
||||||
# send toot!!
|
# send toot!!
|
||||||
client.status_post(post, id, visibility = visibility, spoiler_text = bot['content_warning'])
|
try:
|
||||||
|
client.status_post(post, id, visibility = visibility, spoiler_text = bot['content_warning'])
|
||||||
|
except MastodonUnauthorizedError:
|
||||||
|
# user has revoked the token given to the bot
|
||||||
|
# this needs to be dealt with properly later on, but for now, we'll just disable the bot
|
||||||
|
c.execute("UPDATE bots SET enabled = FALSE WHERE handle = %s", (handle,))
|
||||||
|
|
||||||
if id == None:
|
if id == None:
|
||||||
# this wasn't a reply, it was a regular post, so update the last post date
|
# this wasn't a reply, it was a regular post, so update the last post date
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import MySQLdb
|
import MySQLdb
|
||||||
import requests
|
import requests
|
||||||
from multiprocessing import Pool
|
from multiprocessing import Pool
|
||||||
|
@ -14,7 +16,7 @@ def scrape_posts(account):
|
||||||
last_post = 0
|
last_post = 0
|
||||||
c.execute("SELECT COUNT(*) FROM `posts` WHERE `fedi_id` = %s", (handle,))
|
c.execute("SELECT COUNT(*) FROM `posts` WHERE `fedi_id` = %s", (handle,))
|
||||||
count = c.fetchone()
|
count = c.fetchone()
|
||||||
if count is not None and count[0] > 0:
|
if count is not None and int(count[0]) > 0:
|
||||||
# we've downloaded this user's posts before
|
# we've downloaded this user's posts before
|
||||||
# find out the most recently downloaded post of theirs
|
# find out the most recently downloaded post of theirs
|
||||||
c.execute("SELECT `post_id` FROM `posts` WHERE `fedi_id` = %s ORDER BY `id` DESC LIMIT 1", (handle,))
|
c.execute("SELECT `post_id` FROM `posts` WHERE `fedi_id` = %s ORDER BY `id` DESC LIMIT 1", (handle,))
|
||||||
|
@ -41,7 +43,8 @@ def scrape_posts(account):
|
||||||
# first, check to see if we already have this in the database
|
# first, check to see if we already have this in the database
|
||||||
post_id = re.search(r"([^\/]+)/?$", oi['object']['id']).group(1) # extract 123 from https://example.com/posts/123/
|
post_id = re.search(r"([^\/]+)/?$", oi['object']['id']).group(1) # extract 123 from https://example.com/posts/123/
|
||||||
c.execute("SELECT COUNT(*) FROM `posts` WHERE `fedi_id` = %s AND `post_id` = %s", (handle, post_id))
|
c.execute("SELECT COUNT(*) FROM `posts` WHERE `fedi_id` = %s AND `post_id` = %s", (handle, post_id))
|
||||||
if c.fetchone()[0] > 0:
|
count = c.fetchone()
|
||||||
|
if count is not None and int(count[0]) > 0:
|
||||||
# this post is already in the DB.
|
# this post is already in the DB.
|
||||||
# we'll set done to true because we've caught up to where we were last time.
|
# we'll set done to true because we've caught up to where we were last time.
|
||||||
done = True
|
done = True
|
||||||
|
@ -80,7 +83,7 @@ def scrape_posts(account):
|
||||||
j = r.json()
|
j = r.json()
|
||||||
|
|
||||||
db.commit()
|
db.commit()
|
||||||
c.close()
|
|
||||||
print("Finished scraping {}".format(handle))
|
print("Finished scraping {}".format(handle))
|
||||||
|
|
||||||
print("Establishing DB connection")
|
print("Establishing DB connection")
|
||||||
|
|
|
@ -31,9 +31,9 @@ CREATE TABLE IF NOT EXISTS `bots` (
|
||||||
`fake_mentions_full` BOOLEAN DEFAULT 0,
|
`fake_mentions_full` BOOLEAN DEFAULT 0,
|
||||||
`post_privacy` ENUM('public', 'unlisted', 'private') DEFAULT 'unlisted',
|
`post_privacy` ENUM('public', 'unlisted', 'private') DEFAULT 'unlisted',
|
||||||
`learn_from_cw` BOOLEAN DEFAULT 0,
|
`learn_from_cw` BOOLEAN DEFAULT 0,
|
||||||
`last_post` DATETIME DEFAULT 0,
|
`last_post` DATETIME DEFAULT CURRENT_TIMESTAMP(),
|
||||||
`icon` VARCHAR(512),
|
`icon` VARCHAR(512),
|
||||||
`icon_update_time` DATETIME DEFAULT 0,
|
`icon_update_time` DATETIME DEFAULT '1000-01-01 00:00:00',
|
||||||
FOREIGN KEY (`user_id`) REFERENCES users(id) ON DELETE CASCADE,
|
FOREIGN KEY (`user_id`) REFERENCES users(id) ON DELETE CASCADE,
|
||||||
FOREIGN KEY (`credentials_id`) REFERENCES credentials(id) ON DELETE CASCADE
|
FOREIGN KEY (`credentials_id`) REFERENCES credentials(id) ON DELETE CASCADE
|
||||||
) ENGINE=INNODB;
|
) ENGINE=INNODB;
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
<div class="panel-text">
|
<div class="panel-text">
|
||||||
{% set handle_list = bot['handle'].split('@') %}
|
{% 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-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-status">{{ "Online" if bot['enabled'] else "Offline"}}, learning from {{ bot_users[bot['handle']] }} accounts.{% if bot['handle'] in next_posts %} Next post in {{ next_posts[bot['handle']][0] }} minutes.{% endif %}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-actions">
|
<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['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>
|
||||||
|
|
19
webui.py
19
webui.py
|
@ -42,18 +42,23 @@ def home():
|
||||||
c.execute("SELECT COUNT(*) FROM `bots` WHERE user_id = %s AND enabled = TRUE", (session['user_id'],))
|
c.execute("SELECT COUNT(*) FROM `bots` WHERE user_id = %s AND enabled = TRUE", (session['user_id'],))
|
||||||
active_count = c.fetchone()[0]
|
active_count = c.fetchone()[0]
|
||||||
dc = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
|
dc = mysql.connection.cursor(MySQLdb.cursors.DictCursor)
|
||||||
dc.execute("SELECT `handle`, `enabled` FROM `bots` WHERE user_id = %s", (session['user_id'],))
|
dc.execute("SELECT `handle`, `enabled`, `last_post`, `post_frequency` FROM `bots` WHERE user_id = %s", (session['user_id'],))
|
||||||
bots = dc.fetchall()
|
bots = dc.fetchall()
|
||||||
dc.close()
|
dc.close()
|
||||||
bot_users = {}
|
bot_users = {}
|
||||||
|
next_posts = {}
|
||||||
|
|
||||||
for bot in bots:
|
for bot in bots:
|
||||||
# multiple SELECTS is slow, maybe SELECT all at once and filter with python?
|
# 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'],))
|
c.execute("SELECT COUNT(*) FROM `bot_learned_accounts` WHERE bot_id = %s", (bot['handle'],))
|
||||||
bot_users[bot['handle']] = c.fetchone()[0]
|
bot_users[bot['handle']] = c.fetchone()[0]
|
||||||
|
c.execute("SELECT post_frequency - TIMESTAMPDIFF(MINUTE, last_post, CURRENT_TIMESTAMP()) FROM bots WHERE TIMESTAMPDIFF(MINUTE, last_post, CURRENT_TIMESTAMP()) <= post_frequency AND enabled = TRUE AND handle = %s", (bot['handle'],))
|
||||||
|
next_post = c.fetchone()
|
||||||
|
if next_post is not None:
|
||||||
|
next_posts[bot['handle']] = next_post
|
||||||
|
|
||||||
c.close()
|
c.close()
|
||||||
return render_template("home.html", bot_count = bot_count, active_count = active_count, bots = bots, bot_users = bot_users)
|
return render_template("home.html", bot_count = bot_count, active_count = active_count, bots = bots, bot_users = bot_users, next_posts = next_posts)
|
||||||
else:
|
else:
|
||||||
return render_template("front_page.html")
|
return render_template("front_page.html")
|
||||||
|
|
||||||
|
@ -375,7 +380,15 @@ def bot_create():
|
||||||
session['instance'] = re.match(r"^(?:https?:\/\/)?(.*)", request.form['instance']).group(1)
|
session['instance'] = re.match(r"^(?:https?:\/\/)?(.*)", request.form['instance']).group(1)
|
||||||
|
|
||||||
# check for mastodon/pleroma
|
# check for mastodon/pleroma
|
||||||
r = requests.get("https://{}/api/v1/instance".format(session['instance']), timeout=10)
|
try:
|
||||||
|
r = requests.get("https://{}/api/v1/instance".format(session['instance']), timeout=10)
|
||||||
|
except requests.ConnectionError:
|
||||||
|
session['error'] = "Couldn't connect to https://{}.".format(session['instance'])
|
||||||
|
return render_template("bot_create.html", error = session.pop('error', None))
|
||||||
|
except:
|
||||||
|
session['error'] = "An unknown error occurred while trying to load https://{}".format(session['instance'])
|
||||||
|
return render_template("bot_create.html", error = session.pop('error', None))
|
||||||
|
|
||||||
if r.status_code == 200:
|
if r.status_code == 200:
|
||||||
j = r.json()
|
j = r.json()
|
||||||
if "Pleroma" in j['version']:
|
if "Pleroma" in j['version']:
|
||||||
|
|
Loading…
Reference in a new issue