broach 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +18 -0
- data/lib/broach.rb +92 -0
- data/lib/broach/attributes.rb +18 -0
- data/lib/broach/exceptions.rb +12 -0
- data/lib/broach/room.rb +51 -0
- data/lib/broach/session.rb +73 -0
- data/lib/broach/user.rb +16 -0
- metadata +61 -0
data/LICENSE
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Copyright (c) 2009 Manfred Stienstra, Fingertips <manfred@fngtps.com>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
5
|
+
the Software without restriction, including without limitation the rights to
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
7
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
8
|
+
subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
15
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
16
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
17
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
18
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/lib/broach.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'rubygems' rescue nil
|
2
|
+
require 'rest'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
require 'broach/exceptions'
|
6
|
+
|
7
|
+
# === Settings
|
8
|
+
#
|
9
|
+
# Before you can do anything else you will need to provide credentials first, this includes the account name and
|
10
|
+
# authentication token. The +use_ssl+ parameter is optional and defaults to false.
|
11
|
+
#
|
12
|
+
# Broach.settings = { 'account' => 'example', 'token' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'use_ssl' => true }
|
13
|
+
#
|
14
|
+
# You can find the token for any Campfire account by logging into the web interface and clicking 'My Info' in the top-right
|
15
|
+
# corner.
|
16
|
+
#
|
17
|
+
# === Say someting in a room real quick
|
18
|
+
#
|
19
|
+
# If you just need to say something real quick in a room, you can use the speak class method.
|
20
|
+
#
|
21
|
+
# Broach.speak("Office", "Manfred just deployed a new version of the weblog (http://www.fngtps.com)")
|
22
|
+
#
|
23
|
+
# Note that this fetches a list of all rooms so it can figure out the ID for the room you specified.
|
24
|
+
#
|
25
|
+
# === Post a lot of stuff to a room
|
26
|
+
#
|
27
|
+
# If you want to post multiple lines to one room, it's a good idea to create a Room instance.
|
28
|
+
#
|
29
|
+
# room = Broach.rooms.find { |room| room.name == 'Office' }
|
30
|
+
# room.speak('Manfred just commited to the `weblog' repository')
|
31
|
+
# room.speak("commit 4578530113cb87e1e7dbd696c376181e97d429d7\n" +
|
32
|
+
# "Author: Manfred Stienstra <manfred@fngtps.com>\n" +
|
33
|
+
# "Date: Wed Dec 16 14:03:33 2009 +0100\n\n" +
|
34
|
+
# " Add a speak method to Broach to quickly say something in a room.", :type => :paste)
|
35
|
+
module Broach
|
36
|
+
autoload :Attributes, 'broach/attributes'
|
37
|
+
autoload :Session, 'broach/session'
|
38
|
+
autoload :User, 'broach/user'
|
39
|
+
autoload :Room, 'broach/room'
|
40
|
+
|
41
|
+
# Returns the current Broach settings
|
42
|
+
def self.settings
|
43
|
+
@settings
|
44
|
+
end
|
45
|
+
|
46
|
+
# Sets the broach settings
|
47
|
+
def self.settings=(settings)
|
48
|
+
@settings = settings
|
49
|
+
@session = nil
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns a session object with the current settings
|
53
|
+
def self.session
|
54
|
+
@session ||= Broach::Session.new(settings)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Returns a User instance for the currently authenticated user
|
58
|
+
def self.me
|
59
|
+
Broach::User.me
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns a Room instance for all rooms accesible to the currently authenticated user
|
63
|
+
def self.rooms
|
64
|
+
Broach::Room.all
|
65
|
+
end
|
66
|
+
|
67
|
+
# Send a message to a room with a certain name.
|
68
|
+
#
|
69
|
+
# Note that you should only use this method if you're sending just one message. It fetches
|
70
|
+
# all rooms before sending the message to find the room with the name you're specifying.
|
71
|
+
#
|
72
|
+
# If you need to send multiple messages to the same room you should instantiate a room first.
|
73
|
+
#
|
74
|
+
# ==== Options
|
75
|
+
#
|
76
|
+
# +room+
|
77
|
+
# The name of the room, ie. 'Office'
|
78
|
+
# +content+
|
79
|
+
# The content of the message, see Broach::Room#speak for more information.
|
80
|
+
# +options+
|
81
|
+
# Options for the message, see Broach::Room#speak for more information.
|
82
|
+
#
|
83
|
+
# ==== Examples
|
84
|
+
#
|
85
|
+
# Broach.speak('Office', 'Manfred just deployed a new version of the weblog (http://www.fngtps.com)')
|
86
|
+
# Broach.speak('Office', 'crickets', :type => :sound)
|
87
|
+
def self.speak(room_name, content, options={})
|
88
|
+
if room = rooms.find { |room| room.name == room_name }
|
89
|
+
room.speak(content, options)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Broach
|
2
|
+
# Makes a very simple attribute driven model from the class when included.
|
3
|
+
module Attributes
|
4
|
+
def initialize(attributes)
|
5
|
+
@attributes = attributes
|
6
|
+
end
|
7
|
+
|
8
|
+
def id; @attributes['id']; end
|
9
|
+
|
10
|
+
def method_missing(method, *arguments, &block)
|
11
|
+
if value = @attributes[method.to_s]
|
12
|
+
value
|
13
|
+
else
|
14
|
+
super
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Broach
|
2
|
+
# Raised when something unexpected happened during communication with Campfire
|
3
|
+
class APIError < RuntimeError
|
4
|
+
attr_accessor :response
|
5
|
+
end
|
6
|
+
|
7
|
+
# Raised when the credentials were incorrect
|
8
|
+
class AuthenticationError < APIError; end
|
9
|
+
|
10
|
+
# Raised when the credentials were correct, but the resource could not be accessed
|
11
|
+
class AuthorizationError < APIError; end
|
12
|
+
end
|
data/lib/broach/room.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
module Broach
|
2
|
+
# Represents a chat room on the server
|
3
|
+
class Room
|
4
|
+
TYPE_MAP = {
|
5
|
+
:text => 'TextMessage',
|
6
|
+
:paste => 'PasteMessage',
|
7
|
+
:sound => 'SoundMessage'
|
8
|
+
}
|
9
|
+
|
10
|
+
include Broach::Attributes
|
11
|
+
|
12
|
+
# Send a message to the room
|
13
|
+
#
|
14
|
+
# ==== Parameters and options
|
15
|
+
#
|
16
|
+
# [+content+]
|
17
|
+
# Content to send. For a normal text message this is the content of the message. For a paste
|
18
|
+
# it's the content of the paste. For a sound it's the name of the sound.
|
19
|
+
#
|
20
|
+
# [<tt>:type</tt>]
|
21
|
+
# The type of message to send, this is :text by default for normal text messages.
|
22
|
+
# You can also use :paste and :sound. Valid sound messages are 'rimshot', 'crickets',
|
23
|
+
# or 'trombone'.
|
24
|
+
#
|
25
|
+
# ==== Examples
|
26
|
+
#
|
27
|
+
# room = Broach::Room.all.first
|
28
|
+
# room.speak("Let's review these figures.")
|
29
|
+
# room.speak("<code>$stderr.write('-')</code>", :type => :paste)
|
30
|
+
# room.speak("rimshot", :type => :sound)
|
31
|
+
def speak(content, options={})
|
32
|
+
options[:type] ||= :text
|
33
|
+
Broach.session.post("room/#{id}/speak", 'message' => {
|
34
|
+
'type' => TYPE_MAP[options[:type]],
|
35
|
+
'body' => content
|
36
|
+
})['message']
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns a Room instance for all rooms accessible to the authenticated user
|
40
|
+
def self.all
|
41
|
+
Broach.session.get('rooms')['rooms'].map do |attributes|
|
42
|
+
Broach::Room.new(attributes)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns a Room instance for a room with a specific ID
|
47
|
+
def self.find(id)
|
48
|
+
new(Broach.session.get("room/#{id.to_i}")['room'])
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Broach
|
2
|
+
# Represents a session with Campfire
|
3
|
+
class Session
|
4
|
+
include Broach::Attributes
|
5
|
+
|
6
|
+
# Returns true when the connection should use SSL and false otherwise.
|
7
|
+
def use_ssl?
|
8
|
+
@attributes['use_ssl'] || false
|
9
|
+
end
|
10
|
+
|
11
|
+
# Returns either http or https depending on whether we should use SSL or not.
|
12
|
+
def scheme
|
13
|
+
use_ssl? ? 'https' : 'http'
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns the full URL for a certain path
|
17
|
+
#
|
18
|
+
# session.url_for('rooms') #=> "http://example.campfirenow.com/rooms"
|
19
|
+
def url_for(path)
|
20
|
+
["#{scheme}:/", "#{account}.campfirenow.com", path].join('/')
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns the headers to send for a specific HTTP method
|
24
|
+
#
|
25
|
+
# session.headers_for(:get) #=> { 'Accept' => 'application/json' }
|
26
|
+
def headers_for(method)
|
27
|
+
headers = { 'Accept' => 'application/json', 'User-Agent' => 'Broach' }
|
28
|
+
headers['Content-type'] = 'application/json' if method == :post
|
29
|
+
headers
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns the credentials to authenticate the current user
|
33
|
+
def credentials
|
34
|
+
{ :username => token, :password => 'x' }
|
35
|
+
end
|
36
|
+
|
37
|
+
# Gets a resource with a certain path on the server. When the GET is succesful
|
38
|
+
# the parsed body is returned, otherwise an exception is raised.
|
39
|
+
def get(path)
|
40
|
+
response = REST.get(url_for(path), headers_for(:get), credentials)
|
41
|
+
if response.ok?
|
42
|
+
return JSON.parse(response.body)
|
43
|
+
else
|
44
|
+
handle_response(:get, path, response)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Posts a resource to a certain path on the server. When the POST is successful
|
49
|
+
# the parsed body is returned, otherwise an exception is raised.
|
50
|
+
def post(path, payload)
|
51
|
+
response = REST.post(url_for(path), JSON.dump(payload), headers_for(:post), credentials)
|
52
|
+
if response.created?
|
53
|
+
return JSON.parse(response.body)
|
54
|
+
else
|
55
|
+
handle_response(:post, path, response)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def handle_response(method, path, response)
|
62
|
+
exception = if response.unauthorized?
|
63
|
+
Broach::AuthenticationError.new("Couldn't authenticate with the supplied credentials for the account `#{account}'")
|
64
|
+
elsif response.forbidden?
|
65
|
+
Broach::AuthorizationError.new("Couldn't #{method.to_s.upcase} the resource `#{path}' on the account `#{account}'")
|
66
|
+
else
|
67
|
+
Broach::APIError.new("Response from the server was unexpected (#{response.status_code})")
|
68
|
+
end
|
69
|
+
exception.response = response
|
70
|
+
raise exception
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/broach/user.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module Broach
|
2
|
+
# Represents a user on the server
|
3
|
+
class User
|
4
|
+
include Broach::Attributes
|
5
|
+
|
6
|
+
# Returns a User instance for the currently authenticated user
|
7
|
+
def self.me
|
8
|
+
new(Broach.session.get('users/me')['user'])
|
9
|
+
end
|
10
|
+
|
11
|
+
# Returns a User instance for a user with a specific ID
|
12
|
+
def self.find(id)
|
13
|
+
new(Broach.session.get("users/#{id.to_i}")['user'])
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: broach
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "0.1"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Manfred Stienstra
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-12-16 00:00:00 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: " Ruby implementation of 37signal's Campfire API.\n"
|
17
|
+
email: manfred@fngtps.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- LICENSE
|
24
|
+
files:
|
25
|
+
- LICENSE
|
26
|
+
- lib/broach/attributes.rb
|
27
|
+
- lib/broach/exceptions.rb
|
28
|
+
- lib/broach/room.rb
|
29
|
+
- lib/broach/session.rb
|
30
|
+
- lib/broach/user.rb
|
31
|
+
- lib/broach.rb
|
32
|
+
has_rdoc: true
|
33
|
+
homepage:
|
34
|
+
licenses: []
|
35
|
+
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options:
|
38
|
+
- --charset=utf-8
|
39
|
+
require_paths:
|
40
|
+
- lib
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: "0"
|
46
|
+
version:
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "0"
|
52
|
+
version:
|
53
|
+
requirements: []
|
54
|
+
|
55
|
+
rubyforge_project:
|
56
|
+
rubygems_version: 1.3.5
|
57
|
+
signing_key:
|
58
|
+
specification_version: 3
|
59
|
+
summary: Ruby implementation of 37signal's Campfire API.
|
60
|
+
test_files: []
|
61
|
+
|