clix/roster.lua

changeset 48
8206f3369d37
child 56
4b5f9a50ae68
equal deleted inserted replaced
46:b5d6e443e571 48:8206f3369d37
1 short_opts.i = "interactive";
2 local split_jid = require "util.jid".split;
3 local function printor(str) return function() print(str) end end
4
5 return function (opts, arg)
6 if opts.short_help then
7 print("Show or edit your roster");
8 return;
9 end
10 if opts.help and not opts.interactive then
11 return 0;
12 end
13 local function on_connect(conn)
14 -- Fake socket object around stdin
15 local stdin = {
16 getfd = function () return 0; end;
17 dirty = function (self) return false; end;
18 settimeout = function () end;
19 send = function (_, d) return #d, 0; end;
20 close = function () end;
21 receive = function (_, patt)
22 local data = io.stdin:read(patt);
23 if data == nil then
24 conn:close();
25 end
26 if opts.echo then
27 io.write(data, patt == "*l" and "\n" or "");
28 end
29 return data;
30 end
31 };
32 local commands = {
33 quit = function(param) conn:close(); end;
34 add = function(param) conn.roster:add_contact(param) end;
35 sub = function(param) conn:send(verse.presence{to=param, type="subscribe"}); end;
36 auth = function(param) conn:send(verse.presence{to=param, type="subscribed"}); end;
37 del = function(param) conn.roster:delete_contact(param) end;
38 setnick = function(param)
39 local jid, nick = param:match("^(%S+)%s+(%S+)");
40 local item = conn.roster.items[jid];
41 if not item then print("no jid "..jid); return; end
42 conn.roster:add_contact(jid, nick, item.groups or {}, printor("saved"));
43 end;
44 addgroup = function(param)
45 local jid, group = param:match("^(%S+)%s+(%S+)");
46 local item = conn.roster.items[jid];
47 local groups = item.groups or {};
48 table.insert(groups, group);
49 conn.roster:add_contact(jid, item.name, groups, printor("saved"));
50 end;
51 delgroup = function(param)
52 local jid, group = param:match("^(%S+)%s+(%S+)");
53 local item = conn.roster.items[jid];
54 local groups = item.groups;
55 if not groups then return end;
56 for i = 1,#groups do
57 if groups[i] == group then
58 table.remove(groups, i);
59 break
60 end
61 end
62 conn.roster:add_contact(jid, item.name, groups, printor("saved"));
63 end;
64 list = function()
65 for jid, item in pairs(conn.roster.items) do
66 local name = item.name, host or split_jid(jid);
67 print(name or host, jid, table.concat(item.groups or {}, ", "));
68 end
69 end;
70 listgroups = function(param)
71 local groups = {};
72 for jid, item in pairs(conn.roster.items) do
73 for i = 1,#item.groups do
74 groups[item.groups[i]] = ( groups[item.groups[i]] or 0 ) + 1;
75 end
76 end
77 for group, size in pairs(groups) do
78 print(group, size)
79 end
80 end;
81 show = function(param)
82 local item = conn.roster.items[param];
83 if not item then
84 print("No such contact");
85 return;
86 end
87
88 for k,v in pairs(item) do
89 print(k,type(v) == "table" and table.concat(v) or v)
90 end
91 end;
92 }
93 local function on_incoming(stdin, text)
94 local cmd = text:match("^(%a*)");
95 local param = text:match("%s+(.*)", #cmd);
96 if commands[cmd] then
97 commands[cmd](param);
98 end
99 end
100 stdin = require "net.server".wrapclient(stdin, "stdin", 0, {
101 onincoming = on_incoming, ondisconnect = function () end
102 }, "*l");
103 conn:add_plugin("roster");
104 conn.roster:fetch(function(roster)
105 if not roster then
106 print("There was an error fetching your roster");
107 conn:close()
108 end
109
110 local firstcmd = commands[arg[1] or "list"];
111 if firstcmd then
112 firstcmd(table.concat(arg, " ", 2, #arg))
113 end
114 if not opts.interactive then
115 conn:close();
116 end
117 end);
118 local function notif(e)
119 return function(item)
120 return print(("%s %s"):format((item.name and item.name .. " (" .. item.jid .. ")") or item.jid, e));
121 end
122 end
123 if opts.interactive then
124 conn:hook("roster/item-added", notif("added"));
125 conn:hook("roster/item-changed", notif("changed"));
126 conn:hook("roster/item-removed", notif("removed"));
127 end
128 end
129 clix_connect(opts, on_connect);
130 end

mercurial