]> git.madduck.net Git - etc/awesome.git/blob - asyncshell.lua.orig

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

5c6e7e8e7fab0eb07fd5724780d72ef431a41d61
[etc/awesome.git] / asyncshell.lua.orig
1
2 --[[
3                                                   
4      Licensed under GNU General Public License v2 
5 <<<<<<< HEAD
6 =======
7       * (c) 2015, worron                          
8 >>>>>>> upstream/master
9       * (c) 2013, Alexander Yakushev              
10                                                   
11 --]]
12
13 -- Asynchronous io.popen for Awesome WM.
14 <<<<<<< HEAD
15 -- How to use...
16 -- ...asynchronously:
17 -- asyncshell.request('wscript -Kiev', function(f) wwidget.text = f:read("*l") end)
18 -- ...synchronously:
19 -- widget:set_text(asyncshell.demand('wscript -Kiev', 5):read("*l") or "Error")
20
21 local spawn = require('awful.util').spawn
22
23 asyncshell               = {}
24 asyncshell.request_table = {}
25 asyncshell.id_counter    = 0
26 asyncshell.folder        = "/tmp/asyncshell"
27 asyncshell.file_template = asyncshell.folder .. '/req'
28
29 -- Create a directory for asynchell response files
30 os.execute("mkdir -p " .. asyncshell.folder)
31
32 -- Returns next tag - unique identifier of the request
33 local function next_id()
34    asyncshell.id_counter = (asyncshell.id_counter + 1) % 100000
35    return asyncshell.id_counter
36 end
37
38 -- Sends an asynchronous request for an output of the shell command.
39 -- @param command Command to be executed and taken output from
40 -- @param callback Function to be called when the command finishes
41 -- @return Request ID
42 function asyncshell.request(command, callback)
43    local id = next_id()
44    local tmpfname = asyncshell.file_template .. id
45    asyncshell.request_table[id] = { callback = callback }
46    local req =
47       string.format("sh -c '%s > %s; " ..
48                     'echo "asyncshell.deliver(%s)" | ' ..
49                     "awesome-client' 2> /dev/null",
50                     string.gsub(command, "'", "'\\''"), tmpfname, id)
51    spawn(req, false)
52    return id
53 end
54
55 -- Calls the remembered callback function on the output of the shell
56 -- command.
57 -- @param id Request ID
58 -- @param output The output file of the shell command to be delievered
59 function asyncshell.deliver(id)
60    if asyncshell.request_table[id] and
61       asyncshell.request_table[id].callback then
62       local output = io.open(asyncshell.file_template .. id, 'r')
63       asyncshell.request_table[id].callback(output)
64    end
65 end
66
67 -- Sends a synchronous request for an output of the command. Waits for
68 -- the output, but if the given timeout expires returns nil.
69 -- @param command Command to be executed and taken output from
70 -- @param timeout Maximum amount of time to wait for the result
71 -- @return File handler on success, nil otherwise
72 function asyncshell.demand(command, timeout)
73    local id = next_id()
74    local tmpfname = asyncshell.file_template .. id
75    local f = io.popen(string.format("(%s > %s; echo asyncshell_done) & " ..
76                                     "(sleep %s; echo asynchell_timeout)",
77                                     command, tmpfname, timeout))
78    local result = f:read("*line")
79    if result == "asyncshell_done" then
80       return io.open(tmpfname)
81    end
82 =======
83 -- How to use:
84 -- asyncshell.request('wscript -Kiev', function(output) wwidget.text = output end)
85
86 -- Grab environment
87 local awful = require('awful')
88
89 -- Initialize tables for module
90 asyncshell = { request_table = {}, id_counter = 0 }
91
92 -- Request counter
93 local function next_id()
94     asyncshell.id_counter = (asyncshell.id_counter + 1) % 10000
95     return asyncshell.id_counter
96 end
97
98 -- Remove given request
99 function asyncshell.clear(id)
100     if asyncshell.request_table[id] then
101         if asyncshell.request_table[id].timer then
102             asyncshell.request_table[id].timer:stop()
103             asyncshell.request_table[id].timer = nil
104         end
105         asyncshell.request_table[id] = nil
106     end
107 end
108
109 -- Sends an asynchronous request for an output of the shell command
110 -- @param command Command to be executed and taken output from
111 -- @param callback Function to be called when the command finishes
112 -- @param timeout Maximum amount of time to wait for the result (optional)
113 function asyncshell.request(command, callback, timeout)
114     local id = next_id()
115     asyncshell.request_table[id] = { callback = callback }
116
117     local formatted_command = string.gsub(command, '"','\"')
118
119     local req = string.format(
120         "echo \"asyncshell.deliver(%s, [[\\\"$(%s)\\\"]])\" | awesome-client &",
121         id, formatted_command
122     )
123
124     awful.util.spawn_with_shell(req)
125
126     if timeout then
127         asyncshell.request_table[id].timer = timer({ timeout = timeout })
128         asyncshell.request_table[id].timer:connect_signal("timeout", function() asyncshell.clear(id) end)
129         asyncshell.request_table[id].timer:start()
130     end
131 end
132
133 -- Calls the remembered callback function on the output of the shell command
134 -- @param id Request ID
135 -- @param output Shell command output to be delievered
136 function asyncshell.deliver(id, output)
137     local output = string.sub(output, 2, -2)
138     if asyncshell.request_table[id] then
139         asyncshell.request_table[id].callback(output)
140         asyncshell.clear(id)
141     end
142 >>>>>>> upstream/master
143 end
144
145 return asyncshell