chimpmunk 0.0.1

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.
@@ -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