72 return false |
70 return false |
73 end ) |
71 end ) |
74 |
72 |
75 -- mcabber |
73 -- mcabber |
76 |
74 |
77 local tune_enabled = false |
75 local pep_handler_registered = false |
78 local mpd_pub_song = { } |
|
79 |
|
80 -- XXX in fact, we should separate library code from client code here, but it is silly. |
|
81 -- seting up four registrators, four default handlers, four handler storage variables... |
|
82 -- and, in fact, we cannot do much about complex datatypes of mood and activity. |
|
83 pep.handlers['http://jabber.org/protocol/tune'] = |
|
84 function ( from, node, data ) |
|
85 local self = false |
|
86 if from == lm.connection.bless ( main.connection () ):jid():gsub ( '/.*', '' ) then -- o_O |
|
87 self = true |
|
88 mpd_pub_song = { } |
|
89 end |
|
90 local item = data:children () |
|
91 local text = '' |
|
92 while item do |
|
93 local name = item:name () |
|
94 local value = item:value () |
|
95 if self then |
|
96 mpd_pub_song[name] = { value or '' } |
|
97 end |
|
98 text = ("%s\n- %s: %s"):format ( text, item:name (), item:value () or '' ) |
|
99 item = item:next () |
|
100 end |
|
101 if main.yesno ( main.option ( 'lua_pep_notification' ) ) then |
|
102 if text ~= '' then |
|
103 text = 'Now listening to:' .. text |
|
104 else |
|
105 text = 'Now not listening to anything' |
|
106 end |
|
107 end |
|
108 main.print_info ( from, text ) |
|
109 return true |
|
110 end |
|
111 pep.handlers['http://jabber.org/protocol/mood'] = |
|
112 function ( from, node, data ) |
|
113 if not main.yesno ( main.option ( 'lua_pep_notification' ) ) then |
|
114 return true |
|
115 end |
|
116 local item = data:children () |
|
117 local mood, desc |
|
118 while item do |
|
119 if item:name () == 'text' then |
|
120 desc = item:value () |
|
121 else |
|
122 mood = item:name () |
|
123 -- here we can add child elements handling (by namespace) |
|
124 end |
|
125 item = item:next () |
|
126 end |
|
127 if mood then |
|
128 main.print_info ( from, ("Buddy's mood now %s %s"):format ( mood, desc or '' ) ) |
|
129 else |
|
130 main.print_info ( from, "Buddy hides his mood" ) |
|
131 end |
|
132 end |
|
133 pep.handlers['http://jabber.org/protocol/activity'] = |
|
134 function ( from, node, data ) |
|
135 if not main.yesno ( main.option ( 'lua_pep_notification' ) ) then |
|
136 return true |
|
137 end |
|
138 local item = data:children () |
|
139 local activity, desc |
|
140 while item do |
|
141 if item:name () == 'text' then |
|
142 desc = item:value () |
|
143 else |
|
144 activity = item:name () |
|
145 local subitem = item:children () |
|
146 if subitem then |
|
147 -- here we can check for non-standard subactivity elements, |
|
148 -- add subactivity child elements handling |
|
149 activity = ("%s: %s"):format ( activity, subitem:name () ) |
|
150 end |
|
151 end |
|
152 item = item:next () |
|
153 end |
|
154 if activity then |
|
155 main.print_info ( from, ("Now %s %s"):format ( activity, desc or '' ) ) |
|
156 else |
|
157 main.print_info ( from, "Buddy hides his activity" ) |
|
158 end |
|
159 return true |
|
160 end |
|
161 pep.handlers['http://jabber.org/protocol/geoloc'] = |
|
162 function ( from, node, data ) |
|
163 if not main.yesno ( main.option ( 'lua_pep_notification' ) ) then |
|
164 return true |
|
165 end |
|
166 local item = data:children () |
|
167 local text = '' |
|
168 while item do |
|
169 text = ("%s\n- %s: %s"):format ( text, item:name (), item:value () or '' ) |
|
170 item = item:next () |
|
171 end |
|
172 if text ~= '' then |
|
173 text = 'Now at:' .. text |
|
174 else |
|
175 text = 'Now in unknown location' |
|
176 end |
|
177 main.print_info ( from, text ) |
|
178 return true |
|
179 end |
|
180 |
|
181 local function mpd_getstatus () |
|
182 local status = mpd.call_command { 'status' } |
|
183 if not tune_enabled or ( status.state ~= 'play' and status.state ~= 'pause' ) then |
|
184 for k, v in pairs ( mpd_pub_song ) do -- if there is anything published, publish nothing |
|
185 return { } |
|
186 end |
|
187 return nil |
|
188 end |
|
189 |
|
190 local song = mpd.call_command { 'currentsong' } |
|
191 local dir, file = song.file:match ( '(.+)/(.-)' ) |
|
192 -- populate according to currentsong fields: artist - artist, length - time, source - album, title - title, track - id, rating - ?, uri - ? |
|
193 local ret = { |
|
194 artist = { song.artist or 'Unknown' }, |
|
195 length = { song.time }, |
|
196 source = { song.album or dir }, |
|
197 title = { song.title or file }, |
|
198 track = { song.id }, |
|
199 } |
|
200 |
|
201 if not song.time or song.time == '0' then -- XXX |
|
202 ret.length = nil |
|
203 end |
|
204 |
|
205 local modified = false |
|
206 for k, v in pairs ( ret ) do |
|
207 if not mpd_pub_song[k] or mpd_pub_song[k][1] ~= v[1] then |
|
208 modified = true |
|
209 break |
|
210 end |
|
211 end |
|
212 if not modified then |
|
213 for k, v in pairs ( mpd_pub_song ) do |
|
214 if not ret[k] or ret[k][1] ~= v[1] then |
|
215 modified = true |
|
216 break |
|
217 end |
|
218 end |
|
219 end |
|
220 |
|
221 if modified then |
|
222 return ret |
|
223 else |
|
224 return nil |
|
225 end |
|
226 end |
|
227 |
|
228 local function dummy () |
|
229 end |
|
230 |
|
231 local function mpd_callback () |
|
232 local sdata = mpd_getstatus () |
|
233 if sdata then |
|
234 sdata.xmlns = 'http://jabber.org/protocol/tune' |
|
235 pep.publish ( lm.connection.bless ( main.connection () ), 'http://jabber.org/protocol/tune', { tune = sdata }, dummy, dummy ) |
|
236 end |
|
237 if tune_enabled then |
|
238 return true |
|
239 else |
|
240 return false |
|
241 end |
|
242 end |
|
243 |
|
244 -- do not call it too fast, or you end up with many daemons at once |
|
245 local function enable_tune ( yn ) |
|
246 if yn == nil then |
|
247 yn = true |
|
248 end |
|
249 if yn then |
|
250 if not tune_enabled then |
|
251 main.timer ( 15, mpd_callback ) |
|
252 tune_enabled = true |
|
253 -- update status |
|
254 end |
|
255 else |
|
256 if tune_enabled then |
|
257 tune_enabled = false |
|
258 -- update status |
|
259 end |
|
260 end |
|
261 end |
|
262 |
|
263 main.command ( 'tune', |
|
264 function ( args ) |
|
265 local enable = main.yesno ( args ) |
|
266 if enable == nil then |
|
267 if tune_enabled then |
|
268 print ( "Tune notifications enabled" ) |
|
269 else |
|
270 print ( "Tune notifications disabled" ) |
|
271 end |
|
272 else |
|
273 enable_tune ( enable ) |
|
274 end |
|
275 end, false, 'yesno' ) |
|
276 main.command ( 'mood', |
|
277 function ( args ) |
|
278 local data = { xmlns = 'http://jabber.org/protocol/mood' } |
|
279 local mood, text = args[1], args[2] |
|
280 if text then |
|
281 data.text = { text } |
|
282 end |
|
283 if mood then |
|
284 data[mood] = { } |
|
285 end |
|
286 pep.publish ( lm.connection.bless ( main.connection () ), 'http://jabber.org/protocol/mood', { mood = data }, dummy, dummy ) |
|
287 end, true ) |
|
288 main.command ( 'activity', |
|
289 function ( args ) |
|
290 local data = { xmlns = 'http://jabber.org/protocol/activity' } |
|
291 local activity, text = args[1], args[2] |
|
292 if text then |
|
293 data.text = { text } |
|
294 end |
|
295 local act, subact = activity:match ( "(.-)%-(.+)" ) |
|
296 if not act then |
|
297 act = activity |
|
298 end |
|
299 if act ~= '' then |
|
300 data[act] = { } |
|
301 if subact then |
|
302 data[act][subact] = { } |
|
303 end |
|
304 end |
|
305 pep.publish ( lm.connection.bless ( main.connection () ), 'http://jabber.org/protocol/activity', { activity = data }, dummy, dummy ) |
|
306 end, true ) |
|
307 main.command ( 'location', |
|
308 function ( args ) |
|
309 local data = { xmlns = 'http://jabber.org/protocol/geoloc' } |
|
310 for key, val in pairs ( args ) do |
|
311 data[key] = { val } |
|
312 end |
|
313 pep.publish ( lm.connection.bless ( main.connection () ), 'http://jabber.org/protocol/geoloc', { geoloc = data }, dummy, dummy ) |
|
314 end, true ) |
|
315 |
|
316 commands_help['tune'] = "[enable|disable|on|off|yes|no|true|false]\n\nEnables or disables publishing of notifications about playing music in your player (currently only mpd is supported)." |
|
317 commands_help['mood'] = "[mood [message]]\n\nPublishes your mood.\nNote, that for now it does not checks for mood validity, so, see xep0107 for valid moods." |
|
318 commands_help['activity'] = "[activity[-specific_activity] [text]]\n\nPublishes your activity.\nNote, that for now it does not checks for activity validity, so, see xep0108 for valid activity values." |
|
319 commands_help['location'] = "[-key value [-key value ...]]\n\nPublishes your current geolocation.\nValid keys are accuracy, alt, area, bearing, building, country, datum, description, error, floor, lat, locality, lon, postalcode, region, room, speed, street, text, timestamp and uri, according to xep0080." |
|
320 |
76 |
321 hooks_d['hook-post-connect'].pep = |
77 hooks_d['hook-post-connect'].pep = |
322 function ( args ) |
78 function ( args ) |
323 lm.connection.bless( main.connection () ):handler ( pep_incoming_message_handler, 'message', 'normal' ) |
79 lm.connection.bless( main.connection () ):handler ( pep_incoming_message_handler, 'message', 'normal' ) |
324 pep_handler_registered = true |
80 pep_handler_registered = true |
325 if tune_enabled then |
81 hooks_d['hook-post-connect'].pep = nil |
326 mpd_callback () |
|
327 end |
|
328 -- XXX may it confuse pairs()? |
|
329 hooks_d['hook-post-connect'].pep = |
|
330 function ( args ) |
|
331 if tune_enabled then |
|
332 mpd_callback () |
|
333 end |
|
334 end |
|
335 hooks_d['hook-quit'].pep = |
82 hooks_d['hook-quit'].pep = |
336 function ( args ) |
83 function ( args ) |
337 if pep_handler_registered then |
84 if pep_handler_registered then |
338 lm.connection.bless( main.connection () ):handler ( pep_incoming_message_handler, 'message' ) |
85 lm.connection.bless( main.connection () ):handler ( pep_incoming_message_handler, 'message' ) |
339 pep_handler_registered = false |
86 pep_handler_registered = false |
340 end |
87 end |
341 end |
88 end |
342 end |
89 end |
343 |
90 |
344 -- XXX this really should be initialized after connection establishment (?) |
|
345 -- but as this thing is implemented by now, it will be cached by server, |
|
346 -- and, thus, we will be unable to get notifications. |
|
347 main.add_feature ( 'http://jabber.org/protocol/tune+notify' ) |
|
348 main.add_feature ( 'http://jabber.org/protocol/tune' ) |
|
349 main.add_feature ( 'http://jabber.org/protocol/mood+notify' ) |
|
350 main.add_feature ( 'http://jabber.org/protocol/mood' ) |
|
351 main.add_feature ( 'http://jabber.org/protocol/activity+notify' ) |
|
352 main.add_feature ( 'http://jabber.org/protocol/activity' ) |
|
353 main.add_feature ( 'http://jabber.org/protocol/geoloc+notify' ) |
|
354 main.add_feature ( 'http://jabber.org/protocol/geoloc' ) |
|
355 |
|
356 -- vim: se ts=4: -- |
91 -- vim: se ts=4: -- |