Compare commits

...

10 commits

5 changed files with 134 additions and 91 deletions

View file

@ -48,6 +48,8 @@ Customize the templates (if you know HTML, CSS and Jinja2) and run the command.
-P, --mail-pass TEXT User password for SMTP Mail server to send -P, --mail-pass TEXT User password for SMTP Mail server to send
emails. emails.
-p, --mail-server-port INTEGER SMTP Mail server port to send emails. -p, --mail-server-port INTEGER SMTP Mail server port to send emails.
-t, --subjet-template TEXT Jinja2 template for the subject of the
emails.
-l, --log-file TEXT File to store all debug messages. -l, --log-file TEXT File to store all debug messages.
--config FILE Read configuration from FILE. --config FILE Read configuration from FILE.
--help Show this message and exit. --help Show this message and exit.

View file

@ -18,7 +18,8 @@ import sqlite3
import click import click
import click_config_file import click_config_file
import requests import requests
from jinja2 import Environment, PackageLoader, select_autoescape, FileSystemLoader from jinja2 import Environment, select_autoescape, FileSystemLoader
import importlib
class MastodonEmailBridge: class MastodonEmailBridge:
'''CLass to redirect the Mastodon home timeline to email''' '''CLass to redirect the Mastodon home timeline to email'''
@ -170,19 +171,19 @@ class MastodonEmailBridge:
sender = self._str_template(self.config['sender'], data) sender = self._str_template(self.config['sender'], data)
recipient = self._str_template(self.config['recipient'], data) recipient = self._str_template(self.config['recipient'], data)
msg = MIMEMultipart('alternative') msg = MIMEMultipart('alternative')
if data['in_reply_to_id']: msg['Subject'] = self._str_template(self.config['subjet_template'], data)
msg['Subject'] = f"FediReply from {data['account']['display_name']} ({data['account']['username']})"
else:
msg['Subject'] = f"FediPost from {data['account']['display_name']} ({data['account']['username']})"
msg['From'] = sender msg['From'] = sender
msg['Date'] = time.strftime('%a, %d %b %Y %H:%M:%S %z')
msg['To'] = recipient msg['To'] = recipient
html_template = self.j2env.get_template("new_post.html.j2") html_template = self.j2env.get_template("new_post.html.j2")
html_source = html_template.render( html_source = html_template.render(
imp0rt = importlib.import_module,
data=data, data=data,
json_raw=json.dumps(data, indent=2) json_raw=json.dumps(data, indent=2)
) )
txt_template = self.j2env.get_template("new_post.txt.j2") txt_template = self.j2env.get_template("new_post.txt.j2")
txt_source = txt_template.render( txt_source = txt_template.render(
imp0rt = importlib.import_module,
data=data, data=data,
json_raw=json.dumps(data, indent=2) json_raw=json.dumps(data, indent=2)
) )
@ -321,6 +322,12 @@ class MastodonEmailBridge:
default=465, default=465,
help='SMTP Mail server port to send emails.' help='SMTP Mail server port to send emails.'
) )
@click.option(
'--subjet-template',
'-t',
default='{{ data["account"]["display_name"] }} ({{ data["account"]["username"] }}) {% if data["in_reply_to_id"] %}replied {% else %}posted{% endif %}{% for tag in data["tags"] %} #{{ tag["name"] }}{% endfor %}',
help='Jinja2 template for the subject of the emails.'
)
@click.option('--log-file', '-l', help="File to store all debug messages.") @click.option('--log-file', '-l', help="File to store all debug messages.")
# @click.option("--dummy","-n", is_flag=True, # @click.option("--dummy","-n", is_flag=True,
# help="Don't do anything, just show what would be done.") # help="Don't do anything, just show what would be done.")

View file

@ -7,7 +7,7 @@ Homepage = "https://codeberg.org/adelgado/mastodon_email_bridge"
[project] [project]
name = "mastodon_email_bridge" name = "mastodon_email_bridge"
version = "0.0.6" version = "1.0.0"
description = "Redirect your Mastodon Home timeline to your email" description = "Redirect your Mastodon Home timeline to your email"
readme = "README.md" readme = "README.md"
authors = [{ name = "Antonio J. Delgado", email = "ad@susurrando.com" }] authors = [{ name = "Antonio J. Delgado", email = "ad@susurrando.com" }]

