Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
rafmagana committed Feb 15, 2010
1 parent dbeb787 commit d8f1cc1
Show file tree
Hide file tree
Showing 6 changed files with 278 additions and 3 deletions.
43 changes: 42 additions & 1 deletion README.rdoc
@@ -1,6 +1,47 @@
= prowly

Description goes here.
Yet another Ruby interface to Prowl

== Usage

Prowly.notify do |n| # :notify is an alias of :add
n.apikey = "apikey" or n.apikeys = ["apikey_1", "apikey_2", "apikey_n"]
n.priority = Prowly::Notification::Priority::MODERATE
n.application = "Prowly"
n.event = "Notification"
n.description = "Your server is under attack!!!"
end

notification = Prowly::Notification.new(:apikey => "apikey", :application => "Prowly", :description => "Testing...")
notification = Prowly::Notification.new(:apikeys => ["apikey_1", "apikey_2", "apikey_n"], :application => "Prowly", :description => "Testing...")

result = Prowly.notify(notification)

== Handling the Prowl API response

ON SUCCESS
result.status # => "success"
result.code # => "200"

if result.succeeded?
result.remaining # => "977"
resetdate.resetdate # => "1266272588"
else
resetdate.message # =>
end

ON ERROR
result.status # => "error"
result.code # => "401" <= This depends on the error code sent by the prowl API

if result.succeeded?
result.remaining # =>
resetdate.resetdate # =>
else
resetdate.message # => "Invalid API Key(s)" <= This depends on the message sent by the prowl API
end



== Note on Patches/Pull Requests

Expand Down
4 changes: 2 additions & 2 deletions Rakefile
Expand Up @@ -7,7 +7,7 @@ begin
gem.name = "prowly"
gem.summary = %Q{TODO: one-line summary of your gem}
gem.description = %Q{TODO: longer description of your gem}
gem.email = "rafael.magana@crowdint.com"
gem.email = "raf.magana@gmail.com"
gem.homepage = "http://github.com/rafmagana/prowly"
gem.authors = ["Rafael Magaña"]
gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
Expand Down Expand Up @@ -50,4 +50,4 @@ Rake::RDocTask.new do |rdoc|
rdoc.title = "prowly #{version}"
rdoc.rdoc_files.include('README*')
rdoc.rdoc_files.include('lib/**/*.rb')
end
end
36 changes: 36 additions & 0 deletions lib/prowly.rb
@@ -0,0 +1,36 @@
require 'prowly/interface'
require 'prowly/notification'

module Prowly

extend self

def add(notification = Notification.new)
yield notification if block_given?
api.call Interface::Command::ADD, notification.to_params
end

def verify(apikey)
api.call Interface::Command::VERIFY, "apikey=#{apikey}"
end

def valid_key?(key)
result = verify(key)
result.succeeded?
end

def remaining_calls(key)
result = verify(key)
return result.remaining if result.succeeded?
result.message
end

private
def api
Interface.instance
end

#aliases
alias :notify :add

end
47 changes: 47 additions & 0 deletions lib/prowly/interface.rb
@@ -0,0 +1,47 @@
require 'net/https'
require 'prowly/response'
require 'prowly/notification'
require 'singleton'

module Prowly

class Interface

include Singleton

def initialize
@url = "https://prowl.weks.net/publicapi"
end

## Make the actual call to the prowl api
def call(command, params)
@command = command
request = Net::HTTP::Get.new(uri.request_uri + "?" + params)
response = http.request(request)
Response.new(response.body, response)
end

private
def http
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
http
end

def uri
URI.parse("#{@url}/#{@command}")
end

## Available commands are documented in http://prowl.weks.net/api.php
module Command
ADD = "add"
VERIFY = "verify"
end

## EXCEPTIONS
class NoAPIKeyGiven < RuntimeError; end

end

end
88 changes: 88 additions & 0 deletions lib/prowly/notification.rb
@@ -0,0 +1,88 @@
require 'cgi'

