Class: Tinder::Room

Inherits:
Object
  • Object
show all
Defined in:
lib/tinder/room.rb

Overview

A campfire room

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(connection, attributes = {}) ⇒ Room

Returns a new instance of Room.



7
8
9
10
11
12
# File 'lib/tinder/room.rb', line 7

def initialize(connection, attributes = {})
  @connection = connection
  @id = attributes['id']
  @name = attributes['name']
  @loaded = false
end

Instance Attribute Details

#idObject (readonly)

Returns the value of attribute id.



5
6
7
# File 'lib/tinder/room.rb', line 5

def id
  @id
end

#nameObject

Returns the value of attribute name.



5
6
7
# File 'lib/tinder/room.rb', line 5

def name
  @name
end

Instance Method Details

#files(count = 5) ⇒ Object

Get the list of latest files for this room



239
240
241
# File 'lib/tinder/room.rb', line 239

def files(count = 5)
  get(:uploads)['uploads'].map { |u| u['full_url'] }
end

#guest_access_enabled?Boolean

Returns:

  • (Boolean)


34
35
36
37
# File 'lib/tinder/room.rb', line 34

def guest_access_enabled?
  load
  @open_to_guests ? true : false
end

#guest_invite_codeObject

The invite code use for guest



40
41
42
43
# File 'lib/tinder/room.rb', line 40

def guest_invite_code
  load
  @active_token_value
end

#guest_urlObject

Get the url for guest access



30
31
32
# File 'lib/tinder/room.rb', line 30

def guest_url
  "#{@connection.uri}/#{guest_invite_code}" if guest_access_enabled?
end

#joinObject

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 :\



18
19
20
# File 'lib/tinder/room.rb', line 18

def join
  post 'join', 'xml'
end

#leaveObject

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



24
25
26
27
# File 'lib/tinder/room.rb', line 24

def leave
  post 'leave', 'xml'
  stop_listening
end

#listen(options = {}) ⇒ Object

Listen for new messages in the room, yielding them to the provided block as they arrive. Each message is a hash with:

  • :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

    room.listen do |m|

    room.speak "Go away!" if m[:body] =~ /Java/i
    

    end

Raises:

  • (ArgumentError)


130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/tinder/room.rb', line 130

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'
  require 'time'

  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[:user] = user(message.delete(:user_id))
      message[:created_at] = Time.parse(message[:created_at])
      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?Boolean

Returns:

  • (Boolean)


175
176
177
# File 'lib/tinder/room.rb', line 175

def listening?
  @stream != nil
end

#lockObject

Lock the room to prevent new users from entering and to disable logging



67
68
69
# File 'lib/tinder/room.rb', line 67

def lock
  post 'lock'
end

#paste(message) ⇒ Object



81
82
83
# File 'lib/tinder/room.rb', line 81

def paste(message)
  send_message(message, 'PasteMessage')
end

#play(sound) ⇒ Object



85
86
87
# File 'lib/tinder/room.rb', line 85

def play(sound)
  send_message(sound, 'SoundMessage')
end

#recent(limit = 10, since_message_id = nil) ⇒ Object

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



247
248
249
250
251
252
253
254
255
256
# File 'lib/tinder/room.rb', line 247

def recent(limit=10, since_message_id=nil)
  # Build url manually, faraday has to be 8.0 to do this
  url = "#{room_url_for(:recent)}?limit=#{limit}&since_message_id=#{since_message_id}"

  connection.get(url)['messages'].map do |msg|
    msg[:created_at] = Time.parse(msg[:created_at])
    msg[:user] = user(msg[:user_id])
    msg
  end
end

#search(term) ⇒ Object

Search transcripts for a specific term

room.search("bobloblaw")
#=> [{:message=>"foo!",
      :user_id=>"99999",
      :person=>"Brandon",
      :id=>"18659245",
      :timestamp=>=>Tue May 05 07:15:00 -0700 2009}]


217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/tinder/room.rb', line 217

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 |room|
    { :id => room['id'],
      :user_id => room['user_id'],
      :message => room['body'],
      :timestamp => Time.parse(room['created_at']) }
  end
end

#speak(message, options = {}) ⇒ Object

Post a new message to the chat room



77
78
79
# File 'lib/tinder/room.rb', line 77

def speak(message, options = {})
  send_message(message)
end

#stop_listeningObject



179
180
181
182
183
184
185
# File 'lib/tinder/room.rb', line 179

def stop_listening
  return unless listening?

  Tinder.logger.info "Stopped listening to #{@name}"
  @stream.stop
  @stream = nil
end

#topicObject

Get the current topic



61
62
63
64
# File 'lib/tinder/room.rb', line 61

def topic
  reload!
  @topic
end

#topic=(topic) ⇒ Object

Change the topic



52
53
54
# File 'lib/tinder/room.rb', line 52

def topic=(topic)
  update :topic => topic
end

#transcript(transcript_date) ⇒ Object

Get the transcript for the given date (Returns a hash in the same format as #listen)

room.transcript(room.available_transcripts.first)
#=> [{: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.



198
199
200
201
202
203
204
205
206
# File 'lib/tinder/room.rb', line 198

def transcript(transcript_date)
  url = "/room/#{@id}/transcript/#{transcript_date.to_date.strftime('%Y/%m/%d')}.json"
  connection.get(url)['messages'].map do |room|
    { :id => room['id'],
      :user_id => room['user_id'],
      :message => room['body'],
      :timestamp => Time.parse(room['created_at']) }
  end
end

#tweet(url) ⇒ Object



89
90
91
# File 'lib/tinder/room.rb', line 89

def tweet(url)
  send_message(url, 'TweetMessage')
end

#unlockObject

Unlock the room



72
73
74
# File 'lib/tinder/room.rb', line 72

def unlock
  post 'unlock'
end

#update(attrs) ⇒ Object



56
57
58
# File 'lib/tinder/room.rb', line 56

def update(attrs)
  connection.put("/room/#{@id}.json", {:room => attrs})
end

#upload(file, content_type = nil, filename = nil) ⇒ Object



232
233
234
235
236
# File 'lib/tinder/room.rb', line 232

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) ⇒ Object

return the user with the given id; if it isn’t in our room cache, do a request to get it



100
101
102
103
104
105
106
107
108
109
110
# File 'lib/tinder/room.rb', line 100

def user(id)
  if id
    user = users.detect {|u| u[:id] == id }
    unless user
      user_data = connection.get("/users/#{id}.json")
      user = user_data && user_data[:user]
    end
    user[:created_at] = Time.parse(user[:created_at])
    user
  end
end

#usersObject

Get the list of users currently chatting for this room



94
95
96
97
# File 'lib/tinder/room.rb', line 94

def users
  reload!
  @users
end