tinder 1.1.7 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,10 @@
1
- 0.1.7 - 2008-07-24
1
+ 1.2.0 - 2009-01-28
2
+ * Get the list of available files [Christopher MacGown]
3
+ * Upload files [Joshua Want]
4
+ * Find rooms even when full [Josh Owens]
5
+ * Join rooms as a guest [Ian Lesperance]
6
+
7
+ 1.1.7 - 2008-07-24
2
8
  * Don't join the room when only speaking [Brian Donovan]
3
9
  * Added support for HTTP proxies
4
10
  * Fix listening for messages that contain URLs [Jared Kuolt]
@@ -5,5 +5,6 @@ Rakefile
5
5
  init.rb
6
6
  lib/tinder.rb
7
7
  lib/tinder/campfire.rb
8
+ lib/tinder/multipart.rb
8
9
  lib/tinder/room.rb
9
10
  lib/tinder/version.rb
data/README.txt CHANGED
@@ -6,11 +6,15 @@ Tinder is a library for interfacing with Campfire, the chat application from 37S
6
6
 
7
7
  campfire = Campfire.new 'mysubdomain'
8
8
  campfire.login 'myemail@example.com', 'mypassword'
9
+
9
10
  room = campfire.create_room 'New Room', 'My new campfire room to test tinder'
10
11
  room.rename 'New Room Name'
11
12
  room.speak 'Hello world!'
12
13
  room.paste "my pasted\ncode"
13
14
  room.destroy
15
+
16
+ room = campfire.find_room_by_guest_hash 'abc123', 'John Doe'
17
+ room.speak 'Hello world!'
14
18
 
15
19
  See the RDoc for more details.
16
20
 
@@ -36,5 +40,4 @@ The source for Tinder is available at http://source.collectiveidea.com/public/ti
36
40
  == ToDo
37
41
 
38
42
  * Tests! (unit and remote)
39
- * Log in via guest url
40
43
  * Marshmallow-style integration scripts for exception notification and continuous integration
data/Rakefile CHANGED
@@ -1,5 +1,12 @@
1
1
  require 'rubygems'
2
2
  require 'hoe'
3
+ begin
4
+ require 'spec/rake/spectask'
5
+ rescue LoadError
6
+ puts 'To use rspec for testing you must install rspec gem:'
7
+ puts '$ sudo gem install rspec'
8
+ exit
9
+ end
3
10
  require File.join(File.dirname(__FILE__), 'lib', 'tinder', 'version')
4
11
 
5
12
  # RDOC_OPTS = ['--quiet', '--title', "Tinder",
@@ -21,4 +28,14 @@ hoe = Hoe.new('tinder', ENV['VERSION'] || Tinder::VERSION::STRING) do |p|
21
28
  p.changes = p.paragraphs_of('CHANGELOG.txt', 0..1).join("\n\n")
22
29
  p.extra_deps << ['activesupport']
23
30
  p.extra_deps << ['hpricot']
31
+ p.extra_deps << ['mime-types']
32
+ end
33
+
34
+ desc "Run the specs under spec"
35
+ Spec::Rake::SpecTask.new do |t|
36
+ t.spec_opts = ['--options', "spec/spec.opts"]
37
+ t.spec_files = FileList['spec/**/*_spec.rb']
24
38
  end
39
+
40
+ desc "Default task is to run specs"
41
+ task :default => :spec
@@ -4,9 +4,13 @@ module Tinder
4
4
  #
5
5
  # campfire = Tinder::Campfire.new 'mysubdomain'
6
6
  # campfire.login 'myemail@example.com', 'mypassword'
7
+ #
7
8
  # room = campfire.create_room 'New Room', 'My new campfire room to test tinder'
8
9
  # room.speak 'Hello world!'
9
10
  # room.destroy
11
+ #
12
+ # room = campfire.find_room_by_guest_hash 'abc123', 'John Doe'
13
+ # room.speak 'Hello world!'
10
14
  class Campfire
11
15
  attr_reader :subdomain, :uri
12
16
 
@@ -56,8 +60,10 @@ module Tinder
56
60
  # Get an array of all the available rooms
57
61
  # TODO: detect rooms that are full (no link)
58
62
  def rooms
