AnthoLume/client/syncninja.koplugin/SyncNinjaClient.lua
2023-09-18 20:03:57 -04:00

317 lines
11 KiB
Lua

local UIManager = require("ui/uimanager")
local socketutil = require("socketutil")
local logger = require("logger")
-- Push/Pull
local SYNC_TIMEOUTS = {2, 5}
-- Login/Register
local AUTH_TIMEOUTS = {5, 10}
local SyncNinjaClient = {service_spec = nil, custom_url = nil}
function SyncNinjaClient:new(o)
if o == nil then o = {} end
setmetatable(o, self)
self.__index = self
if o.init then o:init() end
return o
end
function SyncNinjaClient:init()
local Spore = require("Spore")
self.client = Spore.new_from_spec(self.service_spec,
{base_url = self.custom_url})
package.loaded["Spore.Middleware.GinClient"] = {}
require("Spore.Middleware.GinClient").call = function(_, req)
req.headers["accept"] = "application/vnd.koreader.v1+json"
end
package.loaded["Spore.Middleware.SyncNinjaAuth"] = {}
require("Spore.Middleware.SyncNinjaAuth").call = function(args, req)
req.headers["x-auth-user"] = args.username
req.headers["x-auth-key"] = args.userkey
end
package.loaded["Spore.Middleware.AsyncHTTP"] = {}
require("Spore.Middleware.AsyncHTTP").call = function(args, req)
-- disable async http if Turbo looper is missing
if not UIManager.looper then return end
req:finalize()
local result
local turbo = require("turbo")
turbo.log.categories.success = false
turbo.log.categories.warning = false
local client = turbo.async.HTTPClient({verify_ca = false})
local res = coroutine.yield(client:fetch(request.url, {
url = req.url,
method = req.method,
body = req.env.spore.payload,
connect_timeout = 10,
request_timeout = 20,
on_headers = function(headers)
for header, value in pairs(req.headers) do
if type(header) == "string" then
headers:add(header, value)
end
end
end
}))
return res
-- return coroutine.create(function() coroutine.yield(result) end)
end
end
------------------------------------------
-------------- New Functions -------------
------------------------------------------
function SyncNinjaClient:check_activity(username, password, device_id, callback)
self.client:reset_middlewares()
self.client:enable("Format.JSON")
self.client:enable("GinClient")
self.client:enable("SyncNinjaAuth",
{username = username, userkey = password})
socketutil:set_timeout(SYNC_TIMEOUTS[1], SYNC_TIMEOUTS[2])
local co = coroutine.create(function()
local ok, res = pcall(function()
return self.client:check_activity({device_id = device_id})
end)
if ok then
callback(res.status == 200, res.body)
else
logger.dbg("SyncNinjaClient:check_activity failure:", res)
callback(false, res.body)
end
end)
self.client:enable("AsyncHTTP", {thread = co})
coroutine.resume(co)
if UIManager.looper then UIManager:setInputTimeout() end
socketutil:reset_timeout()
end
function SyncNinjaClient:add_activity(username, password, device_id, device,
activity, callback)
self.client:reset_middlewares()
self.client:enable("Format.JSON")
self.client:enable("GinClient")
self.client:enable("SyncNinjaAuth",
{username = username, userkey = password})
socketutil:set_timeout(SYNC_TIMEOUTS[1], SYNC_TIMEOUTS[2])
local co = coroutine.create(function()
local ok, res = pcall(function()
return self.client:add_activity({
device_id = device_id,
device = device,
activity = activity
})
end)
if ok then
callback(res.status == 200, res.body)
else
logger.dbg("SyncNinjaClient:add_activity failure:", res)
callback(false, res.body)
end
end)
self.client:enable("AsyncHTTP", {thread = co})
coroutine.resume(co)
if UIManager.looper then UIManager:setInputTimeout() end
socketutil:reset_timeout()
end
function SyncNinjaClient:add_documents(username, password, documents, callback)
self.client:reset_middlewares()
self.client:enable("Format.JSON")
self.client:enable("GinClient")
self.client:enable("SyncNinjaAuth",
{username = username, userkey = password})
socketutil:set_timeout(SYNC_TIMEOUTS[1], SYNC_TIMEOUTS[2])
local co = coroutine.create(function()
local ok, res = pcall(function()
return self.client:add_documents({documents = documents})
end)
if ok then
callback(res.status == 200, res.body)
else
logger.dbg("SyncNinjaClient:add_documents failure:", res)(
"SyncNinjaClient:add_documents failure:", res)
callback(false, res.body)
end
end)
self.client:enable("AsyncHTTP", {thread = co})
coroutine.resume(co)
if UIManager.looper then UIManager:setInputTimeout() end
socketutil:reset_timeout()
end
function SyncNinjaClient:check_documents(username, password, device_id, device,
have, callback)
self.client:reset_middlewares()
self.client:enable("Format.JSON")
self.client:enable("GinClient")
self.client:enable("SyncNinjaAuth",
{username = username, userkey = password})
socketutil:set_timeout(SYNC_TIMEOUTS[1], SYNC_TIMEOUTS[2])
local co = coroutine.create(function()
local ok, res = pcall(function()
return self.client:check_documents({
device_id = device_id,
device = device,
have = have
})
end)
if ok then
callback(res.status == 200, res.body)
else
logger.dbg("SyncNinjaClient:check_documents failure:", res)
callback(false, res.body)
end
end)
self.client:enable("AsyncHTTP", {thread = co})
coroutine.resume(co)
if UIManager.looper then UIManager:setInputTimeout() end
socketutil:reset_timeout()
end
function SyncNinjaClient:download_document(username, password, document,
callback)
self.client:reset_middlewares()
self.client:enable("Format.JSON")
self.client:enable("GinClient")
self.client:enable("SyncNinjaAuth",
{username = username, userkey = password})
local ok, res = pcall(function()
return self.client:download_document({document = document})
end)
if ok then
callback(res.status == 200, res.body)
else
logger.dbg("SyncNinjaClient:download_document failure:", res)
callback(false, res.body)
end
end
function SyncNinjaClient:upload_document(username, password, document, file,
callback)
self.client:reset_middlewares()
self.client:enable("Format.JSON")
self.client:enable("GinClient")
self.client:enable("SyncNinjaAuth",
{username = username, userkey = password})
local ok, res = pcall(function()
return self.client:upload_document({document = document, file = file})
end)
if ok then
callback(res.status == 200, res.body)
else
logger.dbg("SyncNinjaClient:upload_document failure:", res)
callback(false, res.body)
end
end
------------------------------------------
----------- Existing Functions -----------
------------------------------------------
function SyncNinjaClient:register(username, password)
self.client:reset_middlewares()
self.client:enable("Format.JSON")
self.client:enable("GinClient")
socketutil:set_timeout(AUTH_TIMEOUTS[1], AUTH_TIMEOUTS[2])
local ok, res = pcall(function()
return self.client:register({username = username, password = password})
end)
socketutil:reset_timeout()
if ok then
return res.status == 201, res.body
else
logger.dbg("SyncNinjaClient:register failure:", res)
return false, res.body
end
end
function SyncNinjaClient:authorize(username, password)
self.client:reset_middlewares()
self.client:enable("Format.JSON")
self.client:enable("GinClient")
self.client:enable("SyncNinjaAuth",
{username = username, userkey = password})
socketutil:set_timeout(AUTH_TIMEOUTS[1], AUTH_TIMEOUTS[2])
local ok, res = pcall(function() return self.client:authorize() end)
socketutil:reset_timeout()
if ok then
return res.status == 200, res.body
else
logger.dbg("SyncNinjaClient:authorize failure:", res)
return false, res.body
end
end
function SyncNinjaClient:update_progress(username, password, document, progress,
percentage, device, device_id, callback)
self.client:reset_middlewares()
self.client:enable("Format.JSON")
self.client:enable("GinClient")
self.client:enable("SyncNinjaAuth",
{username = username, userkey = password})
socketutil:set_timeout(SYNC_TIMEOUTS[1], SYNC_TIMEOUTS[2])
local co = coroutine.create(function()
local ok, res = pcall(function()
return self.client:update_progress({
document = document,
progress = tostring(progress),
percentage = percentage,
device = device,
device_id = device_id
})
end)
if ok then
callback(res.status == 200, res.body)
else
logger.dbg("SyncNinjaClient:update_progress failure:", res)
callback(false, res.body)
end
end)
self.client:enable("AsyncHTTP", {thread = co})
coroutine.resume(co)
if UIManager.looper then UIManager:setInputTimeout() end
socketutil:reset_timeout()
end
function SyncNinjaClient:get_progress(username, password, document, callback)
self.client:reset_middlewares()
self.client:enable("Format.JSON")
self.client:enable("GinClient")
self.client:enable("SyncNinjaAuth",
{username = username, userkey = password})
socketutil:set_timeout(SYNC_TIMEOUTS[1], SYNC_TIMEOUTS[2])
local co = coroutine.create(function()
local ok, res = pcall(function()
return self.client:get_progress({document = document})
end)
if ok then
callback(res.status == 200, res.body)
else
logger.dbg("SyncNinjaClient:get_progress failure:", res)
callback(false, res.body)
end
end)
self.client:enable("AsyncHTTP", {thread = co})
coroutine.resume(co)
if UIManager.looper then UIManager:setInputTimeout() end
socketutil:reset_timeout()
end
return SyncNinjaClient