Merge pull request #367 from Aquafina-water-bottle/master

Added various calls for model fields (getting & setting font, setting description)
This commit is contained in:
Alexei Yatskov 2022-12-29 11:42:01 -08:00 committed by GitHub
commit 7234914d44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 259 additions and 27 deletions

109
README.md
View File

@ -1865,6 +1865,38 @@ corresponding to when the API was available for use.
}
```
* **modelFieldFonts**
Gets the complete list of fonts along with their font sizes.
*Sample request*:
```json
{
"action": "modelFieldFonts",
"version": 6,
"params": {
"modelName": "Basic"
}
}
```
*Sample result*:
```json
{
"result": {
"Front": {
"font": "Arial",
"size": 20
},
"Back": {
"font": "Arial",
"size": 20
}
},
"error": null
}
```
* **modelFieldsOnTemplates**
Returns an object indicating the fields on the question and answer side of each card template for the given model
@ -2238,6 +2270,83 @@ corresponding to when the API was available for use.
}
```
* **modelFieldSetFont**
Sets the font for a field within a given model.
*Sample Request*:
```json
{
"action": "modelFieldSetFont",
"version": 6,
"params": {
"modelName": "Basic",
"fieldName": "Front",
"font": "Courier"
}
}
```
*Sample result*:
```json
{
"result": null,
"error": null
}
```
* **modelFieldSetFontSize**
Sets the font size for a field within a given model.
*Sample Request*:
```json
{
"action": "modelFieldSetFont",
"version": 6,
"params": {
"modelName": "Basic",
"fieldName": "Front",
"fontSize": 10
}
}
```
*Sample result*:
```json
{
"result": null,
"error": null
}
```
* **modelFieldSetDescription**
Sets the description (the text seen in the gui editor when a field is empty) for a field within a given model.
Older versions of Anki (2.1.49 and below) do not have field descriptions. In that case, this will return with `false`.
*Sample Request*:
```json
{
"action": "modelFieldSetDescription",
"version": 6,
"params": {
"modelName": "Basic",
"fieldName": "Front",
"description": "example field description"
}
}
```
*Sample result*:
```json
{
"result": true,
"error": null
}
```
#### Note Actions
* **addNote**

View File

