class Tinder::Room
A campfire room
Attributes
Public Class Methods
# File lib/tinder/room.rb, line 8 def initialize(connection, attributes = {}) @connection = connection @id = attributes['id'] @name = attributes['name'] @loaded = false end
Public Instance Methods
# File lib/tinder/room.rb, line 99 def current_users reload! @current_users end
Perform a request for the user with the given ID
# File lib/tinder/room.rb, line 116 def fetch_user(id) user_data = connection.get("/users/#{id}.json") user = user_data && user_data[:user] user[:created_at] = Time.parse(user[:created_at]) user end
Get the list of latest files for this room
# File lib/tinder/room.rb, line 246 def files(count = 5) get(:uploads)['uploads'].map { |u| u['full_url'] } end
# File lib/tinder/room.rb, line 35 def guest_access_enabled? load @open_to_guests ? true : false end
The invite code use for guest
# File lib/tinder/room.rb, line 41 def guest_invite_code load @active_token_value end
Get the url for guest access
# File lib/tinder/room.rb, line 31 def guest_url "#{@connection.uri}/#{guest_invite_code}" if guest_access_enabled? end
Leave a room POST /room/#{id}/leave.xml
# File lib/tinder/room.rb, line 25 def leave post 'leave', 'xml' stop_listening end
Listen for new messages in the room, parsing them with parse_message and then yielding them to the provided block as they arrive.
room.listen do |m| room.speak "Go away!" if m[:body] =~ /Java/i end
# File lib/tinder/room.rb, line 151 def listen(options = {}) raise ArgumentError, "no block provided" unless block_given? Tinder.logger.info "Joining #{@name}…" join # you have to be in the room to listen require 'json' require 'hashie' require 'multi_json' require 'twitter/json_stream' auth = connection.basic_auth_settings options = { :host => "streaming.#{Connection::HOST}", :path => room_url_for('live'), :auth => "#{auth[:username]}:#{auth[:password]}", :timeout => 6, :ssl => connection.options[:ssl] }.merge(options) Tinder.logger.info "Starting EventMachine server…" EventMachine::run do @stream = Twitter::JSONStream.connect(options) Tinder.logger.info "Listening to #{@name}…" @stream.each_item do |message| message = Hashie::Mash.new(MultiJson.decode(message)) message = parse_message(message) yield(message) end @stream.on_error do |message| raise ListenFailed.new("got an error! #{message.inspect}!") end @stream.on_max_reconnects do |timeout, retries| raise ListenFailed.new("Tried #{retries} times to connect. Got disconnected from #{@name}!") end # if we really get disconnected raise ListenFailed.new("got disconnected from #{@name}!") if !EventMachine.reactor_running? end end
# File lib/tinder/room.rb, line 194 def listening? @stream != nil end
Lock the room to prevent new users from entering and to disable logging
# File lib/tinder/room.rb, line 68 def lock post 'lock' end
Change the name of the room
# File lib/tinder/room.rb, line 47 def name=(name) update :name => name end
Modifies a hash representation of a Campfire
message. Expands :user_id
to a full hash at
:user
, generates Timestamp from :created_at
.
Full returned hash:
-
:body
: the body of the message -
:user
: Campfire user, which is itself a hash, of:-
:id
: User id -
:name
: User name -
:email_address
: Email address -
:admin
: Boolean admin flag -
:created_at
: User creation timestamp -
:type
: User type (e.g. Member)
-
-
:id
: Campfire message id -
:type
: Campfire message type -
:room_id
: Campfire room id -
:created_at
: Message creation timestamp
# File lib/tinder/room.rb, line 139 def parse_message(message) message[:user] = user(message.delete(:user_id)) message[:created_at] = Time.parse(message[:created_at]) message end
# File lib/tinder/room.rb, line 82 def paste(message) send_message(message, 'PasteMessage') end
# File lib/tinder/room.rb, line 86 def play(sound) send_message(sound, 'SoundMessage') end
Get a list of recent messages Accepts a hash for options:
-
:limit
: Restrict the number of messages returned -
:since_message_id
: Get messages created after the specified message id
# File lib/tinder/room.rb, line 254 def recent(options = {}) options = { :limit => 10, :since_message_id => nil }.merge(options) # Build url manually, faraday has to be 8.0 to do this url = "#{room_url_for(:recent)}?limit=#{options[:limit]}&since_message_id=#{options[:since_message_id]}" connection.get(url)['messages'].map do |msg| parse_message(msg) end end
Search transcripts for the given term (returns an array of messages parsed via parse_message, see parse_message for format of returned message)
# File lib/tinder/room.rb, line 227 def search(term) encoded_term = URI.encode(term) room_messages = connection.get("/search/#{encoded_term}.json")["messages"].select do |message| message[:room_id] == id end room_messages.map do |message| parse_message(message) end end
Post a new message to the chat room
# File lib/tinder/room.rb, line 78 def speak(message, options = {}) send_message(message) end
# File lib/tinder/room.rb, line 198 def stop_listening return unless listening? Tinder.logger.info "Stopped listening to #{@name}…" @stream.stop @stream = nil end
Get the current topic
# File lib/tinder/room.rb, line 62 def topic reload! @topic end
Change the topic
# File lib/tinder/room.rb, line 53 def topic=(topic) update :topic => topic end
Get the transcript for the given date (Returns a hash in the same format as listen)
room.transcript(Time.now) #=> [{:message=>"foobar!", :user_id=>"99999", :person=>"Brandon", :id=>"18659245", :timestamp=>=>Tue May 05 07:15:00 -0700 2009}]
The timestamp slot will typically have a granularity of five minutes.
# File lib/tinder/room.rb, line 217 def transcript(transcript_date = Date.today) url = "/room/#{@id}/transcript/#{transcript_date.strftime('%Y/%m/%d')}.json" connection.get(url)['messages'].map do |message| parse_message(message) end end
# File lib/tinder/room.rb, line 90 def tweet(url) send_message(url, 'TweetMessage') end
Unlock the room
# File lib/tinder/room.rb, line 73 def unlock post 'unlock' end
# File lib/tinder/room.rb, line 57 def update(attrs) connection.put("/room/#{@id}.json", {:room => attrs}) end
# File lib/tinder/room.rb, line 239 def upload(file, content_type = nil, filename = nil) require 'mime/types' content_type ||= MIME::Types.type_for(filename || file) raw_post(:uploads, { :upload => Faraday::UploadIO.new(file, content_type, filename) }) end
return the user with the given id; if it isn't in our room cache, do a request to get it
# File lib/tinder/room.rb, line 106 def user(id) if id cached_user = users.detect {|u| u[:id] == id } user = cached_user || fetch_user(id) self.users << user user end end
Get the list of users currently chatting for this room
# File lib/tinder/room.rb, line 95 def users @users ||= current_users end
Protected Instance Methods
# File lib/tinder/room.rb, line 307 def connection @connection end
# File lib/tinder/room.rb, line 291 def get(action) connection.get(room_url_for(action)) end
# File lib/tinder/room.rb, line 266 def load reload! unless @loaded end
# File lib/tinder/room.rb, line 295 def post(action, body = nil) connection.post(room_url_for(action), body) end
# File lib/tinder/room.rb, line 299 def raw_post(action, body = nil) connection.raw_post(room_url_for(action), body) end
# File lib/tinder/room.rb, line 270 def reload! attributes = connection.get("/room/#{@id}.json")['room'] @id = attributes['id'] @name = attributes['name'] @topic = attributes['topic'] @full = attributes['full'] @open_to_guests = attributes['open_to_guests'] @active_token_value = attributes['active_token_value'] @current_users = attributes['users'].map do |user| user[:created_at] = Time.parse(user[:created_at]) user end @loaded = true end
# File lib/tinder/room.rb, line 303 def room_url_for(action, format="json") "/room/#{@id}/#{action}.#{format}" end
# File lib/tinder/room.rb, line 287 def send_message(message, type = 'TextMessage') post 'speak', {:message => {:body => message, :type => type}} end