Merge pull request #138 from andreaskienle/multiple-audio-files

Accept multiple audio files in note creation and update
This commit is contained in:
Alex Yatskov 2020-03-01 16:52:24 -08:00 committed by GitHub
commit 7b6e80cd34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 35 deletions

View File

@ -926,12 +926,12 @@ guarantee that your application continues to function properly in the future.
the created note created on success, and `null` on failure. the created note created on success, and `null` on failure.
AnkiConnect can download audio files and embed them in newly created notes. The corresponding `audio` note member is AnkiConnect can download audio files and embed them in newly created notes. The corresponding `audio` note member is
optional and can be omitted. If you choose to include it, the `url` and `filename` fields must be also defined. The optional and can be omitted. If you choose to include it, it should contain a single object or an array of objects
`skipHash` field can be optionally provided to skip the inclusion of downloaded files with an MD5 hash that matches with mandatory `url` and `filename` fields. The `skipHash` field can be optionally provided to skip the inclusion of
the provided value. This is useful for avoiding the saving of error pages and stub files. The `fields` member is a downloaded files with an MD5 hash that matches the provided value. This is useful for avoiding the saving of error
list of fields that should play audio when the card is displayed in Anki. The `allowDuplicate` member inside pages and stub files. The `fields` member is a list of fields that should play audio when the card is displayed in
`options` group can be set to true to enable adding duplicate cards. Normally duplicate cards can not be added and Anki. The `allowDuplicate` member inside `options` group can be set to true to enable adding duplicate cards.
trigger exception. Normally duplicate cards can not be added and trigger exception.
*Sample request*: *Sample request*:
```json ```json
@ -952,14 +952,14 @@ guarantee that your application continues to function properly in the future.
"tags": [ "tags": [
"yomichan" "yomichan"
], ],
"audio": { "audio": [{
"url": "https://assets.languagepod101.com/dictionary/japanese/audiomp3.php?kanji=猫&kana=ねこ", "url": "https://assets.languagepod101.com/dictionary/japanese/audiomp3.php?kanji=猫&kana=ねこ",
"filename": "yomichan_ねこ_猫.mp3", "filename": "yomichan_ねこ_猫.mp3",
"skipHash": "7e2c2f954ef6051373ba916f000168dc", "skipHash": "7e2c2f954ef6051373ba916f000168dc",
"fields": [ "fields": [
"Front" "Front"
] ]
} }]
} }
} }
} }
@ -996,14 +996,14 @@ guarantee that your application continues to function properly in the future.
"tags": [ "tags": [
"yomichan" "yomichan"
], ],
"audio": { "audio": [{
"url": "https://assets.languagepod101.com/dictionary/japanese/audiomp3.php?kanji=猫&kana=ねこ", "url": "https://assets.languagepod101.com/dictionary/japanese/audiomp3.php?kanji=猫&kana=ねこ",
"filename": "yomichan_ねこ_猫.mp3", "filename": "yomichan_ねこ_猫.mp3",
"skipHash": "7e2c2f954ef6051373ba916f000168dc", "skipHash": "7e2c2f954ef6051373ba916f000168dc",
"fields": [ "fields": [
"Front" "Front"
] ]
} }]
} }
] ]
} }
@ -1056,7 +1056,8 @@ guarantee that your application continues to function properly in the future.
* **updateNoteFields** * **updateNoteFields**
Modify the fields of an exist note. Modify the fields of an exist note. You can also include audio files which will be added to the note with an
optional `audio` property. Please see the documentation for `addNote` for an explanation of objects in the `audio` array.
*Sample request*: *Sample request*:
```json ```json
@ -1069,7 +1070,15 @@ guarantee that your application continues to function properly in the future.
"fields": { "fields": {
"Front": "new front content", "Front": "new front content",
"Back": "new back content" "Back": "new back content"
} },
"audio": [{
"url": "https://assets.languagepod101.com/dictionary/japanese/audiomp3.php?kanji=猫&kana=ねこ",
"filename": "yomichan_ねこ_猫.mp3",
"skipHash": "7e2c2f954ef6051373ba916f000168dc",
"fields": [
"Front"
]
}]
} }
} }
} }

View File

@ -449,29 +449,8 @@ class AnkiConnect:
def addNote(self, note): def addNote(self, note):
ankiNote = self.createNote(note) ankiNote = self.createNote(note)
audio = note.get('audio') audioObjectOrList = note.get('audio')
if audio is not None and len(audio['fields']) > 0: self.addAudio(ankiNote, audioObjectOrList)
try:
data = util.download(audio['url'])
skipHash = audio.get('skipHash')
if skipHash is None:
skip = False
else:
m = hashlib.md5()
m.update(data)
skip = skipHash == m.hexdigest()
if not skip:
audioFilename = self.media().writeData(audio['filename'], data)
for field in audio['fields']:
if field in ankiNote:
ankiNote[field] += u'[sound:{}]'.format(audioFilename)
except Exception as e:
errorMessage = str(e).replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
for field in audio['fields']:
if field in ankiNote:
ankiNote[field] += errorMessage
collection = self.collection() collection = self.collection()
self.startEditing() self.startEditing()
@ -484,6 +463,34 @@ class AnkiConnect:
return ankiNote.id return ankiNote.id
def addAudio(self, ankiNote, audioObjectOrList):
if audioObjectOrList is not None:
audioList = audioObjectOrList if isinstance(audioObjectOrList, list) else [audioObjectOrList]
for audio in audioList:
if audio is not None and len(audio['fields']) > 0:
try:
data = util.download(audio['url'])
skipHash = audio.get('skipHash')
if skipHash is None:
skip = False
else:
m = hashlib.md5()
m.update(data)
skip = skipHash == m.hexdigest()
if not skip:
audioFilename = self.media().writeData(audio['filename'], data)
for field in audio['fields']:
if field in ankiNote:
ankiNote[field] += u'[sound:{}]'.format(audioFilename)
except Exception as e:
errorMessage = str(e).replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;')
for field in audio['fields']:
if field in ankiNote:
ankiNote[field] += errorMessage
@util.api() @util.api()
def canAddNote(self, note): def canAddNote(self, note):
try: try:
@ -502,6 +509,9 @@ class AnkiConnect:
if name in ankiNote: if name in ankiNote:
ankiNote[name] = value ankiNote[name] = value
audioObjectOrList = note['audio']
self.addAudio(ankiNote, audioObjectOrList)
ankiNote.flush() ankiNote.flush()