Merge pull request #382 from Aquafina-water-bottle/modelTemplates

Added various actions relating to model templates
This commit is contained in:
Alexei Yatskov 2023-04-14 17:21:32 -07:00 committed by GitHub
commit 08e5a34d6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 249 additions and 10 deletions

128
README.md
View File

@ -2630,6 +2630,134 @@ corresponding to when the API was available for use.
``` ```
</details> </details>
#### `modelTemplateRename`
* Renames a template in an existing model.
<details>
<summary><i>Sample request:</i></summary>
```json
{
"action": "modelTemplateRename",
"version": 6,
"params": {
"modelName": "Basic",
"oldTemplateName": "Card 1",
"newTemplateName": "Card 1 renamed"
}
}
```
</details>
<details>
<summary><i>Sample result:</i></summary>
```json
{
"result": null,
"error": null
}
```
</details>
#### `modelTemplateReposition`
* Repositions a template in an existing model.
The value of `index` starts at 0. For example, an index of `0` puts the template in the first position, and an index of `2` puts the template in the third position.
<details>
<summary><i>Sample request:</i></summary>
```json
{
"action": "modelTemplateRemove",
"version": 6,
"params": {
"modelName": "Basic",
"templateName": "Card 1",
"index": 1
}
}
```
</details>
<details>
<summary><i>Sample result:</i></summary>
```json
{
"result": null,
"error": null
}
```
</details>
#### `modelTemplateAdd`
* Adds a template to an existing model by name. If you want to update an existing template, use `updateModelTemplates`.
<details>
<summary><i>Sample request:</i></summary>
```json
{
"action": "modelTemplateAdd",
"version": 6,
"params": {
"modelName": "Basic",
"template": {
"Name": "Card 3",
"Front": "Front html {{Field1}}",
"Back": "Back html {{Field2}}"
}
}
}
```
</details>
<details>
<summary><i>Sample result:</i></summary>
```json
{
"result": null,
"error": null
}
```
</details>
#### `modelTemplateRemove`
* Removes a template from an existing model.
<details>
<summary><i>Sample request:</i></summary>
```json
{
"action": "modelTemplateRemove",
"version": 6,
"params": {
"modelName": "Basic",
"templateName": "Card 1"
}
}
```
</details>
<details>
<summary><i>Sample result:</i></summary>
```json
{
"result": null,
"error": null
}
```
</details>
#### `modelFieldRename` #### `modelFieldRename`
* Rename the field name of a given model. * Rename the field name of a given model.

View File

