commit 1f09e7bc3e6b5ad09e416ec1eb9a9f34295f5756 Author: Nico Jensen Date: Sat Feb 8 03:35:18 2025 +0100 Init version 1 diff --git a/DeleteInactiveUser.py b/DeleteInactiveUser.py new file mode 100644 index 0000000..df733a0 --- /dev/null +++ b/DeleteInactiveUser.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 + +import json +from mastodon import Mastodon +import datetime +import sys + +CONFIG_FILE = "config.json" + +try: + with open(CONFIG_FILE, "r") as f: + config = json.load(f) + API_BASE_URL = config["server_url"] + ACCESS_TOKEN = config["access_token"] +except Exception as e: + sys.exit(f"Fehler beim Laden der Konfigurationsdatei {CONFIG_FILE}: {e}") + +try: + mastodon = Mastodon( + access_token=ACCESS_TOKEN, + api_base_url=API_BASE_URL + ) + + my_account = mastodon.me() +except Exception as e: + sys.exit(f"Fehler beim Verbinden mit der Instanz: {e}") + +my_id = my_account['id'] + +print("Lade alle Accounts, denen Du folgst...\n") +following = [] +accounts = mastodon.account_following(my_id) +following.extend(accounts) + +while accounts: + accounts = mastodon.fetch_next(accounts) + if accounts: + following.extend(accounts) + +print(f"Du folgst insgesamt {len(following)} Accounts.\n") + +now = datetime.datetime.now(datetime.timezone.utc) +threshold_date = now - datetime.timedelta(days=180) + +unfollowed_users = [] + +for account in following: + account_id = account['id'] + + full_acct = account.get('acct', account.get('username', 'Unbekannt')) + + + last_activity = None + if account.get('statuses_count', 0) > 0: + try: + statuses = mastodon.account_statuses(account_id, limit=1) + except Exception as e: + print(f"Fehler beim Abruf der Status für {full_acct}: {e}") + continue + if statuses: + last_activity = statuses[0]['created_at'] + + if last_activity is None: + last_activity = account.get('created_at', None) + + if last_activity is None: + print(f"Keine Aktivitätsdaten für {full_acct}. Überspringe diesen Account.") + continue + + if last_activity < threshold_date: + try: + mastodon.account_unfollow(account_id) + unfollowed_users.append((full_acct, last_activity)) + print(f"Entfolgt: {full_acct} – Letzte Aktivität: {last_activity.date()}") + except Exception as e: + print(f"Fehler beim Entfolgen von {full_acct}: {e}") + +if unfollowed_users: + print("\nZusammenfassung der entfolgten Accounts:") + for acct, last in unfollowed_users: + print(f"- {acct}: Letzte Aktivität am {last.date()}") +else: + print("Es wurden keine Accounts gefunden, die seit mehr als 6 Monaten inaktiv sind.") + +print("\nUnd wie der legendäre Giovanni Trapatoni einst sagte: 'Ich habe fertig!'\n") diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5f0d450 --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) [Jahr] [Dein Name] + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..4aa1069 --- /dev/null +++ b/README.md @@ -0,0 +1,64 @@ +# Mastodon Inactive Unfollower + +Dieses Python-Skript verbindet sich mit der Mastodon-API, liest alle Accounts aus, denen du folgst, und entfolgt automatisch diejenigen, die seit mehr als 6 Monaten inaktiv sind. Es zeigt ausschließlich die entfolgten Accounts (mit vollständiger Mastodon-Adresse) an und beendet die Ausführung mit einem humorvollen Spruch im Stil des legendären Trapatoni-Interviews. + +## Features + +- **API-Anbindung:** Verbindung zur Mastodon-API mittels [Mastodon.py](https://mastodonpy.readthedocs.io/) +- **Folgeliste abrufen:** Automatischer Abruf aller Accounts, denen du folgst (inklusive Paginierung) +- **Inaktivitätsprüfung:** Überprüfung des letzten Aktivitätsdatums (Status oder Kontoerstellungsdatum) jedes Accounts +- **Automatisches Entfolgen:** Entfernt automatisch Accounts, die seit über 6 Monaten inaktiv sind +- **Ausgabe:** Es werden nur die entfolgten Accounts mit ihrer vollständigen Mastodon-Adresse angezeigt + +## Voraussetzungen + +- Python 3.x +- [Mastodon.py](https://mastodonpy.readthedocs.io/) (Installation via `pip install Mastodon.py`) + +## Installation + +1. Klone das Repository: + + ```bash + git clone https://github.com/deinBenutzername/mastodon-inactive-unfollower.git + cd mastodon-inactive-unfollower + ``` + +2. Installiere die benötigten Abhängigkeiten: + + ```bash + pip install Mastodon.py + ``` + +## Konfiguration + +Erstelle im Projektverzeichnis eine Datei namens config.json. Der Inhalt der Datei sollte wie folgt aussehen: + + ```JSON + { + "server_url": "SERVER", + "access_token": "TOKEN" + } + ``` + +- server_url: Die URL deiner Mastodon-Instanz. +- access_token: Dein persönlicher Access-Token zur Authentifizierung bei der Mastodon-API. + +## Nutzung + +Führe das Skript über die Kommandozeile aus: + + ```JSON + python unfollow_inactive.py + ```gi + +Das Skript verbindet sich mit der Mastodon-API, ruft alle Accounts ab, denen du folgst, und entfolgt diejenigen, die seit mehr als 6 Monaten inaktiv sind. Anschließend wird eine Zusammenfassung der entfolgten Accounts ausgegeben, gefolgt von einem humorvollen Spruch im Stil des legendären Trapatoni-Interviews. + +## Lizenz + +Dieses Projekt steht unter der MIT-Lizenz. Siehe dazu die LICENSE Datei für weitere Informationen. + +## Hinweise + +- Achtung: Das Skript entfolgt automatisch inaktive Accounts. Bitte überprüfe vor der Ausführung, ob du mit dieser Vorgehensweise einverstanden bist. +- Zeitzonen: Das Skript arbeitet mit UTC-Zeit, um die Vergleichbarkeit der Aktivitätsdaten zu gewährleisten. \ No newline at end of file