clix/archive.lua

Mon, 08 Feb 2021 22:59:49 +0100

author
Kim Alvefur <zash@zash.se>
date
Mon, 08 Feb 2021 22:59:49 +0100
changeset 148
27a9f28724d3
parent 147
0bc82a318c45
child 159
68e09745d928
permissions
-rw-r--r--

clix.archive: Add 'irc' output format, useful for MUC export

local jid_split = require"util.jid".split;
local bare_jid = require"util.jid".bare;
local parse_datetime = require"util.datetime".parse;
return function (opts, arg)
	if opts.short_help then
		print("Fetch archived messages");
		return;
	end

	local reverse = opts.before;
	if opts.start then
		opts.start = parse_datetime(opts.start);
	end
	if opts["end"] then
		opts["end"] = parse_datetime(opts["end"]);
	end
	local selfjid;
	local function print_message(i)
		-- TODO Roster lookup
		local m = i.message;
		if not m:get_child("body") then return end
		local a = m.attr;
		if i.stamp then
			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));
		end
		if a.from and bare_jid(a.from) ~= selfjid then
			print("From ".. bare_jid(a.from));
		end
		print(m:get_child_text"body");
		print"";
	end
	if opts.format == "raw" then
		local st = require"util.stanza";
		local datetime = require"util.datetime".datetime;
		function print_message(i)
		print(st.stanza("forwarded",{xmlns="urn:xmpp:forward:0"})
			:tag("delay", {xmlns="urn:xmpp:delay", stamp=datetime(i.stamp)}):up()
			:add_child(i.message));
		end
	elseif opts.format == "irc" then
		local date;
		local os_date = os.date;
		function print_message(i)
			local m = i.message;
			local body = m:get_child_text("body");
			local a = m.attr;
			local _, _, nick = jid_split(a.from);

			local curdate = os_date("%F", i.stamp);
			if date ~= curdate then
				print("-!- "..curdate);
				date = curdate;
			end
			if nick and body then
				print(("%s <%s> %s"):format(os_date("%T", i.stamp), nick, body));
			end
		end
	end

	local function on_connect(conn)
		if opts.debug then
			conn:hook("stanza-out", print);
			conn:hook("stanza", print);
		end
		selfjid = bare_jid(conn.jid);
		local function handle_results(ok, result)
			for i=1,#result do
				print_message(result[i]);
			end
			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
					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
					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
		conn:add_plugin"archive";
		-- TODO conn:add_plugin"roster";
		-- c.roster:fetch(function()
		conn:query_archive(opts.to, opts, handle_results);
	end
	clix_connect(opts, on_connect);
end

mercurial