Clean up formatting and help linter calm down
This commit is contained in:
parent
dd78364f2d
commit
a904587b32
4 changed files with 92 additions and 81 deletions
|
@ -8,6 +8,7 @@ from bs4 import BeautifulSoup
|
||||||
from random import randint
|
from random import randint
|
||||||
import re, multiprocessing, sqlite3, shutil, os, html
|
import re, multiprocessing, sqlite3, shutil, os, html
|
||||||
|
|
||||||
|
|
||||||
def make_sentence(output, cfg):
|
def make_sentence(output, cfg):
|
||||||
class nlt_fixed(markovify.NewlineText): # modified version of NewlineText that never rejects sentences
|
class nlt_fixed(markovify.NewlineText): # modified version of NewlineText that never rejects sentences
|
||||||
def test_sentence_input(self, sentence):
|
def test_sentence_input(self, sentence):
|
||||||
|
@ -35,8 +36,6 @@ def make_sentence(output, cfg):
|
||||||
db.close()
|
db.close()
|
||||||
os.remove("toots-copy.db")
|
os.remove("toots-copy.db")
|
||||||
|
|
||||||
toots_str = None
|
|
||||||
|
|
||||||
if cfg['limit_length']:
|
if cfg['limit_length']:
|
||||||
sentence_len = randint(cfg['length_lower_limit'], cfg['length_upper_limit'])
|
sentence_len = randint(cfg['length_lower_limit'], cfg['length_upper_limit'])
|
||||||
|
|
||||||
|
@ -59,6 +58,7 @@ def make_sentence(output, cfg):
|
||||||
|
|
||||||
output.send(sentence)
|
output.send(sentence)
|
||||||
|
|
||||||
|
|
||||||
def make_toot(cfg):
|
def make_toot(cfg):
|
||||||
toot = None
|
toot = None
|
||||||
pin, pout = multiprocessing.Pipe(False)
|
pin, pout = multiprocessing.Pipe(False)
|
||||||
|
@ -71,10 +71,11 @@ def make_toot(cfg):
|
||||||
else:
|
else:
|
||||||
toot = pin.recv()
|
toot = pin.recv()
|
||||||
|
|
||||||
if toot == None:
|
if toot is None:
|
||||||
toot = "Toot generation failed! Contact Lynne (lynnesbian@fedi.lynnesbian.space) for assistance."
|
toot = "Toot generation failed! Contact Lynne (lynnesbian@fedi.lynnesbian.space) for assistance."
|
||||||
return toot
|
return toot
|
||||||
|
|
||||||
|
|
||||||
def extract_toot(toot):
|
def extract_toot(toot):
|
||||||
toot = html.unescape(toot) # convert HTML escape codes to text
|
toot = html.unescape(toot) # convert HTML escape codes to text
|
||||||
soup = BeautifulSoup(toot, "html.parser")
|
soup = BeautifulSoup(toot, "html.parser")
|
||||||
|
@ -87,7 +88,7 @@ def extract_toot(toot):
|
||||||
for ht in soup.select("a.hashtag"): # convert hashtags from links to text
|
for ht in soup.select("a.hashtag"): # convert hashtags from links to text
|
||||||
ht.unwrap()
|
ht.unwrap()
|
||||||
|
|
||||||
for link in soup.select("a"): #ocnvert <a href='https://example.com>example.com</a> to just https://example.com
|
for link in soup.select("a"): # convert <a href='https://example.com>example.com</a> to just https://example.com
|
||||||
if 'href' in link:
|
if 'href' in link:
|
||||||
# apparently not all a tags have a href, which is understandable if you're doing normal web stuff, but on a social media platform??
|
# apparently not all a tags have a href, which is understandable if you're doing normal web stuff, but on a social media platform??
|
||||||
link.replace_with(link["href"])
|
link.replace_with(link["href"])
|
||||||
|
|
8
gen.py
8
gen.py
|
@ -8,9 +8,11 @@ import argparse, json, re
|
||||||
import functions
|
import functions
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description='Generate and post a toot.')
|
parser = argparse.ArgumentParser(description='Generate and post a toot.')
|
||||||
parser.add_argument('-c', '--cfg', dest='cfg', default='config.json', nargs='?',
|
parser.add_argument(
|
||||||
|
'-c', '--cfg', dest='cfg', default='config.json', nargs='?',
|
||||||
help="Specify a custom location for config.json.")
|
help="Specify a custom location for config.json.")
|
||||||
parser.add_argument('-s', '--simulate', dest='simulate', action='store_true',
|
parser.add_argument(
|
||||||
|
'-s', '--simulate', dest='simulate', action='store_true',
|
||||||
help="Print the toot without actually posting it. Use this to make sure your bot's actually working.")
|
help="Print the toot without actually posting it. Use this to make sure your bot's actually working.")
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
@ -33,7 +35,7 @@ if __name__ == '__main__':
|
||||||
if not args.simulate:
|
if not args.simulate:
|
||||||
try:
|
try:
|
||||||
client.status_post(toot, visibility='unlisted', spoiler_text=cfg['cw'])
|
client.status_post(toot, visibility='unlisted', spoiler_text=cfg['cw'])
|
||||||
except Exception as err:
|
except Exception:
|
||||||
toot = "An error occurred while submitting the generated post. Contact lynnesbian@fedi.lynnesbian.space for assistance."
|
toot = "An error occurred while submitting the generated post. Contact lynnesbian@fedi.lynnesbian.space for assistance."
|
||||||
client.status_post(toot, visibility='unlisted', spoiler_text="Error!")
|
client.status_post(toot, visibility='unlisted', spoiler_text="Error!")
|
||||||
try:
|
try:
|
||||||
|
|
25
main.py
25
main.py
|
@ -5,14 +5,13 @@
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
from mastodon import Mastodon, MastodonUnauthorizedError
|
from mastodon import Mastodon, MastodonUnauthorizedError
|
||||||
from os import path
|
import sqlite3, signal, sys, json, re, argparse
|
||||||
from bs4 import BeautifulSoup
|
|
||||||
import os, sqlite3, signal, sys, json, re, shutil, argparse
|
|
||||||
import requests
|
import requests
|
||||||
import functions
|
import functions
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description='Log in and download posts.')
|
parser = argparse.ArgumentParser(description='Log in and download posts.')
|
||||||
parser.add_argument('-c', '--cfg', dest='cfg', default='config.json', nargs='?',
|
parser.add_argument(
|
||||||
|
'-c', '--cfg', dest='cfg', default='config.json', nargs='?',
|
||||||
help="Specify a custom location for config.json.")
|
help="Specify a custom location for config.json.")
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
@ -48,7 +47,8 @@ if not cfg['site'].startswith("https://") and not cfg['site'].startswith("http:/
|
||||||
|
|
||||||
if "client" not in cfg:
|
if "client" not in cfg:
|
||||||
print("No application info -- registering application with {}".format(cfg['site']))
|
print("No application info -- registering application with {}".format(cfg['site']))
|
||||||
client_id, client_secret = Mastodon.create_app("mstdn-ebooks",
|
client_id, client_secret = Mastodon.create_app(
|
||||||
|
"mstdn-ebooks",
|
||||||
api_base_url=cfg['site'],
|
api_base_url=cfg['site'],
|
||||||
scopes=scopes,
|
scopes=scopes,
|
||||||
website="https://github.com/Lynnesbian/mstdn-ebooks")
|
website="https://github.com/Lynnesbian/mstdn-ebooks")
|
||||||
|
@ -60,7 +60,8 @@ if "client" not in cfg:
|
||||||
|
|
||||||
if "secret" not in cfg:
|
if "secret" not in cfg:
|
||||||
print("No user credentials -- logging in to {}".format(cfg['site']))
|
print("No user credentials -- logging in to {}".format(cfg['site']))
|
||||||
client = Mastodon(client_id = cfg['client']['id'],
|
client = Mastodon(
|
||||||
|
client_id=cfg['client']['id'],
|
||||||
client_secret=cfg['client']['secret'],
|
client_secret=cfg['client']['secret'],
|
||||||
api_base_url=cfg['site'])
|
api_base_url=cfg['site'])
|
||||||
|
|
||||||
|
@ -69,11 +70,13 @@ if "secret" not in cfg:
|
||||||
|
|
||||||
json.dump(cfg, open(args.cfg, "w+"))
|
json.dump(cfg, open(args.cfg, "w+"))
|
||||||
|
|
||||||
|
|
||||||
def extract_toot(toot):
|
def extract_toot(toot):
|
||||||
toot = functions.extract_toot(toot)
|
toot = functions.extract_toot(toot)
|
||||||
toot = toot.replace("@", "@\u200B") # put a zws between @ and username to avoid mentioning
|
toot = toot.replace("@", "@\u200B") # put a zws between @ and username to avoid mentioning
|
||||||
return(toot)
|
return(toot)
|
||||||
|
|
||||||
|
|
||||||
client = Mastodon(
|
client = Mastodon(
|
||||||
client_id=cfg['client']['id'],
|
client_id=cfg['client']['id'],
|
||||||
client_secret=cfg['client']['secret'],
|
client_secret=cfg['client']['secret'],
|
||||||
|
@ -115,7 +118,7 @@ if not found:
|
||||||
c.execute("CREATE TABLE `toots_temp` (sortid INTEGER UNIQUE PRIMARY KEY AUTOINCREMENT, id VARCHAR NOT NULL, cw INT NOT NULL DEFAULT 0, userid VARCHAR NOT NULL, uri VARCHAR NOT NULL, content VARCHAR NOT NULL)")
|
c.execute("CREATE TABLE `toots_temp` (sortid INTEGER UNIQUE PRIMARY KEY AUTOINCREMENT, id VARCHAR NOT NULL, cw INT NOT NULL DEFAULT 0, userid VARCHAR NOT NULL, uri VARCHAR NOT NULL, content VARCHAR NOT NULL)")
|
||||||
for f in following:
|
for f in following:
|
||||||
user_toots = c.execute("SELECT * FROM `toots` WHERE userid LIKE ? ORDER BY id", (f.id,)).fetchall()
|
user_toots = c.execute("SELECT * FROM `toots` WHERE userid LIKE ? ORDER BY id", (f.id,)).fetchall()
|
||||||
if user_toots == None:
|
if user_toots is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if columns[-1] == "cw":
|
if columns[-1] == "cw":
|
||||||
|
@ -131,11 +134,13 @@ if not found:
|
||||||
|
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
|
||||||
def handleCtrlC(signal, frame):
|
def handleCtrlC(signal, frame):
|
||||||
print("\nPREMATURE EVACUATION - Saving chunks")
|
print("\nPREMATURE EVACUATION - Saving chunks")
|
||||||
db.commit()
|
db.commit()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
signal.signal(signal.SIGINT, handleCtrlC)
|
signal.signal(signal.SIGINT, handleCtrlC)
|
||||||
|
|
||||||
patterns = {
|
patterns = {
|
||||||
|
@ -150,7 +155,7 @@ def insert_toot(oii, acc, post, cursor): # extracted to prevent duplication
|
||||||
pid = patterns["pid"].search(oii['object']['id']).group(0)
|
pid = patterns["pid"].search(oii['object']['id']).group(0)
|
||||||
cursor.execute("REPLACE INTO toots (id, cw, userid, uri, content) VALUES (?, ?, ?, ?, ?)", (
|
cursor.execute("REPLACE INTO toots (id, cw, userid, uri, content) VALUES (?, ?, ?, ?, ?)", (
|
||||||
pid,
|
pid,
|
||||||
1 if (oii['object']['summary'] != None and oii['object']['summary'] != "") else 0,
|
1 if (oii['object']['summary'] is not None and oii['object']['summary'] != "") else 0,
|
||||||
acc.id,
|
acc.id,
|
||||||
oii['object']['id'],
|
oii['object']['id'],
|
||||||
post
|
post
|
||||||
|
@ -159,7 +164,7 @@ def insert_toot(oii, acc, post, cursor): # extracted to prevent duplication
|
||||||
|
|
||||||
for f in following:
|
for f in following:
|
||||||
last_toot = c.execute("SELECT id FROM `toots` WHERE userid LIKE ? ORDER BY sortid DESC LIMIT 1", (f.id,)).fetchone()
|
last_toot = c.execute("SELECT id FROM `toots` WHERE userid LIKE ? ORDER BY sortid DESC LIMIT 1", (f.id,)).fetchone()
|
||||||
if last_toot != None:
|
if last_toot is not None:
|
||||||
last_toot = last_toot[0]
|
last_toot = last_toot[0]
|
||||||
else:
|
else:
|
||||||
last_toot = 0
|
last_toot = 0
|
||||||
|
@ -168,7 +173,7 @@ for f in following:
|
||||||
# find the user's activitypub outbox
|
# find the user's activitypub outbox
|
||||||
print("WebFingering...")
|
print("WebFingering...")
|
||||||
instance = patterns["handle"].search(f.acct)
|
instance = patterns["handle"].search(f.acct)
|
||||||
if instance == None:
|
if instance is None:
|
||||||
instance = patterns["url"].search(cfg['site']).group(1)
|
instance = patterns["url"].search(cfg['site']).group(1)
|
||||||
else:
|
else:
|
||||||
instance = instance.group(1)
|
instance = instance.group(1)
|
||||||
|
|
9
reply.py
9
reply.py
|
@ -4,12 +4,12 @@
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
import mastodon
|
import mastodon
|
||||||
import random, re, json, argparse
|
import re, json, argparse
|
||||||
import functions
|
import functions
|
||||||
from bs4 import BeautifulSoup
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description='Reply service. Leave running in the background.')
|
parser = argparse.ArgumentParser(description='Reply service. Leave running in the background.')
|
||||||
parser.add_argument('-c', '--cfg', dest='cfg', default='config.json', nargs='?',
|
parser.add_argument(
|
||||||
|
'-c', '--cfg', dest='cfg', default='config.json', nargs='?',
|
||||||
help="Specify a custom location for config.json.")
|
help="Specify a custom location for config.json.")
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
@ -22,12 +22,14 @@ client = mastodon.Mastodon(
|
||||||
access_token=cfg['secret'],
|
access_token=cfg['secret'],
|
||||||
api_base_url=cfg['site'])
|
api_base_url=cfg['site'])
|
||||||
|
|
||||||
|
|
||||||
def extract_toot(toot):
|
def extract_toot(toot):
|
||||||
text = functions.extract_toot(toot)
|
text = functions.extract_toot(toot)
|
||||||
text = re.sub(r"^@[^@]+@[^ ]+\s*", r"", text) # remove the initial mention
|
text = re.sub(r"^@[^@]+@[^ ]+\s*", r"", text) # remove the initial mention
|
||||||
text = text.lower() # treat text as lowercase for easier keyword matching (if this bot uses it)
|
text = text.lower() # treat text as lowercase for easier keyword matching (if this bot uses it)
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
||||||
class ReplyListener(mastodon.StreamListener):
|
class ReplyListener(mastodon.StreamListener):
|
||||||
def on_notification(self, notification): # listen for notifications
|
def on_notification(self, notification): # listen for notifications
|
||||||
if notification['type'] == 'mention': # if we're mentioned:
|
if notification['type'] == 'mention': # if we're mentioned:
|
||||||
|
@ -82,5 +84,6 @@ class ReplyListener(mastodon.StreamListener):
|
||||||
client.status_post(toot, post_id, visibility=visibility, spoiler_text=cfg['cw']) # send toost
|
client.status_post(toot, post_id, visibility=visibility, spoiler_text=cfg['cw']) # send toost
|
||||||
print("replied with " + toot) # logging
|
print("replied with " + toot) # logging
|
||||||
|
|
||||||
|
|
||||||
rl = ReplyListener()
|
rl = ReplyListener()
|
||||||
client.stream_user(rl) # go!
|
client.stream_user(rl) # go!
|
||||||
|
|
Loading…
Reference in a new issue