examples/mc_ibb.lua
changeset 68 742878c74b8e
parent 67 d33ca5572e91
child 69 ab6d4ee8974c
equal deleted inserted replaced
67:d33ca5572e91 68:742878c74b8e
     1 
       
     2 local lm  = require 'lm'
       
     3 local ibb = require 'ibb'
       
     4 
       
     5 local mc_incoming_files = { }
       
     6 
       
     7 ibb.handler (
       
     8 	function ( from, accept, reject )
       
     9 		local fid = #mc_incoming_files + 1
       
    10 		mc_incoming_files[fid] = {
       
    11 				from   = from,
       
    12 				accept =
       
    13 					function ( name )
       
    14 						mc_incoming_files[fid].name = name
       
    15 						accept (
       
    16 							function ( data )
       
    17 								local h = io.open ( mc_incoming_files[fid].name, 'w' )
       
    18 								if not h then
       
    19 									print ( 'Cannot open output file: ' .. mc_incoming_files[fid].name )
       
    20 									return
       
    21 								end
       
    22 								h:write ( data )
       
    23 								h:close ()
       
    24 								print ( 'Stream ' .. fid .. ' successfully saved to ' .. mc_incoming_files[fid].name )
       
    25 								mc_incoming_files[fid] = nil
       
    26 							end,
       
    27 							function ( mesg )
       
    28 								main.print_info ( from, 'Stream error: ' .. mesg )
       
    29 								mc_incoming_files[fid] = nil -- XXX
       
    30 							end )
       
    31 					end,
       
    32 				reject =
       
    33 					function ()
       
    34 						reject ()
       
    35 						print ( 'Stream ' .. fid .. ' rejected' )
       
    36 						mc_incoming_files[fid] = nil
       
    37 					end,
       
    38 		}
       
    39 		main.print_info ( from, from .. ' wants you to receive stream. Use /ibb [accept|reject] ' .. fid .. ' to process his request.' )
       
    40 	end )
       
    41 
       
    42 local ibb_sid = 0
       
    43 
       
    44 main.command ( 'ibb',
       
    45 	function ( args )
       
    46 		local action = args[1]
       
    47 		if action == 'send' then
       
    48 			local who
       
    49 			if args.t then
       
    50 				who = args.t
       
    51 			else
       
    52 				who = main.full_jid ()
       
    53 			end
       
    54 			local fname = args[2]
       
    55 			local conn  = lm.connection.bless ( main.connection () )
       
    56 			local sid   = ibb_sid
       
    57 			ibb_sid     = ibb_sid + 1
       
    58 			local stream = ibb.new ( conn, who, 4096, sid )
       
    59 			stream:open (
       
    60 				function ()
       
    61 					main.print_info ( who, 'Stream accepted' )
       
    62 					local noerr = true
       
    63 					local h     = io.open ( fname, 'r' )
       
    64 					if not h then
       
    65 						print ( 'Cannot open file ' .. fname )
       
    66 						return
       
    67 					end
       
    68 					local data = h:read ( '*a' ) -- In fact, it is better to read it in chunks :/
       
    69 					h:close ()
       
    70 					local fail =
       
    71 						function ( mesg )
       
    72 							noerr = false
       
    73 							main.print_info ( who, 'Stream error: ' .. mesg )
       
    74 						end
       
    75 					stream:send ( data,
       
    76 						function ( seq )
       
    77 							main.print_info ( who, 'Delivery notification of chunk #' .. seq )
       
    78 						end, fail )
       
    79 					if noerr then
       
    80 						stream:close (
       
    81 							function ()
       
    82 								main.print_info ( who, 'Stream finalizing notification' )
       
    83 							end, fail )
       
    84 					end
       
    85 					if noerr then
       
    86 						main.print_info ( who, 'Stream sent' )
       
    87 					else
       
    88 						main.print_info ( who, 'Stream error occured' )
       
    89 					end
       
    90 				end,
       
    91 				function ( mesg )
       
    92 					main.print_info ( who, 'Stream initiation error: ' .. mesg )
       
    93 				end )
       
    94 		elseif action == 'accept' then
       
    95 			local id = tonumber(args[2])
       
    96 			if mc_incoming_files[id] then
       
    97 				mc_incoming_files[id].accept ( args[3] )
       
    98 			end
       
    99 		elseif action == 'reject' then
       
   100 			local id = tonumber(args[2])
       
   101 			if mc_incoming_files[id] then
       
   102 				mc_incoming_files[id].reject ()
       
   103 			end
       
   104 		else
       
   105 			local text = ''
       
   106 			for sid, data in pairs ( mc_incoming_files ) do
       
   107 				text = text .. '\n' ..  sid .. ': ' .. data.from .. ' --> ' .. ( data.name or '?' )
       
   108 			end
       
   109 			if text ~= '' then
       
   110 				print ( 'List of incoming streams:' .. text )
       
   111 			else
       
   112 				print ( 'No streams' )
       
   113 			end
       
   114 		end
       
   115 	end, true, { "send", "accept", "reject" } )
       
   116 
       
   117 
       
   118 commands_help['ibb'] = "[[-t target_jid] send filename | accept sid filename | reject sid]\n\nRequests, accepts or rejects sending file via in-band bytestream."
       
   119 
       
   120 local ibb_handler            = lm.message_handler.new ( ibb.iq_handler )
       
   121 local ibb_handler_registered = false
       
   122 
       
   123 hooks_d['hook-post-connect'].ibb =
       
   124 	function ( args )
       
   125 		lm.connection.bless( main.connection () ):handler ( ibb_handler, 'iq', 'normal' )
       
   126 		ibb_handler_registered = true
       
   127 		hooks_d['hook-post-connect'].ibb = nil
       
   128 		hooks_d['hook-quit'].ibb =
       
   129 			function ( args )
       
   130 				if ibb_handler_registered then
       
   131 					lm.connection.bless( main.connection () ):handler ( ibb_handler, 'iq' )
       
   132 				end
       
   133 			end
       
   134 	end
       
   135 
       
   136 main.add_feature ( 'http://jabber.org/protocol/ibb' )
       
   137 
       
   138 -- vim: se ts=4: --