dynamicdudes-speaking-apps 1.1.3
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.
- 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
|
+
|