From 8ef903a7206a4c1bf65c2657a69e5150e504f758 Mon Sep 17 00:00:00 2001 From: unroll3677 Date: Mon, 14 Jul 2025 14:23:13 +0200 Subject: [PATCH] Update main.py added hashtag support --- main.py | 147 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 105 insertions(+), 42 deletions(-) diff --git a/main.py b/main.py index a02ac11..8644805 100644 --- a/main.py +++ b/main.py @@ -2,73 +2,136 @@ import feedparser from mastodon import Mastodon import os import time -# Replace these with your Mastodon application details and access token -MASTODON_CLIENT_ID = os.environ['MASTODON_CLIENT_ID'] -MASTODON_CLIENT_SECRET = os.environ['MASTODON_CLIENT_SECRET'] -MASTODON_ACCESS_TOKEN = os.environ['MASTODON_ACCESS_TOKEN'] -MASTODON_INSTANCE_URL = os.environ['MASTODON_INSTANCE_URL'] -TOOT_VISIBILITY = os.environ['TOOT_VISIBILITY'] # Toot visibility ('public', 'unlisted', 'private', or 'direct') -# RSS feed URL -RSS_FEED_URL = os.environ['RSS_FEED_URL'] -# File to store the processed entry URLs. Note that /state directory is for the docker setup +# --- Configuratie --- +# Haal configuratie op uit omgevingsvariabelen +MASTODON_CLIENT_ID = os.environ.get('MASTODON_CLIENT_ID') +MASTODON_CLIENT_SECRET = os.environ.get('MASTODON_CLIENT_SECRET') +MASTODON_ACCESS_TOKEN = os.environ.get('MASTODON_ACCESS_TOKEN') +MASTODON_INSTANCE_URL = os.environ.get('MASTODON_INSTANCE_URL') +RSS_FEED_URL = os.environ.get('RSS_FEED_URL') + +# Optionele configuratie met standaardwaarden +TOOT_VISIBILITY = os.environ.get('TOOT_VISIBILITY', 'public') # Standaard op 'public' +CHECK_INTERVAL = int(os.environ.get('CHECK_INTERVAL', 3600)) # Standaard op 1 uur (3600s) + +# Hashtags om toe te voegen aan elke post, gescheiden door spaties +HASHTAGS = os.environ.get('MASTO_RSS_HASHTAGS', '') + +# Bestand om de verwerkte entry-URL's op te slaan. +# De /state map is bedoeld voor een Docker-setup voor persistente data. PROCESSED_ENTRIES_FILE = '/state/processed_entries.txt' -# Time delay between RSS checks (in seconds) -CHECK_INTERVAL = os.environ['CHECK_INTERVAL'] # Check interval in seconds +# Controleer of alle benodigde configuratie aanwezig is +if not all([MASTODON_CLIENT_ID, MASTODON_CLIENT_SECRET, MASTODON_ACCESS_TOKEN, MASTODON_INSTANCE_URL, RSS_FEED_URL]): + print("Fout: Niet alle vereiste omgevingsvariabelen zijn ingesteld.") + print("Zorg ervoor dat MASTODON_CLIENT_ID, MASTODON_CLIENT_SECRET, MASTODON_ACCESS_TOKEN, MASTODON_INSTANCE_URL, en RSS_FEED_URL zijn ingesteld.") + exit(1) -# Initialize Mastodon client -mastodon = Mastodon( - client_id=MASTODON_CLIENT_ID, - client_secret=MASTODON_CLIENT_SECRET, - access_token=MASTODON_ACCESS_TOKEN, - api_base_url=MASTODON_INSTANCE_URL -) +# --- Mastodon Initialisatie --- +try: + mastodon = Mastodon( + client_id=MASTODON_CLIENT_ID, + client_secret=MASTODON_CLIENT_SECRET, + access_token=MASTODON_ACCESS_TOKEN, + api_base_url=MASTODON_INSTANCE_URL + ) + # Verifieer de inloggegevens + mastodon.account_verify_credentials() + print("Succesvol ingelogd bij Mastodon.") +except Exception as e: + print(f"Fout bij het initialiseren van de Mastodon client: {e}") + exit(1) + +# --- Functies --- -# Function to load processed entry URLs from a file def load_processed_entries(): + """Laadt verwerkte entry-URL's uit een bestand.""" + # Zorg ervoor dat de /state map bestaat + os.makedirs(os.path.dirname(PROCESSED_ENTRIES_FILE), exist_ok=True) try: with open(PROCESSED_ENTRIES_FILE, 'r') as file: return set(file.read().splitlines()) except FileNotFoundError: return set() -# Function to save processed entry URLs to a file def save_processed_entries(processed_entries): + """Slaat verwerkte entry-URL's op in een bestand.""" with open(PROCESSED_ENTRIES_FILE, 'w') as file: file.write('\n'.join(processed_entries)) -# Function to check and post new RSS items +def format_hashtags(hashtag_string): + """Formatteert een string van hashtags naar een correcte lijst.""" + if not hashtag_string: + return "" + # Split de string op spaties, verwijder eventuele lege items + tags = filter(None, hashtag_string.split(' ')) + # Voeg een '#' toe aan elke tag (als deze er nog niet is) en voeg ze samen + return " ".join([f"#{tag.lstrip('#')}" for tag in tags]) + def check_and_post_new_items(): + """Controleert de RSS-feed en post alleen het laatste item als het nieuw is.""" + + # Formatteer de hashtags eenmalig en geef feedback aan de gebruiker + formatted_hashtags = format_hashtags(HASHTAGS) + if formatted_hashtags: + print(f"Hashtags geconfigureerd voor deze sessie: {formatted_hashtags}") + else: + print("INFO: Geen hashtags geconfigureerd (omgevingsvariabele MASTO_RSS_HASHTAGS is leeg of niet ingesteld).") + + while True: - print("Checking for new RSS items...") - # Load processed entry URLs from the file + print(f"Controleren op nieuwe RSS-items van: {RSS_FEED_URL}") + + # Laad verwerkte entry-URL's uit het bestand processed_entries = load_processed_entries() - # Parse the RSS feed + # Parse de RSS-feed feed = feedparser.parse(RSS_FEED_URL) + + if feed.bozo: + print(f"Waarschuwing: De RSS-feed is mogelijk niet goed geformatteerd. Fout: {feed.bozo_exception}") - for entry in feed.entries: - entry_url = entry.link + # Controleer of er überhaupt items in de feed zijn + if not feed.entries: + print("Geen items gevonden in de RSS-feed.") + else: + # Neem alleen het laatste item (de eerste in de lijst, dit is de meest recente) + latest_entry = feed.entries[0] + entry_url = latest_entry.get('link') + entry_title = latest_entry.get('title', 'Geen titel') - # Check if the entry is new (not in the processed_entries set) - if entry_url not in processed_entries: - print(f"Found a new RSS item: {entry.title}") - # Create a Mastodon status - status = f"\n{entry.title}\n\n{entry.link}" + if not entry_url: + print(f"Laatste item '{entry_title}' overgeslagen omdat het geen link heeft.") + # Controleer of het laatste item nog niet is gepost + elif entry_url not in processed_entries: + print(f"Nieuw laatste item gevonden: {entry_title}") + + # Stel de Mastodon-status samen + status_parts = [entry_title, entry_url] + if formatted_hashtags: + status_parts.append(formatted_hashtags) + + status = "\n\n".join(status_parts) - # Post the status to Mastodon - mastodon.status_post(status, visibility=TOOT_VISIBILITY) + # Post de status naar Mastodon + try: + print(f"Bezig met posten: {status}") + mastodon.status_post(status, visibility=TOOT_VISIBILITY) + print("Post succesvol geplaatst.") + + # Voeg de URL toe aan de set van verwerkte items en sla direct op + processed_entries.add(entry_url) + save_processed_entries(processed_entries) + except Exception as e: + print(f"Fout bij het posten naar Mastodon: {e}") + else: + # Als de link al in de set zit, is het bericht al gepost. + print("Het laatste item is al gepost.") - # Add the entry URL to the processed_entries set - processed_entries.add(entry_url) - - # Save the updated processed_entries set to the file - save_processed_entries(processed_entries) - - print("Sleeping for", CHECK_INTERVAL, "seconds...") - # Wait for the specified interval before checking again - time.sleep(int(CHECK_INTERVAL)) + print(f"Wachten voor {CHECK_INTERVAL} seconden...") + time.sleep(CHECK_INTERVAL) +# --- Hoofdprogramma --- if __name__ == "__main__": check_and_post_new_items()