feedbot/feedbot.py

191 lines
4.8 KiB
Python
Raw Normal View History

2022-04-30 14:05:18 +00:00
import feedparser
import requests
2022-04-30 17:01:42 +00:00
import textwrap
2022-04-30 14:05:18 +00:00
import logging
import pnutpy
import click
2022-04-30 17:01:42 +00:00
import time
2022-04-30 14:05:18 +00:00
import re
import os
import models as zdb
from PIL import ImageFile
SNAP_USER_DATA = os.environ.get('SNAP_USER_DATA')
2022-04-30 17:01:24 +00:00
dr = False
2022-04-30 14:05:18 +00:00
@click.group(invoke_without_command=True)
@click.pass_context
@click.option('--db')
@click.option('--prime', is_flag=True)
@click.option('--debug', is_flag=True)
2022-04-30 17:01:24 +00:00
@click.option('--dryrun', is_flag=True)
2022-07-12 18:12:57 +00:00
@click.version_option(version='0.2.2')
2022-04-30 17:01:24 +00:00
def main(ctx, db, prime, debug, dryrun):
global dr
2022-04-30 14:05:18 +00:00
if debug:
logging.basicConfig(level=logging.DEBUG)
2022-04-30 17:01:24 +00:00
else:
logging.basicConfig(level=logging.INFO)
if dryrun:
dr = dryrun
2022-04-30 14:05:18 +00:00
if SNAP_USER_DATA is None and db is not None:
db_file = db
else:
db_file = SNAP_USER_DATA + '/feeds.db'
zdb.db.init(db_file)
zdb.create_tables()
if ctx.invoked_subcommand is None:
for feed in zdb.Feeds.select():
fetch(feed.url, feed.pnut_uid, feed.id, prime)
@main.command()
@click.argument('username')
@click.argument('token')
def adduser(username, token):
'''Add a pnut user'''
pnutpy.api.add_authorization_token(token)
pass
try:
pnut_user, meta = pnutpy.api.get_user('me')
user = zdb.User(pnut_uid=pnut_user.id, pnut_token=token, pnut_enabled=True)
user.save()
except pnutpy.errors.PnutAuthAPIException:
logging.error(f"pnut user token not valid")
@main.command()
@click.argument('uid')
def enable(uid):
'''Enable posts to pnut'''
user = zdb.User.get(pnut_uid=uid)
user.pnut_enabled = 1
user.save()
@main.command()
@click.argument('uid')
def disable(uid):
'''Disable posts to pnut'''
user = zdb.User.get(pnut_uid=uid)
user.pnut_enabled = 0
user.save()
2022-04-30 14:05:18 +00:00
@main.command()
@click.argument('uid')
@click.argument('url')
def add(uid, url):
'''Add a feed'''
feed = zdb.Feeds(pnut_uid=uid, url=url)
feed.save()
def fetch(url, pnut_uid, fid, prime):
feed = feedparser.parse(url)
try:
user = zdb.User.get(pnut_uid=pnut_uid)
source = {
'link': feed.feed.link,
'username': feed.feed.title,
'avatar': feed.feed.image.href
}
for post in reversed(feed.entries):
link = post.link
try:
entry = zdb.Entries.get(feedid=fid, link=link)
logging.debug(f"skipping {link}...")
except zdb.Entries.DoesNotExist:
2022-04-30 17:01:24 +00:00
if not dr:
entry = zdb.Entries(feedid=fid, link=link)
entry.save()
2022-04-30 14:05:18 +00:00
if prime:
logging.debug(f"saving {link}...")
elif user.pnut_enabled:
2022-04-30 14:05:18 +00:00
logging.debug(f"posting {link}...")
pnutpost(post, source, user.pnut_token)
else:
logging.debug(f"pnut disabled, saving {link}...")
2022-04-30 14:05:18 +00:00
except zdb.User.DoesNotExist:
logging.error(f"user {pnut_uid} not found")
except Exception:
logging.exception("bad stuff")
def pnutpost(entry, source, token):
pnutpy.api.add_authorization_token(token)
crosspost = {
'type': "io.pnut.core.crosspost",
'value': {
'canonical_url': entry.link,
#'source': {'url': source['link']},
'user': {
'username': source['username'],
'avatar_image': source['avatar']
}
}
}
raw = [crosspost]
2022-07-12 18:12:57 +00:00
if hasattr(entry, 'media_content'):
for media in entry.media_content:
if media["medium"] == "image":
raw.append(embed_image(media["url"]))
2022-04-30 14:05:18 +00:00
try:
rx = re.compile('<.*?>')
text = re.sub(rx, '', entry.summary)
2022-04-30 17:01:24 +00:00
2022-04-30 17:01:42 +00:00
lchk = textwrap.wrap(text, 256)
if len(lchk) > 1:
pretext = textwrap.wrap(text, 250)
longpost = {
'type': "nl.chimpnut.blog.post",
'value': {
'body': text,
'tstamp': time.time() * 1000
}
}
raw.append(longpost)
text = pretext + " [...](" + entry.link + ")"
2022-04-30 17:01:24 +00:00
if dr:
logging.info({'text': text, 'raw': raw})
else:
p, meta = pnutpy.api.create_post(data={'text': text, 'raw': raw})
2022-04-30 14:05:18 +00:00
except Exception:
logging.exception("bad stuff")
def embed_image(link):
resume_header = {'Range': 'bytes=0-2000000'}
2022-06-22 00:01:28 +00:00
r = requests.get(link, stream=True, headers=resume_header)
2022-04-30 14:05:18 +00:00
p = ImageFile.Parser()
p.feed(r.content)
if p.image:
width, height = p.image.size
embed = {
'version': "1.0",
'type': "photo",
'width': width,
'height': height,
2022-06-22 00:01:28 +00:00
'url': link
2022-04-30 14:05:18 +00:00
}
return {'type': "io.pnut.core.oembed", 'value': embed}
else:
return {}