mirror of
https://github.com/koreader/koreader
synced 2024-11-11 19:11:14 +00:00
Merge pull request #664 from chrox/zsync
add peer-to-peer file sharing plugin ZSync
This commit is contained in:
commit
3433241c1a
@ -19,7 +19,7 @@ function PluginLoader:loadPlugins()
|
||||
local package_cpath = package.cpath
|
||||
package.path = path.."/?.lua;"..package.path
|
||||
package.cpath = path.."/lib/?.so;"..package.cpath
|
||||
local ok, module = pcall(require, "main")
|
||||
local ok, module = pcall(dofile, mainfile)
|
||||
if not ok then
|
||||
DEBUG("Error when loading", mainfile, module)
|
||||
end
|
||||
@ -37,6 +37,8 @@ function PluginLoader:loadPlugins()
|
||||
package.cpath = package.cpath..";"..plugin.path.."/lib/?.so"
|
||||
end
|
||||
|
||||
table.sort(self.plugins, function(v1,v2) return v1.path < v2.path end)
|
||||
|
||||
return self.plugins
|
||||
end
|
||||
|
||||
|
@ -301,6 +301,7 @@ end
|
||||
function ReaderUI:onClose()
|
||||
DEBUG("closing reader")
|
||||
self:saveSettings()
|
||||
self:handleEvent(Event:new("CloseReader"))
|
||||
if self.document ~= nil then
|
||||
self.document:close()
|
||||
self.document = nil
|
||||
|
45
frontend/ui/message/filemessagequeue.lua
Normal file
45
frontend/ui/message/filemessagequeue.lua
Normal file
@ -0,0 +1,45 @@
|
||||
local ffi = require("ffi")
|
||||
local DEBUG = require("dbg")
|
||||
local util = require("ffi/util")
|
||||
local Event = require("ui/event")
|
||||
local MessageQueue = require("ui/message/messagequeue")
|
||||
|
||||
local dummy = require("ffi/zeromq_h")
|
||||
local filemq = ffi.load("libs/libfmq.so.1")
|
||||
|
||||
local FileMessageQueue = MessageQueue:new{
|
||||
client = nil,
|
||||
server = nil,
|
||||
}
|
||||
|
||||
function FileMessageQueue:init()
|
||||
if self.client ~= nil then
|
||||
self.fmq_recv = filemq.fmq_client_recv_nowait
|
||||
self.filemq = self.client
|
||||
elseif self.server ~= nil then
|
||||
self.fmq_recv = filemq.fmq_server_recv_nowait
|
||||
self.filemq = self.server
|
||||
end
|
||||
end
|
||||
|
||||
function FileMessageQueue:stop()
|
||||
if self.client ~= nil then
|
||||
DEBUG("stop filemq client")
|
||||
filemq.fmq_client_destroy(ffi.new('fmq_client_t *[1]', self.client))
|
||||
end
|
||||
if self.server ~= nil then
|
||||
DEBUG("stop filemq server")
|
||||
filemq.fmq_server_destroy(ffi.new('fmq_server_t *[1]', self.server))
|
||||
end
|
||||
end
|
||||
|
||||
function FileMessageQueue:waitEvent()
|
||||
local msg = self.fmq_recv(self.filemq)
|
||||
while msg ~= nil do
|
||||
table.insert(self.messages, msg)
|
||||
msg = self.fmq_recv(self.filemq)
|
||||
end
|
||||
return self:handleZMsgs(self.messages)
|
||||
end
|
||||
|
||||
return FileMessageQueue
|
85
frontend/ui/message/messagequeue.lua
Normal file
85
frontend/ui/message/messagequeue.lua
Normal file
@ -0,0 +1,85 @@
|
||||
local ffi = require("ffi")
|
||||
local util = require("ffi/util")
|
||||
local Event = require("ui/event")
|
||||
local DEBUG = require("dbg")
|
||||
|
||||
local dummy = require("ffi/zeromq_h")
|
||||
local czmq = ffi.load("libs/libczmq.so.1")
|
||||
local zyre = ffi.load("libs/libzyre.so.1")
|
||||
|
||||
local MessageQueue = {}
|
||||
|
||||
function MessageQueue:new(o)
|
||||
o = o or {}
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
if o.init then o:init() end
|
||||
self.messages = {}
|
||||
return o
|
||||
end
|
||||
|
||||
function MessageQueue:init()
|
||||
end
|
||||
|
||||
function MessageQueue:start()
|
||||
end
|
||||
|
||||
function MessageQueue:stop()
|
||||
end
|
||||
|
||||
function MessageQueue:waitEvent()
|
||||
end
|
||||
|
||||
function MessageQueue:handleZMsgs(messages)
|
||||
local function drop_message()
|
||||
if czmq.zmsg_size(messages[1]) == 0 then
|
||||
czmq.zmsg_destroy(ffi.new('zmsg_t *[1]', messages[1]))
|
||||
table.remove(messages, 1)
|
||||
end
|
||||
end
|
||||
local function pop_string()
|
||||
local str_p = czmq.zmsg_popstr(messages[1])
|
||||
local message_size = czmq.zmsg_size(messages[1])
|
||||
local res = ffi.string(str_p)
|
||||
czmq.zstr_free(ffi.new('char *[1]', str_p))
|
||||
drop_message()
|
||||
return res
|
||||
end
|
||||
local function pop_header()
|
||||
local header = {}
|
||||
local frame = czmq.zmsg_pop(messages[1])
|
||||
if frame ~= nil then
|
||||
local hash = czmq.zhash_unpack(frame)
|
||||
czmq.zframe_destroy(ffi.new('zframe_t *[1]', frame))
|
||||
if hash ~= nil then
|
||||
local value, key = czmq.zhash_first(hash), czmq.zhash_cursor(hash)
|
||||
while value ~= nil and key ~= nil do
|
||||
header[ffi.string(key)] = ffi.string(value)
|
||||
value, key = czmq.zhash_next(hash), czmq.zhash_cursor(hash)
|
||||
end
|
||||
czmq.zhash_destroy(ffi.new('zhash_t *[1]', hash))
|
||||
end
|
||||
end
|
||||
drop_message()
|
||||
return header
|
||||
end
|
||||
if #messages == 0 then return end
|
||||
local message_size = czmq.zmsg_size(messages[1])
|
||||
local command = pop_string()
|
||||
DEBUG("ØMQ message", command)
|
||||
if command == "ENTER" and #messages >= 4 then
|
||||
local id = pop_string()
|
||||
local name = pop_string()
|
||||
local header = pop_header()
|
||||
local endpoint = pop_string()
|
||||
--DEBUG(id, name, header, endpoint)
|
||||
return Event:new("ZyreEnter", id, name, header, endpoint)
|
||||
elseif command == "DELIVER" then
|
||||
local filename = pop_string()
|
||||
local fullname = pop_string()
|
||||
--DEBUG("received", filename)
|
||||
return Event:new("FileDeliver", filename, fullname)
|
||||
end
|
||||
end
|
||||
|
||||
return MessageQueue
|
41
frontend/ui/message/zyremessagequeue.lua
Normal file
41
frontend/ui/message/zyremessagequeue.lua
Normal file
@ -0,0 +1,41 @@
|
||||
local ffi = require("ffi")
|
||||
local DEBUG = require("dbg")
|
||||
local util = require("ffi/util")
|
||||
local Event = require("ui/event")
|
||||
local MessageQueue = require("ui/message/messagequeue")
|
||||
|
||||
local dummy = require("ffi/zeromq_h")
|
||||
local zyre = ffi.load("libs/libzyre.so.1")
|
||||
|
||||
local ZyreMessageQueue = MessageQueue:new{
|
||||
header = {},
|
||||
}
|
||||
|
||||
function ZyreMessageQueue:start()
|
||||
self.node = zyre.zyre_new()
|
||||
for key, value in pairs(self.header) do
|
||||
zyre.zyre_set_header(self.node, key, value)
|
||||
end
|
||||
zyre.zyre_set_verbose(self.node)
|
||||
zyre.zyre_start(self.node)
|
||||
zyre.zyre_join(self.node, "GLOBAL")
|
||||
end
|
||||
|
||||
function ZyreMessageQueue:stop()
|
||||
if self.node ~= nil then
|
||||
DEBUG("stop zyre node")
|
||||
zyre.zyre_stop(self.node)
|
||||
zyre.zyre_destroy(ffi.new('zyre_t *[1]', self.node))
|
||||
end
|
||||
end
|
||||
|
||||
function ZyreMessageQueue:waitEvent()
|
||||
local msg = zyre.zyre_recv_nowait(self.node)
|
||||
while msg ~= nil do
|
||||
table.insert(self.messages, msg)
|
||||
msg = zyre.zyre_recv_nowait(self.node)
|
||||
end
|
||||
return self:handleZMsgs(self.messages)
|
||||
end
|
||||
|
||||
return ZyreMessageQueue
|
@ -11,16 +11,16 @@ Screen:init()
|
||||
-- initialize the input handling
|
||||
Input:init()
|
||||
|
||||
local WAVEFORM_MODE_INIT = 0x0 -- Screen goes to white (clears)
|
||||
local WAVEFORM_MODE_DU = 0x1 -- Grey->white/grey->black
|
||||
local WAVEFORM_MODE_GC16 = 0x2 -- High fidelity (flashing)
|
||||
local WAVEFORM_MODE_GC4 = WAVEFORM_MODE_GC16 -- For compatibility
|
||||
local WAVEFORM_MODE_GC16_FAST = 0x3 -- Medium fidelity
|
||||
local WAVEFORM_MODE_A2 = 0x4 -- Faster but even lower fidelity
|
||||
local WAVEFORM_MODE_GL16 = 0x5 -- High fidelity from white transition
|
||||
local WAVEFORM_MODE_GL16_FAST = 0x6 -- Medium fidelity from white transition
|
||||
local WAVEFORM_MODE_AUTO = 0x101
|
||||
|
||||
local WAVEFORM_MODE_INIT = 0x0 -- Screen goes to white (clears)
|
||||
local WAVEFORM_MODE_DU = 0x1 -- Grey->white/grey->black
|
||||
local WAVEFORM_MODE_GC16 = 0x2 -- High fidelity (flashing)
|
||||
local WAVEFORM_MODE_GC4 = WAVEFORM_MODE_GC16 -- For compatibility
|
||||
local WAVEFORM_MODE_GC16_FAST = 0x3 -- Medium fidelity
|
||||
local WAVEFORM_MODE_A2 = 0x4 -- Faster but even lower fidelity
|
||||
local WAVEFORM_MODE_GL16 = 0x5 -- High fidelity from white transition
|
||||
local WAVEFORM_MODE_GL16_FAST = 0x6 -- Medium fidelity from white transition
|
||||
local WAVEFORM_MODE_AUTO = 0x101
|
||||
|
||||
-- there is only one instance of this
|
||||
local UIManager = {
|
||||
default_refresh_type = 0, -- 0 for partial refresh, 1 for full refresh
|
||||
@ -42,7 +42,8 @@ local UIManager = {
|
||||
_running = true,
|
||||
_window_stack = {},
|
||||
_execution_stack = {},
|
||||
_dirty = {}
|
||||
_dirty = {},
|
||||
_zeromqs = {},
|
||||
}
|
||||
|
||||
-- For the Kobo Aura an offset is needed, because the bezel make the visible screen smaller.
|
||||
@ -139,9 +140,26 @@ function UIManager:setDirty(widget, refresh_type)
|
||||
self._dirty[widget] = refresh_type
|
||||
end
|
||||
|
||||
function UIManager:insertZMQ(zeromq)
|
||||
table.insert(self._zeromqs, zeromq)
|
||||
return zeromq
|
||||
end
|
||||
|
||||
function UIManager:removeZMQ(zeromq)
|
||||
for i = #self._zeromqs, 1, -1 do
|
||||
if self._zeromqs[i] == zeromq then
|
||||
table.remove(self._zeromqs, i)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- signal to quit
|
||||
function UIManager:quit()
|
||||
self._running = false
|
||||
for i = #self._zeromqs, 1, -1 do
|
||||
self._zeromqs[i]:stop()
|
||||
table.remove(self._zeromqs, i)
|
||||
end
|
||||
end
|
||||
|
||||
-- transmit an event to registered widgets
|
||||
@ -216,6 +234,7 @@ function UIManager:run()
|
||||
-- stop when we have no window to show
|
||||
if #self._window_stack == 0 then
|
||||
DEBUG("no dialog left to show, would loop endlessly")
|
||||
self:quit()
|
||||
return nil
|
||||
end
|
||||
|
||||
@ -295,8 +314,19 @@ function UIManager:run()
|
||||
-- note that we will skip that if in the meantime we have tasks that are ready to run
|
||||
local input_event = nil
|
||||
if not wait_until then
|
||||
-- no pending task, wait endlessly
|
||||
input_event = Input:waitEvent()
|
||||
if #self._zeromqs > 0 then
|
||||
-- pending message queue, wait 100ms for input
|
||||
input_event = Input:waitEvent(1000*100)
|
||||
if input_event and input_event.handler == "onInputError" then
|
||||
for _, zeromq in ipairs(self._zeromqs) do
|
||||
input_event = zeromq:waitEvent()
|
||||
if input_event then break end
|
||||
end
|
||||
end
|
||||
else
|
||||
-- no pending task, wait endlessly
|
||||
input_event = Input:waitEvent()
|
||||
end
|
||||
elseif wait_until[1] > now[1]
|
||||
or wait_until[1] == now[1] and wait_until[2] > now[2] then
|
||||
local wait_for = { s = wait_until[1] - now[1], us = wait_until[2] - now[2] }
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 995dbe75d9a5325ce93cd04486b0a1fe20143197
|
||||
Subproject commit 7108ec4fd145d32d7abe32c25f5811001f5f570c
|
6
plugins/zsync.koplugin/client.cfg
Normal file
6
plugins/zsync.koplugin/client.cfg
Normal file
@ -0,0 +1,6 @@
|
||||
# Configure server for plain access
|
||||
#
|
||||
client
|
||||
heartbeat = 1 # Interval in seconds
|
||||
resync = 1
|
||||
|
369
plugins/zsync.koplugin/main.lua
Normal file
369
plugins/zsync.koplugin/main.lua
Normal file
@ -0,0 +1,369 @@
|
||||
local FileManagerHistory = require("apps/filemanager/filemanagerhistory")
|
||||
local FileManagerMenu = require("apps/filemanager/filemanagermenu")
|
||||
local InputContainer = require("ui/widget/container/inputcontainer")
|
||||
local FrameContainer = require("ui/widget/container/framecontainer")
|
||||
local FileManager = require("apps/filemanager/filemanager")
|
||||
local VerticalGroup = require("ui/widget/verticalgroup")
|
||||
local VerticalSpan = require("ui/widget/verticalspan")
|
||||
local ButtonDialog = require("ui/widget/buttondialog")
|
||||
local FileChooser = require("ui/widget/filechooser")
|
||||
local InfoMessage = require("ui/widget/infomessage")
|
||||
local TextWidget = require("ui/widget/textwidget")
|
||||
local DocSettings = require("docsettings")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local Screen = require("ui/screen")
|
||||
local Event = require("ui/event")
|
||||
local Font = require("ui/font")
|
||||
local DEBUG = require("dbg")
|
||||
local _ = require("gettext")
|
||||
local util = require("ffi/util")
|
||||
-- lfs
|
||||
|
||||
local ffi = require("ffi")
|
||||
ffi.cdef[[
|
||||
int remove(const char *);
|
||||
int rmdir(const char *);
|
||||
]]
|
||||
|
||||
local dummy = require("ffi/zeromq_h")
|
||||
local ZSync = InputContainer:new{
|
||||
}
|
||||
|
||||
function ZSync:init()
|
||||
self.ui.menu:registerToMainMenu(self)
|
||||
self.outbox = self.path.."/outbox"
|
||||
self.server_config = self.path.."/server.cfg"
|
||||
self.client_config = self.path.."/client.cfg"
|
||||
end
|
||||
|
||||
function ZSync:addToMainMenu(tab_item_table)
|
||||
table.insert(tab_item_table.plugins, {
|
||||
text = _("ZSync"),
|
||||
sub_item_table = {
|
||||
{
|
||||
text_func = function()
|
||||
return not self.filemq_server
|
||||
and _("Publish this document")
|
||||
or _("Stop publisher")
|
||||
end,
|
||||
enabled_func = function()
|
||||
return self.filemq_client == nil
|
||||
end,
|
||||
callback = function()
|
||||
if not self.filemq_server then
|
||||
self:publish()
|
||||
else
|
||||
self:unpublish()
|
||||
end
|
||||
end
|
||||
},
|
||||
{
|
||||
text_func = function()
|
||||
return not self.filemq_client
|
||||
and _("Subscribe documents")
|
||||
or _("Stop subscriber")
|
||||
end,
|
||||
enabled_func = function()
|
||||
return self.filemq_server == nil
|
||||
end,
|
||||
callback = function()
|
||||
if not self.filemq_client then
|
||||
self:subscribe()
|
||||
else
|
||||
self:unsubscribe()
|
||||
end
|
||||
end
|
||||
}
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
function ZSync:initServerZyreMQ()
|
||||
local ZyreMessageQueue = require("ui/message/zyremessagequeue")
|
||||
if self.zyre_messagequeue == nil then
|
||||
self.server_zyre = ZyreMessageQueue:new{
|
||||
header = {["FILEMQ-SERVER"] = tostring(self.fmq_port)},
|
||||
}
|
||||
self.server_zyre:start()
|
||||
self.zyre_messagequeue = UIManager:insertZMQ(self.server_zyre)
|
||||
end
|
||||
end
|
||||
|
||||
function ZSync:initClientZyreMQ()
|
||||
local ZyreMessageQueue = require("ui/message/zyremessagequeue")
|
||||
if self.zyre_messagequeue == nil then
|
||||
self.client_zyre = ZyreMessageQueue:new{}
|
||||
self.client_zyre:start()
|
||||
self.zyre_messagequeue = UIManager:insertZMQ(self.client_zyre)
|
||||
end
|
||||
end
|
||||
|
||||
function ZSync:initServerFileMQ(outboxes)
|
||||
local FileMessageQueue = require("ui/message/filemessagequeue")
|
||||
local filemq = ffi.load("libs/libfmq.so.1")
|
||||
if self.file_messagequeue == nil then
|
||||
self.filemq_server = filemq.fmq_server_new()
|
||||
self.file_messagequeue = UIManager:insertZMQ(FileMessageQueue:new{
|
||||
server = self.filemq_server
|
||||
})
|
||||
self.fmq_port = filemq.fmq_server_bind(self.filemq_server, "tcp://*:*")
|
||||
filemq.fmq_server_configure(self.filemq_server, self.server_config)
|
||||
filemq.fmq_server_set_anonymous(self.filemq_server, true)
|
||||
end
|
||||
UIManager:scheduleIn(1, function()
|
||||
for _, outbox in ipairs(outboxes) do
|
||||
DEBUG("publish", outbox.path, outbox.alias)
|
||||
filemq.fmq_server_publish(self.filemq_server, outbox.path, outbox.alias)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function ZSync:initClientFileMQ(inbox)
|
||||
local FileMessageQueue = require("ui/message/filemessagequeue")
|
||||
local filemq = ffi.load("libs/libfmq.so.1")
|
||||
if self.file_messagequeue == nil then
|
||||
self.filemq_client = filemq.fmq_client_new()
|
||||
self.file_messagequeue = UIManager:insertZMQ(FileMessageQueue:new{
|
||||
client = self.filemq_client
|
||||
})
|
||||
filemq.fmq_client_configure(self.filemq_client, self.client_config)
|
||||
end
|
||||
UIManager:scheduleIn(1, function()
|
||||
filemq.fmq_client_set_inbox(self.filemq_client, inbox)
|
||||
end)
|
||||
end
|
||||
|
||||
local function clearDirectory(dir, rmdir)
|
||||
for f in lfs.dir(dir) do
|
||||
local path = dir.."/"..f
|
||||
local mode = lfs.attributes(path, "mode")
|
||||
if mode == "file" then
|
||||
ffi.C.remove(path)
|
||||
elseif mode == "directory" and f ~= "." and f ~= ".." then
|
||||
clearDirectory(path, true)
|
||||
end
|
||||
end
|
||||
if rmdir then
|
||||
ffi.C.rmdir(dir)
|
||||
end
|
||||
end
|
||||
|
||||
local function mklink(path, filename)
|
||||
local basename = filename:match(".*/(.*)") or filename
|
||||
local linkname = path .. "/" .. basename .. ".ln"
|
||||
local linkfile = io.open(linkname, "w")
|
||||
if linkfile then
|
||||
linkfile:write(filename .. "\n")
|
||||
linkfile:close()
|
||||
end
|
||||
end
|
||||
|
||||
function ZSync:getOutboxes(files)
|
||||
lfs.mkdir(self.outbox)
|
||||
clearDirectory(self.outbox)
|
||||
local outboxes = {}
|
||||
for _, filename in ipairs(files) do
|
||||
local mode = lfs.attributes(filename, "mode")
|
||||
if mode == "file" then
|
||||
mklink(self.outbox, filename)
|
||||
elseif mode == "directory" then
|
||||
local basename = filename:match(".*/(.*)") or filename
|
||||
table.insert(outboxes, {
|
||||
path = filename,
|
||||
alias = "/" .. basename,
|
||||
})
|
||||
end
|
||||
end
|
||||
table.insert(outboxes, {
|
||||
path = self.outbox,
|
||||
alias = "/",
|
||||
})
|
||||
return outboxes
|
||||
end
|
||||
|
||||
function ZSync:publish()
|
||||
DEBUG("publish document", self.view.document.file)
|
||||
local file = self.view.document.file
|
||||
local outboxes = self:getOutboxes({file})
|
||||
-- init filemq first to get filemq port
|
||||
self:initServerFileMQ(outboxes)
|
||||
self:initServerZyreMQ()
|
||||
end
|
||||
|
||||
function ZSync:unpublish()
|
||||
DEBUG("ZSync unpublish")
|
||||
clearDirectory(self.outbox)
|
||||
self:stopZyreMQ()
|
||||
self:stopFileMQ()
|
||||
end
|
||||
|
||||
local InboxChooser = InputContainer:new{
|
||||
title = _("Choose inbox"),
|
||||
dimen = Screen:getSize(),
|
||||
exclude_dirs = {"%.sdr$"},
|
||||
}
|
||||
|
||||
function InboxChooser:init()
|
||||
self.show_parent = self.show_parent or self
|
||||
local banner = VerticalGroup:new{
|
||||
TextWidget:new{
|
||||
face = Font:getFace("tfont", 24),
|
||||
text = _("Choose inbox"),
|
||||
},
|
||||
VerticalSpan:new{ width = Screen:scaleByDPI(10) }
|
||||
}
|
||||
|
||||
local g_show_hidden = G_reader_settings:readSetting("show_hidden")
|
||||
local show_hidden = g_show_hidden == nil and DSHOWHIDDENFILES or g_show_hidden
|
||||
local root_path = G_reader_settings:readSetting("lastdir") or lfs.currentdir()
|
||||
local file_chooser = FileChooser:new{
|
||||
-- remeber to adjust the height when new item is added to the group
|
||||
path = root_path,
|
||||
show_parent = self.show_parent,
|
||||
show_hidden = show_hidden,
|
||||
height = Screen:getHeight() - banner:getSize().h,
|
||||
is_popout = false,
|
||||
is_borderless = true,
|
||||
dir_filter = function(dirname)
|
||||
for _, pattern in ipairs(self.exclude_dirs) do
|
||||
if dirname:match(pattern) then return end
|
||||
end
|
||||
return true
|
||||
end,
|
||||
file_filter = function(filename) end,
|
||||
close_callback = function() UIManager:close(self) end,
|
||||
}
|
||||
|
||||
local on_close_chooser = function() self:onClose() end
|
||||
local on_confirm_inbox = function(inbox) self:onConfirm(inbox) end
|
||||
|
||||
function file_chooser:onFileHold(dir)
|
||||
self.chooser_dialog = self
|
||||
self.button_dialog = ButtonDialog:new{
|
||||
buttons = {
|
||||
{
|
||||
{
|
||||
text = _("Confirm"),
|
||||
callback = function()
|
||||
UIManager:close(self.button_dialog)
|
||||
on_confirm_inbox(dir)
|
||||
on_close_chooser()
|
||||
end,
|
||||
},
|
||||
{
|
||||
text = _("Cancel"),
|
||||
callback = function()
|
||||
UIManager:close(self.button_dialog)
|
||||
on_close_chooser()
|
||||
end,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
UIManager:show(self.button_dialog)
|
||||
return true
|
||||
end
|
||||
|
||||
self[1] = FrameContainer:new{
|
||||
padding = 0,
|
||||
bordersize = 0,
|
||||
background = 0,
|
||||
VerticalGroup:new{
|
||||
banner,
|
||||
file_chooser,
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
function InboxChooser:onClose()
|
||||
UIManager:close(self)
|
||||
return true
|
||||
end
|
||||
|
||||
function InboxChooser:onConfirm(inbox)
|
||||
if inbox:sub(-3, -1) == "/.." then
|
||||
inbox = inbox:sub(1, -4)
|
||||
end
|
||||
G_reader_settings:saveSetting("lastdir", inbox)
|
||||
self.zsync:onChooseInbox(inbox)
|
||||
return true
|
||||
end
|
||||
|
||||
function ZSync:onChooseInbox(inbox)
|
||||
DEBUG("choose inbox", inbox)
|
||||
self.inbox = inbox
|
||||
-- init zyre first for filemq endpoint
|
||||
self:initClientZyreMQ()
|
||||
self:initClientFileMQ(inbox)
|
||||
return true
|
||||
end
|
||||
|
||||
function ZSync:subscribe()
|
||||
DEBUG("subscribe documents")
|
||||
self.inbox_chooser = InboxChooser:new{zsync = self}
|
||||
UIManager:show(self.inbox_chooser)
|
||||
end
|
||||
|
||||
function ZSync:unsubscribe()
|
||||
DEBUG("ZSync unsubscribe")
|
||||
self:stopFileMQ()
|
||||
self:stopZyreMQ()
|
||||
end
|
||||
|
||||
function ZSync:onZyreEnter(id, name, header, endpoint)
|
||||
local filemq = ffi.load("libs/libfmq.so.1")
|
||||
if header and endpoint and header["FILEMQ-SERVER"] then
|
||||
self.server_zyre_endpoint = endpoint
|
||||
local port = header["FILEMQ-SERVER"]
|
||||
local host = endpoint:match("(.*:)") or "*:"
|
||||
local fmq_server_endpoint = host..port
|
||||
DEBUG("connect filemq server at", fmq_server_endpoint)
|
||||
-- wait for filemq server setup befor connecting
|
||||
UIManager:scheduleIn(2, function()
|
||||
filemq.fmq_client_set_resync(self.filemq_client, true)
|
||||
filemq.fmq_client_subscribe(self.filemq_client, "/")
|
||||
filemq.fmq_client_connect(self.filemq_client, fmq_server_endpoint)
|
||||
end)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function ZSync:onFileDeliver(filename, fullname)
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = _("Received file:") .. "\n" .. filename,
|
||||
timeout = 1,
|
||||
})
|
||||
end
|
||||
|
||||
--[[
|
||||
-- We assume that ZSync is running in either server mode or client mode
|
||||
-- but never both. The zyre_messagequeue may be a server_zyre or client_zyre.
|
||||
-- And the file_messagequeue may be a filemq_server or filemq_client.
|
||||
--]]
|
||||
function ZSync:stopZyreMQ()
|
||||
if self.zyre_messagequeue then
|
||||
self.zyre_messagequeue:stop()
|
||||
UIManager:removeZMQ(self.zyre_messagequeue)
|
||||
self.zyre_messagequeue = nil
|
||||
self.server_zyre = nil
|
||||
self.client_zyre = nil
|
||||
end
|
||||
end
|
||||
|
||||
function ZSync:stopFileMQ()
|
||||
if self.file_messagequeue then
|
||||
self.file_messagequeue:stop()
|
||||
UIManager:removeZMQ(self.file_messagequeue)
|
||||
self.file_messagequeue = nil
|
||||
self.filemq_server = nil
|
||||
self.filemq_client = nil
|
||||
end
|
||||
end
|
||||
|
||||
function ZSync:onCloseReader()
|
||||
self:stopZyreMQ()
|
||||
self:stopFileMQ()
|
||||
end
|
||||
|
||||
return ZSync
|
||||
|
9
plugins/zsync.koplugin/server.cfg
Normal file
9
plugins/zsync.koplugin/server.cfg
Normal file
@ -0,0 +1,9 @@
|
||||
# Configure server to allow anonymous access
|
||||
#
|
||||
server
|
||||
monitor = 1 # Check mount points
|
||||
heartbeat = 1 # Heartbeat to clients
|
||||
|
||||
security
|
||||
echo = I: server accepts anonymous access
|
||||
anonymous = 1
|
10
reader.lua
10
reader.lua
@ -24,13 +24,14 @@ if lang_locale then
|
||||
_.changeLang(lang_locale)
|
||||
end
|
||||
|
||||
local DocumentRegistry = require("document/documentregistry")
|
||||
local FileManager = require("apps/filemanager/filemanager")
|
||||
local InfoMessage = require("ui/widget/infomessage")
|
||||
local UIManager = require("ui/uimanager")
|
||||
local Menu = require("ui/widget/menu")
|
||||
local InfoMessage = require("ui/widget/infomessage")
|
||||
local DocumentRegistry = require("document/documentregistry")
|
||||
local DEBUG = require("dbg")
|
||||
local Device = require("ui/device")
|
||||
local Screen = require("ui/screen")
|
||||
local DEBUG = require("dbg")
|
||||
|
||||
local ReaderUI = require("apps/reader/readerui")
|
||||
|
||||
@ -98,12 +99,11 @@ function doShowReaderUI(file, pass)
|
||||
end
|
||||
|
||||
function showHomePage(path)
|
||||
local FileManager = require("apps/filemanager/filemanager")
|
||||
G_reader_settings:saveSetting("lastdir", path)
|
||||
UIManager:show(FileManager:new{
|
||||
dimen = Screen:getSize(),
|
||||
root_path = path,
|
||||
onExit = function()
|
||||
exitReader()
|
||||
UIManager:quit()
|
||||
end
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user