From ef03ffaf00f392ddbc772ec0c10a3d4c75900a94 Mon Sep 17 00:00:00 2001 From: "Kaz Saita(raspi5)" Date: Sun, 5 May 2024 22:05:36 +0900 Subject: [PATCH] implement, working for taito-ku rss --- .gitignore | 2 + pyproject.toml | 10 ++- rss-mastodon-poster/__main__.py | 126 +++++++++++++++++++++++++++++--- 3 files changed, 126 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 59e0d00..179e182 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ .venv/* poetry.lock __pycache__/ +.env +config.yaml diff --git a/pyproject.toml b/pyproject.toml index 9034d58..194fafd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,8 +1,8 @@ [tool.poetry] -name = "python-project-template" +name = "rss-mastodon-poster" version = "0.1.0" -description = "template project for pyenv+poetry" -authors = ["Kaz Saita(raspi4) "] +description = "rss -> mastodon" +authors = ["Kaz Saita "] license = "MIT" readme = "README.md" package-mode = false @@ -10,6 +10,10 @@ package-mode = false [tool.poetry.dependencies] python = "^3.11" feedparser = "^6.0.11" +mastodon-py = "^1.8.1" +python-dotenv = "^1.0.1" +pyyaml = "^6.0.1" +python-dateutil = "^2.9.0.post0" [build-system] diff --git a/rss-mastodon-poster/__main__.py b/rss-mastodon-poster/__main__.py index 86bd30d..f972036 100644 --- a/rss-mastodon-poster/__main__.py +++ b/rss-mastodon-poster/__main__.py @@ -1,22 +1,130 @@ # !/usr/bin/env python3 +import dotenv +dotenv.load_dotenv() +import os import feedparser +from mastodon import Mastodon import pprint +import yaml +import datetime +from dateutil import parser as datetimeparser +import zoneinfo +import time -# rss_url = "https://www.city.taito.lg.jp/rss_news.xml" -rss_url = 'https://notes.kinoshita-lab.org/index.xml' +config_file = 'config.yaml' +items = [] +last_toot_id = '' +rss_url = '' +mastodon = None +config_parsed = {} + +class RssItem: + def __init__(self, title :str, date :str , url :str, id :str) -> None: + self.title = title + self.date = date + self.url = url + self.id = id -def main(): + + +def readRss() -> None: + global config_file + global config_parsed + global rss_url + last_id = '' + + def read_config() -> None: + global rss_url + global config_parsed + nonlocal last_id + + try: + with open(config_file, 'r') as file: + config_parsed = yaml.safe_load(file) or {} + rss_url = config_parsed.get('RSS_URL') + last_id = config_parsed.get('LAST_ID') + except Exception as e: + print("Read config error: ", e) + + + read_config() + parsed = feedparser.parse(rss_url) + for entry in parsed.entries: - print("id: {}".format(entry.id)) - print("title: {}".format(entry.title)) - print("link: {}".format(entry.link)) - print("published: {}".format(entry.published)) - # print("description: {}".format(entry.description)) - # pprint.pprint(entry) + + if entry.id == last_id: + print(f'found last processed id: {last_id}, stop') + break + date = datetimeparser.parse(entry.published) + date_timezone = date.astimezone(zoneinfo.ZoneInfo('Japan')) + formatted_date = date_timezone.strftime('%Y/%m/%d %H:%M') + print(formatted_date) + + item = RssItem(entry.title, formatted_date, entry.link, entry.id) + items.append(item) + + items.reverse() # old to new order + + + + + +def login() -> Mastodon: + url = os.getenv('MASTODON_URL') + if (url == None): + print("error: no mastodon url specified.") + exit() + + token = os.getenv('MASTODON_TOKEN') + if (token == None): + print("error: no mastodon token specified.") + exit() + + m = Mastodon( + access_token=token, + api_base_url=url + ) + + return m + +def post_to_mastodon(message: str) -> bool: + global mastodon + + print(message) + + if mastodon == None: + return False + + mastodon.status_post(message) + + return True + +def main() -> None: + global mastodon + global items + global config_parsed + + readRss() + mastodon = login() + + for item in items: + message = item.title + '\n' + message += item.date + '\n\n' + message += item.url + '' + + + result = post_to_mastodon(message) + if result == True: + config_parsed['LAST_ID'] = item.id + with open(config_file, 'w') as f: + yaml.dump(config_parsed, f, default_flow_style=False) + time.sleep(10) + + if __name__ == '__main__': main()