subscribed_to 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +18 -0
- data/Gemfile.lock +121 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +113 -0
- data/Rakefile +46 -0
- data/lib/generators/subscribed_to/USAGE +9 -0
- data/lib/generators/subscribed_to/install_generator.rb +34 -0
- data/lib/generators/subscribed_to/templates/migration.rb +9 -0
- data/lib/generators/subscribed_to/templates/subscribed_to.rb +21 -0
- data/lib/subscribed_to/mail_chimp/config.rb +29 -0
- data/lib/subscribed_to/mail_chimp.rb +51 -0
- data/lib/subscribed_to/version.rb +10 -0
- data/lib/subscribed_to.rb +81 -0
- data/spec/app/models/user.rb +43 -0
- data/spec/database.yml.example +17 -0
- data/spec/factories/users.rb +15 -0
- data/spec/generators/install_generator_spec.rb +34 -0
- data/spec/schema.rb +9 -0
- data/spec/spec_helper.rb +48 -0
- data/spec/subscribed_to/mail_chimp/config_spec.rb +21 -0
- data/spec/subscribed_to/mail_chimp_spec.rb +53 -0
- data/spec/subscribed_to_spec.rb +50 -0
- metadata +203 -0
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
gem "activerecord"
|
4
|
+
gem "hominid", ">= 3.0.2"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "sqlite3-ruby", :require => "sqlite3"
|
10
|
+
gem "factory_girl_rails", "1.0.1"
|
11
|
+
gem "mocha", "0.9.12"
|
12
|
+
gem "rspec-rails", "2.5.0"
|
13
|
+
gem "generator_spec"
|
14
|
+
gem "bundler", "~> 1.0.0"
|
15
|
+
gem "jeweler", "~> 1.6.0"
|
16
|
+
gem "simplecov", ">=0.4.0"
|
17
|
+
gem "hanna"
|
18
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
abstract (1.0.0)
|
5
|
+
actionmailer (3.0.7)
|
6
|
+
actionpack (= 3.0.7)
|
7
|
+
mail (~> 2.2.15)
|
8
|
+
actionpack (3.0.7)
|
9
|
+
activemodel (= 3.0.7)
|
10
|
+
activesupport (= 3.0.7)
|
11
|
+
builder (~> 2.1.2)
|
12
|
+
erubis (~> 2.6.6)
|
13
|
+
i18n (~> 0.5.0)
|
14
|
+
rack (~> 1.2.1)
|
15
|
+
rack-mount (~> 0.6.14)
|
16
|
+
rack-test (~> 0.5.7)
|
17
|
+
tzinfo (~> 0.3.23)
|
18
|
+
activemodel (3.0.7)
|
19
|
+
activesupport (= 3.0.7)
|
20
|
+
builder (~> 2.1.2)
|
21
|
+
i18n (~> 0.5.0)
|
22
|
+
activerecord (3.0.7)
|
23
|
+
activemodel (= 3.0.7)
|
24
|
+
activesupport (= 3.0.7)
|
25
|
+
arel (~> 2.0.2)
|
26
|
+
tzinfo (~> 0.3.23)
|
27
|
+
activeresource (3.0.7)
|
28
|
+
activemodel (= 3.0.7)
|
29
|
+
activesupport (= 3.0.7)
|
30
|
+
activesupport (3.0.7)
|
31
|
+
arel (2.0.9)
|
32
|
+
builder (2.1.2)
|
33
|
+
diff-lcs (1.1.2)
|
34
|
+
erubis (2.6.6)
|
35
|
+
abstract (>= 1.0.0)
|
36
|
+
factory_girl (1.3.3)
|
37
|
+
factory_girl_rails (1.0.1)
|
38
|
+
factory_girl (~> 1.3)
|
39
|
+
railties (>= 3.0.0)
|
40
|
+
generator_spec (0.8.3)
|
41
|
+
rails (~> 3.0)
|
42
|
+
rspec-rails
|
43
|
+
git (1.2.5)
|
44
|
+
haml (2.2.24)
|
45
|
+
hanna (0.1.12)
|
46
|
+
haml (~> 2.2.8)
|
47
|
+
rake (~> 0.8.2)
|
48
|
+
rdoc (~> 2.3.0)
|
49
|
+
hominid (3.0.2)
|
50
|
+
i18n (0.5.0)
|
51
|
+
jeweler (1.6.0)
|
52
|
+
bundler (~> 1.0.0)
|
53
|
+
git (>= 1.2.5)
|
54
|
+
rake
|
55
|
+
mail (2.2.19)
|
56
|
+
activesupport (>= 2.3.6)
|
57
|
+
i18n (>= 0.4.0)
|
58
|
+
mime-types (~> 1.16)
|
59
|
+
treetop (~> 1.4.8)
|
60
|
+
mime-types (1.16)
|
61
|
+
mocha (0.9.12)
|
62
|
+
polyglot (0.3.1)
|
63
|
+
rack (1.2.2)
|
64
|
+
rack-mount (0.6.14)
|
65
|
+
rack (>= 1.0.0)
|
66
|
+
rack-test (0.5.7)
|
67
|
+
rack (>= 1.0)
|
68
|
+
rails (3.0.7)
|
69
|
+
actionmailer (= 3.0.7)
|
70
|
+
actionpack (= 3.0.7)
|
71
|
+
activerecord (= 3.0.7)
|
72
|
+
activeresource (= 3.0.7)
|
73
|
+
activesupport (= 3.0.7)
|
74
|
+
bundler (~> 1.0)
|
75
|
+
railties (= 3.0.7)
|
76
|
+
railties (3.0.7)
|
77
|
+
actionpack (= 3.0.7)
|
78
|
+
activesupport (= 3.0.7)
|
79
|
+
rake (>= 0.8.7)
|
80
|
+
thor (~> 0.14.4)
|
81
|
+
rake (0.8.7)
|
82
|
+
rdoc (2.3.0)
|
83
|
+
rspec (2.5.0)
|
84
|
+
rspec-core (~> 2.5.0)
|
85
|
+
rspec-expectations (~> 2.5.0)
|
86
|
+
rspec-mocks (~> 2.5.0)
|
87
|
+
rspec-core (2.5.2)
|
88
|
+
rspec-expectations (2.5.0)
|
89
|
+
diff-lcs (~> 1.1.2)
|
90
|
+
rspec-mocks (2.5.0)
|
91
|
+
rspec-rails (2.5.0)
|
92
|
+
actionpack (~> 3.0)
|
93
|
+
activesupport (~> 3.0)
|
94
|
+
railties (~> 3.0)
|
95
|
+
rspec (~> 2.5.0)
|
96
|
+
simplecov (0.4.2)
|
97
|
+
simplecov-html (~> 0.4.4)
|
98
|
+
simplecov-html (0.4.5)
|
99
|
+
sqlite3 (1.3.3)
|
100
|
+
sqlite3-ruby (1.3.3)
|
101
|
+
sqlite3 (>= 1.3.3)
|
102
|
+
thor (0.14.6)
|
103
|
+
treetop (1.4.9)
|
104
|
+
polyglot (>= 0.3.1)
|
105
|
+
tzinfo (0.3.27)
|
106
|
+
|
107
|
+
PLATFORMS
|
108
|
+
ruby
|
109
|
+
|
110
|
+
DEPENDENCIES
|
111
|
+
activerecord
|
112
|
+
bundler (~> 1.0.0)
|
113
|
+
factory_girl_rails (= 1.0.1)
|
114
|
+
generator_spec
|
115
|
+
hanna
|
116
|
+
hominid (>= 3.0.2)
|
117
|
+
jeweler (~> 1.6.0)
|
118
|
+
mocha (= 0.9.12)
|
119
|
+
rspec-rails (= 2.5.0)
|
120
|
+
simplecov (>= 0.4.0)
|
121
|
+
sqlite3-ruby
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 whtt-eric
|
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,113 @@
|
|
1
|
+
= SubscribedTo
|
2
|
+
|
3
|
+
Abstraction layer for managing mailing list subscription information for your user model. It makes the basic mailing list management tasks super simple.
|
4
|
+
|
5
|
+
The gem creates callbacks on your model for <tt>after_create</tt> and <tt>after_update</tt>.
|
6
|
+
|
7
|
+
The <tt>after_create</tt> callback registers the user for the mailing list if <tt>subscribed_to_list</tt> is true (ie: the user chooses checks the "Join the mailing list" box on the registration form).
|
8
|
+
|
9
|
+
The <tt>after_update</tt> callback will update the user subscription or member details. It will either:
|
10
|
+
|
11
|
+
* Unsubscribe the user from the mailing list if they have so requested
|
12
|
+
* Subscribe the user to the list if they weren't already subscribed
|
13
|
+
* Update the user's member subscription details on the mailing list for any specified <tt>merge_vars</tt> when they change
|
14
|
+
* Do nothing if neither the subscription status nor the attributes specified in the <tt>merge_vars</tt> hash change
|
15
|
+
|
16
|
+
=== Requirements
|
17
|
+
|
18
|
+
* Rails 3.x
|
19
|
+
|
20
|
+
=== Supported Services
|
21
|
+
|
22
|
+
<b>MailChimp</b>
|
23
|
+
|
24
|
+
via the Hominid gem - http://github.com/terra-firma/hominid
|
25
|
+
|
26
|
+
API v1.3 - http://apidocs.mailchimp.com/1.3
|
27
|
+
|
28
|
+
* listSubscribe
|
29
|
+
* listUnsubscribe
|
30
|
+
* listUpdateMember
|
31
|
+
|
32
|
+
|
33
|
+
<b>Constant Contact</b>
|
34
|
+
|
35
|
+
Planned
|
36
|
+
|
37
|
+
== Installation
|
38
|
+
|
39
|
+
Add the gem to your Gemfile
|
40
|
+
|
41
|
+
gem "subscribed_to"
|
42
|
+
|
43
|
+
Install the gem using bundler
|
44
|
+
|
45
|
+
bundle install
|
46
|
+
|
47
|
+
Run the generator. You must specify the name of your user model.
|
48
|
+
Other options:
|
49
|
+
|
50
|
+
<tt>--skip-migration</tt>:: Do not generate the migration file to add the required column
|
51
|
+
<tt>--service=SERVICE</tt>:: Specify which mailing list service you subscribe to (currently only supports "mail_chimp")
|
52
|
+
|
53
|
+
rails generate subscribed_to:install MODEL
|
54
|
+
|
55
|
+
If you run the generator with <tt>--skip-migration</tt>, then you must be sure to to include the <tt>subscribed_to_list</tt> column in some other migration.
|
56
|
+
|
57
|
+
t.boolean :subscribed_to_list, :default => false
|
58
|
+
|
59
|
+
Be sure to run the migration before you continue.
|
60
|
+
|
61
|
+
=== Initializer Configuration
|
62
|
+
|
63
|
+
After the initializer has been generated, you must set your mail service configuration options. The initializer is located at: <tt>config/initializers/subscribe_to.rb</tt>
|
64
|
+
|
65
|
+
==== Mail Chimp
|
66
|
+
|
67
|
+
Set your API key
|
68
|
+
|
69
|
+
mail_chimp_config.api_key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-us1"
|
70
|
+
|
71
|
+
Set up your mailing lists to subscribe users to. List names can be any valid symbol.
|
72
|
+
|
73
|
+
<tt>:id</tt>:: id of list - get this from the "Settings" page of your list
|
74
|
+
<tt>:merge_vars</tt>:: hash of merge vars on list. The key is a string which corresponds to a merge var on your mailing list. The value is a symbol corresponding to the attribute/method on the user model related to the specified merge var. It MUST at least include "EMAIL" (do not use "MERGE0").
|
75
|
+
|
76
|
+
mail_chimp_config.lists = {
|
77
|
+
:mailing_list => {
|
78
|
+
:id => "xxxxxxxx",
|
79
|
+
:merge_vars => {"FNAME" => :first_name, "LNAME" => :last_name, "EMAIL" => :email}}}
|
80
|
+
|
81
|
+
=== User Model Configuration
|
82
|
+
|
83
|
+
You must enable *SubscribedTo* in your user model with <tt>subscribed_to</tt>.
|
84
|
+
|
85
|
+
The only paramter it takes is a symbol which corresponds to a list in the <tt>mail_chimp_config.lists</tt> hash.
|
86
|
+
|
87
|
+
subscribed_to :mailing_list
|
88
|
+
|
89
|
+
You may also need to specify <tt>subscribed_to_list</tt> as an accessible attribute.
|
90
|
+
|
91
|
+
attr_accessible :subscribed_to_list
|
92
|
+
|
93
|
+
=== View Configuration
|
94
|
+
|
95
|
+
To get things working with the view, just include a checkbox input on your user registration/edit forms.
|
96
|
+
|
97
|
+
= f.check_box :subscribed_to_list
|
98
|
+
= f.label :subscribed_to_list, "Join the mailing list"
|
99
|
+
|
100
|
+
== Contributing to subscribed_to
|
101
|
+
|
102
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
103
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
104
|
+
* Fork the project
|
105
|
+
* Start a feature/bugfix branch
|
106
|
+
* Commit and push until you are happy with your contribution
|
107
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
108
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
109
|
+
|
110
|
+
== Copyright
|
111
|
+
|
112
|
+
Copyright (c) 2011 Eric Salczynski. See LICENSE.txt for further details.
|
113
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
require './lib/subscribed_to/version.rb'
|
16
|
+
Jeweler::Tasks.new do |gem|
|
17
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
18
|
+
gem.name = "subscribed_to"
|
19
|
+
gem.homepage = "http://github.com/whtt-eric/subscribed_to"
|
20
|
+
gem.license = "MIT"
|
21
|
+
gem.summary = %Q{Abstract layer for managing mailing list subscriptions}
|
22
|
+
gem.description = %Q{Abstract layer for managing mailing list subscriptions}
|
23
|
+
gem.email = "eric@wehaventthetime.com"
|
24
|
+
gem.authors = ["whtt-eric"]
|
25
|
+
gem.version = SubscribedTo::Version::STRING
|
26
|
+
# dependencies defined in Gemfile
|
27
|
+
end
|
28
|
+
Jeweler::RubygemsDotOrgTasks.new
|
29
|
+
|
30
|
+
require 'rspec/core'
|
31
|
+
require 'rspec/core/rake_task'
|
32
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
33
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
34
|
+
end
|
35
|
+
|
36
|
+
task :default => :spec
|
37
|
+
|
38
|
+
require 'hanna/rdoctask'
|
39
|
+
Rake::RDocTask.new do |rdoc|
|
40
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
41
|
+
|
42
|
+
rdoc.rdoc_dir = 'rdoc'
|
43
|
+
rdoc.title = "subscribed_to #{version}"
|
44
|
+
rdoc.rdoc_files.include('README*')
|
45
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
46
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module SubscribedTo
|
2
|
+
module Generators #:nodoc:
|
3
|
+
class InstallGenerator < Rails::Generators::NamedBase #:nodoc:
|
4
|
+
include Rails::Generators::Migration
|
5
|
+
source_root File.expand_path('../templates', __FILE__)
|
6
|
+
|
7
|
+
desc "Create SubscribedTo initializer and migration. Pass the name of the model to hook up with SubscribedTo."
|
8
|
+
class_option :migration, :type => :boolean, :default => true, :desc => "Include migration for required columns"
|
9
|
+
class_option :service, :type => :string, :default => "mail_chimp", :desc => "Mailing list service to connect to [mail_chimp, constant_contact]"
|
10
|
+
|
11
|
+
def self.next_migration_number(dirname)
|
12
|
+
@next_migration_number ||= Time.now.strftime("%Y%m%d%H%M%S")
|
13
|
+
end
|
14
|
+
|
15
|
+
def copy_initializer
|
16
|
+
template "subscribed_to.rb", "config/initializers/subscribed_to.rb"
|
17
|
+
end
|
18
|
+
|
19
|
+
def copy_migration
|
20
|
+
migration_template "migration.rb", "db/migrate/#{migration_name}" if options.migration?
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def migration_name
|
26
|
+
"add_subscribed_to_list_to_#{table_name}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def table_name
|
30
|
+
name.tableize
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class <%= migration_name.camelize %> < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
add_column :<%= table_name.to_sym %>, :subscribed_to_list, :boolean, :default => false
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.down
|
7
|
+
remove_column :<%= table_name.to_sym %>, :subscribed_to_list
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
SubscribedTo.setup do |config|
|
2
|
+
config.service = :<%= options.service.to_sym %>
|
3
|
+
|
4
|
+
<%- if options.service == "mail_chimp" -%>
|
5
|
+
config.mail_chimp do |mail_chimp_config|
|
6
|
+
# Your MailChimp API key.
|
7
|
+
mail_chimp_config.api_key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-us1"
|
8
|
+
|
9
|
+
# A hash of mailing lists to subscribe users to.
|
10
|
+
# List names can be any valid symbol.
|
11
|
+
#
|
12
|
+
# Required:
|
13
|
+
# :id - id of list
|
14
|
+
# :merge_vars - hash of merge vars on list, MUST at least include "EMAIL" (do not use "MERGE0")
|
15
|
+
mail_chimp_config.lists = {
|
16
|
+
:mailing_list => {
|
17
|
+
:id => "xxxxxxxx",
|
18
|
+
:merge_vars => {"FNAME" => :first_name, "LNAME" => :last_name, "EMAIL" => :email}}}
|
19
|
+
end
|
20
|
+
<%- end -%>
|
21
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module SubscribedTo
|
2
|
+
module MailChimp
|
3
|
+
class Config < Hash #:nodoc:
|
4
|
+
# Creates an accessor that simply sets and reads a key in the hash:
|
5
|
+
# Borrowed from Warden: https://github.com/hassox/warden/blob/master/lib/warden/config.rb
|
6
|
+
def self.hash_accessor(*names) #:nodoc:
|
7
|
+
names.each do |name|
|
8
|
+
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
9
|
+
def #{name}
|
10
|
+
self[:#{name}]
|
11
|
+
end
|
12
|
+
|
13
|
+
def #{name}=(value)
|
14
|
+
self[:#{name}] = value
|
15
|
+
end
|
16
|
+
METHOD
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
hash_accessor :api_key, :lists
|
21
|
+
|
22
|
+
def initialize(config = {})
|
23
|
+
merge!(config)
|
24
|
+
self[:api_key] ||= nil
|
25
|
+
self[:lists] ||= {}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'subscribed_to/mail_chimp/config'
|
2
|
+
require 'hominid'
|
3
|
+
|
4
|
+
module SubscribedTo
|
5
|
+
# Module for MailChimp subscription interaction
|
6
|
+
module MailChimp
|
7
|
+
module InstanceMethods
|
8
|
+
private
|
9
|
+
|
10
|
+
# Subscribe the user to the mailing list
|
11
|
+
def subscribe_to_list #:doc:
|
12
|
+
merge_vars = self.class.merge_vars.dup
|
13
|
+
|
14
|
+
if subscribed_to_list
|
15
|
+
h = Hominid::API.new(SubscribedTo.mail_chimp_config.api_key)
|
16
|
+
h.list_subscribe(self.class.list_id, self.email, merge_vars.each { |key, method| merge_vars[key] = self.send(method.to_sym) })
|
17
|
+
end
|
18
|
+
rescue Hominid::APIError => e
|
19
|
+
Rails.logger.warn e
|
20
|
+
end
|
21
|
+
|
22
|
+
# Update attributes of existing member
|
23
|
+
def update_list_member #:doc:
|
24
|
+
config = SubscribedTo.mail_chimp_config
|
25
|
+
merge_vars = self.class.merge_vars.dup
|
26
|
+
|
27
|
+
# only do the update if either the subscription preference has changed (the user wants to be (un)subscribed),
|
28
|
+
# or if one of the attributes in mail_chimp_config.merge_vars has changed
|
29
|
+
if !(self.changed & merge_vars.collect { |key, method| method.to_s }.push("subscribed_to_list")).empty?
|
30
|
+
api_key = config.api_key
|
31
|
+
list_id = self.class.list_id
|
32
|
+
email_attr = merge_vars["EMAIL"]
|
33
|
+
subscribed_email = self.changed.include?(email_attr.to_s) ? changed_attributes[email_attr.to_s] : self.send(email_attr)
|
34
|
+
h = Hominid::API.new(api_key)
|
35
|
+
|
36
|
+
if self.changed.include?("subscribed_to_list")
|
37
|
+
if !subscribed_to_list
|
38
|
+
h.list_unsubscribe(list_id, subscribed_email)
|
39
|
+
else
|
40
|
+
h.list_subscribe(list_id, subscribed_email, merge_vars.each { |key, method| merge_vars[key] = self.send(method.to_sym) })
|
41
|
+
end
|
42
|
+
elsif subscribed_to_list && !(self.changed & merge_vars.collect { |key, method| method.to_s }).empty?
|
43
|
+
h.listUpdateMember(list_id, subscribed_email, merge_vars.each { |key, method| merge_vars[key] = self.send(method.to_sym) })
|
44
|
+
end
|
45
|
+
end
|
46
|
+
rescue Hominid::APIError => e
|
47
|
+
Rails.logger.warn e
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'rails'
|
2
|
+
require 'active_record'
|
3
|
+
require 'subscribed_to/mail_chimp'
|
4
|
+
|
5
|
+
module SubscribedTo
|
6
|
+
# Mailing list service to interact with.
|
7
|
+
# Options: :mail_chimp, :constant_contact
|
8
|
+
# Currently only supports Mail Chimp
|
9
|
+
mattr_accessor :service
|
10
|
+
@@service = :mail_chimp
|
11
|
+
|
12
|
+
mattr_reader :mail_chimp_config
|
13
|
+
@@mail_chimp_config = nil
|
14
|
+
|
15
|
+
# Set up SubscribedTo
|
16
|
+
def self.setup
|
17
|
+
yield self
|
18
|
+
end
|
19
|
+
|
20
|
+
# Sets Mail Chimp configuration using a block
|
21
|
+
#
|
22
|
+
# Example configuration:
|
23
|
+
# SubscribedTo.setup do |config|
|
24
|
+
# config.service = :mail_chimp
|
25
|
+
#
|
26
|
+
# config.mail_chimp do |mail_chimp_config|
|
27
|
+
# mail_chimp_config.api_key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-us1"
|
28
|
+
# mail_chimp_config.lists = {:mailing_list => {:id => "123456", :merge_vars => {"FNAME" => :first_name}
|
29
|
+
# end
|
30
|
+
# end
|
31
|
+
def self.mail_chimp(&block)
|
32
|
+
@@mail_chimp_config = SubscribedTo::MailChimp::Config.new
|
33
|
+
block.call @@mail_chimp_config
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.included(base) #:nodoc:
|
37
|
+
base.send :extend, ClassMethods
|
38
|
+
end
|
39
|
+
|
40
|
+
module ClassMethods
|
41
|
+
# Enable *SubscribedTo* in your user model.
|
42
|
+
# The only paramter it takes is a symbol which corresponds to a list in the <tt>mail_chimp_config.lists</tt> hash.
|
43
|
+
# subscribed_to :mailing_list
|
44
|
+
def subscribed_to(id)
|
45
|
+
include InstanceMethods
|
46
|
+
include MailChimp::InstanceMethods if SubscribedTo.service == :mail_chimp
|
47
|
+
|
48
|
+
@list_key = id.to_sym
|
49
|
+
|
50
|
+
class_eval do
|
51
|
+
after_create :subscribe_to_list
|
52
|
+
after_update :update_list_member
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Returns the list id for the class as defined in mail_chimp
|
57
|
+
def list_id
|
58
|
+
SubscribedTo.mail_chimp_config.lists[@list_key][:id]
|
59
|
+
end
|
60
|
+
|
61
|
+
# Returns the hash of merge vars for the class as defined in mail_chimp
|
62
|
+
def merge_vars
|
63
|
+
SubscribedTo.mail_chimp_config.lists[@list_key][:merge_vars]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Provides instance methods which should be overwritten in service modules
|
68
|
+
module InstanceMethods
|
69
|
+
private
|
70
|
+
|
71
|
+
# Override in MailChimp module
|
72
|
+
def subscribe_to_list
|
73
|
+
end
|
74
|
+
|
75
|
+
# Override in MailChimp module
|
76
|
+
def update_list_member
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
ActiveRecord::Base.send :include, SubscribedTo
|
@@ -0,0 +1,43 @@
|
|
1
|
+
class User < ActiveRecord::Base
|
2
|
+
subscribed_to :mailing_list
|
3
|
+
end
|
4
|
+
|
5
|
+
class MailChimpUser < User
|
6
|
+
subscribed_to :mailing_list
|
7
|
+
|
8
|
+
attr_accessor :callback_result
|
9
|
+
|
10
|
+
# Stubbed for testing
|
11
|
+
def subscribe_to_list
|
12
|
+
if subscribed_to_list
|
13
|
+
merge_vars = self.class.merge_vars.dup
|
14
|
+
|
15
|
+
# use hominid to subscribe user
|
16
|
+
self.callback_result = "Subscribed with: #{merge_vars.each { |key, method| merge_vars[key] = self.send(method.to_sym) }.values.join(", ")}"
|
17
|
+
else # mocked for test -- subscribed_to_list normally doesn't do anything if !subscribed_to_list
|
18
|
+
self.callback_result = "Not Subscribed"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Stubbed for testing
|
23
|
+
def update_list_member
|
24
|
+
merge_vars = self.class.merge_vars.dup
|
25
|
+
|
26
|
+
if !(self.changed & merge_vars.collect { |key, method| method.to_s }.push("subscribed_to_list")).empty?
|
27
|
+
if self.changed.include?("subscribed_to_list")
|
28
|
+
if !subscribed_to_list
|
29
|
+
# use hominid to unsubscribe user
|
30
|
+
self.callback_result = "Unsubscribed"
|
31
|
+
else
|
32
|
+
# use hominid to subscribe user
|
33
|
+
self.callback_result = "Subscribed with: #{merge_vars.each { |key, method| merge_vars[key] = self.send(method.to_sym) }.values.join(", ")}"
|
34
|
+
end
|
35
|
+
elsif subscribed_to_list && !(self.changed & merge_vars.collect { |key, method| method.to_s }).empty?
|
36
|
+
# use hominid to update user
|
37
|
+
self.callback_result = "Updated with: #{merge_vars.each { |key, method| merge_vars[key] = self.send(method.to_sym) }.values.join(", ")}"
|
38
|
+
end
|
39
|
+
else # mocked for test -- update_list_member normally doesn't do anything in this case
|
40
|
+
self.callback_result = "Nothing updated"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
sqlite3:
|
2
|
+
adapter: sqlite3
|
3
|
+
database: subscribed_to.sqlite3
|
4
|
+
|
5
|
+
mysql:
|
6
|
+
adapter: mysql
|
7
|
+
hostname: localhost
|
8
|
+
username: root
|
9
|
+
password:
|
10
|
+
database: subscribed_to
|
11
|
+
|
12
|
+
postgresql:
|
13
|
+
adapter: postgresql
|
14
|
+
hostname: localhost
|
15
|
+
username: postgres
|
16
|
+
password:
|
17
|
+
database: subscribed_to
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Factory.define :subscribed_user, :class => User do |u|
|
2
|
+
u.first_name "Eric"
|
3
|
+
u.last_name "Salczynski"
|
4
|
+
u.email "eric@wehaventthetime.com"
|
5
|
+
u.subscribed_to_list true
|
6
|
+
u.password "abc123"
|
7
|
+
end
|
8
|
+
|
9
|
+
Factory.define :non_subscribed_user, :class => User do |u|
|
10
|
+
u.first_name "Ashley"
|
11
|
+
u.last_name "Beasy"
|
12
|
+
u.email "ashley@wehaventthetime.com"
|
13
|
+
u.subscribed_to_list false
|
14
|
+
u.password "abc123"
|
15
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "action_controller"
|
3
|
+
require "generator_spec/test_case"
|
4
|
+
require 'generators/subscribed_to/install_generator'
|
5
|
+
|
6
|
+
describe SubscribedTo::Generators::InstallGenerator do
|
7
|
+
include GeneratorSpec::TestCase
|
8
|
+
destination File.expand_path("../../../tmp", __FILE__)
|
9
|
+
|
10
|
+
before(:all) { prepare_destination }
|
11
|
+
|
12
|
+
context "when run with default options" do
|
13
|
+
before(:all) { run_generator %w(User) }
|
14
|
+
|
15
|
+
it "should create an initializer" do
|
16
|
+
assert_file "config/initializers/subscribed_to.rb", /config.service = :mail_chimp/
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should create a migration" do
|
20
|
+
assert_file "db/migrate/#{SubscribedTo::Generators::InstallGenerator.next_migration_number("")}_add_subscribed_to_list_to_users.rb"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "when run with --skip-migration" do
|
25
|
+
before(:all) do
|
26
|
+
prepare_destination
|
27
|
+
run_generator %w(User --skip-migration)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should not create a migration" do
|
31
|
+
assert_no_file "db/migrate/#{SubscribedTo::Generators::InstallGenerator.next_migration_number("")}_add_subscribed_to_list_to_users.rb"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/spec/schema.rb
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'simplecov'
|
4
|
+
SimpleCov.start
|
5
|
+
|
6
|
+
require 'rspec'
|
7
|
+
require 'factory_girl'
|
8
|
+
require 'subscribed_to'
|
9
|
+
|
10
|
+
# Requires supporting files with custom matchers and macros, etc,
|
11
|
+
# in ./support/ and its subdirectories.
|
12
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
13
|
+
|
14
|
+
RSpec.configure do |config|
|
15
|
+
config.mock_with :mocha
|
16
|
+
end
|
17
|
+
|
18
|
+
ENV['DB'] ||= 'sqlite3'
|
19
|
+
|
20
|
+
database_yml = File.expand_path('../database.yml', __FILE__)
|
21
|
+
if File.exists?(database_yml)
|
22
|
+
active_record_configuration = YAML.load_file(database_yml)[ENV['DB']]
|
23
|
+
|
24
|
+
ActiveRecord::Base.establish_connection(active_record_configuration)
|
25
|
+
ActiveRecord::Base.logger = Logger.new(File.join(File.dirname(__FILE__), "log", "debug.log"))
|
26
|
+
|
27
|
+
ActiveRecord::Base.silence do
|
28
|
+
ActiveRecord::Migration.verbose = false
|
29
|
+
|
30
|
+
load('schema.rb')
|
31
|
+
Dir["#{File.dirname(__FILE__)}/app/**/*.rb"].each {|f| load f}
|
32
|
+
Dir["#{File.dirname(__FILE__)}/factories/*.rb"].each {|f| load f}
|
33
|
+
end
|
34
|
+
|
35
|
+
else
|
36
|
+
raise "Please create #{database_yml} first to configure your database. Take a look at: #{database_yml}.sample"
|
37
|
+
end
|
38
|
+
|
39
|
+
Rails.logger = Logger.new(File.join(File.dirname(__FILE__), "log", "debug.log"))
|
40
|
+
|
41
|
+
def clean_database!
|
42
|
+
models = [User]
|
43
|
+
models.each do |model|
|
44
|
+
ActiveRecord::Base.connection.execute "DELETE FROM #{model.table_name}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
clean_database!
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SubscribedTo::MailChimp::Config do
|
4
|
+
before(:each) { @config = SubscribedTo::MailChimp::Config.new }
|
5
|
+
|
6
|
+
it "should behave like a hash" do
|
7
|
+
@config[:foo] = :bar
|
8
|
+
@config[:foo].should eq :bar
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should provide hash accessors" do
|
12
|
+
@config.api_key = "1234567890"
|
13
|
+
@config[:api_key].should eq "1234567890"
|
14
|
+
@config[:api_key] = "0987654321"
|
15
|
+
@config.api_key.should eq "0987654321"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should merge given options on initialization" do
|
19
|
+
SubscribedTo::MailChimp::Config.new(:foo => :bar)[:foo].should eq :bar
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'hominid'
|
3
|
+
|
4
|
+
describe SubscribedTo::MailChimp do
|
5
|
+
before(:each) do
|
6
|
+
SubscribedTo.mail_chimp do |config|
|
7
|
+
config.api_key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-us1"
|
8
|
+
config.lists = {:mailing_list => {:id => "123456", :merge_vars => {"FNAME" => :first_name, "LNAME" => :last_name, "EMAIL" => :email}}}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context "for a new user" do
|
13
|
+
it "should subscribe the user" do
|
14
|
+
@user = MailChimpUser.create(Factory.attributes_for(:subscribed_user))
|
15
|
+
@user.callback_result.should eq "Subscribed with: Eric, Salczynski, eric@wehaventthetime.com"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should not subscribe the user" do
|
19
|
+
@user = MailChimpUser.create(Factory.attributes_for(:non_subscribed_user))
|
20
|
+
@user.callback_result.should eq "Not Subscribed"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "for an existing user" do
|
25
|
+
context "who is not subscribed to the mailing list" do
|
26
|
+
before { @user = MailChimpUser.create(Factory.attributes_for(:non_subscribed_user)) }
|
27
|
+
|
28
|
+
it "should subscribe the user" do
|
29
|
+
@user.update_attributes({:subscribed_to_list => true})
|
30
|
+
@user.callback_result.should eq "Subscribed with: #{[@user.first_name, @user.last_name, @user.email].join(", ")}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "who is subscribed to the mailing list" do
|
35
|
+
before(:each) { @user = MailChimpUser.create(Factory.attributes_for(:subscribed_user)) }
|
36
|
+
|
37
|
+
it "should unsubscribe the user" do
|
38
|
+
@user.update_attributes({:subscribed_to_list => false})
|
39
|
+
@user.callback_result.should eq "Unsubscribed"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should update list member attributes for the user" do
|
43
|
+
@user.update_attributes({:first_name => "Ed", :last_name => "Salczynski", :email => "ed@whtt.me"})
|
44
|
+
@user.callback_result.should eq "Updated with: Ed, Salczynski, ed@whtt.me"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should not update list member when attributes not defined in merge vars are changed" do
|
48
|
+
@user.update_attributes({:password => "zyx321"})
|
49
|
+
@user.callback_result.should eq "Nothing updated"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SubscribedTo do
|
4
|
+
it "should yield self on setup" do
|
5
|
+
SubscribedTo.setup do |config|
|
6
|
+
config.should eq SubscribedTo
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should configure MailChimp through a block" do
|
11
|
+
SubscribedTo.mail_chimp do |config|
|
12
|
+
config.should be_an_instance_of SubscribedTo::MailChimp::Config
|
13
|
+
config.api_key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-us1"
|
14
|
+
config.lists = {:mailing_list => {:id => "123456", :merge_vars => {"FNAME" => :first_name}}}
|
15
|
+
end
|
16
|
+
|
17
|
+
SubscribedTo.mail_chimp_config.api_key.should eq "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX-us1"
|
18
|
+
SubscribedTo.mail_chimp_config.lists.should eq :mailing_list => {:id => "123456", :merge_vars => {"FNAME" => :first_name}}
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should include the default instance methods" do
|
22
|
+
User.included_modules.should include SubscribedTo::InstanceMethods
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should add subscribe and update methods to the callback chain" do
|
26
|
+
@user = Factory.build(:subscribed_user)
|
27
|
+
@user.expects(:subscribe_to_list).once
|
28
|
+
@user.save
|
29
|
+
|
30
|
+
@user.first_name = "Edward"
|
31
|
+
@user.expects(:update_list_member).once
|
32
|
+
@user.save
|
33
|
+
end
|
34
|
+
|
35
|
+
# the default service is MailChimp
|
36
|
+
context "for MailChimp" do
|
37
|
+
it "should include the MailChimp instance methods" do
|
38
|
+
User.included_modules.should include SubscribedTo::MailChimp::InstanceMethods
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should provide the class with list_id and merge_vars methods" do
|
42
|
+
SubscribedTo.mail_chimp do |config|
|
43
|
+
config.lists = {:mailing_list => {:id => "123456", :merge_vars => {"FNAME" => :first_name}}}
|
44
|
+
end
|
45
|
+
|
46
|
+
User.list_id.should eq "123456"
|
47
|
+
User.merge_vars.should eq "FNAME" => :first_name
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
metadata
ADDED
@@ -0,0 +1,203 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: subscribed_to
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.2.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- whtt-eric
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-05-18 00:00:00 -04:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: activerecord
|
18
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
type: :runtime
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: hominid
|
29
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
30
|
+
none: false
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 3.0.2
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: sqlite3-ruby
|
40
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: "0"
|
46
|
+
type: :development
|
47
|
+
prerelease: false
|
48
|
+
version_requirements: *id003
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: factory_girl_rails
|
51
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - "="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 1.0.1
|
57
|
+
type: :development
|
58
|
+
prerelease: false
|
59
|
+
version_requirements: *id004
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: mocha
|
62
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - "="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 0.9.12
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: *id005
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: rspec-rails
|
73
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - "="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 2.5.0
|
79
|
+
type: :development
|
80
|
+
prerelease: false
|
81
|
+
version_requirements: *id006
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: generator_spec
|
84
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: "0"
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: *id007
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: bundler
|
95
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
96
|
+
none: false
|
97
|
+
requirements:
|
98
|
+
- - ~>
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: 1.0.0
|
101
|
+
type: :development
|
102
|
+
prerelease: false
|
103
|
+
version_requirements: *id008
|
104
|
+
- !ruby/object:Gem::Dependency
|
105
|
+
name: jeweler
|
106
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
108
|
+
requirements:
|
109
|
+
- - ~>
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: 1.6.0
|
112
|
+
type: :development
|
113
|
+
prerelease: false
|
114
|
+
version_requirements: *id009
|
115
|
+
- !ruby/object:Gem::Dependency
|
116
|
+
name: simplecov
|
117
|
+
requirement: &id010 !ruby/object:Gem::Requirement
|
118
|
+
none: false
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: 0.4.0
|
123
|
+
type: :development
|
124
|
+
prerelease: false
|
125
|
+
version_requirements: *id010
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: hanna
|
128
|
+
requirement: &id011 !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: "0"
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: *id011
|
137
|
+
description: Abstract layer for managing mailing list subscriptions
|
138
|
+
email: eric@wehaventthetime.com
|
139
|
+
executables: []
|
140
|
+
|
141
|
+
extensions: []
|
142
|
+
|
143
|
+
extra_rdoc_files:
|
144
|
+
- LICENSE.txt
|
145
|
+
- README.rdoc
|
146
|
+
files:
|
147
|
+
- .document
|
148
|
+
- .rspec
|
149
|
+
- Gemfile
|
150
|
+
- Gemfile.lock
|
151
|
+
- LICENSE.txt
|
152
|
+
- README.rdoc
|
153
|
+
- Rakefile
|
154
|
+
- lib/generators/subscribed_to/USAGE
|
155
|
+
- lib/generators/subscribed_to/install_generator.rb
|
156
|
+
- lib/generators/subscribed_to/templates/migration.rb
|
157
|
+
- lib/generators/subscribed_to/templates/subscribed_to.rb
|
158
|
+
- lib/subscribed_to.rb
|
159
|
+
- lib/subscribed_to/mail_chimp.rb
|
160
|
+
- lib/subscribed_to/mail_chimp/config.rb
|
161
|
+
- lib/subscribed_to/version.rb
|
162
|
+
- spec/app/models/user.rb
|
163
|
+
- spec/database.yml.example
|
164
|
+
- spec/factories/users.rb
|
165
|
+
- spec/generators/install_generator_spec.rb
|
166
|
+
- spec/schema.rb
|
167
|
+
- spec/spec_helper.rb
|
168
|
+
- spec/subscribed_to/mail_chimp/config_spec.rb
|
169
|
+
- spec/subscribed_to/mail_chimp_spec.rb
|
170
|
+
- spec/subscribed_to_spec.rb
|
171
|
+
has_rdoc: true
|
172
|
+
homepage: http://github.com/whtt-eric/subscribed_to
|
173
|
+
licenses:
|
174
|
+
- MIT
|
175
|
+
post_install_message:
|
176
|
+
rdoc_options: []
|
177
|
+
|
178
|
+
require_paths:
|
179
|
+
- lib
|
180
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
181
|
+
none: false
|
182
|
+
requirements:
|
183
|
+
- - ">="
|
184
|
+
- !ruby/object:Gem::Version
|
185
|
+
hash: 1335917726808869519
|
186
|
+
segments:
|
187
|
+
- 0
|
188
|
+
version: "0"
|
189
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
190
|
+
none: false
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: "0"
|
195
|
+
requirements: []
|
196
|
+
|
197
|
+
rubyforge_project:
|
198
|
+
rubygems_version: 1.6.2
|
199
|
+
signing_key:
|
200
|
+
specification_version: 3
|
201
|
+
summary: Abstract layer for managing mailing list subscriptions
|
202
|
+
test_files: []
|
203
|
+
|