59
- Hpricot(get.body).search("//h2/a").collect do |a|
60
- Room.new(self, room_id_from_url(a.attributes['href']), a.inner_html)
63
+ Hpricot(get.body).search("//div.room").collect do |a|
64
+ name = a.search("//h2/a").inner_html.strip
65
+ name = a.search("//h2").inner_html.strip if name.empty?
66
+ Room.new(self, room_id_from_element(a.attributes['id']), name)
61
67
  end
62
68
  end
63
69
 
@@ -65,6 +71,13 @@ module Tinder
65
71
  def find_room_by_name(name)
66
72
  rooms.detect {|room| room.name == name }
67
73
  end
74
+
75
+ # Find a campfire room by its guest hash
76
+ def find_room_by_guest_hash(hash, name)
77
+ res = post(hash, :name => name)
78
+
79
+ Room.new(self, room_id_from_url(res['location'])) if verify_response(res, :redirect)
80
+ end
68
81
 
69
82
  # Creates and returns a new Room with the given +name+ and optionally a +topic+
70
83
  def create_room(name, topic = nil)
@@ -111,6 +124,10 @@ module Tinder
111
124
  def room_id_from_url(url)
112
125
  url.scan(/room\/(\d*)/).to_s
113
126
  end
127
+
128
+ def room_id_from_element(element)
129
+ element.split("_").last
130
+ end
114
131
 
115
132
  def url_for(*args)
116
133
  options = {:only_path => true}.merge(args.last.is_a?(Hash) ? args.pop : {})
@@ -121,8 +138,11 @@ module Tinder
121
138
  def post(path, data = {}, options = {})
122
139
  perform_request(options) do
123
140
  returning Net::HTTP::Post.new(url_for(path)) do |request|
124
- request.add_field 'Content-Type', 'application/x-www-form-urlencoded'
125
- request.set_form_data flatten(data)
141
+ if options[:multipart]
142
+ request.body = data
143
+ else
144
+ request.set_form_data(flatten(data))
145
+ end
126
146
  end
127
147
  end
128
148
  end
@@ -139,6 +159,11 @@ module Tinder
139
159
  request.add_field 'X-Requested-With', 'XMLHttpRequest'
140
160
  request.add_field 'X-Prototype-Version', '1.5.1.1'
141
161
  end
162
+ if options[:multipart]
163
+ request.add_field 'Content-Type', 'multipart/form-data, boundary=' + Multipart::MultipartPost::BOUNDARY + " "
164
+ else
165
+ request.add_field 'Content-Type', 'application/x-www-form-urlencoded'
166
+ end
142
167
  end
143
168
  end
144
169
 
@@ -0,0 +1,64 @@
1
+ require 'rubygems'
2
+ require 'mime/types'
3
+ require 'net/http'
4
+ require 'cgi'
5
+
6
+ module Multipart #:nodoc:
7
+ # From: http://deftcode.com/code/flickr_upload/multipartpost.rb
8
+ ## Helper class to prepare an HTTP POST request with a file upload
9
+ ## Mostly taken from
10
+ #http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/113774
11
+ ### WAS:
12
+ ## Anything that's broken and wrong probably the fault of Bill Stilwell
13
+ ##(bill@marginalia.org)
14
+ ### NOW:
15
+ ## Everything wrong is due to keith@oreilly.com
16
+
17
+ class Param #:nodoc:
18
+ attr_accessor :k, :v
19
+ def initialize(k, v)
20
+ @k = k
21
+ @v = v
22
+ end
23
+
24
+ def to_multipart
25
+ "Content-Disposition: form-data; name=\"#{k}\"\r\n\r\n#{v}\r\n"
26
+ end
27
+ end
28
+
29
+ class FileParam #:nodoc:
30
+ attr_accessor :k, :filename, :content
31
+ def initialize(k, filename, content)
32
+ @k = k
33
+ @filename = filename
34
+ @content = content
35
+ end
36
+
37
+ def to_multipart
38
+ "Content-Disposition: form-data; name=\"#{k}\"; filename=\"#{filename}\"\r\n" +
39
+ "Content-Transfer-Encoding: binary\r\n" +
40
+ "Content-Type: #{MIME::Types.type_for(@filename)}\r\n\r\n" +
41
+ @content + "\r\n"
42
+ end
43
+ end
44
+
45
+ class MultipartPost #:nodoc:
46
+ BOUNDARY = 'campfire-is-awesome'
47
+ HEADER = {"Content-type" => "multipart/form-data, boundary=" + BOUNDARY + " "}
48
+ TIMEOUT_SECONDS = 30
49
+
50
+ attr_accessor :params, :query, :headers
51
+ def initialize(params)
52
+ @params = params
53
+ @query = {}
54
+ self.prepare_query
55
+ end
56
+
57
+ def prepare_query()
58
+ @query = @params.map do |k,v|
59
+ param = v.respond_to?(:read) ? FileParam.new(k, v.path, v.read) : Param.new(k, v)
60
+ "--#{BOUNDARY}\r\n#{param.to_multipart}"
61
+ end.join("") + "--#{BOUNDARY}--"
62
+ end
63
+ end
64
+ end
@@ -95,8 +95,17 @@ module Tinder
95
95
 
