bottocto/MastodonFeedHTML.py

112 lines
3.1 KiB
Python

#!/usr/bin/env python3
import base64
import feedparser
import os
import urllib.request
import email, smtplib, ssl
from email import encoders
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
URLs = ["https://botsin.space/@sitoctt.rss"]
Receivers = ["example@example.com"]
Sender = "example@example.com"
Password = "Example"
Server = "smtp.example.com"
Port = 465
LocalSave = True
MailSend = True
def MakePathStr(Str):
for c in ('<>:"/\\|?* '):
Str = Str.replace(c, '_')
return Str
def Main():
Feeds = [feedparser.parse(URL)['entries'] for URL in URLs]
for Feed in Feeds:
Feed.reverse() # Order from oldest to newest
for Entry in Feed:
if os.path.isfile('MastodonFeedToHTML.db'):
with open('MastodonFeedToHTML.db', 'r') as Db:
if Entry['id'] in Db.read().splitlines():
continue
try:
print(f"{Entry['id']} - {Entry['title']}")
Attached = ''
HTML = f"""\
<h1>{Entry['title']}</h1>
<div id="content">
{Entry['summary']}
{{ Replace:Attached }}
</div>
<br><hr><br>
<p>Published on {Entry['published']}</p>
<p>From <a href="{Entry['link']}">{Entry['link']}</a></p>
<br>
<h3>JSON dump</h3>
<div style="overflow-x:scroll;">
<xmp>
{Entry}
</xmp>
</div>
<p><i>Via <a href="https://gitlab.com/-/snippets/2388397">https://gitlab.com/-/snippets/2388397</a></i></p>
"""
Message = MIMEMultipart()
Message['From'] = Sender
Message['To'] = ', '.join(Receivers)
Message['Subject'] = Entry['title']
Message.attach(MIMEText(HTML.replace('{ Replace:Attached }', ''), 'html'))
for Link in Entry['links']:
if Link['type'].startswith(('audio/', 'image/', 'video/')):
Response = urllib.request.urlopen(Link['href'])
Data = Response.read()
Type = 'img' if Link['type'].startswith('image/') else Link['type'].split('/')[0]
Opening = f"<{Type}" if Type == 'img' else f"<{Type} controls"
Closing = '>' if Type == 'img' else f"></{Type}>"
Attached += f"""{Opening} style="max-width:100%;max-height:100vh;" src="data:{Link['type']};base64,{base64.b64encode(Data).decode()}"{Closing}\n"""
File = MIMEBase(Link['type'].split('/')[0], Link['type'].split('/')[1])
File.set_payload(Data)
encoders.encode_base64(File)
File.add_header(
"Content-Disposition",
f"attachment; filename= {Link['href'].split('/')[-1]}",
)
Message.attach(File)
if MailSend:
with smtplib.SMTP_SSL(Server, Port, context=ssl.create_default_context()) as Client:
Client.login(Sender, Password)
Client.sendmail(Sender, Receivers, Message.as_string())
if LocalSave:
LocalBackupDir = MakePathStr(Entry['title_detail']['base'].lstrip('https://').lstrip('http://'))
if not os.path.isdir(LocalBackupDir):
os.mkdir(LocalBackupDir)
FileName = MakePathStr(f"{Entry['id'].split('/')[-1]} - {Entry['title']}")
with open(f'{LocalBackupDir}/{FileName}.html', 'w') as File:
File.write(HTML.replace('{ Replace:Attached }', Attached))
with open('MastodonFeedToHTML.db', 'a') as Db:
Db.write(Entry['id'] + '\n')
except Exception:
raise
if __name__ == '__main__':
Main()