spreedly 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +6 -0
- data/Manifest.txt +66 -0
- data/README.txt +68 -0
- data/Rakefile +72 -0
- data/lib/spreedly.rb +154 -0
- data/lib/spreedly/common.rb +24 -0
- data/lib/spreedly/mock.rb +113 -0
- data/lib/spreedly/version.rb +3 -0
- data/test/spreedly_gem_test.rb +152 -0
- data/test/test_site.yml +2 -0
- data/vendor/httparty/History +108 -0
- data/vendor/httparty/MIT-LICENSE +20 -0
- data/vendor/httparty/Manifest +55 -0
- data/vendor/httparty/README +35 -0
- data/vendor/httparty/Rakefile +47 -0
- data/vendor/httparty/bin/httparty +98 -0
- data/vendor/httparty/cucumber.yml +1 -0
- data/vendor/httparty/examples/aaws.rb +32 -0
- data/vendor/httparty/examples/basic.rb +11 -0
- data/vendor/httparty/examples/delicious.rb +37 -0
- data/vendor/httparty/examples/google.rb +16 -0
- data/vendor/httparty/examples/rubyurl.rb +14 -0
- data/vendor/httparty/examples/twitter.rb +31 -0
- data/vendor/httparty/examples/whoismyrep.rb +10 -0
- data/vendor/httparty/features/basic_authentication.feature +20 -0
- data/vendor/httparty/features/command_line.feature +7 -0
- data/vendor/httparty/features/deals_with_http_error_codes.feature +26 -0
- data/vendor/httparty/features/handles_multiple_formats.feature +34 -0
- data/vendor/httparty/features/steps/env.rb +15 -0
- data/vendor/httparty/features/steps/httparty_response_steps.rb +26 -0
- data/vendor/httparty/features/steps/httparty_steps.rb +15 -0
- data/vendor/httparty/features/steps/mongrel_helper.rb +55 -0
- data/vendor/httparty/features/steps/remote_service_steps.rb +47 -0
- data/vendor/httparty/features/supports_redirection.feature +22 -0
- data/vendor/httparty/httparty.gemspec +37 -0
- data/vendor/httparty/lib/core_extensions.rb +189 -0
- data/vendor/httparty/lib/httparty.rb +201 -0
- data/vendor/httparty/lib/httparty/cookie_hash.rb +9 -0
- data/vendor/httparty/lib/httparty/exceptions.rb +7 -0
- data/vendor/httparty/lib/httparty/logging.rb +35 -0
- data/vendor/httparty/lib/httparty/module_inheritable_attributes.rb +25 -0
- data/vendor/httparty/lib/httparty/parsers.rb +4 -0
- data/vendor/httparty/lib/httparty/parsers/json.rb +74 -0
- data/vendor/httparty/lib/httparty/parsers/xml.rb +209 -0
- data/vendor/httparty/lib/httparty/request.rb +169 -0
- data/vendor/httparty/lib/httparty/response.rb +17 -0
- data/vendor/httparty/lib/httparty/version.rb +3 -0
- data/vendor/httparty/setup.rb +1585 -0
- data/vendor/httparty/spec/fixtures/delicious.xml +23 -0
- data/vendor/httparty/spec/fixtures/empty.xml +0 -0
- data/vendor/httparty/spec/fixtures/google.html +3 -0
- data/vendor/httparty/spec/fixtures/twitter.json +1 -0
- data/vendor/httparty/spec/fixtures/twitter.xml +403 -0
- data/vendor/httparty/spec/fixtures/undefined_method_add_node_for_nil.xml +2 -0
- data/vendor/httparty/spec/hash_spec.rb +49 -0
- data/vendor/httparty/spec/httparty/cookie_hash_spec.rb +38 -0
- data/vendor/httparty/spec/httparty/parsers/json_spec.rb +44 -0
- data/vendor/httparty/spec/httparty/parsers/xml_spec.rb +454 -0
- data/vendor/httparty/spec/httparty/request_spec.rb +203 -0
- data/vendor/httparty/spec/httparty/response_spec.rb +53 -0
- data/vendor/httparty/spec/httparty_spec.rb +259 -0
- data/vendor/httparty/spec/spec.opts +3 -0
- data/vendor/httparty/spec/spec_helper.rb +21 -0
- data/vendor/httparty/spec/string_spec.rb +29 -0
- data/vendor/httparty/website/css/common.css +47 -0
- data/vendor/httparty/website/index.html +74 -0
- metadata +141 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
README.txt
|
4
|
+
Rakefile
|
5
|
+
lib/spreedly.rb
|
6
|
+
lib/spreedly/common.rb
|
7
|
+
lib/spreedly/mock.rb
|
8
|
+
lib/spreedly/version.rb
|
9
|
+
test/spreedly_gem_test.rb
|
10
|
+
test/test_site.yml
|
11
|
+
vendor/httparty/History
|
12
|
+
vendor/httparty/MIT-LICENSE
|
13
|
+
vendor/httparty/Manifest
|
14
|
+
vendor/httparty/README
|
15
|
+
vendor/httparty/Rakefile
|
16
|
+
vendor/httparty/bin/httparty
|
17
|
+
vendor/httparty/cucumber.yml
|
18
|
+
vendor/httparty/examples/aaws.rb
|
19
|
+
vendor/httparty/examples/basic.rb
|
20
|
+
vendor/httparty/examples/delicious.rb
|
21
|
+
vendor/httparty/examples/google.rb
|
22
|
+
vendor/httparty/examples/rubyurl.rb
|
23
|
+
vendor/httparty/examples/twitter.rb
|
24
|
+
vendor/httparty/examples/whoismyrep.rb
|
25
|
+
vendor/httparty/features/basic_authentication.feature
|
26
|
+
vendor/httparty/features/command_line.feature
|
27
|
+
vendor/httparty/features/deals_with_http_error_codes.feature
|
28
|
+
vendor/httparty/features/handles_multiple_formats.feature
|
29
|
+
vendor/httparty/features/steps/env.rb
|
30
|
+
vendor/httparty/features/steps/httparty_response_steps.rb
|
31
|
+
vendor/httparty/features/steps/httparty_steps.rb
|
32
|
+
vendor/httparty/features/steps/mongrel_helper.rb
|
33
|
+
vendor/httparty/features/steps/remote_service_steps.rb
|
34
|
+
vendor/httparty/features/supports_redirection.feature
|
35
|
+
vendor/httparty/httparty.gemspec
|
36
|
+
vendor/httparty/lib/core_extensions.rb
|
37
|
+
vendor/httparty/lib/httparty.rb
|
38
|
+
vendor/httparty/lib/httparty/cookie_hash.rb
|
39
|
+
vendor/httparty/lib/httparty/exceptions.rb
|
40
|
+
vendor/httparty/lib/httparty/logging.rb
|
41
|
+
vendor/httparty/lib/httparty/module_inheritable_attributes.rb
|
42
|
+
vendor/httparty/lib/httparty/parsers.rb
|
43
|
+
vendor/httparty/lib/httparty/parsers/json.rb
|
44
|
+
vendor/httparty/lib/httparty/parsers/xml.rb
|
45
|
+
vendor/httparty/lib/httparty/request.rb
|
46
|
+
vendor/httparty/lib/httparty/response.rb
|
47
|
+
vendor/httparty/lib/httparty/version.rb
|
48
|
+
vendor/httparty/setup.rb
|
49
|
+
vendor/httparty/spec/fixtures/delicious.xml
|
50
|
+
vendor/httparty/spec/fixtures/empty.xml
|
51
|
+
vendor/httparty/spec/fixtures/google.html
|
52
|
+
vendor/httparty/spec/fixtures/twitter.json
|
53
|
+
vendor/httparty/spec/fixtures/twitter.xml
|
54
|
+
vendor/httparty/spec/fixtures/undefined_method_add_node_for_nil.xml
|
55
|
+
vendor/httparty/spec/hash_spec.rb
|
56
|
+
vendor/httparty/spec/httparty/cookie_hash_spec.rb
|
57
|
+
vendor/httparty/spec/httparty/parsers/json_spec.rb
|
58
|
+
vendor/httparty/spec/httparty/parsers/xml_spec.rb
|
59
|
+
vendor/httparty/spec/httparty/request_spec.rb
|
60
|
+
vendor/httparty/spec/httparty/response_spec.rb
|
61
|
+
vendor/httparty/spec/httparty_spec.rb
|
62
|
+
vendor/httparty/spec/spec.opts
|
63
|
+
vendor/httparty/spec/spec_helper.rb
|
64
|
+
vendor/httparty/spec/string_spec.rb
|
65
|
+
vendor/httparty/website/css/common.css
|
66
|
+
vendor/httparty/website/index.html
|
data/README.txt
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
= Spreedly-Gem
|
2
|
+
|
3
|
+
* http://terralien.com/static/projects/spreedly-gem/
|
4
|
+
* http://github.com/terralien/spreedly-gem
|
5
|
+
|
6
|
+
== DESCRIPTION:
|
7
|
+
|
8
|
+
The Spreedly gem provides a convenient Ruby wrapper for the goodness that is
|
9
|
+
the http://spreedly.com API. Created by Terralien[http://terralien.com].
|
10
|
+
|
11
|
+
== FEATURES:
|
12
|
+
|
13
|
+
* Makes it easy to get started.
|
14
|
+
* Fully tested.
|
15
|
+
* (Mostly) fully substitutable mock implementation for fast tests.
|
16
|
+
* Great example code.
|
17
|
+
|
18
|
+
== SYNOPSIS:
|
19
|
+
|
20
|
+
# For real
|
21
|
+
require 'spreedly'
|
22
|
+
Spreedly.configure('site name', 'crazy hash token')
|
23
|
+
url = Spreedly.subscribe_url(:id => 'customer id', :plan => 'plan id')
|
24
|
+
subscriber = Spreedly::Subscriber.find('customer id')
|
25
|
+
subscriber.active?
|
26
|
+
|
27
|
+
# For mock
|
28
|
+
require 'spreedly/mock'
|
29
|
+
Spreedly.configure('site name', 'crazy hash token')
|
30
|
+
url = Spreedly.subscribe_url(:id => 'customer id', :plan => 'plan id')
|
31
|
+
subscriber = Spreedly::Subscriber.find('customer id')
|
32
|
+
subscriber.active?
|
33
|
+
|
34
|
+
Yup, they're exactly the same except for the require and the speed!
|
35
|
+
|
36
|
+
== REQUIREMENTS:
|
37
|
+
|
38
|
+
* A (free) Spreedly account.
|
39
|
+
* HTTParty (vendored for now).
|
40
|
+
|
41
|
+
== INSTALL:
|
42
|
+
|
43
|
+
`sudo gem install spreedly-gem`
|
44
|
+
|
45
|
+
== LICENSE:
|
46
|
+
|
47
|
+
(The MIT License)
|
48
|
+
|
49
|
+
Copyright (c) 2009 Nathaniel Talbott
|
50
|
+
|
51
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
52
|
+
a copy of this software and associated documentation files (the
|
53
|
+
'Software'), to deal in the Software without restriction, including
|
54
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
55
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
56
|
+
permit persons to whom the Software is furnished to do so, subject to
|
57
|
+
the following conditions:
|
58
|
+
|
59
|
+
The above copyright notice and this permission notice shall be
|
60
|
+
included in all copies or substantial portions of the Software.
|
61
|
+
|
62
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
63
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
64
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
65
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
66
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
67
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
68
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'hoe'
|
2
|
+
require './lib/spreedly/version.rb'
|
3
|
+
|
4
|
+
ENV["COPYFILE_DISABLE"] = "true" # Lose all the fugly ._ files when tar'ing
|
5
|
+
|
6
|
+
hoe = nil
|
7
|
+
Hoe.new('spreedly', Spreedly::VERSION) do |project|
|
8
|
+
hoe = project
|
9
|
+
project.rubyforge_name = 'terralien'
|
10
|
+
project.developer('Nathaniel Talbott', 'nathaniel@terralien.com')
|
11
|
+
project.test_globs = ["test/**/*_test.rb"]
|
12
|
+
project.extra_dev_deps = ["thoughtbot-shoulda"]
|
13
|
+
end
|
14
|
+
|
15
|
+
def remove_task(*task_names)
|
16
|
+
task_names.each do |task_name|
|
17
|
+
Rake.application.instance_eval{@tasks.delete(task_name.to_s)}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def replace_task(task_name, *args, &block)
|
22
|
+
name = (task_name.is_a?(Hash) ? task_name.keys.first : task_name)
|
23
|
+
remove_task(name)
|
24
|
+
task(task_name, *args, &block)
|
25
|
+
end
|
26
|
+
|
27
|
+
remove_task :docs, 'doc/index.html'
|
28
|
+
Rake::RDocTask.new(:docs) do |rd|
|
29
|
+
rd.main = hoe.readme_file
|
30
|
+
rd.rdoc_dir = 'doc'
|
31
|
+
|
32
|
+
rd.rdoc_files += ['lib/spreedly.rb', 'lib/spreedly/common.rb', hoe.readme_file]
|
33
|
+
|
34
|
+
title = "Terralien's Spreedly Gem (#{hoe.version}) Documentation"
|
35
|
+
|
36
|
+
rd.options << "-t" << title << "-f" << "darkfish"
|
37
|
+
end
|
38
|
+
|
39
|
+
replace_task :publish_docs => [:clean, :docs] do
|
40
|
+
host = "terralien@terralien.biz"
|
41
|
+
|
42
|
+
remote_dir = "/var/www/terralien/www/shared/static/projects/spreedly-gem"
|
43
|
+
local_dir = 'doc'
|
44
|
+
|
45
|
+
sh %{rsync #{hoe.rsync_args} #{local_dir}/ #{host}:#{remote_dir}}
|
46
|
+
end
|
47
|
+
|
48
|
+
desc "Run tests with and without mocking."
|
49
|
+
replace_task :test do
|
50
|
+
hoe.run_tests
|
51
|
+
|
52
|
+
ENV["SPREEDLY_TEST"] = "REAL"
|
53
|
+
hoe.run_tests
|
54
|
+
end
|
55
|
+
|
56
|
+
desc "Run only mock tests."
|
57
|
+
task :test_mock do
|
58
|
+
hoe.run_tests
|
59
|
+
end
|
60
|
+
|
61
|
+
desc "Run only real tests."
|
62
|
+
task :test_real do
|
63
|
+
ENV["SPREEDLY_TEST"] = "REAL"
|
64
|
+
hoe.run_tests
|
65
|
+
end
|
66
|
+
|
67
|
+
desc "Run both sets of tests under multiruby"
|
68
|
+
replace_task :multi do
|
69
|
+
hoe.run_tests(true)
|
70
|
+
ENV["SPREEDLY_TEST"] = "REAL"
|
71
|
+
hoe.run_tests(true)
|
72
|
+
end
|
data/lib/spreedly.rb
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
require 'spreedly/common'
|
2
|
+
require 'httparty'
|
3
|
+
|
4
|
+
raise "Mock Spreedly already required!" if defined?(Spreedly::MOCK)
|
5
|
+
|
6
|
+
=begin rdoc
|
7
|
+
Provides a convenient wrapper around the http://spreedly.com API.
|
8
|
+
Instead of mucking around with http you can just Spreedly.configure
|
9
|
+
and Spreedly::Subscriber.find. Much of the functionality is hung off
|
10
|
+
of the Spreedly::Subscriber class, and there's also a
|
11
|
+
Spreedly::SubscriptionPlan class.
|
12
|
+
|
13
|
+
One of the goals of this wrapper is to keep your tests fast while
|
14
|
+
also keeping your app working. It does this by providing a drop-in
|
15
|
+
replacement for the real Spreedly functionality that skips the
|
16
|
+
network and gives you a simple (some might call it stupid)
|
17
|
+
implementation that will work for 90% of your tests. At least we
|
18
|
+
hope so.
|
19
|
+
|
20
|
+
Help us make the mock work better by telling us when it doesn't work
|
21
|
+
so we can improve it. Thanks!
|
22
|
+
|
23
|
+
==Example mock usage:
|
24
|
+
|
25
|
+
if ENV["SPREEDLY"] == "REAL"
|
26
|
+
require 'spreedly'
|
27
|
+
else
|
28
|
+
require 'spreedly/mock'
|
29
|
+
end
|
30
|
+
=end
|
31
|
+
|
32
|
+
module Spreedly
|
33
|
+
REAL = "real" # :nodoc:
|
34
|
+
|
35
|
+
include HTTParty
|
36
|
+
headers 'Accept' => 'text/xml'
|
37
|
+
headers 'Content-Type' => 'text/xml'
|
38
|
+
format :xml
|
39
|
+
|
40
|
+
# Call this before you start using the API to set things up.
|
41
|
+
def self.configure(site_name, token)
|
42
|
+
base_uri "https://spreedly.com/api/v4/#{site_name}"
|
43
|
+
basic_auth token, 'X'
|
44
|
+
@site_name = site_name
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.site_name # :nodoc:
|
48
|
+
@site_name
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.to_xml_params(hash) # :nodoc:
|
52
|
+
hash.collect do |key, value|
|
53
|
+
tag = key.to_s.tr('_', '-')
|
54
|
+
result = "<#{tag}>"
|
55
|
+
if value.is_a?(Hash)
|
56
|
+
result << to_xml_params(value)
|
57
|
+
else
|
58
|
+
result << value.to_s
|
59
|
+
end
|
60
|
+
result << "</#{tag}>"
|
61
|
+
result
|
62
|
+
end.join('')
|
63
|
+
end
|
64
|
+
|
65
|
+
class Resource # :nodoc: all
|
66
|
+
def initialize(data)
|
67
|
+
@data = data
|
68
|
+
end
|
69
|
+
|
70
|
+
def method_missing(method, *args, &block)
|
71
|
+
if method.to_s =~ /\?$/
|
72
|
+
send(method.to_s[0..-2])
|
73
|
+
elsif @data.include?(method.to_s)
|
74
|
+
@data[method.to_s]
|
75
|
+
else
|
76
|
+
super
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class Subscriber < Resource
|
82
|
+
|
83
|
+
# This will DELETE all the subscribers from the site.
|
84
|
+
#
|
85
|
+
# Only works for tests sites (enforced on the Spreedly side).
|
86
|
+
def self.wipe!
|
87
|
+
Spreedly.delete('/subscribers.xml')
|
88
|
+
end
|
89
|
+
|
90
|
+
# Creates a new subscriber on Spreedly. The subscriber will NOT
|
91
|
+
# be active - they have to pay or you have to comp them for that
|
92
|
+
# to happen.
|
93
|
+
def self.create!(id, email=nil, screen_name=nil)
|
94
|
+
result = Spreedly.post('/subscribers.xml', :body =>
|
95
|
+
Spreedly.to_xml_params(:subscriber => {:customer_id => id, :email => email, :screen_name => screen_name}))
|
96
|
+
case result.code
|
97
|
+
when /2../
|
98
|
+
new(result['subscriber'])
|
99
|
+
when '403'
|
100
|
+
raise "Could not create subscriber: no id passed OR already exists."
|
101
|
+
else
|
102
|
+
raise "Could not create subscriber: result code #{result.code}."
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Looks a subscriber up by id.
|
107
|
+
def self.find(id)
|
108
|
+
new(Spreedly.get("/subscribers/#{id}.xml")['subscriber'])
|
109
|
+
end
|
110
|
+
|
111
|
+
# Returns all the subscribers in your site.
|
112
|
+
def self.all
|
113
|
+
Spreedly.get('/subscribers.xml')['subscribers'].collect{|data| new(data)}
|
114
|
+
end
|
115
|
+
|
116
|
+
# Spreedly calls your id for the user the "customer id". This
|
117
|
+
# gives you a handy alias so you can just call it "id".
|
118
|
+
def id
|
119
|
+
customer_id
|
120
|
+
end
|
121
|
+
|
122
|
+
# Allows you to give a complimentary subscription (if the
|
123
|
+
# subscriber is inactive) or a complimentary time extension (if
|
124
|
+
# the subscriber is inactive). Automatically figures out which
|
125
|
+
# to do.
|
126
|
+
#
|
127
|
+
# Note: units must be one of "days" or "months" (Spreedly
|
128
|
+
# enforced).
|
129
|
+
def comp(quantity, units, feature_level=nil)
|
130
|
+
params = {:duration_quantity => quantity, :duration_units => units}
|
131
|
+
params[:feature_level] = feature_level if feature_level
|
132
|
+
endpoint = (active? ? "complimentary_time_extensions" : "complimentary_subscriptions")
|
133
|
+
result = Spreedly.post("/subscribers/#{id}/#{endpoint}.xml", :body => Spreedly.to_xml_params(endpoint[0..-2] => params))
|
134
|
+
case result.code
|
135
|
+
when /2../
|
136
|
+
when '404'
|
137
|
+
raise "Could not comp subscriber: no longer exists."
|
138
|
+
when '422'
|
139
|
+
raise "Could not comp subscriber: validation failed."
|
140
|
+
when '403'
|
141
|
+
raise "Could not comp subscriber: invalid comp type (#{endpoint})."
|
142
|
+
else
|
143
|
+
raise "Could not comp subscriber: result code #{result.code}."
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
class SubscriptionPlan < Resource
|
149
|
+
# Returns all of the subscription plans defined in your site.
|
150
|
+
def self.all
|
151
|
+
Spreedly.get('/subscription_plans.xml')['subscription_plans'].collect{|data| new(data)}
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
Dir[File.dirname(__FILE__) + '/../../vendor/*'].each do |directory|
|
2
|
+
next unless File.directory?(directory)
|
3
|
+
$LOAD_PATH.unshift File.expand_path(directory + '/lib')
|
4
|
+
end
|
5
|
+
|
6
|
+
require 'uri'
|
7
|
+
require 'bigdecimal'
|
8
|
+
|
9
|
+
require 'spreedly/version'
|
10
|
+
|
11
|
+
module Spreedly
|
12
|
+
# Generates a subscribe url for the given user id and plan.
|
13
|
+
def self.subscribe_url(id, plan, screen_name=nil)
|
14
|
+
screen_name = (screen_name ? URI.escape(screen_name) : "")
|
15
|
+
"https://spreedly.com/#{site_name}/subscribers/#{id}/subscribe/#{plan}/#{screen_name}"
|
16
|
+
end
|
17
|
+
|
18
|
+
# Generates an edit subscriber for the given subscriber token. The
|
19
|
+
# token is returned with the subscriber info (i.e. by
|
20
|
+
# Subscriber.find).
|
21
|
+
def self.edit_subscriber_url(token)
|
22
|
+
"https://spreedly.com/#{site_name}/subscriber_accounts/#{token}"
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'spreedly/common'
|
2
|
+
|
3
|
+
raise "Real Spreedly already required!" if defined?(Spreedly::REAL)
|
4
|
+
|
5
|
+
module Spreedly
|
6
|
+
MOCK = "mock"
|
7
|
+
|
8
|
+
def self.configure(name, token)
|
9
|
+
@site_name = name
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.site_name
|
13
|
+
@site_name
|
14
|
+
end
|
15
|
+
|
16
|
+
class Resource
|
17
|
+
def self.attributes
|
18
|
+
@attributes ||= {}
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.attributes=(value)
|
22
|
+
@attributes = value
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(params={})
|
26
|
+
@attributes = params
|
27
|
+
self.class.attributes.each{|k,v| @attributes[k] = v.call}
|
28
|
+
end
|
29
|
+
|
30
|
+
def id
|
31
|
+
@attributes[:id]
|
32
|
+
end
|
33
|
+
|
34
|
+
def method_missing(method, *args)
|
35
|
+
if method.to_s =~ /\?$/
|
36
|
+
send(method.to_s[0..-2], *args)
|
37
|
+
elsif @attributes.include?(method)
|
38
|
+
@attributes[method]
|
39
|
+
else
|
40
|
+
super
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class Subscriber < Resource
|
46
|
+
self.attributes = {
|
47
|
+
:created_at => proc{Time.now},
|
48
|
+
:token => proc{(rand * 1000).round},
|
49
|
+
:active => proc{false},
|
50
|
+
:store_credit => proc{BigDecimal("0.0")},
|
51
|
+
:active_until => proc{nil},
|
52
|
+
:feature_level => proc{""},
|
53
|
+
}
|
54
|
+
|
55
|
+
def self.wipe! # :nodoc: all
|
56
|
+
@subscribers = nil
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.create!(id, email=nil, screen_name=nil) # :nodoc: all
|
60
|
+
sub = new({:id => id, :email => email, :screen_name => screen_name})
|
61
|
+
|
62
|
+
if subscribers[sub.id]
|
63
|
+
raise "Could not create subscriber: already exists."
|
64
|
+
end
|
65
|
+
|
66
|
+
subscribers[sub.id] = sub
|
67
|
+
sub
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.find(id)
|
71
|
+
subscribers[id]
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.subscribers
|
75
|
+
@subscribers ||= {}
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.all
|
79
|
+
@subscribers.values
|
80
|
+
end
|
81
|
+
|
82
|
+
def initialize(params={})
|
83
|
+
super
|
84
|
+
if !id || id == ''
|
85
|
+
raise "Could not create subscriber: no id passed OR already exists."
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def comp(quantity, units, feature_level=nil)
|
90
|
+
raise "Could not comp subscriber: no longer exists." unless self.class.find(id)
|
91
|
+
raise "Could not comp subscriber: validation failed." unless units && quantity
|
92
|
+
current_active_until = (active_until || Time.now)
|
93
|
+
@attributes[:active_until] = case units
|
94
|
+
when 'days'
|
95
|
+
current_active_until + (quantity.to_i * 86400)
|
96
|
+
when 'months'
|
97
|
+
current_active_until + (quantity.to_i * 30 * 86400)
|
98
|
+
end
|
99
|
+
@attributes[:feature_level] = feature_level if feature_level
|
100
|
+
@attributes[:active] = true
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class SubscriptionPlan < Resource
|
105
|
+
def self.all
|
106
|
+
plans.values
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.plans
|
110
|
+
@plans ||= {1 => new(:id => 1, :name => 'Default mock plan')}
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|