Skip to content
This repository has been archived by the owner on Dec 31, 2023. It is now read-only.

Added various actions relating to model templates #382

Merged
merged 3 commits into from
Apr 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 128 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2630,6 +2630,134 @@ corresponding to when the API was available for use.
```
</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`

* Rename the field name of a given model.
Expand Down
79 changes: 69 additions & 10 deletions plugin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,15 +196,20 @@ def getModel(self, modelName):
return model


def getField(self, modelName, fieldName):
model = self.getModel(modelName)

def getField(self, model, fieldName):
fieldMap = self.collection().models.fieldMap(model)
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]


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):
self.window().requireReset()

Expand Down Expand Up @@ -1268,11 +1273,65 @@ def findAndReplaceInModels(self, modelName, findText, replaceText, front=True, b
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()
def modelFieldRename(self, modelName, oldFieldName, newFieldName):
mm = self.collection().models
model = self.getModel(modelName)
field = self.getField(modelName, oldFieldName)
field = self.getField(model, oldFieldName)

mm.renameField(model, field, newFieldName)

Expand All @@ -1283,7 +1342,7 @@ def modelFieldRename(self, modelName, oldFieldName, newFieldName):
def modelFieldReposition(self, modelName, fieldName, index):
mm = self.collection().models
model = self.getModel(modelName)
field = self.getField(modelName, fieldName)
field = self.getField(model, fieldName)

mm.repositionField(model, field, index)

Expand Down Expand Up @@ -1314,7 +1373,7 @@ def modelFieldAdd(self, modelName, fieldName, index=None):
def modelFieldRemove(self, modelName, fieldName):
mm = self.collection().models
model = self.getModel(modelName)
field = self.getField(modelName, fieldName)
field = self.getField(model, fieldName)

mm.removeField(model, field)

Expand All @@ -1325,7 +1384,7 @@ def modelFieldRemove(self, modelName, fieldName):
def modelFieldSetFont(self, modelName, fieldName, font):
mm = self.collection().models
model = self.getModel(modelName)
field = self.getField(modelName, fieldName)
field = self.getField(model, fieldName)

if not isinstance(font, str):
raise Exception('font should be a string: {}'.format(font))
Expand All @@ -1339,7 +1398,7 @@ def modelFieldSetFont(self, modelName, fieldName, font):
def modelFieldSetFontSize(self, modelName, fieldName, fontSize):
mm = self.collection().models
model = self.getModel(modelName)
field = self.getField(modelName, fieldName)
field = self.getField(model, fieldName)

if not isinstance(fontSize, int):
raise Exception('fontSize should be an integer: {}'.format(fontSize))
Expand All @@ -1353,7 +1412,7 @@ def modelFieldSetFontSize(self, modelName, fieldName, fontSize):
def modelFieldSetDescription(self, modelName, fieldName, description):
mm = self.collection().models
model = self.getModel(modelName)
field = self.getField(modelName, fieldName)
field = self.getField(model, fieldName)

if not isinstance(description, str):
raise Exception('description should be a string: {}'.format(description))
Expand Down
52 changes: 52 additions & 0 deletions tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
def test_modelFieldRename(self, setup):
ac.modelFieldRename(
Expand Down