diff --git a/mastodon_blocklist_deploy/cli.py b/mastodon_blocklist_deploy/cli.py index 68ea688..a8faa5d 100644 --- a/mastodon_blocklist_deploy/cli.py +++ b/mastodon_blocklist_deploy/cli.py @@ -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 def load_blocklist_file(filename: str) -> [Instance]: @@ -39,6 +40,31 @@ 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 == "markdown": + exported_text = blocklist_to_markdown(blocklist, private) + if output is not None: + with open(output, "w") as f: + f.write(exported_text) + else: + print(exported_text) + if format == "toml": + exported_text = blocklist_to_toml(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 +79,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") + 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) @@ -64,6 +93,8 @@ def cli(): else: token = os.getenv('MBD_TOKEN') + + """if there is a remote blocklist provided load this instead of fetching it from a server (for debugging reasons)""" if args.remote_blocklist: with open(args.remote_blocklist) as f: @@ -89,12 +120,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.exportable_dict for b in remote_blocklist]})) - else: - with open(args.output, "w") as f: - toml.dump({"instances": [b.exportable_dict for b in remote_blocklist]}, f) - + exporter(remote_blocklist, args.output, args.format, args.private) if __name__ == "__main__": cli() diff --git a/mastodon_blocklist_deploy/helpers.py b/mastodon_blocklist_deploy/helpers.py new file mode 100644 index 0000000..93d7b30 --- /dev/null +++ b/mastodon_blocklist_deploy/helpers.py @@ -0,0 +1,21 @@ +from mastodon_blocklist_deploy.models import Instance +import toml + + +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 diff --git a/mastodon_blocklist_deploy/models.py b/mastodon_blocklist_deploy/models.py index bf650d3..7b360a1 100644 --- a/mastodon_blocklist_deploy/models.py +++ b/mastodon_blocklist_deploy/models.py @@ -27,9 +27,10 @@ class Instance: def status_str(self): return f"{self.severity}\nReject reports: {self.reject_reports}\nReject media: {self.reject_media}\nObfuscate: {self.obfuscate}" - @property - def exportable_dict(self): - keys = ["domain", "severity", "public_comment", "private_comment", "obfuscate", "reject_media", "reject_reports"] + 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) @@ -86,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"""