examples/ibb.lua
author Myhailo Danylenko <isbear@ukrpost.net>
Wed, 28 Nov 2012 20:17:53 +0200
changeset 146 04d19c9c1196
parent 68 742878c74b8e
permissions -rw-r--r--
Fix module loading problem


local lm  = require 'lm'
local ibb = require 'lm.ibb'

local mc_incoming_files = { }

ibb.handler (
	function ( from, accept, reject )
		local fid = #mc_incoming_files + 1
		mc_incoming_files[fid] = {
				from   = from,
				accept =
					function ( name )
						mc_incoming_files[fid].name = name
						accept (
							function ( data )
								local h = io.open ( mc_incoming_files[fid].name, 'w' )
								if not h then
									print ( 'Cannot open output file: ' .. mc_incoming_files[fid].name )
									return
								end
								h:write ( data )
								h:close ()
								print ( 'Stream ' .. fid .. ' successfully saved to ' .. mc_incoming_files[fid].name )
								mc_incoming_files[fid] = nil
							end,
							function ( mesg )
								main.print_info ( from, 'Stream error: ' .. mesg )
								mc_incoming_files[fid] = nil -- XXX
							end )
					end,
				reject =
					function ()
						reject ()
						print ( 'Stream ' .. fid .. ' rejected' )
						mc_incoming_files[fid] = nil
					end,
		}
		main.print_info ( from, from .. ' wants you to receive stream. Use /ibb [accept|reject] ' .. fid .. ' to process his request.' )
	end )

local ibb_sid = 0

main.command ( 'ibb',
	function ( args )
		local action = args[1]
		if action == 'send' then
			local who
			if args.t then
				who = args.t
			else
				who = main.full_jid ()
			end
			local fname = args[2]
			local conn  = lm.connection.bless ( main.connection () )
			local sid   = ibb_sid
			ibb_sid     = ibb_sid + 1
			local stream = ibb.new ( conn, who, 4096, sid )
			stream:open (
				function ()
					main.print_info ( who, 'Stream accepted' )
					local noerr = true
					local h     = io.open ( fname, 'r' )
					if not h then
						print ( 'Cannot open file ' .. fname )
						return
					end
					local data = h:read ( '*a' ) -- In fact, it is better to read it in chunks :/
					h:close ()
					local fail =
						function ( mesg )
							noerr = false
							main.print_info ( who, 'Stream error: ' .. mesg )
						end
					stream:send ( data,
						function ( seq )
							main.print_info ( who, 'Delivery notification of chunk #' .. seq )
						end, fail )
					if noerr then
						stream:close (
							function ()
								main.print_info ( who, 'Stream finalizing notification' )
							end, fail )
					end
					if noerr then
						main.print_info ( who, 'Stream sent' )
					else
						main.print_info ( who, 'Stream error occured' )
					end
				end,
				function ( mesg )
					main.print_info ( who, 'Stream initiation error: ' .. mesg )
				end )
		elseif action == 'accept' then
			local id = tonumber(args[2])
			if mc_incoming_files[id] then
				mc_incoming_files[id].accept ( args[3] )
			end
		elseif action == 'reject' then
			local id = tonumber(args[2])
			if mc_incoming_files[id] then
				mc_incoming_files[id].reject ()
			end
		else
			local text = ''
			for sid, data in pairs ( mc_incoming_files ) do
				text = text .. '\n' ..  sid .. ': ' .. data.from .. ' --> ' .. ( data.name or '?' )
			end
			if text ~= '' then
				print ( 'List of incoming streams:' .. text )
			else
				print ( 'No streams' )
			end
		end
	end, true, { "send", "accept", "reject" } )


commands_help['ibb'] = "[[-t target_jid] send filename | accept sid filename | reject sid]\n\nRequests, accepts or rejects sending file via in-band bytestream."

local ibb_handler            = lm.message_handler.new ( ibb.iq_handler )
local ibb_handler_registered = false

hooks_d['hook-post-connect'].ibb =
	function ( args )
		lm.connection.bless( main.connection () ):handler ( ibb_handler, 'iq', 'normal' )
		ibb_handler_registered = true
		hooks_d['hook-post-connect'].ibb = nil
		hooks_d['hook-quit'].ibb =
			function ( args )
				if ibb_handler_registered then
					lm.connection.bless( main.connection () ):handler ( ibb_handler, 'iq' )
				end
			end
	end

main.add_feature ( 'http://jabber.org/protocol/ibb' )

-- vim: se ts=4: --