lib/blather/client/dsl.rb in blather-0.4.7 vs lib/blather/client/dsl.rb in blather-0.4.8
- old
+ new
@@ -1,140 +1,264 @@
require File.join(File.dirname(__FILE__), 'client')
module Blather
+
+ # # Blather DSL
+ #
+ # The DSL is a set of methods that enables you to write cleaner code. Being a
+ # module means it can be included in or extend any class you may want to
+ # create.
+ #
+ # Every stanza handler is registered as a method on the DSL.
+ #
+ # @example Include the DSL in the top level namespace.
+ #
+ # require 'blather/client'
+ # when_ready { puts "Connected ! send messages to #{jid.stripped}." }
+ #
+ # subscription :request? do |s|
+ # write_to_stream s.approve!
+ # end
+ #
+ # message :chat?, :body => 'exit' do |m|
+ # say m.from, 'Exiting ...'
+ # shutdown
+ # end
+ #
+ # message :chat?, :body do |m|
+ # say m.from, "You sent: #{m.body}"
+ # end
+ #
+ # @example Set the DSL to its own namespace.
+ #
+ # require 'blather/client/dsl'
+ # module Echo
+ # extend Blather::DSL
+ # def self.run
+ # client.run
+ # end
+ #
+ # when_ready { puts "Connected ! send messages to #{jid.stripped}." }
+ #
+ # subscription :request? do |s|
+ # write_to_stream s.approve!
+ # end
+ #
+ # message :chat?, :body => 'exit' do |m|
+ # say m.from, 'Exiting ...'
+ # shutdown
+ # end
+ #
+ # message :chat?, :body do |m|
+ # say m.from, "You sent: #{m.body}"
+ # end
+ # end
+ #
+ # EM.run { Echo.run }
+ #
+ # @example Create a class out of it
+ #
+ # require 'blather/client/dsl'
+ # class Echo
+ # include Blather::DSL
+ # end
+ #
+ # echo = Echo.new
+ # echo.when_ready { puts "Connected ! send messages to #{jid.stripped}." }
+ #
+ # echo.subscription :request? do |s|
+ # write_to_stream s.approve!
+ # end
+ #
+ # echo.message :chat?, :body => 'exit' do |m|
+ # say m.from, 'Exiting ...'
+ # shutdown
+ # end
+ #
+ # echo.message :chat?, :body do |m|
+ # say m.from, "You sent: #{m.body}"
+ # end
+ #
+ # EM.run { echo.client.run }
module DSL
autoload :PubSub, File.expand_path(File.join(File.dirname(__FILE__), *%w[dsl pubsub]))
+ # The actual client connection
+ #
+ # @return [Blather::Client]
def client
@client ||= Client.new
end
module_function :client
+ # A pubsub helper
+ #
+ # @return [Blather::PubSub]
def pubsub
@pubsub ||= PubSub.new client, jid.domain
end
- ##
# Push data to the stream
# This works such that it can be chained:
- # self << stanza1 << stanza2 << "raw data"
+ # self << stanza1 << stanza2 << "raw data"
+ #
+ # @param [#to_xml, #to_s] stanza data to send down the wire
+ # @return [self]
def <<(stanza)
client.write stanza
self
end
- ##
# Prepare server settings
- # setup [node@domain/resource], [password], [host], [port]
- # host and port are optional defaulting to the domain in the JID and 5222 respectively
+ #
+ # @param [#to_s] jid the JID to authenticate with
+ # @param [#to_s] password the password to authenticate with
+ # @param [String] host (optional) the host to connect to (can be an IP). If
+ # this is `nil` the domain on the JID will be used
+ # @param [Fixnum, String] (optional) port the port to connect on
def setup(jid, password, host = nil, port = nil)
client.setup(jid, password, host, port)
end
- ##
# Shutdown the connection.
# Flushes the write buffer then stops EventMachine
def shutdown
client.close
end
- ##
# Setup a before filter
+ #
+ # @param [Symbol] handler (optional) the stanza handler the filter should
+ # run before
+ # @param [guards] guards (optional) a set of guards to check the stanza
+ # against
+ # @yield [Blather::Stanza] stanza
def before(handler = nil, *guards, &block)
client.register_filter :before, handler, *guards, &block
end
- ##
# Setup an after filter
+ #
+ # @param [Symbol] handler (optional) the stanza handler the filter should
+ # run after
+ # @param [guards] guards (optional) a set of guards to check the stanza
+ # against
+ # @yield [Blather::Stanza] stanza
def after(handler = nil, *guards, &block)
client.register_filter :after, handler, *guards, &block
end
- ##
# Set handler for a stanza type
- def handle(stanza_type, *guards, &block)
- client.register_handler stanza_type, *guards, &block
+ #
+ # @param [Symbol] handler the stanza type it should handle
+ # @param [guards] guards (optional) a set of guards to check the stanza
+ # against
+ # @yield [Blather::Stanza] stanza
+ def handle(handler, *guards, &block)
+ client.register_handler handler, *guards, &block
end
- ##
# Wrapper for "handle :ready" (just a bit of syntactic sugar)
+ #
+ # This is run after the connection has been completely setup
def when_ready(&block)
handle :ready, &block
end
- ##
# Wrapper for "handle :disconnected"
+ #
+ # This is run after the connection has been shut down.
+ #
+ # @example Reconnect after a disconnection
+ # disconnected { client.run }
def disconnected(&block)
handle :disconnected, &block
end
- ##
# Set current status
+ #
+ # @param [Blather::Stanza::Presence::State::VALID_STATES] state the current
+ # state
+ # @param [#to_s] msg the status message to use
def set_status(state = nil, msg = nil)
client.status = state, msg
end
- ##
# Direct access to the roster
+ #
+ # @return [Blather::Roster]
def my_roster
client.roster
end
- ##
# Write data to the stream
- # Anything that resonds to #to_s can be paseed to the stream
+ #
+ # @param [#to_xml, #to_s] stanza the data to send down the wire.
def write_to_stream(stanza)
client.write stanza
end
- ##
# Helper method to make sending basic messages easier
- # say [jid], [msg]
+ #
+ # @param [Blather::JID, #to_s] to the JID of the message recipient
+ # @param [#to_s] msg the message to send
def say(to, msg)
client.write Blather::Stanza::Message.new(to, msg)
end
- ##
- # Wrapper to grab the current JID
+ # The JID according to the server
+ #
+ # @return [Blather::JID]
def jid
client.jid
end
- ##
# Halt the handler chain
+ #
+ # Use this to stop the propogation of the stanza though the handler chain.
+ #
+ # @example
+ # Ignore all IQ stanzas
+ #
+ # before(:iq) { halt }
def halt
throw :halt
end
- ##
# Pass responsibility to the next handler
+ #
+ # Use this to jump out of the current handler and let the next registered
+ # handler take care of the stanza
+ #
+ # @example
+ # This is contrive and should be handled with guards, but pass a message
+ # to the next handler based on the content
+ #
+ # message { |s| puts "message caught" }
+ # message { |s| pass if s.body =~ /pass along/ }
def pass
throw :pass
end
- ##
# Request items or info from an entity
- # discover (items|info), [jid], [node] do |response|
- # end
+ # discover (items|info), [jid], [node] do |response|
+ # end
def discover(what, who, where, &callback)
stanza = Blather::Stanza.class_from_registration(:query, "http://jabber.org/protocol/disco##{what}").new
stanza.to = who
stanza.node = where
client.register_tmp_handler stanza.id, &callback
client.write stanza
end
- ##
- # Checks to see if the method is part of the handlers list.
- # If so it creates a handler, otherwise it'll pass it back
- # to Ruby's method_missing handler
+ # Generate a method for every stanza handler that exists.
Blather::Stanza.handler_list.each do |handler_name|
module_eval <<-METHOD, __FILE__, __LINE__
def #{handler_name}(*args, &callback)
handle :#{handler_name}, *args, &callback
end
METHOD
end
- end #DSL
-end #Blather
+ end # DSL
+end # Blather