From 42b14e0e520bb2bc511b92ebf745ce969e8f98b7 Mon Sep 17 00:00:00 2001 From: Daniel Langbein Date: Mon, 12 Dec 2022 20:22:38 +0100 Subject: [PATCH] Multiple changes - rework of "Conversation" class - "Update" class - Flask development server - Waitress production server - output as RSS/Atom feed - output as JSON and HTML - improved CLI output --- Makefile | 40 +++++++ requirements.txt | 5 +- src/mastodon_toot_follower/app.py | 6 +- src/mastodon_toot_follower/conversation.py | 99 ------------------ .../conversation/__init__.py | 0 .../conversation/conversation.py | 80 ++++++++++++++ .../conversation/update.py | 93 ++++++++++++++++ src/mastodon_toot_follower/main.py | 31 +++--- src/mastodon_toot_follower/mastodon_util.py | 14 +++ src/mastodon_toot_follower/path_util.py | 28 +++++ src/mastodon_toot_follower/server/__init__.py | 0 .../server/flask_server.py | 69 ++++++++++++ .../server/waitress_server.py | 8 ++ static/favicon.png | Bin 0 -> 48612 bytes static/index.js | 26 +++++ static/style.css | 50 +++++++++ templates/index.html | 39 +++++++ templates/updates.html | 36 +++++++ 18 files changed, 503 insertions(+), 121 deletions(-) create mode 100644 Makefile delete mode 100644 src/mastodon_toot_follower/conversation.py create mode 100644 src/mastodon_toot_follower/conversation/__init__.py create mode 100644 src/mastodon_toot_follower/conversation/conversation.py create mode 100644 src/mastodon_toot_follower/conversation/update.py create mode 100644 src/mastodon_toot_follower/mastodon_util.py create mode 100644 src/mastodon_toot_follower/server/__init__.py create mode 100644 src/mastodon_toot_follower/server/flask_server.py create mode 100755 src/mastodon_toot_follower/server/waitress_server.py create mode 100644 static/favicon.png create mode 100644 static/index.js create mode 100644 static/style.css create mode 100644 templates/index.html create mode 100644 templates/updates.html diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5dd20d1 --- /dev/null +++ b/Makefile @@ -0,0 +1,40 @@ +.ONESHELL: +SHELL := bash +# https://github.com/JordanMartinez/purescript-cookbook/blob/master/makefile +# set -e = bash immediately exits if any command has a non-zero exit status. +# set -u = a reference to any shell variable you haven't previously +# defined -- with the exceptions of $* and $@ -- is an error, and causes +# the program to immediately exit with non-zero code. +# set -o pipefail = the first non-zero exit code emitted in one part of a +# pipeline (e.g. `cat file.txt | grep 'foo'`) will be used as the exit +# code for the entire pipeline. If all exit codes of a pipeline are zero, +# the pipeline will emit an exit code of 0. +.SHELLFLAGS := -eu -o pipefail -c + +.PHONY: all +all: prod + +.PHONY: prod +prod: requirements.txt + source venv/bin/activate + export PYTHONPATH="${PYTHONPATH}:src" + python3 src/mastodon_toot_follower/server/waitress_server.py + +.PHONY: dev +dev: requirements.txt + source venv/bin/activate + export PYTHONPATH="${PYTHONPATH}:src" + python3 src/mastodon_toot_follower/server/flask_server.py + + +.PHONY: requirements.txt +requirements.txt: + if ! [ -d venv ]; then + python3 -m venv venv + source venv/bin/activate + python3 -m pip install -r requirements.txt + fi + +.PHONY: clean +clean: + rm -rf venv diff --git a/requirements.txt b/requirements.txt index b033626..6fb5355 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,4 @@ -Mastodon.py \ No newline at end of file +Mastodon.py +Flask +feedgen +waitress \ No newline at end of file diff --git a/src/mastodon_toot_follower/app.py b/src/mastodon_toot_follower/app.py index e1eda55..e1f6129 100644 --- a/src/mastodon_toot_follower/app.py +++ b/src/mastodon_toot_follower/app.py @@ -22,9 +22,9 @@ class App: config_dir.mkdir(parents=True, exist_ok=True) self._credential_dir().mkdir(parents=True, exist_ok=True) - self._toot_cache_dir().mkdir(parents=True, exist_ok=True) + self.toot_cache_dir().mkdir(parents=True, exist_ok=True) - def _get_mastodon(self, mastodon_instance: str) -> Mastodon: + def get_mastodon(self, mastodon_instance: str) -> Mastodon: if mastodon_instance not in self.mastodon_dict: self._create_or_load_credentials(mastodon_instance) # Create Mastdon API wrapper object. @@ -51,5 +51,5 @@ class App: def _credential_dir(self) -> Path: return self.config_dir.joinpath('credentials') - def _toot_cache_dir(self) -> Path: + def toot_cache_dir(self) -> Path: return self.config_dir.joinpath('toots') diff --git a/src/mastodon_toot_follower/conversation.py b/src/mastodon_toot_follower/conversation.py deleted file mode 100644 index 9f10abb..0000000 --- a/src/mastodon_toot_follower/conversation.py +++ /dev/null @@ -1,99 +0,0 @@ -from mastodon_toot_follower import path_util -import json -from mastodon_toot_follower.app import App - - -class Conversation: - def __init__(self, app: App, mastodon_instance: str, toot_id: str): - self.app = app - self.mastodon = self.app._get_mastodon(mastodon_instance) - - self.toot_id = toot_id - self.toot = self.mastodon.status(id=self.toot_id) - self.toot_file = self.app._toot_cache_dir().joinpath(path_util.escape(self.toot['uri']) + '.json') - - self._replies = None - self._changed_toots = None - self._saved = False - - def get_conversation_length(self) -> int: - return len(self.toots()) - - def get_changed_toots_and_update(self): - """ - Compares the old and current versions of this conversation. - Saves the current version of the conversation afterwards. - - :return: New and changes toots which are part of this conversation. - """ - if self.is_new(): - self._changed_toots = [] - self.save() - return self._changed_toots - else: - changed_toots = self.get_changed_toots() - if len(changed_toots) > 0: - self.save() - return changed_toots - - def get_changed_toots(self) -> list: - """ - Compares the old and current versions of this conversation. - - :return: New and changes toots which are part of this conversation. - """ - if self._changed_toots is None: - old_toots = self.load() - old_toots_dict = {old_toot['id']: old_toot['edited_at'] - for old_toot in old_toots} - toots = self.toots() - - self._changed_toots = [] - for toot in toots: - toot_id_not_found = object() - old_edited_at = old_toots_dict.get(toot['id'], toot_id_not_found) - if old_edited_at is toot_id_not_found or toot['edited_at'] != old_edited_at: - # New reply or has been edited. - self._changed_toots.append(toot) - - return self._changed_toots - - def is_new(self): - """ - :return: True if this is a new conversation of which no old version exists. - """ - return not self.toot_file.exists() - - def save(self): - """ - :return: Saves the current version of the conversation. This overwrites the previously saved version. - """ - if self._saved: - return - self._saved = True - toots = [{'id': entry['id'], 'edited_at': entry['edited_at']} - for entry in self.toots()] - with self.toot_file.open('w') as f: - f.write(json.dumps(toots)) - - def load(self) -> list: - """ - :return: Loads an old version of this conversation. - """ - if self._saved: - raise ValueError('The old version of this conversation has been overwritten.') - return json.loads(self.toot_file.read_text()) - - def toots(self) -> list: - """ - :return: List of initial toot and it's replies. - """ - return [self.toot] + self.replies() - - def replies(self) -> list: - """ - :return: List of replies to initial toot. - """ - if self._replies is None: - self._replies = self.mastodon.status_context(id=self.toot_id)['descendants'] - return self._replies diff --git a/src/mastodon_toot_follower/conversation/__init__.py b/src/mastodon_toot_follower/conversation/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/mastodon_toot_follower/conversation/conversation.py b/src/mastodon_toot_follower/conversation/conversation.py new file mode 100644 index 0000000..321fd45 --- /dev/null +++ b/src/mastodon_toot_follower/conversation/conversation.py @@ -0,0 +1,80 @@ +from feedgen.feed import FeedGenerator +from flask import url_for + +from mastodon_toot_follower import path_util +from mastodon_toot_follower.app import App +from mastodon_toot_follower.conversation.update import Update as ConversationUpdate + + +class Conversation: + def __init__(self, app: App, mastodon_instance: str, toot_id: str, seed: str = ''): + self.app = app + self.mastodon = self.app.get_mastodon(mastodon_instance) + + self.toot_id = toot_id + self.toot = self.mastodon.status(id=self.toot_id) + + if len(seed) > 0: + self.file = self.app.toot_cache_dir().joinpath(f'{path_util.escape(self.toot["uri"])}_{seed}.json') + else: + self.file = self.app.toot_cache_dir().joinpath(f'{path_util.escape(self.toot["uri"])}.json') + + # List of replies to initial toot. + self.replies = self.mastodon.status_context(id=self.toot_id)['descendants'] + + self.previous_updates: list[ConversationUpdate] = ConversationUpdate.load(self.file) + self.new_updates = ConversationUpdate.get_new_updates(self.previous_updates, self.toots()) + + self._changes_saved = False + + def as_feed(self, feed_url) -> FeedGenerator: + """ + Returns a FeedGenerator object "fg". + + atomfeed = fg.atom_str(pretty=True) # Get the ATOM feed as string + rssfeed = fg.rss_str(pretty=True) # Get the RSS feed as string + """ + + fg = FeedGenerator() + fg.id(self.toot['uri']) # Unique feed ID. + fg.title(f'MastodonConversation{self.toot_id}') + fg.author({'name': self.toot['account']['acct']}) + fg.link(href=self.toot['uri'], rel='alternate') # Webpage. + fg.logo(url_for('static', filename='favicon.png')) + fg.subtitle('RSS feed of a conversation on Mastodon.') + fg.link(href=feed_url, rel='self') # URL of the feed itself. + fg.language('en') + + update: ConversationUpdate + for update in self.updates(): + fe = fg.add_entry() + fe.id(update.dict['uri']) + acct = update.dict['acct'] + if update.dict['reason'] == 'new': + fe.title(f'Reply by {acct}') + fe.published(update.dict['created_at']) + else: + fe.title(f'Edit by {acct}') + fe.published(update.dict['edited_at']) + fe.link(href=update.dict['uri']) + fe.content(update.dict['content']) + + return fg + + def conversation_length(self) -> int: + return len(self.toots()) + + def toots(self) -> list: + """ + :return: List of initial toot and it's replies. + """ + return [self.toot] + self.replies + + def updates(self) -> list[ConversationUpdate]: + return self.previous_updates + self.new_updates + + def save_changes(self) -> None: + if self._changes_saved: + return + ConversationUpdate.save(self.updates(), self.file) + self._changes_saved = True diff --git a/src/mastodon_toot_follower/conversation/update.py b/src/mastodon_toot_follower/conversation/update.py new file mode 100644 index 0000000..e785dfa --- /dev/null +++ b/src/mastodon_toot_follower/conversation/update.py @@ -0,0 +1,93 @@ +from __future__ import annotations + +import inspect +from pathlib import Path +from typing import Literal +import json + + +class Update: + @classmethod + def save(cls, updates: list[Update], file: Path) -> None: + with file.open('w') as f: + dict_list = [update.dict for update in updates] + f.write(json.dumps(dict_list)) + + @classmethod + def load(cls, file: Path) -> list[Update]: + if not file.exists(): + return [] + dict_list = json.loads(file.read_text()) + return [cls._from_dict(d) for d in dict_list] + + @classmethod + def get_new_updates(cls, + previous_updates: list[Update], + toots: list[dict]) -> list[Update]: + previous_updates_dict = {pu.dict['id']: pu.dict['edited_at'] + for pu in previous_updates} + new_updates: list[Update] = [] + for toot in toots: + id_not_in_previous_updates = object() + old_edited_at = previous_updates_dict.get(toot['id'], id_not_in_previous_updates) + if old_edited_at is id_not_in_previous_updates: + new_updates.append(Update.new('new', toot)) + elif str(toot['edited_at']) != old_edited_at: + new_updates.append(Update.new('edited', toot)) + return new_updates + + @classmethod + def new(cls, reason: Literal['new', 'edited'], toot: dict) -> Update: + update = Update() + update.dict = { + 'reason': reason, + # + 'created_at': str(toot['created_at']), + 'edited_at': str(toot['edited_at']), + # + 'id': toot['id'], + 'uri': toot['uri'], + # + 'acct': toot['account']['acct'], + 'username': toot['account']['username'], + 'display_name': toot['account']['display_name'], + # + 'content': toot['content'], + 'language': toot['language'], + 'media_attachments': toot['media_attachments'], + } + return update + + @classmethod + def _from_dict(cls, d: dict) -> Update: + update = Update() + update.dict = d + return update + + def __init__(self): + # Make constructor "private": + # Can only be called from classmethod of Update class. + stack = inspect.stack() + if 'cls' not in stack[1][0].f_locals or stack[1][0].f_locals["cls"] is not Update: + raise ValueError('This constructor is private. Please use one of the classemthods.') + + self.dict = {} + + def get_title(self) -> str: + acct = self.dict['acct'] + if self.dict['reason'] == 'new': + return f'Reply by {acct}' + else: + return f'Edit by {acct}' + + def get_date(self): + acct = self.dict['acct'] + if self.dict['reason'] == 'new': + return self.dict['created_at'] + else: + return self.dict['edited_at'] + + def __str__(self): + return f'{self.get_date()}\n' \ + f'\t{self.get_title()}\n' \ + f'\t{self.dict["uri"]}\n' diff --git a/src/mastodon_toot_follower/main.py b/src/mastodon_toot_follower/main.py index 654b898..7f51777 100644 --- a/src/mastodon_toot_follower/main.py +++ b/src/mastodon_toot_follower/main.py @@ -1,8 +1,10 @@ -import re +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- import sys +from mastodon_toot_follower import mastodon_util from mastodon_toot_follower.app import App -from mastodon_toot_follower.conversation import Conversation +from mastodon_toot_follower.conversation.conversation import Conversation def main(): @@ -10,28 +12,21 @@ def main(): usage() toot_url = sys.argv[1] - # - # PARSE TOOT URL - # - - # Example: https://mastodon.instance/@user@another.instance/123456 - pattern = re.compile(r'(^https://[^/]+)/([^/]+)/([0-9]+)$') - match = pattern.match(toot_url) - if match is None: - print(f'Could not parse toot url: {toot_url}', file=sys.stderr) + try: + instance_url, username, toot_id = mastodon_util.parse_toot_url(url=toot_url) + except Exception as e: + print(e, file=sys.stderr) usage() - instance_url, username, toot_id = match.group(1), match.group(2), match.group(3) - - # - # RUN THE APP - # app = App() conversation = Conversation(app=app, mastodon_instance=instance_url, toot_id=toot_id) - print(f'Conversation length: {conversation.get_conversation_length()}') - print(f'Updates: {conversation.get_changed_toots_and_update()}') + conversation.save_changes() + + print(f'Conversation length: {conversation.conversation_length()}') + print(f'Conversation updates:\n') + print('\n'.join([str(update) for update in conversation.new_updates])) def usage(): diff --git a/src/mastodon_toot_follower/mastodon_util.py b/src/mastodon_toot_follower/mastodon_util.py new file mode 100644 index 0000000..6fbc466 --- /dev/null +++ b/src/mastodon_toot_follower/mastodon_util.py @@ -0,0 +1,14 @@ +import re + + +def parse_toot_url(url: str) -> tuple[str, str, str]: + """ + :param url: E.g. https://mastodon.instance/@user@another.instance/123456 + :return: instance, username, toot_id + """ + + pattern = re.compile(r'(^https://[^/]+)/([^/]+)/([0-9]+)$') + match = pattern.match(url) + if match is None: + raise ValueError(f'Could not parse toot url: {url}') + return match.group(1), match.group(2), match.group(3) diff --git a/src/mastodon_toot_follower/path_util.py b/src/mastodon_toot_follower/path_util.py index ad5b64a..3f9b5c8 100644 --- a/src/mastodon_toot_follower/path_util.py +++ b/src/mastodon_toot_follower/path_util.py @@ -1,2 +1,30 @@ +import os +from pathlib import Path + + def escape(filename: str) -> str: return filename.replace('/', '_') + + +def _get_path_util_py_dir() -> Path: + return Path(os.path.dirname(os.path.realpath(__file__))) + + +def get_src_dir() -> Path: + return _get_path_util_py_dir().parent + + +def get_project_dir() -> Path: + return get_src_dir().parent + + +def get_templates_dir() -> Path: + return get_project_dir().joinpath('templates') + + +def get_static_dir() -> Path: + return get_project_dir().joinpath('static') + + +if __name__ == '__main__': + get_project_dir() diff --git a/src/mastodon_toot_follower/server/__init__.py b/src/mastodon_toot_follower/server/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/mastodon_toot_follower/server/flask_server.py b/src/mastodon_toot_follower/server/flask_server.py new file mode 100644 index 0000000..ac60135 --- /dev/null +++ b/src/mastodon_toot_follower/server/flask_server.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +from enum import Enum + +from flask import Flask, Response, render_template +from flask import request + +from mastodon_toot_follower import mastodon_util, path_util +from mastodon_toot_follower.app import App as MastodonApp +from mastodon_toot_follower.conversation.conversation import Conversation + +# Create Flask's `app` object +app = Flask( + __name__, + instance_relative_config=False, + template_folder=str(path_util.get_templates_dir()), + static_folder=str(path_util.get_static_dir()), +) + +mastodon_app = MastodonApp() + + +class Templates(Enum): + index = 'index.html' + updates = 'updates.html' + + +@app.route('/', methods=['GET']) +def hello_world(): + return render_template(Templates.index.value) + + +@app.route('/rss/') +def rss(): + url = request.args.get('url', 'None') + instance_url, username, toot_id = mastodon_util.parse_toot_url(url=url) + + conversation = Conversation(app=mastodon_app, mastodon_instance=instance_url, toot_id=toot_id) + conversation.save_changes() + + fg = conversation.as_feed(request.url) + return Response(fg.rss_str(), mimetype='application/rss+xml') + + +@app.route('/html//') +def html(seed: str): + url = request.args.get('url', 'None') + instance_url, username, toot_id = mastodon_util.parse_toot_url(url=url) + + conversation = Conversation(app=mastodon_app, mastodon_instance=instance_url, toot_id=toot_id, seed=seed) + conversation.save_changes() + + return render_template(Templates.updates.value, updates=conversation.new_updates) + + +@app.route('/json//') +def json(seed: str): + url = request.args.get('url', 'None') + instance_url, username, toot_id = mastodon_util.parse_toot_url(url=url) + + conversation = Conversation(app=mastodon_app, mastodon_instance=instance_url, toot_id=toot_id, seed=seed) + conversation.save_changes() + + # If you return a dict or list from a view, it will be converted to a JSON response. + return [update.dict for update in conversation.new_updates] + + +if __name__ == '__main__': + app.run(host='0.0.0.0', port=5000) diff --git a/src/mastodon_toot_follower/server/waitress_server.py b/src/mastodon_toot_follower/server/waitress_server.py new file mode 100755 index 0000000..dca2f4c --- /dev/null +++ b/src/mastodon_toot_follower/server/waitress_server.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +from waitress import serve + +import flask_server + +if __name__ == '__main__': + serve(flask_server.app, host='0.0.0.0', port=5000) diff --git a/static/favicon.png b/static/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..0971b1ac4891eb7abe01eb625801c1726b97a8b5 GIT binary patch literal 48612 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 + + + + + + My Website + + + + + +
+

MastodonTootFollower

+

+ + +

+

+ + +

+
    +
  • + +
  • +
  • + +
  • +
  • + +
  • +
+

Resulting link:

+ +
+ + + diff --git a/templates/updates.html b/templates/updates.html new file mode 100644 index 0000000..0797cf8 --- /dev/null +++ b/templates/updates.html @@ -0,0 +1,36 @@ + + + + + + + My Website + + + + + + +

Consecutive Toot Updates

+ + + + + + + + + + + {% for update in updates %} + + + + + + {% endfor %} + +
DateAccountContent
{{ update.get_date() }}{{ update.dict['acct'] }}{{ update.dict['content'] | safe }}
+ + +