This commit is contained in:
Alex Yatskov 2018-01-14 08:41:28 -08:00
commit de56be0ad9
2 changed files with 237 additions and 0 deletions

View File

@ -29,6 +29,7 @@ import socket
import sys import sys
from time import time from time import time
from unicodedata import normalize from unicodedata import normalize
from operator import itemgetter
# #
@ -425,6 +426,18 @@ class AnkiBridge:
if not note.dupeOrEmpty(): if not note.dupeOrEmpty():
return note return note
def updateNoteFields(self, params):
collection = self.collection()
if collection is None:
return
note = collection.getNote(params['id'])
if note is None:
raise Exception("Failed to get note:{}".format(params['id']))
for name, value in params['fields'].items():
if name in note:
note[name] = value
note.flush()
def addTags(self, notes, tags, add=True): def addTags(self, notes, tags, add=True):
self.startEditing() self.startEditing()
@ -432,6 +445,10 @@ class AnkiBridge:
self.stopEditing() self.stopEditing()
def getTags(self):
return self.collection().tags.all()
def suspend(self, cards, suspend=True): def suspend(self, cards, suspend=True):
for card in cards: for card in cards:
isSuspended = self.isSuspended(card) isSuspended = self.isSuspended(card)
@ -695,6 +712,72 @@ class AnkiBridge:
else: else:
return [] return []
def cardsInfo(self,cards):
result = []
for cid in cards:
try:
card = self.collection().getCard(cid)
model = card.model()
note = card.note()
fields = {}
for info in model['flds']:
order = info['ord']
name = info['name']
fields[name] = {'value': note.fields[order], 'order': order}
result.append({
'cardId': card.id,
'fields': fields,
'fieldOrder': card.ord,
'question': card._getQA()['q'],
'answer': card._getQA()['a'],
'modelName': model['name'],
'deckName': self.deckNameFromId(card.did),
'css': model['css'],
'factor': card.factor,
#This factor is 10 times the ease percentage,
# so an ease of 310% would be reported as 3100
'interval': card.ivl,
'note': card.nid
})
except TypeError as e:
# Anki will give a TypeError if the card ID does not exist.
# Best behavior is probably to add an "empty card" to the
# returned result, so that the items of the input and return
# lists correspond.
result.append({})
return result
def notesInfo(self,notes):
result = []
for nid in notes:
try:
note = self.collection().getNote(nid)
model = note.model()
fields = {}
for info in model['flds']:
order = info['ord']
name = info['name']
fields[name] = {'value': note.fields[order], 'order': order}
result.append({
'noteId': note.id,
'tags' : note.tags,
'fields': fields,
'modelName': model['name'],
'cards': self.collection().db.list(
"select id from cards where nid = ? order by ord", note.id)
})
except TypeError as e:
# Anki will give a TypeError if the note ID does not exist.
# Best behavior is probably to add an "empty card" to the
# returned result, so that the items of the input and return
# lists correspond.
result.append({})
return result
def getDecks(self, cards): def getDecks(self, cards):
decks = {} decks = {}
@ -1024,6 +1107,9 @@ class AnkiConnect:
return results return results
@webApi()
def updateNoteFields(self, note):
return self.anki.updateNoteFields(note)
@webApi() @webApi()
def canAddNotes(self, notes): def canAddNotes(self, notes):
@ -1045,6 +1131,11 @@ class AnkiConnect:
return self.anki.addTags(notes, tags, False) return self.anki.addTags(notes, tags, False)
@webApi()
def getTags(self):
return self.anki.getTags()
@webApi() @webApi()
def suspend(self, cards, suspend=True): def suspend(self, cards, suspend=True):
return self.anki.suspend(cards, suspend) return self.anki.suspend(cards, suspend)
@ -1182,6 +1273,13 @@ class AnkiConnect:
def guiExitAnki(self): def guiExitAnki(self):
return self.anki.guiExitAnki() return self.anki.guiExitAnki()
@webApi()
def cardsInfo(self, cards):
return self.anki.cardsInfo(cards)
@webApi()
def notesInfo(self, notes):
return self.anki.notesInfo(notes)
# #
# Entry # Entry

139
README.md
View File

@ -763,6 +763,38 @@ guarantee that your application continues to function properly in the future.
} }
``` ```
#### Note Modification ####
* **updateNoteFields**
Modify the fields of an exist note.
*Sample request*:
```json
{
"action": "updateNoteFields",
"version": 5,
"params": {
"note": {
"id": 1514547547030,
"fields": {
"Front": "new front content",
"Back": "new back content"
},
}
}
}
```
*Sample result*:
```json
{
"result": null,
"error": null
}
```
#### Note Tags #### #### Note Tags ####
* **addTags** * **addTags**
@ -813,6 +845,26 @@ guarantee that your application continues to function properly in the future.
} }
``` ```
* **getTags**
Gets the complete list of tags for the current user.
*Sample request*:
```json
{
"action": "getTags",
"version": 5
}
```
*Sample result*:
```json
{
"result": ["european-languages", "idioms"],
"error": null
}
```
#### Card Suspension #### #### Card Suspension ####
* **suspend** * **suspend**
@ -1033,6 +1085,93 @@ guarantee that your application continues to function properly in the future.
} }
``` ```
* **cardsInfo**
Returns a list of objects containing for each card ID the card fields, front and back sides including CSS, note type, the note that the card belongs to, and deck name, as well as ease and interval.
*Sample request*:
```json
{
"action": "cardsInfo",
"version": 5,
"params": {
"cards": [1498938915662, 1502098034048]
}
}
```
*Sample result*:
```json
{
"result": [
{
"answer": "back content",
"question": "front content",
"deckName": "Default",
"modelName": "Basic",
"fieldOrder": 1,
"fields": {
"Front": {"value": "front content", "order": 0},
"Back": {"value": "back content", "order": 1}
},
"css":"p {font-family:Arial;}",
"cardId": 1498938915662,
"interval": 16,
"note":1502298033753
},
{
"answer": "back content",
"question": "front content",
"deckName": "Default",
"modelName": "Basic",
"fieldOrder": 0,
"fields": {
"Front": {"value": "front content", "order": 0},
"Back": {"value": "back content", "order": 1}
},
"css":"p {font-family:Arial;}",
"cardId": 1502098034048,
"interval": 23,
"note":1502298033753
}
],
"error": null
}
```
* **notesInfo**
Returns a list of objects containing for each note ID the note fields, tags, note type and the cards belonging to the note.
*Sample request*:
```json
{
"action": "notesInfo",
"version": 5,
"params": {
"notes": [1502298033753]
}
}
```
*Sample result*:
```json
{
"result": [
{
"noteId":1502298033753,
"modelName": "Basic",
"tags":["tag","another_tag"],
"fields": {
"Front": {"value": "front content", "order": 0},
"Back": {"value": "back content", "order": 1}
},
}
],
"error": null
}
```
#### Media File Storage #### #### Media File Storage ####
* **storeMediaFile** * **storeMediaFile**