Cloud-based sync for 2 plugins: reading statistics and vocabulary builder (#9709)

This commit adds cross-device sync ability for two plugins: reading statistics and vocabulary builder. It relies on user setting up a Cloud server (DropBox and WebDAV but not FTP though) and designating a path. Behind the curtains sqlite databases are being passed around and updated.

UI-wise, for the statistics plugin, two new menu items Synchronize now and Cloud sync to set it up (might not be the best wording) are added. As for vocabulary builder, a similar Cloud sync button is added to the menu and a shortcut icon button to Synchronize now is pinned at the bottom corner.

CloudStorage new features: WebDAV creating folders and uploading files. And a new widget-like sync server chooser. In the end I decided not to add automatic sync, as the SQL commands part seem a bit much.
This commit is contained in:
weijiuqiao
2022-11-11 22:53:06 +08:00
committed by GitHub
parent 4f3000e882
commit 8500fdd519
8 changed files with 727 additions and 19 deletions

View File

@@ -117,7 +117,7 @@ end
function DropBoxApi:downloadFile(path, token, local_path)
local data1 = "{\"path\": \"" .. path .. "\"}"
socketutil:set_timeout(socketutil.FILE_BLOCK_TIMEOUT, socketutil.FILE_TOTAL_TIMEOUT)
local code, _, status = socket.skip(1, http.request{
local code, headers, status = socket.skip(1, http.request{
url = API_DOWNLOAD_FILE,
method = "GET",
headers = {
@@ -130,12 +130,12 @@ function DropBoxApi:downloadFile(path, token, local_path)
if code ~= 200 then
logger.warn("DropBoxApi: Download failure:", status or code or "network unreachable")
end
return code
return code, (headers or {}).etag
end
function DropBoxApi:uploadFile(path, token, file_path)
function DropBoxApi:uploadFile(path, token, file_path, etag, overwrite)
local data = "{\"path\": \"" .. path .. "/" .. BaseUtil.basename(file_path) ..
"\",\"mode\": \"add\",\"autorename\": true,\"mute\": false,\"strict_conflict\": false}"
"\",\"mode\":" .. (overwrite and "\"overwrite\"" or "\"add\"") .. ",\"autorename\": " .. (overwrite and "false" or "true") .. ",\"mute\": false,\"strict_conflict\": false}"
socketutil:set_timeout(socketutil.FILE_BLOCK_TIMEOUT, socketutil.FILE_TOTAL_TIMEOUT)
local code, _, status = socket.skip(1, http.request{
url = API_UPLOAD_FILE,
@@ -145,6 +145,7 @@ function DropBoxApi:uploadFile(path, token, file_path)
["Dropbox-API-Arg"] = data,
["Content-Type"] = "application/octet-stream",
["Content-Length"] = lfs.attributes(file_path, "size"),
["If-Match"] = etag,
},
source = ltn12.source.file(io.open(file_path, "r")),
})