This commit is contained in:
Alex Yatskov 2017-08-20 18:24:14 -07:00
commit 285645e516
2 changed files with 267 additions and 31 deletions

View File

@ -199,6 +199,26 @@ class AjaxServer:
self.handler = handler self.handler = handler
self.clients = [] self.clients = []
self.sock = None self.sock = None
self.resetHeaders()
def setHeader(self, name, value):
self.extraHeaders[name] = value
def resetHeaders(self):
self.headers = [
['HTTP/1.1 200 OK', None],
['Content-Type', 'text/json']
]
self.extraHeaders = {}
def getHeaders(self):
headers = self.headers[:]
for name in self.extraHeaders:
headers.append([name, self.extraHeaders[name]])
return headers
def advance(self): def advance(self):
@ -243,11 +263,9 @@ class AjaxServer:
body = json.dumps(None); body = json.dumps(None);
resp = bytes() resp = bytes()
headers = [
['HTTP/1.1 200 OK', None], self.setHeader('Content-Length', str(len(body)))
['Content-Type', 'text/json'], headers = self.getHeaders()
['Content-Length', str(len(body))]
]
for key, value in headers: for key, value in headers:
if value is None: if value is None:
@ -474,6 +492,13 @@ class AnkiBridge:
return self.collection().sched return self.collection().sched
def multi(self, actions):
response = []
for item in actions:
response.append(AnkiConnect.handler(ac, item))
return response
def media(self): def media(self):
collection = self.collection() collection = self.collection()
if collection is not None: if collection is not None:
@ -502,11 +527,59 @@ class AnkiBridge:
return [field['name'] for field in model['flds']] return [field['name'] for field in model['flds']]
def multi(self, actions): def getDeckConfig(self, deck):
response = [] if not deck in self.deckNames():
for item in actions: return False
response.append(AnkiConnect.handler(ac, item))
return response did = self.collection().decks.id(deck)
return self.collection().decks.confForDid(did)
def saveDeckConfig(self, config):
configId = str(config['id'])
if not configId in self.collection().decks.dconf:
return False
mod = anki.utils.intTime()
usn = self.collection().usn()
config['mod'] = mod
config['usn'] = usn
self.collection().decks.dconf[configId] = config
self.collection().decks.changed = True
return True
def setDeckConfigId(self, decks, configId):
for deck in decks:
if not deck in self.deckNames():
return False
if not str(configId) in self.collection().decks.dconf:
return False
for deck in decks:
did = str(self.collection().decks.id(deck))
aqt.mw.col.decks.decks[did]['conf'] = configId
return True
def cloneDeckConfigId(self, name, cloneFrom=1):
if not str(cloneFrom) in self.collection().decks.dconf:
return False
cloneFrom = self.collection().decks.getConf(cloneFrom)
return self.collection().decks.confId(name, cloneFrom)
def removeDeckConfigId(self, configId):
if configId == 1 or not str(configId) in self.collection().decks.dconf:
return False
self.collection().decks.remConf(configId)
return True
def deckNames(self): def deckNames(self):
@ -520,8 +593,8 @@ class AnkiBridge:
deckNames = self.deckNames() deckNames = self.deckNames()
for deck in deckNames: for deck in deckNames:
id = self.collection().decks.id(deck) did = self.collection().decks.id(deck)
decks[deck] = id decks[deck] = did
return decks return decks
@ -582,8 +655,8 @@ class AnkiBridge:
def deleteDecks(self, decks, cardsToo=False): def deleteDecks(self, decks, cardsToo=False):
self.startEditing() self.startEditing()
for deck in decks: for deck in decks:
id = self.collection().decks.id(deck) did = self.collection().decks.id(deck)
self.collection().decks.rem(id, cardsToo) self.collection().decks.rem(did, cardsToo)
self.stopEditing() self.stopEditing()
@ -636,7 +709,7 @@ class AnkiBridge:
'fieldOrder': card.ord, 'fieldOrder': card.ord,
'question': card._getQA()['q'], 'question': card._getQA()['q'],
'answer': card._getQA()['a'], 'answer': card._getQA()['a'],
'buttons': map(lambda b: b[0], reviewer._answerButtonList()), 'buttons': [b[0] for b in reviewer._answerButtonList()],
'modelName': model['name'], 'modelName': model['name'],
'deckName': self.deckNameFromId(card.did) 'deckName': self.deckNameFromId(card.did)
} }
@ -759,6 +832,11 @@ class AnkiConnect:
return handler(**params) return handler(**params)
@webApi
def multi(self, actions):
return self.anki.multi(actions)
@webApi @webApi
def deckNames(self): def deckNames(self):
return self.anki.deckNames() return self.anki.deckNames()
@ -780,8 +858,28 @@ class AnkiConnect:
@webApi @webApi
def multi(self, actions): def getDeckConfig(self, deck):
return self.anki.multi(actions) return self.anki.getDeckConfig(deck)
@webApi
def saveDeckConfig(self, config):
return self.anki.saveDeckConfig(config)
@webApi
def setDeckConfigId(self, decks, configId):
return self.anki.setDeckConfigId(decks, configId)
@webApi
def cloneDeckConfigId(self, name, cloneFrom=1):
return self.anki.cloneDeckConfigId(name, cloneFrom)
@webApi
def removeDeckConfigId(self, configId):
return self.anki.removeDeckConfigId(configId)
@webApi @webApi

