use setuptools and add multi-user
Resolves #20 - now uses setuptools for easy installation with pip Resolves #13 - can now manage multiple accounts Config file is now in YAML and is passed to script with --config flag Can now execute from anywhere
This commit is contained in:
parent
ff448a45bd
commit
61d0d01f12
|
@ -1 +1,2 @@
|
|||
config.py
|
||||
config.py
|
||||
config.yaml
|
160
README.md
160
README.md
|
@ -1,90 +1,160 @@
|
|||
A script for deleting old toots.
|
||||
A tool for deleting old toots, written in Python 3.
|
||||
|
||||
Based partially on [tweet-deleting script](https://gist.github.com/flesueur/bcb2d9185b64c5191915d860ad19f23f) by [@flesueur](https://github.com/flesueur)
|
||||
# Prior work
|
||||
The initial `ephemetoot` script was based on [this tweet-deleting script](https://gist.github.com/flesueur/bcb2d9185b64c5191915d860ad19f23f) by [@flesueur](https://github.com/flesueur)
|
||||
|
||||
`ephemetoot` relies heavily on the Mastodon.py package by [@halcy](https://github.com/halcy)
|
||||
|
||||
# Usage
|
||||
|
||||
You can use this script to delete [Mastodon](https://github.com/tootsuite/mastodon) toots that are older than a certain number of days. By default it will keep any pinned toots, but if you want them to be deleted as well you can change `keep_pinned` to `False` in `config.py`. You can also make a list toots that you want to keep, by adding the ID numbers to the `toots_to_keep` list in `config.py` (see point 9 below). The ID of a toot is the last part of its individual URL. e.g. for [https://ausglam.space/@hugh/101294246770105799](https://ausglam.space/@hugh/101294246770105799) the id is `101294246770105799`
|
||||
|
||||
This script requires Python3, the `mastodon.py` package and an API access token.
|
||||
You can use `ephemetoot` to delete [Mastodon](https://github.com/tootsuite/mastodon) toots that are older than a certain number of days. Toots can optionally be saved from deletion if:
|
||||
* they are pinned;
|
||||
* they include certain hashtags;
|
||||
* they have certain visibility; or
|
||||
* they are individually listed to be kept
|
||||
|
||||
# Setup
|
||||
|
||||
1. Install Python3 if you don't already have it (recommended approach is to [use Homebrew](https://docs.brew.sh/Homebrew-and-Python) if you're on MacOS)
|
||||
2. Install the mastodon package: `pip3 install mastodon.py`
|
||||
3. Copy _example.config.py_ to a new file called _config.py_ (e.g. `cp example.config.py config.py`)
|
||||
4. Log in to your Mastodon account using a web browser
|
||||
1. Click the settings cog
|
||||
2. Click on Development
|
||||
3. Click 'NEW APPLICATION'
|
||||
4. Enter an application name, and give the app 'read' and 'write' Scopes
|
||||
5. Click 'SUBMIT'
|
||||
6. Click on the name of the new app
|
||||
7. Copy the 'access token' string
|
||||
5. Replace `YOUR_ACCESS_TOKEN_HERE` in config.py with the access token string
|
||||
6. Set the `base_url` to match your mastodon server
|
||||
7. Set the `days_to_keep` to the number of days you want to keep toots before deleting them
|
||||
8. If you do **not** wish to keep all pinned toots regardless of age, change `keep_pinned` to `False`
|
||||
9. If there are any other toots you want to keep, put the ID numbers (without quotes) in the `toots_to_keep` list, separated by commas. For example:
|
||||
```python
|
||||
toots_to_keep = [100029521330725397, 100013562864734780, 100044187305250752]
|
||||
## Install Python 3
|
||||
|
||||
You need to [install Python 3](https://wiki.python.org/moin/BeginnersGuide/Download) to use `ephemetoot`. Python 2 is now end-of-life, however it continued to be installed as the default Python on MacOS until very recently, and may also be installed on your server.
|
||||
|
||||
## Install ephemetoot
|
||||
### get code with git
|
||||
If you already have `git` installed on the machine where you're running ephemetoot, you can download the latest release with:
|
||||
```shell
|
||||
git clone https://github.com/hughrun/ephemetoot.git
|
||||
```
|
||||
10. If you want to keep toots with a particular hashtag, list each hashtag in the `hashtags_to_keep` set (omitting the `#`):
|
||||
```python
|
||||
hashtags_to_keep = {'introduction', 'announcement'}
|
||||
### get code by downloading zip file
|
||||
If you don't have `git` or don't want to use it, you can download the zip file by clicking the green `Clone or download` button above and selecting `Download ZIP`. You will then need to unzip the file into a new directory where you want to run it.
|
||||
|
||||
### install using pip
|
||||
From a command line, move into the main `ephemetoot` directory (i.e. where the README file is) and run:
|
||||
```shell
|
||||
pip install .
|
||||
```
|
||||
11. You can keep toots with particular visibility (e.g. direct messages) by including that visibility in `visibility_to_keep`. For example the following would only delete public toots:
|
||||
```python
|
||||
visibility_to_keep = ['unlisted', 'private', 'direct']
|
||||
With some Python 3 installations (e.g on MacOS with Homebrew) you may need to use:
|
||||
```shell
|
||||
pip3 install .
|
||||
```
|
||||
|
||||
## Obtain an access token
|
||||
|
||||
Now you've installed `ephemetoot`, in order to actually use it you will need an application "access token" from each user. Log in to your Mastodon account using a web browser:
|
||||
|
||||
1. Click the `settings` cog
|
||||
2. Click on `Development`
|
||||
3. Click `NEW APPLICATION`
|
||||
4. Enter an application name (e.g. 'ephemetoot'), and give the app both 'read' and 'write' Scopes
|
||||
5. Click `SUBMIT`
|
||||
6. Click on the name of the new app, which should be a link
|
||||
7. Copy the `Your access token` string
|
||||
|
||||
## Configuration file
|
||||
|
||||
As of version 2, you can use a single `ephemetoot` installation to delete toots from multiple accounts. Configuration for each user is set up in the `config.yaml` file. This uses [yaml syntax](https://yaml.org/spec/1.2/spec.html) and can be updated at any time without having to reload `ephemetoot`.
|
||||
|
||||
Copy `example-config.yaml` to a new file called `config.yml`:
|
||||
```shell
|
||||
cp example-config.yam config.yaml
|
||||
```
|
||||
You can now enter the configuration details for each user:
|
||||
|
||||
| setting | description |
|
||||
| ---: | :--- |
|
||||
| access_token | The alphanumeric access token string from the app you created in Mastodon |
|
||||
| username | Your username without the '@' or server domain. e.g. `hugh`|
|
||||
| base_url | The base url of your Mastodon server, without the 'https://'. e.g. `ausglam.space`|
|
||||
| days_to_keep | Number of days to keep toots e.g. `30`|
|
||||
| keep_pinned | Either `True` or `False` - if `True`, any pinned toots will be kept regardless of age |
|
||||
| toots_to_keep | A list of toot ids indicating toots to be kept regardless of other settings. The ID of a toot is the last part of its individual URL. e.g. for [https://ausglam.space/@hugh/101294246770105799](https://ausglam.space/@hugh/101294246770105799) the id is `101294246770105799` |
|
||||
| hashtags_to_keep | a Set of hashtags, where any toots with any of these hashtags will be kept regardless of age. Do not include the '#' symbol, and remember the [rules for hashtags](https://docs.joinmastodon.org/user/posting/#hashtags) |
|
||||
| visibility_to_keep | Any toots with visibility settings in this list will be kept regardless of age. Options are: `public`, `unlisted`, `private`, `direct`. For example the following would only delete public toots:
|
||||
```yaml
|
||||
- unlisted
|
||||
- private
|
||||
- direct
|
||||
```
|
||||
|
|
||||
|
||||
If you want to use `ephemetoot` for multiple accounts, separate the config for each user with a single dash (`-`), as shown in the example file.
|
||||
|
||||
# Running the script
|
||||
|
||||
## Test mode
|
||||
It is **strongly recommended** that you do a [test run](#running-in-test-mode) before using `ephemetoot` live.
|
||||
|
||||
To call the script you can simply enter:
|
||||
```shell
|
||||
ephemetoot
|
||||
```
|
||||
|
||||
Depending on how many toots you have and how long you want to keep them, it may take a minute or two before you see any results.
|
||||
|
||||
## Specifying the config location
|
||||
|
||||
By default ephemetoot expects there to be a config file called `config.yaml` in the directory from where you run the `ephemetoot` command. If you want to call it from elsewhere (e.g. from `cron`), you need to specify where your config file is:
|
||||
|
||||
```shell
|
||||
ephemetoot --config 'directory/config.yaml'
|
||||
```
|
||||
|
||||
## Running in test mode
|
||||
|
||||
To do a test-run without actually deleting anything, run the script with the `--test` flag:
|
||||
```shell
|
||||
python3 ephemetoot.py --test
|
||||
ephemetoot --test
|
||||
```
|
||||
Depending on how many toots you have and how long you want to keep them, it may take a minute or two before you see any results.
|
||||
|
||||
## Live mode
|
||||
## Other flag options
|
||||
|
||||
Run the script with no flags:
|
||||
You can use both flags together:
|
||||
```shell
|
||||
python3 ephemetoot.py
|
||||
ephemetoot --config 'directory/config.yaml' --test
|
||||
```
|
||||
Use them in any order:
|
||||
```shell
|
||||
ephemetoot --test --config 'directory/config.yaml'
|
||||
```
|
||||
Instead of coming back to this page when you forget the flags, you can just use the help option:
|
||||
```shell
|
||||
ephemetoot --help
|
||||
```
|
||||
|
||||
Depending on how many toots you have and how long you want to keep them, it may take a minute or two before you see any results.
|
||||
## Rate limits
|
||||
|
||||
As of v2.7.2 the Mastodon API has a rate limit of 30 deletions per 30 minutes. `mastodon.py` automatically handles this. If you are running `ephemetoot` for the first time and/or have a lot of toots to delete, it may take a while as the script will pause when it hits a rate limit, until the required time has expired. Note that the rate limit is per access token, so using ephemetoot for multiple accounts on the same server shouldn't be a big problem, however one new user may delay action on subsequent accounts in the config file.
|
||||
|
||||
## Scheduling
|
||||
|
||||
Deleting old toots daily is the best approach to keeping your timeline clean and avoiding problems wiht the API rate limit.
|
||||
|
||||
To run automatically every day you could try using crontab:
|
||||
To run automatically every day on a n*x server you could try using crontab:
|
||||
|
||||
1. `crontab -e`
|
||||
2. `@daily python3 ~/ephemetoot/ephemetoot.py`
|
||||
2. `@daily ephemetoot`
|
||||
|
||||
Alternatively on MacOS you could use [launchd](https://www.launchd.info/) or Automator.
|
||||
Alternatively on MacOS you could use [launchd](https://www.launchd.info/). Some further work on an example setup for launchd is coming soonish.
|
||||
|
||||
## Rate limits
|
||||
|
||||
As of v2.7.2 the Mastodon API has a rate limit of 30 deletions per 30 minutes. `mastodon.py` automatically handles this. If you are running `ephemetoot` for the first time and/or have a lot of toots to delete, it may take a while as the script will pause when it hits a rate limit, until the required time has expired.
|
||||
|
||||
## ASCII / utf-8 errors
|
||||
# ASCII / utf-8 errors
|
||||
|
||||
Prior to Python 3.7, running a Python script on some BSD and Linux systems may throw an error. This can be resolved by:
|
||||
* setting a _locale_ that encodes utf-8, by using the environment setting `PYTHONIOENCODING=utf-8` when running the script, or
|
||||
* upgrading your Python version to 3.7 or higher. See [Issue 11](https://github.com/hughrun/ephemetoot/issues/11) for more information.
|
||||
|
||||
# Uninstalling
|
||||
|
||||
Uninstall using pip;
|
||||
```
|
||||
pip uninstall ephemetoot
|
||||
```
|
||||
|
||||
# Bugs and suggestions
|
||||
|
||||
Please check existing [issues](https://github.com/hughrun/ephemetoot/issues) and if your issue is not already listed, create a new one with as much detail as possible (but don't include your access token!).
|
||||
|
||||
# Contributing
|
||||
|
||||
Contributions are very welcome, but if you want to suggest any changes or improvements, please log an issue or have a chat to [me on Mastodon](https://ausglam.space/@hugh) _before_ lodging a pull request.
|
||||
Contributions are very welcome, but if you want to suggest any changes or improvements, please log an issue or have a chat to [me on Mastodon](https://ausglam.space/@hugh) _before_ making a pull request.
|
||||
|
||||
# License
|
||||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# #####################################################################
|
||||
# Ephemetoot - A script to delete your old toots
|
||||
# Copyright (C) 2018 Hugh Rundle, 2019-2020 Hugh Rundle & Mark Eaton
|
||||
# Initial work based on tweet-deleting script by @flesueur
|
||||
# (https://gist.github.com/flesueur/bcb2d9185b64c5191915d860ad19f23f)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# You can contact Hugh on Mastodon @hugh@ausglam.space
|
||||
# or email hugh [at] hughrundle [dot] net
|
||||
# #####################################################################
|
||||
|
||||
# import
|
||||
import yaml
|
||||
|
||||
# from standard library
|
||||
from argparse import ArgumentParser
|
||||
import os
|
||||
|
||||
# local files
|
||||
from lib import ephemetoot
|
||||
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--config", action="store", metavar="'filepath'", default="config.yaml", help="filepath of your config file, relative to the current directory. If no --config path is provided, ephemetoot will use 'config.yaml'."
|
||||
)
|
||||
parser.add_argument(
|
||||
"--test", action="store_true", help="do a test run without deleting any toots"
|
||||
)
|
||||
|
||||
options = parser.parse_args()
|
||||
if options.config[0] == '~':
|
||||
config_file = os.path.expanduser(options.config)
|
||||
elif options.config[0] == '/':
|
||||
config_file = options.config
|
||||
else:
|
||||
config_file = os.path.join( os.getcwd(), options.config )
|
||||
|
||||
if __name__ == "__main__":
|
||||
with open(config_file) as config:
|
||||
for accounts in yaml.safe_load_all(config):
|
||||
for user in accounts:
|
||||
ephemetoot.checkToots(user, options)
|
|
@ -0,0 +1,42 @@
|
|||
# access_token : the access token from the app you created in Mastodon at Settings - Development
|
||||
# username : your username without the '@' or server domain.
|
||||
# base_url : the base url of your Mastodon server, without the 'https://'
|
||||
# days_to_keep : number of days to keep toots.
|
||||
# keep_pinned : either True or False - if True, any pinned toots will be kept
|
||||
# toots_to_keep : a List of toot ids indicating toots to be kept regardless of other settings
|
||||
# hashtags_to_keep : a Set of hashtags, where any toots with any of these hashtags will be kept. Do not include the '#' symbol
|
||||
# visibility_to_keep : any toots with visibility settings in this list will be kept. Options are: 'public', 'unlisted', 'private', 'direct'
|
||||
|
||||
# you can list only one user, or multiple users
|
||||
# each user account should be preceded by a single dash, and indented, as per below
|
||||
-
|
||||
# ausglam.space account
|
||||
access_token : ZA-Yj3aBD8U8Cm7lKUp-lm9O9BmDgdhHzDeqsY8tlL0
|
||||
username : alice
|
||||
base_url : ausglam.space
|
||||
days_to_keep : 14
|
||||
keep_pinned : True
|
||||
toots_to_keep :
|
||||
- 103996285277439262
|
||||
- 103976473612749097
|
||||
- 103877521458738491
|
||||
hashtags_to_keep : !!set { python, glamblogclub }
|
||||
visibility_to_keep :
|
||||
- direct
|
||||
- private
|
||||
-
|
||||
# aus.social account
|
||||
access_token : AZ-Yj3aBD8U8Cm7lKUp-lm9O9BmDgdhHzDeqsY8tlL9
|
||||
username : bob
|
||||
base_url : aus.social
|
||||
days_to_keep : 30
|
||||
keep_pinned : False
|
||||
# toots_to_keep can be empty
|
||||
toots_to_keep :
|
||||
-
|
||||
# hashtags_to_keep can be empty
|
||||
hashtags_to_keep : !!set { }
|
||||
# visibility_to_keep can be empty
|
||||
visibility_to_keep :
|
||||
-
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
access_token = 'YOUR_ACCESS_TOKEN_HERE'
|
||||
base_url = 'https://ausglam.space'
|
||||
days_to_keep = 30
|
||||
keep_pinned = True
|
||||
toots_to_keep = []
|
||||
hashtags_to_keep = {'introduction', 'announcement'} # comma separated Set as strings, e.g. 'introduction'
|
||||
visibility_to_keep = ['private', 'unlisted'] # options are: 'public', 'unlisted', 'private', 'direct'
|
|
@ -1,68 +1,38 @@
|
|||
# #####################################################################
|
||||
# Ephemetoot - A script to delete your old toots
|
||||
# Copyright (C) 2018, 2020 Hugh Rundle, 2019 Hugh Rundle & Mark Eaton
|
||||
# Based partially on tweet-deleting script by @flesueur
|
||||
# (https://gist.github.com/flesueur/bcb2d9185b64c5191915d860ad19f23f)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# You can contact Hugh on Mastodon @hugh@ausglam.space
|
||||
# or email hugh [at] hughrundle [dot] net
|
||||
# #####################################################################
|
||||
|
||||
from argparse import ArgumentParser
|
||||
import config
|
||||
import json
|
||||
from mastodon import Mastodon, MastodonError
|
||||
from datetime import datetime, timedelta, timezone
|
||||
import time
|
||||
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--test", action="store_true", help="do a test run without deleting any toots"
|
||||
)
|
||||
options = parser.parse_args()
|
||||
if options.test:
|
||||
print("This is a test run...")
|
||||
def checkToots(config, options, deleted_count=0):
|
||||
if options.test:
|
||||
print("This is a test run...")
|
||||
print("Fetching account details for @" + config['username'] + "@" + config['base_url'] + "...")
|
||||
mastodon = Mastodon(
|
||||
access_token=config['access_token'],
|
||||
api_base_url="https://" + config['base_url'],
|
||||
ratelimit_method="wait",
|
||||
)
|
||||
|
||||
print("Fetching account details...")
|
||||
cutoff_date = datetime.now(timezone.utc) - timedelta(days=config['days_to_keep'])
|
||||
user_id = mastodon.account_verify_credentials().id
|
||||
account = mastodon.account(user_id)
|
||||
timeline = mastodon.account_statuses(user_id, limit=40)
|
||||
|
||||
mastodon = Mastodon(
|
||||
access_token=config.access_token,
|
||||
api_base_url=config.base_url,
|
||||
ratelimit_method="wait",
|
||||
)
|
||||
print("Checking " + str(account.statuses_count) + " toots...")
|
||||
|
||||
cutoff_date = datetime.now(timezone.utc) - timedelta(days=config.days_to_keep)
|
||||
user_id = mastodon.account_verify_credentials().id
|
||||
timeline = mastodon.account_statuses(user_id, limit=40)
|
||||
|
||||
|
||||
def checkToots(timeline, deleted_count=0):
|
||||
for toot in timeline:
|
||||
|
||||
toot_tags = set()
|
||||
for tag in toot.tags:
|
||||
toot_tags.add(tag.name)
|
||||
try:
|
||||
if config.keep_pinned and hasattr(toot, "pinned") and toot.pinned:
|
||||
if config['keep_pinned'] and hasattr(toot, "pinned") and toot.pinned:
|
||||
print("📌 skipping pinned toot - " + str(toot.id))
|
||||
elif toot.id in config.toots_to_keep:
|
||||
elif toot.id in config['toots_to_keep']:
|
||||
print("💾 skipping saved toot - " + str(toot.id))
|
||||
elif toot.visibility in config.visibility_to_keep:
|
||||
elif toot.visibility in config['visibility_to_keep']:
|
||||
print("👀 skipping " + toot.visibility + " toot - " + str(toot.id))
|
||||
elif len(config.hashtags_to_keep.intersection(toot_tags)) > 0:
|
||||
elif len(config['hashtags_to_keep'].intersection(toot_tags)) > 0:
|
||||
print("#️⃣ skipping toot with hashtag - " + str(toot.id))
|
||||
elif cutoff_date > toot.created_at:
|
||||
if hasattr(toot, "reblog") and toot.reblog:
|
||||
|
@ -137,11 +107,4 @@ def checkToots(timeline, deleted_count=0):
|
|||
else:
|
||||
print("Removed " + str(deleted_count) + " toots.")
|
||||
except IndexError:
|
||||
print("No toots found!")
|
||||
|
||||
|
||||
# trigger from here
|
||||
if __name__ == "__main__":
|
||||
account = mastodon.account(user_id)
|
||||
print("Checking " + str(account.statuses_count) + " toots...")
|
||||
checkToots(timeline)
|
||||
print("No toots found!")
|
|
@ -0,0 +1,19 @@
|
|||
from setuptools import setup, find_packages
|
||||
|
||||
setup(name='ephemetoot',
|
||||
version='2.0.0',
|
||||
url='https://github.com/hughrun/ephemetoot',
|
||||
license='GPL-3.0-or-later',
|
||||
packages=find_packages(),
|
||||
scripts=['bin/ephemetoot'],
|
||||
install_requires=['Mastodon.py', 'pyyaml'],
|
||||
zip_safe=False,
|
||||
author='Hugh Rundle',
|
||||
author_email='hugh@hughrundle.net',
|
||||
description='A command line tool for selectively deleting old toots.',
|
||||
keywords='mastodon, mastodon api',
|
||||
project_urls={
|
||||
'Source Code': 'https://github.com/hughrun/ephemetoot',
|
||||
'Documentation': 'https://github.com/hughrun/ephemetoot'
|
||||
}
|
||||
)
|
Loading…
Reference in New Issue