campy 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .rvmrc
19
+ .rbx/
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 1.9.2
5
+ - rbx-19mode
6
+ - 1.8.7
7
+ - ree
8
+ - rbx-18mode
9
+ - jruby-18mode
10
+ - ruby-head
11
+ - jruby-head
@@ -0,0 +1,5 @@
1
+ ## 0.1.0 (April 4, 2012)
2
+
3
+ The initial release.
4
+
5
+ [@fnichol]: https://github.com/fnichol
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in campy.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'rake', '~> 0.9'
8
+
9
+ gem 'growl'
10
+ gem 'guard'
11
+ gem 'guard-minitest'
12
+ end
13
+
14
+ platforms :jruby do
15
+ gem 'jruby-openssl'
16
+ end
@@ -0,0 +1,5 @@
1
+ guard 'minitest' do
2
+ # with Minitest::Spec
3
+ watch(%r|^spec/(.*)_spec\.rb|)
4
+ watch(%r|^lib/(.*)([^/]+)\.rb|) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
5
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Fletcher Nichol
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,99 @@
1
+ # <a name="title"></a> Campy [![Build Status](https://secure.travis-ci.org/fnichol/campy.png)](http://travis-ci.org/fnichol/campy)
2
+
3
+ Tiny Campfire client so you can get on with it. It's implemented on top of
4
+ `Net::HTTP` and only requires the `multi_json` gem for Ruby compatibilities.
5
+
6
+ ## <a name="installation"></a> Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'campy'
12
+ ```
13
+
14
+ And then execute:
15
+
16
+ ```bash
17
+ $ bundle
18
+ ```
19
+
20
+ Or install it yourself as:
21
+
22
+ ```
23
+ $ gem install campy
24
+ ```
25
+
26
+ ## <a name="usage"></a> Usage
27
+
28
+ First create a `campfire.yml` file in your home directory:
29
+
30
+ ```bash
31
+ $ cat <<CAMPFIRE_YAML > $HOME/.campfire.yml
32
+ :account: mysubdomain
33
+ :token: mytoken123
34
+ :room: House of Hubot
35
+ CAMPFIRE_YAML
36
+ ```
37
+
38
+ ### <a name="usage-bin"></a> campy Command
39
+
40
+ Campy comes with the `campy` command so you can send messages from the
41
+ command line:
42
+
43
+ ```bash
44
+ $ campy speak "Campy says yello"
45
+ $ campy play ohmy
46
+ ```
47
+
48
+ ### <a name="usage-ruby"></a> Ruby Library
49
+
50
+ There's not much to the API; create a `Campy::Room` and go:
51
+
52
+ ```ruby
53
+ require 'campy'
54
+
55
+ campy = Campy::Room.new(:account => "mysubdomain", :token => "mytoken123",
56
+ :room => "House of Hubot")
57
+ campy.speak "Campy says yello"
58
+ campy.play "ohmy"
59
+ ```
60
+
61
+ Why not use the `campfire.yml` config? Let's do that:
62
+
63
+ ```ruby
64
+ require 'campy'
65
+ require 'yaml'
66
+
67
+ campy = Campy::Room.new(YAML.load_file(File.expand_path("~/.campfire.yml")))
68
+ campy.speak "Campy says yello"
69
+ campy.play "ohmy"
70
+ ```
71
+
72
+ ## <a name="development"></a> Development
73
+
74
+ * Source hosted at [GitHub][repo]
75
+ * Report issues/questions/feature requests on [GitHub Issues][issues]
76
+
77
+ Pull requests are very welcome! Make sure your patches are well tested.
78
+ Ideally create a topic branch for every separate change you make. For
79
+ example:
80
+
81
+ 1. Fork the repo
82
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
83
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
84
+ 4. Push to the branch (`git push origin my-new-feature`)
85
+ 5. Create new Pull Request
86
+
87
+ ## <a name="authors"></a> Authors
88
+
89
+ Created and maintained by [Fletcher Nichol][fnichol] (<fnichol@nichol.ca>)
90
+
91
+ ## <a name="license"></a> License
92
+
93
+ MIT (see [LICENSE][license])
94
+
95
+ [license]: https://github.com/fnichol/campy/blob/master/LICENSE
96
+ [fnichol]: https://github.com/fnichol
97
+ [repo]: https://github.com/fnichol/campy
98
+ [issues]: https://github.com/fnichol/campy/issues
99
+ [contributors]: https://github.com/fnichol/campy/contributors
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.libs.push "lib"
8
+ t.test_files = FileList['spec/**/*_spec.rb']
9
+ t.verbose = true
10
+ end
11
+
12
+ task :default => 'test'
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
4
+ require 'campy'
5
+ require 'yaml'
6
+
7
+ def options
8
+ yaml_file = File.expand_path(ENV['CAMPFIRE_YAML_FILE'] || '~/.campfire.yml')
9
+ if !File.exists?(yaml_file)
10
+ abort "File '#{yaml_file}' does not exist with campfire configuration."
11
+ end
12
+ YAML.load_file(yaml_file)
13
+ end
14
+
15
+ def usage
16
+ <<-USAGE.gsub(/^ {4}/, '')
17
+
18
+ Usage
19
+
20
+ campy <action> <message>
21
+
22
+ Actions
23
+
24
+ help - Display CLI help (this output)
25
+ speak - Speak a message into the campfire room
26
+ play - Play a sound into the campfire room
27
+
28
+ USAGE
29
+ end
30
+
31
+ if ARGV.first == "help"
32
+ puts usage
33
+ exit
34
+ end
35
+
36
+ abort usage if ARGV.empty? || !%w{speak play}.include?(ARGV.first)
37
+
38
+ Campy::Room.new(options).send(ARGV.shift, ARGV.shift)
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/campy/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Fletcher Nichol"]
6
+ gem.email = ["fnichol@nichol.ca"]
7
+ gem.description = %q{Small Campfire client using Net::HTTP.}
8
+ gem.summary = gem.description
9
+ gem.homepage = "http://fnichol.github.com/campy/"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "campy"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Campy::VERSION
17
+
18
+ gem.add_dependency "multi_json", "~> 1.0"
19
+
20
+ gem.add_development_dependency "minitest", "~> 2.12.0"
21
+ gem.add_development_dependency "webmock", "~> 1.8.5"
22
+ end
@@ -0,0 +1,6 @@
1
+ require 'campy/version'
2
+ require 'campy/room'
3
+
4
+ module Campy
5
+ # Your code goes here...
6
+ end
@@ -0,0 +1,186 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'net/https'
3
+ require 'multi_json'
4
+
5
+ module Campy
6
+ class Room
7
+ # Public: Error class raised when a room ID cannot be found with a
8
+ # given name.
9
+ class NotFound < RuntimeError ; end
10
+
11
+ # Public: Error class raised when an HTTP error has occured.
12
+ class ConnectionError < RuntimeError ; end
13
+
14
+ # Public: Returns the String account name.
15
+ attr_reader :account
16
+
17
+ # Public: Returns the String room name.
18
+ attr_reader :room
19
+
20
+ # Public: Returns the API token String for a user.
21
+ attr_reader :ssl
22
+
23
+ # Public: Initializes a Room from a Hash of configuration options.
24
+ #
25
+ # options - A Hash of options to set up the Room (default: {}):
26
+ # :account - The String account/subdomain name.
27
+ # :room - The String room name, not the room ID.
28
+ # :token - The API token String for a user.
29
+ # :ssl - A truthy object which is true when SSL is
30
+ # required (default: true).
31
+ def initialize(options = {})
32
+ options = { :ssl => true }.merge(options)
33
+
34
+ [:account, :room, :token, :ssl].each do |option|
35
+ instance_variable_set "@#{option}", options[option]
36
+ end
37
+ end
38
+
39
+ # Public: Returns the Integer room ID of the Campfire room.
40
+ #
41
+ # Returns the Integer room ID.
42
+ # Raises NotFound if a room cannot be found for the given name.
43
+ # Raises ConnectionError if an HTTP error occurs.
44
+ def room_id
45
+ @room_id ||= fetch_room_id
46
+ end
47
+
48
+ # Public: Posts a message into the campfire room.
49
+ #
50
+ # msg - A String message.
51
+ #
52
+ # Returns true if message is delivered.
53
+ # Raises ConnectionError if an HTTP error occurs.
54
+ def speak(msg)
55
+ send_message(msg)
56
+ end
57
+
58
+ # Public: Plays a sound into the campfire room.
59
+ #
60
+ # sound - A String representing the sound.
61
+ #
62
+ # Returns true if message is delivered.
63
+ # Raises ConnectionError if an HTTP error occurs.
64
+ def play(msg)
65
+ send_message(msg, 'SoundMessage')
66
+ end
67
+
68
+ private
69
+
70
+ # Internal: Array of errors that will be wrapped when using Net::HTTP.
71
+ HTTP_ERRORS = [Timeout::Error, Errno::EINVAL, Errno::ECONNRESET,
72
+ EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
73
+ Net::ProtocolError, SocketError, OpenSSL::SSL::SSLError,
74
+ Errno::ECONNREFUSED]
75
+
76
+ # Internal: Returns the API token String for a user.
77
+ attr_reader :token
78
+
79
+ # Internal: Returns the campfire hostname with subdomain.
80
+ def host
81
+ "#{account}.campfirenow.com"
82
+ end
83
+
84
+ # Internal: Returns the Integer HTTP port number to connect with.
85
+ def port
86
+ ssl ? 443 : 80
87
+ end
88
+
89
+ # Internal: Returns the Integer number of the room.
90
+ #
91
+ # Returns the Integer room number.
92
+ # Raises NotFound if a room cannot be found for the given name.
93
+ # Raises ConnectionError if an HTTP error occurs.
94
+ def fetch_room_id
95
+ connect do |http|
96
+ response = http.request(http_request(:get, "/rooms.json"))
97
+
98
+ case response
99
+ when Net::HTTPOK
100
+ find_room_in_json(MultiJson.decode(response.body))
101
+ else
102
+ raise ConnectionError
103
+ end
104
+ end
105
+ end
106
+
107
+ # Internal: Posts a message to the campfire room.
108
+ #
109
+ # msg - The String message to send.
110
+ # type - The String type of campfire message (default: TextMessage).
111
+ #
112
+ # Returns true if message is delivered.
113
+ # Raises ConnectionError if an HTTP error occurs.
114
+ def send_message(msg, type = 'TextMessage')
115
+ connect do |http|
116
+ request = http_request(:post, "/room/#{room_id}/speak.json")
117
+ request.body = MultiJson.encode(
118
+ { :message => { :body => msg, :type => type } })
119
+ response = http.request(request)
120
+
121
+ case response
122
+ when Net::HTTPCreated
123
+ true
124
+ else
125
+ raise ConnectionError,
126
+ "Error sending message '#{msg}' (#{response.class})"
127
+ end
128
+ end
129
+ end
130
+
131
+ # Internal: Parses through the rooms JSON response and returns the
132
+ # Integer room ID.
133
+ #
134
+ # json - the rooms Hash of JSON data.
135
+ #
136
+ # Returns the Integer room number.
137
+ # Raises NotFound if a room cannot be found for the given name.
138
+ def find_room_in_json(json)
139
+ room_hash = json["rooms"].find { |r| r["name"] == room }
140
+
141
+ if room_hash
142
+ room_hash["id"]
143
+ else
144
+ raise NotFound, "Room name '#{room}' could not be found."
145
+ end
146
+ end
147
+
148
+ # Internal: Creates a Net::HTTP connection and yields to a block with
149
+ # the connection.
150
+ #
151
+ # Yields the Net::HTTP connection.
152
+ #
153
+ # Returns the return value (if any) of the block.
154
+ # Raises ConnectionError if any common HTTP errors are raised.
155
+ def connect
156
+ http = Net::HTTP.new(host, port)
157
+ http.use_ssl = ssl
158
+
159
+ begin
160
+ yield http
161
+ rescue *HTTP_ERRORS => exception
162
+ raise ConnectionError, "#{exception.class.name}: #{exception.message}"
163
+ end
164
+ end
165
+
166
+ # Internal: Returns a Net::HTTPRequest object initialized with
167
+ # authentication and content headers set.
168
+ #
169
+ # verb - A Symbol representing an HTTP verb.
170
+ # path - The String path of the request.
171
+ #
172
+ # Examples
173
+ #
174
+ # http_request(:get, "/rooms.json")
175
+ # http_request(:post, "/room/1/speak.json")
176
+ #
177
+ # Returns a Net::HTTPRequest object.
178
+ def http_request(verb, path)
179
+ klass = klass = Net::HTTP.const_get(verb.to_s.capitalize)
180
+ request = klass.new(path)
181
+ request.basic_auth(token, "X")
182
+ request["Content-Type"] = "application/json"
183
+ request
184
+ end
185
+ end
186
+ end
@@ -0,0 +1,4 @@
1
+ # -*- encoding: utf-8 -*-
2
+ module Campy
3
+ VERSION = "0.1.0"
4
+ end
@@ -0,0 +1,166 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require 'minitest/autorun'
3
+ require 'webmock/minitest'
4
+ require 'campy/room'
5
+
6
+ describe Campy::Room do
7
+ WRAPPED_ERRORS = [Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError,
8
+ Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError,
9
+ SocketError, OpenSSL::SSL::SSLError, Errno::ECONNREFUSED]
10
+
11
+ let(:opts) do
12
+ { :account => 'zubzub', :token => 'yepyep',
13
+ :room => 'myroom', :ssl => true }
14
+ end
15
+
16
+ let(:stub_rooms!) do
17
+ stub_request(:get, "https://yepyep:X@zubzub.campfirenow.com/rooms.json").
18
+ with(:headers => {'Content-Type' => 'application/json'}).
19
+ to_return(:status => 200, :body => fixture("rooms"), :headers => {})
20
+ end
21
+
22
+ let(:stub_rooms_no_room!) do
23
+ stub_request(:get, "https://yepyep:X@zubzub.campfirenow.com/rooms.json").
24
+ with(:headers => {'Content-Type' => 'application/json'}).
25
+ to_return(:status => 200, :body => fixture("no_rooms"), :headers => {})
26
+ end
27
+
28
+ let(:stub_rooms_invalid_token!) do
29
+ stub_request(:get, "https://yepyep:X@zubzub.campfirenow.com/rooms.json").
30
+ with(:headers => {'Content-Type' => 'application/json'}).
31
+ to_return(:status => 401, :body => "HTTP Basic: Access denied.\n",
32
+ :headers => {})
33
+ end
34
+
35
+ def stub_rooms_error!(error)
36
+ stub_request(:get, "https://yepyep:X@zubzub.campfirenow.com/rooms.json").
37
+ with(:headers => {'Content-Type' => 'application/json'}).
38
+ to_raise(error)
39
+ end
40
+
41
+ def stub_speak!(msg, type = 'TextMessage')
42
+ stub_request(:post, "https://yepyep:X@zubzub.campfirenow.com/room/123456/speak.json").
43
+ with(:headers => {'Content-Type' => 'application/json'},
44
+ :body => {:message => {:body => msg, :type => type}}).
45
+ to_return(:status => 201, :headers => {},
46
+ :body => fixture("speak").sub(/@@MESSAGE@@/, msg))
47
+ end
48
+
49
+ def stub_speak_error!(error)
50
+ stub_request(:post, "https://yepyep:X@zubzub.campfirenow.com/room/123456/speak.json").
51
+ with(:headers => {'Content-Type' => 'application/json'}).
52
+ to_raise(error)
53
+ end
54
+
55
+ def fixture(name)
56
+ File.read(File.dirname(__FILE__) + "/../fixtures/webmock_#{name}.txt")
57
+ end
58
+
59
+ describe "#initialize" do
60
+ it "takes a hash of campfire configuration" do
61
+ room = Campy::Room.new(opts)
62
+ room.account.must_equal 'zubzub'
63
+ room.room.must_equal 'myroom'
64
+ end
65
+
66
+ it "defaults to SSL mode enabled" do
67
+ opts.delete(:ssl)
68
+ room = Campy::Room.new(opts)
69
+ room.ssl.must_equal true
70
+ end
71
+ end
72
+
73
+ describe "#room_id" do
74
+ let(:subject) { Campy::Room.new(opts) }
75
+
76
+ it "fetches the room id from the API" do
77
+ stub_rooms!
78
+ subject.room_id.must_equal 666666
79
+ end
80
+
81
+ it "raises NotFound if no room is found" do
82
+ stub_rooms_no_room!
83
+
84
+ proc { subject.room_id }.must_raise(
85
+ Campy::Room::NotFound)
86
+ end
87
+
88
+ it "raises ConnectionError if the token is invalid" do
89
+ stub_rooms_invalid_token!
90
+
91
+ proc { subject.room_id }.must_raise(
92
+ Campy::Room::ConnectionError)
93
+ end
94
+
95
+ WRAPPED_ERRORS.each do |error|
96
+ it "wraps #{error} and raises a ConnectionError" do
97
+ stub_rooms_error!(error)
98
+
99
+ proc { subject.room_id }.must_raise(
100
+ Campy::Room::ConnectionError)
101
+ end
102
+ end
103
+ end
104
+
105
+ describe "#speak" do
106
+ let(:subject) { Campy::Room.new(opts) }
107
+
108
+ before do
109
+ # stub out #room_id since we don't care about this API call
110
+ def subject.room_id ; 123456 ; end
111
+ end
112
+
113
+ it "calls the speak API with a message" do
114
+ stub = stub_speak!("talking about talking")
115
+ subject.speak "talking about talking"
116
+
117
+ assert_requested(stub)
118
+ end
119
+
120
+ it "returns true when message is delivered" do
121
+ stub = stub_speak!("talking about talking")
122
+
123
+ subject.speak("talking about talking").must_equal true
124
+ end
125
+
126
+ WRAPPED_ERRORS.each do |error|
127
+ it "wraps #{error} and raises a ConnectionError" do
128
+ stub_speak_error!(error)
129
+
130
+ proc { subject.speak "nope" }.must_raise(
131
+ Campy::Room::ConnectionError)
132
+ end
133
+ end
134
+ end
135
+
136
+ describe "#play" do
137
+ let(:subject) { Campy::Room.new(opts) }
138
+
139
+ before do
140
+ # stub out #room_id since we don't care about this API call
141
+ def subject.room_id ; 123456 ; end
142
+ end
143
+
144
+ it "calls the play API with a sound" do
145
+ stub = stub_speak!("tada", "SoundMessage")
146
+ subject.play "tada"
147
+
148
+ assert_requested(stub)
149
+ end
150
+
151
+ it "returns true when message is delivered" do
152
+ stub = stub_speak!("tada", "SoundMessage")
153
+
154
+ subject.play("tada").must_equal true
155
+ end
156
+
157
+ WRAPPED_ERRORS.each do |error|
158
+ it "wraps #{error} and raises a ConnectionError" do
159
+ stub_speak_error!(error)
160
+
161
+ proc { subject.play "tada" }.must_raise(
162
+ Campy::Room::ConnectionError)
163
+ end
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,4 @@
1
+ {
2
+ "rooms": [
3
+ ]
4
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "rooms": [
3
+ {
4
+ "created_at": "2012/01/01 00:01:02 +0000",
5
+ "id": 123456,
6
+ "locked": false,
7
+ "membership_limit": 4,
8
+ "name": "nuggettalk",
9
+ "topic": "Pop go the nuggets",
10
+ "updated_at": "2012/02/23 02:21:49 +0000"
11
+ },
12
+ {
13
+ "created_at": "2011/01/01 00:02:03 +0000",
14
+ "id": 666666,
15
+ "locked": false,
16
+ "membership_limit": 12,
17
+ "name": "myroom",
18
+ "topic": "There is only one test",
19
+ "updated_at": "2011/12/05 16:23:40 +0000"
20
+ }
21
+ ]
22
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "message": {
3
+ "body": "@@MESSAGE@@",
4
+ "created_at": "2012/04/04 18:11:36 +0000",
5
+ "id": 999999999,
6
+ "room_id": 123456,
7
+ "starred": false,
8
+ "type": "TextMessage",
9
+ "user_id": 666
10
+ }
11
+ }
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: campy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Fletcher Nichol
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-04 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: multi_json
16
+ requirement: &70347351272720 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70347351272720
25
+ - !ruby/object:Gem::Dependency
26
+ name: minitest
27
+ requirement: &70347351272200 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 2.12.0
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70347351272200
36
+ - !ruby/object:Gem::Dependency
37
+ name: webmock
38
+ requirement: &70347351271740 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 1.8.5
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70347351271740
47
+ description: Small Campfire client using Net::HTTP.
48
+ email:
49
+ - fnichol@nichol.ca
50
+ executables:
51
+ - campy
52
+ extensions: []
53
+ extra_rdoc_files: []
54
+ files:
55
+ - .gitignore
56
+ - .travis.yml
57
+ - CHANGELOG.md
58
+ - Gemfile
59
+ - Guardfile
60
+ - LICENSE
61
+ - README.md
62
+ - Rakefile
63
+ - bin/campy
64
+ - campy.gemspec
65
+ - lib/campy.rb
66
+ - lib/campy/room.rb
67
+ - lib/campy/version.rb
68
+ - spec/campy/room_spec.rb
69
+ - spec/fixtures/webmock_no_rooms.txt
70
+ - spec/fixtures/webmock_rooms.txt
71
+ - spec/fixtures/webmock_speak.txt
72
+ homepage: http://fnichol.github.com/campy/
73
+ licenses: []
74
+ post_install_message:
75
+ rdoc_options: []
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ! '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ segments:
85
+ - 0
86
+ hash: 1286988910110324181
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ! '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ segments:
94
+ - 0
95
+ hash: 1286988910110324181
96
+ requirements: []
97
+ rubyforge_project:
98
+ rubygems_version: 1.8.17
99
+ signing_key:
100
+ specification_version: 3
101
+ summary: Small Campfire client using Net::HTTP.
102
+ test_files:
103
+ - spec/campy/room_spec.rb
104
+ - spec/fixtures/webmock_no_rooms.txt
105
+ - spec/fixtures/webmock_rooms.txt
106
+ - spec/fixtures/webmock_speak.txt