From 96e96f001c5fb182d14afe9c708ac519fb137f87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian-Samuel=20Geb=C3=BChr?= Date: Thu, 5 Jan 2023 17:29:16 +0100 Subject: [PATCH 01/14] Add blocklist example --- blocklist.toml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 blocklist.toml diff --git a/blocklist.toml b/blocklist.toml new file mode 100644 index 0000000..116beb1 --- /dev/null +++ b/blocklist.toml @@ -0,0 +1,18 @@ +instance=lediver.se + +[instance] + [instance.beta_birdsite_live] + url = "https://beta.birdsite.live" + type = reject_media + public_comment = "Crossposter" + private_comment = "Crossposter" + [instance.truth_social] + url = "https://truth.social" + type = limit + public_comment = "Right-Wing extremists" + private_comment = "Trump shit" + [instance.aethy_com] + url = "https://aethy.com" + type = suspend + public_comment = "Lollicon" + private_comment = "Übernommen von chaos.social" -- 2.40.1 From 78a7ea185a715042b30bd79954fa878c70690705 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian-Samuel=20Geb=C3=BChr?= Date: Sun, 8 Jan 2023 21:33:44 +0100 Subject: [PATCH 02/14] change blocklist format --- blocklist.toml | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/blocklist.toml b/blocklist.toml index 116beb1..65b4676 100644 --- a/blocklist.toml +++ b/blocklist.toml @@ -1,18 +1,20 @@ -instance=lediver.se +[[instances]] +name = "beta_birdsite_live" +url = "https://beta.birdsite.live" +type = "reject_media" +public_comment = "Crossposter" +private_comment = "Crossposter" -[instance] - [instance.beta_birdsite_live] - url = "https://beta.birdsite.live" - type = reject_media - public_comment = "Crossposter" - private_comment = "Crossposter" - [instance.truth_social] - url = "https://truth.social" - type = limit - public_comment = "Right-Wing extremists" - private_comment = "Trump shit" - [instance.aethy_com] - url = "https://aethy.com" - type = suspend - public_comment = "Lollicon" - private_comment = "Übernommen von chaos.social" +[[instances]] +name = "truth_social" +url = "https://truth.social" +type = "limit" +public_comment = "Right-Wing extremists" +private_comment = "Trump shit" + +[[instances]] +name = "aethy_com" +url = "https://aethy.com" +type = "suspend" +public_comment = "Lollicon" +private_comment = "Übernommen von chaos.social" \ No newline at end of file -- 2.40.1 From 7f0dc0c0a6d612124fad6a6a1728135dd8909f88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian-Samuel=20Geb=C3=BChr?= Date: Sun, 8 Jan 2023 21:36:54 +0100 Subject: [PATCH 03/14] Add pyproject.toml --- pyproject.toml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 pyproject.toml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..9bf2f78 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,16 @@ +[tool.poetry] +name = "mastodon-blocklist-deploy" +version = "0.1.0" +description = "A small tool to deploy blocklist updates to a mastodon server using its API." +authors = ["Georg Krause ", "Julian-Samuel Gebühr "] +readme = "README.md" +packages = [{include = "mastodon_blocklist_deploy"}] + +[tool.poetry.dependencies] +python = "^3.10" +tomli = "^2.0.1" + + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" -- 2.40.1 From 5e6e8415ca538e831cba8fb180ef63f9ada93c8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian-Samuel=20Geb=C3=BChr?= Date: Sun, 8 Jan 2023 21:38:16 +0100 Subject: [PATCH 04/14] Add .idea folder to gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index f8b73e7..f982253 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +.idea +poetry.lock + # ---> Python # Byte-compiled / optimized / DLL files __pycache__/ -- 2.40.1 From 84faa398b17ae5cbcd014aa55274cd288b0bc1c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian-Samuel=20Geb=C3=BChr?= Date: Mon, 9 Jan 2023 08:40:28 +0100 Subject: [PATCH 05/14] Formatting --- README.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d7b2373..820feb4 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,16 @@ A small tool to deploy blocklist updates to a mastodon server using its API. ## Concept -The idea is to maintain a blocklist in a simple structured file in this repository. All changes need to be deployed to the mastodon server, this is supposed to be automated with Drone CI. +The idea is to maintain a blocklist in a simple structured file in this repository. All changes need to be deployed to +the mastodon server, this is supposed to be automated with Drone CI. -In order to compare the list entries, we can read the whole blocklist using [the get endpoint](https://docs.joinmastodon.org/methods/admin/domain_blocks/#get). At the same time we read the whole file in the repository, make a comparision and [remove](https://docs.joinmastodon.org/methods/admin/domain_blocks/#delete) unblocked domains from the blocklist and [add](https://docs.joinmastodon.org/methods/admin/domain_blocks/#create) newly added. +In order to compare the list entries, we can read the whole blocklist +using [the get endpoint](https://docs.joinmastodon.org/methods/admin/domain_blocks/#get). At the same time we read the +whole file in the repository, make a comparision +and [remove](https://docs.joinmastodon.org/methods/admin/domain_blocks/#delete) unblocked domains from the blocklist +and [add](https://docs.joinmastodon.org/methods/admin/domain_blocks/#create) newly added. -Since we have several attributes for a domain blog, a simple `.txt` file might not be sufficient. We probably want to set the severity, reject_media, reject_reports and comments. This means we need a human readable, easily python-readable and structured file format. Since Python 3.11 got native support for [toml](https://toml.io/) and it supports [Array of Tables](https://toml.io/en/v1.0.0#array-of-tables), I'd prefer to use this. +Since we have several attributes for a domain blog, a simple `.txt` file might not be sufficient. We probably want to +set the severity, reject_media, reject_reports and comments. This means we need a human readable, easily python-readable +and structured file format. Since Python 3.11 got native support for [toml](https://toml.io/) and it +supports [Array of Tables](https://toml.io/en/v1.0.0#array-of-tables), I'd prefer to use this. -- 2.40.1 From 58bb66e6cb4dd024a660e2ecaf336f16c0d56244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian-Samuel=20Geb=C3=BChr?= Date: Mon, 9 Jan 2023 08:41:16 +0100 Subject: [PATCH 06/14] Change key names to comply with API names --- blocklist.toml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/blocklist.toml b/blocklist.toml index 65b4676..32beb6f 100644 --- a/blocklist.toml +++ b/blocklist.toml @@ -1,20 +1,22 @@ [[instances]] name = "beta_birdsite_live" -url = "https://beta.birdsite.live" -type = "reject_media" +domain = "beta.birdsite.live" +severity = "silence" +reject_media = true +reject_reports = false public_comment = "Crossposter" private_comment = "Crossposter" [[instances]] name = "truth_social" -url = "https://truth.social" -type = "limit" +domain = "truth.social" +severity = "limit" public_comment = "Right-Wing extremists" private_comment = "Trump shit" [[instances]] name = "aethy_com" -url = "https://aethy.com" -type = "suspend" +domain = "aethy.com" +severity = "suspend" public_comment = "Lollicon" private_comment = "Übernommen von chaos.social" \ No newline at end of file -- 2.40.1 From a72ddfcdf40e2748072c03e6d2dcdd21c4ee8bc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian-Samuel=20Geb=C3=BChr?= Date: Mon, 9 Jan 2023 08:41:28 +0100 Subject: [PATCH 07/14] Add dependencies --- pyproject.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 9bf2f78..e3db728 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,6 +9,8 @@ packages = [{include = "mastodon_blocklist_deploy"}] [tool.poetry.dependencies] python = "^3.10" tomli = "^2.0.1" +requests = "^2.28.1" +rich = "^13.0.1" [build-system] -- 2.40.1 From aa64c6dbd229d7d45fe1310b501eb126ea67c027 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian-Samuel=20Geb=C3=BChr?= Date: Mon, 9 Jan 2023 08:42:36 +0100 Subject: [PATCH 08/14] Initial code commit, adds diff functionality --- cli.py | 70 +++++++++++++++++++++++++++++++++++++++++++++ models.py | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 cli.py create mode 100644 models.py diff --git a/cli.py b/cli.py new file mode 100644 index 0000000..1f4282f --- /dev/null +++ b/cli.py @@ -0,0 +1,70 @@ +# import tomllib +import argparse +import json +import logging +import requests + +import tomli + +from models import Instance + + +def load_local_blocklist(filename: str) -> [Instance]: + with open(filename, "rb") as f: + data = tomli.load(f) + instances = [] + for instance_dict in data["instances"]: + instance = Instance(instance_dict) + instances.append(instance) + for instance in instances: + print(instance) + return instances + + +def blocklist_json_to_instances(blocklist_json): + instances = [] + for i in blocklist_json: + instances.append(Instance(i)) + return instances + + +def load_remote_blocklist(server, token): + headers = { + f'Authorization': f'Bearer {token}', + } + + response = requests.get(f'https://{server}/api/v1/admin/domain_blocks', headers=headers) + if response.status_code == 200: + blocklist_json = json.loads(response.content) + return blocklist_json_to_instances(blocklist_json) + else: + raise ConnectionError(f"Could not connect to the server ({response.status_code}: {response.reason})") + + +def cli(): + parser = argparse.ArgumentParser(description='Deploy blocklist updates to a mastodon server') + parser.add_argument('action', choices=['diff', 'deploy'], + help="Either use 'diff' to check the difference between current blocks and future blocks or 'deploy'.") + parser.add_argument('-s', '--server', help="The address of the server where you want to deploy (e.g. " + "mastodon.social)") + parser.add_argument('-t', '--token', help="Authorization token") + parser.add_argument('-i', '--input-file', help="The blocklist to use") + parser.add_argument('-r', '--remote-blocklist', help="The remote blocklist as json for debugging reasons") + args = parser.parse_args() + logging.basicConfig(level=logging.WARN) + if args.input_file: + blocklist_filename = args.input_file + else: + blocklist_filename = "blocklist.toml" + local_blocklist = load_local_blocklist(blocklist_filename) + if args.remote_blocklist: + with open(args.remote_blocklist) as f: + remote_blocklist = blocklist_json_to_instances(json.load(f)) + else: + remote_blocklist = load_remote_blocklist(server=args.server, token=args.token) + + Instance.show_diff(local_blocklist, remote_blocklist) + + +if __name__ == "__main__": + cli() diff --git a/models.py b/models.py new file mode 100644 index 0000000..f3b9a07 --- /dev/null +++ b/models.py @@ -0,0 +1,85 @@ +class Instance: + def __init__(self, instance_dict): + """If obfuscate, reject_media or reject_reports are not specified default to False""" + self.obfuscate = False + self.reject_media = False + self.reject_reports = False + self.id = None + + """Remote blocks and local blocks are parsed differently""" + try: + instance_dict["id"] + self.parse_remote_block(instance_dict) + except KeyError: + self.parse_local_block(instance_dict) + + def __str__(self): + return f"{self.name}: {self.severity}" + + def __eq__(self, other): + return self.domain == other.domain and self.severity == other.severity and self.reject_media == other.reject_media and self.reject_reports == other.reject_reports and self.obfuscate == other.obfuscate + + def status_str(self): + return f"{self.severity}, Reject reports: {self.reject_reports}, Reject media: {self.reject_media}, Obfuscate: {self.obfuscate}" + + def parse_remote_block(self, instance_dict): + self.domain = instance_dict["domain"] + self.id = instance_dict["id"] + self.severity = instance_dict["severity"] + self.public_comment = instance_dict["public_comment"] + self.private_comment = instance_dict["private_comment"] + self.remote = True + + def parse_local_block(self, instance_dict): + self.name = instance_dict["name"] + self.domain = instance_dict["domain"] + self.severity = instance_dict["severity"] + self.public_comment = instance_dict["public_comment"] + self.private_comment = instance_dict["private_comment"] + self.remote = False + + def apply(self, instance, token): + pass + + @staticmethod + def list_diff(local_blocklist, remote_blocklist): + diffs = [] + for local_instance in local_blocklist: + instance_found = False + for idx, remote_instance in enumerate(remote_blocklist): + if local_instance.domain == remote_instance.domain: + instance_found = True + if local_instance == remote_instance: + pass + else: + """If the local block is different from the remote block, add it to the diff""" + diffs.append({"local": local_instance, "remote": remote_instance}) + """Remove the remote instance from the list so we later have a list of remote instances we don't + have locally""" + del remote_blocklist[idx] + """If the local instance is not in the remote blocklist, add it to the diff""" + if not instance_found: + diffs.append({"local": local_instance, "remote": None}) + for remote_instance in remote_blocklist: + diffs.append({"local": None, "remote": remote_instance}) + return diffs + + @staticmethod + def show_diff(local_blocklist, remote_blocklist): + from rich.table import Table + from rich.console import Console + table = Table(title="Differences", expand=True, show_lines=True) + + table.add_column("Domain", style="cyan") + table.add_column("Current remote status", style="magenta") + table.add_column("Local status", style="green") + diffs = Instance.list_diff(local_blocklist, remote_blocklist) + for diff in diffs: + if diff["local"] is None: + table.add_row(diff["remote"].domain, None, diff["remote"].status_str()) + elif diff["remote"] is None: + table.add_row(diff["local"].domain, diff["local"].status_str(), None) + else: + table.add_row(diff["local"].domain, diff["local"].status_str(), diff["remote"].status_str()) + console = Console() + console.print(table) \ No newline at end of file -- 2.40.1 From 1197228650ca63a19bd44b607782e59ffeb1837e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian-Samuel=20Geb=C3=BChr?= Date: Mon, 9 Jan 2023 11:48:44 +0100 Subject: [PATCH 09/14] Add deploy option --- cli.py | 8 +++++--- models.py | 58 +++++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 55 insertions(+), 11 deletions(-) diff --git a/cli.py b/cli.py index 1f4282f..4291e3b 100644 --- a/cli.py +++ b/cli.py @@ -62,9 +62,11 @@ def cli(): remote_blocklist = blocklist_json_to_instances(json.load(f)) else: remote_blocklist = load_remote_blocklist(server=args.server, token=args.token) - - Instance.show_diff(local_blocklist, remote_blocklist) - + if args.action == "diff": + Instance.show_diffs(local_blocklist, remote_blocklist) + elif args.action == "deploy": + diffs = Instance.list_diffs(local_blocklist, remote_blocklist) + Instance.apply_blocks_from_diff(diffs, args.server, args.token) if __name__ == "__main__": cli() diff --git a/models.py b/models.py index f3b9a07..b97b5ff 100644 --- a/models.py +++ b/models.py @@ -1,3 +1,6 @@ +import requests + + class Instance: def __init__(self, instance_dict): """If obfuscate, reject_media or reject_reports are not specified default to False""" @@ -28,7 +31,9 @@ class Instance: self.severity = instance_dict["severity"] self.public_comment = instance_dict["public_comment"] self.private_comment = instance_dict["private_comment"] - self.remote = True + self.obfuscate = instance_dict["obfuscate"] + self.reject_media = instance_dict["reject_media"] + self.reject_reports = instance_dict["reject_reports"] def parse_local_block(self, instance_dict): self.name = instance_dict["name"] @@ -36,13 +41,40 @@ class Instance: self.severity = instance_dict["severity"] self.public_comment = instance_dict["public_comment"] self.private_comment = instance_dict["private_comment"] - self.remote = False + try: + self.obfuscate = instance_dict["obfuscate"] + except KeyError: + pass + try: + self.reject_media = instance_dict["reject_media"] + except KeyError: + pass + try: + self.reject_reports = instance_dict["reject_reports"] + except KeyError: + pass - def apply(self, instance, token): - pass + def apply(self, server, token, block_id=None): + headers = { + f'Authorization': f'Bearer {token}', + } + data = {"domain": self.domain, + "severity": self.severity, + "reject_media": self.reject_media, + "reject_reports": self.reject_reports, + "private_comment": self.private_comment, + "public_comment": self.public_comment, + "obfuscate": self.obfuscate} + """If no id is given add a new block, else update the existing block""" + if block_id is None: + response = requests.post(f'https://{server}/api/v1/admin/domain_blocks', data=data, headers=headers) + else: + response = requests.post(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})") @staticmethod - def list_diff(local_blocklist, remote_blocklist): + def list_diffs(local_blocklist, remote_blocklist): diffs = [] for local_instance in local_blocklist: instance_found = False @@ -65,7 +97,17 @@ class Instance: return diffs @staticmethod - def show_diff(local_blocklist, remote_blocklist): + def apply_blocks_from_diff(diffs, server, token): + for diff in diffs: + if diff["local"] is None: + pass + elif diff["remote"] is None: + diff["local"].apply(server, token) + else: + diff["local"].apply(server, token, block_id=diff["remote"].id) + + @staticmethod + def show_diffs(local_blocklist, remote_blocklist): from rich.table import Table from rich.console import Console table = Table(title="Differences", expand=True, show_lines=True) @@ -73,7 +115,7 @@ class Instance: table.add_column("Domain", style="cyan") table.add_column("Current remote status", style="magenta") table.add_column("Local status", style="green") - diffs = Instance.list_diff(local_blocklist, remote_blocklist) + diffs = Instance.list_diffs(local_blocklist, remote_blocklist) for diff in diffs: if diff["local"] is None: table.add_row(diff["remote"].domain, None, diff["remote"].status_str()) @@ -82,4 +124,4 @@ class Instance: else: table.add_row(diff["local"].domain, diff["local"].status_str(), diff["remote"].status_str()) console = Console() - console.print(table) \ No newline at end of file + console.print(table) -- 2.40.1 From 7f3154f5151314ff6b3c3c21d8d6698bce6c38bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian-Samuel=20Geb=C3=BChr?= Date: Mon, 9 Jan 2023 12:01:39 +0100 Subject: [PATCH 10/14] Make update of block possible --- cli.py | 6 ++++-- models.py | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/cli.py b/cli.py index 4291e3b..504da76 100644 --- a/cli.py +++ b/cli.py @@ -21,14 +21,14 @@ def load_local_blocklist(filename: str) -> [Instance]: return instances -def blocklist_json_to_instances(blocklist_json): +def blocklist_json_to_instances(blocklist_json: str): instances = [] for i in blocklist_json: instances.append(Instance(i)) return instances -def load_remote_blocklist(server, token): +def load_remote_blocklist(server: str, token: str): headers = { f'Authorization': f'Bearer {token}', } @@ -68,5 +68,7 @@ def cli(): diffs = Instance.list_diffs(local_blocklist, remote_blocklist) Instance.apply_blocks_from_diff(diffs, args.server, args.token) + if __name__ == "__main__": + logging.basicConfig(level=logging.DEBUG) cli() diff --git a/models.py b/models.py index b97b5ff..dcc8aea 100644 --- a/models.py +++ b/models.py @@ -69,7 +69,7 @@ class Instance: if block_id is None: response = requests.post(f'https://{server}/api/v1/admin/domain_blocks', data=data, headers=headers) else: - response = requests.post(f'https://{server}/api/v1/admin/domain_blocks/{block_id}', data=data, headers=headers) + 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})") -- 2.40.1 From fb85a358286bfc189b5b99615c1b024fcc690321 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian-Samuel=20Geb=C3=BChr?= Date: Mon, 9 Jan 2023 13:10:40 +0100 Subject: [PATCH 11/14] Add export options, use toml --- cli.py | 41 +++++++++++++++++++++++++++++++++-------- models.py | 2 +- pyproject.toml | 2 +- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/cli.py b/cli.py index 504da76..7c5bdf0 100644 --- a/cli.py +++ b/cli.py @@ -4,14 +4,14 @@ import json import logging import requests -import tomli +import toml from models import Instance def load_local_blocklist(filename: str) -> [Instance]: with open(filename, "rb") as f: - data = tomli.load(f) + data = toml.load(f) instances = [] for instance_dict in data["instances"]: instance = Instance(instance_dict) @@ -21,6 +21,23 @@ def load_local_blocklist(filename: str) -> [Instance]: return instances +def export_blocklist_toml(blocklist: [Instance], filname: str): + toml_str = "" + for instance in blocklist: + toml_str += f''' +[instance] +name = "{instance.domain}" +domain = "{instance.domain}" +severity = "{instance.severity}" +reject_media = {str(instance.reject_media).lower()} +reject_reports = {str(instance.reject_reports).lower()} +public_comment = "{instance.public_comment}" +private_comment = "{instance.private_comment}" + ''' + with open(filname, "w") as f: + f.write(toml_str) + + def blocklist_json_to_instances(blocklist_json: str): instances = [] for i in blocklist_json: @@ -43,30 +60,38 @@ def load_remote_blocklist(server: str, token: str): def cli(): parser = argparse.ArgumentParser(description='Deploy blocklist updates to a mastodon server') - parser.add_argument('action', choices=['diff', 'deploy'], + parser.add_argument('action', choices=['diff', 'deploy', 'export'], help="Either use 'diff' to check the difference between current blocks and future blocks or 'deploy'.") parser.add_argument('-s', '--server', help="The address of the server where you want to deploy (e.g. " "mastodon.social)") parser.add_argument('-t', '--token', help="Authorization token") parser.add_argument('-i', '--input-file', help="The blocklist to use") parser.add_argument('-r', '--remote-blocklist', help="The remote blocklist as json for debugging reasons") + parser.add_argument('-o', '--output', help="Filename where to export the blocklist") args = parser.parse_args() logging.basicConfig(level=logging.WARN) - if args.input_file: - blocklist_filename = args.input_file - else: - blocklist_filename = "blocklist.toml" - local_blocklist = load_local_blocklist(blocklist_filename) + if args.remote_blocklist: with open(args.remote_blocklist) as f: remote_blocklist = blocklist_json_to_instances(json.load(f)) else: remote_blocklist = load_remote_blocklist(server=args.server, token=args.token) + + """Load local blocklist only when needed""" + if args.action in ["diff", "deploy"]: + if args.input_file: + blocklist_filename = args.input_file + else: + blocklist_filename = "blocklist.toml" + local_blocklist = load_local_blocklist(blocklist_filename) + if args.action == "diff": Instance.show_diffs(local_blocklist, remote_blocklist) elif args.action == "deploy": diffs = Instance.list_diffs(local_blocklist, remote_blocklist) Instance.apply_blocks_from_diff(diffs, args.server, args.token) + elif args.action == "export": + export_blocklist_toml(remote_blocklist, args.output) if __name__ == "__main__": diff --git a/models.py b/models.py index dcc8aea..69ea012 100644 --- a/models.py +++ b/models.py @@ -17,7 +17,7 @@ class Instance: self.parse_local_block(instance_dict) def __str__(self): - return f"{self.name}: {self.severity}" + return f"{self.domain}: {self.severity}" def __eq__(self, other): return self.domain == other.domain and self.severity == other.severity and self.reject_media == other.reject_media and self.reject_reports == other.reject_reports and self.obfuscate == other.obfuscate diff --git a/pyproject.toml b/pyproject.toml index e3db728..5ad0955 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,9 +8,9 @@ packages = [{include = "mastodon_blocklist_deploy"}] [tool.poetry.dependencies] python = "^3.10" -tomli = "^2.0.1" requests = "^2.28.1" rich = "^13.0.1" +toml = "^0.10.2" [build-system] -- 2.40.1 From 76c637720ef2df81f078e0985900ef059ff570c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian-Samuel=20Geb=C3=BChr?= Date: Mon, 9 Jan 2023 13:25:35 +0100 Subject: [PATCH 12/14] Remove personal files and readd poetry.lock --- .gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index f982253..b3522a1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,3 @@ -.idea -poetry.lock # ---> Python # Byte-compiled / optimized / DLL files -- 2.40.1 From 1b1cf765be387ff4189eff6e4cfa89b22069319b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian-Samuel=20Geb=C3=BChr?= Date: Wed, 11 Jan 2023 19:16:59 +0100 Subject: [PATCH 13/14] Fix ex-and import --- cli.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli.py b/cli.py index 7c5bdf0..952e310 100644 --- a/cli.py +++ b/cli.py @@ -10,7 +10,7 @@ from models import Instance def load_local_blocklist(filename: str) -> [Instance]: - with open(filename, "rb") as f: + with open(filename, "r") as f: data = toml.load(f) instances = [] for instance_dict in data["instances"]: @@ -25,7 +25,7 @@ def export_blocklist_toml(blocklist: [Instance], filname: str): toml_str = "" for instance in blocklist: toml_str += f''' -[instance] +[[instances]] name = "{instance.domain}" domain = "{instance.domain}" severity = "{instance.severity}" -- 2.40.1 From 5b7347ce718654e6f32489aba593d74109c0d997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian-Samuel=20Geb=C3=BChr?= Date: Wed, 11 Jan 2023 19:19:14 +0100 Subject: [PATCH 14/14] Add delete method --- models.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/models.py b/models.py index 69ea012..3c8ad4d 100644 --- a/models.py +++ b/models.py @@ -72,6 +72,14 @@ 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})") + def delete(self, server: str, token: str): + headers = { + f'Authorization': f'Bearer {token}', + } + response = requests.delete(f'https://{server}/api/v1/admin/domain_blocks/{self.id}', headers=headers) + if response.status_code != 200: + raise ConnectionError(f"Could not apply block ({response.status_code}: {response.reason})") + @staticmethod def list_diffs(local_blocklist, remote_blocklist): -- 2.40.1