# HG changeset patch # User Kim Alvefur # Date 1410171624 -7200 # Node ID 1dfd28db10bd651329ec2cbd6238116a271d8ae6 # Parent 45843df81db0937027e882b0fa4e2d474415338c# Parent 896a25ed6b1bdc2a6bc2cb9d3a80ffd70d7f86f3 Merge with MattJ diff -r 45843df81db0 -r 1dfd28db10bd clix.lua --- a/clix.lua Sun Aug 24 20:34:04 2014 +0100 +++ b/clix.lua Mon Sep 08 12:20:24 2014 +0200 @@ -59,8 +59,12 @@ io.stderr:write("The specified account (", opts.account or "default", ") wasn't found in the config file\n"); return nil; end - verse.set_log_handler(io.stderr, opts.quiet and {} or not opts.verbose and {"info", "error"}); + verse.set_log_handler(io.stderr, opts.quiet and {} or not opts.verbose and {"info", "warn", "error"}); local conn = verse.new(verse.new_logger("clix")); + if opts.raw then + conn:hook("incoming-raw", print, 1000); + conn:hook("outgoing-raw", print, 1000); + end for _, plugin in ipairs(plugins or {}) do conn:add_plugin(plugin); end @@ -83,7 +87,7 @@ conn:close(); end); conn:hook("disconnected", function (info) - if info.reason then + if info and info.reason and info.reason ~= "stream closed" then conn:warn("Disconnecting: %s", tostring(info.reason)); end verse.quit(); diff -r 45843df81db0 -r 1dfd28db10bd clix/adhoc.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/clix/adhoc.lua Mon Sep 08 12:20:24 2014 +0200 @@ -0,0 +1,84 @@ +local dataforms = require "util.dataforms"; + +-- TODO Cleanup, commit +return function (opts, arg) + if opts.short_help then + print("Execute an Ad-Hoc Command"); + return; + end + local function on_connect(conn) + if opts.node then + conn:execute_command(opts.to or conn.host, opts.node, function(cmd) + conn:info("status: %s", cmd.status); + local note = cmd.note; + if note then + conn[note.attr.type or "info"](conn, note:get_text()); + end + if cmd.status == "executing" then + local data = {}; + for i=1,#arg do + local k,v = arg[i]:match"^([^=]+)=(.*)"; + if k and v then + data[k] = v; --FIXME multiple + end + end + local command_form_layout = dataforms.from_stanza(cmd.form) + if opts.interactive then + for i=1,#command_form_layout do + local item = command_form_layout[i]; + if item.type ~= "hidden" and not data[item.name] then + -- FIXME Current value isn't shown + io.stderr:write(item.label..": "); + if item.type:match"%-multi" then + local t = { }; + repeat + local line = io.read("*l"); + if line and line ~= "" then + t[#t+1] = line; + end + until not line or line == ""; + if item.type == "text-multi" then + t = table.concat(t, "\n"); + end + data[item.name] = t; + --elseif item.type == "list-single" then + --data[item.name] = { (io.read("*l")) }; + else + data[item.name] = io.read("*l"); + end + end + end + end + cmd:next(command_form_layout:form(data, "submit")); + elseif cmd.status == "completed" then + if cmd.form then + local command_form_layout = dataforms.from_stanza(cmd.form) + local data = command_form_layout:data(cmd.form); + for i, item in ipairs(command_form_layout) do + if item.type ~= "hidden" then + print("== " .. item.name .. " ==") + print(data[item.name]); + end + end + + end + conn:close(); + else + conn:warn("unhandled command status: %s", tostring(cmd.status)); + end + end); + else + conn:disco_items(opts.to or conn.host, "http://jabber.org/protocol/commands", function(items) + -- TODO It would be neat to be able to choose from this list + if items then + for i=1,#items do + print(items[i].name, items[i].node); + end + end + conn:close(); + end); + end + end + clix_connect(opts, on_connect, {"adhoc"}); +end + diff -r 45843df81db0 -r 1dfd28db10bd clix/archive.lua --- a/clix/archive.lua Sun Aug 24 20:34:04 2014 +0100 +++ b/clix/archive.lua Mon Sep 08 12:20:24 2014 +0200 @@ -6,6 +6,7 @@ return; end + local reverse = opts.before; if opts.start then opts.start = parse_datetime(opts.start); end @@ -18,7 +19,7 @@ local m = i.message; local a = m.attr; if i.stamp then - print(os.date(nil, i.stamp)); + print(os.date("%Y-%m-%d %H:%M:%S", i.stamp)); end if a.to and bare_jid(a.to) ~= selfjid then print("To ".. bare_jid(a.to)); @@ -40,19 +41,32 @@ for i=1,#result do print_message(result[i]); end - if result.last then + if result[reverse and "first" or "last"] then local fetch_next = opts.everything; if opts.interactive and not fetch_next then io.stderr:write "--More--" fetch_next = io.read"*l" or print(); end if fetch_next then - opts.after = result.last; + if reverse then + opts.before = result.first and result.first[1]; + else + opts.after = result.last; + end conn:query_archive(opts.to, opts, handle_results); return else - conn:info("Next page: --after=%s", result.last); + local whatnext, nextpage = reverse and "before" or "after"; + if reverse then + nextpage = result.first and result.first[1]; + else + nextpage = result.last; end + conn:info("Next page: --%s=%s", whatnext, nextpage); + end + end + if result.count then + conn:info("Total: %d items", result.count); end conn:close(); end diff -r 45843df81db0 -r 1dfd28db10bd clix/ping.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/clix/ping.lua Mon Sep 08 12:20:24 2014 +0200 @@ -0,0 +1,24 @@ +return function (opts, arg) + if opts.short_help then + print("Measure the round-trip latency time of a given JID"); + return; + end + if #arg == 0 or opts.help then + return 0; + end + local conn; + local function on_reply(time, jid, reply) + if time then + print(string.format("%s latency: %1.3fs", jid, time)); + else + print("Error requesting ping ("..(reply.condition or "unknown")..")"..(reply.text and (": "..reply.text) or "")); + end + conn:close(); + end + local function on_connect(_conn) + conn = _conn; + conn:add_plugin("ping"); + conn:ping(arg[1], on_reply); + end + clix_connect(opts, on_connect); +end diff -r 45843df81db0 -r 1dfd28db10bd clix/publish_atom.lua --- a/clix/publish_atom.lua Sun Aug 24 20:34:04 2014 +0100 +++ b/clix/publish_atom.lua Mon Sep 08 12:20:24 2014 +0200 @@ -3,15 +3,13 @@ local xmlns_atom = "http://www.w3.org/2005/Atom"; local xmlns_activitystreams = "http://activitystrea.ms/spec/1.0/"; -local activitystreams_schema_base = "http://activitystrea.ms/schema/1.0/"; return function (opts, arg) if opts.short_help then print("Publish an Atom entry to a pubsub node"); return; end - --if (#arg == 0 or opts.help) then -- why? - if opts.help then + if opts.help or not opts.node then print("clix publish_atom \\"); print("","--service=pubsub.shakespeare.lit \\"); print("","--node=princely_musings \\"); @@ -25,27 +23,23 @@ -- Required: id, title, updated, author (which must have a name) local entry_id = opts.id or new_uuid(); local atom_entry = verse.stanza("entry", { xmlns = xmlns_atom}) - :tag("id"):text(entry_id):up(id) - :tag("title"):text(opts.title or ""):up() + :tag("id"):text(entry_id):up() + :tag("title", { type = opts["title-type"] }):text(opts.title or ""):up() :tag("updated"):text(opts.updated or datetime()):up(); atom_entry:tag("author"):tag("name"):text(opts.author or os.getenv("USER") or "Unknown author"):up(); atom_entry:up(); - atom_entry:tag("source") - :tag("id"):text(opts.node):up() - :tag("link", { rel = "self", href = opts.node }):up() - :up(); if opts.summary then - atom_entry:tag("summary"):text(opts.summary):up(); + atom_entry:tag("summary", { type = opts["summary-type"] }):text(opts.summary):up(); end if opts.content then - atom_entry:tag("content"):text(opts.content):up(); + atom_entry:tag("content", { type = opts["content-type"] }):text(opts.content):up(); end for opt, optval in pairs(opts) do - if opt:match"^as_" then - atom_entry:tag(opt:sub(4):gsub("_", "-"), { xmlns = xmlns_activitystreams } ) - :text(activitystreams_schema_base..optval):up(); + if opt:match"^as%-" then + atom_entry:tag(opt:sub(4), { xmlns = xmlns_activitystreams } ) + :text(optval):up(); end end diff -r 45843df81db0 -r 1dfd28db10bd clix/roster.lua --- a/clix/roster.lua Sun Aug 24 20:34:04 2014 +0100 +++ b/clix/roster.lua Mon Sep 08 12:20:24 2014 +0200 @@ -70,7 +70,7 @@ for jid, item in pairs(conn.roster.items) do local name, host = item.name or split_jid(jid); local groups = table.concat(item.groups or {}, ", "); - if not param or ( (name and name:match(param)) or jid:match(param) ) then + if not param or ( (name and name:find(param, 1, true)) or jid:find(param, 1, true) ) then print(jid, name or host, groups); end end @@ -97,6 +97,17 @@ print(k,type(v) == "table" and table.concat(v, ", ") or v) end end; + export = function() + local stored_roster = { [false] = { version = conn.roster.ver } } + for jid, item in pairs(conn.roster.items) do + stored_roster[jid] = { + name = item.name; + subscription = item.subscription; + groups = { unpack(item.groups) }; + } + end + print("return "..require"util.serialization".serialize(stored_roster)); + end } function commands.help () print("Roster commands"); diff -r 45843df81db0 -r 1dfd28db10bd squishy --- a/squishy Sun Aug 24 20:34:04 2014 +0100 +++ b/squishy Mon Sep 08 12:20:24 2014 +0200 @@ -3,6 +3,7 @@ "sendfilecontent"; "receive"; "version"; + "ping"; "bounce"; "mirror"; "raw";