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.



9
10
11
12
13
14
# File 'lib/tinder/room.rb', line 9

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.



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

def id
  @id
end

#nameObject

Returns the value of attribute name.



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

def name
  @name
end

Instance Method Details

#current_usersObject



100
101
102
103
# File 'lib/tinder/room.rb', line 100

def current_users
  reload!
  @current_users
end

#fetch_user(id) ⇒ Object

Perform a request for the user with the given ID



117
118
119
120
121
122
# File 'lib/tinder/room.rb', line 117

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

Get the list of latest files for this room



247
248
249
# File 'lib/tinder/room.rb', line 247

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

#guest_access_enabled?Boolean

Returns:

  • (Boolean)


36
37
38
39
# File 'lib/tinder/room.rb', line 36

def guest_access_enabled?
  load
  @open_to_guests ? true : false
end

#guest_invite_codeObject

The invite code use for guest



42
43
44
45
# File 'lib/tinder/room.rb', line 42

def guest_invite_code
  load
  @active_token_value
end

#guest_urlObject

Get the url for guest access



32
33
34
# File 'lib/tinder/room.rb', line 32

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



20
21
22
# File 'lib/tinder/room.rb', line 20

def join
  post 'join', 'xml'
end

#leaveObject

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



26
27
28
29
# File 'lib/tinder/room.rb', line 26

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

#listen(options = {}) ⇒ Object

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

Raises:

  • (ArgumentError)


152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/tinder/room.rb', line 152

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?Boolean

Returns:

  • (Boolean)


195
196
197
# File 'lib/tinder/room.rb', line 195

def listening?
  @stream != nil
end

#lockObject

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



69
70
71
# File 'lib/tinder/room.rb', line 69

def lock
  post 'lock'
end

#parse_message(message) ⇒ Object

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



140
141
142
143
144
# File 'lib/tinder/room.rb', line 140

def parse_message(message)
  message[:user] = user(message.delete(:user_id))
  message[:created_at] = Time.parse(message[:created_at])
  message
end

#paste(message) ⇒ Object



83
84
85
# File 'lib/tinder/room.rb', line 83

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

#play(sound) ⇒ Object



87
88
89
# File 'lib/tinder/room.rb', line 87

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

#recent(options = {}) ⇒ 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



255
256
257
258
259
260
261
262
263
# File 'lib/tinder/room.rb', line 255

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

Search transcripts for the given term (returns an array of messages parsed via #parse_message, see #parse_message for format of returned message)



228
229
230
231
232
233
234
235
236
237
238
# File 'lib/tinder/room.rb', line 228

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

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

Post a new message to the chat room



79
80
81
# File 'lib/tinder/room.rb', line 79

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

#stop_listeningObject



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

def stop_listening
  return unless listening?

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

#topicObject

Get the current topic



63
64
65
66
# File 'lib/tinder/room.rb', line 63

def topic
  reload!
  @topic
end

#topic=(topic) ⇒ Object

Change the topic



54
55
56
# File 'lib/tinder/room.rb', line 54

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

#transcript(transcript_date = Date.today) ⇒ Object

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.



218
219
220
221
222
223
# File 'lib/tinder/room.rb', line 218

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



91
92
93
# File 'lib/tinder/room.rb', line 91

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

#unlockObject

Unlock the room



74
75
76
# File 'lib/tinder/room.rb', line 74

def unlock
  post 'unlock'
end

#update(attrs) ⇒ Object



58
59
60
# File 'lib/tinder/room.rb', line 58

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

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



240
241
242
243
244
# File 'lib/tinder/room.rb', line 240

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



107
108
109
110
111
112
113
114
# File 'lib/tinder/room.rb', line 107

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

#usersObject

Get the list of users currently chatting for this room



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

def users
  @users ||= current_users
end