tinder 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.txt +3 -0
- data/Manifest.txt +11 -0
- data/README.txt +24 -0
- data/Rakefile +24 -0
- data/init.rb +1 -0
- data/lib/tinder.rb +9 -0
- data/lib/tinder/campfire.rb +107 -0
- data/lib/tinder/room.rb +74 -0
- data/lib/tinder/version.rb +9 -0
- data/test/remote/remote_campfire_test.rb +37 -0
- data/test/test_helper.rb +4 -0
- metadata +81 -0
data/CHANGELOG.txt
ADDED
data/Manifest.txt
ADDED
data/README.txt
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
= Tinder
|
2
|
+
|
3
|
+
Tinder is a library for interfacing with Campfire, the chat application from 37Signals.
|
4
|
+
|
5
|
+
campfire = Campfire.new 'mysubdomain'
|
6
|
+
campfire.login 'myemail@example.com', 'mypassword'
|
7
|
+
room = campfire.create_room 'New Room', 'My new campfire room to test tinder'
|
8
|
+
room.rename 'New Room Name'
|
9
|
+
room.speak 'Hello world!'
|
10
|
+
room.speak "my pasted\ncode", :paste => true
|
11
|
+
room.destroy
|
12
|
+
|
13
|
+
== Requirements
|
14
|
+
|
15
|
+
* Active Support
|
16
|
+
gem install activesupport
|
17
|
+
* Hpricot
|
18
|
+
gem install hpricot
|
19
|
+
|
20
|
+
== ToDo
|
21
|
+
|
22
|
+
* Tests! (unit and remote)
|
23
|
+
* Log in via guest url
|
24
|
+
* SSL
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'hoe'
|
3
|
+
require File.join(File.dirname(__FILE__), 'lib', 'tinder', 'version')
|
4
|
+
|
5
|
+
# RDOC_OPTS = ['--quiet', '--title', "Tinder",
|
6
|
+
# "--opname", "index.html",
|
7
|
+
# "--line-numbers",
|
8
|
+
# "--main", "README",
|
9
|
+
# "--inline-source"]
|
10
|
+
#
|
11
|
+
# Generate all the Rake tasks
|
12
|
+
|
13
|
+
hoe = Hoe.new('tinder', ENV['VERSION'] || Tinder::VERSION::STRING) do |p|
|
14
|
+
p.rubyforge_name = 'tinder'
|
15
|
+
p.summary = "An (unofficial) Campfire API"
|
16
|
+
p.description = "An API for interfacing with Campfire, the 37Signals chat application."
|
17
|
+
p.author = 'Brandon Keepers'
|
18
|
+
p.email = 'brandon@opensoul.org'
|
19
|
+
p.url = 'http://tinder.rubyforge.org'
|
20
|
+
p.test_globs = ["test/**/*_test.rb"]
|
21
|
+
p.changes = p.paragraphs_of('CHANGELOG.txt', 0..1).join("\n\n")
|
22
|
+
p.extra_deps << ['activesupport']
|
23
|
+
p.extra_deps << ['hpricot']
|
24
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'tinder'
|
data/lib/tinder.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
module Tinder
|
2
|
+
|
3
|
+
# == Usage
|
4
|
+
#
|
5
|
+
# campfire = Campfire.new 'mysubdomain'
|
6
|
+
# campfire.login 'myemail@example.com', 'mypassword'
|
7
|
+
# room = campfire.create_room 'New Room', 'My new campfire room to test tinder'
|
8
|
+
# room.speak 'Hello world!'
|
9
|
+
# room.destroy
|
10
|
+
class Campfire
|
11
|
+
attr_accessor :subdomain, :host
|
12
|
+
|
13
|
+
def initialize(subdomain)
|
14
|
+
@cookie = nil
|
15
|
+
self.subdomain = subdomain
|
16
|
+
self.host = "#{subdomain}.campfirenow.com"
|
17
|
+
end
|
18
|
+
|
19
|
+
def login(email, password)
|
20
|
+
@logged_in = verify_response(post("login", :email_address => email, :password => password), :redirect_to => url_for)
|
21
|
+
end
|
22
|
+
|
23
|
+
def logged_in?
|
24
|
+
@logged_in
|
25
|
+
end
|
26
|
+
|
27
|
+
def logout
|
28
|
+
@logged_in = !verify_response(get("logout"), :redirect)
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_room(name, topic = nil)
|
32
|
+
find_room_by_name(name) if verify_response(post("account/create/room?from=lobby", {:room => {:name => name, :topic => topic}}, :ajax => true), :success)
|
33
|
+
end
|
34
|
+
|
35
|
+
def find_room_by_name(name)
|
36
|
+
link = Hpricot(get.body).search("//h2/a").detect { |a| a.inner_html == name }
|
37
|
+
link.blank? ? nil : Room.new(self, link.attributes['href'].scan(/room\/(\d*)$/).to_s, name)
|
38
|
+
end
|
39
|
+
|
40
|
+
def users(*room_names)
|
41
|
+
users = Hpricot(get.body).search("div.room").collect do |room|
|
42
|
+
if room_names.empty? || room_names.include?((room/"h2/a").inner_html)
|
43
|
+
room.search("//li.user").collect { |user| user.inner_html }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
users.flatten.compact.uniq.sort
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def url_for(path = "")
|
52
|
+
"http://#{host}/#{path}"
|
53
|
+
end
|
54
|
+
|
55
|
+
def post(path, data = {}, options = {})
|
56
|
+
@request = returning Net::HTTP::Post.new(url_for(path)) do |request|
|
57
|
+
prepare_request(request, options)
|
58
|
+
request.add_field 'Content-Type', 'application/x-www-form-urlencoded'
|
59
|
+
request.set_form_data flatten(data)
|
60
|
+
end
|
61
|
+
returning @response = Net::HTTP.new(host, 80).start { |http| http.request(@request) } do |response|
|
62
|
+
@cookie = response['set-cookie'] if response['set-cookie']
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def get(path = nil, options = {})
|
67
|
+
@request = returning Net::HTTP::Get.new(url_for(path)) do |request|
|
68
|
+
prepare_request(request, options)
|
69
|
+
end
|
70
|
+
returning @response = Net::HTTP.new(host, 80).start { |http| http.request(@request) } do |response|
|
71
|
+
@cookie = response['set-cookie'] if response['set-cookie']
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def prepare_request(request, options = {})
|
76
|
+
request.add_field 'Cookie', @cookie if @cookie
|
77
|
+
if options[:ajax]
|
78
|
+
request.add_field 'X-Requested-With', 'XMLHttpRequest'
|
79
|
+
request.add_field 'X-Prototype-Version', '1.5.0_rc1'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# flatten a nested hash
|
84
|
+
def flatten(params)
|
85
|
+
params = params.dup
|
86
|
+
params.stringify_keys!.each do |k,v|
|
87
|
+
if v.is_a? Hash
|
88
|
+
params.delete(k)
|
89
|
+
v.each {|subk,v| params["#{k}[#{subk}]"] = v }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def verify_response(response, options = {})
|
95
|
+
if options.is_a? Symbol
|
96
|
+
response.code == case options
|
97
|
+
when :success then "200"
|
98
|
+
end
|
99
|
+
elsif options[:redirect_to]
|
100
|
+
response.code == "302" && response['location'] == options[:redirect_to]
|
101
|
+
else
|
102
|
+
false
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
end
|
data/lib/tinder/room.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
module Tinder
|
2
|
+
class Room
|
3
|
+
attr_accessor :id, :name
|
4
|
+
|
5
|
+
def initialize(campfire, id, name = nil)
|
6
|
+
@campfire = campfire
|
7
|
+
self.id = id
|
8
|
+
self.name = name
|
9
|
+
end
|
10
|
+
|
11
|
+
def toggle_guest_access
|
12
|
+
verify_response(post("room/#{self.id}/toggle_guest_access"), :success)
|
13
|
+
end
|
14
|
+
|
15
|
+
def guest_url
|
16
|
+
(Hpricot(@campfire.send(:get, "room/#{self.id}").body)/"#guest_access h4").first.inner_html
|
17
|
+
end
|
18
|
+
|
19
|
+
def guest_invite_code
|
20
|
+
guest_url.scan(/^http:\/\/#{@campfire.host}\/(\w*)$/).to_s
|
21
|
+
end
|
22
|
+
|
23
|
+
def rename(name)
|
24
|
+
name if verify_response(post("account/edit/room/#{self.id}", { :room => { :name => name }}, :ajax => true), :success)
|
25
|
+
end
|
26
|
+
|
27
|
+
def topic=(topic)
|
28
|
+
topic if verify_response(post("room/#{self.id}/change_topic", { 'room' => { 'topic' => topic }}, :ajax => true), :success)
|
29
|
+
end
|
30
|
+
|
31
|
+
def lock
|
32
|
+
verify_response(post("room/#{self.id}/lock", {}, :ajax => true), :success)
|
33
|
+
end
|
34
|
+
|
35
|
+
def unlock
|
36
|
+
verify_response(post("room/#{self.id}/unlock", {}, :ajax => true), :success)
|
37
|
+
end
|
38
|
+
|
39
|
+
def destroy
|
40
|
+
verify_response(post("account/delete/room/#{self.id}"), :success)
|
41
|
+
end
|
42
|
+
|
43
|
+
def speak(message)
|
44
|
+
send message
|
45
|
+
end
|
46
|
+
|
47
|
+
def paste(message)
|
48
|
+
send message, { :paste => true }
|
49
|
+
end
|
50
|
+
|
51
|
+
def users
|
52
|
+
@campfire.users self.name
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def post(*args)
|
58
|
+
@campfire.send :post, *args
|
59
|
+
end
|
60
|
+
|
61
|
+
def get(*args)
|
62
|
+
@campfire.send :get, *args
|
63
|
+
end
|
64
|
+
|
65
|
+
def verify_response(*args)
|
66
|
+
@campfire.send :verify_response, *args
|
67
|
+
end
|
68
|
+
|
69
|
+
def send(message, options = {})
|
70
|
+
message if verify_response(post("room/#{self.id}/speak", { :message => message, }.merge(options), :ajax => true), :success)
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class RemoteCampfireTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@campfire = Tinder::Campfire.new 'opensoul'
|
7
|
+
@user, @pass = 'brandon@opensoul.org', 'testing'
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_create_and_delete_room
|
11
|
+
assert login
|
12
|
+
room = @campfire.create_room('Testing123')
|
13
|
+
|
14
|
+
assert Tinder::Room, room
|
15
|
+
assert_not_nil room.id
|
16
|
+
assert_equal "new name", room.rename("new name")
|
17
|
+
|
18
|
+
room.destroy
|
19
|
+
assert_nil @campfire.find_room_by_name('Testing123')
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_failed_login
|
23
|
+
assert !@campfire.login(@user, 'notmypassword')
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_find_nonexistent_room
|
27
|
+
login
|
28
|
+
assert_nil @campfire.find_room_by_name('No Room Should Have This Name')
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def login(user = @user, pass = @pass)
|
34
|
+
@campfire.login(user, pass)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.11
|
3
|
+
specification_version: 1
|
4
|
+
name: tinder
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.1.0
|
7
|
+
date: 2007-01-23 00:00:00 -05:00
|
8
|
+
summary: An (unofficial) Campfire API
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: brandon@opensoul.org
|
12
|
+
homepage: http://tinder.rubyforge.org
|
13
|
+
rubyforge_project: tinder
|
14
|
+
description: An API for interfacing with Campfire, the 37Signals chat application.
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
authors:
|
29
|
+
- Brandon Keepers
|
30
|
+
files:
|
31
|
+
- CHANGELOG.txt
|
32
|
+
- Manifest.txt
|
33
|
+
- README.txt
|
34
|
+
- Rakefile
|
35
|
+
- init.rb
|
36
|
+
- lib/tinder.rb
|
37
|
+
- lib/tinder/campfire.rb
|
38
|
+
- lib/tinder/room.rb
|
39
|
+
- lib/tinder/version.rb
|
40
|
+
- test/remote/remote_campfire_test.rb
|
41
|
+
- test/test_helper.rb
|
42
|
+
test_files:
|
43
|
+
- test/remote/remote_campfire_test.rb
|
44
|
+
rdoc_options: []
|
45
|
+
|
46
|
+
extra_rdoc_files: []
|
47
|
+
|
48
|
+
executables: []
|
49
|
+
|
50
|
+
extensions: []
|
51
|
+
|
52
|
+
requirements: []
|
53
|
+
|
54
|
+
dependencies:
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activesupport
|
57
|
+
version_requirement:
|
58
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 0.0.0
|
63
|
+
version:
|
64
|
+
- !ruby/object:Gem::Dependency
|
65
|
+
name: hpricot
|
66
|
+
version_requirement:
|
67
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">"
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: 0.0.0
|
72
|
+
version:
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: hoe
|
75
|
+
version_requirement:
|
76
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 1.1.7
|
81
|
+
version:
|