dynamicdudes-speaking-apps 1.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.rdoc +47 -0
- data/Rakefile +51 -0
- data/VERSION.yml +4 -0
- data/bin/speaking-apps +4 -0
- data/init.rb +1 -0
- data/lib/speaking_apps.rb +70 -0
- data/lib/speaking_apps/config.rb +58 -0
- data/lib/speaking_apps/daemon/control.rb +4 -0
- data/lib/speaking_apps/daemon/queue_service.rb +98 -0
- data/lib/speaking_apps/daemon/remote.rb +61 -0
- data/lib/speaking_apps/message_queue.rb +57 -0
- data/rails/init.rb +1 -0
- data/spec/lib/speaking_apps/config_spec.rb +22 -0
- data/spec/lib/speaking_apps/daemon/queue_service_spec.rb +12 -0
- data/spec/lib/speaking_apps/daemon/remote_spec.rb +40 -0
- data/spec/lib/speaking_apps/message_queue_spec.rb +52 -0
- data/spec/lib/speaking_apps_spec.rb +54 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +9 -0
- metadata +96 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 rubyphunk, speakingapps.com
|
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.
|
data/README.rdoc
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
= speaking-apps
|
2
|
+
|
3
|
+
speaking-apps allows you to add remote logging facilities to your application. It uses the http://speakingapps.com API to store and organize your messages. It works for all Ruby projects but was especially designed to be backed into your Rails app.
|
4
|
+
|
5
|
+
Caveats: You will need a http://speakingapps.com account.
|
6
|
+
|
7
|
+
== Setup
|
8
|
+
|
9
|
+
Github Home: http://github.com/dynamicdudes/speaking-apps/tree/master
|
10
|
+
|
11
|
+
Gem:
|
12
|
+
gem install dynamicdudes-speaking-apps --source http://gems.github.com
|
13
|
+
$ irb(main):001:0> require 'speaking_apps'
|
14
|
+
|
15
|
+
or with Rails >= 2.1:
|
16
|
+
config.gem "dynamicdudes-speaking-apps", :lib => "speaking_apps", :source => "http://gems.github.com"
|
17
|
+
|
18
|
+
== Configuration
|
19
|
+
|
20
|
+
Just before you start sending messages to the http://speakingapps.com API you should configure a few essential things:
|
21
|
+
SpeakingApps::Config.token = 'your_super_secret_token'
|
22
|
+
|
23
|
+
If you are on Rails you might want to define which environments should be used for remote logging:
|
24
|
+
SpeakingApps::Config.environments = [ 'staging', 'production' ]
|
25
|
+
|
26
|
+
== Usage
|
27
|
+
|
28
|
+
speaking-apps gives you two methods for sending messages. A one-liner that takes optional tags:
|
29
|
+
SpeakingApps.log('hello World')
|
30
|
+
SpeakingApps.log('hello World', 'tag1', 'tag2', 'tagx')
|
31
|
+
|
32
|
+
and a &block taking version for more readability if you have longer messages:
|
33
|
+
SpeakingApps.log_with_tags('tag1', 'tag2') do
|
34
|
+
msg = 'He'
|
35
|
+
msg << 'llo '
|
36
|
+
msg << 'World'
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
== More
|
41
|
+
|
42
|
+
* Written by rubyphunk (http://rubyphunk.com)
|
43
|
+
* For http://speakingapps.com
|
44
|
+
* Supported by http://dynamicdudes.com
|
45
|
+
|
46
|
+
|
47
|
+
Copyright (c) 2008 rubyphunk, speakingapps.com. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'rake'
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'jeweler'
|
5
|
+
Jeweler::Tasks.new do |s|
|
6
|
+
s.name = "speaking-apps"
|
7
|
+
s.summary = %Q{The official SpeakingApps Gem}
|
8
|
+
s.email = "treas@dynamicdudes.com"
|
9
|
+
s.homepage = "http://github.com/dynamicdudes/speaking-apps"
|
10
|
+
s.description = "The official SpeakingApps Gem. Allows your Rails app (or every other Ruby project) to chat with the http://speakingapps.com logging service."
|
11
|
+
s.authors = ["rubyphunk", "speakingapps.com"]
|
12
|
+
s.add_dependency 'daemons', '>= 1.0.10'
|
13
|
+
s.add_dependency 'json', '>= 1.1.3'
|
14
|
+
s.add_dependency 'sinatra', '>= 0.9.0.4'
|
15
|
+
s.files = FileList['lib/**/*.rb', 'bin/*', '[A-Z]*', 'spec/**/*', 'rails/*', 'init.rb'].to_a
|
16
|
+
end
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'rake/rdoctask'
|
22
|
+
Rake::RDocTask.new do |rdoc|
|
23
|
+
rdoc.rdoc_dir = 'rdoc'
|
24
|
+
rdoc.title = 'speaking-apps'
|
25
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
26
|
+
rdoc.rdoc_files.include('README.rdoc*')
|
27
|
+
rdoc.rdoc_files.include('LICENSE*')
|
28
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
29
|
+
rdoc.rdoc_files.exclude('spec')
|
30
|
+
end
|
31
|
+
|
32
|
+
require 'spec/rake/spectask'
|
33
|
+
Spec::Rake::SpecTask.new(:spec) do |t|
|
34
|
+
t.libs << 'lib' << 'spec'
|
35
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
36
|
+
end
|
37
|
+
|
38
|
+
Spec::Rake::SpecTask.new(:rcov) do |t|
|
39
|
+
t.libs << 'lib' << 'spec'
|
40
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
41
|
+
t.rcov = true
|
42
|
+
end
|
43
|
+
|
44
|
+
begin
|
45
|
+
require 'cucumber/rake/task'
|
46
|
+
Cucumber::Rake::Task.new(:features)
|
47
|
+
rescue LoadError
|
48
|
+
puts "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
|
49
|
+
end
|
50
|
+
|
51
|
+
task :default => :spec
|
data/VERSION.yml
ADDED
data/bin/speaking-apps
ADDED
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/rails/init'
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
require File.dirname(__FILE__) + '/speaking_apps/config'
|
3
|
+
require File.dirname(__FILE__) + '/speaking_apps/message_queue'
|
4
|
+
|
5
|
+
# This is the place to read about the methods that
|
6
|
+
# will help you sending Messages/Logs to the SpeakingApps API Service.
|
7
|
+
#
|
8
|
+
# Please make sure you set the required SpeakingApps::Config values.
|
9
|
+
|
10
|
+
module SpeakingApps
|
11
|
+
class << self
|
12
|
+
|
13
|
+
def init(environment = nil) #:nodoc:
|
14
|
+
unless class_variable_defined?(:@@_message_queue)
|
15
|
+
@@_message_queue = SpeakingApps::MessageQueue.new(environment)
|
16
|
+
ensure_existence_of_service_daemon# if @@_message_queue.environment_valid?
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Send a Messages. You can optionally assign Tags.
|
21
|
+
#
|
22
|
+
# * <tt>SpeakingApps.log('hello World')</tt>
|
23
|
+
# * <tt>SpeakingApps.log('hello World', 'tag1', 'tag2', 'tagx')</tt>
|
24
|
+
def log(message, *tags)
|
25
|
+
begin
|
26
|
+
message_queue.add(message, tags)
|
27
|
+
true
|
28
|
+
rescue
|
29
|
+
false
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Send a Messages with tags.
|
34
|
+
#
|
35
|
+
# * <tt>SpeakingApps.log_with_tags('tag1', 'tag2') { 'Hello World' }</tt>
|
36
|
+
def log_with_tags(*tags, &block)
|
37
|
+
begin
|
38
|
+
message = yield
|
39
|
+
message_queue.add(message, tags)
|
40
|
+
true
|
41
|
+
rescue
|
42
|
+
false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def message_queue #:nodoc:
|
47
|
+
@@_message_queue
|
48
|
+
end
|
49
|
+
|
50
|
+
def ensure_existence_of_service_daemon #:nodoc:
|
51
|
+
begin
|
52
|
+
Timeout::timeout(10) do
|
53
|
+
unless message_queue.ping
|
54
|
+
bin_path = File.expand_path(File.join(File.dirname(__FILE__), '/../bin/speaking-apps'))
|
55
|
+
Kernel.system("#{bin_path} start")
|
56
|
+
end
|
57
|
+
sleep 1
|
58
|
+
end
|
59
|
+
send_to_app "=> SpeakingApps: API service ready."
|
60
|
+
rescue
|
61
|
+
send_to_app "=> SpeakingApps: API service is not available!"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def send_to_app(message)
|
66
|
+
$stdout.puts message
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module SpeakingApps
|
2
|
+
|
3
|
+
# Use <b>SpeakingApps::Config</b> to setup your http://SpeakingApps.com API access.
|
4
|
+
#
|
5
|
+
# Please note: You must set the token in order to use the API.
|
6
|
+
# Don't know your token? Login to your account on http://youraccount.speakingapps.com (or get a new one),
|
7
|
+
# select your project and open 'Settings'.
|
8
|
+
#
|
9
|
+
# Place the configuration wherever you want. In a Rails app you would typically add these lines
|
10
|
+
# under <tt>config/environment</tt> or <tt>config/initializers/</tt>.
|
11
|
+
|
12
|
+
class Config
|
13
|
+
|
14
|
+
# Configure which Project-Token to use.
|
15
|
+
#
|
16
|
+
# <tt>SpeakingApps::Config.token = 'your-api-token'</tt>
|
17
|
+
def self.token=(new_token)
|
18
|
+
@@_token = new_token
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.token #:nodoc:
|
22
|
+
class_variable_defined?(:@@_token) ? @@_token : nil
|
23
|
+
end
|
24
|
+
|
25
|
+
# Set the environment(s) in which SpeakingApps#log should be active. Defaults to: ['production']
|
26
|
+
#
|
27
|
+
# <tt>SpeakingApps::Config.environments = ['staging', 'production']</tt>
|
28
|
+
def self.environments=(new_environments)
|
29
|
+
@@_environments = new_environments
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.environments #:nodoc:
|
33
|
+
class_variable_defined?(:@@_environments) ? @@_environments : ['production']
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.host=(new_host) #:nodoc:
|
37
|
+
@@_host = new_host
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.host #:nodoc:
|
41
|
+
class_variable_defined?(:@@_host) ? @@_host : 'speakingapps.com'
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.port=(new_port) #:nodoc:
|
45
|
+
@@_port = new_port
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.port #:nodoc:
|
49
|
+
class_variable_defined?(:@@_host) ? @@_port : '80'
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.clear! #:nodoc:
|
53
|
+
class_variables.each do |v|
|
54
|
+
remove_class_variable v.intern rescue true
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'sinatra'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module SpeakingApps
|
6
|
+
module Daemon
|
7
|
+
class QueueService
|
8
|
+
attr_accessor :queue
|
9
|
+
attr_accessor :worker
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
$DEBUG_SPEAKING_APPS = ARGV.delete('--debug')
|
13
|
+
self.queue = []
|
14
|
+
init_worker
|
15
|
+
@mutex = Mutex.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_outgoing_message(message_with_options)
|
19
|
+
debug "Scheduling outgoing message.. #{message_with_options['message']} (#{message_with_options['token']})"
|
20
|
+
self.queue << message_with_options
|
21
|
+
self.worker.wakeup
|
22
|
+
true
|
23
|
+
end
|
24
|
+
|
25
|
+
def ping
|
26
|
+
'pong'
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
|
31
|
+
def init_worker
|
32
|
+
self.worker = Thread.new do
|
33
|
+
loop do
|
34
|
+
if @queue.empty?
|
35
|
+
debug "Putting Thread #{Thread.current} to sleep. No waiting items"
|
36
|
+
Thread.stop
|
37
|
+
else
|
38
|
+
debug "Putting Thread #{Thread.current} to sleep for 5 seconds. Waiting messages: #{@queue.size}"
|
39
|
+
sleep 5
|
40
|
+
end
|
41
|
+
|
42
|
+
execute_queue
|
43
|
+
end
|
44
|
+
end
|
45
|
+
debug "Worker initialized.. #{self.worker} #{self.worker.status}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def execute_queue
|
49
|
+
@mutex.synchronize do
|
50
|
+
retry_list = []
|
51
|
+
until @queue.empty?
|
52
|
+
item = @queue.shift
|
53
|
+
api_response = SpeakingApps::Daemon::Remote.upload_message_with_tags(item)
|
54
|
+
if api_response == SpeakingApps::Daemon::Remote::API_RESPONSE_NETWORK_FAILURE
|
55
|
+
retry_list << item
|
56
|
+
end
|
57
|
+
end
|
58
|
+
@queue += retry_list
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
def log(message, mode = :info)
|
68
|
+
return if mode == :debug && !$DEBUG_SPEAKING_APPS
|
69
|
+
puts "[#{Time.now}] #{message}"
|
70
|
+
end
|
71
|
+
|
72
|
+
def debug(message)
|
73
|
+
log(message, :debug)
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
# Init Queue Service
|
78
|
+
configure do
|
79
|
+
require File.join(File.dirname(__FILE__), 'remote')
|
80
|
+
@@queue_service = SpeakingApps::Daemon::QueueService.new
|
81
|
+
debug "SpeakingApps: Activated Debugging Mode"
|
82
|
+
log "SpeakingApps: Ready."
|
83
|
+
end
|
84
|
+
|
85
|
+
# Sinatra Resources
|
86
|
+
get '/ping' do
|
87
|
+
'pong'
|
88
|
+
end
|
89
|
+
|
90
|
+
post '/messages' do
|
91
|
+
begin
|
92
|
+
json_request = JSON.parse(request.env["rack.input"].read)
|
93
|
+
@@queue_service.add_outgoing_message(json_request)
|
94
|
+
'201 Created'
|
95
|
+
rescue => error
|
96
|
+
"500 Error: #{error}"
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'net/https'
|
3
|
+
require 'erb'
|
4
|
+
|
5
|
+
module SpeakingApps
|
6
|
+
module Daemon
|
7
|
+
class Remote
|
8
|
+
|
9
|
+
API_RESPONSE_SUCCESS = 0
|
10
|
+
API_RESPONSE_ERROR = 1
|
11
|
+
API_RESPONSE_NETWORK_FAILURE = 2
|
12
|
+
|
13
|
+
def self.upload_message_with_tags(message_hash)
|
14
|
+
begin
|
15
|
+
encoded_data = encode_message_hash(message_hash)
|
16
|
+
uri = generate_uri(message_hash)
|
17
|
+
return post_to_remote(uri, encoded_data)
|
18
|
+
rescue => e
|
19
|
+
log "SpeakingApps Error: #{e}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.encode_message_hash(hash)
|
24
|
+
post_data = []
|
25
|
+
post_data << [ "message=#{ ERB::Util.url_encode(hash['message']) }" ]
|
26
|
+
post_data << [ "tags=#{ ERB::Util.url_encode(hash['tags'].join(', ')) }"] if hash['tags']
|
27
|
+
post_data << [ "environment=#{ ERB::Util.url_encode(hash['environment']) }"] if hash['environment']
|
28
|
+
post_data.join('&')
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.generate_uri(message_hash)
|
32
|
+
token, host, port = message_hash['token'], message_hash['host'], message_hash['port']
|
33
|
+
"http://#{host}:#{port}/api/v1/#{token}/messages"
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.post_to_remote(uri, encoded_post_data)
|
37
|
+
uri = URI.parse(uri)
|
38
|
+
|
39
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
40
|
+
http.use_ssl = false
|
41
|
+
|
42
|
+
api_response = begin
|
43
|
+
http.post(uri.path, encoded_post_data, { 'Content-type' => 'application/x-www-form-urlencoded' })
|
44
|
+
rescue => error
|
45
|
+
log "Error while contacting the SpeakingApps API HQ: #{error}"
|
46
|
+
return API_RESPONSE_NETWORK_FAILURE
|
47
|
+
end
|
48
|
+
|
49
|
+
case api_response
|
50
|
+
when Net::HTTPCreated
|
51
|
+
debug "Send message: '#{encoded_post_data}' to #{uri.host}"
|
52
|
+
return API_RESPONSE_SUCCESS
|
53
|
+
else
|
54
|
+
log "SpeakingApps Error: #{ api_response.body if api_response.respond_to?(:body) }"
|
55
|
+
return API_RESPONSE_ERROR
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
require 'timeout'
|
4
|
+
|
5
|
+
module SpeakingApps
|
6
|
+
class MessageQueue
|
7
|
+
attr_accessor :remote_queue
|
8
|
+
attr_accessor :environment
|
9
|
+
|
10
|
+
def initialize(environment = nil)
|
11
|
+
@environment = environment
|
12
|
+
end
|
13
|
+
|
14
|
+
def add(message, *attr)
|
15
|
+
if environment_valid?
|
16
|
+
store_in_remote_service_queue({
|
17
|
+
:message => message,
|
18
|
+
:tags => attr,
|
19
|
+
:environment => @environment,
|
20
|
+
:token => SpeakingApps::Config.token,
|
21
|
+
:host => SpeakingApps::Config.host,
|
22
|
+
:port => SpeakingApps::Config.port
|
23
|
+
})
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def ping
|
28
|
+
begin
|
29
|
+
Timeout::timeout(2) do
|
30
|
+
hub_url = URI.parse('http://127.0.0.1:28128/ping')
|
31
|
+
response = Net::HTTP.start(hub_url.host, hub_url.port) { |http| http.get(hub_url.path) }
|
32
|
+
return response.body == 'pong'
|
33
|
+
end
|
34
|
+
rescue => error
|
35
|
+
return false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def store_in_remote_service_queue(message_with_options = {})
|
40
|
+
# begin
|
41
|
+
Timeout::timeout(2) do
|
42
|
+
hub_url = URI.parse('http://127.0.0.1:28128/messages')
|
43
|
+
response = Net::HTTP.start(hub_url.host, hub_url.port) do |http|
|
44
|
+
http.post(hub_url.path, message_with_options.to_json)
|
45
|
+
end
|
46
|
+
return response == Net::HTTPCreated
|
47
|
+
end
|
48
|
+
# rescue => error
|
49
|
+
# return false
|
50
|
+
# end
|
51
|
+
end
|
52
|
+
|
53
|
+
def environment_valid? #:nodoc#
|
54
|
+
@environment.nil? || ::SpeakingApps::Config.environments.include?(@environment)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
SpeakingApps.init(RAILS_ENV)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
require 'lib/speaking_apps/config'
|
3
|
+
|
4
|
+
describe SpeakingApps::Config do
|
5
|
+
before(:each) do
|
6
|
+
SpeakingApps::Config.clear!
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should allow setting the token' do
|
10
|
+
SpeakingApps::Config.token = 'test'
|
11
|
+
SpeakingApps::Config.token.should eql('test')
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should allow defining environments' do
|
15
|
+
SpeakingApps::Config.environments = ['development', 'production']
|
16
|
+
SpeakingApps::Config.environments.should eql(['development', 'production'])
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should use the default environment "production" if nothing was set' do
|
20
|
+
SpeakingApps::Config.environments.should eql(['production'])
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../spec_helper'
|
2
|
+
require File.dirname(__FILE__) + '/../../../../lib/speaking_apps/daemon/queue_service'
|
3
|
+
|
4
|
+
describe SpeakingApps::Daemon::QueueService do
|
5
|
+
before(:each) do
|
6
|
+
@queue = SpeakingApps::Daemon::QueueService.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should have a ping-back method' do
|
10
|
+
@queue.ping.should eql('pong')
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../spec_helper'
|
2
|
+
require File.dirname(__FILE__) + '/../../../../lib/speaking_apps/daemon/remote'
|
3
|
+
|
4
|
+
describe SpeakingApps::Daemon::Remote do
|
5
|
+
|
6
|
+
context '#self.upload_message_with_tags' do
|
7
|
+
before(:each) do
|
8
|
+
SpeakingApps::Daemon::Remote.stub!(:post_to_remote)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should encode the message_hash' do
|
12
|
+
SpeakingApps::Daemon::Remote.should_receive(:encode_message_hash)
|
13
|
+
SpeakingApps::Daemon::Remote.upload_message_with_tags({ 'message' => 'Test', 'tags' => ['peter', 'Hallo welt'] })
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should generate the uri to post to' do
|
17
|
+
SpeakingApps::Daemon::Remote.should_receive(:generate_uri)
|
18
|
+
SpeakingApps::Daemon::Remote.upload_message_with_tags({ 'message' => 'Test' })
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should upload a message' do
|
22
|
+
SpeakingApps::Daemon::Remote.should_receive(:post_to_remote)
|
23
|
+
SpeakingApps::Daemon::Remote.upload_message_with_tags({ 'message' => 'Test' })
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context '#self.encode_message_hash' do
|
28
|
+
it 'should encode the hash into a postable string object' do
|
29
|
+
result = SpeakingApps::Daemon::Remote.encode_message_hash( {'message' => 'test', 'tags' => ['hallo welt', 'peter']} )
|
30
|
+
result.should eql('message=test&tags=hallo%20welt%2C%20peter')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context '#self.generate_uri' do
|
35
|
+
it 'should construct the uri including the project token' do
|
36
|
+
uri = SpeakingApps::Daemon::Remote.generate_uri({ 'token' => '_token_', 'host' => 'localhost', 'port' => '3000'})
|
37
|
+
uri.should eql('http://localhost:3000/api/v1/_token_/messages')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
require 'lib/speaking_apps/config'
|
3
|
+
require 'lib/speaking_apps/message_queue'
|
4
|
+
|
5
|
+
describe 'SpeakingApps::MessageQueue' do
|
6
|
+
before(:each) do
|
7
|
+
SpeakingApps::Config.stub!(:token).and_return(nil)
|
8
|
+
|
9
|
+
@message_queue = SpeakingApps::MessageQueue.new
|
10
|
+
@message_queue.environment = 'test'
|
11
|
+
@message_queue.stub!(:environment_valid?).and_return(true)
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'adding items' do
|
15
|
+
before(:each) do
|
16
|
+
@mock_http = mock('HTTP')
|
17
|
+
Net::HTTP.stub!(:start).and_yield(@mock_http)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should store items in the remote queue' do
|
21
|
+
@mock_http.should_receive(:post).with("/messages", message_hash(:message => 'test').to_json)
|
22
|
+
@message_queue.add('test')
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should accept optional tags' do
|
26
|
+
@mock_http.should_receive(:post).with("/messages", message_hash(:message => 'test', :tags => ['Ruby Cool', 'Defected']).to_json)
|
27
|
+
@message_queue.add('test', 'Ruby Cool', 'Defected')
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should not store items if the current environment is not in the list of allowed environments' do
|
31
|
+
@message_queue.stub!(:environment_valid?).and_return(false)
|
32
|
+
@message_queue.should_not_receive(:store_in_remote_service_queue)
|
33
|
+
@message_queue.add('test')
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'pinging the service' do
|
38
|
+
it 'should return true if the service is available' do
|
39
|
+
Net::HTTP.stub!(:start).and_return(mock('Request', :body => 'pong'))
|
40
|
+
@message_queue.ping.should be_true
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should return false if the service is not available' do
|
44
|
+
Net::HTTP.stub!(:start).and_return(mock('Request', :body => ''))
|
45
|
+
@message_queue.ping.should be_false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def message_hash(opts = {})
|
50
|
+
{ :environment=>"test", :host=>"speakingapps.com", :port=>"80", :tags=>[], :message=>"", :token=>nil }.merge(opts)
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
require 'lib/speaking_apps'
|
3
|
+
|
4
|
+
describe SpeakingApps do
|
5
|
+
before(:each) do
|
6
|
+
@mock_message_queue = mock('MessageQueue')
|
7
|
+
@mock_message_queue.stub!(:add)
|
8
|
+
SpeakingApps.stub!(:message_queue).and_return(@mock_message_queue)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '#init' do
|
12
|
+
it 'should try to load the service daemon' do
|
13
|
+
SpeakingApps.stub!(:class_variable_defined?).and_return(false)
|
14
|
+
@mock_message_queue.stub!(:environment_valid?).and_return(true)
|
15
|
+
SpeakingApps.should_receive(:ensure_existence_of_service_daemon)
|
16
|
+
SpeakingApps.init
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#log' do
|
21
|
+
it 'should have a log method' do
|
22
|
+
SpeakingApps.should respond_to(:log)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should accept a message for loggin' do
|
26
|
+
SpeakingApps.log('hello world').should be_true
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should add a message to the MessageQueue' do
|
30
|
+
@mock_message_queue.should_receive(:add).with('Hello World', [])
|
31
|
+
SpeakingApps.log('Hello World')
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should add optional tags to the MessageQueue' do
|
35
|
+
@mock_message_queue.should_receive(:add).with('test', ['tag', 'tag2'])
|
36
|
+
SpeakingApps.log('test', 'tag', 'tag2')
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should allow adding tags and provide the message as block' do
|
40
|
+
@mock_message_queue.should_receive(:add).with('Hello World', ['tag1', 'tag2'])
|
41
|
+
SpeakingApps.log_with_tags('tag1', 'tag2') do
|
42
|
+
'Hello World'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#ensure_existence_of_service_daemon' do
|
48
|
+
it 'should load the daemon' do
|
49
|
+
@mock_message_queue.stub!(:ping).and_return(false)
|
50
|
+
Kernel.should_receive(:system).with(File.expand_path(File.join(File.dirname(__FILE__), '/../../bin/speaking-apps start')))
|
51
|
+
SpeakingApps.ensure_existence_of_service_daemon
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dynamicdudes-speaking-apps
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- rubyphunk
|
8
|
+
- speakingapps.com
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2009-02-25 00:00:00 -08:00
|
14
|
+
default_executable: speaking-apps
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: daemons
|
18
|
+
type: :runtime
|
19
|
+
version_requirement:
|
20
|
+
version_requirements: !ruby/object:Gem::Requirement
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 1.0.10
|
25
|
+
version:
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: json
|
28
|
+
type: :runtime
|
29
|
+
version_requirement:
|
30
|
+
version_requirements: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 1.1.3
|
35
|
+
version:
|
36
|
+
description: The official SpeakingApps Gem. Allows your Rails app (or every other Ruby project) to chat with the http://speakingapps.com logging service.
|
37
|
+
email: treas@dynamicdudes.com
|
38
|
+
executables:
|
39
|
+
- speaking-apps
|
40
|
+
extensions: []
|
41
|
+
|
42
|
+
extra_rdoc_files: []
|
43
|
+
|
44
|
+
files:
|
45
|
+
- lib/speaking_apps/config.rb
|
46
|
+
- lib/speaking_apps/daemon/control.rb
|
47
|
+
- lib/speaking_apps/daemon/queue_service.rb
|
48
|
+
- lib/speaking_apps/daemon/remote.rb
|
49
|
+
- lib/speaking_apps/message_queue.rb
|
50
|
+
- lib/speaking_apps.rb
|
51
|
+
- bin/speaking-apps
|
52
|
+
- LICENSE
|
53
|
+
- Rakefile
|
54
|
+
- README.rdoc
|
55
|
+
- VERSION.yml
|
56
|
+
- spec/lib
|
57
|
+
- spec/lib/speaking_apps
|
58
|
+
- spec/lib/speaking_apps/config_spec.rb
|
59
|
+
- spec/lib/speaking_apps/daemon
|
60
|
+
- spec/lib/speaking_apps/daemon/queue_service_spec.rb
|
61
|
+
- spec/lib/speaking_apps/daemon/remote_spec.rb
|
62
|
+
- spec/lib/speaking_apps/message_queue_spec.rb
|
63
|
+
- spec/lib/speaking_apps_spec.rb
|
64
|
+
- spec/spec.opts
|
65
|
+
- spec/spec_helper.rb
|
66
|
+
- rails/init.rb
|
67
|
+
- init.rb
|
68
|
+
has_rdoc: true
|
69
|
+
homepage: http://github.com/dynamicdudes/speaking-apps
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options:
|
72
|
+
- --inline-source
|
73
|
+
- --charset=UTF-8
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: "0"
|
81
|
+
version:
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: "0"
|
87
|
+
version:
|
88
|
+
requirements: []
|
89
|
+
|
90
|
+
rubyforge_project:
|
91
|
+
rubygems_version: 1.2.0
|
92
|
+
signing_key:
|
93
|
+
specification_version: 2
|
94
|
+
summary: The official SpeakingApps Gem
|
95
|
+
test_files: []
|
96
|
+
|