96
96
  # Post a new message to the chat room
97
97
  def speak(message, options = {})
98
- message if verify_response(post("room/#{id}/speak", {:message => message,
99
- :t => Time.now.to_i}.merge(options), :ajax => true), :success)
98
+ post_options = {
99
+ :message => message,
100
+ :t => Time.now.to_i
101
+ }.merge(options)
102
+
103
+ post_options.delete(:paste) unless post_options[:paste]
104
+ response = post("room/#{id}/speak", post_options, :ajax => true)
105
+
106
+ if verify_response(response, :success)
107
+ message
108
+ end
100
109
  end
101
110
 
102
111
  def paste(message)
@@ -107,7 +116,7 @@ module Tinder
107
116
  def users
108
117
  @campfire.users name
109
118
  end
110
-
119
+
111
120
  # Get and array of the messages that have been posted to the room. Each
112
121
  # messages is a hash with:
113
122
  # * +:person+: the display name of the person that posted the message
@@ -163,7 +172,22 @@ module Tinder
163
172
  }
164
173
  end
165
174
  end
166
-
175
+
176
+ def upload(filename)
177
+ File.open(filename, "rb") do |file|
178
+ params = Multipart::MultipartPost.new({'upload' => file, 'submit' => "Upload"})
179
+ verify_response post("upload.cgi/room/#{@id}/uploads/new", params.query, :multipart => true), :success
180
+ end
181
+ end
182
+
183
+ # Get the list of latest files for this room
184
+ def files(count = 5)
185
+ join
186
+ (Hpricot(@room.body)/"#file_list li a").to_a[0,count].map do |link|
187
+ @campfire.send :url_for, link.attributes['href'][1..-1], :only_path => false
188
+ end
189
+ end
190
+
167
191
  protected
168
192
 
169
193
  def messages
@@ -1,8 +1,8 @@
1
1
  module Tinder #:nodoc:
2
2
  module VERSION #:nodoc:
3
- MAJOR = 0
4
- MINOR = 1
5
- TINY = 7
3
+ MAJOR = 1
4
+ MINOR = 2
5
+ TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tinder
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.7
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Keepers
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-07-24 00:00:00 -04:00
12
+ date: 2009-01-28 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -32,6 +32,16 @@ dependencies:
32
32
  - !ruby/object:Gem::Version
33
33
  version: "0"
34
34
  version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: mime-types
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
35
45
  - !ruby/object:Gem::Dependency
36
46
  name: hoe
37
47
  type: :development
@@ -40,7 +50,7 @@ dependencies:
40
50
  requirements:
41
51
  - - ">="
42
52
  - !ruby/object:Gem::Version
43
- version: 1.7.0
53
+ version: 1.8.2
44
54
  version:
45
55
  description: An API for interfacing with Campfire, the 37Signals chat application.
46
56
  email: brandon@opensoul.org
@@ -60,6 +70,7 @@ files:
60
70
  - init.rb
61
71
  - lib/tinder.rb
62
72
  - lib/tinder/campfire.rb
73
+ - lib/tinder/multipart.rb
63
74
  - lib/tinder/room.rb
64
75
  - lib/tinder/version.rb
65
76
  has_rdoc: true
@@ -85,7 +96,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
85
96
  requirements: []
86
97
 
87
98
  rubyforge_project: tinder
88
- rubygems_version: 1.2.0
99
+ rubygems_version: 1.3.1
89
100
  signing_key:
90
101
  specification_version: 2
91
102
  summary: An (unofficial) Campfire API