View file

@ -1,6 +1,6 @@
[metadata] [metadata]
name = mastodon_email_bridge name = mastodon_email_bridge
version = 0.0.6 version = 1.0.0
[options] [options]
packages = mastodon_email_bridge packages = mastodon_email_bridge

View file

@ -1,3 +1,4 @@
{% set time = imp0rt( 'time' ) %}
<!doctype html> <!doctype html>
<html lang="{{ data['language'] }}"> <html lang="{{ data['language'] }}">
<head> <head>
@ -6,7 +7,10 @@
<style> <style>
body { background-color: black; color: #999;} body { background-color: black; color: #999;}
p { } p { }
div { margin: 1%; } div {
margin: 1%;
{# border-style: dashed; #}
}
/* unvisited link */ /* unvisited link */
a:link { a:link {
color: blueviolet; color: blueviolet;
@ -27,78 +31,96 @@
<BODY> <BODY>
{% if data['url'] != "" %} {% if data['url'] != "" %}
<!-- URL --> <!-- URL -->
<DIV>
<A TARGET="_blank" HREF="{{ data['url'] }}">Post original page</A> <A TARGET="_blank" HREF="{{ data['url'] }}">Post original page</A>
</DIV>
{% endif %} {% endif %}
<!-- creation_date -->
<P STYLE='font-size: 12px;'>
{% set created_date = time.strptime(data['created_at'], '%Y-%m-%dT%H:%M:%S.%fZ') %}
{{ time.strftime('%Y-%m-%d %H:%M:%S %zUTC', created_date) }}
</P>
<!-- account bloc --> <!-- account bloc -->
<DIV> <TABLE>
<A HREF="{{ data['account']['url'] }}" TARGET="_blank"></A> <TR>
<TD>
<A HREF="{{ data['account']['url'] }}" TARGET="_blank">
<IMG ALT="{{ data['account']['display_name'] }} avatar image" SRC="{{ data['account']['avatar_static'] }}" STYLE="width:64px;height:64px;margin:1%;float: left;"> <IMG ALT="{{ data['account']['display_name'] }} avatar image" SRC="{{ data['account']['avatar_static'] }}" STYLE="width:64px;height:64px;margin:1%;float: left;">
<B>{{ data['account']['display_name'] }} ({{ data['account']['username'] }})</B>
</A> </A>
</DIV> </TD>
<!-- creation_date --> <TD>
<DIV STYLE='font-size: 0.75em;'> <A HREF="{{ data['account']['url'] }}" TARGET="_blank">
{{ data['created_at'] }} <B>{{ data['account']['display_name'] }} ({{ data['account']['acct'] }})</B>
</DIV> </A>
</TD>
</TR>
</TABLE>
<!-- content block --> <!-- content block -->
<DIV STYLE='font-size: 1.5em;'> <DIV STYLE='font-size: 24px;'>
{% if data['spoiler'] != "" and data['spoiler'] != null %}
<!-- spoiler --> <!-- spoiler -->
<DIV CLASS='item-spoiler'> <DIV CLASS='item-spoiler'>
{{ data['spoiler'] }} {{ data['spoiler'] }}
</DIV> </DIV>
{% endif %}
<!-- item-content --> <!-- item-content -->
<DIV CLASS='item-content' STYLE="margin:5%;"> <DIV CLASS='item-content' STYLE="margin:0.5%;background-color:#111;padding:0.5%;">
{{ data['content'] }} {{ data['content'] }}
<!-- media --> <!-- media -->
{% if data['media_attachments'] %} {% if data['media_attachments'] %}
{% for media in data['media_attachments'] %} {% for media in data['media_attachments'] %}
<DIV STYLE="margin:2%;"> {% if media['type'] == 'image' -%}
{% if media['type'] == 'image' %}
<IMG SRC="{{ media['preview_url'] }}" ALT="{{ media['description'] }}"> <IMG SRC="{{ media['preview_url'] }}" ALT="{{ media['description'] }}">
{% elif media['type'] == 'video' or media['type'] == 'gifv' %} {% elif media['type'] == 'video' or media['type'] == 'gifv' -%}
<video controls width="100%"> <video controls height="50%">
<source src="{{ media['url'] }}" type="video/webm" /> <source src="{{ media['url'] }}" type="video/webm" />
<A HREF="{{ media['url'] }}">Download video</A> <A HREF="{{ media['url'] }}">Download video</A>
</video> </video>
{% elif media['type'] == 'audio' %} {% elif media['type'] == 'audio' -%}
<audio controls src="{{ media['url'] }}"></audio> <audio controls src="{{ media['url'] }}"></audio>
<A HREF="{{ media['url'] }}">Download audio</A> <A HREF="{{ media['url'] }}">Download audio</A>
{% endif %} {% else %}
</DIV> <object data="{{ media['url'] }}"></object>
{%- endif %}
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% if data['reply'] %} {% if data['meb_reply_to'] %}
{% for reply in data['meb_reply_to'] %}
<!-- reply --> <!-- reply -->
<DIV STYLE="margin:5%;"> <A TARGET="_blank" HREF="{{ reply['url'] }}">Reply original page</A>
<DIV> <!-- creation_date -->
<A TARGET="_blank" HREF="{{ data['reply']['url'] }}">Reply original page</A> <P STYLE='font-size: 12px;'>
</DIV> {% set reply_created_date = time.strptime(reply['created_at'], '%Y-%m-%dT%H:%M:%S.%fZ') %}
{{ time.strftime('%Y-%m-%d %H:%M:%S %zUTC', reply_created_date) }}
</P>
<DIV STYLE="margin:1%;">
<!-- reply-account --> <!-- reply-account -->
<DIV> <TABLE>
<A HREF="{{ data['reply']['account']['url'] }}" TARGET="_blank"></A> <TR>
<IMG ALT="{{ data['reply']['account']['display_name'] }} avatar image" SRC="{{ data['reply']['account']['avatar_static'] }}" STYLE='width:64px;height:64px;margin:1%;float: left;'> <TD>
<B>{{ data['reply']['account']['display_name'] }} ({{ data['reply']['account']['username'] }})</B> <A HREF="{{ reply['account']['url'] }}" TARGET="_blank">
<IMG ALT="{{ reply['account']['display_name'] }} avatar image" SRC="{{ reply['account']['avatar_static'] }}" STYLE="width:64px;height:64px;margin:1%;float: left;">
</A> </A>
</DIV> </TD>
<!-- reply_creation_date --> <TD>
<DIV STYLE='font-size: 0.75em;'> <A HREF="{{ reply['account']['url'] }}" TARGET="_blank">
{{ data['reply']['created_at'] }} <B>{{ reply['account']['display_name'] }} ({{ reply['account']['acct'] }})</B>
</DIV> </A>
</TD>
</TR>
</TABLE>
<!-- reply_content_bloc --> <!-- reply_content_bloc -->
<DIV STYLE='font-size: 1.5em;'> <DIV STYLE='font-size: 24px;'>
<!-- reply_spoiler --> <!-- reply_spoiler -->
<DIV CLASS='reply-spoiler'> <DIV CLASS='reply-spoiler'>
{{ data['reply']['spoiler'] }} {{ reply['spoiler'] }}
</DIV> </DIV>
<!-- reply_content --> <!-- reply_content -->
<DIV CLASS='reply-content'> <DIV CLASS='reply-content'>
{{ data['reply']['content'] }} {{ reply['content'] }}
<!-- media --> <!-- media -->
{% if data['reply']['media_attachments'] %} {% if reply['media_attachments'] %}
{% for media in data['reply']['media_attachments'] %} {% for media in reply['media_attachments'] %}
{% if media['type'] == 'image' %} {% if media['type'] == 'image' %}
<IMG SRC="{{ media['preview_url'] }}" ALT="{{ media['description'] }}"> <IMG SRC="{{ media['preview_url'] }}" ALT="{{ media['description'] }}">
{% elif media['type'] == 'video' %} {% elif media['type'] == 'video' %}
@ -109,32 +131,43 @@
{% elif media['type'] == 'audio' %} {% elif media['type'] == 'audio' %}
<audio controls src="{{ media['url'] }}"></audio> <audio controls src="{{ media['url'] }}"></audio>
<A HREF="{{ media['url'] }}">Download audio</A> <A HREF="{{ media['url'] }}">Download audio</A>
{% else %}
<object data="{{ media['url'] }}"></object>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
{% endif %} {% endif %}
</DIV> </DIV>
</DIV> </DIV>
</DIV> </DIV>
{% endfor %}
{% endif %} {% endif %}
{% if data['reblog'] %} {% if data['reblog'] %}
<!-- reblog --> <!-- reblog -->
<DIV STYLE="margin:5%;"> <DIV STYLE="margin:1%;">
<DIV> <!-- reply -->
<A TARGET="_blank" HREF="{{ data['reblog']['url'] }}">Reply original page</A> <A TARGET="_blank" HREF="{{ data['reblog']['url'] }}">Reply original page</A>
</DIV> <!-- creation_date -->
<P STYLE='font-size: 12px;'>
{% set reblog_created_date = time.strptime(data['reblog']['created_at'], '%Y-%m-%dT%H:%M:%S.%fZ') %}
{{ time.strftime('%Y-%m-%d %H:%M:%S %zUTC', reblog_created_date) }}
</P>
<!-- reblog-account --> <!-- reblog-account -->
<DIV> <TABLE>
<A HREF="{{ data['reblog']['account']['url'] }}" TARGET="_blank"></A> <TR>
<IMG ALT="{{ data['reblog']['account']['display_name'] }} avatar image" SRC="{{ data['reblog']['account']['avatar_static'] }}" STYLE='width:64px;height:64px;margin:1%;float: left;'> <TD>
<B>{{ data['reblog']['account']['display_name'] }} ({{ data['reblog']['account']['username'] }})</B> <A HREF="{{ data['reblog']['account']['url'] }}" TARGET="_blank">
<IMG ALT="{{ data['reblog']['account']['display_name'] }} avatar image" SRC="{{ data['reblog']['account']['avatar_static'] }}" STYLE="width:64px;height:64px;margin:1%;float: left;">
</A> </A>
</DIV> </TD>
<!-- reblog_creation_date --> <TD>
<DIV STYLE='font-size: 0.75em;'> <A HREF="{{ data['reblog']['account']['url'] }}" TARGET="_blank">
{{ data['reblog']['created_at'] }} <B>{{ data['reblog']['account']['display_name'] }} ({{ data['reblog']['account']['acct'] }})</B>
</DIV> </A>
</TD>
</TR>
</TABLE>
<!-- reblog_content_bloc --> <!-- reblog_content_bloc -->
<DIV STYLE='font-size: 1.5em;'> <DIV STYLE='font-size: 24px;'>
<!-- reblog_spoiler --> <!-- reblog_spoiler -->
<DIV CLASS='reblog-spoiler'> <DIV CLASS='reblog-spoiler'>
{{ data['reblog']['spoiler'] }} {{ data['reblog']['spoiler'] }}
@ -165,9 +198,10 @@
</DIV> </DIV>
</DIV> </DIV>
{# <!-- card -->{{ data['card'] }} #} {# <!-- card -->{{ data['card'] }} #}
<!-- Raw JSON data --> <!-- Raw JSON data
<DIV STYLE="margin-top:15%;font-size:0.75em;"> <DIV STYLE="margin-top:15%;font-size: 12px;">
Raw JSON data: Raw JSON data:
<PRE>{{ json_raw }}</PRE> <PRE>{{ json_raw }}</PRE>
</DIV> </DIV>
-->
</BODY> </BODY>