Duplicate scope options (#203)
* Add additional options to addNote's duplicateScope option * Update documentation
This commit is contained in:
parent
b19bd7902d
commit
ab1f518474
@ -11,9 +11,14 @@
|
|||||||
downloaded files with an MD5 hash that matches the provided value. This is useful for avoiding the saving of error
|
downloaded files with an MD5 hash that matches the provided value. This is useful for avoiding the saving of error
|
||||||
pages and stub files. The `fields` member is a list of fields that should play audio when the card is displayed in
|
pages and stub files. The `fields` member is a list of fields that should play audio when the card is displayed in
|
||||||
Anki. The `allowDuplicate` member inside `options` group can be set to true to enable adding duplicate cards.
|
Anki. The `allowDuplicate` member inside `options` group can be set to true to enable adding duplicate cards.
|
||||||
Normally duplicate cards can not be added and trigger exception. The `duplicateScope` member inside `options` can be
|
Normally duplicate cards can not be added and trigger exception.
|
||||||
used to specify the scope for which duplicates are checked. A value of `"deck"` will only check for duplicates in the
|
|
||||||
target deck; any other value will check the entire collection.
|
The `duplicateScope` member inside `options` can be used to specify the scope for which duplicates are checked.
|
||||||
|
A value of `"deckName"` will only check for duplicates in the target deck; any other value will check the entire collection.
|
||||||
|
The `duplicateScopeOptions` object can be used to specify some additional settings. `duplicateScopeOptions.deckName`
|
||||||
|
will specify which deck to use for checking duplicates in. If undefined or `null`, the target deck will be used.
|
||||||
|
`duplicateScopeOptions.checkChildren` will change whether or not duplicate cards are checked in child decks;
|
||||||
|
the default value is `false`.
|
||||||
|
|
||||||
*Sample request*:
|
*Sample request*:
|
||||||
```json
|
```json
|
||||||
@ -30,7 +35,11 @@
|
|||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"allowDuplicate": false,
|
"allowDuplicate": false,
|
||||||
"duplicateScope": "deck"
|
"duplicateScope": "deck",
|
||||||
|
"duplicateScopeOptions": {
|
||||||
|
"deckName": "Default",
|
||||||
|
"checkChildren": false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"tags": [
|
"tags": [
|
||||||
"yomichan"
|
"yomichan"
|
||||||
|
@ -207,6 +207,8 @@ class AnkiConnect:
|
|||||||
|
|
||||||
allowDuplicate = False
|
allowDuplicate = False
|
||||||
duplicateScope = None
|
duplicateScope = None
|
||||||
|
duplicateScopeDeckName = None
|
||||||
|
duplicateScopeCheckChildren = False
|
||||||
if 'options' in note:
|
if 'options' in note:
|
||||||
if 'allowDuplicate' in note['options']:
|
if 'allowDuplicate' in note['options']:
|
||||||
allowDuplicate = note['options']['allowDuplicate']
|
allowDuplicate = note['options']['allowDuplicate']
|
||||||
@ -214,8 +216,16 @@ class AnkiConnect:
|
|||||||
raise Exception('option parameter \'allowDuplicate\' must be boolean')
|
raise Exception('option parameter \'allowDuplicate\' must be boolean')
|
||||||
if 'duplicateScope' in note['options']:
|
if 'duplicateScope' in note['options']:
|
||||||
duplicateScope = note['options']['duplicateScope']
|
duplicateScope = note['options']['duplicateScope']
|
||||||
|
if 'duplicateScopeOptions' in note['options']:
|
||||||
|
duplicateScopeOptions = note['options']['duplicateScopeOptions']
|
||||||
|
if 'deckName' in duplicateScopeOptions:
|
||||||
|
duplicateScopeDeckName = duplicateScopeOptions['deckName']
|
||||||
|
if 'checkChildren' in duplicateScopeOptions:
|
||||||
|
duplicateScopeCheckChildren = duplicateScopeOptions['checkChildren']
|
||||||
|
if type(duplicateScopeCheckChildren) is not bool:
|
||||||
|
raise Exception('option parameter \'duplicateScopeOptions.checkChildren\' must be boolean')
|
||||||
|
|
||||||
duplicateOrEmpty = self.isNoteDuplicateOrEmptyInScope(ankiNote, deck, duplicateScope)
|
duplicateOrEmpty = self.isNoteDuplicateOrEmptyInScope(ankiNote, deck, collection, duplicateScope, duplicateScopeDeckName, duplicateScopeCheckChildren)
|
||||||
if duplicateOrEmpty == 1:
|
if duplicateOrEmpty == 1:
|
||||||
raise Exception('cannot create note because it is empty')
|
raise Exception('cannot create note because it is empty')
|
||||||
elif duplicateOrEmpty == 2:
|
elif duplicateOrEmpty == 2:
|
||||||
@ -228,7 +238,7 @@ class AnkiConnect:
|
|||||||
else:
|
else:
|
||||||
raise Exception('cannot create note for unknown reason')
|
raise Exception('cannot create note for unknown reason')
|
||||||
|
|
||||||
def isNoteDuplicateOrEmptyInScope(self, note, deck, duplicateScope):
|
def isNoteDuplicateOrEmptyInScope(self, note, deck, collection, duplicateScope, duplicateScopeDeckName, duplicateScopeCheckChildren):
|
||||||
"1 if first is empty; 2 if first is a duplicate, False otherwise."
|
"1 if first is empty; 2 if first is a duplicate, False otherwise."
|
||||||
result = note.dupeOrEmpty()
|
result = note.dupeOrEmpty()
|
||||||
if result != 2 or duplicateScope != 'deck':
|
if result != 2 or duplicateScope != 'deck':
|
||||||
@ -240,18 +250,32 @@ class AnkiConnect:
|
|||||||
did = deck['id']
|
did = deck['id']
|
||||||
csum = anki.utils.fieldChecksum(val)
|
csum = anki.utils.fieldChecksum(val)
|
||||||
|
|
||||||
|
if duplicateScopeDeckName is not None:
|
||||||
|
deck2 = collection.decks.byName(duplicateScopeDeckName)
|
||||||
|
if deck2 is None:
|
||||||
|
# Invalid deck, so cannot be duplicate
|
||||||
|
return False
|
||||||
|
did = deck2['id']
|
||||||
|
|
||||||
|
dids = {}
|
||||||
|
if duplicateScopeCheckChildren:
|
||||||
|
for kv in collection.decks.children(did):
|
||||||
|
dids[kv[1]] = True
|
||||||
|
else:
|
||||||
|
dids[did] = True
|
||||||
|
|
||||||
for noteId in note.col.db.list(
|
for noteId in note.col.db.list(
|
||||||
"select id from notes where csum = ? and id != ? and mid = ?",
|
"select id from notes where csum = ? and id != ? and mid = ?",
|
||||||
csum,
|
csum,
|
||||||
note.id or 0,
|
note.id or 0,
|
||||||
note.mid,
|
note.mid,
|
||||||
):
|
):
|
||||||
if note.col.db.scalar(
|
for cardDeckId in note.col.db.list(
|
||||||
"select id from cards where nid = ? and did = ?",
|
"select did from cards where nid = ?",
|
||||||
noteId,
|
noteId
|
||||||
did
|
|
||||||
):
|
):
|
||||||
return 2
|
if cardDeckId in dids:
|
||||||
|
return 2
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user