chimpactions 0.0.0 → 0.0.4

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 (44) hide show
  1. data/Gemfile +14 -2
  2. data/MIT-LICENSE +20 -0
  3. data/README.textile +134 -0
  4. data/Rakefile +44 -0
  5. data/app/controllers/chimpactions_controller.rb +123 -0
  6. data/app/models/chimpaction.rb +20 -0
  7. data/app/views/chimpactions/_errors.html.erb +10 -0
  8. data/app/views/chimpactions/_form.html.erb +26 -0
  9. data/app/views/chimpactions/_list.html.erb +6 -0
  10. data/app/views/chimpactions/edit.html.erb +4 -0
  11. data/app/views/chimpactions/index.html.erb +22 -0
  12. data/app/views/chimpactions/new.html.erb +4 -0
  13. data/app/views/chimpactions/webhooks.html.erb +26 -0
  14. data/chimpactions.gemspec +9 -4
  15. data/config/deploy/templates/nginx.conf.tpl_ +0 -0
  16. data/config/deploy/templates/unicorn.conf.tpl_ +0 -0
  17. data/config/routes.rb +8 -0
  18. data/lib/chimpactions.rb +210 -2
  19. data/lib/chimpactions/action.rb +73 -0
  20. data/lib/chimpactions/engine.rb +21 -0
  21. data/lib/chimpactions/exception.rb +14 -0
  22. data/lib/chimpactions/list.rb +113 -0
  23. data/lib/chimpactions/notifier.rb +9 -0
  24. data/lib/chimpactions/setup.rb +42 -0
  25. data/lib/chimpactions/subscriber.rb +125 -0
  26. data/lib/chimpactions/utility.rb +13 -0
  27. data/lib/chimpactions/version.rb +1 -1
  28. data/lib/generators/chimpactions/customize/customize_generator.rb +19 -0
  29. data/lib/generators/chimpactions/customize/templates/views/_errors.html.erb +10 -0
  30. data/lib/generators/chimpactions/customize/templates/views/_form.html.erb +26 -0
  31. data/lib/generators/chimpactions/customize/templates/views/_list.html.erb +6 -0
  32. data/lib/generators/chimpactions/customize/templates/views/edit.html.erb +4 -0
  33. data/lib/generators/chimpactions/customize/templates/views/index.html.erb +22 -0
  34. data/lib/generators/chimpactions/customize/templates/views/new.html.erb +4 -0
  35. data/lib/generators/chimpactions/customize/templates/views/webhooks.html.erb +26 -0
  36. data/lib/generators/chimpactions/install/install_generator.rb +19 -0
  37. data/lib/generators/chimpactions/install/templates/README +10 -0
  38. data/lib/generators/chimpactions/install/templates/chimpactions.yml +39 -0
  39. data/lib/generators/chimpactions/install/templates/chimpactions_initializer.rb +1 -0
  40. data/lib/generators/chimpactions/migration/migration_generator.rb +26 -0
  41. data/lib/generators/chimpactions/migration/templates/create_chimpactions.rb +16 -0
  42. data/lib/railtie.rb +16 -0
  43. metadata +82 -38
  44. data/.gitignore +0 -4
