From 7ef10e92daf1ff03ff9f56c334b78f1841c5875d Mon Sep 17 00:00:00 2001 From: David Sauerwein Date: Sat, 20 Feb 2021 19:04:25 +0100 Subject: [PATCH] Allow to add media to notes by file path or base64 encoded data (#230) * Allow to add media to notes by file path or base64 encoded data * Adjust Media Actions documentation * Adjust Note Actions documentation --- actions/media.md | 6 +++--- actions/notes.md | 9 +++++---- plugin/__init__.py | 38 ++++++++++++++++++++++---------------- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/actions/media.md b/actions/media.md index e254c61..6262126 100644 --- a/actions/media.md +++ b/actions/media.md @@ -20,7 +20,7 @@ *Sample result*: ```json { - "result": null, + "result": "_hello.txt", "error": null } ``` @@ -45,7 +45,7 @@ *Sample result*: ```json { - "result": null, + "result": "_hello.txt", "error": null } ``` @@ -65,7 +65,7 @@ *Sample result*: ```json { - "result": null, + "result": "_hello.txt", "error": null } ``` diff --git a/actions/notes.md b/actions/notes.md index 593b5b7..bd6d724 100644 --- a/actions/notes.md +++ b/actions/notes.md @@ -7,9 +7,10 @@ AnkiConnect can download audio, video, and picture files and embed them in newly created notes. The corresponding `audio`, `video`, and `picture` note members are optional and can be omitted. If you choose to include any of them, they 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 or video, or show a picture when the card is displayed in + with the mandatory `filename` field and one of `data`, `path` or `url`. Refer to the documentation of `storeMediaFile` for an explanation of these fields. + The `skipHash` field can be optionally provided to skip the inclusion of 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 or video, or show a picture 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. @@ -453,4 +454,4 @@ "error": null } ``` - \ No newline at end of file + diff --git a/plugin/__init__.py b/plugin/__init__.py index 4eef76b..8c8d7cd 100644 --- a/plugin/__init__.py +++ b/plugin/__init__.py @@ -484,22 +484,32 @@ class AnkiConnect: @util.api() - def storeMediaFile(self, filename, data=None, path=None, url=None): + def storeMediaFile(self, filename, data=None, path=None, url=None, skipHash=None): if data: self.deleteMediaFile(filename) - self.media().writeData(filename, base64.b64decode(data)) + mediaData = base64.b64decode(data) elif path: self.deleteMediaFile(filename) with open(path, 'rb') as f: - data = f.read() - self.media().writeData(filename, data) + mediaData = f.read() elif url: self.deleteMediaFile(filename) - downloadedData = util.download(url) - self.media().writeData(filename, downloadedData) + mediaData = util.download(url) else: raise Exception('You must either provide a "data" or a "url" field.') + if skipHash is None: + skip = False + else: + m = hashlib.md5() + m.update(data) + skip = skipHash == m.hexdigest() + + if skip: + return None + return self.media().writeData(filename, mediaData) + + @util.api() def retrieveMediaFile(self, filename): filename = os.path.basename(filename) @@ -558,17 +568,13 @@ class AnkiConnect: for media in mediaList: if media is not None and len(media['fields']) > 0: try: - data = util.download(media['url']) - skipHash = media.get('skipHash') - if skipHash is None: - skip = False - else: - m = hashlib.md5() - m.update(data) - skip = skipHash == m.hexdigest() + mediaFilename = self.storeMediaFile(media['filename'], + data=media.get('data'), + path=media.get('path'), + url=media.get('url'), + skipHash=media.get('skipHash')) - if not skip: - mediaFilename = self.media().writeData(media['filename'], data) + if mediaFilename is not None: for field in media['fields']: if field in ankiNote: if mediaType is util.MediaType.Picture: