From 3d93f2c06e6d85d12497a284eabc5ed322b2ca77 Mon Sep 17 00:00:00 2001 From: Ren Tatsumoto Date: Tue, 20 Apr 2021 10:54:06 +0300 Subject: [PATCH] add template exporter --- ankiconnect.py | 31 +++++++++++++++++++++++++++ antp.py | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 ankiconnect.py create mode 100644 antp.py diff --git a/ankiconnect.py b/ankiconnect.py new file mode 100644 index 0000000..7133997 --- /dev/null +++ b/ankiconnect.py @@ -0,0 +1,31 @@ +# Taken from https://github.com/FooSoft/anki-connect + +import json +import urllib.request + + +def request(action, **params): + return {'action': action, 'params': params, 'version': 6} + + +def invoke(action, **params): + request_json = json.dumps(request(action, **params)).encode('utf-8') + response = json.load(urllib.request.urlopen(urllib.request.Request('http://localhost:8765', request_json))) + if len(response) != 2: + raise Exception('response has an unexpected number of fields') + if 'error' not in response: + raise Exception('response is missing required error field') + if 'result' not in response: + raise Exception('response is missing required result field') + if response['error'] is not None: + raise Exception(response['error']) + return response['result'] + + +def main(): + result = invoke('deckNames') + print('got list of decks: {}'.format(result)) + + +if __name__ == '__main__': + main() diff --git a/antp.py b/antp.py new file mode 100644 index 0000000..8d266a1 --- /dev/null +++ b/antp.py @@ -0,0 +1,57 @@ +# Anki Note Type Picker +import json +from urllib.error import URLError + +from ankiconnect import invoke + +JSON_INDENT = 4 + + +def read_num(msg: str = "Input number: ", min_val: int = 0, max_val: int = None) -> int: + resp = int(input(msg)) + if resp < min_val or (max_val and resp > max_val): + raise ValueError("Value out of range.") + return resp + + +def fetch_card_templates(model_name: str): + card_templates = [] + for key, val in invoke("modelTemplates", modelName=model_name).items(): + card_templates.append({ + "Name": key, + "Front": val["Front"], + "Back": val["Back"], + }) + return card_templates + + +def fetch_template(model_name: str): + return { + "modelName": model_name, + "inOrderFields": invoke("modelFieldNames", modelName=model_name), + "css": invoke("modelStyling", modelName=model_name)["css"], + "cardTemplates": fetch_card_templates(model_name), + } + + +def export_note_type(): + models = invoke('modelNames') + if not models: + print("Nothing to show.") + return + for idx, model in enumerate(models): + print(f"{idx}: {model}") + idx = read_num("\nSelect model number: ", max_val=len(models) - 1) + model = models[int(idx)] + print(f"Selected model: {model}") + template = fetch_template(model) + print(json.dumps(template, indent=JSON_INDENT)) + + +if __name__ == '__main__': + try: + export_note_type() + except URLError: + print("Couldn't connect. Make sure Anki is open and AnkiConnect is installed.") + except Exception as ex: + print(ex)