From 131a1c7cfc3225451d7853fc13760d117393fa31 Mon Sep 17 00:00:00 2001 From: Venkata Ramana Date: Sat, 27 Feb 2021 10:47:51 +0530 Subject: [PATCH] Added findAndReplaceInModels (#228) * added findAndReplaceInModels api call * added documentation for findAndReplaceInModels * added findAndReplaceInModels api call * updatd findAndReplaceInModels function * added unit test for findAndReplaceInModels in models * updated findAndReplaceInModels * added unit test for findAndReplaceInModels * removed 'all_models' in findAndReplaceInModels --- actions/models.md | 30 ++++++++++++++++++++++++++++++ plugin/__init__.py | 30 ++++++++++++++++++++++++++++++ tests/test_models.py | 8 +++++++- 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/actions/models.md b/actions/models.md index fcbcb43..ef3e817 100644 --- a/actions/models.md +++ b/actions/models.md @@ -309,3 +309,33 @@ "error": null } ``` + +* **findAndReplaceInModels** + + Find and replace string in existing model by model name. Customise to replace in front, back or css by setting to true/false. + + *Sample request*: + ```json + { + "action": "findAndReplaceInModels", + "version": 6, + "params": { + "model": { + "modelName": "", + "findText": "text_to_replace", + "replaceText": "replace_with_text", + "front": true, + "back": true, + "css": true + } + } + } + ``` + + *Sample result*: + ```json + { + "result": 1, + "error": null + } + ``` \ No newline at end of file diff --git a/plugin/__init__.py b/plugin/__init__.py index 91c29a9..1517146 100644 --- a/plugin/__init__.py +++ b/plugin/__init__.py @@ -934,6 +934,36 @@ class AnkiConnect: models.flush() + @util.api() + def findAndReplaceInModels(self, modelName, findText, replaceText, front=True, back=True, css=True): + if not modelName: + ankiModel = self.collection().models.allNames() + else: + model = self.collection().models.byName(modelName) + if model is None: + raise Exception('model was not found: {}'.format(modelName)) + ankiModel = [model] + updatedModels = 0 + for model in ankiModel: + model = self.collection().models.byName(model) + checkForText = False + if css and findText in model['css']: + checkForText = True + model['css'] = model['css'].replace(findText, replaceText) + for tmpls in model.get('tmpls'): + if front and findText in tmpls['qfmt']: + checkForText = True + tmpls['qfmt'] = tmpls['qfmt'].replace(findText, replaceText) + if back and findText in tmpls['afmt']: + checkForText = True + tmpls['afmt'] = tmpls['afmt'].replace(findText, replaceText) + self.collection().models.save(model, True) + self.collection().models.flush() + if checkForText: + updatedModels += 1 + return updatedModels + + @util.api() def deckNameFromId(self, deckId): deck = self.collection().decks.get(deckId) diff --git a/tests/test_models.py b/tests/test_models.py index 550c194..20161f6 100755 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -14,6 +14,8 @@ NEW_CSS = 'new random css' CARD_1_TEMPLATE = {'Front': 'field1', 'Back': 'field2'} NEW_CARD_1_TEMPLATE = {'Front': 'question: field1', 'Back': 'answer: field2'} +TEXT_TO_REPLACE = "new random css" +REPLACE_WITH_TEXT = "new updated css" class TestModels(unittest.TestCase): def runTest(self): @@ -55,6 +57,10 @@ class TestModels(unittest.TestCase): templates = util.invoke('modelTemplates', modelName=MODEL_1_NAME) self.assertEqual({'Card 1': NEW_CARD_1_TEMPLATE}, templates) + # findAndReplaceInModels: find and replace text in all models or model by name + util.invoke('findAndReplaceInModels', modelName=MODEL_1_NAME, findText=TEXT_TO_REPLACE, replaceText=REPLACE_WITH_TEXT, front=True, back=True, css=True) + new_css = util.invoke('modelStyling', modelName=MODEL_1_NAME) + self.assertEqual({'css': REPLACE_WITH_TEXT}, new_css) if __name__ == '__main__': - unittest.main() + unittest.main() \ No newline at end of file