class Tinder::Room

A campfire room

Attributes

id[R]
name[R]

Public Class Methods

new(connection, attributes = {}) click to toggle source
# 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

current_users() click to toggle source
# File lib/tinder/room.rb, line 99
def current_users
  reload!
  @current_users
end
fetch_user(id) click to toggle source

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
files(count = 5) click to toggle source

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
guest_access_enabled?() click to toggle source
# File lib/tinder/room.rb, line 35
def guest_access_enabled?
  load
  @open_to_guests ? true : false
end
guest_invite_code() click to toggle source

The invite code use for guest

# File lib/tinder/room.rb, line 41
def guest_invite_code
  load
  @active_token_value
end
guest_url() click to toggle source

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
join() click to toggle source

Join the room POST /room/#{id}/join.xml For whatever reason, join() and leave() are still xml endpoints whereas elsewhere in this API we're assuming json :\

# File lib/tinder/room.rb, line 19
def join
  post 'join', 'xml'
end
leave() click to toggle source

Leave a room POST /room/#{id}/leave.xml

# File lib/tinder/room.rb, line 25
def leave
  post 'leave', 'xml'
  stop_listening
end
listen(options = {}) { |message| ... } click to toggle source

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
listening?() click to toggle source
# File lib/tinder/room.rb, line 194
def listening?
  @stream != nil
end
lock() click to toggle source

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
name=(name) click to toggle source

Change the name of the room

# File lib/tinder/room.rb, line 47
def name=(name)
  update :name => name
end
Also aliased as: rename
parse_message(message) click to toggle source

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
paste(message) click to toggle source
# File lib/tinder/room.rb, line 82
def paste(message)
  send_message(message, 'PasteMessage')
end
play(sound) click to toggle source
# File lib/tinder/room.rb, line 86
def play(sound)
  send_message(sound, 'SoundMessage')
end
recent(options = {}) click to toggle source

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
rename(name)
Alias for: name=
speak(message, options = {}) click to toggle source

Post a new message to the chat room

# File lib/tinder/room.rb, line 78
def speak(message, options = {})
  send_message(message)
end
stop_listening() click to toggle source
# 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
topic() click to toggle source

Get the current topic

# File lib/tinder/room.rb, line 62
def topic
  reload!
  @topic
end
topic=(topic) click to toggle source

Change the topic

# File lib/tinder/room.rb, line 53
def topic=(topic)
  update :topic => topic
end
transcript(transcript_date = Date.today) click to toggle source

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
tweet(url) click to toggle source
# File lib/tinder/room.rb, line 90
def tweet(url)
  send_message(url, 'TweetMessage')
end
unlock() click to toggle source

Unlock the room

# File lib/tinder/room.rb, line 73
def unlock
  post 'unlock'
end
update(attrs) click to toggle source
# File lib/tinder/room.rb, line 57
def update(attrs)
  connection.put("/room/#{@id}.json", {:room => attrs})
end
upload(file, content_type = nil, filename = nil) click to toggle source
# 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
user(id) click to toggle source

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
users() click to toggle source

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

connection() click to toggle source
# File lib/tinder/room.rb, line 307
def connection
  @connection
end
get(action) click to toggle source
# File lib/tinder/room.rb, line 291
def get(action)
  connection.get(room_url_for(action))
end
load() click to toggle source
# File lib/tinder/room.rb, line 266
def load
  reload! unless @loaded
end
post(action, body = nil) click to toggle source
# File lib/tinder/room.rb, line 295
def post(action, body = nil)
  connection.post(room_url_for(action), body)
end
raw_post(action, body = nil) click to toggle source
# File lib/tinder/room.rb, line 299
def raw_post(action, body = nil)
  connection.raw_post(room_url_for(action), body)
end
reload!() click to toggle source
# 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
room_url_for(action, format="json") click to toggle source
# File lib/tinder/room.rb, line 303
def room_url_for(action, format="json")
  "/room/#{@id}/#{action}.#{format}"
end
send_message(message, type = 'TextMessage') click to toggle source
# File lib/tinder/room.rb, line 287
def send_message(message, type = 'TextMessage')
  post 'speak', {:message => {:body => message, :type => type}}
end