data/Gemfile CHANGED
@@ -1,4 +1,16 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- # Specify your gem's dependencies in chimpactions.gemspec
4
- gemspec
3
+ gem "rails", "3.0.7"
4
+ gem "capybara", ">= 0.4.0"
5
+ gem "sqlite3"
6
+ gem "gibbon", ">= 0.1.5"
7
+ # To use debugger (ruby-debug for Ruby 1.8.7+, ruby-debug19 for Ruby 1.9.2+)
8
+ # gem 'ruby-debug'
9
+ # gem 'ruby-debug19'
10
+
11
+ group :test do
12
+ gem "factory_girl"
13
+ gem "shoulda"
14
+ gem 'simplecov'
15
+ gem 'mocha'
16
+ end
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2011 Peter Bonnell / CIRCUIT LLC
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.textile ADDED
@@ -0,0 +1,134 @@
1
+ h1. Chimpactions
2
+
3
+ Easily move contacts between MailChimp lists in your Rails 3 application.
4
+
5
+ h2. Requirements
6
+
7
+ A MailChimp account and "API key":http://admin.mailchimp.com/account/api.
8
+
9
+ h2. Installation
10
+
11
+ h3. Base
12
+
13
+ # *_Gemfile_* -> <code>gem "chimpactions", "~> 0.0.1"</code>
14
+ # <code>rails generate chimpactions:install</code>
15
+ # _Edit config/chimpactions.yml_ with your information.
16
+ # add <code>include Chimpactions::Subscriber</code> to your model.
17
+ # add <code>after_save :chimpactions </code> (if that's what you want) to your model.
18
+
19
+ The YourModel.chimpactions method fires the actions to move subscribers as specified.
20
+
21
+ Generates:
22
+ * config/chimpactions.yml config file
23
+
24
+ h3. ActiveRecord store
25
+
26
+ <code>rails generate chimpactions:migration </code>
27
+
28
+ <code> rake db:migrate </code>
29
+
30
+ Generates:
31
+ * chimpactions ActiveRecord migration
32
+
33
+ h3. Customizing Admin
34
+
35
+ Chimpactions provides a basic scaffold for managing ActiveRecord Actions @ http:yourapp/chimpactions.
36
+ To override the gem views :
37
+
38
+ <code>rails generate chimpactions:customize </code>
39
+
40
+ Generates:
41
+
42
+ * chimpactions view files for administrative interface
43
+ * yourapp/app/views/chimpactions
44
+
45
+ h2. Configuration
46
+
47
+ _See installed config/chimpactions.yml for configuration options_
48
+
49
+ h2. Usage
50
+
51
+ h3. What's available
52
+
53
+ Once defined (in chimpactions.yml) the local Rails model inherits the following methods from the Chimpactions gem :
54
+ * add_to(List)
55
+ * move_to(List)
56
+ * remove_from(List)
57
+
58
+ h3. A Chimpaction :
59
+
60
+ *WHENN (A model method/attribute) IS (<,>,=) VALUE, ACTION (Chimpactions method) LIST (One of your MailChimp Lists)*
61
+
62
+ ex.
63
+
64
+ 'When a user has more than 50 posts, move them to the Power Poster list'
65
+
66
+ *_in chimpactions.yml_*
67
+ <pre><code> action:
68
+ -
69
+ action: :move_to,
70
+ list: Power Posters,
71
+ whenn: posts.count,
72
+ is: >,
73
+ value: 50
74
+ -
75
+ </code></pre>
76
+
77
+ *_for ActiveRecord store_*
78
+ The admin interface should be a straightforward representation.
79
+
80
+ h3. Administrative Interface
81
+
82
+ Direct your browser to http://yourapp.chimpactions for a simple CRUD to build and manage Actions.
83
+ Available values are set in the forms where applicable, validations will tell you if a value won't work.
84
+
85
+ h3. Manual access
86
+
87
+ You can move subscribers around arbitrarily as well:
88
+
89
+ <pre><code>user = User.find(123)
90
+ user.remove_from("Power Posters")
91
+ </code></pre>
92
+
93
+ h3. Chimpactions Module
94
+
95
+ All your lists with a ton of info:
96
+ <pre><code>@lists = Chimpactions.available_lists
97
+ ...view
98
+ <%= var_dump(@lists) ->
99
+ </code></pre>
100
+
101
+ Calling the MailChimp API directly:
102
+
103
+ Direct access to the "gibbon":http://rubygems.org/gems/gibbon/ socket :
104
+ <pre><code>api_result = Chimpactions.socket.campaigns({:start => 0, :limit => 100})
105
+ </code></pre>
106
+
107
+
108
+ h3. Webhooks
109
+
110
+ To register your application with your MailChimp List direct your browser to : http://yourapp/chimpactions/webhooks
111
+
112
+ The links next to each list will add/delete the webhook http://yourapp/chimpactions/receive to that list.
113
+
114
+ You must handle the post itself in <pre><code> receive_webhook(mc_post_data) </code> </pre> in your mix-in model for it have an effect.
115
+
116
+
117
+ h2. TODO
118
+
119
+ * implement VCR for tests so we don't have to use a real API key
120
+ * get loading don't so we don't have to add <code>include Chimpactions::Subscriber</code> in the model
121
+
122
+ h2. License
123
+
124
+ This project released under the MIT-LICENSE.
125
+
126
+ h2. Thanks
127
+
128
+ p. Made possible by the generous support of the "MailChimp Integration Fund":http://www.mailchimp.com/about/integration-fund/ .
129
+
130
+ h2. Copyrights
131
+
132
+ (c) circuitllc & "imgenius":http://imgeni.us 2011 - Released under the MIT license.
133
+
134
+
data/Rakefile CHANGED
@@ -1,2 +1,46 @@
1
+ # encoding: UTF-8
2
+ require 'rubygems'
3
+ begin
4
+ require 'bundler/setup'
5
+ rescue LoadError
6
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
7
+ end
8
+
1
9
  require 'bundler'
