.yardoc/objects/root.dat in safubot-0.0.2 vs .yardoc/objects/root.dat in safubot-0.0.3

- old
+ new

@@ -1,6 +1,6 @@ -{d: rooto:"YARD::CodeObjects::RootObject:@childrenIC:&YARD::CodeObjects::CodeObjectList[o:$YARD::CodeObjects::ModuleObject;IC;[o:$YARD::CodeObjects::MethodObject: @scope: +{l: rooto:"YARD::CodeObjects::RootObject:@childrenIC:&YARD::CodeObjects::CodeObjectList[o:$YARD::CodeObjects::ModuleObject;IC;[o:$YARD::CodeObjects::MethodObject: @scope: class:@visibility: public: @pathI"Safubot.mode:EF:@parameters[: @files[[I"lib/safubot.rb;Ti:@current_file_has_commentsF: @name: mode:@source_type: ruby: @tags[:@docstringIC:YARD::Docstring"(Returns the value of attribute mode ;F: @object@ : @summary0:@hash_flagF:@ref_tags[;[: @allI"(Returns the value of attribute mode;F:@namespace@: @sourceI"def mode @@ -13,50 +13,67 @@ param;F: @textI",the value to set the attribute mode to.;F;I" value;F: @types0;@;I"QSets the attribute mode @param value the value to set the attribute mode to.;F; @;!I")def mode=(value) @mode = value -end;F;"I"def mode=(value);F;#0;$To:#YARD::CodeObjects::ClassObject;IC;[o; -; : instance; ;;I"Safubot::Request#callback;F;[;[[I"lib/safubot/bot.rb;Ti;T;: callback;;;[;IC;"LIf a callback is set, responses will be sent to it instead of Response. ;F;@+;0;F;[;[;I"LIf a callback is set, responses will be sent to it instead of Response.;F:@line_rangeo: +end;F;"I"def mode=(value);F;#0;$To; +; : instance; ;;I"Safubot#error_report;F;[["e0;[[I"lib/safubot/bot.rb;Ti ;T;:error_report;;;[;IC;"8Pretty-printing of Exceptions and their backtraces. ;F;@);0;T;[;[o;& +;'I" +param;F;(I"An Exception to print.;F;I"e;F;)0;@);I"Y +Pretty-printing of Exceptions and their backtraces. +@param e An Exception to print.;F:@line_rangeo: Range: exclF: -begini:endi; @);!I"!def callback - @callback -end;F;"I"def callback;F;#0;$To; -; ;+; ;;I"Safubot::Request#callback=;F;[[I" -value;F0;[[@0i;T;:callback=;;;[;IC;"LIf a callback is set, responses will be sent to it instead of Response. ;F;@9;0;F;[;[;@5;-@6; @);!I"1def callback=(value) - @callback = value -end;F;"I"def callback=(value);F;#0;$T: @owner@):@class_mixinsIC;[;3@):@instance_mixinsIC;[o:YARD::CodeObjects::Proxy : @imethod0:@origname"MongoMapper::Document:@orignamespace@);: Document; o;6 ;70;80;90;:MongoMapper; @): @obj0;<0;3@):@attributesIC:SymbolHash{; IC;>{:@symbolize_valueT;+IC;>{;,IC;>{: read@+: -write@9;?T;?T;?T: @aliases{: @groups[;[[@0i [I"lib/safubot/xmpp.rb;Ti[I"lib/safubot/twitter.rb;Ti+;T;: Request;;; ;;[;IC;"GExtend the Request class with Twitter-related source_type scoping. ;F;@);0;F;[;[;I"GExtend the Request class with Twitter-related source_type scoping.;F;-o;.;/F;0i*;1i*; @;I"Safubot::Request;F:@superclasso;6 ;70;80;90;: Object; @;<0;#0;$To;*;IC;[;3@_;4IC;[;3@_;5IC;[o;6 ;70;8"MongoMapper::Document;9@_;;:; o;6 ;70;80;90;;;; @_;<0;<0;3@_;=IC;>{; IC;>{;?T;+IC;>{;?T;?T;B{;C[;[[@0i;T;: Response;;; ;;[;IC;"xDefines elements of the output queue, agnostic of the transfer medium. -May be extended by service-specific modules. ;F;@_;0;F;[;[;I"xDefines elements of the output queue, agnostic of the transfer medium. -May be extended by service-specific modules.;F;-o;.;/F;0i;1i; @;I"Safubot::Response;F;Eo;6 ;70;80;90;;F; @;<0;#0;$To;*;IC;[o; -; ;+; ;;I"Safubot::Bot#opts;F;[;[[@0i+;F;: opts;;;[;IC;"(Returns the value of attribute opts ;F;@w;0;F;[;[;I"(Returns the value of attribute opts;F; @u;!I"def opts +begini :endi ; @;!I"Idef error_report(e) + "#{e.inspect}\n#{e.backtrace.join("\n\t")}" +end;F;"I"def error_report(e);F;#0;$T:@explicitTo:#YARD::CodeObjects::ClassObject;IC;[: @owner@=:@class_mixinsIC;[;3@=:@instance_mixinsIC;[o:YARD::CodeObjects::Proxy : @imethod0:@origname"MongoMapper::Document:@orignamespace@=;: Document; o;6 ;70;80;90;:MongoMapper; @=: @obj0;<0;3@=:@attributesIC:SymbolHash{; IC;>{:@symbolize_valueT;*IC;>{;?T;?T: @aliases{: @groups[;[[@0i[I"lib/safubot/xmpp.rb;Ti[I"lib/safubot/twitter.rb;Ti*;T;: Request;;; ;;[;IC;"wDefines elements of the input queue, agnostic of the transfer medium. +May be extended by service-specific modules. ;F;@=;0;T;[;[;I"x +Defines elements of the input queue, agnostic of the transfer medium. +May be extended by service-specific modules.;F;,o;-;.F;/i;0i; @;I"Safubot::Request;F:@superclasso;6 ;70;80;90;: Object; @;<0;#0;$To;2;IC;[;3@W;4IC;[;3@W;5IC;[o;6 ;70;8"MongoMapper::Document;9@W;;:; o;6 ;70;80;90;;;; @W;<0;<0;3@W;=IC;>{; IC;>{;?T;*IC;>{;?T;?T;@{;A[;[[@0i#;T;: Response;;; ;;[;IC;"xDefines elements of the output queue, agnostic of the transfer medium. +May be extended by service-specific modules. ;F;@W;0;T;[;[;I"y +Defines elements of the output queue, agnostic of the transfer medium. +May be extended by service-specific modules.;F;,o;-;.F;/i ;0i"; @;I"Safubot::Response;F;Co;6 ;70;80;90;;D; @;<0;#0;$To;2;IC;[o; +; ;*; ;;I"Safubot::Bot#opts;F;[;[[@0i4;F;: opts;;;[;IC;"(Returns the value of attribute opts ;F;@o;0;F;[;[;I"(Returns the value of attribute opts;F; @m;!I"def opts @opts end;F;"I" def opts;F;#0;$To; -; ;+; ;;I"Safubot::Bot#twitter;F;[;[[@0i+;F;: twitter;;;[;IC;"+Returns the value of attribute twitter ;F;@~;0;F;[;[;I"+Returns the value of attribute twitter;F; @u;!I"def twitter +; ;*; ;;I"Safubot::Bot#twitter;F;[;[[@0i4;F;: twitter;;;[;IC;"+Returns the value of attribute twitter ;F;@{;0;F;[;[;I"+Returns the value of attribute twitter;F; @m;!I"def twitter @twitter end;F;"I"def twitter;F;#0;$To; -; ;+; ;;I"Safubot::Bot#xmpp;F;[;[[@0i+;F;: xmpp;;;[;IC;"(Returns the value of attribute xmpp ;F;@;0;F;[;[;I"(Returns the value of attribute xmpp;F; @u;!I"def xmpp +; ;*; ;;I"Safubot::Bot#xmpp;F;[;[[@0i4;F;: xmpp;;;[;IC;"(Returns the value of attribute xmpp ;F;@;0;F;[;[;I"(Returns the value of attribute xmpp;F; @m;!I"def xmpp @xmpp end;F;"I" def xmpp;F;#0;$To; -; ;+; ;;I"Safubot::Bot#request_error;F;[["req0["e0;[[@0i-;F;:request_error;;;[;IC;" ;F;@;0;F;[;[;I";F; @u;!I"def request_error(req, e) +; ;*; ;;I"Safubot::Bot#request_error;F;[["req0["e0;[[@0i:;T;:request_error;;;[;IC;"ERecords an error and emits a corresponding :request_error event. ;F;@;0;T;[;[o;& +;'I" +param;F;(I"5The Request for which the error was encountered.;F;I"req;F;)0;@o;& +;'I" +param;F;(I"The caught Exception.;F;I"e;F;)0;@;I" +Records an error and emits a corresponding :request_error event. +@param req The Request for which the error was encountered. +@param e The caught Exception.;F;,o;-;.F;/i6;0i9; @m;!I"def request_error(req, e) Log.error "Error processing #{req.source.class} '#{req.text}': #{e}\n#{e.backtrace.join("\n\t")}" req.errors[Time.now] = e req.save emit(:request_error, req, e) -end;F;"I"def request_error(req, e);F;$T:@explicitTo; -; ;+; ;;I"!Safubot::Bot#process_request;F;[["req0;[[@0i4;F;:process_request;;;[;IC;" ;F;@;0;F;[;[;I";F; @u;!I"def process_request(req) +end;F;"I"def request_error(req, e);F;#0;$T;1To; +; ;*; ;;I"!Safubot::Bot#process_request;F;[["req0;[[@0iD;T;:process_request;;;[;IC;"5Processes an individual request (synchronously). ;F;@;0;T;[;[o;& +;'I" +param;F;(I"An unprocessed Request.;F;I"req;F;)0;@;I"Y +Processes an individual request (synchronously). +@param req An unprocessed Request.;F;,o;-;.F;/iA;0iC; @m;!I"def process_request(req) begin emit(:request, req) rescue Exception => e request_error(req, e) ensure req.processed = true req.save end -end;F;"I"def process_request(req);F;$T;LTo; -; ;+; ;;I"Safubot::Bot#dispatch;F;[[" resp0;[[@0i?;F;: dispatch;;;[;IC;" ;F;@;0;F;[;[;I";F; @u;!I"def dispatch(resp) - # Performs appropriate dispatch operation for response type. +end;F;"I"def process_request(req);F;#0;$T;1To; +; ;*; ;;I"Safubot::Bot#dispatch;F;[[" resp0;[[@0iR;T;: dispatch;;;[;IC;"?Performs appropriate dispatch operation for response type. ;F;@;0;T;[;[o;& +;'I" +param;F;(I"An undispatched Response.;F;I" resp;F;)0;@;I"f +Performs appropriate dispatch operation for response type. +@param resp An undispatched Response.;F;,o;-;.F;/iO;0iQ; @m;!I"def dispatch(resp) begin source = resp.request.source if Safubot::mode != :production Log.info "#{source.class} Response to #{source.username}: #{resp.text}" else @@ -75,177 +92,184 @@ Log.error "Error dispatching #{source.class} '#{resp.text}': #{e}" resp.errors[Time.now] = e resp.save emit(:dispatch_error, resp, e) end -end;F;"I"def dispatch(resp);F;$T;LTo; -; ;+; ;;I"Safubot::Bot#pull;F;[;[[@0iY;F;: pull;;;[;IC;" ;F;@;0;F;[;[;I";F; @u;!I"!def pull +end;F;"I"def dispatch(resp);F;#0;$T;1To; +; ;*; ;;I"Safubot::Bot#pull;F;[;[[@0il;T;: pull;;;[;IC;"^This pulls requests from passive non-streaming sources (currently, the Twitter AJAX API). ;F;@;0;F;[;[;I"^This pulls requests from passive non-streaming sources (currently, the Twitter AJAX API).;F;,o;-;.F;/ik;0ik; @m;!I"!def pull @twitter.pull -end;F;"I"def pull( );F;$T;LTo; -; ;+; ;;I"Safubot::Bot#process;F;[;[[@0i];F;: process;;;[;IC;" ;F;@;0;F;[;[;I";F; @u;!I"ydef process +end;F;"I"def pull( );F;#0;$T;1To; +; ;*; ;;I"Safubot::Bot#process;F;[;[[@0iq;T;: process;;;[;IC;"IGoes through each unprocessed Request and submits it for processing. ;F;@;0;F;[;[;I"IGoes through each unprocessed Request and submits it for processing.;F;,o;-;.F;/ip;0ip; @m;!I"ydef process Request.where(:processed => false).each do |req| concurrently(req) { process_request(req) } end -end;F;"I"def process( );F;$T;LTo; -; ;+; ;;I"Safubot::Bot#respond;F;[["req0[" text0;[[@0if;T;: respond;;;[;IC;""Adds a response to the queue. ;F;@;0;F;[;[o;& +end;F;"I"def process( );F;#0;$T;1To; +; ;*; ;;I"Safubot::Bot#respond;F;[["req0[" text0;[[@0i{;T;: respond;;;[;IC;""Adds a response to the queue. ;F;@;0;T;[;[o;& ;'I" -param;F;(I"Request to respond to.;F;I"req;F;)0;@o;& +param;F;(I"Request to respond to.;F;I"req;F;)0;@o;& ;'I" -param;F;(I"Contents of the response.;F;I" text;F;)0;@;I"jAdds a response to the queue. +param;F;(I"Contents of the response.;F;I" text;F;)0;@;I"k +Adds a response to the queue. @param req Request to respond to. -@param text Contents of the response.;F;-o;.;/F;0ic;1ie; @u;!I"def respond(req, text) +@param text Contents of the response.;F;,o;-;.F;/iw;0iz; @m;!I"def respond(req, text) Log.info("#{req.user.name}: #{req.text}\nsafubot: #{text}") Response.create(:request => req, :text => text) -end;F;"I"def respond(req, text);F;#0;$T;LTo; -; ;+; ;;I"Safubot::Bot#respond_now;F;[["req0[" text0;[[@0il;T;:respond_now;;;[;IC;"Respond + push ;F;@;0;F;[;[;I"Respond + push;F;-o;.;/F;0ik;1ik; @u;!I"?def respond_now(req, text) +end;F;"I"def respond(req, text);F;#0;$T;1To; +; ;*; ;;I"Safubot::Bot#respond_now;F;[["req0[" text0;[[@0i|;T;:respond_now;;;[;IC;"Respond + push ;F;@;0;F;[;[;I"Respond + push;F;,o;-;.F;/i{;0i{; @m;!I"?def respond_now(req, text) respond(req, text) push -end;F;"I"def respond_now(req, text);F;#0;$T;LTo; -; ;+; ;;I"Safubot::Bot#push;F;[;[[@0iq;F;: push;;;[;IC;" ;F;@;0;F;[;[;I";F; @u;!I"Qdef push +end;F;"I"def respond_now(req, text);F;#0;$T;1To; +; ;*; ;;I"Safubot::Bot#push;F;[;[[@0i;T;: push;;;[;IC;"+Dispatches all undispatched Responses. ;F;@;0;F;[;[;I"+Dispatches all undispatched Responses.;F;,o;-;.F;/i;0i; @m;!I"Qdef push Response.where(:dispatched => false).each(&method(:dispatch)) -end;F;"I"def push( );F;$T;LTo; -; ;+; ;;I"Safubot::Bot#cycle;F;[;[[@0iu;F;: -cycle;;;[;IC;" ;F;@;0;F;[;[;I";F; @u;!I"(def cycle - pull; process; push -end;F;"I"def cycle( );F;$T;LTo; -; ;+; ;;I"Safubot::Bot#concurrently;F;[["req0[I" &blk;F0;[[@0i|;T;:concurrently;;;[;IC;"TWraps EM::defer with error handling and response pushing for the given request. ;F;@;0;F;[;[o;& +end;F;"I"def push( );F;#0;$T;1To; +; ;*; ;;I"Safubot::Bot#concurrently;F;[["req0[I" &blk;F0;[[@0i;T;:concurrently;;;[;IC;"UWraps Thread.new with error handling and response pushing for the given request. ;F;@;0;T;[;[o;& ;'I" -param;F;(I"!The Request being processed.;F;I"req;F;)0;@o;& +param;F;(I"!The Request being processed.;F;I"req;F;)0;@o;& ;'I" -param;F;(I"8The operation to be performed in a separate thread.;F;I"blk;F;)0;@;I"Wraps EM::defer with error handling and response pushing for the given request. +param;F;(I"8The operation to be performed in a separate thread.;F;I"blk;F;)0;@;I" +Wraps Thread.new with error handling and response pushing for the given request. @param req The Request being processed. -@param blk The operation to be performed in a separate thread.;F;-o;.;/F;0iy;1i{; @u;!I"def concurrently(req, &blk) - EventMachine::defer do +@param blk The operation to be performed in a separate thread.;F;,o;-;.F;/i;0i; @m;!I"def concurrently(req, &blk) + Thread.new do begin blk.call rescue Exception => e request_error(req, e) end push end -end;F;"I" def concurrently(req, &blk);F;#0;$T;LTo; -; ;+; ;;I"Safubot::Bot#run;F;[;[[@0i;F;:run;;;[;IC;" ;F;@5;0;F;[;[;I";F; @u;!I"#def run - EventMachine::run do - EM::error_handler do |e| - if e.is_a? Interrupt - Log.error("Received interrupt, shutting down.") - stop - else - Log.error("Unhandled exception: #{e}\n#{e.backtrace.join("\t\n")}") - end - end - - cycle - @twitter.run if @twitter - @xmpp.run if @xmpp +end;F;"I" def concurrently(req, &blk);F;#0;$T;1To; +; ;*; ;;I"Safubot::Bot#run_nowait;F;[;[[@0i;T;:run_nowait;;;[;IC;"TRuns an initial request-processing loop and then forks the streaming processes. ;F;@7;0;F;[;[;I"TRuns an initial request-processing loop and then forks the streaming processes.;F;,o;-;.F;/i;0i; @m;!I"]def run_nowait + pull; process; push + @twitter.run if @twitter + @xmpp.run if @xmpp +end;F;"I"def run_nowait( );F;#0;$T;1To; +; ;*; ;;I"Safubot::Bot#run;F;[;[[@0i;T;:run;;;[;IC;"=Calls run_nowait and then waits for all child processes. ;F;@D;0;F;[;[;I"=Calls run_nowait and then waits for all child processes.;F;,o;-;.F;/i;0i; @m;!I"Udef run + run_nowait + begin + Process.waitall + rescue Interrupt + stop end -end;F;"I"def run( );F;$T;LTo; -; ;+; ;;I"Safubot::Bot#stop;F;[;[[@0i;F;: stop;;;[;IC;" ;F;@A;0;F;[;[;I";F; @u;!I"Ydef stop +end;F;"I"def run( );F;#0;$T;1To; +; ;*; ;;I"Safubot::Bot#stop;F;[;[[@0i;T;: stop;;;[;IC;"(Shuts down the streaming processes. ;F;@Q;0;F;[;[;I"(Shuts down the streaming processes.;F;,o;-;.F;/i;0i; @m;!I"Cdef stop @twitter.stop if @twitter @xmpp.stop if @xmpp - EM::stop_event_loop -end;F;"I"def stop( );F;$T;LTo; -; ;+; ;;I" Safubot::Bot#enable_twitter;F;[[" opts"{};[[@0i;F;:enable_twitter;;;[;IC;" ;F;@M;0;F;[;[;I";F; @u;!I"~def enable_twitter(opts={}) +end;F;"I"def stop( );F;#0;$T;1To; +; ;*; ;;I" Safubot::Bot#enable_twitter;F;[[" opts"{};[[@0i;T;:enable_twitter;;;[;IC;"/Initialises Twitter-related functionality. ;F;@^;0;F;[;[;I"/Initialises Twitter-related functionality.;F;,o;-;.F;/i;0i; @m;!I"~def enable_twitter(opts={}) @twitter = Twitter::Bot.new(opts) @twitter.on(:request) do |req| process; push end -end;F;"I" def enable_twitter(opts={});F;$T;LTo; -; ;+; ;;I"Safubot::Bot#enable_xmpp;F;[[" options"{};[[@0i;F;:enable_xmpp;;;[;IC;" ;F;@\;0;F;[;[;I";F; @u;!I"def enable_xmpp(options={}) +end;F;"I" def enable_twitter(opts={});F;#0;$T;1To; +; ;*; ;;I"Safubot::Bot#enable_xmpp;F;[[" options"{};[[@0i;T;:enable_xmpp;;;[;IC;",Initialises XMPP-related functionality. ;F;@n;0;F;[;[;I",Initialises XMPP-related functionality.;F;,o;-;.F;/i;0i; @m;!I"def enable_xmpp(options={}) defaults = { :jid => nil, :password => nil } @xmpp = XMPP::Bot.new(defaults.merge(options)) @xmpp.on(:request) do |req| process; push end -end;F;"I" def enable_xmpp(options={});F;$T;LTo; -; ;+; ;;I"Safubot::Bot#initialize;F;[[" options"{};[[@0i;F;:initialize;;;[;IC;" ;F;@k;0;F;[;[o;& -;'I" return;F;(I"a new instance of Bot;F;0;)[I"Bot;F;@k;I";F; @u;!I"def initialize(options={}) +end;F;"I" def enable_xmpp(options={});F;#0;$T;1To; +; ;*; ;;I"Safubot::Bot#initialize;F;[[" options"{};[[@0i;F;:initialize;;;[;IC;" ;F;@~;0;F;[;[o;& +;'I" return;F;(I"a new instance of Bot;F;0;)[I"Bot;F;@~;I";F; @m;!I"def initialize(options={}) defaults = { :database => "safubot" } @opts = defaults.merge(options) MongoMapper.database = @opts[:database] MongoMapper.connection = Mongo::Connection.new('localhost', 27017, :pool_size => 5) @handlers = {} -end;F;"I"def initialize(options={});F;$T;LTo; -; ;+; ;;I"Safubot::Bot#answer;F;[[" text0[" user"nil;[[I"lib/safubot/test_helper.rb;Ti;;T;: answer;;;[;IC;"/A generic "respond immediately" interface. ;F;@;0;F;[;[;I"/A generic "respond immediately" interface.;F;-o;.;/F;0i:;1i:; @u;!I"def answer(text, user=nil) +end;F;"I"def initialize(options={});F;$T;1To; +; ;*; ;;I"Safubot::Bot#answer;F;[[" text0[" user"nil;[[I"lib/safubot/test_helper.rb;TiB;T;: answer;;;[;IC;"/A generic "respond immediately" interface. ;F;@;0;F;[;[o;& +;'I" +param;F;(I"&The body of a Request to process.;F;I" text;F;)0;@o;& +;'I" +param;F;(I"KThe user sending the request. Defaults to KnownUser.by_name('testing');F;I" user;F;)0;@;I"A generic "respond immediately" interface. +@param text The body of a Request to process. +@param user The user sending the request. Defaults to KnownUser.by_name('testing');F;,o;-;.F;/i?;0iA; @m;!I"def answer(text, user=nil) user ||= KnownUser.by_name('testing') query = Query.create(:user => user, :text => text) req = query.make_request process_request(req) req.responses.first.text -end;F;"I"def answer(text, user=nil);F;#0;$T;LT;3@u;4IC;[;3@u;5IC;[o;6 ;70;80;90;: Evented; @;<o; ;IC;[ +end;F;"I"def answer(text, user=nil);F;#0;$T;1T;3@m;4IC;[;3@m;5IC;[o;6 ;70;80;90;: Evented; @;<o; ;IC;[ o; -; ;+; ;;I"Safubot::Evented#bind;F;[[" evid0[" handler0;[[I"lib/safubot/evented.rb;Ti;T;: bind;;;[;IC;"Binds an event handler, which is a Hash of the form: +; ;*; ;;I"Safubot::Evented#bind;F;[[" evid0[" handler0;[[I"lib/safubot/evented.rb;Ti;T;: bind;;;[;IC;"Binds an event handler, which is a Hash of the form: { :evid => Symbol, :id => Symbol, :repeat => Boolean, :proc => Proc } -See {on}[rdoc-ref:Safubot::Evented#on] and {once}[rdoc-ref:Safubot::Evented#once] for sugar. ;F;@;0;T;[;[;I" +See Evented#on and Evented#once for sugar. ;F;@;0;T;[;[;I" Binds an event handler, which is a Hash of the form: { :evid => Symbol, :id => Symbol, :repeat => Boolean, :proc => Proc } -See {on}[rdoc-ref:Safubot::Evented#on] and {once}[rdoc-ref:Safubot::Evented#once] for sugar.;F;-o;.;/F;0i -;1i; @;!I"def bind(evid, handler) +See Evented#on and Evented#once for sugar.;F;,o;-;.F;/i +;0i; @;!I"def bind(evid, handler) @handlers ||= {} @handlers[evid] ||= {} handler[:evid] = evid handler[:id] ||= @handlers[evid].length @handlers[evid][handler[:id]] = handler -end;F;"I"def bind(evid, handler);F;#0;$T;LTo; -; ;+; ;;I"Safubot::Evented#unbind;F;[[" handler0;[[@i;T;: unbind;;;[;IC;"Unbinds the given handler. ;F;@;0;T;[;[;I" -Unbinds the given handler.;F;-o;.;/F;0i;1i; @;!I"Mdef unbind(handler) +end;F;"I"def bind(evid, handler);F;#0;$T;1To; +; ;*; ;;I"Safubot::Evented#unbind;F;[[" handler0;[[@i;T;: unbind;;;[;IC;"Unbinds the given handler. ;F;@;0;T;[;[;I" +Unbinds the given handler.;F;,o;-;.F;/i;0i; @;!I"Mdef unbind(handler) @handlers[handler[:evid]].delete(handler[:id]) -end;F;"I"def unbind(handler);F;#0;$T;LTo; -; ;+; ;;I"Safubot::Evented#on;F;[[" evid0[" opts"{}[I"&callback;F0;[[@i!;T;:on;;;[;IC;"HBinds a block to the specified event id. -Returns the bound handler. ;F;@;0;T;[;[;I"I +end;F;"I"def unbind(handler);F;#0;$T;1To; +; ;*; ;;I"Safubot::Evented#on;F;[[" evid0[" opts"{}[I"&callback;F0;[[@i!;T;:on;;;[;IC;"HBinds a block to the specified event id. +Returns the bound handler. ;F;@;0;T;[;[;I"I Binds a block to the specified event id. -Returns the bound handler.;F;-o;.;/F;0i;1i ; @;!I"jdef on(evid, opts={}, &callback) +Returns the bound handler.;F;,o;-;.F;/i;0i ; @;!I"jdef on(evid, opts={}, &callback) bind(evid, { :repeat => true, :proc => callback }.merge(opts)) -end;F;"I"%def on(evid, opts={}, &callback);F;#0;$T;LTo; -; ;+; ;;I"Safubot::Evented#once;F;[[" evid0[" opts"{}[I"&callback;F0;[[@i(;T;: once;;;[;IC;"bBinds a block to the specified event id, to be executed only once. -Returns the bound handler. ;F;@;0;T;[;[;I"c +end;F;"I"%def on(evid, opts={}, &callback);F;#0;$T;1To; +; ;*; ;;I"Safubot::Evented#once;F;[[" evid0[" opts"{}[I"&callback;F0;[[@i(;T;: once;;;[;IC;"bBinds a block to the specified event id, to be executed only once. +Returns the bound handler. ;F;@;0;T;[;[;I"c Binds a block to the specified event id, to be executed only once. -Returns the bound handler.;F;-o;.;/F;0i%;1i'; @;!I"mdef once(evid, opts={}, &callback) +Returns the bound handler.;F;,o;-;.F;/i%;0i'; @;!I"mdef once(evid, opts={}, &callback) bind(evid, { :repeat => false, :proc => callback }.merge(opts)) -end;F;"I"'def once(evid, opts={}, &callback);F;#0;$T;LTo; -; ;+; ;;I"Safubot::Evented#emit;F;[[" evid0[I" -*args;F0;[[@i.;T;: emit;;;[;IC;"2Fires an evid event with the given arguments. ;F;@;0;T;[;[;I"3 -Fires an evid event with the given arguments.;F;-o;.;/F;0i,;1i-; @;!I"def emit(evid, *args) +end;F;"I"'def once(evid, opts={}, &callback);F;#0;$T;1To; +; ;*; ;;I"Safubot::Evented#emit;F;[[" evid0[I" +*args;F0;[[@i.;T;: emit;;;[;IC;"2Fires an evid event with the given arguments. ;F;@;0;T;[;[;I"3 +Fires an evid event with the given arguments.;F;,o;-;.F;/i,;0i-; @;!I"def emit(evid, *args) return unless @handlers && @handlers[evid] @handlers[evid].each do |id, handler| begin handler[:proc].call(*args) ensure @handlers[evid].delete(id) if !handler[:repeat] end end -end;F;"I"def emit(evid, *args);F;#0;$T;LT;3@;4IC;[;3@;5IC;[;3@;=IC;>{; IC;>{;?T;+IC;>{;?T;?T;B{;C[;[[@i ;T;;\;;; ;;[;IC;">A mixin granting simple event firing and handler binding. ;F;@;0;T;[;[;I"? -A mixin granting simple event firing and handler binding.;F;-o;.;/F;0i;1i; @;I"Safubot::Evented;F;$T;#0;3@u;=IC;>{; IC;>{;?T;+IC;>{;HIC;>{;@@w;A0;?T;IIC;>{;@@~;A0;?T;JIC;>{;@@;A0;?T;?T;?T;B{;C[;[[@0i([@i9;F;:Bot;;; ;;[;IC;" ;F;@u;0;F;[;[;I";F; @;I"Safubot::Bot;F;Eo;6 ;70;80;90;;F; @;<0;$To; ;IC;[o; -; ; ; ;;I"Safubot::Log.path;F;[;[[I"lib/safubot/log.rb;Ti ;F;: path;;;[;IC;"(Returns the value of attribute path ;F;@;0;F;[;[;I"(Returns the value of attribute path;F; @;!I"def path +end;F;"I"def emit(evid, *args);F;#0;$T;1T;3@;4IC;[;3@;5IC;[;3@;=IC;>{; IC;>{;?T;*IC;>{;?T;?T;@{;A[;[[@i ;T;;Y;;; ;;[;IC;">A mixin granting simple event firing and handler binding. ;F;@;0;T;[;[;I"? +A mixin granting simple event firing and handler binding.;F;,o;-;.F;/i;0i; @;I"Safubot::Evented;F;#0;$T;3@m;=IC;>{; IC;>{;?T;*IC;>{;FIC;>{: read@o: +write0;?T;GIC;>{;_@{;`0;?T;HIC;>{;_@;`0;?T;?T;?T;@{;A[;[[@0i1[@i>;T;:Bot;;; ;;[;IC;"The main event-processing class. You are encouraged to +inherit from this class when building your own bot, but +delegation is also entirely feasible. ;F;@m;0;T;[;[;I" +The main event-processing class. You are encouraged to +inherit from this class when building your own bot, but +delegation is also entirely feasible.;F;,o;-;.F;/i-;0i0; @;I"Safubot::Bot;F;Co;6 ;70;80;90;;D; @;<0;#0;$To; ;IC;[o; +; ; ; ;;I"Safubot::Log.path;F;[;[[I"lib/safubot/log.rb;Ti ;F;: path;;;[;IC;"(Returns the value of attribute path ;F;@1;0;F;[;[;I"(Returns the value of attribute path;F; @/;!I"def path @path end;F;"I" def path;F;#0;$To; -; ; ; ;;I"Safubot::Log.path=;F;[["str0;[[@i;T;: -path=;;;[;IC;"1Commence logging to the specified file path. ;F;@";0;F;[;[;I"1Commence logging to the specified file path.;F;-o;.;/F;0i ;1i ; @;!I"Bdef path=(str) +; ; ; ;;I"Safubot::Log.path=;F;[["str0;[[@6i;T;: +path=;;;[;IC;"1Commence logging to the specified file path. ;F;@>;0;F;[;[;I"1Commence logging to the specified file path.;F;,o;-;.F;/i;0i; @/;!I"Bdef path=(str) @path = str @filelog = Logger.new(str) -end;F;"I"def path=(str);F;#0;$T;LTo; -; ; ; ;;I" Safubot::Log.method_missing;F;[[" method0[I" -*args;F0;[[@i;F;:method_missing;;;[;IC;" ;F;@1;0;F;[;[;I";F; @;!I"def method_missing(method, *args) +end;F;"I"def path=(str);F;#0;$T;1To; +; ; ; ;;I" Safubot::Log.method_missing;F;[[" method0[I" +*args;F0;[[@6i;T;:method_missing;;;[;IC;"-Dispatch method calls to Logger objects. ;F;@M;0;F;[;[;I"-Dispatch method calls to Logger objects.;F;,o;-;.F;/i;0i; @/;!I"def method_missing(method, *args) @stdlog ||= Logger.new(STDOUT) @stdlog.send(method, *args) @filelog.send(method, *args) if @filelog -end;F;"I"&def method_missing(method, *args);F;$T;LT;3@;4IC;[;3@;5IC;[;3@;=IC;>{; IC;>{;cIC;>{;@@;A@";?T;?T;+IC;>{;?T;?T;B{;C[;[[@i ;F;:Log;;; ;;[;IC;" ;F;@;0;F;[;[;I";F; @;I"Safubot::Log;F;$To;*;IC;[ +end;F;"I"&def method_missing(method, *args);F;#0;$T;1T;3@/;4IC;[;3@/;5IC;[;3@/;=IC;>{; IC;>{;bIC;>{;_@1;`@>;?T;?T;*IC;>{;?T;?T;@{;A[;[[@6i +;T;:Log;;; ;;[;IC;"JLog is a simple wrapper for stdout and file-writing Logger instances. ;F;@/;0;F;[;[;I"JLog is a simple wrapper for stdout and file-writing Logger instances.;F;,o;-;.F;/i ;0i ; @;I"Safubot::Log;F;#0;$To;2;IC;[ o; -; ; ; ;;I"Safubot::KnownUser.by_xmpp;F;[["jid0;[[@Ti;T;: by_xmpp;;;[;IC;"<Retrieves or creates a KnownUser by an XMPP JID string. ;F;@S;0;F;[;[;I"<Retrieves or creates a KnownUser by an XMPP JID string.;F;-o;.;/F;0i;1i; @Q;!I"def by_xmpp(jid) +; ; ; ;;I"Safubot::KnownUser.by_xmpp;F;[["jid0;[[@Li;T;: by_xmpp;;;[;IC;"<Retrieves or creates a KnownUser by an XMPP JID string. ;F;@q;0;F;[;[;I"<Retrieves or creates a KnownUser by an XMPP JID string.;F;,o;-;.F;/i;0i; @o;!I"def by_xmpp(jid) jid = jid.split('/')[0] KnownUser.where('jid' => jid).first || KnownUser.create(:jid => jid, :name => jid.split('@')[0]) -end;F;"I"def by_xmpp(jid);F;#0;$T;LTo; -; ; ; ;;I""Safubot::KnownUser.by_twitter;F;[["name_or_id0;[[@Vi;T;:by_twitter;;;[;IC;"HRetrieve or construct a KnownUser by the given Twitter screen name. ;F;@b;0;F;[;[o;& +end;F;"I"def by_xmpp(jid);F;#0;$T;1To; +; ; ; ;;I""Safubot::KnownUser.by_twitter;F;[["name_or_id0;[[@Ni;T;:by_twitter;;;[;IC;"HRetrieve or construct a KnownUser by the given Twitter screen name. ;F;@;0;F;[;[o;& ;'I" -param;F;(I"6The Twitter screen_name (String) or id (Integer).;F;I"name_or_id;F;)0;@b;I"Retrieve or construct a KnownUser by the given Twitter screen name. -@param name_or_id The Twitter screen_name (String) or id (Integer).;F;-o;.;/F;0i;1i; @Q;!I"<def by_twitter(name_or_id) +param;F;(I"6The Twitter screen_name (String) or id (Integer).;F;I"name_or_id;F;)0;@;I"Retrieve or construct a KnownUser by the given Twitter screen name. +@param name_or_id The Twitter screen_name (String) or id (Integer).;F;,o;-;.F;/i;0i; @o;!I"<def by_twitter(name_or_id) user = if name_or_id.is_a? String KnownUser.where('twitter.screen_name' => name_or_id).first else KnownUser.where('twitter.id' => name_or_id).first end @@ -258,18 +282,18 @@ user = KnownUser.where('twitter.screen_name' => details.screen_name).first || KnownUser.create(:twitter => details.attrs, :name => details.screen_name) end user -end;F;"I"def by_twitter(name_or_id);F;#0;$T;LTo; -; ;+; ;;I"Safubot::KnownUser#tweets;F;[;[[@Vi%;T;: tweets;;;[;IC;"?Plucky query with Tweets scoped to this user's twitter id. ;F;@u;0;F;[;[;I"?Plucky query with Tweets scoped to this user's twitter id.;F;-o;.;/F;0i$;1i$; @Q;!I"Odef tweets +end;F;"I"def by_twitter(name_or_id);F;#0;$T;1To; +; ;*; ;;I"Safubot::KnownUser#tweets;F;[;[[@Ni%;T;: tweets;;;[;IC;"?Plucky query with Tweets scoped to this user's twitter id. ;F;@;0;F;[;[;I"?Plucky query with Tweets scoped to this user's twitter id.;F;,o;-;.F;/i$;0i$; @o;!I"Odef tweets Twitter::Tweet.where('raw.user.id' => self.twitter['id']) -end;F;"I"def tweets( );F;#0;$T;LTo; -; ;+; ;;I"Safubot::KnownUser#merge;F;[[" user0;[[I"lib/safubot/known_user.rb;Ti;T;: +end;F;"I"def tweets( );F;#0;$T;1To; +; ;*; ;;I"Safubot::KnownUser#merge;F;[[" user0;[[I"lib/safubot/known_user.rb;Ti;T;: merge;;;[;IC;"gCombines the service-specific identities of two users to -form a cohesive picture of an individual. ;F;@;0;F;[;[;I"gCombines the service-specific identities of two users to -form a cohesive picture of an individual.;F;-o;.;/F;0i;1i; @Q;!I"Adef merge(user) +form a cohesive picture of an individual. ;F;@;0;F;[;[;I"gCombines the service-specific identities of two users to +form a cohesive picture of an individual.;F;,o;-;.F;/i;0i; @o;!I"Adef merge(user) self.keys.keys.each do |key| Log.info "#{key.inspect} #{self[key].inspect} #{user[key].inspect}" self[key] = user[key] if self[key].nil? || (self[key].respond_to?(:empty?) && self[key].empty?) end @@ -278,56 +302,55 @@ end save! user.destroy -end;F;"I"def merge(user);F;#0;$T;LTo; -; ; ; ;;I"Safubot::KnownUser.by_name;F;[[" name0;[[@i;T;: by_name;;;[;IC;"+Retrieves user by internal identifier. ;F;@;0;F;[;[;I"+Retrieves user by internal identifier.;F;-o;.;/F;0i;1i; @Q;!I"edef by_name(name) +end;F;"I"def merge(user);F;#0;$T;1To; +; ; ; ;;I"Safubot::KnownUser.by_name;F;[[" name0;[[@i;T;: by_name;;;[;IC;"+Retrieves user by internal identifier. ;F;@;0;F;[;[;I"+Retrieves user by internal identifier.;F;,o;-;.F;/i;0i; @o;!I"edef by_name(name) KnownUser.where(:name => name).first || KnownUser.create(:name => name) -end;F;"I"def by_name(name);F;#0;$T;LT;3@Q;4IC;[;3@Q;5IC;[o;6 ;70;8"MongoMapper::Document;9@Q;;:; o;6 ;70;80;90;;;; @Q;<0;<0;3@Q;=IC;>{; IC;>{;?T;+IC;>{;?T;?T;B{;C[;[ [@i [@Ti -[@Vi -[@i ;T;:KnownUser;;; ;;[;IC;"General identity cache. Extended by service-specific modules. -A single class in order to allow linking of identity between services. ;F;@Q;0;F;[;[;I"General identity cache. Extended by service-specific modules. -A single class in order to allow linking of identity between services.;F;-o;.;/F;0i;1i; @;I"Safubot::KnownUser;F;Eo;6 ;70;80;90;;F; @;<0;#0;$To; ;IC;[o;*;IC;[ o; -; ; ; ;;I" Safubot::XMPP::Message.from;F;[["raw0;[[@Ti0;T;: from;;;[;IC;"Creates a new Message. ;F;@;0;F;[;[o;& +end;F;"I"def by_name(name);F;#0;$T;1T;3@o;4IC;[;3@o;5IC;[o;6 ;70;8"MongoMapper::Document;9@o;;:; o;6 ;70;80;90;;;; @o;<0;<0;3@o;=IC;>{; IC;>{;?T;*IC;>{;?T;?T;@{;A[;[ [@i [@Li +[@Ni +[@i ;T;:KnownUser;;; ;;[;IC;"General identity cache. Extended by service-specific modules. +A single class in order to allow linking of identity between services. ;F;@o;0;F;[;[;I"General identity cache. Extended by service-specific modules. +A single class in order to allow linking of identity between services.;F;,o;-;.F;/i;0i; @;I"Safubot::KnownUser;F;Co;6 ;70;80;90;;D; @;<0;#0;$To; ;IC;[o;2;IC;[ o; +; ; ; ;;I" Safubot::XMPP::Message.from;F;[["raw0;[[@Li1;T;: from;;;[;IC;"Creates a new Message. ;F;@;0;F;[;[o;& ;'I" -param;F;(I"2The Blather stanza from which to source data.;F;I"raw;F;)0;@;I"TCreates a new Message. -@param raw The Blather stanza from which to source data.;F;-o;.;/F;0i.;1i/; @;!I"def from(raw) +param;F;(I"2The Blather stanza from which to source data.;F;I"raw;F;)0;@;I"TCreates a new Message. +@param raw The Blather stanza from which to source data.;F;,o;-;.F;/i/;0i0; @;!I"def from(raw) Message.find_by_xmpp_id(raw.id) || Message.create({ :xml => raw.to_xml, :xmpp_id => raw.id, :text => raw.body.strip, :to => raw.to.to_s, :from => raw.from.to_s }) -end;F;"I"def from(raw);F;#0;$T;LTo; -; ;+; ;;I"$Safubot::XMPP::Message#username;F;[;[[@Ti=;T;: username;;;[;IC;"2Retrieves the sender's username from the JID. ;F;@;0;F;[;[;I"2Retrieves the sender's username from the JID.;F;-o;.;/F;0i<;1i<; @;!I"/def username +end;F;"I"def from(raw);F;#0;$T;1To; +; ;*; ;;I"$Safubot::XMPP::Message#username;F;[;[[@Li>;T;: username;;;[;IC;"2Retrieves the sender's username from the JID. ;F;@;0;F;[;[;I"2Retrieves the sender's username from the JID.;F;,o;-;.F;/i=;0i=; @;!I"/def username self.from.split('@')[0] -end;F;"I"def username( );F;#0;$T;LTo; -; ;+; ;;I" Safubot::XMPP::Message#user;F;[;[[@TiB;T;: user;;;[;IC;":Retrieves the KnownUser associated with this Message. ;F;@;0;F;[;[;I":Retrieves the KnownUser associated with this Message.;F;-o;.;/F;0iA;1iA; @;!I"0def user +end;F;"I"def username( );F;#0;$T;1To; +; ;*; ;;I" Safubot::XMPP::Message#user;F;[;[[@LiC;T;: user;;;[;IC;":Retrieves the KnownUser associated with this Message. ;F;@;0;F;[;[;I":Retrieves the KnownUser associated with this Message.;F;,o;-;.F;/iB;0iB; @;!I"0def user KnownUser.by_xmpp(self.from) -end;F;"I"def user( );F;#0;$T;LTo; -; ;+; ;;I"(Safubot::XMPP::Message#make_request;F;[;[[@TiG;T;:make_request;;;[;IC;"0Retrieves or creates an associated Request. ;F;@;0;F;[;[;I"0Retrieves or creates an associated Request.;F;-o;.;/F;0iF;1iF; @;!I"ndef make_request +end;F;"I"def user( );F;#0;$T;1To; +; ;*; ;;I"(Safubot::XMPP::Message#make_request;F;[;[[@LiH;T;:make_request;;;[;IC;"0Retrieves or creates an associated Request. ;F;@;0;F;[;[;I"0Retrieves or creates an associated Request.;F;,o;-;.F;/iG;0iG; @;!I"ndef make_request self.request || Request.create(:user => user, :source => self, :text => self.text) -end;F;"I"def make_request( );F;#0;$T;LT;3@;4IC;[;3@;5IC;[o;6 ;70;8"MongoMapper::Document;9@;;:; o;6 ;70;80;90;;;; @;<0;<0;3@;=IC;>{; IC;>{;?T;+IC;>{;?T;?T;B{;C[;[[@Ti;T;: Message;;; ;;[;IC;"JA Message is a Request source representing a single XMPP chat stanza. ;F;@;0;F;[;[;I"JA Message is a Request source representing a single XMPP chat stanza.;F;-o;.;/F;0i;1i; @;I"Safubot::XMPP::Message;F;Eo;6 ;70;80;90;;F; @;<0;#0;$To;*;IC;[ o; -; ;+; ;;I"Safubot::XMPP::Bot#jid;F;[;[[@TiO;F;:jid;;;[;IC;"'Returns the value of attribute jid ;F;@ ;0;F;[;[;I"'Returns the value of attribute jid;F; @ -;!I"def jid +end;F;"I"def make_request( );F;#0;$T;1T;3@;4IC;[;3@;5IC;[o;6 ;70;8"MongoMapper::Document;9@;;:; o;6 ;70;80;90;;;; @;<0;<0;3@;=IC;>{; IC;>{;?T;*IC;>{;?T;?T;@{;A[;[[@Li ;T;: Message;;; ;;[;IC;"JA Message is a Request source representing a single XMPP chat stanza. ;F;@;0;F;[;[;I"JA Message is a Request source representing a single XMPP chat stanza.;F;,o;-;.F;/i;0i; @;I"Safubot::XMPP::Message;F;Co;6 ;70;80;90;;D; @;<0;#0;$To;2;IC;[o; +; ;*; ;;I"Safubot::XMPP::Bot#jid;F;[;[[@LiP;F;:jid;;;[;IC;"'Returns the value of attribute jid ;F;@*;0;F;[;[;I"'Returns the value of attribute jid;F; @(;!I"def jid @jid end;F;"I" def jid;F;#0;$To; -; ;+; ;;I"Safubot::XMPP::Bot#client;F;[;[[@TiO;F;: client;;;[;IC;"*Returns the value of attribute client ;F;@;0;F;[;[;I"*Returns the value of attribute client;F; @ -;!I"def client +; ;*; ;;I"Safubot::XMPP::Bot#client;F;[;[[@LiP;F;: client;;;[;IC;"*Returns the value of attribute client ;F;@6;0;F;[;[;I"*Returns the value of attribute client;F; @(;!I"def client @client end;F;"I"def client;F;#0;$To; -; ;+; ;;I"Safubot::XMPP::Bot#state;F;[;[[@TiO;F;: -state;;;[;IC;")Returns the value of attribute state ;F;@$;0;F;[;[;I")Returns the value of attribute state;F; @ -;!I"def state +; ;*; ;;I"Safubot::XMPP::Bot#state;F;[;[[@LiP;F;: +state;;;[;IC;")Returns the value of attribute state ;F;@B;0;F;[;[;I")Returns the value of attribute state;F; @(;!I"def state @state end;F;"I"def state;F;#0;$To; -; ;+; ;;I"Safubot::XMPP::Bot#run;F;[;[[@TiR;T;;V;;;[;IC;"6Sets our Blather::Client event processor running. ;F;@0;0;F;[;[;I"6Sets our Blather::Client event processor running.;F;-o;.;/F;0iQ;1iQ; @ -;!I"def run +; ;*; ;;I"Safubot::XMPP::Bot#pid;F;[;[[@LiP;F;:pid;;;[;IC;"'Returns the value of attribute pid ;F;@N;0;F;[;[;I"'Returns the value of attribute pid;F; @(;!I"def pid + @pid +end;F;"I" def pid;F;#0;$To; +; ;*; ;;I"$Safubot::XMPP::Bot#init_blather;F;[;[[@LiS;T;:init_blather;;;[;IC;"6Sets our Blather::Client event processor running. ;F;@Z;0;F;[;[;I"6Sets our Blather::Client event processor running.;F;,o;-;.F;/iR;0iR; @(;!I"udef init_blather @client = Blather::Client.setup(@jid, @password) @client.register_handler(:ready) do Log.info "XMPP client is online at #{@client.jid.stripped} :D" emit(:ready) @@ -343,176 +366,192 @@ emit(:request, Message.from(msg).make_request) end end @client.register_handler(:disconnected) do + sleep 1 # HACK (Mispy): Give the state a chance to change when we're stopped. if @state == :running Log.warn("XMPP disconnected; attempting reconnection in 5 seconds.") -EM::Timer.new(5) { @client.connect } +sleep 5; @client.connect end end @client.register_handler(:error) do |e| - Log.error "Unhandled Blather error: #{$!} #{$@}" + Log.error "Unhandled Blather error: #{error_report(e)}" end - Fiber.new do - begin -@client.run - rescue Exception => e -if e.is_a? Interrupt - raise e -else - Log.error "Blather client exited unexpectedly: #{$!} #{$@}" -end - end - end.resume @state = :running -end;F;"I"def run( );F;#0;$T;LTo; -; ;+; ;;I"Safubot::XMPP::Bot#stop;F;[;[[@Ti{;T;;W;;;[;IC;"#Shuts down the Blather client. ;F;@=;0;F;[;[;I"#Shuts down the Blather client.;F;-o;.;/F;0i;1i; @ -;!I"5def stop - @state = :stopped - @client.close -end;F;"I"def stop( );F;#0;$T;LTo; -; ;+; ;;I"Safubot::XMPP::Bot#send;F;[[" resp0;[[@Ti;T;: send;;;[;IC;""Dispatch a Response via XMPP. ;F;@J;0;F;[;[;I""Dispatch a Response via XMPP.;F;-o;.;/F;0i;1i; @ -;!I"def send(resp) +end;F;"I"def init_blather( );F;#0;$T;1To; +; ;*; ;;I"#Safubot::XMPP::Bot#run_blather;F;[;[[@Liw;T;:run_blather;;;[;IC;"Runs the Blather client. ;F;@g;0;F;[;[;I"Runs the Blather client.;F;,o;-;.F;/iv;0iv; @(;!I"Tdef run_blather + begin + EM::run { @client.run } + rescue Exception => e + unless e.is_a?(Interrupt) || e.is_a?(SignalException) +Log.error "XMPP client exited unexpectedly: #{error_report(e)}" +Log.error "Restarting XMPP client in 5 seconds." +sleep 5; init_blather; run_blather + end + else + Log.info "XMPP client shutdown complete." + end +end;F;"I"def run_blather( );F;#0;$T;1To; +; ;*; ;;I"Safubot::XMPP::Bot#run;F;[;[[@Li;T;;S;;;[;IC;"8Starts our Blather client running in a new process. ;F;@t;0;F;[;[;I"8Starts our Blather client running in a new process.;F;,o;-;.F;/i;0i; @(;!I"hdef run + @pid = Process.fork do + Signal.trap("TERM") { stop } + init_blather + run_blather + end +end;F;"I"def run( );F;#0;$T;1To; +; ;*; ;;I"Safubot::XMPP::Bot#stop;F;[;[[@Li;T;;T;;;[;IC;"#Shuts down the Blather client. ;F;@;0;F;[;[;I"#Shuts down the Blather client.;F;,o;-;.F;/i;0i; @(;!I"odef stop + if @client + @state = :stopped + @client.close + elsif @pid + Process.kill("TERM", @pid) + end +end;F;"I"def stop( );F;#0;$T;1To; +; ;*; ;;I"Safubot::XMPP::Bot#tell;F;[["jid0[" text0;[[@Li;F;: tell;;;[;IC;" ;F;@;0;F;[;[;I";F; @(;!I"vdef tell(jid, text) msg = Blather::Stanza::Message.new - msg.to = resp.request.source.from - msg.body = resp.text + msg.to = jid + msg.body = text @client.write msg -end;F;"I"def send(resp);F;#0;$T;LTo; -; ;+; ;;I""Safubot::XMPP::Bot#initialize;F;[[" opts0;[[@Ti;F;;Z;;;[;IC;" ;F;@Y;0;F;[;[o;& -;'I" return;F;(I"a new instance of Bot;F;0;)[I"Bot;F;@Y;I";F; @ -;!I"cdef initialize(opts) +end;F;"I"def tell(jid, text);F;$T;1To; +; ;*; ;;I"Safubot::XMPP::Bot#send;F;[[" resp0;[[@Li;T;: send;;;[;IC;""Dispatch a Response via XMPP. ;F;@;0;F;[;[;I""Dispatch a Response via XMPP.;F;,o;-;.F;/i;0i; @(;!I"Cdef send(resp) + tell(resp.request.source.from, resp.text) +end;F;"I"def send(resp);F;#0;$T;1To; +; ;*; ;;I""Safubot::XMPP::Bot#initialize;F;[[" opts0;[[@Li;F;;W;;;[;IC;" ;F;@;0;F;[;[o;& +;'I" return;F;(I"a new instance of Bot;F;0;)[I"Bot;F;@;I";F; @(;!I"cdef initialize(opts) @jid = opts[:jid] @password = opts[:password] @state = :stopped -end;F;"I"def initialize(opts);F;$T;LT;3@ -;4IC;[;3@ -;5IC;[o;6 ;70;80;90;;\; @;<@;3@ -;=IC;>{; IC;>{;?T;+IC;>{;rIC;>{;@@ ;A0;?T;sIC;>{;@@;A0;?T;tIC;>{;@@$;A0;?T;?T;?T;B{;C[;[[@TiL;F;;b;;; ;;[;IC;" ;F;@ -;0;F;[;[;I";F; @;I"Safubot::XMPP::Bot;F;Eo;6 ;70;80;90;;F; @;<0;$T;3@;4IC;[;3@;5IC;[;3@;=IC;>{; IC;>{;?T;+IC;>{;?T;?T;B{;C[;[[@Ti;F;: XMPP;;; ;;[;IC;" ;F;@;0;F;[;[;I";F; @;I"Safubot::XMPP;F;$T@o:&YARD::CodeObjects::ConstantObject;[[I"lib/safubot/version.rb;Ti;F;: VERSION;;; ;;[;IC;" ;F;@;0;F;[;[;I";F; @;I"Safubot::VERSION;F: -@linei;""VERSION = "0.0.2";!I"VERSION = "0.0.2";F: @valueI" "0.0.2";F;$To; ;IC;[o;*;IC;[o; -; ; ; ;;I"Safubot::Twitter::Tweet.[];F;[["id0;[[@Vi@;T;:[];;;[;IC;"Quickly look up a Tweet. ;F;@;0;F;[;[o;& +end;F;"I"def initialize(opts);F;$T;1T;3@(;4IC;[;3@(;5IC;[o;6 ;70;80;90;;Y; @;<@;3@(;=IC;>{; IC;>{;?T;*IC;>{ ;qIC;>{;_@*;`0;?T;rIC;>{;_@6;`0;?T;sIC;>{;_@B;`0;?T;tIC;>{;_@N;`0;?T;?T;?T;@{;A[;[[@LiM;F;;a;;; ;;[;IC;" ;F;@(;0;F;[;[;I";F; @;I"Safubot::XMPP::Bot;F;Co;6 ;70;80;90;;D; @;<0;$T;3@;4IC;[;3@;5IC;[;3@;=IC;>{; IC;>{;?T;*IC;>{;?T;?T;@{;A[;[[@Li;T;: XMPP;;; ;;[;IC;"!XMPP-specific functionality. ;F;@;0;F;[;[;I"!XMPP-specific functionality.;F;,o;-;.F;/i;0i; @;I"Safubot::XMPP;F;#0;$T@o:&YARD::CodeObjects::ConstantObject;[[I"lib/safubot/version.rb;Ti;F;: VERSION;;; ;;[;IC;" ;F;@;0;F;[;[;I";F; @;I"Safubot::VERSION;F: +@linei;""VERSION = "0.0.2";!I"VERSION = "0.0.2";F: @valueI" "0.0.2";F;$To; ;IC;[o;2;IC;[o; +; ; ; ;;I"Safubot::Twitter::Tweet.[];F;[["id0;[[@NiA;T;:[];;;[;IC;"Quickly look up a Tweet. ;F;@;0;F;[;[o;& ;'I" -param;F;(I"The Twitter id.;F;I"id;F;)0;@;I"7Quickly look up a Tweet. -@param id The Twitter id.;F;-o;.;/F;0i>;1i?; @;!I"7def [](id) +param;F;(I"The Twitter id.;F;I"id;F;)0;@;I"7Quickly look up a Tweet. +@param id The Twitter id.;F;,o;-;.F;/i?;0i@; @;!I"7def [](id) Tweet.where('raw.id' => id).first -end;F;"I"def [](id);F;#0;$T;LTo; -; ; ; ;;I"!Safubot::Twitter::Tweet.from;F;[[" status0;[[@ViF;T;;m;;;[;IC;"Find or create a Tweet. ;F;@;0;F;[;[o;& +end;F;"I"def [](id);F;#0;$T;1To; +; ; ; ;;I"!Safubot::Twitter::Tweet.from;F;[[" status0;[[@NiG;T;;l;;;[;IC;"Find or create a Tweet. ;F;@ ;0;F;[;[o;& ;'I" -param;F;(I"6An appropriate ::Twitter or ::TweetStream object.;F;I" status;F;)0;@;I"\Find or create a Tweet. -@param status An appropriate ::Twitter or ::TweetStream object.;F;-o;.;/F;0iD;1iE; @;!I"def from(status) +param;F;(I"6An appropriate ::Twitter or ::TweetStream object.;F;I" status;F;)0;@ ;I"\Find or create a Tweet. +@param status An appropriate ::Twitter or ::TweetStream object.;F;,o;-;.F;/iE;0iF; @;!I"def from(status) Tweet.where('raw.id' => status['id']||status.id).first || Tweet.create(:raw => status['attrs']||status) -end;F;"I"def from(status);F;#0;$T;LTo; -; ;+; ;;I"!Safubot::Twitter::Tweet#text;F;[;[[@ViM;T;: text;;;[;IC;"The plain text. ;F;@;0;F;[;[;I"The plain text.;F;-o;.;/F;0iL;1iL; @;!I"$def text +end;F;"I"def from(status);F;#0;$T;1To; +; ;*; ;;I"!Safubot::Twitter::Tweet#text;F;[;[[@NiN;T;: text;;;[;IC;"The plain text. ;F;@;0;F;[;[;I"The plain text.;F;,o;-;.F;/iM;0iM; @;!I"$def text self.raw['text'] -end;F;"I"def text( );F;#0;$T;LTo; -; ;+; ;;I",Safubot::Twitter::Tweet#targetless_text;F;[;[[@ViR;T;:targetless_text;;;[;IC;"-Plain text without the leading mentions. ;F;@;0;F;[;[;I"-Plain text without the leading mentions.;F;-o;.;/F;0iQ;1iQ; @;!I"9def targetless_text +end;F;"I"def text( );F;#0;$T;1To; +; ;*; ;;I",Safubot::Twitter::Tweet#targetless_text;F;[;[[@NiS;T;:targetless_text;;;[;IC;"-Plain text without the leading mentions. ;F;@);0;F;[;[;I"-Plain text without the leading mentions.;F;,o;-;.F;/iR;0iR; @;!I"9def targetless_text text.gsub(/^(@\w+ )+/, '') -end;F;"I"def targetless_text( );F;#0;$T;LTo; -; ;+; ;;I",Safubot::Twitter::Tweet#header_mentions;F;[;[[@ViW;T;:header_mentions;;;[;IC;":Retrieve a substring containing the leading mentions. ;F;@;0;F;[;[;I":Retrieve a substring containing the leading mentions.;F;-o;.;/F;0iV;1iV; @;!I"Tdef header_mentions +end;F;"I"def targetless_text( );F;#0;$T;1To; +; ;*; ;;I",Safubot::Twitter::Tweet#header_mentions;F;[;[[@NiX;T;:header_mentions;;;[;IC;":Retrieve a substring containing the leading mentions. ;F;@6;0;F;[;[;I":Retrieve a substring containing the leading mentions.;F;,o;-;.F;/iW;0iW; @;!I"Tdef header_mentions m = text.match(/(@\w+ )+/) m.nil? ? [] : m[0].split -end;F;"I"def header_mentions( );F;#0;$T;LTo; -; ;+; ;;I"+Safubot::Twitter::Tweet#original_tweet;F;[;[[@Vi];T;:original_tweet;;;[;IC;"CReturns the original tweet of which this is a RT if available. ;F;@;0;F;[;[;I"CReturns the original tweet of which this is a RT if available.;F;-o;.;/F;0i\;1i\; @;!I"fdef original_tweet +end;F;"I"def header_mentions( );F;#0;$T;1To; +; ;*; ;;I"+Safubot::Twitter::Tweet#original_tweet;F;[;[[@Ni^;T;:original_tweet;;;[;IC;"CReturns the original tweet of which this is a RT if available. ;F;@C;0;F;[;[;I"CReturns the original tweet of which this is a RT if available.;F;,o;-;.F;/i];0i]; @;!I"fdef original_tweet self.raw['retweeted_status'] && Tweet.from(self.raw['retweeted_status']) -end;F;"I"def original_tweet( );F;#0;$T;LTo; -; ;+; ;;I"!Safubot::Twitter::Tweet#user;F;[;[[@Vib;T;;o;;;[;IC;":Finds or creates a KnownUser connected to this Tweet. ;F;@;0;F;[;[;I":Finds or creates a KnownUser connected to this Tweet.;F;-o;.;/F;0ia;1ia; @;!I"@def user +end;F;"I"def original_tweet( );F;#0;$T;1To; +; ;*; ;;I"!Safubot::Twitter::Tweet#user;F;[;[[@Nic;T;;n;;;[;IC;":Finds or creates a KnownUser connected to this Tweet. ;F;@P;0;F;[;[;I":Finds or creates a KnownUser connected to this Tweet.;F;,o;-;.F;/ib;0ib; @;!I"@def user KnownUser.by_twitter(self.raw['user']['id']) -end;F;"I"def user( );F;#0;$T;LTo; -; ;+; ;;I"%Safubot::Twitter::Tweet#username;F;[;[[@Vig;T;;n;;;[;IC;""Finds the user's screen_name. ;F;@;0;F;[;[;I""Finds the user's screen_name.;F;-o;.;/F;0if;1if; @;!I"3def username +end;F;"I"def user( );F;#0;$T;1To; +; ;*; ;;I"%Safubot::Twitter::Tweet#username;F;[;[[@Nih;T;;m;;;[;IC;""Finds the user's screen_name. ;F;@];0;F;[;[;I""Finds the user's screen_name.;F;,o;-;.F;/ig;0ig; @;!I"3def username user.twitter['screen_name'] -end;F;"I"def username( );F;#0;$T;LTo; -; ;+; ;;I"&Safubot::Twitter::Tweet#posted_at;F;[;[[@Vil;T;:posted_at;;;[;IC;">Returns a Time object specifying the time of publication. ;F;@;0;F;[;[;I">Returns a Time object specifying the time of publication.;F;-o;.;/F;0ik;1ik; @;!I";def posted_at +end;F;"I"def username( );F;#0;$T;1To; +; ;*; ;;I"&Safubot::Twitter::Tweet#posted_at;F;[;[[@Nim;T;:posted_at;;;[;IC;">Returns a Time object specifying the time of publication. ;F;@j;0;F;[;[;I">Returns a Time object specifying the time of publication.;F;,o;-;.F;/il;0il; @;!I";def posted_at Time.parse(self.raw['created_at']) -end;F;"I"def posted_at( );F;#0;$T;LTo; -; ;+; ;;I")Safubot::Twitter::Tweet#make_request;F;[;[[@Viq;T;;p;;;[;IC;"8Finds or creates a Request sourced from this Tweet. ;F;@!;0;F;[;[;I"8Finds or creates a Request sourced from this Tweet.;F;-o;.;/F;0ip;1ip; @;!I"ydef make_request +end;F;"I"def posted_at( );F;#0;$T;1To; +; ;*; ;;I")Safubot::Twitter::Tweet#make_request;F;[;[[@Nir;T;;o;;;[;IC;"8Finds or creates a Request sourced from this Tweet. ;F;@w;0;F;[;[;I"8Finds or creates a Request sourced from this Tweet.;F;,o;-;.F;/iq;0iq; @;!I"ydef make_request self.request || Request.create(:user => user, :source => self, :text => self.targetless_text) -end;F;"I"def make_request( );F;#0;$T;LT;3@;4IC;[;3@;5IC;[o;6 ;70;8"MongoMapper::Document;9@;;:; o;6 ;70;80;90;;;; @;<0;<0;3@;=IC;>{; IC;>{;?T;+IC;>{;?T;?T;B{;C[;[[@Vi3;T;: +end;F;"I"def make_request( );F;#0;$T;1T;3@;4IC;[;3@;5IC;[o;6 ;70;8"MongoMapper::Document;9@;;:; o;6 ;70;80;90;;;; @;<0;<0;3@;=IC;>{; IC;>{;?T;*IC;>{;?T;?T;@{;A[;[[@Ni4;T;: Tweet;;; ;;[;IC;"Tweet is both a Request source and general-purpose tweet storage. -Mentions are automatically made into Requests, but not timeline tweets. ;F;@;0;F;[;[;I"Tweet is both a Request source and general-purpose tweet storage. -Mentions are automatically made into Requests, but not timeline tweets.;F;-o;.;/F;0i1;1i2; @;I"Safubot::Twitter::Tweet;F;Eo;6 ;70;80;90;;F; @;<0;#0;$To;*;IC;[ +Mentions are automatically made into Requests, but not timeline tweets. ;F;@;0;F;[;[;I"Tweet is both a Request source and general-purpose tweet storage. +Mentions are automatically made into Requests, but not timeline tweets.;F;,o;-;.F;/i2;0i3; @;I"Safubot::Twitter::Tweet;F;Co;6 ;70;80;90;;D; @;<0;#0;$To;2;IC;[ o; -; ; ; ;;I")Safubot::Twitter::DirectMessage.from;F;[[" message0;[[@Vi;T;;m;;;[;IC;"$Find or create a DirectMessage. ;F;@D;0;F;[;[o;& +; ; ; ;;I")Safubot::Twitter::DirectMessage.from;F;[[" message0;[[@Ni;T;;l;;;[;IC;"$Find or create a DirectMessage. ;F;@;0;F;[;[o;& ;'I" -param;F;(I"6An appropriate ::Twitter or ::TweetStream object.;F;I" message;F;)0;@D;I"eFind or create a DirectMessage. -@param message An appropriate ::Twitter or ::TweetStream object.;F;-o;.;/F;0i~;1i; @B;!I"def from(message) +param;F;(I"6An appropriate ::Twitter or ::TweetStream object.;F;I" message;F;)0;@;I"eFind or create a DirectMessage. +@param message An appropriate ::Twitter or ::TweetStream object.;F;,o;-;.F;/i;0i; @;!I"def from(message) DirectMessage.where('raw.id' => message['id']||message.id).first || DirectMessage.create(:raw => message['attrs']||message) -end;F;"I"def from(message);F;#0;$T;LTo; -; ;+; ;;I")Safubot::Twitter::DirectMessage#text;F;[;[[@Vi;T;;|;;;[;IC;"The plain text. ;F;@W;0;F;[;[;I"The plain text.;F;-o;.;/F;0i;1i; @B;!I"$def text +end;F;"I"def from(message);F;#0;$T;1To; +; ;*; ;;I")Safubot::Twitter::DirectMessage#text;F;[;[[@Ni;T;;;;;[;IC;"The plain text. ;F;@;0;F;[;[;I"The plain text.;F;,o;-;.F;/i;0i; @;!I"$def text self.raw['text'] -end;F;"I"def text( );F;#0;$T;LTo; -; ;+; ;;I"-Safubot::Twitter::DirectMessage#username;F;[;[[@Vi;T;;n;;;[;IC;""Finds the user's screen_name. ;F;@d;0;F;[;[;I""Finds the user's screen_name.;F;-o;.;/F;0i;1i; @B;!I"9def username +end;F;"I"def text( );F;#0;$T;1To; +; ;*; ;;I"-Safubot::Twitter::DirectMessage#username;F;[;[[@Ni;T;;m;;;[;IC;""Finds the user's screen_name. ;F;@;0;F;[;[;I""Finds the user's screen_name.;F;,o;-;.F;/i;0i; @;!I"9def username self.raw['sender']['screen_name'] -end;F;"I"def username( );F;#0;$T;LTo; -; ;+; ;;I")Safubot::Twitter::DirectMessage#user;F;[;[[@Vi;T;;o;;;[;IC;"BFinds or creates a KnownUser connected to this DirectMessage. ;F;@q;0;F;[;[;I"BFinds or creates a KnownUser connected to this DirectMessage.;F;-o;.;/F;0i;1i; @B;!I"2def user +end;F;"I"def username( );F;#0;$T;1To; +; ;*; ;;I")Safubot::Twitter::DirectMessage#user;F;[;[[@Ni;T;;n;;;[;IC;"BFinds or creates a KnownUser connected to this DirectMessage. ;F;@;0;F;[;[;I"BFinds or creates a KnownUser connected to this DirectMessage.;F;,o;-;.F;/i;0i; @;!I"2def user KnownUser.by_twitter(username) -end;F;"I"def user( );F;#0;$T;LTo; -; ;+; ;;I"1Safubot::Twitter::DirectMessage#make_request;F;[;[[@Vi;T;;p;;;[;IC;"@Finds or creates a Request sourced from this DirectMessage. ;F;@~;0;F;[;[;I"@Finds or creates a Request sourced from this DirectMessage.;F;-o;.;/F;0i;1i; @B;!I"ndef make_request +end;F;"I"def user( );F;#0;$T;1To; +; ;*; ;;I"1Safubot::Twitter::DirectMessage#make_request;F;[;[[@Ni;T;;o;;;[;IC;"@Finds or creates a Request sourced from this DirectMessage. ;F;@;0;F;[;[;I"@Finds or creates a Request sourced from this DirectMessage.;F;,o;-;.F;/i;0i; @;!I"ndef make_request self.request || Request.create(:user => user, :source => self, :text => self.text) -end;F;"I"def make_request( );F;#0;$T;LT;3@B;4IC;[;3@B;5IC;[o;6 ;70;8"MongoMapper::Document;9@B;;:; o;6 ;70;80;90;;;; @B;<0;<0;3@B;=IC;>{; IC;>{;?T;+IC;>{;?T;?T;B{;C[;[[@Vix;T;:DirectMessage;;; ;;[;IC;"gDirectMessage is a Request source. -All DirectMessages are made into Requests as they are received. ;F;@B;0;F;[;[;I"hDirectMessage is a Request source. -All DirectMessages are made into Requests as they are received. ;F;-o;.;/F;0iv;1iw; @;I"$Safubot::Twitter::DirectMessage;F;Eo;6 ;70;80;90;;F; @;<0;#0;$To;*;IC;[o; -; ;+; ;;I"#Safubot::Twitter::Bot#username;F;[;[[@Vi;F;;n;;;[;IC;",Returns the value of attribute username ;F;@;0;F;[;[;I",Returns the value of attribute username;F; @;!I"!def username +end;F;"I"def make_request( );F;#0;$T;1T;3@;4IC;[;3@;5IC;[o;6 ;70;8"MongoMapper::Document;9@;;:; o;6 ;70;80;90;;;; @;<0;<0;3@;=IC;>{; IC;>{;?T;*IC;>{;?T;?T;@{;A[;[[@Niy;T;:DirectMessage;;; ;;[;IC;"gDirectMessage is a Request source. +All DirectMessages are made into Requests as they are received. ;F;@;0;F;[;[;I"hDirectMessage is a Request source. +All DirectMessages are made into Requests as they are received. ;F;,o;-;.F;/iw;0ix; @;I"$Safubot::Twitter::DirectMessage;F;Co;6 ;70;80;90;;D; @;<0;#0;$To;2;IC;[o; +; ;*; ;;I"#Safubot::Twitter::Bot#username;F;[;[[@Ni;F;;m;;;[;IC;",Returns the value of attribute username ;F;@;0;F;[;[;I",Returns the value of attribute username;F; @;!I"!def username @username end;F;"I"def username;F;#0;$To; -; ;+; ;;I"!Safubot::Twitter::Bot#client;F;[;[[@Vi;F;;s;;;[;IC;"*Returns the value of attribute client ;F;@;0;F;[;[;I"*Returns the value of attribute client;F; @;!I"def client +; ;*; ;;I"!Safubot::Twitter::Bot#client;F;[;[[@Ni;F;;r;;;[;IC;"*Returns the value of attribute client ;F;@;0;F;[;[;I"*Returns the value of attribute client;F; @;!I"def client @client end;F;"I"def client;F;#0;$To; -; ;+; ;;I"Safubot::Twitter::Bot#opts;F;[;[[@Vi;F;;H;;;[;IC;"(Returns the value of attribute opts ;F;@;0;F;[;[;I"(Returns the value of attribute opts;F; @;!I"def opts +; ;*; ;;I"Safubot::Twitter::Bot#opts;F;[;[[@Ni;F;;F;;;[;IC;"(Returns the value of attribute opts ;F;@;0;F;[;[;I"(Returns the value of attribute opts;F; @;!I"def opts @opts end;F;"I" def opts;F;#0;$To; -; ;+; ;;I"Safubot::Twitter::Bot#send;F;[[" resp0;[[@Vi;T;;u;;;[;IC;"@Sends a Twitter-sourced Response to the appropriate target. ;F;@;0;F;[;[;I"@Sends a Twitter-sourced Response to the appropriate target.;F;-o;.;/F;0i;1i; @;!I"]def send(resp) +; ;*; ;;I"!Safubot::Twitter::Bot#stream;F;[;[[@Ni;F;: stream;;;[;IC;"*Returns the value of attribute stream ;F;@;0;F;[;[;I"*Returns the value of attribute stream;F; @;!I"def stream + @stream +end;F;"I"def stream;F;#0;$To; +; ;*; ;;I"Safubot::Twitter::Bot#pid;F;[;[[@Ni;F;;t;;;[;IC;"'Returns the value of attribute pid ;F;@';0;F;[;[;I"'Returns the value of attribute pid;F; @;!I"def pid + @pid +end;F;"I" def pid;F;#0;$To; +; ;*; ;;I"Safubot::Twitter::Bot#send;F;[[" resp0;[[@Ni;T;;x;;;[;IC;"@Sends a Twitter-sourced Response to the appropriate target. ;F;@3;0;F;[;[;I"@Sends a Twitter-sourced Response to the appropriate target.;F;,o;-;.F;/i;0i; @;!I"]def send(resp) source = resp.request.source if source.is_a?(DirectMessage) @client.direct_message_create(source.raw['sender']['screen_name'], resp.text) elsif source.is_a?(Tweet) reply("#{source.header_mentions.join(' ')} #{resp.text}") else raise NotImplementedError, "Don't know how to send response to a #{req.source.class}!" end -end;F;"I"def send(resp);F;#0;$T;LTo; -; ;+; ;;I")Safubot::Twitter::Bot#handle_request;F;[["req0;[[@Vi;T;:handle_request;;;[;IC;"BEmit a request event unless the request is already processed. ;F;@;0;F;[;[;I"BEmit a request event unless the request is already processed.;F;-o;.;/F;0i;1i; @;!I"Wdef handle_request(req) +end;F;"I"def send(resp);F;#0;$T;1To; +; ;*; ;;I")Safubot::Twitter::Bot#handle_request;F;[["req0;[[@Ni;T;:handle_request;;;[;IC;"BEmit a request event unless the request is already processed. ;F;@B;0;F;[;[;I"BEmit a request event unless the request is already processed.;F;,o;-;.F;/i;0i; @;!I"Wdef handle_request(req) emit(:request, req) unless req.nil? || req.processed -end;F;"I"def handle_request(req);F;#0;$T;LTo; -; ;+; ;;I")Safubot::Twitter::Bot#handle_message;F;[[" message0;[[@Vi;T;:handle_message;;;[;IC;":Stores a DM and creates a matching Request as needed. ;F;@;0;F;[;[;I":Stores a DM and creates a matching Request as needed.;F;-o;.;/F;0i;1i; @;!I"~def handle_message(message) +end;F;"I"def handle_request(req);F;#0;$T;1To; +; ;*; ;;I")Safubot::Twitter::Bot#handle_message;F;[[" message0;[[@Ni;T;:handle_message;;;[;IC;":Stores a DM and creates a matching Request as needed. ;F;@Q;0;F;[;[;I":Stores a DM and creates a matching Request as needed.;F;,o;-;.F;/i;0i; @;!I"~def handle_message(message) return if message.sender.screen_name == @username DirectMessage.from(message).make_request -end;F;"I" def handle_message(message);F;#0;$T;LTo; -; ;+; ;;I"'Safubot::Twitter::Bot#handle_tweet;F;[[" status0;[[@Vi;T;:handle_tweet;;;[;IC;"sStores a tweet. If this tweet is directed at us, create a matching Request. -Otherwise, emit a :timeline event. ;F;@;0;F;[;[;I"sStores a tweet. If this tweet is directed at us, create a matching Request. -Otherwise, emit a :timeline event.;F;-o;.;/F;0i;1i; @;!I"def handle_tweet(status) +end;F;"I" def handle_message(message);F;#0;$T;1To; +; ;*; ;;I"'Safubot::Twitter::Bot#handle_tweet;F;[[" status0;[[@Ni;T;:handle_tweet;;;[;IC;"sStores a tweet. If this tweet is directed at us, create a matching Request. +Otherwise, emit a :timeline event. ;F;@`;0;F;[;[;I"sStores a tweet. If this tweet is directed at us, create a matching Request. +Otherwise, emit a :timeline event.;F;,o;-;.F;/i;0i; @;!I"def handle_tweet(status) return if status.user.screen_name == @username if status.text.match(/@#{@username}/i) Tweet.from(status).make_request else emit(:timeline, Tweet.from(status)) end -end;F;"I"def handle_tweet(status);F;#0;$T;LTo; -; ;+; ;;I"'Safubot::Twitter::Bot#reply_header;F;[[" -tweet0;[[@Vi;T;:reply_header;;;[;IC;"MConstructs the appropriate series of mentions for a reply to this tweet. ;F;@;0;F;[;[;I"MConstructs the appropriate series of mentions for a reply to this tweet.;F;-o;.;/F;0i;1i; @;!I"ndef reply_header(tweet) +end;F;"I"def handle_tweet(status);F;#0;$T;1To; +; ;*; ;;I"'Safubot::Twitter::Bot#reply_header;F;[[" +tweet0;[[@Ni;T;:reply_header;;;[;IC;"MConstructs the appropriate series of mentions for a reply to this tweet. ;F;@o;0;F;[;[;I"MConstructs the appropriate series of mentions for a reply to this tweet.;F;,o;-;.F;/i;0i; @;!I"ndef reply_header(tweet) (["@#{tweet.username}"] + (tweet.header_mentions - ["@#{@username}"])).join -end;F;"I"def reply_header(tweet);F;#0;$T;LTo; -; ;+; ;;I" Safubot::Twitter::Bot#reply;F;[[" -tweet0[" text0;[[@Vi;T;: -reply;;;[;IC;"7Replies to a tweet using the appropriate mentions. ;F;@;0;F;[;[o;& +end;F;"I"def reply_header(tweet);F;#0;$T;1To; +; ;*; ;;I" Safubot::Twitter::Bot#reply;F;[[" +tweet0[" text0;[[@Ni;T;: +reply;;;[;IC;"7Replies to a tweet using the appropriate mentions. ;F;@~;0;F;[;[o;& ;'I" param;F;(I""A Tweet object to respond to.;F;I" -tweet;F;)0;@o;& +tweet;F;)0;@~o;& ;'I" -param;F;(I"The response text.;F;I" text;F;)0;@;I"|Replies to a tweet using the appropriate mentions. +param;F;(I"The response text.;F;I" text;F;)0;@~;I"|Replies to a tweet using the appropriate mentions. @param tweet A Tweet object to respond to. -@param text The response text.;F;-o;.;/F;0i;1i; @;!I"}def reply(tweet, text) +@param text The response text.;F;,o;-;.F;/i;0i; @;!I"}def reply(tweet, text) @client.update("#{reply_header(tweet)} #{text}", :in_reply_to_status_id => tweet.raw['id']) -end;F;"I"def reply(tweet, text);F;#0;$T;LTo; -; ;+; ;;I"Safubot::Twitter::Bot#pull;F;[;[[@Vi;T;;O;;;[;IC;"Pulls DMs and mentions using the AJAX API. Used in tandem with the streaming API -to ensure we don't miss too much while we're offline. ;F;@);0;F;[;[;I"Pulls DMs and mentions using the AJAX API. Used in tandem with the streaming API -to ensure we don't miss too much while we're offline.;F;-o;.;/F;0i;1i; @;!I"def pull +end;F;"I"def reply(tweet, text);F;#0;$T;1To; +; ;*; ;;I"Safubot::Twitter::Bot#pull;F;[;[[@Ni;T;;L;;;[;IC;"Pulls DMs and mentions using the AJAX API. Used in tandem with the streaming API +to ensure we don't miss too much while we're offline. ;F;@;0;F;[;[;I"Pulls DMs and mentions using the AJAX API. Used in tandem with the streaming API +to ensure we don't miss too much while we're offline.;F;,o;-;.F;/i;0i; @;!I"vdef pull begin @client.direct_messages.each do |message| handle_message(message) end @@ -520,78 +559,94 @@ handle_tweet(mention) end rescue ::Twitter::Error::ServiceUnavailable Log.error "Twitter: Couldn't pull tweets due to temporary service unavailability." rescue Exception => e - Log.error "Twitter: Unhandled error: #{e}\n#{e.backtrace.join("\n\t")}" + Log.error "Twitter: Unhandled error: #{error_report(e)}" end -end;F;"I"def pull( );F;#0;$T;LTo; -; ;+; ;;I"Safubot::Twitter::Bot#run;F;[;[[@Vi;T;;V;;;[;IC;"+Starts our TweetStream client running. ;F;@6;0;F;[;[;I"+Starts our TweetStream client running.;F;-o;.;/F;0i;1i; @;!I"Cdef run - Fiber.new do - @stream = TweetStream::Client.new(@opts) +end;F;"I"def pull( );F;#0;$T;1To; +; ;*; ;;I"&Safubot::Twitter::Bot#init_stream;F;[;[[@Ni;T;:init_stream;;;[;IC;"(Initializes the TweetStream client. ;F;@;0;F;[;[;I"(Initializes the TweetStream client.;F;,o;-;.F;/i;0i; @;!I"def init_stream + @stream = TweetStream::Client.new(@opts) - @stream.on_direct_message do |message| -dm = handle_message(message) -handle_request(dm.request) - end + @stream.on_direct_message do |message| + req = handle_message(message) + handle_request(req) if req.is_a? Request + end - @stream.on_error do |err| -# HACK (Mispy): For some reason this is a String instead of an Exception. -if err.match(/invalid status code: 401/) - Log.error "TweetStream authentication failure!" -else - Log.error "Unhandled TweetStream error: #{$!} #{$@}" -end + @stream.on_error do |err| + if err.match(/invalid status code: 401/) +Log.error "TweetStream authentication failure!" + else +Log.error "Unhandled TweetStream error: #{error_report($!)}" end + end - begin -@stream.userstream do |status| - tweet = handle_tweet(status) - handle_request(tweet.request) if tweet.is_a? Tweet -end - rescue Exception => e -if e.is_a? Interrupt - exit -else - Log.error "TweetStream event loop exited: #{$!} #{$@}" - Log.error "Reinitialising TweetStream in 5 seconds." - EM::Timer.new(5) { run } -end + @stream.on_inited do + Log.info("TweetStream client is online at @#{@username} :3") + end +end;F;"I"def init_stream( );F;#0;$T;1To; +; ;*; ;;I"%Safubot::Twitter::Bot#run_stream;F;[;[[@Ni;T;:run_stream;;;[;IC;"!Runs the TweetStream client. ;F;@;0;F;[;[;I"!Runs the TweetStream client.;F;,o;-;.F;/i;0i; @;!I"def run_stream + begin + @stream.userstream do |status| +req = handle_tweet(status) +handle_request(req) if req.is_a? Request end - - Log.info("Twitter client is online at @#{@username} :3") - end.resume -end;F;"I"def run( );F;#0;$T;LTo; -; ;+; ;;I"%Safubot::Twitter::Bot#initialize;F;[[" options"{};[[@Vi ;T;;Z;;;[;IC;"qOptions are passed straight through to ::TweetStream and ::Twitter, -but the :username is ours and important. ;F;@C;0;F;[;[o;& -;'I" return;F;(I"a new instance of Bot;F;0;)[I"Bot;F;@C;I"qOptions are passed straight through to ::TweetStream and ::Twitter, -but the :username is ours and important.;F;-o;.;/F;0i;1i; @;!I"ldef initialize(options={}) + rescue Exception => e + unless e.is_a?(Interrupt) || e.is_a?(SignalException) +Log.error "TweetStream client exited unexpectedly: #{error_report(e)}" +Log.error "Restarting TweetStream client in 5 seconds." +sleep 5; init_stream; run_stream + end + else + Log.info("TweetStream client shutdown complete.") + end +end;F;"I"def run_stream( );F;#0;$T;1To; +; ;*; ;;I"Safubot::Twitter::Bot#run;F;[;[[@Ni ;T;;S;;;[;IC;"<Starts our TweetStream client running in a new process. ;F;@;0;F;[;[;I"<Starts our TweetStream client running in a new process.;F;,o;-;.F;/i +;0i +; @;!I"fdef run + @pid = Process.fork do + Signal.trap("TERM") { stop } + init_stream + run_stream + end +end;F;"I"def run( );F;#0;$T;1To; +; ;*; ;;I"Safubot::Twitter::Bot#stop;F;[;[[@Ni;T;;T;;;[;IC;"&Shut down the TweetStream client. ;F;@;0;F;[;[;I"&Shut down the TweetStream client.;F;,o;-;.F;/i;0i; @;!I"Pdef stop + @stream.stop if @stream + Process.kill("TERM", @pid) if @pid +end;F;"I"def stop( );F;#0;$T;1To; +; ;*; ;;I"%Safubot::Twitter::Bot#initialize;F;[[" options"{};[[@Ni;T;;W;;;[;IC;"qOptions are passed straight through to ::TweetStream and ::Twitter, +but the :username is ours and important. ;F;@;0;F;[;[o;& +;'I" return;F;(I"a new instance of Bot;F;0;)[I"Bot;F;@;I"qOptions are passed straight through to ::TweetStream and ::Twitter, +but the :username is ours and important.;F;,o;-;.F;/i;0i; @;!I"ldef initialize(options={}) defaults = { :username => nil, :consumer_key => nil, :consumer_secret => nil, :oauth_token => nil, :oauth_token_secret => nil, :auth_method => :oauth } @opts = defaults.merge(options) DirectMessage.ensure_index('raw.id', :unique => true) @username = @opts[:username] @client = Object::Twitter::Client.new(@opts) -end;F;"I"def initialize(options={});F;#0;$T;LT;3@;4IC;[;3@;5IC;[o;6 ;70;80;90;;\; @;<@;3@;=IC;>{; IC;>{;?T;+IC;>{;nIC;>{;@@;A0;?T;sIC;>{;@@;A0;?T;HIC;>{;@@;A0;?T;?T;?T;B{;C[;[[@Vi;T;;b;;; ;;[;IC;"VA Twitter::Bot instance provides a Safubot::Bot with Twitter-specific processing. ;F;@;0;F;[;[;I"VA Twitter::Bot instance provides a Safubot::Bot with Twitter-specific processing.;F;-o;.;/F;0i;1i; @;I"Safubot::Twitter::Bot;F;Eo;6 ;70;80;90;;F; @;<0;#0;$T;3@;4IC;[;3@;5IC;[;3@;=IC;>{; IC;>{;?T;+IC;>{;?T;?T;B{;C[;[[@Vi0;F;: Twitter;;; ;;[;IC;" ;F;@;0;F;[;[;I";F; @;I"Safubot::Twitter;F;$To; ;IC;[o; -; ; ; ;;I"$Safubot::Test.clean_environment;F;[;[[@i;F;:clean_environment;;;[;IC;" ;F;@~;0;F;[;[;I";F; @|;!I"def clean_environment +end;F;"I"def initialize(options={});F;#0;$T;1T;3@;4IC;[;3@;5IC;[o;6 ;70;80;90;;Y; @;<@;3@;=IC;>{; IC;>{;?T;*IC;>{ +;mIC;>{;_@;`0;?T;rIC;>{;_@;`0;?T;FIC;>{;_@;`0;?T;IC;>{;_@;`0;?T;tIC;>{;_@';`0;?T;?T;?T;@{;A[;[[@Ni;T;;a;;; ;;[;IC;"VA Twitter::Bot instance provides a Safubot::Bot with Twitter-specific processing. ;F;@;0;F;[;[;I"VA Twitter::Bot instance provides a Safubot::Bot with Twitter-specific processing.;F;,o;-;.F;/i;0i; @;I"Safubot::Twitter::Bot;F;Co;6 ;70;80;90;;D; @;<0;#0;$T;3@;4IC;[;3@;5IC;[;3@;=IC;>{; IC;>{;?T;*IC;>{;?T;?T;@{;A[;[[@Ni1;T;: Twitter;;; ;;[;IC;"!XMPP-specific functionality. ;F;@;0;F;[;[;I"!XMPP-specific functionality.;F;,o;-;.F;/i0;0i0; @;I"Safubot::Twitter;F;#0;$To; ;IC;[o; +; ; ; ;;I"$Safubot::Test.clean_environment;F;[;[[@i;T;:clean_environment;;;[;IC;"DSwitches to the "safubot_testing" database and clears all data. ;F;@;0;F;[;[;I"DSwitches to the "safubot_testing" database and clears all data.;F;,o;-;.F;/i;0i; @;!I"def clean_environment MongoMapper.database = "safubot_testing" Request.destroy_all Query.destroy_all Response.destroy_all KnownUser.destroy_all Safubot::mode = :testing $bot = Safubot::Bot.new(:database => "safubot_testing") -end;F;"I"def clean_environment( );F;$T;LTo; -; ; ; ;;I"Safubot::Test.request;F;[[" text0;[[@i#;F;: request;;;[;IC;" ;F;@;0;F;[;[;I";F; @|;!I"ldef request(text) +end;F;"I"def clean_environment( );F;#0;$T;1To; +; ; ; ;;I"Safubot::Test.request;F;[[" text0;[[@i';T;: request;;;[;IC;"-Creates a Query-sourced testing Request. ;F;@#;0;F;[;[o;& +;'I" +param;F;(I"The body of the Request.;F;I" text;F;)0;@#;I"RCreates a Query-sourced testing Request. +@param text The body of the Request.;F;,o;-;.F;/i%;0i&; @;!I"ldef request(text) Query.create(:user => KnownUser.by_name('testing'), :text => text).make_request -end;F;"I"def request(text);F;$T;LT;3@|;4IC;[;3@|;5IC;[;3@|;=IC;>{; IC;>{;?T;+IC;>{;?T;?T;B{;C[;[[@i;F;: Test;;; ;;[;IC;" ;F;@|;0;F;[;[;I";F; @;I"Safubot::Test;F;$To;*;IC;[o; -; ;+; ;;I" Safubot::Query#make_request;F;[;[[@i4;F;;p;;;[;IC;" ;F;@;0;F;[;[;I";F; @;!I"tdef make_request +end;F;"I"def request(text);F;#0;$T;1T;3@;4IC;[;3@;5IC;[;3@;=IC;>{; IC;>{;?T;*IC;>{;?T;?T;@{;A[;[[@i;T;: Test;;; ;;[;IC;"9Helpful methods for testing either via RSpec or IRB. ;F;@;0;F;[;[;I"9Helpful methods for testing either via RSpec or IRB.;F;,o;-;.F;/i;0i; @;I"Safubot::Test;F;#0;$To;2;IC;[o; +; ;*; ;;I" Safubot::Query#make_request;F;[;[[@i9;T;;o;;;[;IC;"6Find or create a Request sourced from this Query. ;F;@H;0;F;[;[;I"6Find or create a Request sourced from this Query.;F;,o;-;.F;/i8;0i8; @F;!I"tdef make_request self.request || Request.create(:user => self.user, :text => self.text, :source => self) -end;F;"I"def make_request( );F;$T;LT;3@;4IC;[;3@;5IC;[o;6 ;70;8"MongoMapper::Document;9@;;:; o;6 ;70;80;90;;;; @;<0;<0;3@;=IC;>{; IC;>{;?T;+IC;>{;?T;?T;B{;C[;[[@i);F;: -Query;;; ;;[;IC;" ;F;@;0;F;[;[;I";F; @;I"Safubot::Query;F;Eo;6 ;70;80;90;;F; @;<0;$T;3@;4IC;[;3@;5IC;[;3@;=IC;>{; IC;>{;IC;>{;@@ -;A@;?T;?T;+IC;>{;?T;?T;B{;C[;[[@i[@0i[@i[@Ti [@i[@i[@Vi [@i[@i;F;: Safubot;;; ;;[;IC;" ;F;@;0;F;[;[;I";F; @;I" Safubot;F;3@;4IC;[;3@;5IC;[;3@;=IC;>{; IC;>{;?T;+IC;>{;?T;?T;B{;C[;[;F;;;;; ;;[;IC;" ;F;@;0;F;[;[;I";F; 0;I";F;@:Safubot.mode@ -:Safubot.mode=@:Safubot::Request@):Safubot::Request#callback@+:Safubot::Request#callback=@9:Safubot::Response@_:Safubot::Bot@u:Safubot::Bot#opts@w:Safubot::Bot#twitter@~:Safubot::Bot#xmpp@:Safubot::Bot#request_error@:!Safubot::Bot#process_request@:Safubot::Bot#dispatch@:Safubot::Bot#pull@:Safubot::Bot#process@:Safubot::Bot#respond@:Safubot::Bot#respond_now@:Safubot::Bot#push@:Safubot::Bot#cycle@:Safubot::Bot#concurrently@:Safubot::Bot#run@5:Safubot::Bot#stop@A: Safubot::Bot#enable_twitter@M:Safubot::Bot#enable_xmpp@\:Safubot::Bot#initialize@k:Safubot::Log@:Safubot::Log.path@:Safubot::Log.path=@": Safubot::Log.method_missing@1:Safubot::KnownUser@Q:Safubot::KnownUser.by_xmpp@S:Safubot::XMPP@:Safubot::XMPP::Message@: Safubot::XMPP::Message.from@:$Safubot::XMPP::Message#username@: Safubot::XMPP::Message#user@:(Safubot::XMPP::Message#make_request@:Safubot::XMPP::Bot@ -:Safubot::XMPP::Bot#jid@ :Safubot::XMPP::Bot#client@:Safubot::XMPP::Bot#state@$:Safubot::XMPP::Bot#run@0:Safubot::XMPP::Bot#stop@=:Safubot::XMPP::Bot#send@J:"Safubot::XMPP::Bot#initialize@Y:Safubot::Evented@:Safubot::Evented#bind@:Safubot::Evented#unbind@:Safubot::Evented#on@:Safubot::Evented#once@:Safubot::Evented#emit@:Safubot::VERSION@:"Safubot::KnownUser.by_twitter@b:Safubot::KnownUser#tweets@u:Safubot::Twitter@:Safubot::Twitter::Tweet@:Safubot::Twitter::Tweet.[]@:!Safubot::Twitter::Tweet.from@:!Safubot::Twitter::Tweet#text@:,Safubot::Twitter::Tweet#targetless_text@:,Safubot::Twitter::Tweet#header_mentions@:+Safubot::Twitter::Tweet#original_tweet@:!Safubot::Twitter::Tweet#user@:%Safubot::Twitter::Tweet#username@:&Safubot::Twitter::Tweet#posted_at@:)Safubot::Twitter::Tweet#make_request@!:$Safubot::Twitter::DirectMessage@B:)Safubot::Twitter::DirectMessage.from@D:)Safubot::Twitter::DirectMessage#text@W:-Safubot::Twitter::DirectMessage#username@d:)Safubot::Twitter::DirectMessage#user@q:1Safubot::Twitter::DirectMessage#make_request@~:Safubot::Twitter::Bot@:#Safubot::Twitter::Bot#username@:!Safubot::Twitter::Bot#client@:Safubot::Twitter::Bot#opts@:Safubot::Twitter::Bot#send@:)Safubot::Twitter::Bot#handle_request@:)Safubot::Twitter::Bot#handle_message@:'Safubot::Twitter::Bot#handle_tweet@:'Safubot::Twitter::Bot#reply_header@: Safubot::Twitter::Bot#reply@:Safubot::Twitter::Bot#pull@):Safubot::Twitter::Bot#run@6:%Safubot::Twitter::Bot#initialize@C:Safubot::KnownUser#merge@:Safubot::KnownUser.by_name@:Safubot::Test@|:$Safubot::Test.clean_environment@~:Safubot::Test.request@:Safubot::Query@: Safubot::Query#make_request@:Safubot::Bot#answer@ +end;F;"I"def make_request( );F;#0;$T;1T;3@F;4IC;[;3@F;5IC;[o;6 ;70;8"MongoMapper::Document;9@F;;:; o;6 ;70;80;90;;;; @F;<0;<0;3@F;=IC;>{; IC;>{;?T;*IC;>{;?T;?T;@{;A[;[[@i.;T;: +Query;;; ;;[;IC;"'Generic mediumless Request source. ;F;@F;0;F;[;[;I"'Generic mediumless Request source.;F;,o;-;.F;/i-;0i-; @;I"Safubot::Query;F;Co;6 ;70;80;90;;D; @;<0;#0;$T;3@;4IC;[;3@;5IC;[;3@;=IC;>{; IC;>{;IC;>{;_@ +;`@;?T;?T;*IC;>{;?T;?T;@{;A[;[[@i[@0i[@6i[@Li [@i[@i[@Ni [@i[@i;F;: Safubot;;; ;;[;IC;" ;F;@;0;F;[;[;I";F; @;I" Safubot;F;3@;4IC;[;3@;5IC;[;3@;=IC;>{; IC;>{;?T;*IC;>{;?T;?T;@{;A[;[;F;;;;; ;;[;IC;" ;F;@;0;F;[;[;I";F; 0;I";F;@:Safubot.mode@ +:Safubot.mode=@:Safubot#error_report@):Safubot::Request@=:Safubot::Response@W:Safubot::Bot@m:Safubot::Bot#opts@o:Safubot::Bot#twitter@{:Safubot::Bot#xmpp@:Safubot::Bot#request_error@:!Safubot::Bot#process_request@:Safubot::Bot#dispatch@:Safubot::Bot#pull@:Safubot::Bot#process@:Safubot::Bot#respond@:Safubot::Bot#respond_now@:Safubot::Bot#push@:Safubot::Bot#concurrently@:Safubot::Bot#run_nowait@7:Safubot::Bot#run@D:Safubot::Bot#stop@Q: Safubot::Bot#enable_twitter@^:Safubot::Bot#enable_xmpp@n:Safubot::Bot#initialize@~:Safubot::Log@/:Safubot::Log.path@1:Safubot::Log.path=@>: Safubot::Log.method_missing@M:Safubot::KnownUser@o:Safubot::KnownUser.by_xmpp@q:Safubot::XMPP@:Safubot::XMPP::Message@: Safubot::XMPP::Message.from@:$Safubot::XMPP::Message#username@: Safubot::XMPP::Message#user@:(Safubot::XMPP::Message#make_request@:Safubot::XMPP::Bot@(:Safubot::XMPP::Bot#jid@*:Safubot::XMPP::Bot#client@6:Safubot::XMPP::Bot#state@B:Safubot::XMPP::Bot#pid@N:$Safubot::XMPP::Bot#init_blather@Z:#Safubot::XMPP::Bot#run_blather@g:Safubot::XMPP::Bot#run@t:Safubot::XMPP::Bot#stop@:Safubot::XMPP::Bot#tell@:Safubot::XMPP::Bot#send@:"Safubot::XMPP::Bot#initialize@:Safubot::Evented@:Safubot::Evented#bind@:Safubot::Evented#unbind@:Safubot::Evented#on@:Safubot::Evented#once@:Safubot::Evented#emit@:Safubot::VERSION@:"Safubot::KnownUser.by_twitter@:Safubot::KnownUser#tweets@:Safubot::Twitter@:Safubot::Twitter::Tweet@:Safubot::Twitter::Tweet.[]@:!Safubot::Twitter::Tweet.from@ :!Safubot::Twitter::Tweet#text@:,Safubot::Twitter::Tweet#targetless_text@):,Safubot::Twitter::Tweet#header_mentions@6:+Safubot::Twitter::Tweet#original_tweet@C:!Safubot::Twitter::Tweet#user@P:%Safubot::Twitter::Tweet#username@]:&Safubot::Twitter::Tweet#posted_at@j:)Safubot::Twitter::Tweet#make_request@w:$Safubot::Twitter::DirectMessage@:)Safubot::Twitter::DirectMessage.from@:)Safubot::Twitter::DirectMessage#text@:-Safubot::Twitter::DirectMessage#username@:)Safubot::Twitter::DirectMessage#user@:1Safubot::Twitter::DirectMessage#make_request@:Safubot::Twitter::Bot@:#Safubot::Twitter::Bot#username@:!Safubot::Twitter::Bot#client@:Safubot::Twitter::Bot#opts@:!Safubot::Twitter::Bot#stream@:Safubot::Twitter::Bot#pid@':Safubot::Twitter::Bot#send@3:)Safubot::Twitter::Bot#handle_request@B:)Safubot::Twitter::Bot#handle_message@Q:'Safubot::Twitter::Bot#handle_tweet@`:'Safubot::Twitter::Bot#reply_header@o: Safubot::Twitter::Bot#reply@~:Safubot::Twitter::Bot#pull@:&Safubot::Twitter::Bot#init_stream@:%Safubot::Twitter::Bot#run_stream@:Safubot::Twitter::Bot#run@:Safubot::Twitter::Bot#stop@:%Safubot::Twitter::Bot#initialize@:Safubot::KnownUser#merge@:Safubot::KnownUser.by_name@:Safubot::Test@:$Safubot::Test.clean_environment@:Safubot::Test.request@#:Safubot::Query@F: Safubot::Query#make_request@H:Safubot::Bot#answer@ \ No newline at end of file