166
README.md
View File

@ -103,6 +103,35 @@ Below is a list of currently supported actions. Requests with invalid actions or
``` ```
4 4
``` ```
* **multi**
Performs multiple actions in one request, returning an array with the response of each action (in the given order).
*Sample request*:
```
{
"action": "multi",
"params": {
"actions": [
{"action": "deckNames"},
{
"action": "browse",
"params": {"query": "deck:current"}
}
]
}
}
```
*Sample response*:
```
[
["Default"],
[1494723142483, 1494703460437, 1494703479525]
]
```
* **deckNames** * **deckNames**
Gets the complete list of deck names for the current user. Gets the complete list of deck names for the current user.
@ -162,32 +191,141 @@ Below is a list of currently supported actions. Requests with invalid actions or
] ]
``` ```
* **multi** * **getDeckConfig**
Performs multiple actions in one request, returning an array with the response of each action (in the given order). Gets the config group object for the given deck.
*Sample request*: *Sample request*:
``` ```
{ {
"action": "multi", "action": "getDeckConfig",
"params": { "params": {
"actions": [ "deck": "Default"
{"action": "deckNames"},
{
"action": "browse",
"params": {"query": "deck:current"}
}
]
} }
} }
``` ```
*Sample response*: *Sample response*:
``` ```
[ {
["Default"], "lapse": {
[1494723142483, 1494703460437, 1494703479525] "leechFails": 8,
] "delays": [10],
"minInt": 1,
"leechAction": 0,
"mult": 0
},
"dyn": false,
"autoplay": true,
"mod": 1502970872,
"id": 1,
"maxTaken": 60,
"new": {
"bury": true,
"order": 1,
"initialFactor": 2500,
"perDay": 20,
"delays": [1, 10],
"separate": true,
"ints": [1, 4, 7]
},
"name": "Default",
"rev": {
"bury": true,
"ivlFct": 1,
"ease4": 1.3,
"maxIvl": 36500,
"perDay": 100,
"minSpace": 1,
"fuzz": 0.05
},
"timer": 0,
"replayq": true,
"usn": -1
}
```
* **saveDeckConfig**
Saves the given config group, returning `true` on success or `false` if the ID of the config group is invalid (i.e.
it does not exist).
*Sample request*:
```
{
"action": "saveDeckConfig",
"params": {
"config": (config group object)
}
}
```
*Sample response*:
```
true
```
* **setDeckConfigId**
Changes the configuration group for the given decks to the one with the given ID. Returns `true` on success or
`false` if the given configuration group or any of the given decks do not exist.
*Sample request*:
```
{
"action": "setDeckConfigId",
"params": {
"decks": ["Default"],
"configId": 1
}
}
```
*Sample response*:
```
true
```
* **cloneDeckConfigId**
Creates a new config group with the given name, cloning from the group with the given ID, or from the default group
if this is unspecified. Returns the ID of the new config group, or `false` if the specified group to clone from does
not exist.
*Sample request*:
```
{
"action": "cloneDeckConfigId",
"params": {
"name": "Copy of Default",
"cloneFrom": 1
}
}
```
*Sample response*:
```
1502972374573
```
* **removeDeckConfigId**
Removes the config group with the given ID, returning `true` if successful, or `false` if attempting to remove
either the default config group (ID = 1) or a config group that does not exist.
*Sample request*:
```
{
"action": "removeDeckConfigId",
"params": {
"configId": 1502972374573
}
}
```
*Sample response*:
```
true
``` ```
* **addNote** * **addNote**