From be0247ae2f5bd6119544b6b880a880020a508276 Mon Sep 17 00:00:00 2001 From: Ben Kogan Date: Sun, 27 Oct 2019 16:41:53 -0400 Subject: [PATCH] Add get and update endpoints for model templates and styling --- AnkiConnect.py | 58 +++++++++++++++++++++ README.md | 119 +++++++++++++++++++++++++++++++++++++++++++ tests/test_models.py | 33 +++++++++++- 3 files changed, 208 insertions(+), 2 deletions(-) diff --git a/AnkiConnect.py b/AnkiConnect.py index c82b098..22c51ab 100644 --- a/AnkiConnect.py +++ b/AnkiConnect.py @@ -947,6 +947,64 @@ class AnkiConnect: return templates + @api() + def modelTemplates(self, modelName): + model = self.collection().models.byName(modelName) + if model is None: + raise Exception('model was not found: {}'.format(modelName)) + + templates = {} + for template in model['tmpls']: + templates[template['name']] = {'Front': template['qfmt'], 'Back': template['afmt']} + + return templates + + + @api() + def modelStyling(self, modelName): + model = self.collection().models.byName(modelName) + if model is None: + raise Exception('model was not found: {}'.format(modelName)) + + return {'css': model['css']} + + + @api() + def updateModelTemplates(self, model): + models = self.collection().models + ankiModel = models.byName(model['name']) + if ankiModel is None: + raise Exception('model was not found: {}'.format(model['name'])) + + templates = model['templates'] + + for ankiTemplate in ankiModel['tmpls']: + template = templates.get(ankiTemplate['name']) + if template: + qfmt = template.get('Front') + if qfmt: + ankiTemplate['qfmt'] = qfmt + + afmt = template.get('Back') + if afmt: + ankiTemplate['afmt'] = afmt + + models.save(ankiModel, True) + models.flush() + + + @api() + def updateModelStyling(self, model): + models = self.collection().models + ankiModel = models.byName(model['name']) + if ankiModel is None: + raise Exception('model was not found: {}'.format(model['name'])) + + ankiModel['css'] = model['css'] + + models.save(ankiModel, True) + models.flush() + @api() def deckNameFromId(self, deckId): diff --git a/README.md b/README.md index 74a3fa4..08195a6 100644 --- a/README.md +++ b/README.md @@ -820,6 +820,125 @@ guarantee that your application continues to function properly in the future. } ``` + +* **modelTemplates** + + Returns an object indicating the template content for each card connected to the provided model by name. + + *Sample request*: + ```json + { + "action": "modelTemplates", + "version": 6, + "params": { + "modelName": "Basic (and reversed card)" + } + } + ``` + + *Sample result* + ```json + { + "result": { + "Card 1": { + "Front": "{{Front}}", + "Back": "{{FrontSide}}\n\n
\n\n{{Back}}" + }, + "Card 2": { + "Front": "{{Back}}", + "Back": "{{FrontSide}}\n\n
\n\n{{Front}}" + } + }, + "error": null + } + ``` + + +* **modelStyling** + + Gets the CSS styling for the provided model by name. + + *Sample request*: + ```json + { + "action": "modelStyling", + "version": 6, + "params": { + "modelName": "Basic (and reversed card)" + } + } + ``` + + *Sample result* + ```json + { + "result": { + "css": ".card {\n font-family: arial;\n font-size: 20px;\n text-align: center;\n color: black;\n background-color: white;\n}\n" + }, + "error": null + } + ``` + + +* **updateModelTemplates** + + Modify the templates of an existing model by name. Only specifies cards and specified sides will be modified. + If an existing card or side is not included in the request, it will be left unchanged. + + *Sample request*: + ```json + { + "action": "updateModelTemplates", + "version": 6, + "params": { + "model": { + "name": "Custom", + "templates": { + "Card 1": { + "Front": "{{Question}}?", + "Back": "{{Answer}}!" + } + } + } + } + } + ``` + + *Sample result*: + ```json + { + "result": null, + "error": null + } + ``` + + +* **updateModelStyling** + + Modify the CSS styling of an existing model by name. + + *Sample request*: + ```json + { + "action": "updateModelStyling", + "version": 6, + "params": { + "model": { + "name": "Custom", + "css": "p { color: blue; }" + } + } + } + ``` + + *Sample result*: + ```json + { + "result": null, + "error": null + } + ``` + #### Notes #### * **addNote** diff --git a/tests/test_models.py b/tests/test_models.py index d30490c..ea83c3f 100755 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -4,6 +4,16 @@ import unittest import util +MODEL_1_NAME = 'testModel' +MODEL_2_NAME = 'testModel-second' + +CSS = 'some random css' +NEW_CSS = 'new random css' + +CARD_1_TEMPLATE = {'Front': 'field1', 'Back': 'field2'} +NEW_CARD_1_TEMPLATE = {'Front': 'question: field1', 'Back': 'answer: field2'} + + class TestModels(unittest.TestCase): def runTest(self): # modelNames @@ -21,10 +31,29 @@ class TestModels(unittest.TestCase): modelFieldsOnTemplates = util.invoke('modelFieldsOnTemplates', modelName=modelNames[0]) # createModel with css - newModel = util.invoke('createModel', modelName='testModel', inOrderFields=['field1', 'field2'], cardTemplates=[{'Front':'field1','Back':'field2'}], css='some random css') + newModel = util.invoke('createModel', modelName=MODEL_1_NAME, inOrderFields=['field1', 'field2'], cardTemplates=[CARD_1_TEMPLATE], css=CSS) # createModel without css - newModel = util.invoke('createModel', modelName='testModel-second', inOrderFields=['field1', 'field2'], cardTemplates=[{'Front':'field1','Back':'field2'}]) + newModel = util.invoke('createModel', modelName=MODEL_2_NAME, inOrderFields=['field1', 'field2'], cardTemplates=[CARD_1_TEMPLATE]) + + # modelStyling: get model 1 css + css = util.invoke('modelStyling', modelName=MODEL_1_NAME) + self.assertEqual({'css': CSS}, css) + + # modelTemplates: get model 1 templates + templates = util.invoke('modelTemplates', modelName=MODEL_1_NAME) + self.assertEqual({'Card 1': CARD_1_TEMPLATE}, templates) + + # updateModelStyling: change and verify model css + util.invoke('updateModelStyling', model={'name': MODEL_1_NAME, 'css': NEW_CSS}) + new_css = util.invoke('modelStyling', modelName=MODEL_1_NAME) + self.assertEqual({'css': NEW_CSS}, new_css) + + # updateModelTemplates: change and verify model 1 templates + util.invoke('updateModelTemplates', model={'name': MODEL_1_NAME, 'templates': {'Card 1': NEW_CARD_1_TEMPLATE}}) + templates = util.invoke('modelTemplates', modelName=MODEL_1_NAME) + self.assertEqual({'Card 1': NEW_CARD_1_TEMPLATE}, templates) + if __name__ == '__main__': unittest.main()