sappy 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +38 -0
- data/Rakefile +22 -0
- data/VERSION +1 -0
- data/bin/shell +27 -0
- data/lib/core_ext.rb +1 -0
- data/lib/core_ext/module/boolean_accessor.rb +15 -0
- data/lib/sappy.rb +16 -0
- data/lib/sappy/account.rb +72 -0
- data/lib/sappy/monitor.rb +147 -0
- data/lib/sappy/request.rb +34 -0
- data/lib/sappy/response.rb +41 -0
- data/lib/sappy/responses.rb +29 -0
- data/lib/sappy/responses/account_info.rb +14 -0
- data/lib/sappy/responses/add_monitor.rb +17 -0
- data/lib/sappy/responses/auth.rb +19 -0
- data/lib/sappy/responses/disable_monitor.rb +15 -0
- data/lib/sappy/responses/edit_monitor.rb +15 -0
- data/lib/sappy/responses/enable_monitor.rb +15 -0
- data/lib/sappy/responses/error.rb +22 -0
- data/lib/sappy/responses/monitors.rb +11 -0
- data/lib/sappy/responses/remove_monitor.rb +15 -0
- data/lib/sappy/responses/summary_statistics.rb +13 -0
- data/spec/helper.rb +28 -0
- data/spec/sappy/account_bacon.rb +49 -0
- data/spec/sappy/monitor_bacon.rb +43 -0
- metadata +80 -0
data/README.markdown
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# sappy
|
2
|
+
|
3
|
+
## Description:
|
4
|
+
|
5
|
+
A ruby library providing a wrapper around the SiteUptime API.
|
6
|
+
|
7
|
+
## Usage:
|
8
|
+
|
9
|
+
require 'rubygems'
|
10
|
+
require 'sappy'
|
11
|
+
|
12
|
+
@account = Sappy::Account.login('email@email.com', 'password')
|
13
|
+
|
14
|
+
monitors = @account.monitors
|
15
|
+
monitor = monitors.first
|
16
|
+
monitor.disable
|
17
|
+
|
18
|
+
monitor = @account.add_monitor(...)
|
19
|
+
|
20
|
+
## License:
|
21
|
+
|
22
|
+
(The MIT License)
|
23
|
+
|
24
|
+
Copyright (c) 2008-2009 Dylan Egan, Tim Carey-Smith
|
25
|
+
|
26
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
27
|
+
this software and associated documentation files (the 'Software'), to deal in
|
28
|
+
the Software without restriction, including without limitation the rights to use,
|
29
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
30
|
+
Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
31
|
+
|
32
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
33
|
+
|
34
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
35
|
+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
36
|
+
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
37
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
38
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWAge, publish, distribute, sublicense, and/or sell
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
begin
|
2
|
+
require 'jeweler'
|
3
|
+
Jeweler::Tasks.new do |gemspec|
|
4
|
+
gemspec.name = "sappy"
|
5
|
+
gemspec.summary = "Wrapping that shit!"
|
6
|
+
gemspec.description = "A wrapper for the SiteUptime API"
|
7
|
+
gemspec.email = ["dylanegan@gmail.com", "tim@spork.in"]
|
8
|
+
gemspec.homepage = "http://github.com/abcde/sappy"
|
9
|
+
gemspec.authors = ["Dylan Egan", "Tim Carey-Smith"]
|
10
|
+
gemspec.files = %w(README.markdown Rakefile VERSION) + Dir.glob("{lib,bacon}/**/*")
|
11
|
+
gemspec.rubyforge_project = 'abcde'
|
12
|
+
end
|
13
|
+
|
14
|
+
Jeweler::RubyforgeTasks.new
|
15
|
+
rescue LoadError
|
16
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "Run bacon"
|
20
|
+
task :bacon do
|
21
|
+
puts `bacon #{Dir["spec/**/*_bacon.rb"].join(" ")}`
|
22
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.1
|
data/bin/shell
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "irb"
|
4
|
+
require "rubygems"
|
5
|
+
|
6
|
+
require File.dirname(__FILE__) + '/../lib/sappy'
|
7
|
+
|
8
|
+
if ARGV.size != 2
|
9
|
+
$stderr.puts "Credentials required."
|
10
|
+
exit 1
|
11
|
+
end
|
12
|
+
|
13
|
+
username = ARGV.shift
|
14
|
+
password = ARGV.shift
|
15
|
+
$stderr.puts "Starting up the Sappy with #{username}/#{password}"
|
16
|
+
@account = Sappy::Account.login(username, password)
|
17
|
+
|
18
|
+
if __FILE__ == $0
|
19
|
+
IRB.start(__FILE__)
|
20
|
+
else
|
21
|
+
# check -e option
|
22
|
+
if /^-e$/ =~ $0
|
23
|
+
IRB.start(__FILE__)
|
24
|
+
else
|
25
|
+
IRB.setup(__FILE__)
|
26
|
+
end
|
27
|
+
end
|
data/lib/core_ext.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/core_ext/module/boolean_accessor'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module CoreExt
|
2
|
+
module BooleanAccessor
|
3
|
+
def boolean_accessor(*syms)
|
4
|
+
syms.each do |sym|
|
5
|
+
class_eval(<<-EOS, __FILE__, __LINE__)
|
6
|
+
def #{sym}?; @#{sym} == 1; end
|
7
|
+
def #{sym}=(value); @#{sym} = value.to_s.match(/true|yes|on|1/i) ? 1 : 0; end
|
8
|
+
def #{sym}; @#{sym}; end
|
9
|
+
EOS
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
Module.send(:include, CoreExt::BooleanAccessor)
|
data/lib/sappy.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'xmlsimple'
|
3
|
+
|
4
|
+
require File.dirname(__FILE__) + '/core_ext'
|
5
|
+
|
6
|
+
$:.unshift File.dirname(__FILE__)
|
7
|
+
|
8
|
+
module Sappy
|
9
|
+
class Error < StandardError; end
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'sappy/account'
|
13
|
+
require 'sappy/monitor'
|
14
|
+
require 'sappy/request'
|
15
|
+
require 'sappy/response'
|
16
|
+
require 'sappy/responses'
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Sappy
|
2
|
+
class Account
|
3
|
+
attr_reader :authkey, :available_monitors, :down_monitors, :inactive_monitors,
|
4
|
+
:setup_monitors, :sms_alerts, :up_monitors
|
5
|
+
|
6
|
+
def self.login(username, password)
|
7
|
+
account = new(username, password)
|
8
|
+
account.login
|
9
|
+
account
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(username, password)
|
13
|
+
@username, @password = username, password
|
14
|
+
end
|
15
|
+
|
16
|
+
def login
|
17
|
+
connect
|
18
|
+
refresh!
|
19
|
+
end
|
20
|
+
|
21
|
+
def authenticated?
|
22
|
+
@authkey
|
23
|
+
end
|
24
|
+
|
25
|
+
def connect(forced = false)
|
26
|
+
if !authenticated? or forced
|
27
|
+
authenticate
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def refresh!
|
32
|
+
refresh_account_info
|
33
|
+
refresh_summary_statistics
|
34
|
+
end
|
35
|
+
|
36
|
+
def monitors(ids = [])
|
37
|
+
params = ids.any? ? { "MonitorId" => ids.join(',') } : {}
|
38
|
+
response = request('monitors', params)
|
39
|
+
response.monitors.map do |m|
|
40
|
+
Monitor.parse(self, m)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def add_monitor(attributes)
|
45
|
+
Monitor.create(self, attributes)
|
46
|
+
end
|
47
|
+
|
48
|
+
def request(action, parameters = {})
|
49
|
+
Request.perform(self, action, parameters)
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
def authenticate
|
54
|
+
response = request('auth', "Email" => @username, "Password" => @password)
|
55
|
+
@authkey = response.key
|
56
|
+
end
|
57
|
+
|
58
|
+
def refresh_account_info
|
59
|
+
response = request('accountinfo')
|
60
|
+
@available_monitors = response.available_monitors
|
61
|
+
@setup_monitors = response.setup_monitors
|
62
|
+
@sms_alerts = response.sms_alerts
|
63
|
+
end
|
64
|
+
|
65
|
+
def refresh_summary_statistics
|
66
|
+
response = request('summarystatistics')
|
67
|
+
@up_monitors = response.up
|
68
|
+
@down_monitors = response.down
|
69
|
+
@inactive_monitors = response.inactive
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
module Sappy
|
2
|
+
class Monitor
|
3
|
+
# Name (required)
|
4
|
+
# Service name.
|
5
|
+
# Service (required)
|
6
|
+
# Service type. Available values are: http, smtp, ftp, pop3, https, ping, dns
|
7
|
+
SERVICES = %w(http smtp ftp pop3 https ping dns)
|
8
|
+
# Location (required)
|
9
|
+
# Check location. Available values are: sf, ny, ch, ln (i.e. San Francisco, New York, Chicago, London).
|
10
|
+
LOCATIONS = {'sf' => 'San Francisco', 'ny' => 'New York', 'ch' => 'Chicago', 'ln' => 'London'}.sort
|
11
|
+
# HostName (required)
|
12
|
+
# Monitored Host name, IP or Page URL.
|
13
|
+
# CheckPeriod (required)
|
14
|
+
# Monitoring check period. Available values are: 2, 5, 15, 30, 60
|
15
|
+
CHECK_PERIODS = [2, 5, 15, 30, 60]
|
16
|
+
# PortNumber (optional)
|
17
|
+
# Custom port number. Default service port using by default.
|
18
|
+
# Login (optional)
|
19
|
+
# HTTP Authentication login. Used for 'http' and https services only.
|
20
|
+
# Password (optional)
|
21
|
+
# HTTP Authentication password. Used for 'http' and https services only.
|
22
|
+
# Content (optional)
|
23
|
+
# Monitored page content. Used for 'http' and 'https' services only.
|
24
|
+
# Domain (optional)
|
25
|
+
# Lookup domain. Used for 'dns' services only.
|
26
|
+
# IP (optional)
|
27
|
+
# Lookup domain. Used for 'dns' services only. Required if 'Domain' is not empty.
|
28
|
+
# SendSms (optional)
|
29
|
+
# 0 or 1. Send SMS alerts on failures. Default value is '0'.
|
30
|
+
# SendUrlAlert (optional)
|
31
|
+
# 0 or 1. Send Url (JSON) alerts on failures to Url specified on My Profile section. Default value is '0'.
|
32
|
+
# SendJabberAlert (optional)
|
33
|
+
# 0 or 1. Send XMPP/Jabber alerts on failures to Jabber ID specified on My Profile section. Default value is '0'.
|
34
|
+
# AltEmailAlerts (optional)
|
35
|
+
# Alternative Email alerts addresses separated with comma.
|
36
|
+
# DontSendUpAlert (optional)
|
37
|
+
# 0 or 1. Set to 1 if you do not what to receive Up alerts for a monitor. Default value is '0'.
|
38
|
+
# SendAllDownAlerts (optional)
|
39
|
+
# 0 or 1. Set to 1 if you what to receive Down alert on each failure check. Default value is '0'.
|
40
|
+
# Enabled (optional)
|
41
|
+
# 0 or 1. Monitor is enabled on not. Default value is '1'.
|
42
|
+
# SendAlertAfter (optional)
|
43
|
+
# Send alerts after specified number of failures. Available values are: 1, 2, 3, 4, 5. Default value is 1.
|
44
|
+
SEND_ALERT_AFTER = [1, 2, 3, 4, 5]
|
45
|
+
# DownSubject (optional)
|
46
|
+
# Email subject value for Down alerts. Default subject will be used if empty.
|
47
|
+
# UpSubject (optional)
|
48
|
+
# Email subject value for Up alerts. Default subject will be used if empty.
|
49
|
+
# EnablePublicStatistics (optional)
|
50
|
+
# 0 or 1. Allow/Deny visitor to see public statistics report. Default value is '1' (allow).
|
51
|
+
# AddToStatusPage (optional)
|
52
|
+
# 0 or 1. Add/remove monitor to/from your public summary status report. Default value is '1' (add).
|
53
|
+
# Timeout (optional)
|
54
|
+
# Monitor socket connection timeout value in seconds. Available values are: 15, 20, 25, 30, 35. Default value is 25.
|
55
|
+
TIMEOUTS = [15, 20, 25, 30, 35]
|
56
|
+
|
57
|
+
attr_accessor :altemailalerts, :content, :current_status, :domain,
|
58
|
+
:downsubject, :host, :id, :ip, :location, :login,
|
59
|
+
:password, :period, :port, :name, :service, :timeout, :upsubject
|
60
|
+
boolean_accessor :active, :addtostatuspage, :dontsendupalert, :enablepublicstatistics,
|
61
|
+
:sendalertafter, :sendalldownalerts, :sendjabberalert, :sendsms, :sendurlalert
|
62
|
+
attr_reader :account
|
63
|
+
|
64
|
+
def initialize(account, attrs)
|
65
|
+
@account = account
|
66
|
+
self.attributes = attrs
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.parse(account, attrs)
|
70
|
+
a = new(account, attrs)
|
71
|
+
a.current_status = attrs["current_status"]
|
72
|
+
a
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.create(account, attrs)
|
76
|
+
monitor = new(account, attrs)
|
77
|
+
monitor.save
|
78
|
+
monitor
|
79
|
+
end
|
80
|
+
|
81
|
+
def attributes
|
82
|
+
{ "Name" => name, "Service" => service, "Location" => location, "HostName" => host,
|
83
|
+
"CheckPeriod" => period, "PortNumber" => port, "Login" => login, "Password" => password,
|
84
|
+
"Content" => content, "Domain" => domain, "IP" => ip, "SendSms" => sendsms, "SendUrlAlert" => sendurlalert,
|
85
|
+
"SendJabberAlert" => sendjabberalert, "AltEmailAlerts" => altemailalerts, "DontSendUpAlert" => dontsendupalert,
|
86
|
+
"SendAllDownAlerts" => sendalldownalerts, "Enabled" => active, "SendAlertAfter" => sendalertafter,
|
87
|
+
"DownSubject" => downsubject, "UpSubject" => upsubject, "EnablePublicStatistics" => enablepublicstatistics,
|
88
|
+
"AddToStatusPage" => addtostatuspage, "Timeout" => timeout }
|
89
|
+
end
|
90
|
+
|
91
|
+
def attributes=(attrs)
|
92
|
+
attrs.each do |attribute,value|
|
93
|
+
send("#{attribute.to_s}=", value) if respond_to? "#{attribute.to_s}="
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def id=(value)
|
98
|
+
@id = value.to_i
|
99
|
+
end
|
100
|
+
|
101
|
+
def url
|
102
|
+
"#{service}://#{host}"
|
103
|
+
end
|
104
|
+
|
105
|
+
def disable!
|
106
|
+
@account.request('disablemonitor', "MonitorId" => id)
|
107
|
+
@active = 0
|
108
|
+
end
|
109
|
+
|
110
|
+
def enable!
|
111
|
+
@account.request('enablemonitor', "MonitorId" => id)
|
112
|
+
@active = 1
|
113
|
+
end
|
114
|
+
|
115
|
+
def new_record?
|
116
|
+
id.nil?
|
117
|
+
end
|
118
|
+
|
119
|
+
def save
|
120
|
+
new_record? ? create : update
|
121
|
+
end
|
122
|
+
|
123
|
+
def create
|
124
|
+
@id = @account.request("addmonitor", attributes).id
|
125
|
+
end
|
126
|
+
|
127
|
+
def update
|
128
|
+
@account.request("editmonitor", attributes.merge({ "MonitorId" => id }))
|
129
|
+
end
|
130
|
+
|
131
|
+
def destroy
|
132
|
+
@account.request('removemonitor', "MonitorId" => id)
|
133
|
+
end
|
134
|
+
|
135
|
+
def daily_statistics
|
136
|
+
raise "Not yet implemented."
|
137
|
+
end
|
138
|
+
|
139
|
+
def monthly_statistics
|
140
|
+
raise "Not yet implemented."
|
141
|
+
end
|
142
|
+
|
143
|
+
def annual_statistics
|
144
|
+
raise "Not yet implemented."
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'rest_client'
|
2
|
+
require 'rack'
|
3
|
+
|
4
|
+
module Sappy
|
5
|
+
class Request
|
6
|
+
def self.perform(account, action, parameters)
|
7
|
+
new(account, action, parameters).perform
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(account, action, parameters)
|
11
|
+
@account, @action, @parameters = account, action, parameters
|
12
|
+
end
|
13
|
+
|
14
|
+
def perform
|
15
|
+
xml = RestClient.get(uri)
|
16
|
+
r = Responses.for(@action)
|
17
|
+
r.parse(xml)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def uri
|
22
|
+
@uri ||= "https://siteuptime.com/api/rest/?#{query_string}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def query_string
|
26
|
+
if @account.authenticated?
|
27
|
+
@parameters["AuthKey"] = @account.authkey
|
28
|
+
end
|
29
|
+
@parameters["method"] = "siteuptime.#{@action}"
|
30
|
+
|
31
|
+
Rack::Utils.build_query(@parameters)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Sappy
|
2
|
+
class Response
|
3
|
+
class SessionExpired < Error; end
|
4
|
+
class UnhandledError < Error; end
|
5
|
+
|
6
|
+
def self.parse(xml)
|
7
|
+
r = new(xml)
|
8
|
+
r.parse
|
9
|
+
r
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(xml)
|
13
|
+
@xml = xml
|
14
|
+
end
|
15
|
+
|
16
|
+
def parse
|
17
|
+
hash = XmlSimple.xml_in(@xml.to_s)
|
18
|
+
if hash["stat"] == "fail"
|
19
|
+
error = hash["err"]
|
20
|
+
message = error.first["msg"]
|
21
|
+
case code = error.first["code"]
|
22
|
+
when "AUTH_EXPIRED"
|
23
|
+
raise SessionExpired, "The auth session expired, reconnect to continue using the API"
|
24
|
+
else
|
25
|
+
failure(code, message)
|
26
|
+
raise UnhandledError, "Unhandled error: #{code}, #{message}"
|
27
|
+
end
|
28
|
+
else
|
29
|
+
success(hash)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def success(hash)
|
34
|
+
raise NotImplementedError, "Overwrite #success in a Response subclass"
|
35
|
+
end
|
36
|
+
|
37
|
+
def failure(code, message)
|
38
|
+
raise NotImplementedError, "Overwrite #failure in a Response subclass"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'sappy/responses/auth'
|
2
|
+
require 'sappy/responses/account_info'
|
3
|
+
require 'sappy/responses/summary_statistics'
|
4
|
+
require 'sappy/responses/monitors'
|
5
|
+
require 'sappy/responses/add_monitor'
|
6
|
+
require 'sappy/responses/edit_monitor'
|
7
|
+
require 'sappy/responses/remove_monitor'
|
8
|
+
require 'sappy/responses/enable_monitor'
|
9
|
+
require 'sappy/responses/disable_monitor'
|
10
|
+
|
11
|
+
module Sappy
|
12
|
+
module Responses
|
13
|
+
MAP = {
|
14
|
+
"auth" => Auth,
|
15
|
+
"accountinfo" => AccountInfo,
|
16
|
+
"summarystatistics" => SummaryStatistics,
|
17
|
+
"monitors" => Monitors,
|
18
|
+
"addmonitor" => AddMonitor,
|
19
|
+
"editmonitor" => EditMonitor,
|
20
|
+
"removemonitor" => RemoveMonitor,
|
21
|
+
"enablemonitor" => EnableMonitor,
|
22
|
+
"disablemonitor" => DisableMonitor
|
23
|
+
}
|
24
|
+
|
25
|
+
def self.for(action)
|
26
|
+
MAP[action] || raise(ArgumentError, "Couldn't find a Response class to parse a #{action.inspect} result")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Sappy
|
2
|
+
module Responses
|
3
|
+
class AccountInfo < Response
|
4
|
+
attr_reader :available_monitors, :setup_monitors, :sms_alerts
|
5
|
+
|
6
|
+
def success(hash)
|
7
|
+
accountinfo = hash["accountinfo"].first
|
8
|
+
@available_monitors = accountinfo["availablemonitors"].to_i
|
9
|
+
@setup_monitors = accountinfo["setupmonitors"].to_i
|
10
|
+
@sms_alerts = accountinfo["smsalerts"].to_i
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Sappy
|
2
|
+
module Responses
|
3
|
+
class AddMonitor < Response
|
4
|
+
attr_reader :id
|
5
|
+
def success(hash)
|
6
|
+
@id = hash["monitor"].first["id"]
|
7
|
+
end
|
8
|
+
|
9
|
+
def failure(code, message)
|
10
|
+
case code
|
11
|
+
when "WRONG_DATA"
|
12
|
+
raise ArgumentError, "You didn't provide the correct data: #{message}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Sappy
|
2
|
+
module Responses
|
3
|
+
class Auth < Response
|
4
|
+
class LoginFailed < Error; end
|
5
|
+
|
6
|
+
attr_reader :key
|
7
|
+
def success(hash)
|
8
|
+
@key = hash["session"].first["key"]
|
9
|
+
end
|
10
|
+
|
11
|
+
def failure(code, message)
|
12
|
+
case code
|
13
|
+
when "WRONG_DATA"
|
14
|
+
raise LoginFailed, message
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Sappy
|
2
|
+
module Responses
|
3
|
+
class DisableMonitor < Response
|
4
|
+
def success(hash)
|
5
|
+
end
|
6
|
+
|
7
|
+
def failure(code, message)
|
8
|
+
case code
|
9
|
+
when "WRONG_DATA"
|
10
|
+
raise ArgumentError, "You didn't provide a correct monitor id: #{message}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Sappy
|
2
|
+
module Responses
|
3
|
+
class EditMonitor < Response
|
4
|
+
def success(hash)
|
5
|
+
end
|
6
|
+
|
7
|
+
def failure(code, message)
|
8
|
+
case code
|
9
|
+
when "WRONG_DATA"
|
10
|
+
raise ArgumentError, "You didn't provide the correct data: #{message}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Sappy
|
2
|
+
module Responses
|
3
|
+
class EnableMonitor < Response
|
4
|
+
def success(hash)
|
5
|
+
end
|
6
|
+
|
7
|
+
def failure(code, message)
|
8
|
+
case code
|
9
|
+
when "WRONG_DATA"
|
10
|
+
raise ArgumentError, "You didn't provide a correct monitor id: #{message}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Sappy
|
2
|
+
module Responses
|
3
|
+
class ErrorResponse
|
4
|
+
class Error < StandardError; end
|
5
|
+
class AuthenticationError < Error; end
|
6
|
+
|
7
|
+
def initialize(xml)
|
8
|
+
err = xml["err"]
|
9
|
+
message = err.first["msg"]
|
10
|
+
|
11
|
+
case code = err.first["code"]
|
12
|
+
when "AUTH_EXPIRED"
|
13
|
+
raise AuthenticationExpired, message
|
14
|
+
when "AUTH_ERR"
|
15
|
+
raise AuthenticationError, message
|
16
|
+
else
|
17
|
+
raise Error, "Unknown error[#{code}]: #{message}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Sappy
|
2
|
+
module Responses
|
3
|
+
class RemoveMonitor < Response
|
4
|
+
def success(hash)
|
5
|
+
end
|
6
|
+
|
7
|
+
def failure(code, message)
|
8
|
+
case code
|
9
|
+
when "WRONG_DATA"
|
10
|
+
raise ArgumentError, "You didn't provide a correct monitor id: #{message}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Sappy
|
2
|
+
module Responses
|
3
|
+
class SummaryStatistics < Response
|
4
|
+
attr_reader :up, :down, :inactive
|
5
|
+
|
6
|
+
def success(hash)
|
7
|
+
hash["summarystatistics"].first.each do |stat,value|
|
8
|
+
instance_variable_set("@#{stat}", value.to_i)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/spec/helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bacon'
|
3
|
+
require 'fakeweb'
|
4
|
+
require 'pp'
|
5
|
+
|
6
|
+
require File.dirname(__FILE__) + '/../lib/sappy'
|
7
|
+
|
8
|
+
SPEC_DIR = File.dirname(__FILE__) unless defined? SPEC_DIR
|
9
|
+
$:<< SPEC_DIR
|
10
|
+
|
11
|
+
# Don't allow real web requests during specs!
|
12
|
+
FakeWeb.allow_net_connect = false
|
13
|
+
|
14
|
+
# Setup default URL calls
|
15
|
+
|
16
|
+
def cached_page(name)
|
17
|
+
SPEC_DIR + "/xml/#{name}.xml"
|
18
|
+
end
|
19
|
+
|
20
|
+
FakeWeb.register_uri(:get, "https://siteuptime.com/api/rest/?method=siteuptime.auth&Password=password&Email=valid%40email.com", :response => cached_page('valid_account'))
|
21
|
+
FakeWeb.register_uri(:get, "https://siteuptime.com/api/rest/?method=siteuptime.auth&Password=password&Email=invalid%40email.com", :response => cached_page('invalid_account'))
|
22
|
+
FakeWeb.register_uri(:get, "https://siteuptime.com/api/rest/?AuthKey=b7kks5mh1l300v5segaksm8gh3&method=siteuptime.accountinfo", :response => cached_page('accountinfo'))
|
23
|
+
FakeWeb.register_uri(:get, "https://siteuptime.com/api/rest/?AuthKey=b7kks5mh1l300v5segaksm8gh3&method=siteuptime.summarystatistics", :response => cached_page('summarystatistics'))
|
24
|
+
FakeWeb.register_uri(:get, "https://siteuptime.com/api/rest/?AuthKey=b7kks5mh1l300v5segaksm8gh3&method=siteuptime.monitors", :response => cached_page('monitors'))
|
25
|
+
FakeWeb.register_uri(:get, "https://siteuptime.com/api/rest/?Name=New+Monitor&AuthKey=b7kks5mh1l300v5segaksm8gh3&Enabled=&HostName=new-sf-monitor.com&Login=&AltEmailAlerts=&Content=&Location=sf&EnablePublicStatistics=&Domain=&method=siteuptime.addmonitor&Timeout=&Password=&UpSubject=&AddToStatusPage=&SendAllDownAlerts=&IP=&SendAlertAfter=&DontSendUpAlert=&SendJabberAlert=&CheckPeriod=60&DownSubject=&SendUrlAlert=&SendSms=&PortNumber=&Service=http", :response => cached_page('addmonitor'))
|
26
|
+
FakeWeb.register_uri(:get, "https://siteuptime.com/api/rest/?AuthKey=b7kks5mh1l300v5segaksm8gh3&method=siteuptime.enablemonitor&MonitorId=84043", :response => cached_page('enablemonitor'))
|
27
|
+
FakeWeb.register_uri(:get, "https://siteuptime.com/api/rest/?AuthKey=b7kks5mh1l300v5segaksm8gh3&method=siteuptime.disablemonitor&MonitorId=84043", :response => cached_page('disablemonitor'))
|
28
|
+
FakeWeb.register_uri(:get, "https://siteuptime.com/api/rest/?AuthKey=b7kks5mh1l300v5segaksm8gh3&method=siteuptime.removemonitor&MonitorId=84043", :response => cached_page('removemonitor'))
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../helper'
|
2
|
+
|
3
|
+
module Sappy
|
4
|
+
describe Account do
|
5
|
+
describe "with incorrect credentials" do
|
6
|
+
it "raises an error" do
|
7
|
+
lambda { Account.login("invalid@email.com", "password") }.
|
8
|
+
should.raise(Responses::Auth::LoginFailed).
|
9
|
+
message.should.match(/Wrong email or password/)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "with correct credentials" do
|
14
|
+
before do
|
15
|
+
@account = Account.login("valid@email.com", "password")
|
16
|
+
@account.monitors.each do |m|
|
17
|
+
m.destroy
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should obtain an auth key" do
|
22
|
+
@account.authkey.should == "b7kks5mh1l300v5segaksm8gh3"
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "with no monitors" do
|
26
|
+
it "has available monitors" do
|
27
|
+
@account.available_monitors.should > 0
|
28
|
+
end
|
29
|
+
|
30
|
+
it "has no monitors" do
|
31
|
+
@account.setup_monitors.should == 0
|
32
|
+
end
|
33
|
+
|
34
|
+
it "has no SMS alerts" do
|
35
|
+
@account.sms_alerts.should == 0
|
36
|
+
end
|
37
|
+
|
38
|
+
it "can create a new monitor" do
|
39
|
+
monitor = @account.add_monitor({:name => "New Monitor", :service => "http", :location => "sf", :host => "new-sf-monitor.com", :period => "60"})
|
40
|
+
monitor.id.should.not.be.nil
|
41
|
+
FakeWeb.register_uri(:get, "https://siteuptime.com/api/rest/?AuthKey=b7kks5mh1l300v5segaksm8gh3&method=siteuptime.monitors", :response => cached_page('monitors_1'))
|
42
|
+
monitors = @account.monitors
|
43
|
+
monitors.size.should == 1
|
44
|
+
monitors.first.name.should == "New Monitor"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../helper'
|
2
|
+
|
3
|
+
module Sappy
|
4
|
+
describe Monitor do
|
5
|
+
before do
|
6
|
+
@account = Account.login("valid@email.com", "password")
|
7
|
+
@account.monitors.each { |m| m.destroy }
|
8
|
+
@monitor = @account.add_monitor({:name => "New Monitor", :service => "http", :location => "sf", :host => "new-sf-monitor.com", :period => "60"})
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "an active monitor" do
|
12
|
+
before do
|
13
|
+
@monitor.enable!
|
14
|
+
end
|
15
|
+
|
16
|
+
it "can be disabled" do
|
17
|
+
@monitor.disable!
|
18
|
+
@monitor.should.not.be.active
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "an inactive monitor" do
|
23
|
+
before do
|
24
|
+
@monitor.disable!
|
25
|
+
end
|
26
|
+
|
27
|
+
it "can be enabled" do
|
28
|
+
@monitor.enable!
|
29
|
+
@monitor.should.be.active
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "a monitor" do
|
34
|
+
it "can be destroyed" do
|
35
|
+
FakeWeb.register_uri(:get, "https://siteuptime.com/api/rest/?AuthKey=b7kks5mh1l300v5segaksm8gh3&method=siteuptime.monitors", :response => cached_page('monitors_1'))
|
36
|
+
@account.monitors.size.should == 1
|
37
|
+
lambda { @monitor.destroy }.should.not.raise
|
38
|
+
FakeWeb.register_uri(:get, "https://siteuptime.com/api/rest/?AuthKey=b7kks5mh1l300v5segaksm8gh3&method=siteuptime.monitors", :response => cached_page('monitors'))
|
39
|
+
@account.monitors.size.should == 0
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sappy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dylan Egan
|
8
|
+
- Tim Carey-Smith
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2009-08-26 00:00:00 +10:00
|
14
|
+
default_executable: shell
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description: A wrapper for the SiteUptime API
|
18
|
+
email:
|
19
|
+
- dylanegan@gmail.com
|
20
|
+
- tim@spork.in
|
21
|
+
executables:
|
22
|
+
- shell
|
23
|
+
extensions: []
|
24
|
+
|
25
|
+
extra_rdoc_files:
|
26
|
+
- README.markdown
|
27
|
+
files:
|
28
|
+
- README.markdown
|
29
|
+
- Rakefile
|
30
|
+
- VERSION
|
31
|
+
- lib/core_ext.rb
|
32
|
+
- lib/core_ext/module/boolean_accessor.rb
|
33
|
+
- lib/sappy.rb
|
34
|
+
- lib/sappy/account.rb
|
35
|
+
- lib/sappy/monitor.rb
|
36
|
+
- lib/sappy/request.rb
|
37
|
+
- lib/sappy/response.rb
|
38
|
+
- lib/sappy/responses.rb
|
39
|
+
- lib/sappy/responses/account_info.rb
|
40
|
+
- lib/sappy/responses/add_monitor.rb
|
41
|
+
- lib/sappy/responses/auth.rb
|
42
|
+
- lib/sappy/responses/disable_monitor.rb
|
43
|
+
- lib/sappy/responses/edit_monitor.rb
|
44
|
+
- lib/sappy/responses/enable_monitor.rb
|
45
|
+
- lib/sappy/responses/error.rb
|
46
|
+
- lib/sappy/responses/monitors.rb
|
47
|
+
- lib/sappy/responses/remove_monitor.rb
|
48
|
+
- lib/sappy/responses/summary_statistics.rb
|
49
|
+
has_rdoc: true
|
50
|
+
homepage: http://github.com/abcde/sappy
|
51
|
+
licenses: []
|
52
|
+
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options:
|
55
|
+
- --charset=UTF-8
|
56
|
+
require_paths:
|
57
|
+
- lib
|
58
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "0"
|
63
|
+
version:
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
version:
|
70
|
+
requirements: []
|
71
|
+
|
72
|
+
rubyforge_project: abcde
|
73
|
+
rubygems_version: 1.3.4
|
74
|
+
signing_key:
|
75
|
+
specification_version: 3
|
76
|
+
summary: Wrapping that shit!
|
77
|
+
test_files:
|
78
|
+
- spec/helper.rb
|
79
|
+
- spec/sappy/account_bacon.rb
|
80
|
+
- spec/sappy/monitor_bacon.rb
|