@ -189,6 +189,22 @@ class AnkiConnect:
return media
def getModel(self, modelName):
model = self.collection().models.byName(modelName)
if model is None:
raise Exception('model was not found: {}'.format(modelName))
return model
def getField(self, modelName, fieldName):
model = self.getModel(modelName)
fieldMap = self.collection().models.fieldMap(model)
if fieldName not in fieldMap:
raise Exception('field was not found in {}: {}'.format(modelName, fieldName))
return fieldMap[fieldName][1]
def startEditing(self):
self.window().requireReset()
@ -1082,6 +1098,20 @@ class AnkiConnect:
return ['' for field in model['flds']]
@util.api()
def modelFieldFonts(self, modelName):
model = self.getModel(modelName)
fonts = {}
for field in model['flds']:
fonts[field['name']] = {
'font': field['font'],
'size': field['size'],
}
return fonts
@util.api()
def modelFieldsOnTemplates(self, modelName):
@ -1202,14 +1232,8 @@ class AnkiConnect:
@util.api()
def modelFieldRename(self, modelName, oldFieldName, newFieldName):
mm = self.collection().models
model = mm.byName(modelName)
if model is None:
raise Exception('model was not found: {}'.format(modelName))
fieldMap = mm.fieldMap(model)
if oldFieldName not in fieldMap:
raise Exception('field was not found in {}: {}'.format(modelName, oldFieldName))
field = fieldMap[oldFieldName][1]
model = self.getModel(modelName)
field = self.getField(modelName, oldFieldName)
mm.renameField(model, field, newFieldName)
@ -1219,14 +1243,8 @@ class AnkiConnect:
@util.api()
def modelFieldReposition(self, modelName, fieldName, index):
mm = self.collection().models
model = mm.byName(modelName)
if model is None:
raise Exception('model was not found: {}'.format(modelName))
fieldMap = mm.fieldMap(model)
if fieldName not in fieldMap:
raise Exception('field was not found in {}: {}'.format(modelName, fieldName))
field = fieldMap[fieldName][1]
model = self.getModel(modelName)
field = self.getField(modelName, fieldName)
mm.repositionField(model, field, index)
@ -1236,9 +1254,7 @@ class AnkiConnect:
@util.api()
def modelFieldAdd(self, modelName, fieldName, index=None):
mm = self.collection().models
model = mm.byName(modelName)
if model is None:
raise Exception('model was not found: {}'.format(modelName))
model = self.getModel(modelName)
# only adds the field if it doesn't already exist
fieldMap = mm.fieldMap(model)
@ -1258,20 +1274,58 @@ class AnkiConnect:
@util.api()
def modelFieldRemove(self, modelName, fieldName):
mm = self.collection().models
model = mm.byName(modelName)
if model is None:
raise Exception('model was not found: {}'.format(modelName))
fieldMap = mm.fieldMap(model)
if fieldName not in fieldMap:
raise Exception('field was not found in {}: {}'.format(modelName, fieldName))
field = fieldMap[fieldName][1]
model = self.getModel(modelName)
field = self.getField(modelName, fieldName)
mm.removeField(model, field)
self.save_model(mm, model)
@util.api()
def modelFieldSetFont(self, modelName, fieldName, font):
mm = self.collection().models
model = self.getModel(modelName)
field = self.getField(modelName, fieldName)
if not isinstance(font, str):
raise Exception('font should be a string: {}'.format(font))
field['font'] = font
self.save_model(mm, model)
@util.api()
def modelFieldSetFontSize(self, modelName, fieldName, fontSize):
mm = self.collection().models
model = self.getModel(modelName)
field = self.getField(modelName, fieldName)
if not isinstance(fontSize, int):
raise Exception('fontSize should be an integer: {}'.format(fontSize))
field['size'] = fontSize
self.save_model(mm, model)
@util.api()
def modelFieldSetDescription(self, modelName, fieldName, description):
mm = self.collection().models
model = self.getModel(modelName)
field = self.getField(modelName, fieldName)
if not isinstance(description, str):
raise Exception('description should be a string: {}'.format(description))
if 'description' in field: # older versions do not have the 'description' key
field['description'] = description
self.save_model(mm, model)
return True
return False
@util.api()
def deckNameFromId(self, deckId):
deck = self.collection().decks.get(deckId)

View File

@ -1,4 +1,5 @@
from conftest import ac
from plugin import anki_version
def test_modelNames(setup):
@ -21,6 +22,20 @@ def test_modelFieldDescriptions(setup):
assert result == ["", ""]
def test_modelFieldFonts(setup):
result = ac.modelFieldFonts(modelName="test_model")
assert result == {
"field1": {
"font": "Arial",
"size": 20,
},
"field2": {
"font": "Arial",
"size": 20,
},
}
def test_modelFieldsOnTemplates(setup):
result = ac.modelFieldsOnTemplates(modelName="test_model")
assert result == {
@ -172,3 +187,57 @@ class TestModelFieldNames:
result = ac.modelFieldNames(modelName="test_model")
assert result == ["field2"]
def test_modelFieldSetFont(self, setup):
ac.modelFieldSetFont(
modelName="test_model",
fieldName="field1",
font="Courier",
)
result = ac.modelFieldFonts(modelName="test_model")
assert result == {
"field1": {
"font": "Courier",
"size": 20,
},
"field2": {
"font": "Arial",
"size": 20,
},
}
def test_modelFieldSetFontSize(self, setup):
ac.modelFieldSetFontSize(
modelName="test_model",
fieldName="field2",
fontSize=16,
)
result = ac.modelFieldFonts(modelName="test_model")
assert result == {
"field1": {
"font": "Arial",
"size": 20,
},
"field2": {
"font": "Arial",
"size": 16,
},
}
def test_modelFieldSetDescription(self, setup):
set_desc = ac.modelFieldSetDescription(
modelName="test_model",
fieldName="field1",
description="test description",
)
result = ac.modelFieldDescriptions(modelName="test_model")
if anki_version < (2, 1, 50):
assert not set_desc
assert result == ["", ""]
else:
assert set_desc
assert result == ["test description", ""]