Compare commits
8 Commits
8a8a725002
...
rework_exp
Author | SHA1 | Date | |
---|---|---|---|
2984729841 | |||
58429a39f0 | |||
fe12631ee4 | |||
7d986a7072 | |||
46b0fe6b50 | |||
3dce62417e | |||
![]() |
d4c754c103 | ||
![]() |
7ad318bc48 |
23
.drone.yml
Normal file
23
.drone.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
kind: pipeline
|
||||
type: exec
|
||||
name: build
|
||||
|
||||
platform:
|
||||
os: linux
|
||||
arch: arm64
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
commands:
|
||||
- docker build -t gcrkrause/mastodon-blocklist-deploy .
|
||||
- name: push
|
||||
environment:
|
||||
USERNAME:
|
||||
from_secret: docker-hub-user
|
||||
PASSWORD:
|
||||
from_secret: docker-hub-pw
|
||||
commands:
|
||||
- docker login -u $USERNAME -p $PASSWORD
|
||||
- docker push gcrkrause/mastodon-blocklist-deploy
|
||||
- docker image prune -a -f
|
10
README.md
10
README.md
@@ -25,13 +25,15 @@ supports [Array of Tables](https://toml.io/en/v1.0.0#array-of-tables), I'd prefe
|
||||
##
|
||||
|
||||
```
|
||||
$ mastodon_blocklist_deploy -h
|
||||
usage: mastodon_blocklist_deploy [-h] [-s SERVER] [-t TOKEN] [-i INPUT_FILE] [-r REMOTE_BLOCKLIST] [-o OUTPUT] [-v] [-n] {diff,deploy,export}
|
||||
usage: mastodon_blocklist_deploy [-h] [-s SERVER] [-t TOKEN] [-i INPUT_FILE] [-r REMOTE_BLOCKLIST] [-o OUTPUT] [-v] [-n]
|
||||
[--format FORMAT] [--private]
|
||||
{diff,deploy,export}
|
||||
|
||||
Deploy blocklist updates to a mastodon server
|
||||
|
||||
positional arguments:
|
||||
{diff,deploy,export} Either use 'diff' to check the difference between local blockĺist and the blocklist on the server, 'deploy' to apply the current local blocklist or 'export' to export the remote blocklist into a local file.
|
||||
{diff,deploy,export} Either use 'diff' to check the difference between local blockĺist and the blocklist on the server, 'deploy'
|
||||
to apply the current local blocklist or 'export' to export the remote blocklist into a local file.
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
@@ -47,6 +49,8 @@ options:
|
||||
Filename where to export the blocklist
|
||||
-v, --verbose
|
||||
-n, --no-delete Do not delete existing blocks
|
||||
--format FORMAT Export format: toml|markdown|csv
|
||||
--private When the flag is set, private comment will also be exported.
|
||||
```
|
||||
|
||||
## Obtain a server token
|
||||
|
@@ -7,6 +7,7 @@ import os
|
||||
import toml
|
||||
|
||||
from mastodon_blocklist_deploy.models import Instance
|
||||
from mastodon_blocklist_deploy.helpers import blocklist_to_markdown, blocklist_to_toml, blocklist_to_csv
|
||||
|
||||
|
||||
def load_blocklist_file(filename: str) -> [Instance]:
|
||||
@@ -38,10 +39,29 @@ def load_blocklist_from_instance(server: str, token: str) -> [Instance]:
|
||||
else:
|
||||
raise ConnectionError(f"Could not connect to the server ({response.status_code}: {response.reason})")
|
||||
|
||||
|
||||
def remove_key_from_dict(dict, key):
|
||||
del dict[key]
|
||||
return dict
|
||||
|
||||
|
||||
def exporter(blocklist, output=None, format: str = "toml", private: bool = False):
|
||||
if format == "toml":
|
||||
exported_text = blocklist_to_toml(blocklist, private)
|
||||
if format == "csv":
|
||||
exported_text = blocklist_to_csv(blocklist, private)
|
||||
if format == "markdown":
|
||||
exported_text = blocklist_to_markdown(blocklist, private)
|
||||
|
||||
# Output the text
|
||||
if output is not None:
|
||||
with open(output, "w") as f:
|
||||
f.write(exported_text)
|
||||
else:
|
||||
print(exported_text)
|
||||
|
||||
|
||||
|
||||
def cli():
|
||||
parser = argparse.ArgumentParser(description='Deploy blocklist updates to a mastodon server')
|
||||
parser.add_argument('action', choices=['diff', 'deploy', 'export'],
|
||||
@@ -56,6 +76,9 @@ def cli():
|
||||
parser.add_argument('-o', '--output', help="Filename where to export the blocklist")
|
||||
parser.add_argument('-v', '--verbose', action='store_true')
|
||||
parser.add_argument('-n', '--no-delete', action='store_true', help="Do not delete existing blocks")
|
||||
parser.add_argument('--format', help="Export format: toml|markdown|csv")
|
||||
parser.add_argument('--private', action='store_true', help="When the flag is set, private comment will also be "
|
||||
"exported.")
|
||||
args = parser.parse_args()
|
||||
if args.verbose:
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
@@ -94,12 +117,7 @@ def cli():
|
||||
diffs = Instance.list_diffs(local_blocklist, remote_blocklist)
|
||||
Instance.apply_blocks_from_diff(diffs, args.server, token, args.no_delete)
|
||||
elif args.action == "export":
|
||||
if not args.output:
|
||||
print(toml.dumps({"instances": [remove_key_from_dict(b.__dict__, 'id') for b in remote_blocklist]}))
|
||||
else:
|
||||
with open(args.output, "w") as f:
|
||||
toml.dump({"instances": [remove_key_from_dict(b.__dict__, 'id') for b in remote_blocklist]}, f)
|
||||
|
||||
exporter(remote_blocklist, args.output, args.format, args.private)
|
||||
|
||||
if __name__ == "__main__":
|
||||
cli()
|
||||
|
31
mastodon_blocklist_deploy/helpers.py
Normal file
31
mastodon_blocklist_deploy/helpers.py
Normal file
@@ -0,0 +1,31 @@
|
||||
from mastodon_blocklist_deploy.models import Instance
|
||||
import toml
|
||||
import io
|
||||
import csv
|
||||
|
||||
def blocklist_to_markdown(blocklist: [Instance], private: bool = False):
|
||||
if private:
|
||||
markdown_string = "| Instance | Status | Reason | Private Comment |\n | --- | --- | --- |\n"
|
||||
else:
|
||||
markdown_string = "| Instance | Status | Reason |\n | --- | --- | --- |\n"
|
||||
for instance in blocklist:
|
||||
|
||||
if private:
|
||||
markdown_string += f"| {instance.domain} | {instance.severity} | {instance.public_comment} | {instance.private_comment} |\n"
|
||||
else:
|
||||
markdown_string += f"| {instance.domain} | {instance.severity} | {instance.public_comment} |\n"
|
||||
|
||||
return markdown_string
|
||||
|
||||
def blocklist_to_toml(blocklist: [Instance], private: bool = False):
|
||||
toml_string = toml.dumps({"instances": [b.as_dict(private) for b in blocklist]})
|
||||
return toml_string
|
||||
|
||||
def blocklist_to_csv(blocklist: [Instance], private: bool = False):
|
||||
csv_string = io.StringIO()
|
||||
blocklist_as_dict = [b.as_dict(private) for b in blocklist]
|
||||
keys = blocklist_as_dict[0].keys()
|
||||
w = csv.DictWriter(csv_string, keys)
|
||||
w.writeheader()
|
||||
w.writerows(blocklist_as_dict)
|
||||
return csv_string.getvalue()
|
@@ -27,6 +27,15 @@ class Instance:
|
||||
def status_str(self):
|
||||
return f"{self.severity}\nReject reports: {self.reject_reports}\nReject media: {self.reject_media}\nObfuscate: {self.obfuscate}"
|
||||
|
||||
def as_dict(self, private=False):
|
||||
keys = ["domain", "severity", "public_comment", "obfuscate", "reject_media", "reject_reports"]
|
||||
if private:
|
||||
keys.append("private_comment")
|
||||
exportable = {}
|
||||
for key in keys:
|
||||
exportable[key] = getattr(self, key)
|
||||
return exportable
|
||||
|
||||
def parse_remote_block(self, instance_dict):
|
||||
self.domain = instance_dict["domain"]
|
||||
self.id = instance_dict["id"]
|
||||
@@ -78,7 +87,7 @@ class Instance:
|
||||
response = requests.put(f'https://{server}/api/v1/admin/domain_blocks/{block_id}', data=data,
|
||||
headers=headers)
|
||||
if response.status_code != 200:
|
||||
raise ConnectionError(f"Could not apply block ({response.status_code}: {response.reason})")
|
||||
raise ConnectionError(f"Could not apply block for {self.domain} ({response.status_code}: {response.reason})")
|
||||
|
||||
def delete(self, server: str, token: str):
|
||||
"""Deletes the instance from the blocklist on the remote server"""
|
||||
|
Reference in New Issue
Block a user