prowly 0.1.0

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/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Rafael Magaña
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,62 @@
1
+ = prowly
2
+
3
+ Yet another Ruby interface to Prowl
4
+
5
+ == Installation
6
+
7
+ gem install prowly
8
+
9
+ == Usage
10
+
11
+ Prowly.notify do |n| # :notify is an alias of :add
12
+ n.apikey = "apikey" or n.apikeys = ["apikey_1", "apikey_2", "apikey_n"]
13
+ n.priority = Prowly::Notification::Priority::MODERATE
14
+ n.application = "Prowly"
15
+ n.event = "Notification"
16
+ n.description = "Your server is under attack!!!"
17
+ end
18
+
19
+ notification = Prowly::Notification.new(:apikey => "apikey", :application => "Prowly", :description => "Testing...")
20
+ notification = Prowly::Notification.new(:apikeys => ["apikey_1", "apikey_2", "apikey_n"], :application => "Prowly", :description => "Testing...")
21
+
22
+ result = Prowly.notify(notification)
23
+
24
+ == Handling the Prowl API response
25
+
26
+ ON SUCCESS
27
+ result.status # => "success"
28
+ result.code # => "200"
29
+
30
+ if result.succeeded?
31
+ result.remaining # => "977"
32
+ resetdate.resetdate # => "1266272588"
33
+ else
34
+ resetdate.message # =>
35
+ end
36
+
37
+ ON ERROR
38
+ result.status # => "error"
39
+ result.code # => "401" <= This depends on the error code sent by the prowl API
40
+
41
+ if result.succeeded?
42
+ result.remaining # =>
43
+ resetdate.resetdate # =>
44
+ else
45
+ resetdate.message # => "Invalid API Key(s)" <= This depends on the message sent by the prowl API
46
+ end
47
+
48
+
49
+
50
+ == Note on Patches/Pull Requests
51
+
52
+ * Fork the project.
53
+ * Make your feature addition or bug fix.
54
+ * Add tests for it. This is important so I don't break it in a
55
+ future version unintentionally.
56
+ * Commit, do not mess with rakefile, version, or history.
57
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
58
+ * Send me a pull request. Bonus points for topic branches.
59
+
60
+ == Copyright
61
+
62
+ Copyright (c) 2010 Rafael Magaña. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "prowly"
8
+ gem.summary = "A Ruby interface to Prowl (http://prowl.weks.net/)"
9
+ gem.description = "The Prowly gem is a simple wrapper to the Prowl API, you can use it to send messages to your iPhone in a Rails or pure Ruby application."
10
+ gem.email = "raf.magana@gmail.com"
11
+ gem.homepage = "http://github.com/rafmagana/prowly"
12
+ gem.authors = ["Rafael Magaña"]
13
+ gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/test_*.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ begin
29
+ require 'rcov/rcovtask'
30
+ Rcov::RcovTask.new do |test|
31
+ test.libs << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.verbose = true
34
+ end
35
+ rescue LoadError
36
+ task :rcov do
37
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
+ end
39
+ end
40
+
41
+ task :test => :check_dependencies
42
+
43
+ task :default => :test
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "prowly #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/bin/prowly ADDED
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ STDOUT.sync = true
4
+
5
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
6
+
7
+ require 'rubygems'
8
+ require 'prowly'
9
+ require 'optparse'
10
+
11
+ ORIGINAL_ARGV = ARGV.dup
12
+
13
+ #the defaults
14
+ options = {
15
+ :description => "I am testing Prowly, and it works!",
16
+ :event => "Prowly notification",
17
+ :application => "Prowly",
18
+ :priority => Prowly::Notification::Priority::NORMAL}
19
+
20
+
21
+ opts = OptionParser.new do |opts|
22
+ opts.banner = <<-EOF
23
+ Usage:
24
+ prowly -k onekey -e "the event"
25
+ prowly -k apikey_1,apikey_2,apikey_n -e "the event"
26
+
27
+ Options:
28
+ EOF
29
+
30
+ opts.on("-cCOMMAND", "--api-command COMMAND", "API Command, notify or verify so far") do |command|
31
+ options[:command] = command
32
+ end
33
+
34
+ opts.on("-kAPIKEY", "--api-key APIKEY", "Prowl API Key") do |apikey|
35
+ options[:apikey] = apikey
36
+ end
37
+
38
+ opts.on("-dDESCRIPTION", "--description DESCRIPTION", "Description") do |desc|
39
+ options[:description] = desc
40
+ end
41
+
42
+ opts.on("-eEVENT", "--event EVENT", "Event") do |event|
43
+ options[:event] = event
44
+ end
45
+
46
+ opts.on("-pPRIORITY", "--priority PRIORITY", "VERY_LOW, MODERATE, NORMAL (default), HIGH, EMERGENCY") do |priority|
47
+ options[:priority] = priority
48
+ end
49
+
50
+ opts.on("-v", "--version", "Print the version number and exit") do
51
+ options[:version] = true
52
+ end
53
+ end
54
+
55
+ opts.parse!
56
+
57
+ if options[:version]
58
+ abort("Version " + Prowly.version)
59
+ end
60
+
61
+ # validate
62
+ unless options[:command]
63
+ options[:command] == "notify"
64
+ end
65
+
66
+ unless options[:apikey]
67
+ abort("You must specify an API Key")
68
+ end
69
+
70
+ if options[:apikey].size < 40
71
+ abort("Each API key must be a 40-byte hexadecimal string")
72
+ else
73
+ options[:apikey] = options[:apikey].split(",") if options[:apikey].include? ","
74
+ end
75
+
76
+ available_priorities = Prowly::Notification::Priority.constants
77
+ unless available_priorities.include? options[:priority]
78
+ abort("Invalid priority. Valid options are: " + available_priorities.join(", "))
79
+ end
80
+
81
+ result = Prowly.notify do |n|
82
+ n.apikey = options[:apikey]
83
+ n.priority = options[:priority]
84
+ n.application = options[:application]
85
+ n.event = options[:event]
86
+ n.description = options[:description]
87
+ end
88
+
89
+ if result.succeeded?
90
+ exit 1
91
+ else
92
+ puts result.message
93
+ exit 0
94
+ end
data/lib/prowly.rb ADDED
@@ -0,0 +1,40 @@
1
+ require 'prowly/interface'
2
+ require 'prowly/notification'
3
+
4
+ module Prowly
5
+
6
+ extend self
7
+
8
+ def add(notification = Notification.new)
9
+ yield notification if block_given?
10
+ api.call Interface::Command::ADD, notification.to_params
11
+ end
12
+
13
+ def verify(apikey)
14
+ api.call Interface::Command::VERIFY, "apikey=#{apikey}"
15
+ end
16
+
17
+ def valid_key?(key)
18
+ result = verify(key)
19
+ result.succeeded?
20
+ end
21
+
22
+ def remaining_calls(key)
23
+ result = verify(key)
24
+ return result.remaining if result.succeeded?
25
+ result.message
26
+ end
27
+
28
+ def version
29
+ File.read(File.join(File.dirname(__FILE__), *%w[.. VERSION]))
30
+ end
31
+
32
+ private
33
+ def api
34
+ Interface.instance
35
+ end
36
+
37
+ #aliases
38
+ alias :notify :add
39
+
40
+ end
@@ -0,0 +1,47 @@
1
+ require 'net/https'
2
+ require 'prowly/response'
3
+ require 'prowly/notification'
4
+ require 'singleton'
5
+
6
+ module Prowly
7
+
8
+ class Interface
9
+
10
+ include Singleton
11
+
12
+ def initialize
13
+ @url = "https://prowl.weks.net/publicapi"
14
+ end
15
+
16
+ ## Make the actual call to the prowl api
17
+ def call(command, params)
18
+ @command = command
19
+ request = Net::HTTP::Get.new(uri.request_uri + "?" + params)
20
+ response = http.request(request)
21
+ Response.new(response.body, response)
22
+ end
23
+
24
+ private
25
+ def http
26
+ http = Net::HTTP.new(uri.host, uri.port)
27
+ http.use_ssl = true
28
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
29
+ http
30
+ end
31
+
32
+ def uri
33
+ URI.parse("#{@url}/#{@command}")
34
+ end
35
+
36
+ ## Available commands are documented in http://prowl.weks.net/api.php
37
+ module Command
38
+ ADD = "add"
39
+ VERIFY = "verify"
40
+ end
41
+
42
+ ## EXCEPTIONS
43
+ class NoAPIKeyGiven < RuntimeError; end
44
+
45
+ end
46
+
47
+ end
@@ -0,0 +1,88 @@
1
+ require 'cgi'
2
+
3
+ module Prowly
4
+
5
+ class BasicNotification
6
+
7
+ ## EXCEPTIONS
8
+ class NoAPIKeyGiven < RuntimeError; end
9
+ class NoDescriptionGiven < RuntimeError; end
10
+ class NoApplicationNameGiven < RuntimeError; end
11
+ class DuplicatedAssignmentOfApiKey < RuntimeError; end
12
+
13
+ attr_accessor :application, :description
14
+ attr_writer :apikey
15
+
16
+ alias :apikeys= :apikey=
17
+
18
+ def apikey
19
+ if @apikey.is_a? Array
20
+ @apikey.join(',')
21
+ else
22
+ @apikey
23
+ end
24
+ end
25
+ alias :apikeys :apikey
26
+
27
+ def initialize(params = {})
28
+ if params[:apikeys] and params[:apikey]
29
+ raise DuplicatedAssignmentOfApiKey, "Use apikey or apikeys, not both"
30
+ else
31
+ @apikey = params[:apikeys] unless params[:apikeys].nil?
32
+ @apikey = params[:apikey] unless params[:apikey].nil?
33
+ end
34
+ end
35
+
36
+ def to_params
37
+ raise NoAPIKeyGiven if apikey.nil?
38
+ raise NoApplicationNameGiven if @application.nil?
39
+ raise NoDescriptionGiven if @description.nil?
40
+ params.join('&')
41
+ end
42
+
43
+ private
44
+ def params
45
+ attributes = []
46
+ instance_variables.each do |var|
47
+ raw_attr = "#{var.sub('@','')}"
48
+ value = send("#{raw_attr}")
49
+ next if value.nil?
50
+ attributes << "#{raw_attr}=" + CGI.escape(value.to_s)
51
+ end
52
+ attributes.sort
53
+ end
54
+
55
+ end
56
+
57
+ class Notification < BasicNotification
58
+
59
+ ## EXCEPTIONS
60
+ class PriorityNotAvailable < RuntimeError; end
61
+
62
+ attr_accessor :providerkey, :priority, :event
63
+
64
+ def initialize(params = {})
65
+ @apikey = (params[:apikey] || params[:apikeys]) || "fffffffffffffffffffffffffffffffffffffffff"
66
+ @application = params[:application] || "Prowly"
67
+ @event = params[:event] || "Prowly is working!!"
68
+ @description = params[:description] || "This is the default description"
69
+ @priority = params[:priority] || Priority::NORMAL
70
+ super
71
+ end
72
+
73
+ public
74
+ ## Priorities are documented in http://prowl.weks.net/api.php
75
+ module Priority
76
+ VERY_LOW = -2
77
+ MODERATE = -1
78
+ NORMAL = 0
79
+ HIGH = 1
80
+ EMERGENCY = 2
81
+
82
+ def self.const_missing(const)
83
+ raise PriorityNotAvailable, const
84
+ end
85
+ end
86
+ end
87
+
88
+ end
@@ -0,0 +1,63 @@
1
+ require 'rexml/document'
2
+
3
+ module Prowly
4
+
5
+ class Response
6
+
7
+ attr_writer :response
8
+ attr_accessor :http_response
9
+
10
+ def initialize(xml_response, full_http_response)
11
+ @response = xml_response
12
+ @http_response = full_http_response
13
+ Response.map_xml @response
14
+ end
15
+
16
+ def self.map_xml(response)
17
+ #parse xml
18
+ data = REXML::Document.new response
19
+ response_info = data.root[1]
20
+
21
+ #define dynamic methods based on the prowl api response
22
+ #posible methods on success: code, remaining, resetdate
23
+ #posible methods on error: code
24
+ response_info.attributes.each do |key, value|
25
+ add_instance_method(key, value)
26
+ end
27
+
28
+ #define a method named status and it'll return "success" or "error"
29
+ Response.add_instance_method(:status, response_info.name)
30
+
31
+ if response_info.name == "success"
32
+ boolean_status = true
33
+ elsif response_info.name == "error"
34
+ boolean_status = false
35
+ end
36
+
37
+ add_instance_method(:message, response_info.text) unless boolean_status
38
+
39
+ add_instance_method(:succeeded?, boolean_status)
40
+ true
41
+ end
42
+
43
+ #define dynamic methods
44
+ def self.add_instance_method(name, content)
45
+ define_method(name) { content }
46
+ end
47
+
48
+ ## ERRORCODES are documented in http://prowl.weks.net/api.php
49
+ module ErrorCode
50
+ BAD = 400 #Bad request, the parameters you provided did not validate, see ERRORMESSAGE.
51
+ NOT_AUTHORIZED = 401 #Not authorized, the API key given is not valid, and does not correspond to a user.
52
+ METHOD_NOT_ALLOWED = 405 #Method not allowed, you attempted to use a non-SSL connection to Prowl.
53
+ NOT_ACCEPTABLE = 406 #Not acceptable, your IP address has exceeded the API limit.
54
+ INTERNAL_SERVER_ERROR = 500 #Internal server error, something failed to execute properly on the Prowl side.
55
+ end
56
+
57
+ module SuccessCode
58
+ SUCCESS = 200 #Everything went fine
59
+ end
60
+
61
+ end
62
+
63
+ end
data/prowly.gemspec ADDED
@@ -0,0 +1,59 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{prowly}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Rafael Maga\303\261a"]
12
+ s.date = %q{2010-02-15}
13
+ s.default_executable = %q{prowly}
14
+ s.description = %q{The Prowly gem is a simple wrapper to the Prowl API, you can use it to send messages to your iPhone in a Rails or pure Ruby application.}
15
+ s.email = %q{raf.magana@gmail.com}
16
+ s.executables = ["prowly"]
17
+ s.extra_rdoc_files = [
18
+ "LICENSE",
19
+ "README.rdoc"
20
+ ]
21
+ s.files = [
22
+ ".document",
23
+ ".gitignore",
24
+ "LICENSE",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "lib/prowly.rb",
29
+ "lib/prowly/interface.rb",
30
+ "lib/prowly/notification.rb",
31
+ "lib/prowly/response.rb",
32
+ "prowly.gemspec",
33
+ "test/helper.rb",
34
+ "test/test_prowly.rb"
35
+ ]
36
+ s.homepage = %q{http://github.com/rafmagana/prowly}
37
+ s.rdoc_options = ["--charset=UTF-8"]
38
+ s.require_paths = ["lib"]
39
+ s.rubygems_version = %q{1.3.5}
40
+ s.summary = %q{A Ruby interface to Prowl (http://prowl.weks.net/)}
41
+ s.test_files = [
42
+ "test/helper.rb",
43
+ "test/test_prowly.rb"
44
+ ]
45
+
46
+ if s.respond_to? :specification_version then
47
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
48
+ s.specification_version = 3
49
+
50
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
51
+ s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
52
+ else
53
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
54
+ end
55
+ else
56
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
57
+ end
58
+ end
59
+
data/test/helper.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'prowly'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestProwly < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: prowly
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - "Rafael Maga\xC3\xB1a"
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-02-15 00:00:00 -06:00
13
+ default_executable: prowly
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: thoughtbot-shoulda
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description: The Prowly gem is a simple wrapper to the Prowl API, you can use it to send messages to your iPhone in a Rails or pure Ruby application.
26
+ email: raf.magana@gmail.com
27
+ executables:
28
+ - prowly
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - LICENSE
33
+ - README.rdoc
34
+ files:
35
+ - .document
36
+ - .gitignore
37
+ - LICENSE
38
+ - README.rdoc
39
+ - Rakefile
40
+ - VERSION
41
+ - lib/prowly.rb
42
+ - lib/prowly/interface.rb
43
+ - lib/prowly/notification.rb
44
+ - lib/prowly/response.rb
45
+ - prowly.gemspec
46
+ - test/helper.rb
47
+ - test/test_prowly.rb
48
+ has_rdoc: true
49
+ homepage: http://github.com/rafmagana/prowly
50
+ licenses: []
51
+
52
+ post_install_message:
53
+ rdoc_options:
54
+ - --charset=UTF-8
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ version:
69
+ requirements: []
70
+
71
+ rubyforge_project:
72
+ rubygems_version: 1.3.5
73
+ signing_key:
74
+ specification_version: 3
75
+ summary: A Ruby interface to Prowl (http://prowl.weks.net/)
76
+ test_files:
77
+ - test/helper.rb
78
+ - test/test_prowly.rb