campy 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.
@@ -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