apphunk 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
File without changes
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Andreas Wolff
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,17 @@
1
+ = apphunk
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2009 rubyphunk. See LICENSE for details.
@@ -0,0 +1,71 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "apphunk"
8
+ gem.summary = %Q{A library to send messages to Apphunk.com}
9
+ gem.description = %Q{Apphunk is a library that allows your applications (currently only Ruby AND Rails) to send messages to Apphunk.com}
10
+ gem.email = "andreas@apphunk.com"
11
+ gem.homepage = "http://apphunk.com"
12
+ gem.authors = ["Andreas Wolff"]
13
+ gem.add_development_dependency "rspec", ">= 1.2.9"
14
+ gem.add_development_dependency "yard", ">= 0"
15
+ gem.add_dependency "json"
16
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
17
+ end
18
+ Jeweler::GemcutterTasks.new
19
+ rescue LoadError
20
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
21
+ end
22
+
23
+ require 'spec/rake/spectask'
24
+ Spec::Rake::SpecTask.new(:spec) do |spec|
25
+ spec.libs << 'lib' << 'spec'
26
+ spec.spec_files = FileList['spec/**/*_spec.rb']
27
+ end
28
+
29
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
30
+ spec.libs << 'lib' << 'spec'
31
+ spec.pattern = 'spec/**/*_spec.rb'
32
+ spec.rcov = true
33
+ end
34
+
35
+ task :spec => :check_dependencies
36
+
37
+ begin
38
+ require 'reek/adapters/rake_task'
39
+ Reek::RakeTask.new do |t|
40
+ t.fail_on_error = true
41
+ t.verbose = false
42
+ t.source_files = 'lib/**/*.rb'
43
+ end
44
+ rescue LoadError
45
+ task :reek do
46
+ abort "Reek is not available. In order to run reek, you must: sudo gem install reek"
47
+ end
48
+ end
49
+
50
+ begin
51
+ require 'roodi'
52
+ require 'roodi_task'
53
+ RoodiTask.new do |t|
54
+ t.verbose = false
55
+ end
56
+ rescue LoadError
57
+ task :roodi do
58
+ abort "Roodi is not available. In order to run roodi, you must: sudo gem install roodi"
59
+ end
60
+ end
61
+
62
+ task :default => :spec
63
+
64
+ begin
65
+ require 'yard'
66
+ YARD::Rake::YardocTask.new
67
+ rescue LoadError
68
+ task :yardoc do
69
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
70
+ end
71
+ end
File without changes
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
@@ -0,0 +1,70 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{apphunk}
8
+ s.version = "0.1.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Andreas Wolff"]
12
+ s.date = %q{2009-11-20}
13
+ s.description = %q{Apphunk is a library that allows your applications (currently only Ruby AND Rails) to send messages to Apphunk.com}
14
+ s.email = %q{andreas@apphunk.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "History.rdoc",
23
+ "LICENSE",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "TODO.rdoc",
27
+ "VERSION",
28
+ "apphunk.gemspec",
29
+ "lib/apphunk.rb",
30
+ "lib/apphunk/logger.rb",
31
+ "lib/apphunk/proxy.rb",
32
+ "lib/apphunk/remote.rb",
33
+ "lib/apphunk/remote/result.rb",
34
+ "rails/init.rb",
35
+ "spec/apphunk/proxy_spec.rb",
36
+ "spec/apphunk_spec.rb",
37
+ "spec/spec.opts",
38
+ "spec/spec_helper.rb"
39
+ ]
40
+ s.homepage = %q{http://apphunk.com}
41
+ s.rdoc_options = ["--charset=UTF-8"]
42
+ s.require_paths = ["lib"]
43
+ s.rubygems_version = %q{1.3.5}
44
+ s.summary = %q{A library to send messages to Apphunk.com}
45
+ s.test_files = [
46
+ "spec/apphunk/proxy_spec.rb",
47
+ "spec/apphunk_spec.rb",
48
+ "spec/spec_helper.rb"
49
+ ]
50
+
51
+ if s.respond_to? :specification_version then
52
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
53
+ s.specification_version = 3
54
+
55
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
56
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
57
+ s.add_development_dependency(%q<yard>, [">= 0"])
58
+ s.add_runtime_dependency(%q<json>, [">= 0"])
59
+ else
60
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
61
+ s.add_dependency(%q<yard>, [">= 0"])
62
+ s.add_dependency(%q<json>, [">= 0"])
63
+ end
64
+ else
65
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
66
+ s.add_dependency(%q<yard>, [">= 0"])
67
+ s.add_dependency(%q<json>, [">= 0"])
68
+ end
69
+ end
70
+
@@ -0,0 +1,26 @@
1
+ require 'rubygems'
2
+
3
+ module Apphunk
4
+
5
+ autoload :Logger, 'apphunk/logger'
6
+ autoload :Proxy, 'apphunk/proxy'
7
+ autoload :Remote, 'apphunk/remote'
8
+
9
+ class << self
10
+
11
+ attr_accessor :default_options
12
+
13
+ def log(message, options = {})
14
+ options = (self.default_options || {}).merge(options)
15
+ Apphunk::Proxy.send_message_to_apphunkd(message, options)
16
+ end
17
+
18
+ def log_with_options(options = {}, &block)
19
+ preserved_defaults = self.default_options
20
+ self.default_options = (self.default_options || {}).merge(options)
21
+ yield self
22
+ self.default_options = preserved_defaults
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,11 @@
1
+ module Apphunk
2
+ module Logger
3
+ class << self
4
+
5
+ def error(message)
6
+ puts "[Apphunk] Error: #{message}"
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,42 @@
1
+ require 'json'
2
+ require 'ostruct'
3
+
4
+ module Apphunk
5
+ module Proxy
6
+ class << self
7
+
8
+ PROXY_API_URL = "http://127.0.0.1:8212/api/messages"
9
+
10
+ def send_message_to_apphunkd(message, options)
11
+ payload = prepare_payload(message, options)
12
+ result = Apphunk::Remote.post(PROXY_API_URL, payload, 3)
13
+ return process_response(result)
14
+ end
15
+
16
+ def prepare_payload(message, options)
17
+ {
18
+ :message => message,
19
+ :token => options[:token],
20
+ :environment => options[:environment],
21
+ :tags => options[:tags],
22
+ :trails => (options[:trails].to_json if options[:trails])
23
+ }
24
+ end
25
+
26
+ def process_response(result)
27
+ if result.status == :ok
28
+ if result.response.code == '201'
29
+ return true
30
+ else
31
+ Apphunk::Logger.error "The Apphunkd Proxy couldn't store the message: #{result.response.code} / #{result.response.body}"
32
+ return false
33
+ end
34
+ else
35
+ Apphunk::Logger.error "Connection Error: Could not get a response from Apphunkd in time"
36
+ return false
37
+ end
38
+ end
39
+
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,29 @@
1
+ require 'net/http'
2
+ require 'timeout'
3
+ require 'uri'
4
+
5
+ module Apphunk
6
+ module Remote
7
+
8
+ autoload :Result, 'apphunk/remote/result'
9
+
10
+ class << self
11
+
12
+ def post(url, payload = {}, post_timeout = 30)
13
+ begin
14
+ Timeout.timeout(post_timeout) do
15
+ uri = URI.parse(url)
16
+ result = Remote::Result.new(:response => Net::HTTP.post_form(uri, payload))
17
+ result.status = :ok
18
+ return result
19
+ end
20
+ rescue SocketError, Errno::ECONNREFUSED
21
+ Remote::Result.new(:status => :connection_error)
22
+ rescue Timeout::Error
23
+ Remote::Result.new(:status => :timeout)
24
+ end
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,15 @@
1
+ module Apphunk
2
+ module Remote
3
+ class Result
4
+
5
+ attr_accessor :status
6
+ attr_accessor :response
7
+
8
+ def initialize(opts = {})
9
+ self.status = opts.delete(:status)
10
+ self.response = opts.delete(:response)
11
+ end
12
+
13
+ end
14
+ end
15
+ end
File without changes
@@ -0,0 +1,80 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Apphunk::Proxy do
4
+ describe 'send_message_to_apphunkd_proxy' do
5
+ before(:each) do
6
+ @opts = { :tags => 'test', :token => 'secret' }
7
+ Apphunk::Remote.stub!(:post)
8
+ Apphunk::Proxy.stub!(:process_response).and_return(true)
9
+ end
10
+
11
+ it 'should prepare the payload' do
12
+ Apphunk::Proxy.should_receive(:prepare_payload).with("My Message", @opts)
13
+ Apphunk::Proxy.send_message_to_apphunkd("My Message", @opts)
14
+ end
15
+
16
+ context 'posting' do
17
+ before(:each) do
18
+ @payload = { "prepared" => "payload" }
19
+ Apphunk::Proxy.stub!(:prepare_payload).and_return(@payload)
20
+ end
21
+
22
+ it 'should post the payload to the local Apphunkd api' do
23
+ Apphunk::Remote.should_receive(:post).with('http://127.0.0.1:8212/api/messages', @payload, anything)
24
+ Apphunk::Proxy.send_message_to_apphunkd("My Message", @opts)
25
+ end
26
+
27
+ it 'should allow the post to only take 3 seconds to finish' do
28
+ Apphunk::Remote.should_receive(:post).with(anything, anything, 3)
29
+ Apphunk::Proxy.send_message_to_apphunkd("My Message", @opts)
30
+ end
31
+ end
32
+ end
33
+
34
+ describe 'process_response' do
35
+ before(:each) do
36
+ @result = Apphunk::Remote::Result.new
37
+ @result.response = mock('Response')
38
+ Apphunk::Remote.stub!(:post).and_return(@result)
39
+ end
40
+
41
+ it 'should return true if the Proxy return 201, created' do
42
+ @result.status = :ok
43
+ @result.response.stub!(:code).and_return("201")
44
+ Apphunk::Proxy.process_response(@result)
45
+ end
46
+
47
+ it 'should output the failure and return false if the Proxy doesn not return 201' do
48
+ @result.status = :ok
49
+ @result.response.stub!(:code).and_return("404")
50
+ @result.response.stub!(:body).and_return("Not found.")
51
+ Apphunk::Logger.should_receive(:error).with(/Not found/)
52
+ Apphunk::Proxy.process_response(@result)
53
+ end
54
+
55
+ it 'should output the failure and return false if the connection to the proxy failed' do
56
+ @result.status = :connection_error
57
+ Apphunk::Logger.should_receive(:error).with(/Connection Error/)
58
+ Apphunk::Proxy.process_response(@result)
59
+ end
60
+ end
61
+
62
+ describe 'prepare_payload' do
63
+ before(:each) do
64
+ @opts = { :token => 'secret', :environment => 'development', :tags => 'test', :trails => { :user => '5' } }
65
+ end
66
+
67
+ it 'should create an OpenStruct, containing the message and extracted options' do
68
+ payload = Apphunk::Proxy.prepare_payload("My Message", @opts)
69
+ payload.message.should == "My Message"
70
+ payload.token.should == "secret"
71
+ payload.environment.should == "development"
72
+ payload.tags.should == "test"
73
+ end
74
+
75
+ it 'should render the trails to json' do
76
+ payload = Apphunk::Proxy.prepare_payload("My Message", @opts)
77
+ payload.trails.should == "{\"user\":\"5\"}"
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,64 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Apphunk" do
4
+ describe 'log' do
5
+ it 'should send the message to the apphunkd-proxy' do
6
+ Apphunk::Proxy.should_receive(:send_message_to_apphunkd).with("My Message", anything)
7
+ Apphunk.log("My Message")
8
+ end
9
+
10
+ it 'should bypass all options' do
11
+ opts = { :tags => "Hello, World", :trails => { :user => '5', :account => '12' } }
12
+ Apphunk::Proxy.should_receive(:send_message_to_apphunkd).with("My Message", opts)
13
+ Apphunk.log("My Message", opts)
14
+ end
15
+
16
+ it 'should merge provided options with Apphunk.default_options' do
17
+ Apphunk::Proxy.should_receive(:send_message_to_apphunkd).with("My Message", { :tags => 'Hello', :trails => { :user => '5' }})
18
+ Apphunk.default_options = { :trails => { :user => '5' }}
19
+ Apphunk.log("My Message", :tags => "Hello")
20
+ end
21
+
22
+ it 'should override Apphunk.default_options with provided options' do
23
+ Apphunk::Proxy.should_receive(:send_message_to_apphunkd).with("My Message", { :tags => 'Bye' })
24
+ Apphunk.default_options = { :tags => 'Hello'}
25
+ Apphunk.log("My Message", :tags => "Bye")
26
+ end
27
+ end
28
+
29
+ describe 'log_with_options' do
30
+ it 'should yield the Apphunk module back to the block' do
31
+ Apphunk.log_with_options do |apphunk|
32
+ apphunk.should == Apphunk
33
+ end
34
+ end
35
+
36
+ it 'should set Apphunk.default_options before yielding' do
37
+ Apphunk.log_with_options(:tags => 'hello') do |apphunk|
38
+ apphunk.default_options.should == { :tags => 'hello'}
39
+ end
40
+ end
41
+
42
+ it 'should merge existing Apphunk.default_options and provided options' do
43
+ Apphunk.default_options = { :token => 'secret' }
44
+ Apphunk.log_with_options(:tags => 'hello', :trails => { :user => '5' }) do |apphunk|
45
+ apphunk.default_options.should == { :tags => 'hello', :trails => { :user => '5'}, :token => 'secret'}
46
+ end
47
+ end
48
+
49
+ it 'should init the default_options hash on demand' do
50
+ Apphunk.default_options = nil
51
+ Apphunk.log_with_options(:tags => "hallo") do |apphunk|
52
+ apphunk.should == Apphunk
53
+ end
54
+ end
55
+
56
+ it 'should restore old default_options after yielding' do
57
+ Apphunk.default_options = { :token => 'secret' }
58
+ Apphunk.log_with_options(:tags => "hallo") do |apphunk|
59
+ apphunk.should == Apphunk
60
+ end
61
+ Apphunk.default_options.should == { :token => 'secret' }
62
+ end
63
+ end
64
+ end
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'apphunk'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: apphunk
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Andreas Wolff
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-11-20 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.2.9
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: yard
27
+ type: :development
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: json
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:
45
+ description: Apphunk is a library that allows your applications (currently only Ruby AND Rails) to send messages to Apphunk.com
46
+ email: andreas@apphunk.com
47
+ executables: []
48
+
49
+ extensions: []
50
+
51
+ extra_rdoc_files:
52
+ - LICENSE
53
+ - README.rdoc
54
+ files:
55
+ - .document
56
+ - .gitignore
57
+ - History.rdoc
58
+ - LICENSE
59
+ - README.rdoc
60
+ - Rakefile
61
+ - TODO.rdoc
62
+ - VERSION
63
+ - apphunk.gemspec
64
+ - lib/apphunk.rb
65
+ - lib/apphunk/logger.rb
66
+ - lib/apphunk/proxy.rb
67
+ - lib/apphunk/remote.rb
68
+ - lib/apphunk/remote/result.rb
69
+ - rails/init.rb
70
+ - spec/apphunk/proxy_spec.rb
71
+ - spec/apphunk_spec.rb
72
+ - spec/spec.opts
73
+ - spec/spec_helper.rb
74
+ has_rdoc: true
75
+ homepage: http://apphunk.com
76
+ licenses: []
77
+
78
+ post_install_message:
79
+ rdoc_options:
80
+ - --charset=UTF-8
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: "0"
88
+ version:
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: "0"
94
+ version:
95
+ requirements: []
96
+
97
+ rubyforge_project:
98
+ rubygems_version: 1.3.5
99
+ signing_key:
100
+ specification_version: 3
101
+ summary: A library to send messages to Apphunk.com
102
+ test_files:
103
+ - spec/apphunk/proxy_spec.rb
104
+ - spec/apphunk_spec.rb
105
+ - spec/spec_helper.rb