From eafd3c94ddc6a17a25c7f434dc3d1156194ff9db Mon Sep 17 00:00:00 2001 From: Andreas Kienle Date: Sun, 23 Feb 2020 11:59:19 +0100 Subject: [PATCH 1/2] Accept multiple audio files in note creation and update --- plugin/__init__.py | 56 +++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/plugin/__init__.py b/plugin/__init__.py index c8a18ff..d158709 100644 --- a/plugin/__init__.py +++ b/plugin/__init__.py @@ -449,29 +449,8 @@ class AnkiConnect: def addNote(self, note): ankiNote = self.createNote(note) - audio = note.get('audio') - 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("&", "&").replace("<", "<").replace(">", ">") - for field in audio['fields']: - if field in ankiNote: - ankiNote[field] += errorMessage + audioObjectOrList = note.get('audio') + self.addAudio(ankiNote, audioObjectOrList) collection = self.collection() self.startEditing() @@ -484,6 +463,34 @@ class AnkiConnect: 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("&", "&").replace("<", "<").replace(">", ">") + for field in audio['fields']: + if field in ankiNote: + ankiNote[field] += errorMessage + + @util.api() def canAddNote(self, note): try: @@ -502,6 +509,9 @@ class AnkiConnect: if name in ankiNote: ankiNote[name] = value + audioObjectOrList = note['audio'] + self.addAudio(ankiNote, audioObjectOrList) + ankiNote.flush() From d40a905f20e0d1f0423a88c898b205dc7185744e Mon Sep 17 00:00:00 2001 From: Andreas Kienle Date: Tue, 25 Feb 2020 11:22:34 +0100 Subject: [PATCH 2/2] changes from review single quotes updated readme --- README.md | 33 +++++++++++++++++++++------------ plugin/__init__.py | 2 +- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 0fb5bd8..47a0d87 100644 --- a/README.md +++ b/README.md @@ -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. 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 - `skipHash` field can be optionally provided to skip the inclusion of 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 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. + optional and can be omitted. If you choose to include it, it should contain a single object or an array of objects + with mandatory `url` and `filename` fields. The `skipHash` field can be optionally provided to skip the inclusion of + 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 + 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. *Sample request*: ```json @@ -952,14 +952,14 @@ guarantee that your application continues to function properly in the future. "tags": [ "yomichan" ], - "audio": { + "audio": [{ "url": "https://assets.languagepod101.com/dictionary/japanese/audiomp3.php?kanji=猫&kana=ねこ", "filename": "yomichan_ねこ_猫.mp3", "skipHash": "7e2c2f954ef6051373ba916f000168dc", "fields": [ "Front" ] - } + }] } } } @@ -996,14 +996,14 @@ guarantee that your application continues to function properly in the future. "tags": [ "yomichan" ], - "audio": { + "audio": [{ "url": "https://assets.languagepod101.com/dictionary/japanese/audiomp3.php?kanji=猫&kana=ねこ", "filename": "yomichan_ねこ_猫.mp3", "skipHash": "7e2c2f954ef6051373ba916f000168dc", "fields": [ "Front" ] - } + }] } ] } @@ -1056,7 +1056,8 @@ guarantee that your application continues to function properly in the future. * **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*: ```json @@ -1069,7 +1070,15 @@ guarantee that your application continues to function properly in the future. "fields": { "Front": "new front content", "Back": "new back content" - } + }, + "audio": [{ + "url": "https://assets.languagepod101.com/dictionary/japanese/audiomp3.php?kanji=猫&kana=ねこ", + "filename": "yomichan_ねこ_猫.mp3", + "skipHash": "7e2c2f954ef6051373ba916f000168dc", + "fields": [ + "Front" + ] + }] } } } diff --git a/plugin/__init__.py b/plugin/__init__.py index d158709..3b75fa2 100644 --- a/plugin/__init__.py +++ b/plugin/__init__.py @@ -485,7 +485,7 @@ class AnkiConnect: ankiNote[field] += u'[sound:{}]'.format(audioFilename) except Exception as e: - errorMessage = str(e).replace("&", "&").replace("<", "<").replace(">", ">") + errorMessage = str(e).replace('&', '&').replace('<', '<').replace('>', '>') for field in audio['fields']: if field in ankiNote: ankiNote[field] += errorMessage