2020-01-04 00:18:51 +00:00
local BD = require ( " ui/bidi " )
2016-12-20 07:34:00 +00:00
local ButtonDialog = require ( " ui/widget/buttondialog " )
2017-04-06 13:11:21 +00:00
local ButtonDialogTitle = require ( " ui/widget/buttondialogtitle " )
2022-01-04 11:29:08 +00:00
local CheckButton = require ( " ui/widget/checkbutton " )
2017-04-06 13:11:21 +00:00
local ConfirmBox = require ( " ui/widget/confirmbox " )
2016-12-20 07:34:00 +00:00
local DataStorage = require ( " datastorage " )
2017-04-14 18:12:21 +00:00
local DropBox = require ( " apps/cloudstorage/dropbox " )
2021-12-25 21:57:51 +00:00
local FFIUtil = require ( " ffi/util " )
2017-04-14 18:12:21 +00:00
local Ftp = require ( " apps/cloudstorage/ftp " )
2017-08-13 10:57:19 +00:00
local InfoMessage = require ( " ui/widget/infomessage " )
2022-01-04 11:29:08 +00:00
local InputDialog = require ( " ui/widget/inputdialog " )
2017-04-06 13:11:21 +00:00
local LuaSettings = require ( " luasettings " )
2017-08-13 10:57:19 +00:00
local Menu = require ( " ui/widget/menu " )
2022-01-04 11:29:08 +00:00
local PathChooser = require ( " ui/widget/pathchooser " )
2017-04-06 13:11:21 +00:00
local UIManager = require ( " ui/uimanager " )
2018-10-17 12:13:59 +00:00
local WebDav = require ( " apps/cloudstorage/webdav " )
2016-12-20 07:34:00 +00:00
local lfs = require ( " libs/libkoreader-lfs " )
2021-05-16 10:46:26 +00:00
local logger = require ( " logger " )
2017-04-14 18:12:21 +00:00
local _ = require ( " gettext " )
2022-01-22 14:35:01 +00:00
local N_ = _.ngettext
2017-08-13 10:57:19 +00:00
local Screen = require ( " device " ) . screen
2022-01-22 14:35:01 +00:00
local T = require ( " ffi/util " ) . template
2016-12-20 07:34:00 +00:00
local CloudStorage = Menu : extend {
cloud_servers = {
{
2018-07-29 20:58:02 +00:00
text = _ ( " Add new cloud storage " ) ,
title = _ ( " Choose cloud type " ) ,
2016-12-20 07:34:00 +00:00
url = " add " ,
editable = false ,
} ,
} ,
no_title = false ,
show_parent = nil ,
is_popout = false ,
is_borderless = true ,
2021-12-25 21:57:51 +00:00
title = _ ( " Cloud storage " ) ,
}
local server_types = {
dropbox = _ ( " Dropbox " ) ,
ftp = _ ( " FTP " ) ,
webdav = _ ( " WebDAV " ) ,
2016-12-20 07:34:00 +00:00
}
function CloudStorage : init ( )
2021-03-06 21:44:18 +00:00
--- @todo: Probably a good candidate for the new readSetting API
2016-12-20 07:34:00 +00:00
self.cs_settings = self : readSettings ( )
self.show_parent = self
2019-11-18 17:39:45 +00:00
if self.item then
self.item_table = self : genItemTable ( self.item )
self.choose_folder_mode = true
else
self.item_table = self : genItemTableFromRoot ( )
end
2017-08-13 10:57:19 +00:00
self.width = Screen : getWidth ( )
self.height = Screen : getHeight ( )
2022-01-10 19:21:39 +00:00
self.title_bar_left_icon = " plus "
self.onLeftButtonTap = function ( ) -- add new cloud storage
2021-12-25 21:57:51 +00:00
self : selectCloudType ( )
end
2016-12-20 07:34:00 +00:00
Menu.init ( self )
2019-11-18 17:39:45 +00:00
if self.item then
self.item_table [ 1 ] . callback ( )
end
2016-12-20 07:34:00 +00:00
end
function CloudStorage : genItemTableFromRoot ( )
local item_table = { }
local added_servers = self.cs_settings : readSetting ( " cs_servers " ) or { }
for _ , server in ipairs ( added_servers ) do
table.insert ( item_table , {
text = server.name ,
2021-12-25 21:57:51 +00:00
mandatory = server_types [ server.type ] ,
2016-12-20 07:34:00 +00:00
address = server.address ,
username = server.username ,
password = server.password ,
type = server.type ,
editable = true ,
url = server.url ,
2019-11-18 17:39:45 +00:00
sync_source_folder = server.sync_source_folder ,
sync_dest_folder = server.sync_dest_folder ,
2016-12-20 07:34:00 +00:00
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
2019-11-18 17:39:45 +00:00
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
self.address = server.address
self.username = server.username
self : openCloudServer ( server.url )
end ,
} )
end
end
return item_table
end
2016-12-20 07:34:00 +00:00
function CloudStorage : selectCloudType ( )
2021-12-25 21:57:51 +00:00
local buttons = { }
for server_type , name in FFIUtil.orderedPairs ( server_types ) do
table.insert ( buttons , {
2018-10-17 12:13:59 +00:00
{
2021-12-25 21:57:51 +00:00
text = name ,
2018-10-17 12:13:59 +00:00
callback = function ( )
UIManager : close ( self.cloud_dialog )
2021-12-25 21:57:51 +00:00
self : configCloud ( server_type )
2018-10-17 12:13:59 +00:00
end ,
} ,
2021-12-25 21:57:51 +00:00
} )
end
self.cloud_dialog = ButtonDialogTitle : new {
title = _ ( " Add new cloud storage " ) ,
title_align = " center " ,
buttons = buttons ,
2016-12-20 07:34:00 +00:00
}
UIManager : show ( self.cloud_dialog )
return true
end
function CloudStorage : openCloudServer ( url )
2021-05-16 10:46:26 +00:00
local tbl , e
2017-03-18 12:49:28 +00:00
local NetworkMgr = require ( " ui/network/manager " )
2016-12-20 07:34:00 +00:00
if self.type == " dropbox " then
Various Wi-Fi QoL improvements (#6424)
* Revamped most actions that require an internet connection to a new/fixed backend that allows forwarding the initial action and running it automatically once connected. (i.e., it'll allow you to set "Action when Wi-Fi is off" to "turn_on", and whatch stuff connect and do what you wanted automatically without having to re-click anywhere instead of showing you a Wi-Fi prompt and then not doing anything without any other feedback).
* Speaking of, fixed the "turn_on" beforeWifi action to, well, actually work. It's no longer marked as experimental.
* Consistently use "Wi-Fi" everywhere.
* On Kobo/Cervantes/Sony, implemented a "Kill Wi-Fi connection when inactive" system that will automatically disconnect from Wi-Fi after sustained *network* inactivity (i.e., you can keep reading, it'll eventually turn off on its own). This should be smart and flexible enough not to murder Wi-Fi while you need it, while still not keeping it uselessly on and murdering your battery.
(i.e., enable that + turn Wi-Fi on when off and enjoy never having to bother about Wi-Fi ever again).
* Made sending `NetworkConnected` / `NetworkDisconnected` events consistent (they were only being sent... sometimes, which made relying on 'em somewhat problematic).
* restoreWifiAsync is now only run when really needed (i.e., we no longer stomp on an existing working connection just for the hell of it).
* We no longer attempt to kill a bogus non-existent Wi-Fi connection when going to suspend, we only do it when it's actually needed.
* Every method of enabling Wi-Fi will now properly tear down Wi-Fi on failure, instead of leaving it in an undefined state.
* Fixed an issue in the fancy crash screen on Kobo/reMarkable that could sometime lead to the log excerpt being missing.
* Worked-around a number of sneaky issues related to low-level Wi-Fi/DHCP/DNS handling on Kobo (see the lengthy comments [below](https://github.com/koreader/koreader/pull/6424#issuecomment-663881059) for details). Fix #6421
Incidentally, this should also fix the inconsistencies experienced re: Wi-Fi behavior in Nickel when toggling between KOReader and Nickel (use NM/KFMon, and run a current FW for best results).
* For developers, this involves various cleanups around NetworkMgr and NetworkListener. Documentation is in-line, above the concerned functions.
2020-07-27 01:39:06 +00:00
if NetworkMgr : willRerunWhenOnline ( function ( ) self : openCloudServer ( url ) end ) then
2018-01-17 14:32:54 +00:00
return
end
2021-05-16 10:46:26 +00:00
tbl , e = DropBox : run ( url , self.password , self.choose_folder_mode )
2016-12-20 07:34:00 +00:00
elseif self.type == " ftp " then
Various Wi-Fi QoL improvements (#6424)
* Revamped most actions that require an internet connection to a new/fixed backend that allows forwarding the initial action and running it automatically once connected. (i.e., it'll allow you to set "Action when Wi-Fi is off" to "turn_on", and whatch stuff connect and do what you wanted automatically without having to re-click anywhere instead of showing you a Wi-Fi prompt and then not doing anything without any other feedback).
* Speaking of, fixed the "turn_on" beforeWifi action to, well, actually work. It's no longer marked as experimental.
* Consistently use "Wi-Fi" everywhere.
* On Kobo/Cervantes/Sony, implemented a "Kill Wi-Fi connection when inactive" system that will automatically disconnect from Wi-Fi after sustained *network* inactivity (i.e., you can keep reading, it'll eventually turn off on its own). This should be smart and flexible enough not to murder Wi-Fi while you need it, while still not keeping it uselessly on and murdering your battery.
(i.e., enable that + turn Wi-Fi on when off and enjoy never having to bother about Wi-Fi ever again).
* Made sending `NetworkConnected` / `NetworkDisconnected` events consistent (they were only being sent... sometimes, which made relying on 'em somewhat problematic).
* restoreWifiAsync is now only run when really needed (i.e., we no longer stomp on an existing working connection just for the hell of it).
* We no longer attempt to kill a bogus non-existent Wi-Fi connection when going to suspend, we only do it when it's actually needed.
* Every method of enabling Wi-Fi will now properly tear down Wi-Fi on failure, instead of leaving it in an undefined state.
* Fixed an issue in the fancy crash screen on Kobo/reMarkable that could sometime lead to the log excerpt being missing.
* Worked-around a number of sneaky issues related to low-level Wi-Fi/DHCP/DNS handling on Kobo (see the lengthy comments [below](https://github.com/koreader/koreader/pull/6424#issuecomment-663881059) for details). Fix #6421
Incidentally, this should also fix the inconsistencies experienced re: Wi-Fi behavior in Nickel when toggling between KOReader and Nickel (use NM/KFMon, and run a current FW for best results).
* For developers, this involves various cleanups around NetworkMgr and NetworkListener. Documentation is in-line, above the concerned functions.
2020-07-27 01:39:06 +00:00
if NetworkMgr : willRerunWhenConnected ( function ( ) self : openCloudServer ( url ) end ) then
2018-01-17 14:32:54 +00:00
return
end
2021-05-16 10:46:26 +00:00
tbl , e = Ftp : run ( self.address , self.username , self.password , url )
2018-10-17 12:13:59 +00:00
elseif self.type == " webdav " then
Various Wi-Fi QoL improvements (#6424)
* Revamped most actions that require an internet connection to a new/fixed backend that allows forwarding the initial action and running it automatically once connected. (i.e., it'll allow you to set "Action when Wi-Fi is off" to "turn_on", and whatch stuff connect and do what you wanted automatically without having to re-click anywhere instead of showing you a Wi-Fi prompt and then not doing anything without any other feedback).
* Speaking of, fixed the "turn_on" beforeWifi action to, well, actually work. It's no longer marked as experimental.
* Consistently use "Wi-Fi" everywhere.
* On Kobo/Cervantes/Sony, implemented a "Kill Wi-Fi connection when inactive" system that will automatically disconnect from Wi-Fi after sustained *network* inactivity (i.e., you can keep reading, it'll eventually turn off on its own). This should be smart and flexible enough not to murder Wi-Fi while you need it, while still not keeping it uselessly on and murdering your battery.
(i.e., enable that + turn Wi-Fi on when off and enjoy never having to bother about Wi-Fi ever again).
* Made sending `NetworkConnected` / `NetworkDisconnected` events consistent (they were only being sent... sometimes, which made relying on 'em somewhat problematic).
* restoreWifiAsync is now only run when really needed (i.e., we no longer stomp on an existing working connection just for the hell of it).
* We no longer attempt to kill a bogus non-existent Wi-Fi connection when going to suspend, we only do it when it's actually needed.
* Every method of enabling Wi-Fi will now properly tear down Wi-Fi on failure, instead of leaving it in an undefined state.
* Fixed an issue in the fancy crash screen on Kobo/reMarkable that could sometime lead to the log excerpt being missing.
* Worked-around a number of sneaky issues related to low-level Wi-Fi/DHCP/DNS handling on Kobo (see the lengthy comments [below](https://github.com/koreader/koreader/pull/6424#issuecomment-663881059) for details). Fix #6421
Incidentally, this should also fix the inconsistencies experienced re: Wi-Fi behavior in Nickel when toggling between KOReader and Nickel (use NM/KFMon, and run a current FW for best results).
* For developers, this involves various cleanups around NetworkMgr and NetworkListener. Documentation is in-line, above the concerned functions.
2020-07-27 01:39:06 +00:00
if NetworkMgr : willRerunWhenConnected ( function ( ) self : openCloudServer ( url ) end ) then
2018-10-17 12:13:59 +00:00
return
end
2021-05-16 10:46:26 +00:00
tbl , e = WebDav : run ( self.address , self.username , self.password , url )
2016-12-20 07:34:00 +00:00
end
2022-01-04 11:29:08 +00:00
if tbl then
2017-02-01 14:24:21 +00:00
self : switchItemTable ( url , tbl )
2022-01-04 11:29:08 +00:00
if self.type == " dropbox " then
2022-01-10 19:21:39 +00:00
self.onLeftButtonTap = function ( )
2022-01-04 11:29:08 +00:00
self : showPlusMenu ( url )
end
else
2022-01-10 19:21:39 +00:00
self : setTitleBarLeftIcon ( " home " )
self.onLeftButtonTap = function ( )
2022-01-04 11:29:08 +00:00
self : init ( )
end
2021-12-25 21:57:51 +00:00
end
2016-12-20 07:34:00 +00:00
return true
2022-01-04 11:29:08 +00:00
else
2021-05-16 10:46:26 +00:00
logger.err ( " CloudStorage: " , e )
2016-12-20 07:34:00 +00:00
UIManager : show ( InfoMessage : new {
2016-12-22 08:13:26 +00:00
text = _ ( " Cannot fetch list of folder contents \n Please check your configuration or network connection. " ) ,
2016-12-20 07:34:00 +00:00
timeout = 3 ,
} )
table.remove ( self.paths )
return false
end
end
function CloudStorage : onMenuSelect ( item )
if item.callback then
if item.url ~= nil then
table.insert ( self.paths , {
url = item.url ,
} )
end
item.callback ( )
elseif item.type == " file " then
self : downloadFile ( item )
2019-11-18 17:39:45 +00:00
elseif item.type == " other " then
return true
2016-12-20 07:34:00 +00:00
else
table.insert ( self.paths , {
url = item.url ,
} )
if not self : openCloudServer ( item.url ) then
table.remove ( self.paths )
end
end
return true
end
function CloudStorage : downloadFile ( item )
2022-02-17 09:53:15 +00:00
local function startDownloadFile ( unit_item , address , username , password , path_dir , callback_close )
2019-11-19 15:52:11 +00:00
UIManager : scheduleIn ( 1 , function ( )
2022-02-17 09:53:15 +00:00
if self.type == " dropbox " then
DropBox : downloadFile ( unit_item , password , path_dir , callback_close )
elseif self.type == " ftp " then
Ftp : downloadFile ( unit_item , address , username , password , path_dir , callback_close )
elseif self.type == " webdav " then
WebDav : downloadFile ( unit_item , address , username , password , path_dir , callback_close )
end
2019-11-19 15:52:11 +00:00
end )
UIManager : show ( InfoMessage : new {
2022-02-17 09:53:15 +00:00
text = _ ( " Downloading. This might take a moment. " ) ,
2019-11-19 15:52:11 +00:00
timeout = 1 ,
} )
end
2022-02-17 09:53:15 +00:00
local function createTitle ( filename_orig , filename , path ) -- title for ButtonDialogTitle
return T ( _ ( " Filename: \n %1 \n \n Download filename: \n %2 \n \n Download folder: \n %3 " ) ,
filename_orig , filename , BD.dirpath ( path ) )
2019-11-19 15:52:11 +00:00
end
2022-02-17 09:53:15 +00:00
local cs_settings = self : readSettings ( )
local download_dir = cs_settings : readSetting ( " download_dir " ) or G_reader_settings : readSetting ( " lastdir " )
local filename_orig = item.text
local filename = filename_orig
2019-11-19 15:52:11 +00:00
2016-12-20 07:34:00 +00:00
local buttons = {
{
{
2022-02-17 09:53:15 +00:00
text = _ ( " Choose folder " ) ,
2016-12-20 07:34:00 +00:00
callback = function ( )
2022-02-17 09:53:15 +00:00
require ( " ui/downloadmgr " ) : new {
show_hidden = G_reader_settings : readSetting ( " show_hidden " ) ,
onConfirm = function ( path )
self.cs_settings : saveSetting ( " download_dir " , path )
self.cs_settings : flush ( )
download_dir = path
self.download_dialog : setTitle ( createTitle ( filename_orig , filename , download_dir ) )
end ,
} : chooseDir ( download_dir )
end ,
} ,
{
text = _ ( " Change filename " ) ,
callback = function ( )
local input_dialog
input_dialog = InputDialog : new {
title = _ ( " Enter filename " ) ,
input = filename ,
input_hint = filename_orig ,
buttons = {
{
{
text = _ ( " Cancel " ) ,
callback = function ( )
UIManager : close ( input_dialog )
end ,
} ,
{
text = _ ( " Set filename " ) ,
is_enter_default = true ,
callback = function ( )
filename = input_dialog : getInputValue ( )
if filename == " " then
filename = filename_orig
end
UIManager : close ( input_dialog )
self.download_dialog : setTitle ( createTitle ( filename_orig , filename , download_dir ) )
end ,
} ,
}
} ,
}
UIManager : show ( input_dialog )
input_dialog : onShowKeyboard ( )
2016-12-20 07:34:00 +00:00
end ,
} ,
} ,
{
{
2022-02-17 09:53:15 +00:00
text = _ ( " Cancel " ) ,
2016-12-20 07:34:00 +00:00
callback = function ( )
2022-02-17 09:53:15 +00:00
UIManager : close ( self.download_dialog )
end ,
} ,
{
text = _ ( " Download " ) ,
callback = function ( )
UIManager : close ( self.download_dialog )
local path_dir = ( download_dir ~= " / " and download_dir or " " ) .. ' / ' .. filename
local callback_close = function ( ) self : onClose ( ) end
if lfs.attributes ( path_dir ) then
UIManager : show ( ConfirmBox : new {
text = _ ( " File already exists. Would you like to overwrite it? " ) ,
ok_callback = function ( )
startDownloadFile ( item , self.address , self.username , self.password , path_dir , callback_close )
end
} )
else
startDownloadFile ( item , self.address , self.username , self.password , path_dir , callback_close )
end
2016-12-20 07:34:00 +00:00
end ,
} ,
} ,
}
2022-02-17 09:53:15 +00:00
self.download_dialog = ButtonDialogTitle : new {
title = createTitle ( filename_orig , filename , download_dir ) ,
buttons = buttons ,
2016-12-20 07:34:00 +00:00
}
UIManager : show ( self.download_dialog )
end
2019-11-18 17:39:45 +00:00
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
2016-12-20 07:34:00 +00:00
function CloudStorage : onMenuHold ( item )
2019-11-18 17:39:45 +00:00
if item.type == " folder_long_press " then
2021-08-24 20:19:07 +00:00
local title = T ( _ ( " Choose this folder? \n \n %1 " ) , BD.dirpath ( item.url ) )
2019-11-18 17:39:45 +00:00
local onConfirm = self.onConfirm
local button_dialog
button_dialog = ButtonDialogTitle : new {
title = title ,
2016-12-20 07:34:00 +00:00
buttons = {
{
{
2019-11-18 17:39:45 +00:00
text = _ ( " Cancel " ) ,
2016-12-20 07:34:00 +00:00
callback = function ( )
2019-11-18 17:39:45 +00:00
UIManager : close ( button_dialog )
end ,
2016-12-20 07:34:00 +00:00
} ,
{
2021-08-24 20:19:07 +00:00
text = _ ( " Choose " ) ,
2016-12-20 07:34:00 +00:00
callback = function ( )
2019-11-18 17:39:45 +00:00
if onConfirm then
onConfirm ( item.url )
end
UIManager : close ( button_dialog )
UIManager : close ( self )
end ,
2016-12-20 07:34:00 +00:00
} ,
} ,
2019-11-18 17:39:45 +00:00
} ,
}
UIManager : show ( button_dialog )
end
if item.editable then
local cs_server_dialog
local buttons = {
{
{
text = _ ( " Info " ) ,
callback = function ( )
UIManager : close ( cs_server_dialog )
self : infoServer ( item )
end
} ,
{
text = _ ( " Edit " ) ,
callback = function ( )
UIManager : close ( cs_server_dialog )
self : editCloudServer ( item )
end
} ,
{
text = _ ( " Delete " ) ,
callback = function ( )
UIManager : close ( cs_server_dialog )
self : deleteCloudServer ( item )
end
} ,
} ,
}
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 " ) ,
callback = function ( )
UIManager : close ( cs_server_dialog )
self : synchronizeSettings ( item )
end
} ,
} )
end
cs_server_dialog = ButtonDialog : new {
buttons = buttons
2016-12-20 07:34:00 +00:00
}
UIManager : show ( cs_server_dialog )
return true
end
end
2019-11-18 17:39:45 +00:00
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
2019-11-18 19:51:08 +00:00
text = _ ( " No files to download from Dropbox. " )
2019-11-18 17:39:45 +00:00
else
2022-01-22 14:35:01 +00:00
text = T ( N_ ( " Successfully downloaded 1 file from Dropbox to local storage. " , " Successfully downloaded %1 files from Dropbox to local storage. " , downloaded_files ) , downloaded_files )
if failed_files > 0 then
text = text .. " \n " .. T ( N_ ( " Failed to download 1 file. " , " Failed to download %1 files. " , failed_files ) , failed_files )
end
2019-11-18 17:39:45 +00:00
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 {
2020-01-04 00:18:51 +00:00
title = T ( _ ( " Dropbox folder: \n %1 \n Local folder: \n %2 " ) , BD.dirpath ( dropbox_sync_folder ) , BD.dirpath ( local_sync_folder ) ) ,
2019-11-18 17:39:45 +00:00
title_align = " center " ,
buttons = {
{
{
2019-11-18 19:51:08 +00:00
text = _ ( " Choose Dropbox folder " ) ,
2019-11-18 17:39:45 +00:00
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
2022-01-04 11:29:08 +00:00
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 ,
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 )
2022-02-17 09:53:15 +00:00
local url_base = url ~= " / " and url or " "
2022-01-04 11:29:08 +00:00
UIManager : tickAfterNext ( function ( )
2022-02-17 09:53:15 +00:00
DropBox : uploadFile ( url_base , self.password , file_path , callback_close )
2022-01-04 11:29:08 +00:00
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 " ) ,
2022-03-04 20:20:00 +00:00
id = " close " ,
2022-01-04 11:29:08 +00:00
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 )
2022-02-17 09:53:15 +00:00
local url_base = url ~= " / " and url or " "
2022-01-04 11:29:08 +00:00
local callback_close = function ( )
if check_button_enter_folder.checked then
table.insert ( self.paths , {
url = url ,
} )
2022-02-17 09:53:15 +00:00
url = url_base .. " / " .. folder_name
2022-01-04 11:29:08 +00:00
end
self : openCloudServer ( url )
end
2022-02-17 09:53:15 +00:00
DropBox : createFolder ( url_base , self.password , folder_name , callback_close )
2022-01-04 11:29:08 +00:00
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
2016-12-20 07:34:00 +00:00
function CloudStorage : configCloud ( type )
local callbackAdd = function ( fields )
local cs_settings = self : readSettings ( )
local cs_servers = cs_settings : readSetting ( " cs_servers " ) or { }
if type == " dropbox " then
table.insert ( cs_servers , {
name = fields [ 1 ] ,
password = fields [ 2 ] ,
type = " dropbox " ,
url = " / "
} )
elseif type == " ftp " then
table.insert ( cs_servers , {
name = fields [ 1 ] ,
address = fields [ 2 ] ,
username = fields [ 3 ] ,
password = fields [ 4 ] ,
2018-10-18 04:34:29 +00:00
url = fields [ 5 ] ,
2016-12-20 07:34:00 +00:00
type = " ftp " ,
} )
2018-10-17 12:13:59 +00:00
elseif type == " webdav " then
table.insert ( cs_servers , {
name = fields [ 1 ] ,
address = fields [ 2 ] ,
username = fields [ 3 ] ,
password = fields [ 4 ] ,
url = fields [ 5 ] ,
type = " webdav " ,
} )
2016-12-20 07:34:00 +00:00
end
cs_settings : saveSetting ( " cs_servers " , cs_servers )
cs_settings : flush ( )
self : init ( )
end
if type == " dropbox " then
DropBox : config ( nil , callbackAdd )
end
if type == " ftp " then
Ftp : config ( nil , callbackAdd )
end
2018-10-17 12:13:59 +00:00
if type == " webdav " then
WebDav : config ( nil , callbackAdd )
end
2016-12-20 07:34:00 +00:00
end
function CloudStorage : editCloudServer ( item )
local callbackEdit = function ( updated_config , fields )
local cs_settings = self : readSettings ( )
local cs_servers = cs_settings : readSetting ( " cs_servers " ) or { }
if item.type == " dropbox " then
for i , server in ipairs ( cs_servers ) do
if server.name == updated_config.text and server.password == updated_config.password then
server.name = fields [ 1 ]
server.password = fields [ 2 ]
cs_servers [ i ] = server
break
end
end
elseif item.type == " ftp " then
for i , server in ipairs ( cs_servers ) do
if server.name == updated_config.text and server.address == updated_config.address then
server.name = fields [ 1 ]
server.address = fields [ 2 ]
server.username = fields [ 3 ]
server.password = fields [ 4 ]
2018-10-18 04:34:29 +00:00
server.url = fields [ 5 ]
2016-12-20 07:34:00 +00:00
cs_servers [ i ] = server
break
end
end
2018-10-17 12:13:59 +00:00
elseif item.type == " webdav " then
for i , server in ipairs ( cs_servers ) do
if server.name == updated_config.text and server.address == updated_config.address then
server.name = fields [ 1 ]
server.address = fields [ 2 ]
server.username = fields [ 3 ]
server.password = fields [ 4 ]
server.url = fields [ 5 ]
cs_servers [ i ] = server
break
end
end
2016-12-20 07:34:00 +00:00
end
cs_settings : saveSetting ( " cs_servers " , cs_servers )
cs_settings : flush ( )
self : init ( )
end
if item.type == " dropbox " then
DropBox : config ( item , callbackEdit )
elseif item.type == " ftp " then
Ftp : config ( item , callbackEdit )
2018-10-17 12:13:59 +00:00
elseif item.type == " webdav " then
WebDav : config ( item , callbackEdit )
2016-12-20 07:34:00 +00:00
end
end
function CloudStorage : deleteCloudServer ( item )
local cs_settings = self : readSettings ( )
local cs_servers = cs_settings : readSetting ( " cs_servers " ) or { }
for i , server in ipairs ( cs_servers ) do
if server.name == item.text and server.password == item.password and server.type == item.type then
table.remove ( cs_servers , i )
break
end
end
cs_settings : saveSetting ( " cs_servers " , cs_servers )
cs_settings : flush ( )
self : init ( )
end
function CloudStorage : infoServer ( item )
if item.type == " dropbox " then
DropBox : info ( item.password )
elseif item.type == " ftp " then
Ftp : info ( item )
2018-10-17 12:13:59 +00:00
elseif item.type == " webdav " then
WebDav : info ( item )
2016-12-20 07:34:00 +00:00
end
end
function CloudStorage : readSettings ( )
self.cs_settings = LuaSettings : open ( DataStorage : getSettingsDir ( ) .. " /cloudstorage.lua " )
return self.cs_settings
end
function CloudStorage : onReturn ( )
if # self.paths > 0 then
table.remove ( self.paths )
local path = self.paths [ # self.paths ]
if path then
-- return to last path
self : openCloudServer ( path.url )
else
-- return to root path
self : init ( )
end
end
return true
end
2021-06-29 08:22:03 +00:00
function CloudStorage : onHoldReturn ( )
if # self.paths > 1 then
local path = self.paths [ 1 ]
if path then
for i = # self.paths , 2 , - 1 do
table.remove ( self.paths )
end
self : openCloudServer ( path.url )
end
end
return true
end
2016-12-20 07:34:00 +00:00
return CloudStorage