harleytt-simplepay 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +25 -0
- data/Manifest.txt +50 -0
- data/README.rdoc +127 -0
- data/Rakefile +25 -0
- data/lib/simplepay.rb +27 -0
- data/lib/simplepay/authentication.rb +41 -0
- data/lib/simplepay/constants.rb +64 -0
- data/lib/simplepay/errors.rb +16 -0
- data/lib/simplepay/helpers/form_helper.rb +29 -0
- data/lib/simplepay/helpers/notification_helper.rb +54 -0
- data/lib/simplepay/helpers/rails_helper.rb +40 -0
- data/lib/simplepay/rails.rb +9 -0
- data/lib/simplepay/service.rb +133 -0
- data/lib/simplepay/services/donation.rb +91 -0
- data/lib/simplepay/services/marketplace.rb +89 -0
- data/lib/simplepay/services/marketplace_policy.rb +54 -0
- data/lib/simplepay/services/standard.rb +58 -0
- data/lib/simplepay/services/subscription.rb +96 -0
- data/lib/simplepay/support.rb +16 -0
- data/lib/simplepay/support/amount.rb +55 -0
- data/lib/simplepay/support/billing_frequency.rb +14 -0
- data/lib/simplepay/support/boolean.rb +28 -0
- data/lib/simplepay/support/currency.rb +21 -0
- data/lib/simplepay/support/epoch.rb +39 -0
- data/lib/simplepay/support/field.rb +147 -0
- data/lib/simplepay/support/interval.rb +143 -0
- data/lib/simplepay/support/simple_amount.rb +37 -0
- data/lib/simplepay/support/subscription_period.rb +25 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/simplepay.gemspec +41 -0
- data/test/simplepay/helpers/test_notifier.rb +32 -0
- data/test/simplepay/services/test_donation.rb +85 -0
- data/test/simplepay/services/test_marketplace.rb +85 -0
- data/test/simplepay/services/test_marketplace_policy.rb +52 -0
- data/test/simplepay/services/test_standard.rb +71 -0
- data/test/simplepay/services/test_subscription.rb +109 -0
- data/test/simplepay/support/test_amount.rb +46 -0
- data/test/simplepay/support/test_billing_frequency.rb +43 -0
- data/test/simplepay/support/test_boolean.rb +17 -0
- data/test/simplepay/support/test_epoch.rb +34 -0
- data/test/simplepay/support/test_field.rb +99 -0
- data/test/simplepay/support/test_interval.rb +92 -0
- data/test/simplepay/support/test_simple_amount.rb +28 -0
- data/test/simplepay/support/test_subscription_period.rb +49 -0
- data/test/simplepay/test_authentication.rb +25 -0
- data/test/simplepay/test_service.rb +118 -0
- data/test/test_helper.rb +87 -0
- data/test/test_simplepay.rb +11 -0
- metadata +184 -0
@@ -0,0 +1,96 @@
|
|
1
|
+
module Simplepay
|
2
|
+
module Services
|
3
|
+
|
4
|
+
##
|
5
|
+
# A Simple Pay Subscription is an automatically recurring payment which is
|
6
|
+
# charged every interval (Simplepay::Support::BillingFrequency) until
|
7
|
+
# a limiting period (Simplepay::Support::SubscriptionPeriod) is met.
|
8
|
+
#
|
9
|
+
# With this type of payment, for example, you may charge your customer:
|
10
|
+
#
|
11
|
+
# $10.00 every 3 days until 9 days.
|
12
|
+
# $9.95 every 1 month until forever.
|
13
|
+
#
|
14
|
+
# === Simple Pay Subscription Fields
|
15
|
+
#
|
16
|
+
# === Required Fields
|
17
|
+
#
|
18
|
+
# The following attributes are required when creating a Simple Pay
|
19
|
+
# Subscription form (in addition to those listed in +Simplepay::Service+):
|
20
|
+
#
|
21
|
+
# amount:: The dollar value you'd like to collect.
|
22
|
+
# description:: A summary of the reason for the payment, this is displayed to your customer during checkout.
|
23
|
+
# recurring_frequency:: Defines how often to charge your customer (ex. "1 month")
|
24
|
+
#
|
25
|
+
# ==== Optional Fields
|
26
|
+
#
|
27
|
+
# abandon_url:: The fully-qualified URL to send your custom if they cancel during payment.
|
28
|
+
# auto_renew:: Instructs Amazon to automatically renew the subscription after the +subscription_period+ ends.
|
29
|
+
# cobranding_style:: Defines the type of cobranding to use during the checkout process.
|
30
|
+
# collect_shipping_address:: Tells Amazon whether or not to ask for shipping address and contact information.
|
31
|
+
# immediate_return:: Immediately returns the customer to your +return_url+ directly after payment.
|
32
|
+
# ipn_url:: Fully-qualified URL to which Amazon will POST instant payment notifications.
|
33
|
+
# process_immediately:: Instructs Amazon to immediately process the payment.
|
34
|
+
# reference_id:: A custom string your can set to identify this transaction, it will be returned with the IPNs and other returned data.
|
35
|
+
# return_url:: Fully-qualified URL for where to send your customer following payment.
|
36
|
+
# start_date:: Instructs Amazon with the timestamp to start the recurring subscription charges.
|
37
|
+
# subscription_period:: Defines the expiration window of the subscription (i.e. charge +amount+ every +recurring_frequency+ for "36 months")
|
38
|
+
#
|
39
|
+
# === Example
|
40
|
+
#
|
41
|
+
# (in your view, using the form helper)
|
42
|
+
#
|
43
|
+
# <%= simplepay_form_for(:subscription, {
|
44
|
+
# :amount => 12.95,
|
45
|
+
# :recurring_frequency => "1 year",
|
46
|
+
# :description => "My.Url Yearly Dues"
|
47
|
+
# }) %>
|
48
|
+
#
|
49
|
+
class Subscription < Service
|
50
|
+
|
51
|
+
required_field :access_key
|
52
|
+
required_field :signature
|
53
|
+
required_field :account_id, :as => :amazon_payments_account_id
|
54
|
+
required_field :signature_method, :value => 'HmacSHA256'
|
55
|
+
required_field :signature_version, :value => '2'
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
required_field :recurring_frequency, :class => Support::BillingFrequency
|
60
|
+
required_field :description
|
61
|
+
required_field :amount, :class => Support::Amount
|
62
|
+
required_field :cobranding_style, :value => 'logo'
|
63
|
+
|
64
|
+
field :subscription_period, :class => Support::SubscriptionPeriod
|
65
|
+
field :reference_id
|
66
|
+
field :immediate_return, :class => Support::Boolean
|
67
|
+
|
68
|
+
field :start_date, :class => Support::Epoch,
|
69
|
+
:as => :recurring_start_date
|
70
|
+
|
71
|
+
field :collect_shipping_address, :class => Support::Boolean
|
72
|
+
|
73
|
+
field :process_immediately, :class => Support::Boolean,
|
74
|
+
:as => :process_immediate
|
75
|
+
|
76
|
+
field :auto_renew, :class => Support::Boolean,
|
77
|
+
:as => :is_auto_renewal
|
78
|
+
|
79
|
+
field :return_url
|
80
|
+
field :ipn_url
|
81
|
+
field :abandon_url
|
82
|
+
|
83
|
+
# Used for trial periods
|
84
|
+
field :promotion_amount, :class => Support::Amount
|
85
|
+
field :number_of_promotion_transactions, :as => :no_of_promotion_transactions
|
86
|
+
|
87
|
+
# These fields are not currently utilized by the service
|
88
|
+
field :variable_marketplace_fee, :value => ''
|
89
|
+
field :donation_widget, :as => :is_donation_widget,
|
90
|
+
:value => '0'
|
91
|
+
field :fixed_marketplace_fee, :value => ''
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'simplepay/support/amount'
|
2
|
+
require 'simplepay/support/billing_frequency'
|
3
|
+
require 'simplepay/support/boolean'
|
4
|
+
require 'simplepay/support/currency'
|
5
|
+
require 'simplepay/support/epoch'
|
6
|
+
require 'simplepay/support/field'
|
7
|
+
require 'simplepay/support/interval'
|
8
|
+
require 'simplepay/support/simple_amount'
|
9
|
+
require 'simplepay/support/subscription_period'
|
10
|
+
|
11
|
+
module Simplepay
|
12
|
+
|
13
|
+
module Support
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
|
3
|
+
module Simplepay
|
4
|
+
module Support
|
5
|
+
|
6
|
+
##
|
7
|
+
# Amazon often represents dollar values as a combination of a value and a
|
8
|
+
# currency. In several types of requests, the combination is required for
|
9
|
+
# communication.
|
10
|
+
#
|
11
|
+
# At the present time, Amazon only uses USD.
|
12
|
+
#
|
13
|
+
class Amount
|
14
|
+
|
15
|
+
attr_reader :amount
|
16
|
+
attr_reader :currency
|
17
|
+
|
18
|
+
def initialize(amount, currency = Simplepay::Currency::USD)
|
19
|
+
self.amount = amount
|
20
|
+
self.currency = currency
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
##
|
25
|
+
# Sets the amount of the currency value, such as "1" for 1 USD. This
|
26
|
+
# amount cannot be negative.
|
27
|
+
#
|
28
|
+
def amount=(amount)
|
29
|
+
raise(ArgumentError, "Amount cannot be nil") unless amount
|
30
|
+
raise(ArgumentError, "Amount cannot be negative") if amount < 0
|
31
|
+
@amount = BigDecimal.new(amount.to_s)
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Sets the type of currency to use in the transaction. The parameter
|
36
|
+
# can either be a known currency code (see Simplepay::Currency) or a
|
37
|
+
# custom Simplepay::Currency::Currency instance.
|
38
|
+
#
|
39
|
+
def currency=(currency)
|
40
|
+
raise(ArgumentError, "Invalid currency, expected Simplepay::Support::Currency or currency code string.") unless currency.kind_of?(Simplepay::Support::Currency) || currency.kind_of?(String)
|
41
|
+
if currency.kind_of?(String)
|
42
|
+
currency = Simplepay::Currencies.detect { |c| c.code == currency } ||
|
43
|
+
raise(ArgumentError, "Invalid currency, '#{currency}'. Must be one of: #{Simplepay::Currencies.join(', ')}")
|
44
|
+
end
|
45
|
+
@currency = currency
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_s
|
49
|
+
"#{currency.code} #{currency.format % amount}"
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Simplepay
|
2
|
+
module Support
|
3
|
+
|
4
|
+
##
|
5
|
+
# Acts as a delegator for Simplepay::Support::Field <tt>:class</tt>.
|
6
|
+
#
|
7
|
+
# This class acts as a helper for sending boolean values to Amazon. In
|
8
|
+
# their forms, booleans are expected to be either "0" or "1", for false or
|
9
|
+
# true, respectively.
|
10
|
+
#
|
11
|
+
class Boolean
|
12
|
+
|
13
|
+
def initialize(value)
|
14
|
+
@value = value
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# Returns "1" if the boolean is true, "0" otherwise.
|
19
|
+
#
|
20
|
+
def to_s
|
21
|
+
return '' if @value.nil?
|
22
|
+
@value ? Simplepay::Boolean::True : Simplepay::Boolean::False
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Simplepay
|
2
|
+
module Support
|
3
|
+
|
4
|
+
##
|
5
|
+
# Contains a name, recognized code, and basic formatting for a particular
|
6
|
+
# international monetary currency.
|
7
|
+
#
|
8
|
+
class Currency
|
9
|
+
attr_reader :name, :code, :format
|
10
|
+
|
11
|
+
def initialize(name, code, format)
|
12
|
+
@name, @code, @format = name, code, format
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_s
|
16
|
+
"#{code}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Simplepay
|
2
|
+
module Support
|
3
|
+
|
4
|
+
##
|
5
|
+
# Acts as a Simplepay::Support::Field <tt>:class</tt> delegator.
|
6
|
+
#
|
7
|
+
# This class provides a means to have Time values returned as an integer
|
8
|
+
# since epoch (January 1, 1970).
|
9
|
+
#
|
10
|
+
class Epoch
|
11
|
+
|
12
|
+
def initialize(time)
|
13
|
+
@value = time ? parse(time) : Time.now
|
14
|
+
end
|
15
|
+
|
16
|
+
##
|
17
|
+
# Returns a String of Integers, representing seconds since epoch.
|
18
|
+
#
|
19
|
+
def to_s
|
20
|
+
@value.to_i.to_s
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
|
27
|
+
def parse(time)
|
28
|
+
case time
|
29
|
+
when Time, Date, DateTime
|
30
|
+
time
|
31
|
+
else
|
32
|
+
Time.parse(time)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
|
3
|
+
module Simplepay
|
4
|
+
module Support
|
5
|
+
|
6
|
+
##
|
7
|
+
# Represents a data field which will ultimately populate a Simple Pay
|
8
|
+
# form. These fields are often unique to their service.
|
9
|
+
#
|
10
|
+
class Field
|
11
|
+
include Comparable
|
12
|
+
|
13
|
+
ALLOWED_OPTIONS = [:as, :class, :required, :value]
|
14
|
+
|
15
|
+
# The parent service of the field
|
16
|
+
attr_reader :service
|
17
|
+
|
18
|
+
# The name of the field used in your local program (may be different than the service name)
|
19
|
+
attr_reader :name
|
20
|
+
|
21
|
+
##
|
22
|
+
# name:: Name which is used when referring to this field in the code.
|
23
|
+
# options:: An optional hash of field options.
|
24
|
+
#
|
25
|
+
# === Options
|
26
|
+
#
|
27
|
+
# as:: Overrides the +name+ when used by the service to the exact string or symbol (camelized) given.
|
28
|
+
# class:: Delegate the value mechanics to a separate class.
|
29
|
+
# required:: Tells whether or not this field is required for its service.
|
30
|
+
# value:: Set the value of the field at initialization.
|
31
|
+
#
|
32
|
+
# === Example
|
33
|
+
#
|
34
|
+
# Field.new(:example, :required => true, :as => 'ExAmplE')
|
35
|
+
# Field.new(:delegated, :class => Simplepay::Support::Boolean, :value => true)
|
36
|
+
#
|
37
|
+
def initialize(service, name, options)
|
38
|
+
@service, @name, @options = service, name, normalize_options!(options)
|
39
|
+
@delegate = options[:class]
|
40
|
+
@value = nil
|
41
|
+
self.value = options[:value] if options[:value]
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Returns the name of the field used by the service. This may be
|
46
|
+
# different than the Ruby name given to the field.
|
47
|
+
#
|
48
|
+
# Symbol names (or :as options) are camelized. If this is not desired,
|
49
|
+
# use a String, instead.
|
50
|
+
#
|
51
|
+
def service_name
|
52
|
+
source = @options[:as] || @name
|
53
|
+
case source
|
54
|
+
when Symbol
|
55
|
+
source.to_s.camelize(:lower)
|
56
|
+
else
|
57
|
+
source
|
58
|
+
end
|
59
|
+
end
|
60
|
+
alias :to_s :service_name
|
61
|
+
|
62
|
+
##
|
63
|
+
# Returns +true+ if the field is required for the service.
|
64
|
+
#
|
65
|
+
def required?
|
66
|
+
@options[:required] ? true : false
|
67
|
+
end
|
68
|
+
|
69
|
+
##
|
70
|
+
# Converts a Field into an HTML HIDDEN INPUT element as a string.
|
71
|
+
#
|
72
|
+
def to_input
|
73
|
+
raise(RequiredFieldMissing, "Missing Required Field value for #{name}") if required? && value.blank?
|
74
|
+
value.blank? ? '' : html_input_tag
|
75
|
+
end
|
76
|
+
|
77
|
+
def delegated? #:nodoc:
|
78
|
+
@delegate
|
79
|
+
end
|
80
|
+
|
81
|
+
def value=(v) #:nodoc:
|
82
|
+
@value = delegated? ? @delegate.new(v) : v
|
83
|
+
end
|
84
|
+
|
85
|
+
def value #:nodoc:
|
86
|
+
if delegated?
|
87
|
+
@value.to_s
|
88
|
+
else
|
89
|
+
case @value
|
90
|
+
when Proc
|
91
|
+
@value.call(self)
|
92
|
+
else
|
93
|
+
@value
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
##
|
99
|
+
# Sorting is based solely by +service_name+.
|
100
|
+
#
|
101
|
+
def <=>(o)
|
102
|
+
self.service_name <=> o.service_name
|
103
|
+
end
|
104
|
+
|
105
|
+
def ==(o) #:nodoc:
|
106
|
+
self.service == o.service &&
|
107
|
+
self.name == o.name
|
108
|
+
end
|
109
|
+
|
110
|
+
def inspect #:nodoc:
|
111
|
+
%|#<#{self.class.name} Name:"#{@name}"#{" ServiceName:\"#{service_name}\"" if service_name != @name}#{" REQUIRED" if required?}>|
|
112
|
+
end
|
113
|
+
|
114
|
+
def clone_for(o) #:nodoc:
|
115
|
+
self.class.new(o, deep_clone(@name), deep_clone(@options))
|
116
|
+
end
|
117
|
+
|
118
|
+
def delegate #:nodoc:
|
119
|
+
@delegate
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
private
|
124
|
+
|
125
|
+
|
126
|
+
def html_input_tag #:nodoc:
|
127
|
+
Simplepay::Helpers::FormHelper.tag(:input, {
|
128
|
+
:name => service_name,
|
129
|
+
:value => value,
|
130
|
+
:type => 'hidden'
|
131
|
+
})
|
132
|
+
end
|
133
|
+
|
134
|
+
def normalize_options!(options) #:nodoc:
|
135
|
+
options.symbolize_keys!
|
136
|
+
raise(InvalidOptions, "Unrecognized options passed: #{(options.keys - ALLOWED_OPTIONS).join(', ')}") unless (options.keys - ALLOWED_OPTIONS).empty?
|
137
|
+
options
|
138
|
+
end
|
139
|
+
|
140
|
+
def deep_clone(o)
|
141
|
+
Marshal::load(Marshal.dump(o))
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
module Simplepay
|
2
|
+
module Support
|
3
|
+
|
4
|
+
class Interval
|
5
|
+
|
6
|
+
# If set, limits the quantity to a value within this range
|
7
|
+
ALLOWED_QUANTITY_RANGE = nil
|
8
|
+
|
9
|
+
# If set, limits the interval set to a value within this array
|
10
|
+
ALLOWED_INTERVALS = nil
|
11
|
+
|
12
|
+
# Sets the default quantity value for new instances
|
13
|
+
DEFAULT_QUANTITY = nil
|
14
|
+
|
15
|
+
# Sets the default interval value for new instances
|
16
|
+
DEFAULT_INTERVAL = nil
|
17
|
+
|
18
|
+
# The numeric number of intervals
|
19
|
+
attr_reader :quantity
|
20
|
+
|
21
|
+
# The interval, or "period", of time
|
22
|
+
attr_reader :interval
|
23
|
+
|
24
|
+
|
25
|
+
class << self
|
26
|
+
|
27
|
+
def allowed_intervals
|
28
|
+
const_get(:ALLOWED_INTERVALS)
|
29
|
+
end
|
30
|
+
|
31
|
+
def allowed_quantity_range
|
32
|
+
const_get(:ALLOWED_QUANTITY_RANGE)
|
33
|
+
end
|
34
|
+
|
35
|
+
def default_quantity
|
36
|
+
const_get(:DEFAULT_QUANTITY)
|
37
|
+
end
|
38
|
+
|
39
|
+
def default_interval
|
40
|
+
const_get(:DEFAULT_INTERVAL)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
##
|
47
|
+
# Creates an instance of the Interval. This can be called in one of
|
48
|
+
# several ways:
|
49
|
+
#
|
50
|
+
# no arguments:: Creates a new interval instance with default values.
|
51
|
+
# one argument, string:: Creates a new interval by parsing the given string to set both the quantity and interval. Must be formatted as: "3 day" (quantity, space, interval)
|
52
|
+
# one argument, hash:: Creates a new interval and populates it with the given :quantity and :interval. Uses defaults if not given.
|
53
|
+
# two arguments:: Creates a new interval with the first argument as the quantity, second argument as the interval.
|
54
|
+
#
|
55
|
+
# === Examples
|
56
|
+
#
|
57
|
+
# All of these are equivalent:
|
58
|
+
#
|
59
|
+
# Interval.new("3 day")
|
60
|
+
# Interval.new({:quantity => 3, :interval => 'day'})
|
61
|
+
# Interval.new(3, 'day')
|
62
|
+
#
|
63
|
+
def initialize(*args)
|
64
|
+
parse_arguments(*args)
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# Set the interval.
|
69
|
+
#
|
70
|
+
def interval=(i)
|
71
|
+
raise(ArgumentError, "Interval '#{i}' should be one of: #{allowed_intervals.join(', ')}") if i && allowed_intervals && !allowed_intervals.include?(i)
|
72
|
+
@interval = i
|
73
|
+
end
|
74
|
+
|
75
|
+
##
|
76
|
+
# Set the quantity.
|
77
|
+
#
|
78
|
+
def quantity=(q)
|
79
|
+
raise(ArgumentError, "Quantity '#{q}' should be in #{allowed_quantity_range}") if q && allowed_quantity_range && !allowed_quantity_range.include?(q)
|
80
|
+
@quantity = q
|
81
|
+
end
|
82
|
+
|
83
|
+
##
|
84
|
+
# Converts the interval into an Amazon-ready string.
|
85
|
+
#
|
86
|
+
# Interval.new(3, 'day').to_s # => "3 day"
|
87
|
+
#
|
88
|
+
def to_s
|
89
|
+
"#{quantity} #{interval}" if interval
|
90
|
+
end
|
91
|
+
|
92
|
+
def allowed_intervals #:nodoc:
|
93
|
+
self.class.allowed_intervals
|
94
|
+
end
|
95
|
+
|
96
|
+
def allowed_quantity_range #:nodoc:
|
97
|
+
self.class.allowed_quantity_range
|
98
|
+
end
|
99
|
+
|
100
|
+
def default_quantity #:nodoc:
|
101
|
+
self.class.default_quantity
|
102
|
+
end
|
103
|
+
|
104
|
+
def default_interval #:nodoc:
|
105
|
+
self.class.default_interval
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
|
112
|
+
def parse_arguments(*args)
|
113
|
+
case args.size
|
114
|
+
when 0
|
115
|
+
self.quantity = self.default_quantity
|
116
|
+
self.interval = self.default_interval
|
117
|
+
when 1
|
118
|
+
case args.first
|
119
|
+
when String
|
120
|
+
parse_values_from(args.first)
|
121
|
+
when Hash
|
122
|
+
self.quantity = args.first[:quantity] || self.default_quantity
|
123
|
+
self.interval = args.first[:interval] || self.default_interval
|
124
|
+
end
|
125
|
+
else
|
126
|
+
self.quantity = args.first
|
127
|
+
self.interval = args[1]
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def parse_values_from(s)
|
132
|
+
if s =~ /\A([\d]+)\s+([\w]+)\Z/
|
133
|
+
self.quantity = $1.to_i
|
134
|
+
self.interval = $2
|
135
|
+
else
|
136
|
+
raise ArgumentError, "Unrecognzied initialization string given: #{s.inspect}"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
end
|