Update with requested changes

This commit is contained in:
David Bailey 2017-08-22 20:05:12 +01:00
parent f12af86757
commit 04cf33a1d0
2 changed files with 35 additions and 53 deletions

View File

@ -27,6 +27,7 @@ import select
import socket
import sys
from time import time
from unicodedata import normalize
#
@ -336,43 +337,27 @@ class AnkiNoteParams:
#
class AnkiBridge:
def getFilePath(self, filename):
mediaFolder = self.collection().media.dir()
filePath = os.path.normpath(os.path.join(mediaFolder, filename))
# catch attempts to write outside the media folder
if os.path.commonprefix([mediaFolder, filePath]) != mediaFolder:
return False
return filePath
def storeMediaFile(self, filename, data):
self.deleteMediaFile(filename)
self.media().writeData(filename, base64.b64decode(data))
def storeFile(self, filename, data):
filePath = self.getFilePath(filename)
if filePath:
with open(filePath, 'wb') as file:
file.write(base64.b64decode(data))
return True
def retrieveMediaFile(self, filename):
# based on writeData from anki/media.py
filename = os.path.basename(filename)
filename = normalize("NFC", filename)
filename = self.media().stripIllegal(filename)
path = os.path.join(self.media().dir(), filename)
if os.path.exists(path):
with open(path, 'rb') as file:
return base64.b64encode(file.read()).decode('ascii')
return False
def retrieveFile(self, filename):
filePath = self.getFilePath(filename)
if filePath and os.path.isfile(filePath):
with open(filePath, 'rb') as file:
data = base64.b64encode(file.read())
return data.decode('ascii')
return False
def deleteFile(self, filename):
filePath = self.getFilePath(filename)
if filePath and os.path.isfile(filePath):
os.remove(filePath)
return True
return False
def deleteMediaFile(self, filename):
self.media().syncDelete(filename)
def addNote(self, params):
@ -922,18 +907,18 @@ class AnkiConnect:
@webApi
def storeFile(self, filename, data):
return self.anki.storeFile(filename, data)
def storeMediaFile(self, filename, data):
return self.anki.storeMediaFile(filename, data)
@webApi
def retrieveFile(self, filename):
return self.anki.retrieveFile(filename)
def retrieveMediaFile(self, filename):
return self.anki.retrieveMediaFile(filename)
@webApi
def deleteFile(self, filename):
return self.anki.deleteFile(filename)
def deleteMediaFile(self, filename):
return self.anki.deleteMediaFile(filename)
@webApi

View File

@ -95,7 +95,7 @@ Categories:
* [Card Suspension](#card-suspension)
* [Card Intervals](#card-intervals)
* [Finding Notes and Cards](#finding-notes-and-cards)
* [File Storage](#file-storage)
* [Media File Storage](#media-file-storage)
* [Graphical](#graphical)
### Miscellaneous ###
@ -853,12 +853,11 @@ Categories:
]
```
### File Storage ###
### Media File Storage ###
* **storeFile**
* **storeMediaFile**
Stores a file with the specified base64-encoded contents inside the media folder. Returns `true` upon success or
`false` if attempting to write a file outside the media folder.
Stores a file with the specified base64-encoded contents inside the media folder.
Note: to prevent Anki from removing files not used by any cards (e.g. for configuration files), prefix the filename
with an underscore. These files are still synchronized to AnkiWeb.
@ -866,7 +865,7 @@ Categories:
*Sample request*:
```
{
"action": "storeFile",
"action": "storeMediaFile",
"params": {
"filename": "_hello.txt",
"data": "SGVsbG8sIHdvcmxkIQ=="
@ -876,7 +875,7 @@ Categories:
*Sample response*:
```
true
null
```
*Content of `_hello.txt`*:
@ -884,15 +883,14 @@ Categories:
Hello world!
```
* **retrieveFile**
* **retrieveMediaFile**
Retrieves the base64-encoded contents of the specified file, returning `false` if the file does not exist or if
attempting to read a file outside the media folder.
Retrieves the base64-encoded contents of the specified file, returning `false` if the file does not exist.
*Sample request*:
```
{
"action": "retrieveFile",
"action": "retrieveMediaFile",
"params": {
"filename": "_hello.txt"
}
@ -904,15 +902,14 @@ Categories:
"SGVsbG8sIHdvcmxkIQ=="
```
* **deleteFile**
* **deleteMediaFile**
Deletes the specified file inside the media folder, returning `true` if successful, or `false` if the file does not
exist or if attempting to delete a file outside the media folder.
Deletes the specified file inside the media folder.
*Sample request*:
```
{
"action": "deleteFile",
"action": "deleteMediaFile",
"params": {
"filename": "_hello.txt"
}
@ -921,7 +918,7 @@ Categories:
*Sample response*:
```
true
null
```
### Graphical ###