Codebase list awesome-extra / bf7dd7b
Drop old bashets files Reiner Herrmann 5 years ago
2 changed file(s) with 0 addition(s) and 656 deletion(s). Raw diff Collapse all Expand all
+0
-228
bashets/bashets.lua.prev less more
0 ------------------------------------------------------------------
1 -- Bashets - use your shellscript's output in Awesome3 widgets
2 --
3 -- @author Anton Lobov <ahmad200512@yandex.ru>
4 -- @copyright 2009 Anton Lobov
5 -- @license GPLv2
6 -- @release 0.1aw3
7 -- @todo Non-text widget support: progressbar and graph
8 ------------------------------------------------------------------
9
10 -- Grab only needed enviroment
11 local awful = require("awful")
12 local string = string
13 local io = io
14 local table = table
15 local pairs = pairs
16 local coroutine = coroutine
17
18 --- Bashets module
19 module("bashets")
20
21 -- Default paths (could be altered by 'configure' script)
22 local script_path = "/usr/share/awesome/bashets/"
23 local tmp_folder = "/tmp/"
24
25 -- Utility functions table
26 local util = {}
27
28 --- Split string by separator into table
29 -- @param str String to split
30 -- @param sep Separator to use
31 function util.split(str, sep)
32 parts = {} --parts array
33 first = 1
34 ostart, oend = string.find(str, sep, first, true) --regexp disabled search
35
36 while ostart do
37 part = string.sub(str, first, ostart - 1)
38 table.insert(parts, part)
39 first = oend + 1
40 ostart, oend = string.find(str, sep, first, true)
41 end
42
43 part = string.sub(str, first)
44 table.insert(parts, part)
45
46 return parts
47 end
48
49 --- Execute a command and return it's output
50 -- @param script Script to execute
51 function util.exec(script)
52 local fh = io.popen(script)
53 local str = ""
54
55 -- Newlines are replaced with spaces
56 for i in fh:lines() do
57 str = str .. " " .. i
58 end
59
60 io.close(fh)
61 return str
62 end
63
64 --- Execute a command and write it's output to temporary file
65 -- @param script Script to execute
66 -- @param file File for script output
67 function util.exectmp(script, file)
68 -- Maybe there is a more elegant way to correctly execute commands
69 -- and do not hang Awesome?
70 --io.popen(script .. " > " .. file)
71 awful.util.spawn_with_shell(script .. " > " .. file)
72 end
73
74 --- Read temporary file to a single line
75 -- @param file File to be read
76 function util.readfile(file)
77 local fh = io.input(file)
78 local str = ""
79
80 -- Newlines are replaced with spaces
81 for i in fh:lines() do
82 str = str .. " " .. i
83 end
84
85 io.close(fh)
86 return str
87 end
88
89 --- Format script output with user defined format string
90 -- @param output sep-separated string of values
91 -- @param format Format string
92 -- @param sep Separator of values in string
93 function util.format(output, format, sep)
94 -- Delete leading space symbols
95 output = string.gsub(output, "^%s+", "")
96
97 -- Split script output
98 local parts = util.split(output, sep)
99
100 -- For each part with number "k" replace corresponding "$k" variable in format string
101 for k,part in pairs(parts) do
102 part = string.gsub(part, "%%", "%1%1") --percent fix for next gsub (bug found in Wicked)
103 format = string.gsub(format, "$" .. k, part)
104 end
105
106 return format
107 end
108
109 --- Format script output
110 -- @param script Script to execute
111 -- @param format Format string
112 -- @param sep Separator of values in string
113 function util.update(script, format, sep)
114 -- Execute script and format it's output
115 local output = util.exec(script)
116 output = util.format(output, format, sep)
117 return output
118 end
119
120 --- Format file contents (for async variant)
121 -- @param file File to format it's content
122 -- @param format Format string
123 -- @param sep Separator of values in string
124 function util.update_async(file, format, sep)
125 -- Read file and format it's contents
126 local output = util.readfile(file)
127
128 if string.len(output) > 0 then
129 output = util.format(output, format, sep)
130 end
131
132 return output
133 end
134
135
136 --- Register script for text widget
137 -- @param widget Widget to update
138 -- @param script Script to use it's output
139 -- @param format User-defined format string (optional)
140 -- @param updtime Update time in seconds (optional)
141 -- @param sep Output separator (optional)
142 function register(widget, script, format, updtime, sep)
143 -- Set optional variables
144 if updtime == nil then
145 updtime = 2 -- Default update time = 2 seconds
146 end
147
148 if format == nil then
149 format = "$1" -- Default format is the first word in script output
150 end
151
152 if sep == nil then
153 sep = ' ' -- Default separator is the space symbol
154 end
155
156 -- Append script_path to relative script path
157 if string.find(script, '^/') == nil then
158 script = script_path .. script
159 end
160
161 -- User don't want to wait first 'updtime' interval to see the value =)
162 widget.text = util.update(script, format, sep)
163
164 -- Register timer to update widget every 'updtime' seconds
165 awful.hooks.timer.register(updtime, function() widget.text = util.update(script, format, sep) end)
166 end
167
168 --- Register script for text widget throughout the temporary file
169 -- @param widget Widget to update
170 -- @param script Script to use it's output
171 -- @param format User-defined format string (optional)
172 -- @param time1 File update time in seconds (optional)
173 -- @param time2 Widget update time in seconds (optional)
174 -- @param sep Output separator (optional)
175 function register_async(widget, script, format, time1, time2, sep)
176 -- Set optional variables
177 if time1 == nil then
178 time1 = 2 -- Default file update time is 2 seconds
179 end
180
181 if time2 == nil then
182 time2 = 1 -- Default widget update time is 1 second
183 end
184
185 if format == nil then
186 format = "$1" -- Default format is the first word in script output
187 end
188
189 if sep == nil then
190 sep = ' ' -- Default separator is the space symbol
191 end
192
193 -- Replace all slashes with empty string so that /home/user1/script.sh
194 -- and /home/user2/script.sh will have different temporary files
195 local tmpname = string.gsub(script, '/', '')
196
197 -- Replace all spaces with points so that "script.sh arg1"
198 -- and "script.sh arg2" will have different temporary files
199 tmpname = string.gsub(tmpname, '%s+', '.')
200
201 -- Text while updating widget first time - it could take a while
202 widget.text = '...'
203 -- Generated script-parameter-unique temporary file path
204 local file = tmp_folder .. tmpname .. '.bashets.out'
205
206 -- Append script_path to relative script path
207 if string.find(script, '^/') == nil then
208 script = script_path .. script
209 end
210
211 -- Create temporary file
212 awful.util.spawn_with_shell('touch ' .. file)
213
214 -- Do it first time
215 util.exectmp(script, file)
216 widget.text = util.update_async(file, format, sep)
217
218 -- Register timers to update file every 'time1' seconds and widget every 'time2' seconds
219 awful.hooks.timer.register(time1, function() util.exectmp(script, file) end)
220 awful.hooks.timer.register(time2,
221 function()
222 local txt = util.update_async(file, format, sep)
223 if string.len(txt) > 0 then
224 widget.text = txt
225 end
226 end)
227 end
+0
-428
bashets/bashets.previous less more
0 ------------------------------------------------------------------------
1 -- Bashets - use your shellscript's output in Awesome3 widgets
2 --
3 -- @author Anton Lobov <ahmad200512@yandex.ru>
4 -- @copyright 2010 Anton Lobov
5 -- @license GPLv2
6 -- @release 0.3.1 for Awesome 3.4
7 -- @todo Implement better timer scheduling if possible.
8 -----------------------------------------------------------------------
9
10 -- Grab only needed enviroment
11 local awful = require("awful")
12 local string = string
13 local io = io
14 local table = table
15 local pairs = pairs
16 local timer = timer
17 local type = type
18
19 --- Bashets module
20 module("bashets")
21
22 -- Default paths
23 local script_path = "/usr/share/awesome/bashets/"
24 local tmp_folder = "/tmp/"
25
26 -- Utility functions table
27 local util = {}
28
29 -- Timer data
30 local timerdata = {}
31 local timers = {}
32
33 -- Some default values
34 local defaults = {}
35 defaults.update_time = 1
36 defaults.file_update_time = 2
37 defaults.format_string = "$1"
38 defaults.separator = " "
39 defaults.field = "text"
40
41 widget_field = defaults.field
42
43 -- State variable
44 local is_running = false
45
46 -- # Utility functions
47
48 --- Split string by separator into table
49 -- @param str String to split
50 -- @param sep Separator to use
51 function util.split(str, sep)
52 local parts = {} --parts array
53 local first = 1
54 local ostart, oend = string.find(str, sep, first, true) --regexp disabled search
55
56 while ostart do
57 local part = string.sub(str, first, ostart - 1)
58 table.insert(parts, part)
59 first = oend + 1
60 ostart, oend = string.find(str, sep, first, true)
61 end
62
63 local part = string.sub(str, first)
64 table.insert(parts, part)
65
66 return parts
67 end
68
69 function util.tmpname(script)
70 -- Replace all slashes with empty string so that /home/user1/script.sh
71 -- and /home/user2/script.sh will have different temporary files
72 local tmpname = string.gsub(script, '/', '')
73
74 -- Replace all spaces with dots so that "script.sh arg1"
75 -- and "script.sh arg2" will have different temporary files
76 tmpname = string.gsub(tmpname, '%s+', '.')
77
78 -- Generated script-parameter unique temporary file path
79 local file = tmp_folder .. tmpname .. '.bashets.out'
80
81 return file
82 end
83
84 function util.fullpath(script)
85 if string.find(script, '^/') == nil then
86 script = script_path .. script
87 end
88
89 return script
90 end
91
92 --- Execute a command and write it's output to temporary file
93 -- @param script Script to execute
94 -- @param file File for script output
95 function util.execfile(script, file)
96 -- Spawn command and redirect it's output to file
97 awful.util.spawn_with_shell(script .. " > " .. file)
98 end
99
100 --- Read temporary file to a table or string
101 -- @param file File to be read
102 -- @param israw If true, return raw string, not table
103 function util.readfile(file, sep)
104 local fh = io.input(file)
105 local str = fh:read("*all");
106 io.close(fh)
107
108 if sep == nil then
109 return str
110 else
111 parts = util.split(str, sep);
112 return parts
113 end
114 end
115
116 --- Read script output to a table or string
117 -- @param script Script to execute
118 -- @param israw If true, return raw string, not table
119 function util.readshell(script, sep)
120 local str = awful.util.pread(script)
121
122 if sep == nil then
123 return str
124 else
125 parts = util.split(str, sep);
126 return parts
127 end
128 end
129
130 --- Format script output with user defined format string
131 -- @param output sep-separated string of values
132 -- @param format Format string
133 -- @param sep Separator of values in string
134 function util.format(parts, format, sep)
135 -- For each part with number "k" replace corresponding "$k" variable in format string
136 for k,part in pairs(parts) do
137 local part = string.gsub(part, "%%", "%1%1") --percent fix for next gsub (bug found in Wicked)
138 part = awful.util.escape(part) --escape XML entities for correct Pango markup
139 format = string.gsub(format, "$" .. k, part)
140 end
141
142 return format
143 end
144
145 --- Add function to corresponding timer object (Awesome >= 3.4 timer API)
146 -- @param updtime Update time for widget, also dispatch time for timer
147 -- @param func Function to dispatch
148 function util.add_to_timings(updtime, func, force_new)
149 local found = false
150
151 -- Search for an existing timer at the same period
152 for k,tmr in pairs(timerdata) do
153 if tmr[1] == updtime and (force_new == nil or force_new == false) then
154 table.insert(timerdata[k][2], func)
155 found = true
156 end
157 end
158
159 -- Add a new timer for period if not found
160 if not found then
161 table.insert(timerdata, {updtime, {func}})
162 end
163 end
164
165 --- Create timer table to define timers for multiple widget updates
166 function util.create_timers_table()
167 -- Parse table with timer data
168 for _,tmr in pairs(timerdata) do
169 -- Create timer for the period
170 local t = timer {timeout = tmr[1]}
171 -- Function to call all dispatched functions
172 local f = function()
173 for _, func in pairs(tmr[2]) do
174 func()
175 end
176 end
177 t:add_signal("timeout", f)
178 table.insert(timers, t)
179 end
180 end
181
182 --- Update widget from values
183 function util.update_widget(widget, values, format, field)
184 field = field or "text"
185
186 if type(widget) == "table" or type(format) == "table" then
187 if #widget ~= #format then
188 io.stderr:write("E: bashets: widget table must have the same length with format string table")
189 return
190 end
191
192 for k, widg in pairs(widget) do
193 if widg ~= nil then
194 if type(values) == "table" then
195 pvalues = util.format(values, format[k])
196 else
197 pvalues = values
198 end
199
200 if field == "image" then
201 pvalues = image(pvalues)
202 end
203
204 if type(field) == "table" then
205 if #widget ~= #field then
206 io.stderr:write("E: bashets: fields table must have the same length with widget table");
207 return
208 end
209 widg[field[k]] = pvalues
210 else
211 widg[field] = pvalues
212 end
213 end
214 end
215 else
216 if widget ~= nil then
217 if type(values) == "table" then
218 pvalues = util.format(values, format)
219 else
220 pvalues = values
221 end
222
223 if field == "image" then
224 pvalues = image(util.format(values, format))
225 end
226
227 widget[field] = pvalues
228 end
229 end
230 end
231
232 -- # Setter functions
233
234 --- Set path for scripts
235 -- @param path Path to set
236 function set_script_path(path)
237 script_path = path
238 end
239
240 --- Set path for temporary files
241 -- @param path Path to set
242 function set_temporary_path(path)
243 tmp_folder = path
244 end
245
246 --- Set default values
247 -- @param defs Table with defaults
248 function set_defaults(defs)
249 if type(defs) == "table" then
250 if defs.update_time ~= nil then
251 defaults.update_time = defs.update_time
252 end
253 if defs.file_update_time ~= nil then
254 defaults.file_update_time = defs.file_update_time
255 end
256 if defs.format_string ~= nil then
257 defaults.format_string = defs.format_string
258 end
259
260 defaults.separator = defs.separator --now could be nil
261
262 if defs.widget_field ~= nil then
263 defaults.field = defs.widget_field
264 end
265 end
266 end
267
268 --- Set widget field for updates
269 -- @param fieldstr String representing widget field
270 function set_widget_field(fieldstr)
271 widget_field = fieldstr
272 end
273
274
275 -- # Acting functions
276
277 --- Start widget updates
278 function start()
279 -- Create timers table if not initialized or empty
280 if (not timers) or table.maxn(timers) == 0 then
281 util.create_timers_table()
282 end
283 -- Start all timers
284 for _, tmr in pairs(timers) do
285 tmr:start()
286 end
287 is_running = true
288 end
289
290 --- Stop widget updates
291 function stop()
292 -- Stop all timers
293 for _, tmr in pairs(timers) do
294 tmr:stop()
295 end
296 is_running = false
297 end
298
299 --- Check whether updates are running
300 function get_running()
301 return is_running
302 end
303
304 --- Toggle updates
305 function toggle()
306 if is_running then
307 start()
308 else
309 stop()
310 end
311 end
312
313 --- Shedule function for timed execution
314 -- @param func Function to run
315 -- @param updatime Update time (optional)
316 function schedule(func, updtime)
317 updtime = updtime or defaults.update_time
318 if func ~= nil then
319 util.add_to_timings(updtime, func)
320 end
321 end
322
323 -- # Widget registration functions
324
325 --- Register script for text widget
326 -- @param widget Widget to update
327 -- @param script Script to use it's output
328 -- @param format User-defined format string (optional)
329 -- @param updtime Update time in seconds (optional)
330 -- @param sep Output separator (optional)
331 function register(widget, script, format, updtime, sep, field)
332 -- Set optional variables
333 updtime = updtime or defaults.update_time
334 format = format or defaults.format_string
335 sep = sep or defaults.separator
336
337 script = util.fullpath(script)
338
339 -- Do it first time
340 local data = util.readshell(script)
341 util.update_widget(widget, data, format, field)
342
343 -- Schedule it for timed execution
344 schedule(function()
345 local data = util.readshell(script, sep)
346 util.update_widget(widget, data, format, field)
347 end, updtime)
348 end
349
350 --- Register script for widget's widget_field throughout the temporary file
351 -- @param widget Widget to update
352 -- @param script Script to use it's output
353 -- @param format User-defined format string (optional)
354 -- @param time1 File update time in seconds (optional)
355 -- @param time2 Widget update time in seconds (optional)
356 -- @param sep Output separator (optional)
357 function register_async(widget, script, format, time1, time2, sep, field)
358 -- Set optional variables
359 time1 = time1 or defaults.file_update_time
360 time2 = time2 or defaults.update_time
361 format = format or defaults.format_string
362 sep = sep or defaults.separator
363
364 script = util.fullpath(script)
365 local tmpfile = util.tmpname(script)
366
367 -- Create temporary file if not exists
368 fl = io.open(tmpfile, "w")
369 io.close(fl)
370
371 -- Do it first time
372 util.execfile(script, tmpfile)
373 local data = util.readfile(tmpfile)
374 util.update_widget(widget, data, format, field)
375
376 -- Schedule it for timed execution
377 schedule(function() util.execfile(script, tmpfile) end, time1)
378 schedule(function()
379 local data = util.readfile(tmpfile, sep)
380 util.update_widget(widget, data, format, field)
381 end, time2)
382 end
383
384 --- Register text file for text widget
385 -- @param widget Widget to update
386 -- @param file File to use as data source
387 -- @param format Format string (optional)
388 -- @param time Update time (optional)
389 -- @param sep Separator (optional)
390 function register_file(widget, file, format, time, sep, field)
391 -- Set optional variables
392 time = time or defaults.update_time
393 format = format or defaults.format_string
394 sep = sep or defaults.separator
395
396 -- Do it first time
397 local data = util.readfile(file, sep)
398 util.update_widget(widget, data, format, field)
399
400 -- Schedule it for timed execution
401 schedule(function()
402 local data = util.readfile(file, sep)
403 util.update_widget(widget, data, format, field)
404 end, time)
405 end
406
407 --- Register Lua function for text widget
408 -- @param widget Widget to update
409 -- @param func Function to return variables table
410 -- @param format Format string (optional)
411 -- @param time Update time (optional)
412 function register_lua(widget, func, format, time)
413 -- Set optional variables
414 time = time or defaults.update_time
415 format = format or defaults.format_string
416 sep = sep or defaults.separator
417
418 -- Do it first time
419 local data = func()
420 util.update_widget(widget, data, format, field)
421
422 -- Schedule it for timed execution
423 schedule(function()
424 local data = func()
425 util.update_widget(widget, data, format, field)
426 end, time)
427 end