chimpy 0.0.6

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.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +47 -0
  6. data/README.rdoc +3 -0
  7. data/Rakefile +8 -0
  8. data/chimpy.gemspec +37 -0
  9. data/fixtures/vcr_cassettes/run.yml +34 -0
  10. data/fixtures/vcr_cassettes/succesful_list_subscription.yml +34 -0
  11. data/lib/chimpy.rb +22 -0
  12. data/lib/chimpy/base.rb +9 -0
  13. data/lib/chimpy/configuration.rb +11 -0
  14. data/lib/chimpy/email_service.rb +40 -0
  15. data/lib/chimpy/railtie.rb +16 -0
  16. data/lib/chimpy/user_manager.rb +22 -0
  17. data/lib/chimpy/version.rb +3 -0
  18. data/lib/generators/migration_generator.rb +23 -0
  19. data/lib/generators/templates/add_column_to_sync_class.rb.erb +5 -0
  20. data/lib/tasks/chimpy.rake +6 -0
  21. data/test/base_test.rb +36 -0
  22. data/test/configuration_test.rb +16 -0
  23. data/test/dummy/README.rdoc +28 -0
  24. data/test/dummy/Rakefile +6 -0
  25. data/test/dummy/app/assets/images/.keep +0 -0
  26. data/test/dummy/app/assets/javascripts/application.js +13 -0
  27. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  28. data/test/dummy/app/controllers/application_controller.rb +5 -0
  29. data/test/dummy/app/controllers/concerns/.keep +0 -0
  30. data/test/dummy/app/helpers/application_helper.rb +2 -0
  31. data/test/dummy/app/mailers/.keep +0 -0
  32. data/test/dummy/app/models/.keep +0 -0
  33. data/test/dummy/app/models/concerns/.keep +0 -0
  34. data/test/dummy/app/models/user.rb +3 -0
  35. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  36. data/test/dummy/bin/bundle +3 -0
  37. data/test/dummy/bin/rails +4 -0
  38. data/test/dummy/bin/rake +4 -0
  39. data/test/dummy/config.ru +4 -0
  40. data/test/dummy/config/application.rb +23 -0
  41. data/test/dummy/config/boot.rb +5 -0
  42. data/test/dummy/config/database.yml +25 -0
  43. data/test/dummy/config/environment.rb +5 -0
  44. data/test/dummy/config/environments/development.rb +37 -0
  45. data/test/dummy/config/environments/production.rb +83 -0
  46. data/test/dummy/config/environments/test.rb +39 -0
  47. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  48. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  49. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  50. data/test/dummy/config/initializers/inflections.rb +16 -0
  51. data/test/dummy/config/initializers/mime_types.rb +4 -0
  52. data/test/dummy/config/initializers/session_store.rb +3 -0
  53. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  54. data/test/dummy/config/locales/en.yml +23 -0
  55. data/test/dummy/config/routes.rb +56 -0
  56. data/test/dummy/config/secrets.yml +22 -0
  57. data/test/dummy/db/development.sqlite3 +0 -0
  58. data/test/dummy/db/migrate/20140509170116_create_users.rb +11 -0
  59. data/test/dummy/db/migrate/20140513015907_remove_column_from_users.rb +5 -0
  60. data/test/dummy/db/migrate/20140513022907_add_chimpy_to_users.rb +5 -0
  61. data/test/dummy/db/schema.rb +24 -0
  62. data/test/dummy/db/test.sqlite3 +0 -0
  63. data/test/dummy/lib/assets/.keep +0 -0
  64. data/test/dummy/public/404.html +67 -0
  65. data/test/dummy/public/422.html +67 -0
  66. data/test/dummy/public/500.html +66 -0
  67. data/test/dummy/public/favicon.ico +0 -0
  68. data/test/dummy/test/fixtures/users.yml +11 -0
  69. data/test/dummy/test/models/user_test.rb +7 -0
  70. data/test/email_service_test.rb +26 -0
  71. data/test/test_helper.rb +44 -0
  72. data/test/user_manager_test.rb +35 -0
  73. metadata +341 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2c969ef0d51ce19648c2fef489ec6b596d1c32df