2
10
  Bundler::GemHelper.install_tasks
11
+
12
+ require 'rake'
13
+ require 'rake/rdoctask'
14
+
15
+ require 'rake/testtask'
16
+
17
+ Rake::TestTask.new(:test) do |t|
18
+ t.libs << 'lib'
19
+ t.libs << 'test'
20
+ t.pattern = 'test/**/*_test.rb'
21
+ t.verbose = false
22
+ end
23
+
24
+ Rake::TestTask.new(:units) do |t|
25
+ t.libs << 'lib'
26
+ t.libs << 'test'
27
+ t.pattern = 'test/unit/*_test.rb'
28
+ t.verbose = false
29
+ end
30
+
31
+ Rake::TestTask.new(:functionals) do |t|
32
+ t.libs << 'lib'
33
+ t.libs << 'test'
34
+ t.pattern = 'test/integration/*_test.rb'
35
+ t.verbose = false
36
+ end
37
+
38
+ task :default => :test
39
+
40
+ Rake::RDocTask.new(:rdoc) do |rdoc|
41
+ rdoc.rdoc_dir = 'rdoc'
42
+ rdoc.title = 'Chimpactions'
43
+ rdoc.options << '--line-numbers' << '--inline-source'
44
+ rdoc.rdoc_files.include('README.rdoc')
45
+ rdoc.rdoc_files.include('lib/**/*.rb')
46
+ end
@@ -0,0 +1,123 @@
1
+ class ChimpactionsController < ApplicationController
2
+ def index
3
+ @all_actions = Chimpactions.actions
4
+ @registered = Chimpactions.registered_class_name
5
+ @actions = Chimpaction.all
6
+ @lists = Chimpactions.available_lists
7
+ end
8
+
9
+ # GET /chimpactions/new
10
+ # GET /chimpactions/new.xml
11
+ def new
12
+ @chimpaction = Chimpaction.new
13
+
14
+ respond_to do |format|
15
+ format.html # new.html.erb
16
+ format.xml { render :xml => @chimpaction }
17
+ end
18
+ end
19
+
20
+ # GET /chimpactions/1/edit
21
+ def edit
22
+ @chimpaction = Chimpaction.find(params[:id])
23
+ end
24
+
25
+ # POST /chimpactions
26
+ # POST /chimpactions.xml
27
+ def create
28
+ @chimpaction = Chimpaction.new(params[:chimpaction])
29
+
30
+ respond_to do |format|
31
+ if @chimpaction.save
32
+ format.html { redirect_to(chimpactions_url, :notice => 'Chimpaction was successfully created.') }
33
+ format.xml { render :xml => @chimpaction, :status => :created, :location => @chimpaction }
34
+ else
35
+ format.html { render :action => "new" }
36
+ format.xml { render :xml => @chimpaction.errors, :status => :unprocessable_entity }
37
+ end
38
+ end
39
+ end
40
+
41
+ # PUT /chimpactions/1
42
+ # PUT /chimpactions/1.xml
43
+ def update
44
+ @chimpaction = Chimpaction.find(params[:id])
45
+
46
+ respond_to do |format|
47
+ if @chimpaction.update_attributes(params[:chimpaction])
48
+ format.html { redirect_to(chimpactions_url, :notice => 'Chimpaction was successfully updated.') }
49
+ format.xml { head :ok }
50
+ else
51
+ format.html { render :action => "edit" }
52
+ format.xml { render :xml => @chimpaction.errors, :status => :unprocessable_entity }
53
+ end
54
+ end
55
+ end
56
+
57
+ # DELETE /chimpactions/1
58
+ # DELETE /chimpactions/1.xml
59
+ def destroy
60
+ @chimpaction = Chimpaction.find(params[:id])
61
+ @chimpaction.destroy
62
+
63
+ respond_to do |format|
64
+ format.html { redirect_to(chimpactions_url) }
65
+ format.xml { head :ok }
66
+ end
67
+ end
68
+
69
+ def webhooks
70
+ @lists = Chimpactions.available_lists
71
+ end
72
+
73
+ def add_webhook
74
+ list = Chimpactions.list(params[:id])
75
+ if list.set_webhook :url => 'http://www.postbin.org/1iwea1s'#webhook_url
76
+ flash[:notice] = "Added Webhook!"
77
+ end
78
+ redirect_to '/chimpactions/webhooks'
79
+ end
80
+
81
+ def delete_webhook
82
+ list = Chimpactions.list(params[:id])
83
+ if list.remove_webhook :url => 'http://www.postbin.org/1iwea1s' #webhook_url
84
+ flash[:notice] = "Removed Webhook!"
85
+ end
86
+ redirect_to '/chimpactions/webhooks'
87
+ end
88
+
89
+ def receive
90
+ if params['data']
91
+ subscriber = Chimpactions.registered_class.find_by_email(params['data']['email'])
92
+ subscriber.receive_webhook(params) if subscriber.respond_to?(:receive_webhook)
93
+ end
94
+ render :nothing => true
95
+ end
96
+ # data[email] = 'federico@mailchimp.com'
97
+ #
98
+ # data[email_type] = 'html'
99
+ #
100
+ # data[id] = 'da1b07ac4c'
101
+ #
102
+ # data[ip_opt]='69.12.4.2'
103
+ #
104
+ # data[list_id]='45a650bc63'
105
+ #
106
+ # data[merges][EMAIL]='federico@mailchimp.com'
107
+ #
108
+ # data[merges][FNAME] ='Federico'
109
+ #
110
+ # data[merges][IP] ='127.0.0.1'
111
+ #
112
+ # data[merges][LNAME]='Holgado'
113
+ #
114
+ # data[merges][SIGNUP]=''
115
+ #
116
+ # data[web_id]='234305517'
117
+ #
118
+ # fired_at = '2011-06-30 02:34:35'
119
+ #
120
+ # type ='profile'
121
+ # end
122
+
123
+ end
@@ -0,0 +1,20 @@
1
+ require "chimpactions"
2
+
3
+ class ResponseValidator < ActiveModel::Validator
4
+ def validate(record)
5
+ # k = Kernel.const_get(Chimpactions::registered_class.name.to_s.capitalize).new
6
+ k = Chimpactions.registered_class
7
+ if k.respond_to?(record.action) != true
8
+ record.errors[:action] << "- '#{record.action}' is not a method of #{k.class.name} !"
9
+ end
10
+ if k.respond_to?(record.whenn) != true
11
+ record.errors[:whenn] << "- '#{record.whenn}' is not a method of #{k.class.name} !"
12
+ end
13
+ end
14
+ end
15
+
16
+ # ActiveRecord 'wrapper' for Chimpactions::Action to provide non-yml peristence & customization
17
+ class Chimpaction < ActiveRecord::Base
18
+ validates_presence_of :list, :action, :whenn, :is, :value
19
+ validates_with ResponseValidator
20
+ end
@@ -0,0 +1,10 @@
1
+ <% if target.errors.any? %>
2
+ <div id="errorExplanation">
3
+ <h2><%= pluralize(target.errors.count, "error") %> prohibited this record from being saved:</h2>
4
+ <ul>
5
+ <% target.errors.full_messages.each do |msg| %>
6
+ <li><%= msg %></li>
7
+ <% end %>
8
+ </ul>
9
+ </div>
10
+ <% end %>
@@ -0,0 +1,26 @@
1
+ <style>
2
+ .ca_action_form {padding-bottom:25px;width:350px;}
3
+ .ca_action_form fieldset {background-color:inherit;padding:0px;margin:0px;}
4
+ .ca_action_form fieldset legend {background-color:inherit;}
5
+ .ca_action_form * {float:none;font-family: verdana, arial, helvetica, sans-serif;
6
+ font-size: 12px!important;
7
+ line-height: 14px!important;}
8
+ .ca_action_form label {padding:0 4px;}
9
+ .ca_action_form div {display:inline;}
10
+ .ca_action_form .field_with_errors input {border:1px solid red;}
11
+ .ca_action_form ol {list-style:none;padding:14px;margin: 0px auto;max-width:315px;}
12
+ .ca_action_form ol li{padding:4px;}
13
+ .ca_action_form .bold {font-weight:bold;}
14
+ </style>
15
+ <%= form_for @chimpaction, :html => {:class => 'ca_action_form'} do |c| %>
16
+ <%= render "chimpactions/errors", :target => @chimpaction %>
17
+ <fieldset>
18
+ <ol>
19
+ <li><%= c.label :when, {:class => 'bold'} %> <%= Chimpactions.registered_class_name%>.<%= c.text_field :whenn, {:size => '15'} %> </li>
20
+ <li><%= select(:chimpaction, :is, %w(= < >)) %> <%= c.text_field :value %><%= c.label '(Value)' %></li>
21
+ <li><%= c.label "THEN", {:class => 'bold'}%></li>
22
+ <li><%= select(:chimpaction, :action, %w(add_to move_to remove_from).map {|l| [l.gsub('_',' ').titleize , l]}) -%></li>
23
+ <li><%= collection_select(:chimpaction, :list, Chimpactions.available_lists, :name, :name)%></li>
24
+ <li><%= submit_tag "submit"%></li>
25
+ </fieldset>
26
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <style>
2
+ .ca_list {list-style:none;padding:0px;}
3
+ </style>
4
+ <ul class="ca_list">
5
+ <li><%= list.name%> ( ID : <%= list.id %> )</li>
6
+ </ul>
@@ -0,0 +1,4 @@
1
+ <section>
2
+ <h1>EDIT Chimpaction : </h1>
3
+ <%= render :partial => 'form'%>
4
+ </section>
@@ -0,0 +1,22 @@
1
+ <section>
2
+ <% %w(notice warning error).each do |msg| %>
3
+ <% unless flash[msg.to_sym].blank? %>
4
+ <div class='message <%=msg-%>'><p><%=flash[msg.to_sym]-%></p></div>
5
+ <% end %>
6
+ <% end %>
7
+ <h1>Current Chimpactions : </h1>
8
+ <ul>
9
+ <% @actions.each do |action|%>
10
+ <li> When a <%= @registered %> <%= action.whenn %> <%= action.is %> <%= action.value %> => <%= @registered%>.<%= action.action %> (<%= action.list %>)
11
+ <%= link_to 'Edit', edit_chimpaction_path(action) %> ||
12
+ <%= link_to 'Destroy', chimpaction_path(action.id), :confirm => 'Are you sure?', :method => :delete %></li>
13
+ <%end%>
14
+ </ul>
15
+ </section>
16
+ <section>
17
+ <h1> <%= link_to "Add New Chimpaction", new_chimpaction_path %> </h1>
18
+ </section>
19
+ <section>
20
+ <h1>Your MailChimp lists: </h1>
21
+ <%= render :partial => 'list', :collection => @lists if @lists.count > 0%>
22
+ </section>