plugins/jingle_ft.lua

1
local verse = require "verse";
2
local ltn12 = require "ltn12";
3
 
4
local dirsep = package.config:sub(1,1);
5
 
6
local xmlns_jingle_ft = "urn:xmpp:jingle:apps:file-transfer:4";
7
 
8
function verse.plugins.jingle_ft(stream)
9
	stream:hook("ready", function ()
10
		stream:add_disco_feature(xmlns_jingle_ft);
11
	end, 10);
12
 
13
	local ft_content = { type = "file" };
14
 
15
	function ft_content:generate_accept(description, options)
16
		if options and options.save_file then
17
			self.jingle:hook("connected", function ()
18
				local sink = ltn12.sink.file(io.open(options.save_file, "w+"));
19
				self.jingle:set_sink(sink);
20
			end);
21
		end
22
 
23
		return description;
24
	end
25
 
26
	local ft_mt = { __index = ft_content };
27
	stream:hook("jingle/content/"..xmlns_jingle_ft, function (jingle, description_tag)
28
		local file_tag = description_tag:get_child("file");
29
		local file = {
30
			name = file_tag:get_child_text("name");
31
			size = tonumber(file_tag:get_child_text("size"));
32
			desc = file_tag:get_child_text("desc");
33
			date = file_tag:get_child_text("date");
34
		};
35
 
36
		return setmetatable({ jingle = jingle, file = file }, ft_mt);
37
	end);
38
 
39
	stream:hook("jingle/describe/file", function (file_info)
40
		-- Return <description/>
41
		local date;
42
		if file_info.timestamp then
43
			date = os.date("!%Y-%m-%dT%H:%M:%SZ", file_info.timestamp);
44
		end
45
		return verse.stanza("description", { xmlns = xmlns_jingle_ft })
46
			:tag("file")
47
				:tag("name"):text(file_info.filename):up()
48
				:tag("size"):text(tostring(file_info.size)):up()
49
				:tag("date"):text(date):up()
50
				:tag("desc"):text(file_info.description):up()
51
			:up();
52
	end);
53
 
54
	function stream:send_file(to, filename)
55
		local file, err = io.open(filename);
56
		if not file then return file, err; end
57
 
58
		local file_size = file:seek("end", 0);
59
		file:seek("set", 0);
60
 
61
		local source = ltn12.source.file(file);
62
 
63
		local jingle = self:jingle(to);
64
		jingle:offer("file", {
65
			filename = filename:match("[^"..dirsep.."]+$");
66
			size = file_size;
67
		});
68
		jingle:hook("connected", function ()
69
			jingle:set_source(source, true);
70
		end);
71
		return jingle;
72
	end
73
end