4
+ data.tar.gz: d2a8eb0e5fc334e4e8506367ed472f9fa2862312
5
+ SHA512:
6
+ metadata.gz: 339cc748a5107dedc441e986e6eed947a57e02d5989cb0730a1e3eb987eab9809c6b0b792a9cb9a8fc909794775654101c1e52de8dcbb5cc8a03ad1c2e5be057
7
+ data.tar.gz: 9240d729f13d671a2a06936eb741adebe60af4951c4fcb5735e399f74f94065f90b90273572a463b53693dc2cd4bfcec06f38a96dace8f35cd046e434440740c
@@ -0,0 +1,21 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .env
19
+ .DS_Store
20
+ test/dummy/log/
21
+ test/dummy/log/development.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in chimpy.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Ignacio Gutierrez
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,47 @@
1
+ # Chimpy
2
+
3
+ Chimpy syncs your users from your DB to your respective lists in MailChimp.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'chimpy'
10
+
11
+ Then execute:
12
+
13
+ $ bundle
14
+
15
+ Create an initializer with the details for the class you would like to sync with MailChimp and your mailchimp keys. It defaults to User
16
+
17
+ ``` ruby
18
+ #initializers/chimpy.rb
19
+
20
+ Chimpy.configure do |config|
21
+ config.sync_class = User
22
+ config.mailchimp_api_key = "549391d6ed3fc64fd42e4b5cf83ceba9-us8"
23
+ config.mailchimp_list_id = "788e29440b"
24
+ end
25
+
26
+ ```
27
+ Run Chimpy Generator
28
+
29
+ $ rails g chimpy:migrate
30
+
31
+ After that execute the generated migration
32
+
33
+ $ rake db:migration
34
+
35
+ ## Usage
36
+
37
+ To sync your users just run the following rake task. It is recommended to run it frequently with a cron or schedule it with Heroku Scheduler.
38
+
39
+ $ rake chimpy:sync
40
+
41
+ ## Contributing
42
+
43
+ 1. Fork it ( http://github.com/<my-github-username>/chimpy/fork )
44
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
45
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
46
+ 4. Push to the branch (`git push origin my-new-feature`)
47
+ 5. Create new Pull Request
@@ -0,0 +1,3 @@
1
+ = Chimpy
2
+
3
+ This project rocks and uses MIT-LICENSE.
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rake/testtask'
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.libs << "test"
7
+ t.pattern = "test/*_test.rb"
8
+ end
@@ -0,0 +1,37 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'chimpy/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "chimpy"
8
+ spec.version = Chimpy::VERSION
9
+ spec.authors = ["Ignacio Gutierrez"]
10
+ spec.email = ["nachojgutierrez@gmail.com"]
11
+ spec.summary = %q{Chimpy syncs your users from your DB to your respective lists in MailChimp.}
12
+ spec.description = %q{Chimpy syncs your users from your DB to your respective lists in MailChimp.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency'gibbon', '>= 1.1.2'
22
+ spec.add_dependency 'railties', '>= 3.0.0'
23
+ spec.add_dependency 'activerecord', '>= 3.0.0'
24
+
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.5"
27
+ spec.add_development_dependency "rake"
28
+ spec.add_development_dependency "minitest"
29
+ spec.add_development_dependency "dotenv"
30
+ spec.add_development_dependency "webmock"
31
+ spec.add_development_dependency "database_cleaner"
32
+ spec.add_development_dependency "vcr"
33
+
34
+ spec.add_development_dependency "rails", ">= 4.0.2"
35
+ spec.add_development_dependency "sqlite3"
36
+
37
+ end
@@ -0,0 +1,34 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://us8.api.mailchimp.com/2.0/lists/batch-subscribe
6
+ body:
7
+ encoding: UTF-8
8
+ string: '{"apikey":"549391d6ed3fc64fd42e4b5cf83ceba9-us8","id":"788e29440b","batch":[{"email":{"email":"david.gilmour@gmail.com"}},{"email":{"email":"nick.mason@gmail.com"}}],"update_existing":true,"double_optin":false}'
9
+ headers: {}
10
+ response:
11
+ status:
12
+ code: 200
13
+ message: OK
14
+ headers:
15
+ Server:
16
+ - nginx
17
+ Content-Type:
18
+ - application/json; charset=utf-8
19
+ Content-Length:
20
+ - '229'
21
+ Vary:
22
+ - Accept-Encoding
23
+ Date:
24
+ - Sat, 10 May 2014 23:03:46 GMT
25
+ Connection:
26
+ - keep-alive
27
+ Set-Cookie:
28
+ - _AVESTA_ENVIRONMENT=prod; path=/
29
+ body:
30
+ encoding: UTF-8
31
+ string: '{"add_count":2,"adds":[{"email":"david.gilmour@gmail.com","euid":"0a80c3e59f","leid":"151471181"},{"email":"nick.mason@gmail.com","euid":"678343bc63","leid":"151471185"}],"update_count":0,"updates":[],"error_count":0,"errors":[]}'
32
+ http_version:
33
+ recorded_at: Sat, 10 May 2014 23:03:44 GMT
34
+ recorded_with: VCR 2.8.0
@@ -0,0 +1,34 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://us8.api.mailchimp.com/2.0/lists/batch-subscribe
6
+ body:
7
+ encoding: UTF-8
8
+ string: '{"apikey":"549391d6ed3fc64fd42e4b5cf83ceba9-us8","id":"788e29440b","batch":[{"email":{"email":"johndonson@gmail.com"}},{"email":{"email":"donjohnson@gmail.com"}}],"update_existing":true,"double_optin":false}'
9
+ headers: {}
10
+ response:
11
+ status:
12
+ code: 200
13
+ message: OK
14
+ headers:
15
+ Server:
16
+ - nginx
17
+ Content-Type:
18
+ - application/json; charset=utf-8
19
+ Content-Length:
20
+ - '227'
21
+ Vary:
22
+ - Accept-Encoding
23
+ Date:
24
+ - Fri, 09 May 2014 21:17:33 GMT
25
+ Connection:
26
+ - keep-alive
27
+ Set-Cookie:
28
+ - _AVESTA_ENVIRONMENT=prod; path=/
29
+ body:
30
+ encoding: UTF-8
31
+ string: '{"add_count":2,"adds":[{"email":"johndonson@gmail.com","euid":"d4c1408824","leid":"151330921"},{"email":"donjohnson@gmail.com","euid":"7f18d87748","leid":"151330925"}],"update_count":0,"updates":[],"error_count":0,"errors":[]}'
32
+ http_version:
33
+ recorded_at: Fri, 09 May 2014 21:17:33 GMT
34
+ recorded_with: VCR 2.8.0
@@ -0,0 +1,22 @@
1
+ require 'chimpy/version'
2
+ require 'chimpy/configuration'
3
+ require 'chimpy/base'
4
+ require 'chimpy/user_manager'
5
+ require 'chimpy/email_service'
6
+ require 'chimpy/railtie' if defined?(Rails)
7
+
8
+
9
+ module Chimpy
10
+
11
+ def self.run
12
+ Base.run
13
+ end
14
+
15
+ def self.configuration
16
+ @configuration ||= Configuration.new
17
+ end
18
+
19
+ def self.configure
20
+ yield(configuration)
21
+ end
22
+ end
@@ -0,0 +1,9 @@
1
+ module Chimpy
2
+ class Base
3
+ def self.run
4
+ user_manager = UserManager.new
5
+ synced_users = EmailService.new.sync(user_manager.to_sync)
6
+ user_manager.mark_as_synced(synced_users)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module Chimpy
2
+ class Configuration
3
+ attr_accessor :sync_class, :mailchimp_api_key, :mailchimp_list_id
4
+
5
+ def initialize
6
+ @sync_class = User
7
+ @mailchimp_api_key = ENV['MAILCHIMP_API_KEY']
8
+ @mailchimp_list_id = ENV['MAILCHIMP_LIST_ID']
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,40 @@
1
+ require 'gibbon'
2
+
3
+ module Chimpy
4
+ class EmailService
5
+ attr_reader :mailchimp, :mailchimp_api_key, :mailchimp_list_id
6
+
7
+ def initialize
8
+ @mailchimp_api_key = Chimpy.configuration.mailchimp_api_key
9
+ @mailchimp_list_id = Chimpy.configuration.mailchimp_list_id
10
+ @mailchimp = create_mailchimp_client
11
+ end
12
+
13
+ def sync(users)
14
+ struct = users.map { |user| { email: { email: user.email } } }
15
+ response = mailchimp.lists.batch_subscribe(id: mailchimp_list_id,
16
+ batch: struct,
17
+ update_existing: true,
18
+ double_optin: false)
19
+ synced_users(response)
20
+ end
21
+
22
+ private
23
+
24
+ def synced_users(response)
25
+ emails = []
26
+ response['adds'].each do |add|
27
+ emails << add['email']
28
+ end
29
+
30
+ response['updates'].each do |update|
31
+ emails << update['email']
32
+ end
33
+ emails
34
+ end
35
+
36
+ def create_mailchimp_client
37
+ Gibbon::API.new(mailchimp_api_key)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,16 @@
1
+ require 'chimpy'
2
+ require 'rails'
3
+ module Chimpy
4
+ class Railtie < Rails::Railtie
5
+ railtie_name :chimpy
6
+
7
+ rake_tasks do
8
+ load "tasks/chimpy.rake"
9
+ end
10
+
11
+ generators do
12
+ load "generators/migration_generator.rb"
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,22 @@
1
+ module Chimpy
2
+ class UserManager
3
+ attr_reader :sync_class
4
+
5
+ def initialize
6
+ @sync_class = Chimpy.configuration.sync_class
7
+ end
8
+
9
+ def to_sync
10
+ never_synced = sync_class.where(chimpy_synced_at: nil)
11
+ needing_sync = sync_class.where('updated_at > chimpy_synced_at')
12
+ never_synced + needing_sync
13
+ end
14
+
15
+ def mark_as_synced(emails)
16
+ emails.each do |email|
17
+ found = sync_class.find_by_email(email)
18
+ found.update(chimpy_synced_at: Time.now) if found
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,3 @@
1
+ module Chimpy
2
+ VERSION = '0.0.6'
3
+ end
@@ -0,0 +1,23 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/migration'
3
+
4
+
5
+ module Chimpy
6
+ class MigrationGenerator < Rails::Generators::Base
7
+ include Rails::Generators::Migration
8
+ source_root File.expand_path('../templates', __FILE__)
9
+
10
+ def copy_files
11
+ @sync_class = Chimpy.configuration.sync_class.to_s
12
+ migration_template('add_column_to_sync_class.rb.erb', "db/migrate/add_chimpy_to_#{@sync_class.underscore.pluralize}.rb")
13
+ end
14
+
15
+ def self.next_migration_number(dirname) #:nodoc:
16
+ if ActiveRecord::Base.timestamped_migrations
17
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
18
+ else
19
+ "%.3d" % (current_migration_number(dirname) + 1)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,5 @@
1
+ class AddChimpyTo<%= @sync_class.to_s.pluralize %> < ActiveRecord::Migration
2
+ def change
3
+ add_column :<%= @sync_class.parameterize.underscore.pluralize.to_sym %>, :chimpy_synced_at, :datetime
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ namespace :chimpy do
2
+ desc 'Runs Chimpy. It syncs your users to your desired MailChimp list'
3
+ task :sync => :environment do
4
+ Chimpy::Base.run
5
+ end
6
+ end
@@ -0,0 +1,36 @@
1
+ require 'test_helper'
2
+
3
+ describe Chimpy::Base do
4
+
5
+ before do
6
+ Chimpy.configure do |config|
7
+ config.sync_class = User
8
+ config.mailchimp_api_key = "549391d6ed3fc64fd42e4b5cf83ceba9-us8"
9
+ config.mailchimp_list_id = "788e29440b"
10
+ end
11
+ end
12
+
13
+ describe "run" do
14
+ before do
15
+ @new_user = User.create(email: "david.gilmour@gmail.com")
16
+ @already_synced = User.create(email: "roger.waters@gmail.com", chimpy_synced_at: 1.day.ago, updated_at: 3.days.ago)
17
+ @to_sync = User.create(email: "nick.mason@gmail.com", chimpy_synced_at: 5.days.ago, updated_at: 1.day.ago)
18
+ VCR.use_cassette('run') do
19
+ Chimpy.run
20
+ end
21
+ end
22
+
23
+ it "syncs the new user" do
24
+ @new_user.reload.chimpy_synced_at.wont_equal nil
25
+ end
26
+
27
+ it "syncs the user who needs sync" do
28
+ @to_sync.chimpy_synced_at.must_be :<, @to_sync.reload.chimpy_synced_at
29
+ end
30
+
31
+ it "leaves the already synced user untouched" do
32
+ @already_synced.chimpy_synced_at.must_equal @already_synced.reload.chimpy_synced_at
33
+ end
34
+ end
35
+ end
36
+
@@ -0,0 +1,16 @@
1
+ require 'test_helper'
2
+
3
+ describe Chimpy::Configuration do
4
+ describe "#sync_class" do
5
+ it "default value is User" do
6
+ Chimpy::Configuration.new.sync_class.must_equal User
7
+ end
8
+ end
9
+ describe "#sync_class=" do
10
+ it "can set value" do
11
+ config = Chimpy::Configuration.new
12
+ config.sync_class = Object.const_set("Admin" ,Class.new)
13
+ config.sync_class.must_equal Admin
14
+ end
15
+ end
16
+ end