clix/archive.lua

Sat, 24 Jun 2023 09:59:07 +0200

author
Kim Alvefur <zash@zash.se>
date
Sat, 24 Jun 2023 09:59:07 +0200
changeset 170
0d561f921c13
parent 168
75e8ca131178
permissions
-rw-r--r--

clix.adhoc: Move stanza to dataform converter here

Removes the need for verse to have a custom util.dataforms fork only for
this

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

	local function parse_datetime(s)
		if s:match("^%d%d:") then
			s = datetime.date().."T"..s;
		end
		if #s < 20 then
			s = s .. ("0000-01-01T00:00:00Z"):sub(#s+1)
		end
		return datetime.parse(s)
	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"prosody.util.stanza";
		local datetime = require"prosody.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(result, err)
			if not result then
				conn:close();
				return;
			end
			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