mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
TouchMenu: added options to menu items with the following defaults:
keep_menu_open = false
hold_keep_menu_open = true
So, default for Tap callback is to close menu, and for Hold callback
to keep menu open.
In both cases, provide the TouchMenu instance as the 1st argument to
the callback functions (instead of a refresh_menu_func I added in #3941)
so the callback can do more things, like closing, refreshing,
changing menu items text and re-ordering...
ReaderZooming: show symbol for default (like it was done for
ReaderFont, ReaderHyphenation...)
TextEditor plugin: update the previously opened files list in real
time, so the menu can be kept open and used as the TextEditor main
interface.
SSH plugin: keep menu open and update the Start/Stop state in real time
ReadTimer plugin: tried to do what feels right (but I don't use it)
Also remove forgotten cp in the move/paste file code
276 lines
8.0 KiB
Lua
276 lines
8.0 KiB
Lua
local Device = require("device")
|
|
local KeyValuePage = require("ui/widget/keyvaluepage")
|
|
local UIManager = require("ui/uimanager")
|
|
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
|
local util = require("util")
|
|
local _ = require("gettext")
|
|
|
|
local SystemStat = {
|
|
start_sec = os.time(),
|
|
suspend_sec = nil,
|
|
resume_sec = nil,
|
|
wakeup_count = 0,
|
|
sleep_count = 0,
|
|
charge_count = 0,
|
|
discharge_count = 0,
|
|
}
|
|
|
|
function SystemStat:init()
|
|
if Device:isKobo() or Device:isPocketBook() then
|
|
self.storage_filter = "mmcblk"
|
|
elseif Device:isKindle() then
|
|
self.storage_filter = "' /mnt/us$'"
|
|
elseif Device:isSDL() then
|
|
self.storage_filter = "/dev/sd"
|
|
end
|
|
end
|
|
|
|
function SystemStat:put(p)
|
|
table.insert(self.kv_pairs, p)
|
|
end
|
|
|
|
function SystemStat:appendCounters()
|
|
self:put({_("KOReader started at"), os.date("%c", self.start_sec)})
|
|
if self.suspend_sec then
|
|
self:put({_(" Last suspend time"), os.date("%c", self.suspend_sec)})
|
|
end
|
|
if self.resume_sec then
|
|
self:put({_(" Last resume time"), os.date("%c", self.resume_sec)})
|
|
end
|
|
self:put({_(" Up hours"),
|
|
string.format("%.2f", os.difftime(os.time(), self.start_sec) / 60 / 60)})
|
|
self:put({_("Counters"), ""})
|
|
self:put({_(" wake-ups"), self.wakeup_count})
|
|
self:put({_(" sleeps"), self.sleep_count})
|
|
self:put({_(" charge cycles"), self.charge_count})
|
|
self:put({_(" discharge cycles"), self.discharge_count})
|
|
end
|
|
|
|
local function systemInfo()
|
|
local result = {}
|
|
do
|
|
local stat = io.open("/proc/stat", "r")
|
|
if stat ~= nil then
|
|
for line in util.gsplit(stat:read("*all"), "\n", false) do
|
|
local t = util.splitToArray(line, " ")
|
|
if #t >= 5 and string.lower(t[1]) == "cpu" then
|
|
local n1, n2, n3, n4
|
|
n1 = tonumber(t[2])
|
|
n2 = tonumber(t[3])
|
|
n3 = tonumber(t[4])
|
|
n4 = tonumber(t[5])
|
|
if n1 ~= nil and n2 ~= nil and n3 ~= nil and n4 ~= nil then
|
|
result.cpu = {
|
|
user = n1,
|
|
nice = n2,
|
|
system = n3,
|
|
idle = n4,
|
|
total = n1 + n2 + n3 + n4
|
|
}
|
|
break
|
|
end
|
|
end
|
|
end
|
|
stat:close()
|
|
end
|
|
end
|
|
|
|
do
|
|
local meminfo = io.open("/proc/meminfo", "r")
|
|
if meminfo ~= nil then
|
|
result.memory = {}
|
|
for line in util.gsplit(meminfo:read("*all"), "\n", false) do
|
|
local t = util.splitToArray(line, " ")
|
|
if #t >= 2 then
|
|
if string.lower(t[1]) == "memtotal:" then
|
|
local n = tonumber(t[2])
|
|
if n ~= nil then
|
|
result.memory.total = n
|
|
end
|
|
elseif string.lower(t[1]) == "memfree:" then
|
|
local n = tonumber(t[2])
|
|
if n ~= nil then
|
|
result.memory.free = n
|
|
end
|
|
elseif string.lower(t[1]) == "memavailable:" then
|
|
local n = tonumber(t[2])
|
|
if n ~= nil then
|
|
result.memory.available = n
|
|
end
|
|
end
|
|
end
|
|
end
|
|
meminfo:close()
|
|
end
|
|
end
|
|
return result
|
|
end
|
|
|
|
function SystemStat:appendSystemInfo()
|
|
local stat = systemInfo()
|
|
if stat.cpu ~= nil then
|
|
self:put({_("System information"), ""})
|
|
self:put({_(" Total ticks (million)"),
|
|
string.format("%.2f", stat.cpu.total / 1000000)})
|
|
self:put({_(" Idle ticks (million)"),
|
|
string.format("%.2f", stat.cpu.idle / 1000000)})
|
|
self:put({_(" Processor usage %"),
|
|
string.format("%.2f", (1 - stat.cpu.idle / stat.cpu.total) * 100)})
|
|
end
|
|
if stat.memory ~= nil then
|
|
if stat.memory.total ~= nil then
|
|
self:put({_(" Total memory (MB)"),
|
|
string.format("%.2f", stat.memory.total / 1024)})
|
|
end
|
|
if stat.memory.free ~= nil then
|
|
self:put({_(" Free memory (MB)"),
|
|
string.format("%.2f", stat.memory.free / 1024)})
|
|
end
|
|
if stat.memory.available ~= nil then
|
|
self:put({_(" Available memory (MB)"),
|
|
string.format("%.2f", stat.memory.available / 1024)})
|
|
end
|
|
end
|
|
end
|
|
|
|
function SystemStat:appendProcessInfo()
|
|
local stat = io.open("/proc/self/stat", "r")
|
|
if stat == nil then return end
|
|
|
|
local t = util.splitToArray(stat:read("*all"), " ")
|
|
stat:close()
|
|
|
|
local n1, n2
|
|
|
|
if #t == 0 then return end
|
|
self:put({_("Process"), ""})
|
|
|
|
self:put({_(" ID"), t[1]})
|
|
|
|
if #t < 14 then return end
|
|
n1 = tonumber(t[14])
|
|
n2 = tonumber(t[15])
|
|
if n1 ~= nil then
|
|
if n2 ~= nil then
|
|
n1 = n1 + n2
|
|
end
|
|
local sys_stat = systemInfo()
|
|
if sys_stat.cpu ~= nil and sys_stat.cpu.total ~= nil then
|
|
self:put({_(" Processor usage %"),
|
|
string.format("%.2f", n1 / sys_stat.cpu.total * 100)})
|
|
else
|
|
self:put({_(" Processor usage ticks (million)"), n1 / 1000000})
|
|
end
|
|
end
|
|
|
|
if #t < 20 then return end
|
|
n1 = tonumber(t[20])
|
|
if n1 ~= nil then
|
|
self:put({_(" Threads"), tostring(n1)})
|
|
end
|
|
|
|
if #t < 23 then return end
|
|
n1 = tonumber(t[23])
|
|
if n1 ~= nil then
|
|
self:put({_(" Virtual memory (MB)"), string.format("%.2f", n1 / 1024 / 1024)})
|
|
end
|
|
|
|
if #t < 24 then return end
|
|
n1 = tonumber(t[24])
|
|
if n1 ~= nil then
|
|
self:put({_(" RAM usage (MB)"), string.format("%.2f", n1 / 256)})
|
|
end
|
|
end
|
|
|
|
function SystemStat:appendStorageInfo()
|
|
if self.storage_filter == nil then return end
|
|
|
|
local std_out = io.popen(
|
|
"df -h | sed -r 's/ +/ /g' | grep " .. self.storage_filter ..
|
|
" | sed 's/ /\\t/g' | cut -f 2,4,5,6"
|
|
)
|
|
if not std_out then return end
|
|
|
|
self:put({_("Storage information"), ""})
|
|
for line in util.gsplit(std_out:read("*all"), "\n", false) do
|
|
local t = util.splitToArray(line, "\t")
|
|
if #t ~= 4 then
|
|
self:put({_(" Unexpected"), line})
|
|
else
|
|
self:put({_(" Mount point"), t[4]})
|
|
self:put({_(" Available"), t[2]})
|
|
self:put({_(" Total"), t[1]})
|
|
self:put({_(" Used percentage"), t[3]})
|
|
end
|
|
end
|
|
std_out:close()
|
|
end
|
|
|
|
function SystemStat:onSuspend()
|
|
self.suspend_sec = os.time()
|
|
self.sleep_count = self.sleep_count + 1
|
|
end
|
|
|
|
function SystemStat:onResume()
|
|
self.resume_sec = os.time()
|
|
self.wakeup_count = self.wakeup_count + 1
|
|
end
|
|
|
|
function SystemStat:onCharging()
|
|
self.charge_count = self.charge_count + 1
|
|
end
|
|
|
|
function SystemStat:onNotCharging()
|
|
self.discharge_count = self.discharge_count + 1
|
|
end
|
|
|
|
function SystemStat:showStatistics()
|
|
self.kv_pairs = {}
|
|
self:appendCounters()
|
|
self:appendProcessInfo()
|
|
self:appendStorageInfo()
|
|
self:appendSystemInfo()
|
|
UIManager:show(KeyValuePage:new{
|
|
title = _("System statistics"),
|
|
kv_pairs = self.kv_pairs,
|
|
})
|
|
end
|
|
|
|
SystemStat:init()
|
|
|
|
local SystemStatWidget = WidgetContainer:new{
|
|
name = "systemstat",
|
|
}
|
|
|
|
function SystemStatWidget:init()
|
|
self.ui.menu:registerToMainMenu(self)
|
|
end
|
|
|
|
function SystemStatWidget:addToMainMenu(menu_items)
|
|
menu_items.system_statistics = {
|
|
text = _("System statistics"),
|
|
keep_menu_open = true,
|
|
callback = function()
|
|
SystemStat:showStatistics()
|
|
end,
|
|
}
|
|
end
|
|
|
|
function SystemStatWidget:onSuspend()
|
|
SystemStat:onSuspend()
|
|
end
|
|
|
|
function SystemStatWidget:onResume()
|
|
SystemStat:onResume()
|
|
end
|
|
|
|
function SystemStatWidget:onCharging()
|
|
SystemStat:onCharging()
|
|
end
|
|
|
|
function SystemStatWidget:onNotCharging()
|
|
SystemStat:onNotCharging()
|
|
end
|
|
|
|
return SystemStatWidget
|