[fix] large files cause OOM
This commit is contained in:
parent
d02f8c324f
commit
240b3a2b67
@ -1,6 +1,10 @@
|
|||||||
local UIManager = require("ui/uimanager")
|
local UIManager = require("ui/uimanager")
|
||||||
local socketutil = require("socketutil")
|
local http = require("socket.http")
|
||||||
|
local lfs = require("libs/libkoreader-lfs")
|
||||||
local logger = require("logger")
|
local logger = require("logger")
|
||||||
|
local ltn12 = require("ltn12")
|
||||||
|
local socket = require("socket")
|
||||||
|
local socketutil = require("socketutil")
|
||||||
|
|
||||||
-- Push/Pull
|
-- Push/Pull
|
||||||
local SYNC_TIMEOUTS = {2, 5}
|
local SYNC_TIMEOUTS = {2, 5}
|
||||||
@ -199,23 +203,68 @@ function SyncNinjaClient:download_document(username, password, document,
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function SyncNinjaClient:upload_document(username, password, document, file,
|
function SyncNinjaClient:upload_document(username, password, document, filepath,
|
||||||
callback)
|
callback)
|
||||||
self.client:reset_middlewares()
|
-- Create URL
|
||||||
self.client:enable("Format.JSON")
|
local url = self.custom_url ..
|
||||||
self.client:enable("GinClient")
|
(self.custom_url:sub(-#"/") ~= "/" and "/" or "") ..
|
||||||
self.client:enable("SyncNinjaAuth",
|
"api/ko/documents/" .. document .. "/file"
|
||||||
{username = username, userkey = password})
|
|
||||||
|
|
||||||
local ok, res = pcall(function()
|
-- Track Length, Sources, and Boundary
|
||||||
return self.client:upload_document({document = document, file = file})
|
local len = 0
|
||||||
end)
|
local sources = {}
|
||||||
if ok then
|
local boundary = "-----BoundaryePkpFF7tjBAqx29L"
|
||||||
callback(res.status == 200, res.body)
|
|
||||||
else
|
-- Open File & Get Size
|
||||||
|
local file = io.open(filepath, "rb")
|
||||||
|
local file_size = lfs.attributes(filepath, 'size')
|
||||||
|
|
||||||
|
-- Insert File Start
|
||||||
|
local str_start = {}
|
||||||
|
table.insert(str_start, "--" .. boundary .. "\r\n")
|
||||||
|
table.insert(str_start, 'content-disposition: form-data; name="file";')
|
||||||
|
table.insert(str_start, 'filename="' .. "test" ..
|
||||||
|
'"\r\ncontent-type: application/octet-stream\r\n\r\n')
|
||||||
|
str_start = table.concat(str_start)
|
||||||
|
table.insert(sources, ltn12.source.string(str_start))
|
||||||
|
len = len + #str_start
|
||||||
|
|
||||||
|
-- Insert File
|
||||||
|
table.insert(sources, ltn12.source.file(file))
|
||||||
|
len = len + file_size
|
||||||
|
|
||||||
|
-- Insert File End
|
||||||
|
local str_end = "\r\n"
|
||||||
|
table.insert(sources, ltn12.source.string(str_end))
|
||||||
|
len = len + #str_end
|
||||||
|
|
||||||
|
-- Insert Multipart End
|
||||||
|
local str = string.format("--%s--\r\n", boundary)
|
||||||
|
table.insert(sources, ltn12.source.string(str))
|
||||||
|
len = len + #str
|
||||||
|
|
||||||
|
-- Execute Request
|
||||||
|
logger.dbg("SyncNinja: upload_document - Uploading [" .. len .. "]:",
|
||||||
|
filepath)
|
||||||
|
|
||||||
|
local resp = {}
|
||||||
|
local code, headers, status = socket.skip(1, http.request {
|
||||||
|
url = url,
|
||||||
|
method = 'PUT',
|
||||||
|
headers = {
|
||||||
|
["Content-Length"] = len,
|
||||||
|
['Content-Type'] = "multipart/form-data; boundary=" .. boundary,
|
||||||
|
['X-Auth-User'] = username,
|
||||||
|
['X-Auth-Key'] = password
|
||||||
|
},
|
||||||
|
source = ltn12.source.cat(unpack(sources)),
|
||||||
|
sink = ltn12.sink.table(resp)
|
||||||
|
})
|
||||||
|
|
||||||
|
if code ~= 200 then
|
||||||
logger.dbg("SyncNinjaClient:upload_document failure:", res)
|
logger.dbg("SyncNinjaClient:upload_document failure:", res)
|
||||||
callback(false, res.body)
|
|
||||||
end
|
end
|
||||||
|
callback(code == 200, resp)
|
||||||
end
|
end
|
||||||
|
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
local ConfirmBox = require("ui/widget/confirmbox")
|
local ConfirmBox = require("ui/widget/confirmbox")
|
||||||
local DataStorage = require("datastorage")
|
local DataStorage = require("datastorage")
|
||||||
local Device = require("device")
|
local Device = require("device")
|
||||||
local Dispatcher = require("dispatcher")
|
|
||||||
local DocSettings = require("docsettings")
|
local DocSettings = require("docsettings")
|
||||||
local InfoMessage = require("ui/widget/infomessage")
|
local InfoMessage = require("ui/widget/infomessage")
|
||||||
local MultiInputDialog = require("ui/widget/multiinputdialog")
|
local MultiInputDialog = require("ui/widget/multiinputdialog")
|
||||||
@ -15,11 +14,6 @@ local _ = require("gettext")
|
|||||||
local logger = require("logger")
|
local logger = require("logger")
|
||||||
local md5 = require("ffi/sha2").md5
|
local md5 = require("ffi/sha2").md5
|
||||||
|
|
||||||
-- TODO:
|
|
||||||
-- - Handle ReadHistory missing files (statistics.sqlite3, bookinfo_cache.sqlite3)
|
|
||||||
-- - Handle document uploads (Manual push only, warning saying this may take awhile)
|
|
||||||
-- - Configure activity bulk size? 1000, 5000, 10000? Separate manual settings to upload ALL?
|
|
||||||
|
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
------------ Helper Functions ------------
|
------------ Helper Functions ------------
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
@ -574,9 +568,10 @@ function SyncNinja:performSync(interactive)
|
|||||||
self:checkActivity(interactive)
|
self:checkActivity(interactive)
|
||||||
self:checkDocuments(interactive)
|
self:checkDocuments(interactive)
|
||||||
|
|
||||||
|
-- Notify
|
||||||
if interactive == true then
|
if interactive == true then
|
||||||
UIManager:show(InfoMessage:new{
|
UIManager:show(InfoMessage:new{
|
||||||
text = _("SyncNinja: Manual Sync Success"),
|
text = _("SyncNinja: Manual Sync Initiated"),
|
||||||
timeout = 3
|
timeout = 3
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
@ -634,7 +629,6 @@ function SyncNinja:uploadActivity(activity_data, interactive)
|
|||||||
timeout = 3
|
timeout = 3
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
return logger.dbg("SyncNinja: uploadActivity Error:", dump(body))
|
return logger.dbg("SyncNinja: uploadActivity Error:", dump(body))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -769,7 +763,6 @@ function SyncNinja:uploadDocumentFiles(doc_metadata, interactive)
|
|||||||
if self.settings.sync_document_files ~= true then return end
|
if self.settings.sync_document_files ~= true then return end
|
||||||
if interactive ~= true then return end
|
if interactive ~= true then return end
|
||||||
|
|
||||||
-- API Callback Function
|
|
||||||
local callback_func = function(ok, body)
|
local callback_func = function(ok, body)
|
||||||
if not ok then
|
if not ok then
|
||||||
UIManager:show(InfoMessage:new{
|
UIManager:show(InfoMessage:new{
|
||||||
@ -787,24 +780,30 @@ function SyncNinja:uploadDocumentFiles(doc_metadata, interactive)
|
|||||||
text = _("Uploading Documents - Please Wait...")
|
text = _("Uploading Documents - Please Wait...")
|
||||||
})
|
})
|
||||||
|
|
||||||
-- API Client
|
UIManager:nextTick(function()
|
||||||
local SyncNinjaClient = require("SyncNinjaClient")
|
-- API Client
|
||||||
local client = SyncNinjaClient:new{
|
local SyncNinjaClient = require("SyncNinjaClient")
|
||||||
custom_url = self.settings.server,
|
local client = SyncNinjaClient:new{
|
||||||
service_spec = self.path .. "/api.json"
|
custom_url = self.settings.server,
|
||||||
}
|
service_spec = self.path .. "/api.json"
|
||||||
|
}
|
||||||
|
|
||||||
for _, v in pairs(doc_metadata) do
|
for _, v in pairs(doc_metadata) do
|
||||||
if v.filepath ~= nil then
|
if v.filepath ~= nil then
|
||||||
-- TODO: Partial File Uploads (Resolve: OOM Issue)
|
local ok, err = pcall(client.upload_document, client,
|
||||||
local ok, err = pcall(client.upload_document, client,
|
self.settings.username,
|
||||||
self.settings.username,
|
self.settings.password, v.id,
|
||||||
self.settings.password, v.id, v.filepath,
|
v.filepath, callback_func)
|
||||||
callback_func)
|
else
|
||||||
|
logger.dbg("SyncNinja: uploadDocumentFiles - no file for:",
|
||||||
|
v.id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
UIManager:show(InfoMessage:new{text = _("Uploading Documents Complete")})
|
UIManager:show(InfoMessage:new{
|
||||||
|
text = _("Uploading Documents Complete")
|
||||||
|
})
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
UIManager:show(ConfirmBox:new{
|
UIManager:show(ConfirmBox:new{
|
||||||
|
Loading…
Reference in New Issue
Block a user