mirror of
https://github.com/koreader/koreader.git
synced 2025-12-13 20:36:53 +01:00
Dropbox: upload file, create folder (#8610)
This commit is contained in:
@@ -1,14 +1,17 @@
|
||||
local BD = require("ui/bidi")
|
||||
local ButtonDialog = require("ui/widget/buttondialog")
|
||||
local ButtonDialogTitle = require("ui/widget/buttondialogtitle")
|
||||
local CheckButton = require("ui/widget/checkbutton")
|
||||
local ConfirmBox = require("ui/widget/confirmbox")
|
||||
local DataStorage = require("datastorage")
|
||||
local DropBox = require("apps/cloudstorage/dropbox")
|
||||
local FFIUtil = require("ffi/util")
|
||||
local Ftp = require("apps/cloudstorage/ftp")
|
||||
local InfoMessage = require("ui/widget/infomessage")
|
||||
local InputDialog = require("ui/widget/inputdialog")
|
||||
local LuaSettings = require("luasettings")
|
||||
local Menu = require("ui/widget/menu")
|
||||
local PathChooser = require("ui/widget/pathchooser")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local WebDav = require("apps/cloudstorage/webdav")
|
||||
local lfs = require("libs/libkoreader-lfs")
|
||||
@@ -155,14 +158,20 @@ function CloudStorage:openCloudServer(url)
|
||||
end
|
||||
tbl, e = WebDav:run(self.address, self.username, self.password, url)
|
||||
end
|
||||
if tbl and #tbl > 0 then
|
||||
if tbl then
|
||||
self:switchItemTable(url, tbl)
|
||||
self:setTitleBarIconAndText("home")
|
||||
self.onExtraButtonTap = function()
|
||||
self:init()
|
||||
if self.type == "dropbox" then
|
||||
self.onExtraButtonTap = function()
|
||||
self:showPlusMenu(url)
|
||||
end
|
||||
else
|
||||
self:setTitleBarIconAndText("home")
|
||||
self.onExtraButtonTap = function()
|
||||
self:init()
|
||||
end
|
||||
end
|
||||
return true
|
||||
elseif not tbl then
|
||||
else
|
||||
logger.err("CloudStorage:", e)
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = _("Cannot fetch list of folder contents\nPlease check your configuration or network connection."),
|
||||
@@ -170,9 +179,6 @@ function CloudStorage:openCloudServer(url)
|
||||
})
|
||||
table.remove(self.paths)
|
||||
return false
|
||||
else
|
||||
UIManager:show(InfoMessage:new{ text = _("Empty folder") })
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
@@ -371,7 +377,6 @@ function CloudStorage:onMenuHold(item)
|
||||
{
|
||||
{
|
||||
text = _("Info"),
|
||||
enabled = true,
|
||||
callback = function()
|
||||
UIManager:close(cs_server_dialog)
|
||||
self:infoServer(item)
|
||||
@@ -379,7 +384,6 @@ function CloudStorage:onMenuHold(item)
|
||||
},
|
||||
{
|
||||
text = _("Edit"),
|
||||
enabled = true,
|
||||
callback = function()
|
||||
UIManager:close(cs_server_dialog)
|
||||
self:editCloudServer(item)
|
||||
@@ -388,7 +392,6 @@ function CloudStorage:onMenuHold(item)
|
||||
},
|
||||
{
|
||||
text = _("Delete"),
|
||||
enabled = true,
|
||||
callback = function()
|
||||
UIManager:close(cs_server_dialog)
|
||||
self:deleteCloudServer(item)
|
||||
@@ -408,7 +411,6 @@ function CloudStorage:onMenuHold(item)
|
||||
},
|
||||
{
|
||||
text = _("Synchronize settings"),
|
||||
enabled = true,
|
||||
callback = function()
|
||||
UIManager:close(cs_server_dialog)
|
||||
self:synchronizeSettings(item)
|
||||
@@ -565,6 +567,119 @@ function CloudStorage:synchronizeSettings(item)
|
||||
UIManager:show(syn_dialog)
|
||||
end
|
||||
|
||||
function CloudStorage:showPlusMenu(url)
|
||||
local button_dialog
|
||||
button_dialog = ButtonDialog:new{
|
||||
buttons = {
|
||||
{
|
||||
{
|
||||
text = _("Upload file"),
|
||||
callback = function()
|
||||
UIManager:close(button_dialog)
|
||||
self:uploadFile(url)
|
||||
end,
|
||||
},
|
||||
},
|
||||
{
|
||||
{
|
||||
text = _("New folder"),
|
||||
callback = function()
|
||||
UIManager:close(button_dialog)
|
||||
self:createFolder(url)
|
||||
end,
|
||||
},
|
||||
},
|
||||
{},
|
||||
{
|
||||
{
|
||||
text = _("Return to cloud storage list"),
|
||||
callback = function()
|
||||
UIManager:close(button_dialog)
|
||||
self:init()
|
||||
end,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
UIManager:show(button_dialog)
|
||||
end
|
||||
|
||||
function CloudStorage:uploadFile(url)
|
||||
local path_chooser
|
||||
path_chooser = PathChooser:new{
|
||||
select_directory = false,
|
||||
detailed_file_info = true,
|
||||
path = self.last_path,
|
||||
onConfirm = function(file_path)
|
||||
self.last_path = file_path:match("(.*)/")
|
||||
if self.last_path == "" then self.last_path = "/" end
|
||||
if lfs.attributes(file_path, "size") > 157286400 then
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = _("File size must be less than 150 MB."),
|
||||
})
|
||||
else
|
||||
local callback_close = function()
|
||||
self:openCloudServer(url)
|
||||
end
|
||||
UIManager:nextTick(function()
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = _("Uploading…"),
|
||||
timeout = 1,
|
||||
})
|
||||
end)
|
||||
UIManager:tickAfterNext(function()
|
||||
DropBox:uploadFile(url, self.password, file_path, callback_close)
|
||||
end)
|
||||
end
|
||||
end
|
||||
}
|
||||
UIManager:show(path_chooser)
|
||||
end
|
||||
|
||||
function CloudStorage:createFolder(url)
|
||||
local input_dialog, check_button_enter_folder
|
||||
input_dialog = InputDialog:new{
|
||||
title = _("New folder"),
|
||||
buttons = {
|
||||
{
|
||||
{
|
||||
text = _("Cancel"),
|
||||
callback = function()
|
||||
UIManager:close(input_dialog)
|
||||
end,
|
||||
},
|
||||
{
|
||||
text = _("Create"),
|
||||
is_enter_default = true,
|
||||
callback = function()
|
||||
local folder_name = input_dialog:getInputText()
|
||||
if folder_name == "" then return end
|
||||
UIManager:close(input_dialog)
|
||||
local callback_close = function()
|
||||
if check_button_enter_folder.checked then
|
||||
table.insert(self.paths, {
|
||||
url = url,
|
||||
})
|
||||
url = url .. "/" .. folder_name
|
||||
end
|
||||
self:openCloudServer(url)
|
||||
end
|
||||
DropBox:createFolder(url, self.password, folder_name, callback_close)
|
||||
end,
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
check_button_enter_folder = CheckButton:new{
|
||||
text = _("Enter folder after creation"),
|
||||
checked = false,
|
||||
parent = input_dialog,
|
||||
}
|
||||
input_dialog:addWidget(check_button_enter_folder)
|
||||
UIManager:show(input_dialog)
|
||||
input_dialog:onShowKeyboard()
|
||||
end
|
||||
|
||||
function CloudStorage:configCloud(type)
|
||||
local callbackAdd = function(fields)
|
||||
local cs_settings = self:readSettings()
|
||||
|
||||
@@ -61,6 +61,36 @@ function DropBox:downloadFileNoUI(url, password, path)
|
||||
end
|
||||
end
|
||||
|
||||
function DropBox:uploadFile(url, password, file_path, callback_close)
|
||||
local code_response = DropBoxApi:uploadFile(url, password, file_path)
|
||||
local __, filename = util.splitFilePathName(file_path)
|
||||
if code_response == 200 then
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = T(_("File uploaded:\n%1"), filename),
|
||||
})
|
||||
if callback_close then
|
||||
callback_close()
|
||||
end
|
||||
else
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = T(_("Could not upload file:\n%1"), filename),
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
function DropBox:createFolder(url, password, folder_name, callback_close)
|
||||
local code_response = DropBoxApi:createFolder(url, password, folder_name)
|
||||
if code_response == 200 then
|
||||
if callback_close then
|
||||
callback_close()
|
||||
end
|
||||
else
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = T(_("Could not create folder:\n%1"), folder_name),
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
function DropBox:config(item, callback)
|
||||
local text_info = "How to generate Access Token:\n"..
|
||||
"1. Open the following URL in your Browser, and log in using your account: https://www.dropbox.com/developers/apps.\n"..
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
local DocumentRegistry = require("document/documentregistry")
|
||||
local JSON = require("json")
|
||||
local http = require("socket.http")
|
||||
local lfs = require("libs/libkoreader-lfs")
|
||||
local logger = require("logger")
|
||||
local ltn12 = require("ltn12")
|
||||
local socket = require("socket")
|
||||
local socketutil = require("socketutil")
|
||||
local util = require("util")
|
||||
local BaseUtil = require("ffi/util")
|
||||
local _ = require("gettext")
|
||||
|
||||
local DropBoxApi = {
|
||||
@@ -13,6 +16,8 @@ local DropBoxApi = {
|
||||
local API_URL_INFO = "https://api.dropboxapi.com/2/users/get_current_account"
|
||||
local API_LIST_FOLDER = "https://api.dropboxapi.com/2/files/list_folder"
|
||||
local API_DOWNLOAD_FILE = "https://content.dropboxapi.com/2/files/download"
|
||||
local API_UPLOAD_FILE = "https://content.dropboxapi.com/2/files/upload"
|
||||
local API_CREATE_FOLDER = "https://api.dropboxapi.com/2/files/create_folder_v2"
|
||||
local API_LIST_ADD_FOLDER = "https://api.dropboxapi.com/2/files/list_folder/continue"
|
||||
|
||||
function DropBoxApi:fetchInfo(token)
|
||||
@@ -100,6 +105,48 @@ function DropBoxApi:downloadFile(path, token, local_path)
|
||||
return code
|
||||
end
|
||||
|
||||
function DropBoxApi:uploadFile(path, token, file_path)
|
||||
local data = "{\"path\": \"" .. path .. "/" .. BaseUtil.basename(file_path) ..
|
||||
"\",\"mode\": \"add\",\"autorename\": 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,
|
||||
method = "POST",
|
||||
headers = {
|
||||
["Authorization"] = "Bearer ".. token,
|
||||
["Dropbox-API-Arg"] = data,
|
||||
["Content-Type"] = "application/octet-stream",
|
||||
["Content-Length"] = lfs.attributes(file_path, "size"),
|
||||
},
|
||||
source = ltn12.source.file(io.open(file_path, "r")),
|
||||
})
|
||||
socketutil:reset_timeout()
|
||||
if code ~= 200 then
|
||||
logger.warn("DropBoxApi: Upload failure:", status or code or "network unreachable")
|
||||
end
|
||||
return code
|
||||
end
|
||||
|
||||
function DropBoxApi:createFolder(path, token, folder_name)
|
||||
local data = "{\"path\": \"" .. path .. "/" .. folder_name .. "\",\"autorename\": false}"
|
||||
socketutil:set_timeout()
|
||||
local code, _, status = socket.skip(1, http.request{
|
||||
url = API_CREATE_FOLDER,
|
||||
method = "POST",
|
||||
headers = {
|
||||
["Authorization"] = "Bearer ".. token,
|
||||
["Content-Type"] = "application/json",
|
||||
["Content-Length"] = #data,
|
||||
},
|
||||
source = ltn12.source.string(data),
|
||||
})
|
||||
socketutil:reset_timeout()
|
||||
if code ~= 200 then
|
||||
logger.warn("DropBoxApi: Folder creation failure:", status or code or "network unreachable")
|
||||
end
|
||||
return code
|
||||
end
|
||||
|
||||
-- folder_mode - set to true when we want to see only folder.
|
||||
-- We see also extra folder "Long-press to select current directory" at the beginning.
|
||||
function DropBoxApi:listFolder(path, token, folder_mode)
|
||||
@@ -124,6 +171,7 @@ function DropBoxApi:listFolder(path, token, folder_mode)
|
||||
or G_reader_settings:isTrue("show_unsupported")) and not folder_mode then
|
||||
table.insert(dropbox_file, {
|
||||
text = text,
|
||||
mandatory = util.getFriendlySize(files.size),
|
||||
url = files.path_display,
|
||||
type = tag,
|
||||
})
|
||||
@@ -147,6 +195,7 @@ function DropBoxApi:listFolder(path, token, folder_mode)
|
||||
for _, files in ipairs(dropbox_file) do
|
||||
table.insert(dropbox_list, {
|
||||
text = files.text,
|
||||
mandatory = files.mandatory,
|
||||
url = files.url,
|
||||
type = files.type,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user