module Prowly

class BasicNotification

## EXCEPTIONS
class NoAPIKeyGiven < RuntimeError; end
class NoDescriptionGiven < RuntimeError; end
class NoApplicationNameGiven < RuntimeError; end
class DuplicatedAssignmentOfApiKey < RuntimeError; end

attr_accessor :application, :description
attr_writer :apikey

alias :apikeys= :apikey=

def apikey
if @apikey.is_a? Array
@apikey.join(',')
else
@apikey
end
end
alias :apikeys :apikey

def initialize(params = {})
if params[:apikeys] and params[:apikey]
raise DuplicatedAssignmentOfApiKey, "Use apikey or apikeys, not both"
else
@apikey = params[:apikeys] unless params[:apikeys].nil?
@apikey = params[:apikey] unless params[:apikey].nil?
end
end

def to_params
raise NoAPIKeyGiven if apikey.nil?
raise NoApplicationNameGiven if @application.nil?
raise NoDescriptionGiven if @description.nil?
params.join('&')
end

private
def params
attributes = []
instance_variables.each do |var|
raw_attr = "#{var.sub('@','')}"
value = send("#{raw_attr}")
next if value.nil?
attributes << "#{raw_attr}=" + CGI.escape(value.to_s)
end
attributes.sort
end

end

class Notification < BasicNotification

## EXCEPTIONS
class PriorityNotAvailable < RuntimeError; end

attr_accessor :providerkey, :priority, :event

def initialize(params = {})
@apikey = (params[:apikey] || params[:apikeys]) || "fffffffffffffffffffffffffffffffffffffffff"
@application = params[:application] || "Prowly"
@event = params[:event] || "Prowly is working!!"
@description = params[:description] || "This is the default description"
@priority = params[:priority] || Priority::NORMAL
super
end

public
## Priorities are documented in http://prowl.weks.net/api.php
module Priority
VERY_LOW = -2
MODERATE = -1
NORMAL = 0
HIGH = 1
EMERGENCY = 2

def self.const_missing(const)
raise PriorityNotAvailable, const
end
end
end

end
63 changes: 63 additions & 0 deletions lib/prowly/response.rb
@@ -0,0 +1,63 @@
require 'rexml/document'

module Prowly

class Response

attr_writer :response
attr_accessor :http_response

def initialize(xml_response, full_http_response)
@response = xml_response
@http_response = full_http_response
Response.map_xml @response
end

def self.map_xml(response)
#parse xml
data = REXML::Document.new response
response_info = data.root[1]

#define dynamic methods based on the prowl api response
#posible methods on success: code, remaining, resetdate
#posible methods on error: code
response_info.attributes.each do |key, value|
add_instance_method(key, value)
end

#define a method named status and it'll return "success" or "error"
Response.add_instance_method(:status, response_info.name)

if response_info.name == "success"
boolean_status = true
elsif response_info.name == "error"
boolean_status = false
end

add_instance_method(:message, response_info.text) unless boolean_status

add_instance_method(:succeeded?, boolean_status)
true
end

#define dynamic methods
def self.add_instance_method(name, content)
define_method(name) { content }
end

## ERRORCODES are documented in http://prowl.weks.net/api.php
module ErrorCode
BAD = 400 #Bad request, the parameters you provided did not validate, see ERRORMESSAGE.
NOT_AUTHORIZED = 401 #Not authorized, the API key given is not valid, and does not correspond to a user.
METHOD_NOT_ALLOWED = 405 #Method not allowed, you attempted to use a non-SSL connection to Prowl.
NOT_ACCEPTABLE = 406 #Not acceptable, your IP address has exceeded the API limit.
INTERNAL_SERVER_ERROR = 500 #Internal server error, something failed to execute properly on the Prowl side.
end

module SuccessCode
SUCCESS = 200 #Everything went fine
end

end

end

0 comments on commit d8f1cc1

Please sign in to comment.