spreedly 1.0.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/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
|