1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
|
-- Authors: Antti Vähäkotamäki
-- License: LGPL, version 2.1 or later
-- Last Changed: 2005
--
-- statusbar_external.lua
--
if not statusbar_external then
statusbar_external = {
-- a simple example which shows utc time and date
-- in %udate every second with 'date -u'
{
template_key = 'dateb',
external_program = 'date',
execute_delay = 1 * 1000,
},
{
template_key = 'udate',
external_program = 'date -u',
execute_delay = 5 * 1000,
},
-- a more complicated example showing the usage
-- percentage of hda1 every 30 seconds in %hda1u
-- with df, grep and sed.
{
template_key = 'hda1u',
external_program = 'df|grep hda1|sed "s/.*\\(..%\\).*/\\1/"',
execute_delay = 30 * 1000,
meter_length = 4,
hint_regexp = {
important = '9[456].',
critical = {
'9[789].',
'1...',
},
},
},
}
end
--
-- -- What is this?
--
-- This is a simple "general" statusbar lua script which
-- lets you show output of external programs in ion
-- statusbar. This is convenient if you are not familiar
-- with lua but can handle yourself with some other
-- language enough to output what you would want the
-- statusbar to show.
--
--
-- -- How to use it?
--
-- Short version:
--
-- 1 ) modify settings variable
-- 2 ) update template to include specified keys
-- 3 ) dopath( "statusbar_external" ) in cfg_user.lua
--
--
-- Longer version:
--
-- There is an example settings-variable which can be
-- modified to specify your own programs. The needed
-- parameters are the following :
--
-- * template_key
-- An unique name for the meter. You must add this
-- name with preceding % (for example %meter_name)
-- into your statusbar template which is usually set
-- in cfg_statusbar.lua.
--
-- * external_program
-- The program to execute. The last line of each
-- flushed output this program writes to stdout is
-- inserted as the content of the meter.
--
-- * execute_delay
-- The delay to wait before running the program again
-- once it stops sending data. Some programs just
-- send the data and exit while others continue
-- sending data periodically. This value can be used
-- to control the update rate for the first type of
-- programs.
--
-- * meter_length (optional)
-- The space reserved for this meter in characters.
-- If the value is not specified or is less than 1
-- then the space is determined by the length of the
-- data being shown but some people do not want their
-- statusbar width to change randomly.
--
-- * hint_regexp (optional)
-- These regular expressions (in Lua syntax) are
-- matched with the data and in case of a match the
-- named hint is set to the meter. The value can be
-- either a string containing the regexp or a table
-- containing several possible regexps (Lua regexp
-- doesn't have an 'or'). By default the themes define
-- a color for 'important' and 'critical' hints.
--
-- After this script is loaded it starts executing all
-- the provided programs and updates the statusbar every
-- time one of them prints (and flushes) something.
--
-- Also this is not a normal statusd script so it
-- doesn't get loaded by template name automatically
-- when ion starts. You must add
--
-- dopath( "statusbar_external" )
--
-- to some script that is being loaded in Ion. For
-- example ~/.ion3/cfg_user.lua is a good place. Note
-- that cfg_statusbar.lua is not loaded inside the
-- Ion process but in a separate process and thus this
-- script can not be loaded from that file!
--
--
---------------------------------------------------------
local timers = {}
local callbacks = {}
-- Just print out stderr for now.
local function flush_stderr(partial_data)
local result = ""
while partial_data do
result = result .. partial_data
-- Yield until we get more input. popen_bgread will call resume on us.
partial_data = coroutine.yield()
end
print(result, "\n")
end
-- Execute a program. This will continuously retrieve output from the program.
function start_execute(key)
-- Read output from the program and (if data) then update the statusbar
local handle_output_changes = coroutine.create(
function(input_data)
local key = input_data
local data = ""
local partial_data = ""
-- Keep reading data until we have it all
while partial_data do
data = data .. partial_data
-- Yield until we get more input.
-- popen_bgread will call resume on us.
partial_data = coroutine.yield()
end
-- If no updates, then just schedule another run
if not data or data == "" then
return timers[key]:set(statusbar_external[key].execute_delay,
callbacks[key])
end
-- remove all but the last line
data = string.gsub( data, "\n$", "" )
data = string.gsub( data, ".*\n", "" );
local sets = statusbar_external[key]
local t_key = sets.template_key
local t_length = sets.meter_length
local h_regexp = sets.hint_regexp
if not tlength or t_length < 1 then
t_length = string.len( data )
end
mod_statusbar.inform( t_key, data )
mod_statusbar.inform( t_key .. "_hint", '' )
mod_statusbar.inform(t_key .. "_template", string.rep( ' ', t_length))
if not h_regexp then h_regexp = {} end
for hint, re in pairs( h_regexp ) do
if ( type( re ) == 'string' ) then
re = { re }
end
for _, r in ipairs( re ) do
if ( string.find( data, r ) ) then
mod_statusbar.inform(t_key .. "_hint", hint)
end
end
end
mod_statusbar.update()
return timers[key]:set(statusbar_external[key].execute_delay,
callbacks[key])
end
)
-- We need to pass it the key before calling a background call.
coroutine.resume(handle_output_changes, key)
ioncore.popen_bgread(statusbar_external[key].external_program,
function(cor) coroutine.resume(handle_output_changes,
cor) end,
coroutine.wrap(flush_stderr))
end
-- Start all
for key in pairs(statusbar_external) do
timers[key] = ioncore.create_timer()
callbacks[key] = loadstring("start_execute("..key..")")
start_execute(key)
end
--
-- Copyright (c) Antti Vähäkotamäki 2005.
--
-- Ion is free software; you can redistribute it and/or modify it under
-- the terms of the GNU Lesser General Public License as published by
-- the Free Software Foundation; either version 2.1 of the License, or
-- (at your option) any later version.
--
|