18 Commits

Author SHA1 Message Date
2984729841 Upadte reference in readme 2023-05-03 15:11:56 +02:00
58429a39f0 Add csv format option 2023-05-03 15:09:12 +02:00
fe12631ee4 Remove double output, typo 2023-05-03 14:45:53 +02:00
7d986a7072 Update help 2023-05-03 11:53:41 +02:00
46b0fe6b50 Rework exporter 2023-05-03 11:30:28 +02:00
3dce62417e refactor: Cleaner solution for exportable dict 2023-01-26 12:05:12 +01:00
Georg Krause
d4c754c103 Merge branch 'develop' 2023-01-26 11:54:22 +01:00
8a8a725002 fix: Remove id from export
As this wil not be the same id on other instances exporting it does not make sense
2023-01-25 23:36:25 +01:00
58998e1c17 fix: Allow name to be empty in local blocklist 2023-01-25 23:35:04 +01:00
a484a41b45 Merge branch 'develop' of https://git.gieszer.link/gcrkrause/mastodon-blocklist-deploy into develop 2023-01-22 18:23:54 +01:00
Georg Krause
7ad318bc48 feat: Build docker image in CI 2023-01-18 12:02:56 +01:00
Georg Krause
8d5676d0b2 refactor: Avoid manually templating toml file entries 2023-01-13 13:56:56 +01:00
6d2a4d82b4 fix: Avoid exception when input is missing for diff and deploy 2023-01-13 13:56:55 +01:00
Georg Krause
d9d3f02fda feat: Add Dockerfile for development and deployment 2023-01-13 13:56:55 +01:00
0fca58810a feat: Allow token via environment variables 2023-01-13 13:56:55 +01:00
181ac45bbf refactor: Rename load_remote_blocklist->load_blocklist_from_instance 2023-01-13 13:56:43 +01:00
6a2a13bd74 refactor: Add missing return types 2023-01-13 13:56:43 +01:00
0dd6930c0f refactor: Rename load_local_blocklist -> load_blocklist_file 2023-01-13 13:56:43 +01:00
5 changed files with 102 additions and 11 deletions

23
.drone.yml Normal file
View 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

View File

@@ -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

View File

@@ -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]:
@@ -39,6 +40,28 @@ def load_blocklist_from_instance(server: str, token: str) -> [Instance]:
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'],
@@ -53,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)
@@ -91,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": [b.__dict__ for b in remote_blocklist]}))
else:
with open(args.output, "w") as f:
toml.dump({"instances": [b.__dict__ for b in remote_blocklist]}, f)
exporter(remote_blocklist, args.output, args.format, args.private)
if __name__ == "__main__":
cli()

View 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()

View File

@@ -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"]
@@ -38,7 +47,10 @@ class Instance:
self.reject_reports = instance_dict["reject_reports"]
def parse_local_block(self, instance_dict):
self.name = instance_dict["name"]
try:
self.name = instance_dict["name"]
except KeyError:
pass
self.domain = instance_dict["domain"]
self.severity = instance_dict["severity"]
self.public_comment = instance_dict["public_comment"]
@@ -75,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"""