1 -- Authors: Antti Vähäkotamäki
2 -- License: LGPL, version 2.1 or later
10 -- This is a simple "general" statusd Lua script which
11 -- lets you show output of external programs in ion
12 -- statusbar. This is convenient if you are not familiar
13 -- with Lua but can handle yourself with some other
14 -- language enough to output what you would want the
17 -- After this script is loaded it starts executing all
18 -- the provided programs (wether a placeholder exists in
19 -- template or not) and updates the statusbar every time
20 -- one of them prints (and flushes) a line.
24 -- 1 ) update statusbar template to include %exec_something
25 -- 2 ) specify parameters in cfg_statusbar.lua like this:
27 -- mod_statusbar.launch_statusd{
29 -- [ ... some other config here ... ],
33 -- -- show date each second in %exec_date with.. date!
37 -- retry_delay = 1 * 1000,
40 -- -- show percentage of hda1 every 30 seconds in
41 -- -- %exec_hda1u with df, grep and sed.
42 -- -- also highlights entry if usage is high.
45 -- program = 'df|grep hda1|sed "s/.*\\(..%\\).*/\\1/"',
46 -- retry_delay = 30 * 1000,
49 -- important = '9[456].',
57 -- -- keep continous track of a remote machine in
58 -- -- %exec_remote with ssh, bash and uptime.
59 -- -- if the connection breaks, wait 60 seconds and retry
62 -- program = 'ssh -tt myhost.com "while (uptime);' ..
63 -- 'do sleep 1; done"',
64 -- retry_delay = 60 * 1000,
69 -- -- Description of variables:
72 -- The program to execute. The last line of each
73 -- flushed output this program writes to stdout is
74 -- inserted as the content of the meter.
76 -- * retry_delay (optional)
77 -- The delay to wait (ms) before running the program again
78 -- once it stops sending data. Some programs just
79 -- send the data and exit while others continue
80 -- sending data periodically. This value can be used
81 -- to control the update rate for the first type of
82 -- programs. You can also specify a value for the other
83 -- type of programs to retry if the program stops for
86 -- * meter_length (optional)
87 -- The space reserved for this meter in characters.
88 -- If the value is not specified or is less than 1
89 -- then the space is determined by the length of the
90 -- data being shown but some people do not want their
91 -- statusbar width to change randomly.
93 -- * hint_regexp (optional)
94 -- These regular expressions (in Lua syntax) are
95 -- matched with the data and in case of a match the
96 -- named hint is set to the meter. The value can be
97 -- either a string containing the regexp or a table
98 -- containing several possible regexps (Lua regexp
99 -- doesn't have an 'or'). By default the themes define
100 -- a color for 'important' and 'critical' hints.
104 local settings
= table.join( statusd
.get_config("exec"), {} )
105 local start_execution
= nil
108 -- Function for starting and restarting execution of a process
110 start_execution
= function ( key
)
112 -- Set up a function for receiving the data
113 -- and informing the statusbar
115 local process_input
= function ( new_data
)
117 local received_data
= ""
119 -- When we get new data, output the last complete line
122 received_data
= received_data
.. new_data
124 -- Erase old data which we do not need anymore
126 received_data
= string.gsub( received_data
,
127 ".*\n(.*\n.*)", "%1" )
129 -- Set the last complete line as the current line
131 local current_line
= string.gsub( received_data
,
134 local t_key
= "exec_" .. key
135 local t_length
= settings
[key
].meter_length
136 local h_regexp
= settings
[key
].hint_regexp
138 if not tlength
or t_length
< 1 then
139 t_length
= string.len( current_line
)
142 statusd
.inform( t_key
.. "_hint", '' )
143 statusd
.inform( t_key
.. "_template",
144 string.rep( 'x', t_length
) )
145 statusd
.inform( t_key
, current_line
)
147 if not h_regexp
then h_regexp
= {} end
149 for hint
, re
in pairs( h_regexp
) do
150 if ( type( re
) == 'string' ) then
154 for _
, r
in ipairs( re
) do
155 if ( string.find( current_line
, r
) ) then
156 statusd
.inform(t_key
.. "_hint", hint
)
161 -- Wait for bgread to signal that more data
162 -- is available or the program has exited
164 new_data
= coroutine
.yield()
167 -- Program has exited.
168 -- Start a timer for a new execution if set.
170 if settings
[key
].retry_delay
then
171 timers
[key
]:set( settings
[key
].retry_delay
,
178 -- Set up a simple function for printing errors
180 local process_error
= function( new_data
)
182 io
.stderr
:write( "ion-statusd [statusd_exec, key='"
183 .. key
.. "']: " .. new_data
)
185 new_data
= coroutine
.yield()
189 -- Execute the program in the background and create
190 -- coroutine functions to handle input and error data
192 statusd
.popen_bgread( settings
[key
].program
,
193 coroutine
.wrap( process_input
),
194 coroutine
.wrap( process_error
) )
198 -- Now start execution of all defined processes
200 for key
in pairs(settings
) do
201 timers
[key
] = statusd
.create_timer()
206 -- Copyright (c) Antti Vähäkotamäki 2006.
208 -- Ion is free software; you can redistribute it and/or modify it under
209 -- the terms of the GNU Lesser General Public License as published by
210 -- the Free Software Foundation; either version 2.1 of the License, or
211 -- (at your option) any later version.