@ -10,6 +10,7 @@ local Menu = require("ui/widget/menu")
local UIManager = require ( " ui/uimanager " )
local WebDav = require ( " apps/cloudstorage/webdav " )
local lfs = require ( " libs/libkoreader-lfs " )
local T = require ( " ffi/util " ) . template
local _ = require ( " gettext " )
local Screen = require ( " device " ) . screen
@ -26,17 +27,24 @@ local CloudStorage = Menu:extend{
show_parent = nil ,
is_popout = false ,
is_borderless = true ,
title = _ ( " Cloud storage " )
}
function CloudStorage : init ( )
self.cs_settings = self : readSettings ( )
self.menu_select = nil
self.title = _ ( " Cloud storage " )
self.show_parent = self
if self.item then
self.item_table = self : genItemTable ( self.item )
self.choose_folder_mode = true
else
self.item_table = self : genItemTableFromRoot ( )
end
self.width = Screen : getWidth ( )
self.height = Screen : getHeight ( )
Menu.init ( self )
if self.item then
self.item_table [ 1 ] . callback ( )
end
end
function CloudStorage : genItemTableFromRoot ( )
@ -57,6 +65,32 @@ function CloudStorage:genItemTableFromRoot()
type = server.type ,
editable = true ,
url = server.url ,
sync_source_folder = server.sync_source_folder ,
sync_dest_folder = server.sync_dest_folder ,
callback = function ( )
self.type = server.type
self.password = server.password
self.address = server.address
self.username = server.username
self : openCloudServer ( server.url )
end ,
} )
end
return item_table
end
function CloudStorage : genItemTable ( item )
local item_table = { }
local added_servers = self.cs_settings : readSetting ( " cs_servers " ) or { }
for _ , server in ipairs ( added_servers ) do
if server.name == item.text and server.password == item.password and server.type == item.type then
table.insert ( item_table , {
text = server.name ,
address = server.address ,
username = server.username ,
password = server.password ,
type = server.type ,
url = server.url ,
callback = function ( )
self.type = server.type
self.password = server.password
@ -66,6 +100,7 @@ function CloudStorage:genItemTableFromRoot()
end ,
} )
end
end
return item_table
end
@ -117,7 +152,7 @@ function CloudStorage:openCloudServer(url)
NetworkMgr : promptWifiOn ( )
return
end
tbl = DropBox : run ( url , self.password )
tbl = DropBox : run ( url , self.password , self.choose_folder_mode )
elseif self.type == " ftp " then
if not NetworkMgr : isConnected ( ) then
NetworkMgr : promptWifiOn ( )
@ -157,6 +192,8 @@ function CloudStorage:onMenuSelect(item)
item.callback ( )
elseif item.type == " file " then
self : downloadFile ( item )
elseif item.type == " other " then
return true
else
table.insert ( self.paths , {
url = item.url ,
@ -255,11 +292,57 @@ function CloudStorage:cloudFile(item, path)
UIManager : show ( self.download_dialog )
end
function CloudStorage : updateSyncFolder ( item , source , dest )
local cs_settings = self : readSettings ( )
local cs_servers = cs_settings : readSetting ( " cs_servers " ) or { }
for _ , server in ipairs ( cs_servers ) do
if server.name == item.text and server.password == item.password and server.type == item.type then
if source then
server.sync_source_folder = source
end
if dest then
server.sync_dest_folder = dest
end
break
end
end
cs_settings : saveSetting ( " cs_servers " , cs_servers )
cs_settings : flush ( )
end
function CloudStorage : onMenuHold ( item )
if item.type == " folder_long_press " then
local title = T ( _ ( " Select this directory? \n \n %1 " ) , item.url )
local onConfirm = self.onConfirm
local button_dialog
button_dialog = ButtonDialogTitle : new {
title = title ,
buttons = {
{
{
text = _ ( " Cancel " ) ,
callback = function ( )
UIManager : close ( button_dialog )
end ,
} ,
{
text = _ ( " Select " ) ,
callback = function ( )
if onConfirm then
onConfirm ( item.url )
end
UIManager : close ( button_dialog )
UIManager : close ( self )
end ,
} ,
} ,
} ,
}
UIManager : show ( button_dialog )
end
if item.editable then
local cs_server_dialog
cs_server_dialog = ButtonDialog : new {
buttons = {
local buttons = {
{
{
text = _ ( " Info " ) ,
@ -288,12 +371,175 @@ function CloudStorage:onMenuHold(item)
} ,
} ,
}
if item.type == " dropbox " then
table.insert ( buttons , {
{
text = _ ( " Synchronize now " ) ,
enabled = item.sync_source_folder ~= nil and item.sync_dest_folder ~= nil ,
callback = function ( )
UIManager : close ( cs_server_dialog )
self : synchronizeCloud ( item )
end
} ,
{
text = _ ( " Synchronize settings " ) ,
enabled = true ,
callback = function ( )
UIManager : close ( cs_server_dialog )
self : synchronizeSettings ( item )
end
} ,
} )
end
cs_server_dialog = ButtonDialog : new {
buttons = buttons
}
UIManager : show ( cs_server_dialog )
return true
end
end
function CloudStorage : synchronizeCloud ( item )
local Trapper = require ( " ui/trapper " )
Trapper : wrap ( function ( )
Trapper : setPausedText ( " Download paused. \n Do you want to continue or abort downloading files? " )
local ok , downloaded_files , failed_files = pcall ( self.downloadListFiles , self , item )
if ok and downloaded_files then
if not failed_files then failed_files = 0 end
local text
if downloaded_files == 0 and failed_files == 0 then
text = _ ( " No files to download from dropbox. " )
elseif downloaded_files > 0 and failed_files == 0 then
text = T ( _ ( " Successfuly downloaded %1 files from Dropbox to local storage. " ) , downloaded_files )
else
text = T ( _ ( " Successfuly downloaded %1 files from Dropbox to local storage. \n Failed downloaded %2 files. " ) ,
downloaded_files , failed_files )
end
UIManager : show ( InfoMessage : new {
text = text ,
timeout = 3 ,
} )
else
Trapper : reset ( ) -- close any last widget not cleaned if error
UIManager : show ( InfoMessage : new {
text = _ ( " No files to download from Dropbox. \n Please check your configuration and connection. " ) ,
timeout = 3 ,
} )
end
end )
end
function CloudStorage : downloadListFiles ( item )
local local_files = { }
local path = item.sync_dest_folder
local UI = require ( " ui/trapper " )
UI : info ( _ ( " Retrieving files… " ) )
local ok , iter , dir_obj = pcall ( lfs.dir , path )
if ok then
for f in iter , dir_obj do
local filename = path .. " / " .. f
local attributes = lfs.attributes ( filename )
if attributes.mode == " file " then
local_files [ f ] = attributes.size
end
end
end
local remote_files = DropBox : showFiles ( item.sync_source_folder , item.password )
if # remote_files == 0 then
UI : clear ( )
return false
end
local files_to_download = 0
for i , file in ipairs ( remote_files ) do
if not local_files [ file.text ] or local_files [ file.text ] ~= file.size then
files_to_download = files_to_download + 1
remote_files [ i ] . download = true
end
end
if files_to_download == 0 then
UI : clear ( )
return 0
end
local response , go_on
local proccessed_files = 0
local success_files = 0
local unsuccess_files = 0
for _ , file in ipairs ( remote_files ) do
if file.download then
proccessed_files = proccessed_files + 1
print ( file.url )
local text = string.format ( " Downloading file (%d/%d): \n %s " , proccessed_files , files_to_download , file.text )
go_on = UI : info ( text )
if not go_on then
break
end
response = DropBox : downloadFileNoUI ( file.url , item.password , item.sync_dest_folder .. " / " .. file.text )
if response then
success_files = success_files + 1
else
unsuccess_files = unsuccess_files + 1
end
end
end
UI : clear ( )
return success_files , unsuccess_files
end
function CloudStorage : synchronizeSettings ( item )
local syn_dialog
local dropbox_sync_folder = item.sync_source_folder or " not set "
local local_sync_folder = item.sync_dest_folder or " not set "
syn_dialog = ButtonDialogTitle : new {
title = T ( _ ( " Dropbox folder: \n %1 \n Local folder: \n %2 " ) , dropbox_sync_folder , local_sync_folder ) ,
title_align = " center " ,
buttons = {
{
{
text = _ ( " Choose dropbox folder " ) ,
callback = function ( )
UIManager : close ( syn_dialog )
require ( " ui/cloudmgr " ) : new {
item = item ,
onConfirm = function ( path )
self : updateSyncFolder ( item , path )
item.sync_source_folder = path
self : synchronizeSettings ( item )
end ,
} : chooseDir ( )
end ,
} ,
} ,
{
{
text = _ ( " Choose local folder " ) ,
callback = function ( )
UIManager : close ( syn_dialog )
require ( " ui/downloadmgr " ) : new {
onConfirm = function ( path )
self : updateSyncFolder ( item , nil , path )
item.sync_dest_folder = path
self : synchronizeSettings ( item )
end ,
} : chooseDir ( )
end ,
} ,
} ,
{
{
text = _ ( " Close " ) ,
callback = function ( )
UIManager : close ( syn_dialog )
end ,
} ,
} ,
}
}
UIManager : show ( syn_dialog )
end
function CloudStorage : configCloud ( type )
local callbackAdd = function ( fields )
local cs_settings = self : readSettings ( )