Wed, 01 Dec 2021 17:25:25 +0100
clix: Import Verse where needed
In the olden days of `module()` this would have been a global, but that
is no longer the convention nor the case.
164 | 1 | local verse = require "verse" |
48 | 2 | short_opts.i = "interactive"; |
3 | local split_jid = require "util.jid".split; | |
123
c61fadb9d4fa
clix.roster: Print error resplies
Kim Alvefur <zash@zash.se>
parents:
121
diff
changeset
|
4 | local function printor(str) |
c61fadb9d4fa
clix.roster: Print error resplies
Kim Alvefur <zash@zash.se>
parents:
121
diff
changeset
|
5 | return function(ok, err) |
c61fadb9d4fa
clix.roster: Print error resplies
Kim Alvefur <zash@zash.se>
parents:
121
diff
changeset
|
6 | if ok then |
c61fadb9d4fa
clix.roster: Print error resplies
Kim Alvefur <zash@zash.se>
parents:
121
diff
changeset
|
7 | print(str) |
c61fadb9d4fa
clix.roster: Print error resplies
Kim Alvefur <zash@zash.se>
parents:
121
diff
changeset
|
8 | else |
c61fadb9d4fa
clix.roster: Print error resplies
Kim Alvefur <zash@zash.se>
parents:
121
diff
changeset
|
9 | print(err:get_error()); |
c61fadb9d4fa
clix.roster: Print error resplies
Kim Alvefur <zash@zash.se>
parents:
121
diff
changeset
|
10 | end |
c61fadb9d4fa
clix.roster: Print error resplies
Kim Alvefur <zash@zash.se>
parents:
121
diff
changeset
|
11 | end |
c61fadb9d4fa
clix.roster: Print error resplies
Kim Alvefur <zash@zash.se>
parents:
121
diff
changeset
|
12 | end |
48 | 13 | |
14 | return function (opts, arg) | |
15 | if opts.short_help then | |
16 | print("Show or edit your roster"); | |
17 | return; | |
18 | end | |
19 | if opts.help and not opts.interactive then | |
20 | return 0; | |
21 | end | |
22 | local function on_connect(conn) | |
23 | -- Fake socket object around stdin | |
24 | local stdin = { | |
25 | getfd = function () return 0; end; | |
26 | dirty = function (self) return false; end; | |
27 | settimeout = function () end; | |
28 | send = function (_, d) return #d, 0; end; | |
29 | close = function () end; | |
30 | receive = function (_, patt) | |
31 | local data = io.stdin:read(patt); | |
32 | if data == nil then | |
33 | conn:close(); | |
34 | end | |
35 | if opts.echo then | |
36 | io.write(data, patt == "*l" and "\n" or ""); | |
37 | end | |
38 | return data; | |
39 | end | |
40 | }; | |
41 | local commands = { | |
42 | quit = function(param) conn:close(); end; | |
43 | add = function(param) conn.roster:add_contact(param) end; | |
44 | sub = function(param) conn:send(verse.presence{to=param, type="subscribe"}); end; | |
61
7d62bff46601
clix.roster: Add command for unsubscribing and canceling subscription
Kim Alvefur <zash@zash.se>
parents:
59
diff
changeset
|
45 | unsub = function(param) conn:send(verse.presence{to=param, type="unsubscribe"}); end; |
48 | 46 | auth = function(param) conn:send(verse.presence{to=param, type="subscribed"}); end; |
61
7d62bff46601
clix.roster: Add command for unsubscribing and canceling subscription
Kim Alvefur <zash@zash.se>
parents:
59
diff
changeset
|
47 | unauth = function(param) conn:send(verse.presence{to=param, type="unsubscribed"}); end; |
48 | 48 | del = function(param) conn.roster:delete_contact(param) end; |
49 | setnick = function(param) | |
62
f455dad33efd
clix.roster: Use rest of line as last parameter for nick and group sub-commands.
Kim Alvefur <zash@zash.se>
parents:
61
diff
changeset
|
50 | local jid, nick = param:match("^(%S+)%s+(.+)"); |
48 | 51 | local item = conn.roster.items[jid]; |
52 | if not item then print("no jid "..jid); return; end | |
53 | conn.roster:add_contact(jid, nick, item.groups or {}, printor("saved")); | |
54 | end; | |
55 | addgroup = function(param) | |
62
f455dad33efd
clix.roster: Use rest of line as last parameter for nick and group sub-commands.
Kim Alvefur <zash@zash.se>
parents:
61
diff
changeset
|
56 | local jid, group = param:match("^(%S+)%s+(.+)"); |
48 | 57 | local item = conn.roster.items[jid]; |
58 | local groups = item.groups or {}; | |
59 | table.insert(groups, group); | |
60 | conn.roster:add_contact(jid, item.name, groups, printor("saved")); | |
61 | end; | |
62 | delgroup = function(param) | |
62
f455dad33efd
clix.roster: Use rest of line as last parameter for nick and group sub-commands.
Kim Alvefur <zash@zash.se>
parents:
61
diff
changeset
|
63 | local jid, group = param:match("^(%S+)%s+(.+)"); |
48 | 64 | local item = conn.roster.items[jid]; |
65 | local groups = item.groups; | |
66 | if not groups then return end; | |
67 | for i = 1,#groups do | |
68 | if groups[i] == group then | |
69 | table.remove(groups, i); | |
70 | break | |
71 | end | |
72 | end | |
73 | conn.roster:add_contact(jid, item.name, groups, printor("saved")); | |
74 | end; | |
66
13d6d39f5952
clix.roster: List now lets you search on nickname and jid.
Kim Alvefur <zash@zash.se>
parents:
63
diff
changeset
|
75 | list = function(param) |
13d6d39f5952
clix.roster: List now lets you search on nickname and jid.
Kim Alvefur <zash@zash.se>
parents:
63
diff
changeset
|
76 | if param == "" then |
13d6d39f5952
clix.roster: List now lets you search on nickname and jid.
Kim Alvefur <zash@zash.se>
parents:
63
diff
changeset
|
77 | param = nil |
13d6d39f5952
clix.roster: List now lets you search on nickname and jid.
Kim Alvefur <zash@zash.se>
parents:
63
diff
changeset
|
78 | end |
48 | 79 | for jid, item in pairs(conn.roster.items) do |
56
4b5f9a50ae68
clix.roster: Fix nickname fallback
Kim Alvefur <zash@zash.se>
parents:
48
diff
changeset
|
80 | local name, host = item.name or split_jid(jid); |
66
13d6d39f5952
clix.roster: List now lets you search on nickname and jid.
Kim Alvefur <zash@zash.se>
parents:
63
diff
changeset
|
81 | local groups = table.concat(item.groups or {}, ", "); |
121
896a25ed6b1b
clix.roster: Turn off pattern matching in the list command (thanks mva)
Kim Alvefur <zash@zash.se>
parents:
110
diff
changeset
|
82 | if not param or ( (name and name:find(param, 1, true)) or jid:find(param, 1, true) ) then |
91
7816f24d0fdc
clix.roster: Switch order of name and jid in the list command
Kim Alvefur <zash@zash.se>
parents:
66
diff
changeset
|
83 | print(jid, name or host, groups); |
66
13d6d39f5952
clix.roster: List now lets you search on nickname and jid.
Kim Alvefur <zash@zash.se>
parents:
63
diff
changeset
|
84 | end |
48 | 85 | end |
86 | end; | |
87 | listgroups = function(param) | |
88 | local groups = {}; | |
89 | for jid, item in pairs(conn.roster.items) do | |
90 | for i = 1,#item.groups do | |
91 | groups[item.groups[i]] = ( groups[item.groups[i]] or 0 ) + 1; | |
92 | end | |
93 | end | |
94 | for group, size in pairs(groups) do | |
95 | print(group, size) | |
96 | end | |
97 | end; | |
98 | show = function(param) | |
99 | local item = conn.roster.items[param]; | |
100 | if not item then | |
101 | print("No such contact"); | |
102 | return; | |
103 | end | |
104 | ||
105 | for k,v in pairs(item) do | |
59
46cb6e772e31
clix.roster: Add a separator between groups in the show sub command
Kim Alvefur <zash@zash.se>
parents:
58
diff
changeset
|
106 | print(k,type(v) == "table" and table.concat(v, ", ") or v) |
48 | 107 | end |
108 | end; | |
110
ded3938232f0
clix.roster: Add a sub-command that exports a prosody-style roster data structure
Kim Alvefur <zash@zash.se>
parents:
91
diff
changeset
|
109 | export = function() |
ded3938232f0
clix.roster: Add a sub-command that exports a prosody-style roster data structure
Kim Alvefur <zash@zash.se>
parents:
91
diff
changeset
|
110 | local stored_roster = { [false] = { version = conn.roster.ver } } |
ded3938232f0
clix.roster: Add a sub-command that exports a prosody-style roster data structure
Kim Alvefur <zash@zash.se>
parents:
91
diff
changeset
|
111 | for jid, item in pairs(conn.roster.items) do |
ded3938232f0
clix.roster: Add a sub-command that exports a prosody-style roster data structure
Kim Alvefur <zash@zash.se>
parents:
91
diff
changeset
|
112 | stored_roster[jid] = { |
ded3938232f0
clix.roster: Add a sub-command that exports a prosody-style roster data structure
Kim Alvefur <zash@zash.se>
parents:
91
diff
changeset
|
113 | name = item.name; |
ded3938232f0
clix.roster: Add a sub-command that exports a prosody-style roster data structure
Kim Alvefur <zash@zash.se>
parents:
91
diff
changeset
|
114 | subscription = item.subscription; |
ded3938232f0
clix.roster: Add a sub-command that exports a prosody-style roster data structure
Kim Alvefur <zash@zash.se>
parents:
91
diff
changeset
|
115 | groups = { unpack(item.groups) }; |
ded3938232f0
clix.roster: Add a sub-command that exports a prosody-style roster data structure
Kim Alvefur <zash@zash.se>
parents:
91
diff
changeset
|
116 | } |
ded3938232f0
clix.roster: Add a sub-command that exports a prosody-style roster data structure
Kim Alvefur <zash@zash.se>
parents:
91
diff
changeset
|
117 | end |
ded3938232f0
clix.roster: Add a sub-command that exports a prosody-style roster data structure
Kim Alvefur <zash@zash.se>
parents:
91
diff
changeset
|
118 | print("return "..require"util.serialization".serialize(stored_roster)); |
ded3938232f0
clix.roster: Add a sub-command that exports a prosody-style roster data structure
Kim Alvefur <zash@zash.se>
parents:
91
diff
changeset
|
119 | end |
48 | 120 | } |
63
bbbef9f4a798
clix.roster: Add a help command to list available sub-commands.
Kim Alvefur <zash@zash.se>
parents:
62
diff
changeset
|
121 | function commands.help () |
bbbef9f4a798
clix.roster: Add a help command to list available sub-commands.
Kim Alvefur <zash@zash.se>
parents:
62
diff
changeset
|
122 | print("Roster commands"); |
bbbef9f4a798
clix.roster: Add a help command to list available sub-commands.
Kim Alvefur <zash@zash.se>
parents:
62
diff
changeset
|
123 | for cmd in pairs(commands) do |
bbbef9f4a798
clix.roster: Add a help command to list available sub-commands.
Kim Alvefur <zash@zash.se>
parents:
62
diff
changeset
|
124 | print(" * " .. cmd); |
bbbef9f4a798
clix.roster: Add a help command to list available sub-commands.
Kim Alvefur <zash@zash.se>
parents:
62
diff
changeset
|
125 | end |
bbbef9f4a798
clix.roster: Add a help command to list available sub-commands.
Kim Alvefur <zash@zash.se>
parents:
62
diff
changeset
|
126 | print("Most commands takes a JID as argument."); |
bbbef9f4a798
clix.roster: Add a help command to list available sub-commands.
Kim Alvefur <zash@zash.se>
parents:
62
diff
changeset
|
127 | end |
48 | 128 | local function on_incoming(stdin, text) |
129 | local cmd = text:match("^(%a*)"); | |
130 | local param = text:match("%s+(.*)", #cmd); | |
131 | if commands[cmd] then | |
132 | commands[cmd](param); | |
133 | end | |
134 | end | |
135 | stdin = require "net.server".wrapclient(stdin, "stdin", 0, { | |
136 | onincoming = on_incoming, ondisconnect = function () end | |
137 | }, "*l"); | |
138 | conn:add_plugin("roster"); | |
139 | conn.roster:fetch(function(roster) | |
140 | if not roster then | |
141 | print("There was an error fetching your roster"); | |
142 | conn:close() | |
143 | end | |
144 | ||
145 | if not opts.interactive then | |
58
d5d9f7dffc1f
clix.roster: Don't run any command by default when --interactive
Kim Alvefur <zash@zash.se>
parents:
57
diff
changeset
|
146 | local firstcmd = commands[arg[1] or "list"]; |
d5d9f7dffc1f
clix.roster: Don't run any command by default when --interactive
Kim Alvefur <zash@zash.se>
parents:
57
diff
changeset
|
147 | if firstcmd then |
d5d9f7dffc1f
clix.roster: Don't run any command by default when --interactive
Kim Alvefur <zash@zash.se>
parents:
57
diff
changeset
|
148 | firstcmd(table.concat(arg, " ", 2, #arg)) |
d5d9f7dffc1f
clix.roster: Don't run any command by default when --interactive
Kim Alvefur <zash@zash.se>
parents:
57
diff
changeset
|
149 | end |
48 | 150 | conn:close(); |
151 | end | |
152 | end); | |
153 | local function notif(e) | |
154 | return function(item) | |
155 | return print(("%s %s"):format((item.name and item.name .. " (" .. item.jid .. ")") or item.jid, e)); | |
156 | end | |
157 | end | |
158 | if opts.interactive then | |
159 | conn:hook("roster/item-added", notif("added")); | |
160 | conn:hook("roster/item-changed", notif("changed")); | |
161 | conn:hook("roster/item-removed", notif("removed")); | |
162 | end | |
57
830baad98c9a
clix.roster: Show incomming subscription requests when --presence is used
Kim Alvefur <zash@zash.se>
parents:
56
diff
changeset
|
163 | if opts.presence then |
830baad98c9a
clix.roster: Show incomming subscription requests when --presence is used
Kim Alvefur <zash@zash.se>
parents:
56
diff
changeset
|
164 | conn:hook("presence", function(presence) |
830baad98c9a
clix.roster: Show incomming subscription requests when --presence is used
Kim Alvefur <zash@zash.se>
parents:
56
diff
changeset
|
165 | if presence.attr.type == "subscribe" then |
830baad98c9a
clix.roster: Show incomming subscription requests when --presence is used
Kim Alvefur <zash@zash.se>
parents:
56
diff
changeset
|
166 | print(("%s wants to subscribe to you"):format(presence.attr.from)); |
830baad98c9a
clix.roster: Show incomming subscription requests when --presence is used
Kim Alvefur <zash@zash.se>
parents:
56
diff
changeset
|
167 | --elseif presence.attr.type == "subscribed" then |
830baad98c9a
clix.roster: Show incomming subscription requests when --presence is used
Kim Alvefur <zash@zash.se>
parents:
56
diff
changeset
|
168 | --print(("%s subscribed to you?"):format(presence.attr.from)); |
830baad98c9a
clix.roster: Show incomming subscription requests when --presence is used
Kim Alvefur <zash@zash.se>
parents:
56
diff
changeset
|
169 | end |
830baad98c9a
clix.roster: Show incomming subscription requests when --presence is used
Kim Alvefur <zash@zash.se>
parents:
56
diff
changeset
|
170 | end) |
830baad98c9a
clix.roster: Show incomming subscription requests when --presence is used
Kim Alvefur <zash@zash.se>
parents:
56
diff
changeset
|
171 | end |
48 | 172 | end |
173 | clix_connect(opts, on_connect); | |
174 | end |