From 1bdeb215cf7bf0a94bc397323bab4636bd7a9ba7 Mon Sep 17 00:00:00 2001 From: rra Date: Thu, 23 Nov 2023 11:12:17 +0100 Subject: [PATCH] init --- README.md | 8 ++++ logansrun.py | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 README.md create mode 100644 logansrun.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fd1b8f --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +# Expire Accounts + +Python reimplementation of [Windfluechter's script](https://codeberg.org/Windfluechter/mastodon-scripts). WIP. + +# Depends on: + +* Python 3.6+ +* pyycopg2 diff --git a/logansrun.py b/logansrun.py new file mode 100644 index 0000000..1c5eeae --- /dev/null +++ b/logansrun.py @@ -0,0 +1,131 @@ +#!/bin/python3 + +import sys +import argparse +from os import system +from os import path +import psycopg2 + +LOWERLIMIT = "12 months" +UPPERLIMIT = "13 months" + + +site="post.lurk.org" #what you call your instance +siteurl="https://post.lurk.org/" #full url for your instance +siteadmin="lurk@bleu255.com" #admin email address +sitefrom="no-reply@post.lurk.org" # the "from" field for sending emails +protectedusers= "rra" #"" +sqlprotectedusers= "'rra', '320x200'"#"" +mastodonpath="/home/mastodon/live" + +#DB settings, can be found by running "grep -e ^"DB_" -e ^"LOCAL_DOMAIN" /home/mastodon/live/.env.production" +LOCAL_DOMAIN="post.lurk.org" +DB_HOST="/var/run/postgresql" +DB_PORT="5432" +DB_NAME="mastodon_production" +DB_USER="mastodon" +DB_PASS="" + +parser = argparse.ArgumentParser( + """ + This script recursively traverses folders and creates dithered versions of the images it finds. + These are stored in the same folder as the images in a folder called "dithers". + """ +) + +parser.add_argument( + "--do-it", help = "Don't run in test mode, this will lead you to possibly delete data", action="store_false" + ) + +parser.add_argument( + "--dry-run", help = "Running in test mode, no mails sent and nothing deleted. The Default.", action="store_true" + ) + +args = parser.parse_args() + + +#initialize DB connection + +connection = psycopg2.connect(database=DB_NAME, user=DB_USER, host=DB_HOST, port=DB_PORT, password=DB_PASS) +cursor = connection.cursor() +tootctl = path.join(mastodonpath, "bin/tootcl") + + +# set up the email templates that are sent out, variables are from the respective db queries + +#when LOWERLIMIT is hit, account gets a warning notification +notification_template = """ +Dear {dispname}, + +We are removing disused accounts from our database. You have a registered an account on {site} on {registered} and last time you logged in was on {last_login}. + +If you want to continue to keep your Mastodon account on {site} then please log in at least every {lowerlimit} via the web browser to keep your account active. Otherwise we assume that you don't want to use it anymore and will cancel your account {upperlimit} after your last login. + +You can: + +* access your profile at {profileurl} +* reset your password at {reseturl} +* export your posts and followers on {exporturl} +* or delete your account on your own via {deleteurl} after logging in. + +We would like to have you back though! Just login to keep your account.. or stay logged out for another month to automatically delete it. + +Sincerely, +your {site} admins +""" + +#when UPPERLIMIT is hit, account gets a deletion notice +deletion_template = """Dear {dispname}, + +Last month we mailed you about your account on {site}. Since you have not logged in again since {last_login}, our system has now deleted your account. In case you have any questions you can reach us at lurk@bleu255.com. + +Sincerely, +your {site} admins +""" #todo + +psql_unconfirmed_query = """select username, email from accounts a, users u where domain is null and a.id=u.account_id and last_sign_in_at is null and u.created_at < now()-'2 weeks'::interval and username not in ({})""".format(sqlprotectedusers) + +cursor.execute(psql_unconfirmed_query) + +results = cursor.fetchall() + +for username, usermail in results: + if not args.dry_run: + if username not in protectedusers: + os.system("{} accounts delete {}".format(tootctl, username)) + print("Deleting unconfirmed user {}".format(username)) + else: + print("Protected: skipping deleting unconfirmed user {}".format(username)) + if args.dry_run: + if username not in protectedusers: + print("Dry run: skipping deleting unconfirmed user {}".format(username)) + + +# Find all user accounts between lower and upper limit to send them a mail +psql_warning_query = """select username, display_name, email, to_char(a.created_at, 'YYYY-MM-DD'), to_char(last_sign_in_at,'YYYY-MM-DD') from accounts a, users u where domain is null and a.id=u.account_id and last_sign_in_at between now()-'{0}'::interval and now()-'{1}'::interval and username not in ({2}) order by last_sign_in_at""".format(UPPERLIMIT, LOWERLIMIT, sqlprotectedusers) + +cursor.execute(psql_warning_query) +results=cursor.fetchall() + +for username, display_name, email, registered_date, last_login in results: + if not display_name: + display_name = username + + if not args.dry_run: + if username not in protectedusers: + # SEND MAIL os.system() + print("Sending warning mail to {}/{}".format(username, display_name)) + print(notification_template.format(dispname=display_name, site=site, siteurl=siteurl, registered=registered_date, last_login=last_login, lowerlimit=LOWERLIMIT, upperlimit=UPPERLIMIT, profileurl=siteurl+'@'+username, exporturl=siteurl+"settings/export", deleteurl=siteurl+"settings/delete", reseturl=siteurl+"auth/password/new")) + else: + print("Protected: skipping warning mail for protected user {}".format(username)) + if args.dry_run: + print("Dry run: skipping warning mail for {}/{}".format(username, display_name)) + +# Find all who havent logged in since upper limit to send them a mail and delete the account +psql_deletion_query = """select username, display_name, email, to_char(a.created_at, 'YYYY-MM-DD'), to_char(last_sign_in_at,'YYYY-MM-DD') from accounts a, users u where domain is null and a.id=u.account_id and last_sign_in_at between now()-'{0}'::interval and username not in ({2}) order by last_sign_in_at""".format(UPPERLIMIT, LOWERLIMIT, sqlprotectedusers) + + + + + + \ No newline at end of file