Class: Uppercut::Agent
Constant Summary collapse
- VALID_CALLBACKS =
[:signon, :signoff, :subscribe, :unsubscribe, :subscription_approval, :subscription_denial, :status_change, :status_message_change]
- DEFAULT_OPTIONS =
{ :connect => true }
Instance Attribute Summary collapse
-
#allowed_roster ⇒ Object
Returns the value of attribute allowed_roster.
-
#roster ⇒ Object
Returns the value of attribute roster.
Attributes inherited from Base
Class Method Summary collapse
-
.command(pattern, &block) ⇒ Object
Define a new command for the agent.
-
.on(type, &block) ⇒ Object
Define a callback for specific presence events.
Instance Method Summary collapse
-
#initialize(user, pw, options = {}) ⇒ Agent
constructor
Create a new instance of an Agent, possibly connecting to the server.
-
#inspect ⇒ Object
:nodoc:.
-
#listen ⇒ Object
Makes an Agent instance begin listening for incoming messages and subscription requests.
-
#listening? ⇒ Boolean
True if the Agent is currently listening for incoming messages.
- #redirect_from(contact, &block) ⇒ Object
-
#stop ⇒ Object
Stops the Agent from listening to incoming messages.
Methods inherited from Base
#connect, #connected?, #disconnect, #reconnect, #stanza
Constructor Details
#initialize(user, pw, options = {}) ⇒ Agent
Create a new instance of an Agent, possibly connecting to the server.
user should be a String in the form: “user@server/Resource”. pw is simply the password for this account. The final, and optional, argument is a boolean which controls whether or not it will attempt to connect to the server immediately. Defaults to true.
54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/uppercut/agent.rb', line 54 def initialize(user,pw,={}) = DEFAULT_OPTIONS.merge() @user = user @pw = pw connect if [:connect] listen if [:listen] @allowed_roster = [:roster] @redirects = {} end |
Instance Attribute Details
#allowed_roster ⇒ Object
Returns the value of attribute allowed_roster.
169 170 171 |
# File 'lib/uppercut/agent.rb', line 169 def allowed_roster @allowed_roster end |
#roster ⇒ Object
Returns the value of attribute roster.
169 170 171 |
# File 'lib/uppercut/agent.rb', line 169 def roster @roster end |
Class Method Details
.command(pattern, &block) ⇒ Object
Define a new command for the agent.
The pattern can be a String or a Regexp. If a String is passed, it will dispatch this command only on an exact match. A Regexp simply must match.
There is always at least one argument sent to the block. The first is a always an Uppercut::Message object, which can be used to reply to the sender. The rest of the arguments to the block correspond to any captures in the pattern Regexp. (Does not apply to String patterns).
18 19 20 21 22 23 |
# File 'lib/uppercut/agent.rb', line 18 def command(pattern,&block) @@patterns ||= [] g = gensym @@patterns << [pattern,g] define_method(g, &block) end |
.on(type, &block) ⇒ Object
Define a callback for specific presence events.
At the moment this is only confirmed to work with :subscribe and :unsubscribe, but it may work with other types as well. Example:
on :subscribe do |conversation|
conversation.send "Welcome! Send 'help' for instructions."
end
34 35 36 37 |
# File 'lib/uppercut/agent.rb', line 34 def on(type, &block) raise 'Not a valid callback' unless VALID_CALLBACKS.include?(type) define_method("__on_#{type.to_s}") { |conversation| block[conversation] } end |
Instance Method Details
#inspect ⇒ Object
:nodoc:
67 68 69 70 71 |
# File 'lib/uppercut/agent.rb', line 67 def inspect #:nodoc: "<Uppercut::Agent #{@user} " + "#{listening? ? 'Listening' : 'Not Listening'}:" + "#{connected? ? 'Connected' : 'Disconnected'}>" end |
#listen ⇒ Object
Makes an Agent instance begin listening for incoming messages and subscription requests.
Current listen simply eats any errors that occur, in the interest of keeping the remote agent alive. These should be logged at some point in the future. Pass debug as true to prevent this behaviour.
Calling listen fires off a new Thread whose sole purpose is to listen for new incoming messages and then fire off a new Thread which dispatches the message to the proper handler.
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/uppercut/agent.rb', line 83 def listen connect unless connected? @listen_thread = Thread.new { @client. do || log_and_continue do next if .body.nil? next unless allowed_roster_includes?(.from) dispatch end end @roster ||= Jabber::Roster::Helper.new(@client) @roster.add_presence_callback do |item, old_presence, new_presence| # Callbacks: # post-subscribe initial stuff (oldp == nil) # status change: (oldp.show != newp.show) # status message change: (oldp.status != newp.status) log_and_continue do if old_presence.nil? && new_presence.type == :unavailable dispatch_presence :signoff, new_presence elsif old_presence.nil? # do nothing, we don't care elsif old_presence.type == :unavailable && new_presence dispatch_presence :signon, new_presence elsif old_presence.show != new_presence.show dispatch_presence :status_change, new_presence elsif old_presence.status != new_presence.status dispatch_presence :status_message_change, new_presence end end end @roster.add_subscription_request_callback do |item,presence| # Callbacks: # someone tries to subscribe (presence.type == 'subscribe') log_and_continue do case presence.type when :subscribe next unless allowed_roster_includes?(presence.from) @roster.accept_subscription(presence.from) @roster.add(presence.from, nil, true) dispatch_presence :subscribe, presence end end end @roster.add_subscription_callback do |item, presence| # Callbacks: # user allows agent to subscribe to them (presence.type == 'subscribed') # user denies agent subscribe request (presence.type == 'unsubscribed') # user unsubscribes from agent (presence.type == 'unsubscribe') log_and_continue do case presence.type when :subscribed dispatch_presence :subscription_approval, presence when :unsubscribed # if item.subscription != :from, it's not a denial... it's just an unsub dispatch_presence(:subscription_denial, presence) if item.subscription == :from when :unsubscribe dispatch_presence :unsubscribe, presence end end end sleep } end |
#listening? ⇒ Boolean
True if the Agent is currently listening for incoming messages.
160 161 162 |
# File 'lib/uppercut/agent.rb', line 160 def listening? @listen_thread && @listen_thread.alive? end |
#redirect_from(contact, &block) ⇒ Object
164 165 166 167 |
# File 'lib/uppercut/agent.rb', line 164 def redirect_from(contact,&block) @redirects[contact] ||= [] @redirects[contact].push block end |
#stop ⇒ Object
Stops the Agent from listening to incoming messages.
Simply kills the thread if it is running.
155 156 157 |
# File 'lib/uppercut/agent.rb', line 155 def stop @listen_thread.kill if listening? end |