chimpmunk 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,69 @@
1
+ # encoding: utf-8
2
+ module Chimpmunk
3
+ class EmailList < ::ActiveRecord::Base
4
+
5
+ # rails 3
6
+ attr_accessible :default_from_email, :default_from_name, :default_subject, :mailchimp_id, :name if defined?(ActiveModel::MassAssignmentSecurity)
7
+
8
+ # Associations
9
+ has_many :email_campaigns
10
+ has_many :email_list_groupings, dependent: :destroy
11
+ has_many :email_subscribers
12
+
13
+ # Validations
14
+ validates :name, presence: true
15
+
16
+ # Nested Attributes
17
+ accepts_nested_attributes_for :email_list_groupings, allow_destroy: true
18
+ accepts_nested_attributes_for :email_subscribers, allow_destroy: true
19
+
20
+ #
21
+ # refresh email lists
22
+ #
23
+ def self.refresh_email_lists
24
+ lists = Chimpmunk.mailchimp.lists.list
25
+ lists['data'].each do |list|
26
+ next if Chimpmunk::EmailList.where(mailchimp_id: list['id']).first
27
+
28
+ Chimpmunk::EmailList.create(
29
+ mailchimp_id: list['id'],
30
+ name: list['name'],
31
+ default_from_name: list['default_from_name'],
32
+ default_from_email: list['default_from_email'],
33
+ default_subject: list['default_subject']
34
+ )
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ if defined?(RailsAdmin)
41
+
42
+ rails_admin do
43
+ navigation_label 'Mailchimp'
44
+
45
+ edit do
46
+ field :mailchimp_id do
47
+ label 'Mailchimp ID'
48
+ read_only true
49
+ end
50
+ field :name do
51
+ read_only true
52
+ end
53
+ field :default_from_name do
54
+ read_only true
55
+ end
56
+ field :default_from_email do
57
+ read_only true
58
+ end
59
+ field :default_subject do
60
+ read_only true
61
+ end
62
+ field :email_list_groupings
63
+ end
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+ end
@@ -0,0 +1,98 @@
1
+ # encoding: utf-8
2
+ module Chimpmunk
3
+ class EmailListGroup < ::ActiveRecord::Base
4
+
5
+ # rails 3
6
+ attr_accessible :name if defined?(ActiveModel::MassAssignmentSecurity)
7
+
8
+ # Associations
9
+ belongs_to :email_list_grouping, foreign_key: :grouping_id, inverse_of: :email_list_groups
10
+ has_and_belongs_to_many :email_subscribers, before_add: :add_subscriber_grouping, before_remove: :remove_subscriber_grouping
11
+ has_many :email_campaigns, inverse_of: :email_list_group
12
+
13
+ # Valiations
14
+ validates_uniqueness_of :name, scope: :grouping_id
15
+
16
+ # Callbacks
17
+ before_update :update_name
18
+
19
+ private
20
+
21
+ ##
22
+ # updates the name via the mailchimp api
23
+ def update_name
24
+ mailchimp.lists.interest_group_update(
25
+ id: self.email_list_grouping.email_list.mailchimp_id,
26
+ old_name: self.name_was,
27
+ new_name: self.name,
28
+ grouping_id: self.email_list_grouping.mailchimp_grouping_id
29
+ )
30
+ end
31
+
32
+ ##
33
+ # Adds a subscriber grouping via mailcimp api
34
+ def add_subscriber_grouping(email_subscriber)
35
+ groups = (email_subscriber.email_list_groups.where(grouping_id: self.grouping_id).pluck(:name) << self.name).uniq
36
+
37
+ mailchimp.lists.subscribe(
38
+ id: self.email_list_grouping.email_list.mailchimp_id,
39
+ email: { email: email_subscriber.email },
40
+ merge_vars: {
41
+ groupings: [
42
+ {
43
+ id: self.email_list_grouping.mailchimp_grouping_id,
44
+ groups: groups
45
+ }
46
+ ]
47
+ },
48
+ update_existing: true
49
+ )
50
+ end
51
+
52
+ ##
53
+ # removes a subscriber grouping via mailchimp api
54
+ def remove_subscriber_grouping(email_subscriber)
55
+ groups = email_subscriber.email_list_groups.where(grouping_id: self.grouping_id).pluck(:name).uniq
56
+ groups.delete(self.name)
57
+
58
+ mailchimp.lists.update_member(
59
+ id: self.email_list_grouping.email_list.mailchimp_id,
60
+ email: { email: email_subscriber.email },
61
+ merge_vars: {
62
+ groupings: [
63
+ {
64
+ id: self.email_list_grouping.mailchimp_grouping_id,
65
+ groups: groups
66
+ }
67
+ ]
68
+ }
69
+ )
70
+ end
71
+
72
+ if defined?(RailsAdmin)
73
+ rails_admin do
74
+ navigation_label 'Mailchimp'
75
+ visible false
76
+ edit do
77
+ field :name
78
+ field :email_subscribers do
79
+ column_width 1200
80
+ associated_collection_scope do
81
+ form = bindings[:form]
82
+ binding_object = bindings[:object]
83
+ list = if form
84
+ bindings[:form].options[:parent_builder].options[:parent_builder].object
85
+ elsif binding_object
86
+ binding_object.email_list_grouping.email_list
87
+ end
88
+
89
+ Proc.new { |scope|
90
+ scope = scope.where(email_list_id: list.id, subscribed: true)
91
+ } if list
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,102 @@
1
+ # encoding: utf-8
2
+ module Chimpmunk
3
+ class EmailListGrouping < ::ActiveRecord::Base
4
+
5
+ # rails 3
6
+ attr_accessible :name if defined?(ActiveModel::MassAssignmentSecurity)
7
+
8
+ # Associations
9
+ belongs_to :email_list, inverse_of: :email_list_groupings
10
+ has_many :email_list_groups, foreign_key: :grouping_id, dependent: :destroy,
11
+ before_add: :create_mailchimp_group, before_remove: :remove_mailchimp_group
12
+
13
+ # Nested Attribute
14
+ accepts_nested_attributes_for :email_list_groups, allow_destroy: true, limit: 60
15
+
16
+ # Callbacks
17
+ before_create :create_mailchimp_grouping
18
+ before_destroy :destroy_mailchimp_grouping
19
+ before_update :update_mailchimp_grouping, if: Proc.new{|record| record.name_changed? }
20
+
21
+ private
22
+
23
+ ##
24
+ # create the mailchimp grouping before db create
25
+ def create_mailchimp_grouping
26
+ return false if email_list_groups.length < 1 # groupings have to have at least one group
27
+
28
+ interest_grouping = mailchimp.lists.interest_grouping_add(
29
+ name: name,
30
+ type: 'checkboxes',
31
+ id: email_list.mailchimp_id,
32
+ groups: email_list_groups.pluck(:name)
33
+ )
34
+
35
+ self.mailchimp_grouping_id = interest_grouping['id']
36
+ end
37
+
38
+ ##
39
+ # delete the mailchimp grouping
40
+ def destroy_mailchimp_grouping
41
+ # don't care if it fails
42
+ begin
43
+ mailchimp.lists.interest_grouping_del(grouping_id: self.mailchimp_grouping_id)
44
+ rescue
45
+ end
46
+ end
47
+
48
+ ##
49
+ # update the mailchimp groupings name
50
+ def update_mailchimp_grouping
51
+ mailchimp.lists.interest_grouping_update(
52
+ grouping_id: self.mailchimp_grouping_id,
53
+ name: 'name',
54
+ value: self.name
55
+ )
56
+ end
57
+
58
+ ##
59
+ # remove grouping only if single grouping being removed and we have more than 1 to remove
60
+ def remove_mailchimp_group(email_list_group)
61
+ if !self.marked_for_destruction? &&
62
+ !self.email_list_groups.count == 1 &&
63
+ email_list_group.marked_for_destruction?
64
+
65
+ mailchimp.lists.interest_group_del(
66
+ id: self.email_list.mailchimp_id,
67
+ group_name: email_list_group.name,
68
+ groupind_id: self.mailchimp_grouping_id
69
+ )
70
+ end
71
+ end
72
+
73
+ #
74
+ # creates a mailchimp group (only if adding to an existing grouping, not on grouping creation)
75
+ #
76
+ def create_mailchimp_group(email_list_group)
77
+ # if new grouping, groups are created in the grouping api call
78
+ return if email_list_group.grouping_id.nil?
79
+
80
+ if email_list_group.new_record?
81
+ mailchimp.lists.interest_group_add(
82
+ id: self.email_list.mailchimp_id,
83
+ group_name: email_list_group.name,
84
+ grouping_id: self.mailchimp_grouping_id
85
+ )
86
+ end
87
+ end
88
+
89
+ if defined?(RailsAdmin)
90
+ rails_admin do
91
+ navigation_label 'Mailchimp'
92
+ visible false
93
+
94
+ edit do
95
+ field :email_list
96
+ field :name
97
+ field :email_list_groups
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,74 @@
1
+ # encoding: utf-8
2
+ module Chimpmunk
3
+ class EmailSubscriber < ::ActiveRecord::Base
4
+
5
+ # rails 3
6
+ attr_accessible :mailchimp_id, :first_name, :last_name, :email, :subscribed, :email_list_id if defined?(ActiveModel::MassAssignmentSecurity)
7
+
8
+ # Validations
9
+ validates :email, presence: true, uniqueness: true
10
+ validates :email_list, presence: true
11
+
12
+ # Associations
13
+ has_and_belongs_to_many :email_list_groups
14
+ belongs_to :email_list
15
+
16
+ # Callbacks
17
+ before_create :create_mailchimp_subscriber
18
+ before_destroy :destroy_mailchimp_subscriber
19
+
20
+ private
21
+
22
+ ##
23
+ # create the subscription on mailchimp
24
+ def create_mailchimp_subscriber
25
+ Chimpmunk.mailchimp.lists.subscribe({
26
+ id: self.email_list.mailchimp_id,
27
+ email: { email: self.email }
28
+ })
29
+ end
30
+
31
+ ##
32
+ # do the mailchimp unsubscribe first
33
+ def destroy_mailchimp_subscriber
34
+ begin
35
+ Chimpmunk.mailchimp.lists.unsubscribe({
36
+ id: self.email_list.mailchimp_id,
37
+ email: { email: self.email }
38
+ })
39
+ rescue Gibbon::MailChimpError => e
40
+ # don't care if the user isn't a subscriber to the list, only if there was another error
41
+ raise Gibbon::MailchimpError unless e.message.include?('is not subscribed to list')
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ if defined?(RailsAdmin)
48
+ rails_admin do
49
+ navigation_label 'Mailchimp'
50
+ list do
51
+ field :mailchimp_id
52
+ field :first_name
53
+ field :last_name
54
+ field :email
55
+ field :subscribed
56
+ field :email_list
57
+ end
58
+ edit do
59
+ field :email_list do
60
+ inline_add false
61
+ inline_edit false
62
+ end
63
+ field :mailchimp_id do
64
+ label "Mailchimp ID"
65
+ read_only true
66
+ end
67
+ field :first_name
68
+ field :last_name
69
+ field :email
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+ module Chimpmunk
3
+ class EmailTemplate < ::ActiveRecord::Base
4
+
5
+ # rails 3
6
+ attr_accessible :mailchimp_id, :name, :layout, :preview_image if defined?(ActiveModel::MassAssignmentSecurity)
7
+
8
+ # Assocaitions
9
+ has_many :email_campaigns
10
+
11
+ private
12
+
13
+ if defined?(RailsAdmin)
14
+ rails_admin do
15
+ navigation_label 'Mailchimp'
16
+ visible false
17
+ show do
18
+ field :name
19
+ field :layout
20
+ field :preview_image do
21
+ pretty_value do
22
+ "<img src='#{value}' />".html_safe
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,8 @@
1
+ require 'rails'
2
+ require 'rails/engine'
3
+ require 'chimpmunk'
4
+
5
+ module Chimpmunk
6
+ class Engine < Rails::Engine
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ module Chimpmunk
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,50 @@
1
+ require 'rails/generators'
2
+
3
+ module Chimpmunk
4
+ class InstallGenerator < Rails::Generators::Base
5
+ def install
6
+ rails_admin_initializer = "#{Rails.root}/config/initializers/rails_admin.rb"
7
+ if File.exist?(rails_admin_initializer)
8
+ inject_into_file rails_admin_initializer, after: 'RailsAdmin.config do |config|' do <<-'TEMPLATE'
9
+
10
+ # include all custom actions from lib/rails_admin
11
+ Dir["#{Rails.root}/lib/rails_admin/*.rb"].each {|file| require file }
12
+
13
+ # include all existing models and Chimpmunk models
14
+ config.included_models = Dir.glob("#{Rails.root}/app/models/*.rb").map{|x| File.basename(x, ".rb").camelize} + ['Chimpmunk::EmailCampaign', 'Chimpmunk::EmailList', 'Chimpmunk::EmailListGroup', 'Chimpmunk::EmailListGrouping', 'Chimpmunk::EmailSubscriber', 'Chimpmunk::EmailTemplate']
15
+
16
+ TEMPLATE
17
+ end
18
+
19
+ inject_into_file rails_admin_initializer, after: 'config.actions do' do <<-'TEMPLATE'
20
+
21
+ refresh_email_campaigns do
22
+ only 'Chimpmunk::EmailCampaign'
23
+ end
24
+
25
+ refresh_email_campaign_stats do
26
+ only 'Chimpmunk::EmailCampaign'
27
+ end
28
+
29
+ send_email_campaign do
30
+ only 'Chimpmunk::EmailCampaign'
31
+ end
32
+
33
+ schedule_email_campaign do
34
+ only 'Chimpmunk::EmailCampaign'
35
+ end
36
+
37
+ un_schedule_email_campaign do
38
+ only 'Chimpmunk::EmailCampaign'
39
+ end
40
+
41
+ refresh_email_lists do
42
+ only 'Chimpmunk::EmailList'
43
+ end
44
+
45
+ TEMPLATE
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,201 @@
1
+ require 'rails_admin/config/actions'
2
+ require 'rails_admin/config/actions/base'
3
+
4
+ module RailsAdmin
5
+ module Config
6
+ module Actions
7
+
8
+ #
9
+ # Refresh Email Lists
10
+ #
11
+ class RefreshEmailLists < RailsAdmin::Config::Actions::Base
12
+ RailsAdmin::Config::Actions.register(self)
13
+
14
+ register_instance_option :collection? do
15
+ true
16
+ end
17
+
18
+ register_instance_option :link_icon do
19
+ 'icon-refresh'
20
+ end
21
+
22
+ register_instance_option :controller do
23
+ Proc.new do
24
+ @abstract_model.model_name.constantize.refresh_email_lists()
25
+ redirect_to rails_admin.index_path('chimpmunk~email_list')
26
+ end
27
+ end
28
+ end
29
+
30
+ #
31
+ # Refresh Email Campaigns
32
+ #
33
+ class RefreshEmailCampaigns < RailsAdmin::Config::Actions::Base
34
+ RailsAdmin::Config::Actions.register(self)
35
+
36
+ register_instance_option :collection? do
37
+ true
38
+ end
39
+
40
+ register_instance_option :link_icon do
41
+ 'icon-refresh'
42
+ end
43
+
44
+ register_instance_option :controller do
45
+ Proc.new do
46
+ @abstract_model.model_name.constantize.refresh_email_campaigns()
47
+ redirect_to rails_admin.index_path("chimpmunk~email_campaign")
48
+ end
49
+ end
50
+ end
51
+
52
+ #
53
+ # Refresh Email Campaigns
54
+ #
55
+ class RefreshEmailCampaignStats < RailsAdmin::Config::Actions::Base
56
+ RailsAdmin::Config::Actions.register(self)
57
+
58
+ register_instance_option :collection? do
59
+ true
60
+ end
61
+
62
+ register_instance_option :link_icon do
63
+ 'icon-signal'
64
+ end
65
+
66
+ register_instance_option :controller do
67
+ Proc.new do
68
+ @abstract_model.model_name.constantize.refresh_email_campaign_stats()
69
+ redirect_to rails_admin.index_path("chimpmunk~email_campaign")
70
+ end
71
+ end
72
+ end
73
+
74
+ #
75
+ # Duplicate Email Campaign
76
+ # => Allows the user to duplicate an email campaign
77
+ class DuplicateEmailCampaign < RailsAdmin::Config::Actions::Base
78
+ RailsAdmin::Config::Actions.register(self)
79
+
80
+ register_instance_option :member do
81
+ true
82
+ end
83
+
84
+ register_instance_option :link_icon do
85
+ 'icon-copy'
86
+ end
87
+
88
+ register_instance_option :pjax? do
89
+ false
90
+ end
91
+
92
+ register_instance_option :controller do
93
+ Proc.new do
94
+ # Would rather have this method be new instead of edit
95
+ @new_object = @object.duplicate_campaign
96
+ if @new_object.save
97
+ flash[:notice] = "Campaign was duplicated. Please edit the content now."
98
+ redirect_to rails_admin.edit_path("email_campaign", @new_object)
99
+ else
100
+ flash[:error] = "Campaign could not be duplicated."
101
+ redirect_to rails_admin.show_path("chimpmunk~email_campaign", @object)
102
+ end
103
+ end
104
+ end
105
+ end
106
+
107
+ #
108
+ # Immediate Send Email Campaign
109
+ # => Allows the user to send an email campaign
110
+ class SendEmailCampaign < RailsAdmin::Config::Actions::Base
111
+ RailsAdmin::Config::Actions.register(self)
112
+
113
+ register_instance_option :member do
114
+ true
115
+ end
116
+
117
+ register_instance_option :link_icon do
118
+ 'icon-envelope'
119
+ end
120
+
121
+ register_instance_option :pjax? do
122
+ false
123
+ end
124
+
125
+ register_instance_option :controller do
126
+ Proc.new do
127
+ if @object.send_campaign
128
+ flash[:notice] = "Campaign was successfully sent."
129
+ redirect_to rails_admin.index_path("chimpmunk~email_campaign")
130
+ else
131
+ flash[:error] = "Campaign could not be sent."
132
+ redirect_to rails_admin.show_path("chimpmunk~email_campaign", @object)
133
+ end
134
+ end
135
+ end
136
+ end
137
+
138
+ #
139
+ # Send Email Campaign on Schedule
140
+ # => Allows the user to scheduled send an email campaign
141
+ class ScheduleEmailCampaign < RailsAdmin::Config::Actions::Base
142
+ RailsAdmin::Config::Actions.register(self)
143
+
144
+ register_instance_option :member do
145
+ true
146
+ end
147
+
148
+ register_instance_option :link_icon do
149
+ 'icon-time'
150
+ end
151
+
152
+ register_instance_option :pjax? do
153
+ false
154
+ end
155
+
156
+ register_instance_option :controller do
157
+ Proc.new do
158
+ if @object.schedule_campaign
159
+ flash[:notice] = "Campaign was successfully scheduled."
160
+ redirect_to rails_admin.index_path("chimpmunk~email_campaign")
161
+ else
162
+ flash[:error] = "Campaign could not be scheduled."
163
+ redirect_to rails_admin.show_path("chimpmunk~email_campaign", @object)
164
+ end
165
+ end
166
+ end
167
+ end
168
+
169
+ #
170
+ # Un-Schedule Email Campaign
171
+ #
172
+ class UnScheduleEmailCampaign < RailsAdmin::Config::Actions::Base
173
+ RailsAdmin::Config::Actions.register(self)
174
+
175
+ register_instance_option :member do
176
+ true
177
+ end
178
+
179
+ register_instance_option :link_icon do
180
+ 'icon-remove-sign'
181
+ end
182
+
183
+ register_instance_option :pjax? do
184
+ false
185
+ end
186
+
187
+ register_instance_option :controller do
188
+ Proc.new do
189
+ if @object.unschedule_campaign
190
+ flash[:notice] = "Campaign was successfully un-scheduled."
191
+ redirect_to rails_admin.index_path("chimpmunk~email_campaign")
192
+ else
193
+ flash[:error] = "Campaign could not be un-scheduled."
194
+ redirect_to rails_admin.show_path("chimpmunk~email_campaign", @object)
195
+ end
196
+ end
197
+ end
198
+ end
199
+ end
200
+ end
201
+ end