@ -196,15 +196,20 @@ class AnkiConnect:
return model return model
def getField(self, modelName, fieldName): def getField(self, model, fieldName):
model = self.getModel(modelName)
fieldMap = self.collection().models.fieldMap(model) fieldMap = self.collection().models.fieldMap(model)
if fieldName not in fieldMap: if fieldName not in fieldMap:
raise Exception('field was not found in {}: {}'.format(modelName, fieldName)) raise Exception('field was not found in {}: {}'.format(model['name'], fieldName))
return fieldMap[fieldName][1] return fieldMap[fieldName][1]
def getTemplate(self, model, templateName):
for ankiTemplate in model['tmpls']:
if ankiTemplate['name'] == templateName:
return ankiTemplate
raise Exception('template was not found in {}: {}'.format(model['name'], templateName))
def startEditing(self): def startEditing(self):
self.window().requireReset() self.window().requireReset()
@ -1268,11 +1273,65 @@ class AnkiConnect:
return updatedModels return updatedModels
@util.api()
def modelTemplateRename(self, modelName, oldTemplateName, newTemplateName):
mm = self.collection().models
model = self.getModel(modelName)
ankiTemplate = self.getTemplate(model, oldTemplateName)
ankiTemplate['name'] = newTemplateName
self.save_model(mm, model)
@util.api()
def modelTemplateReposition(self, modelName, templateName, index):
mm = self.collection().models
model = self.getModel(modelName)
ankiTemplate = self.getTemplate(model, templateName)
mm.reposition_template(model, ankiTemplate, index)
self.save_model(mm, model)
@util.api()
def modelTemplateAdd(self, modelName, template):
# "Name", "Front", "Back" borrows from `createModel`
mm = self.collection().models
model = self.getModel(modelName)
name = template['Name']
qfmt = template['Front']
afmt = template['Back']
# updates the template if it already exists
for ankiTemplate in model['tmpls']:
if ankiTemplate['name'] == name:
ankiTemplate['qfmt'] = qfmt
ankiTemplate['afmt'] = afmt
return
ankiTemplate = mm.new_template(name)
ankiTemplate['qfmt'] = qfmt
ankiTemplate['afmt'] = afmt
mm.add_template(model, ankiTemplate)
self.save_model(mm, model)
@util.api()
def modelTemplateRemove(self, modelName, templateName):
mm = self.collection().models
model = self.getModel(modelName)
ankiTemplate = self.getTemplate(model, templateName)
mm.remove_template(model, ankiTemplate)
self.save_model(mm, model)
@util.api() @util.api()
def modelFieldRename(self, modelName, oldFieldName, newFieldName): def modelFieldRename(self, modelName, oldFieldName, newFieldName):
mm = self.collection().models mm = self.collection().models
model = self.getModel(modelName) model = self.getModel(modelName)
field = self.getField(modelName, oldFieldName) field = self.getField(model, oldFieldName)
mm.renameField(model, field, newFieldName) mm.renameField(model, field, newFieldName)
@ -1283,7 +1342,7 @@ class AnkiConnect:
def modelFieldReposition(self, modelName, fieldName, index): def modelFieldReposition(self, modelName, fieldName, index):
mm = self.collection().models mm = self.collection().models
model = self.getModel(modelName) model = self.getModel(modelName)
field = self.getField(modelName, fieldName) field = self.getField(model, fieldName)
mm.repositionField(model, field, index) mm.repositionField(model, field, index)
@ -1314,7 +1373,7 @@ class AnkiConnect:
def modelFieldRemove(self, modelName, fieldName): def modelFieldRemove(self, modelName, fieldName):
mm = self.collection().models mm = self.collection().models
model = self.getModel(modelName) model = self.getModel(modelName)
field = self.getField(modelName, fieldName) field = self.getField(model, fieldName)
mm.removeField(model, field) mm.removeField(model, field)
@ -1325,7 +1384,7 @@ class AnkiConnect:
def modelFieldSetFont(self, modelName, fieldName, font): def modelFieldSetFont(self, modelName, fieldName, font):
mm = self.collection().models mm = self.collection().models
model = self.getModel(modelName) model = self.getModel(modelName)
field = self.getField(modelName, fieldName) field = self.getField(model, fieldName)
if not isinstance(font, str): if not isinstance(font, str):
raise Exception('font should be a string: {}'.format(font)) raise Exception('font should be a string: {}'.format(font))
@ -1339,7 +1398,7 @@ class AnkiConnect:
def modelFieldSetFontSize(self, modelName, fieldName, fontSize): def modelFieldSetFontSize(self, modelName, fieldName, fontSize):
mm = self.collection().models mm = self.collection().models
model = self.getModel(modelName) model = self.getModel(modelName)
field = self.getField(modelName, fieldName) field = self.getField(model, fieldName)
if not isinstance(fontSize, int): if not isinstance(fontSize, int):
raise Exception('fontSize should be an integer: {}'.format(fontSize)) raise Exception('fontSize should be an integer: {}'.format(fontSize))
@ -1353,7 +1412,7 @@ class AnkiConnect:
def modelFieldSetDescription(self, modelName, fieldName, description): def modelFieldSetDescription(self, modelName, fieldName, description):
mm = self.collection().models mm = self.collection().models
model = self.getModel(modelName) model = self.getModel(modelName)
field = self.getField(modelName, fieldName) field = self.getField(model, fieldName)
if not isinstance(description, str): if not isinstance(description, str):
raise Exception('description should be a string: {}'.format(description)) raise Exception('description should be a string: {}'.format(description))

View File

@ -132,6 +132,58 @@ def test_findAndReplaceInModels(setup):
} }
class TestModelTemplates:
def test_modelTemplateRename(self, setup):
ac.modelTemplateRename(
modelName="test_model",
oldTemplateName="Card 1",
newTemplateName="Card 1 Renamed",
)
result = ac.modelTemplates(modelName="test_model")
assert result == {
"Card 1 Renamed": {"Front": "{{field1}}", "Back": "{{field2}}"},
"Card 2": {"Front": "{{field2}}", "Back": "{{field1}}"}
}
def test_modelTemplateReposition(self, setup):
# There currently isn't a way to test for order, so this is just a
# smoke test for now
ac.modelTemplateReposition(
modelName="test_model",
templateName="Card 1",
index=1,
)
def test_modelTemplateAdd(self, setup):
ac.modelTemplateAdd(
modelName="test_model",
template={
"Name": "Card 3",
"Front": "{{field1}} Card 3",
"Back": "{{field2}}",
}
)
result = ac.modelTemplates(modelName="test_model")
assert result == {
"Card 1": {"Front": "{{field1}}", "Back": "{{field2}}"},
"Card 2": {"Front": "{{field2}}", "Back": "{{field1}}"},
"Card 3": {"Front": "{{field1}} Card 3", "Back": "{{field2}}"},
}
def test_modelTemplateRemove(self, setup):
ac.modelTemplateRemove(
modelName="test_model",
templateName="Card 2"
)
result = ac.modelTemplates(modelName="test_model")
assert result == {
"Card 1": {"Front": "{{field1}}", "Back": "{{field2}}"},
}
class TestModelFieldNames: class TestModelFieldNames:
def test_modelFieldRename(self, setup): def test_modelFieldRename(self, setup):
ac.modelFieldRename( ac.modelFieldRename(