mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
This is a major overhaul of the hardware abstraction layer. A few notes: General platform distinction happens in frontend/device.lua which will delegate everything else to frontend/device/<platform_name>/device.lua which should extend frontend/device/generic/device.lua Screen handling is implemented in frontend/device/screen.lua which includes the *functionality* to support device specifics. Actually setting up the device specific functionality, however, is done in the device specific setup code in the relevant device.lua file. The same goes for input handling.
210 lines
6.6 KiB
Lua
210 lines
6.6 KiB
Lua
local InfoMessage = require("ui/widget/infomessage")
|
|
local ConfirmBox = require("ui/widget/confirmbox")
|
|
local NetworkMgr = require("ui/networkmgr")
|
|
local lfs = require("libs/libkoreader-lfs")
|
|
local UIManager = require("ui/uimanager")
|
|
local Device = require("device")
|
|
local DEBUG = require("dbg")
|
|
local _ = require("gettext")
|
|
|
|
local OTAManager = {
|
|
ota_servers = {
|
|
"http://vislab.bjmu.edu.cn:80/apps/koreader/ota/",
|
|
"http://koreader.ak-team.com:80/",
|
|
"http://hal9k.ifsc.usp.br:80/koreader/",
|
|
},
|
|
ota_channels = {
|
|
"nightly",
|
|
},
|
|
zsync_template = "koreader-%s-latest-%s.zsync",
|
|
installed_package = "ota/koreader.installed.tar",
|
|
package_indexfile = "ota/package.index",
|
|
updated_package = "ota/koreader.updated.tar",
|
|
}
|
|
|
|
function OTAManager:getOTAModel()
|
|
if Device:isKindle() then
|
|
return "kindle"
|
|
elseif Device:isKobo() then
|
|
return "kobo"
|
|
else
|
|
return ""
|
|
end
|
|
end
|
|
|
|
function OTAManager:getOTAServer()
|
|
return G_reader_settings:readSetting("ota_server") or self.ota_servers[1]
|
|
end
|
|
|
|
function OTAManager:setOTAServer(server)
|
|
DEBUG("Set OTA server:", server)
|
|
G_reader_settings:saveSetting("ota_server", server)
|
|
end
|
|
|
|
function OTAManager:getOTAChannel()
|
|
return G_reader_settings:readSetting("ota_channel") or self.ota_channels[1]
|
|
end
|
|
|
|
function OTAManager:setOTAChannel(channel)
|
|
DEBUG("Set OTA channel:", channel)
|
|
G_reader_settings:saveSetting("ota_channel", channel)
|
|
end
|
|
|
|
function OTAManager:getZsyncFilename()
|
|
return self.zsync_template:format(self:getOTAModel(), self:getOTAChannel())
|
|
end
|
|
|
|
function OTAManager:checkUpdate()
|
|
local http = require("socket.http")
|
|
local ltn12 = require("ltn12")
|
|
|
|
local zsync_file = self:getZsyncFilename()
|
|
local ota_zsync_file = self:getOTAServer() .. zsync_file
|
|
local local_zsync_file = "ota/" .. zsync_file
|
|
-- download zsync file from OTA server
|
|
local r, c, h = http.request{
|
|
url = ota_zsync_file,
|
|
sink = ltn12.sink.file(io.open(local_zsync_file, "w"))}
|
|
-- prompt users to turn on Wifi if network is unreachable
|
|
if c ~= 200 then return end
|
|
-- parse OTA package version
|
|
local ota_package = nil
|
|
local zsync = io.open(local_zsync_file, "r")
|
|
if zsync then
|
|
for line in zsync:lines() do
|
|
ota_package = line:match("^Filename:%s*(.-)%s*$")
|
|
if ota_package then break end
|
|
end
|
|
zsync:close()
|
|
end
|
|
local local_version = io.open("git-rev", "r"):read()
|
|
local ota_version = nil
|
|
if ota_package then
|
|
ota_version = ota_package:match(".-(v%d.-)%.tar")
|
|
end
|
|
-- return ota package version if package on OTA server has version
|
|
-- larger than the local package version
|
|
if ota_version and ota_version > local_version then
|
|
return ota_version
|
|
elseif ota_version and ota_version == local_version then
|
|
return 0
|
|
end
|
|
end
|
|
|
|
function OTAManager:fetchAndProcessUpdate()
|
|
local ota_version = OTAManager:checkUpdate()
|
|
if ota_version == 0 then
|
|
UIManager:show(InfoMessage:new{
|
|
text = _("Your koreader is updated."),
|
|
})
|
|
elseif ota_version == nil then
|
|
UIManager:show(InfoMessage:new{
|
|
text = _("OTA server is not available."),
|
|
})
|
|
elseif ota_version then
|
|
UIManager:show(ConfirmBox:new{
|
|
text = _("Do you want to update to version ")..ota_version.."?",
|
|
ok_callback = function()
|
|
UIManager:show(InfoMessage:new{
|
|
text = _("Downloading may take several minutes..."),
|
|
timeout = 3,
|
|
})
|
|
UIManager:scheduleIn(1, function()
|
|
if OTAManager:zsync() == 0 then
|
|
UIManager:show(InfoMessage:new{
|
|
text = _("Koreader will be updated on next restart."),
|
|
})
|
|
else
|
|
UIManager:show(ConfirmBox:new{
|
|
text = _("Error updating Koreader. Would you like to delete temporary files?"),
|
|
ok_callback = function()
|
|
os.execute("rm ota/ko*")
|
|
end,
|
|
})
|
|
end
|
|
end)
|
|
end
|
|
})
|
|
end
|
|
end
|
|
|
|
function OTAManager:_buildLocalPackage()
|
|
-- TODO: validate the installed package?
|
|
local installed_package = lfs.currentdir() .. "/" .. self.installed_package
|
|
if lfs.attributes(installed_package, "mode") == "file" then
|
|
return 0
|
|
end
|
|
return os.execute(string.format(
|
|
"./tar cvf %s -C .. -T %s --no-recursion",
|
|
self.installed_package, self.package_indexfile))
|
|
end
|
|
|
|
function OTAManager:zsync()
|
|
if self:_buildLocalPackage() == 0 then
|
|
return os.execute(string.format(
|
|
"./zsync -i %s -o %s -u %s %s",
|
|
self.installed_package, self.updated_package,
|
|
self:getOTAServer(), "ota/" .. self:getZsyncFilename()
|
|
))
|
|
end
|
|
end
|
|
|
|
function OTAManager:genServerList()
|
|
local servers = {}
|
|
for _, server in ipairs(self.ota_servers) do
|
|
local server_item = {
|
|
text = server,
|
|
checked_func = function() return self:getOTAServer() == server end,
|
|
callback = function() self:setOTAServer(server) end
|
|
}
|
|
table.insert(servers, server_item)
|
|
end
|
|
return servers
|
|
end
|
|
|
|
function OTAManager:genChannelList()
|
|
local channels = {}
|
|
for _, channel in ipairs(self.ota_channels) do
|
|
local channel_item = {
|
|
text = channel,
|
|
checked_func = function() return self:getOTAChannel() == channel end,
|
|
callback = function() self:setOTAChannel(channel) end
|
|
}
|
|
table.insert(channels, channel_item)
|
|
end
|
|
return channels
|
|
end
|
|
|
|
function OTAManager:getOTAMenuTable()
|
|
return {
|
|
text = _("OTA update"),
|
|
sub_item_table = {
|
|
{
|
|
text = _("Check update"),
|
|
callback = function()
|
|
if NetworkMgr:getWifiStatus() == false then
|
|
NetworkMgr:promptWifiOn()
|
|
else
|
|
OTAManager.fetchAndProcessUpdate()
|
|
end
|
|
end
|
|
},
|
|
{
|
|
text = _("Settings"),
|
|
sub_item_table = {
|
|
{
|
|
text = _("OTA server"),
|
|
sub_item_table = self:genServerList()
|
|
},
|
|
{
|
|
text = _("OTA channel"),
|
|
sub_item_table = self:genChannelList()
|
|
},
|
|
}
|
|
},
|
|
}
|
|
}
|
|
end
|
|
|
|
return OTAManager
|