correole 0.0.2 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: fa914631ebd1483e1e4ec3f2e72b2e6ad8b0842c
4
- data.tar.gz: 48491bc95bdfaaf363f337dfce859af9310225a6
2
+ SHA256:
3
+ metadata.gz: c383918b800ea3b2cbe74401782d07e462762a89659e917275c938234e4e3aa4
4
+ data.tar.gz: 50497adea72cd5b913eb02e748a8cf521c49d5540ef65ace4efba4da67409cde
5
5
  SHA512:
6
- metadata.gz: 5ff71315753d357a1db73ca235e18d1f58c1c443e0b8f543439c00ba0210eedfb8ad5a9567fb492d362d8639273d2a2b21eec5a6712f2e87f2a6330edc4149ca
7
- data.tar.gz: d2c0e6bbeb236291e188e6e14009cb0fb9668b50c3b0f09303239efb52a5ed76c90ccb9adb216e755ba26fc29fe121d25d799299f24de2a1ccdbb948c82c6058
6
+ metadata.gz: 8873b9c5abb6dfe2806f1ee2509d6633fb3a07c771c5df39ff78e6839ee2454ac7037a49a8d58b4ff7ca8f94d1339bf68dd150f409b0b7636e6896fddb65c645
7
+ data.tar.gz: '07618872e9306c83cb78ae5a12452f18f8f623cb28b1340b0367b2c1fbaed46207bc9d29d6021c7c9dd7956ffdb25f8d329073bec28e38471288e5e45cb329fd'
@@ -12,8 +12,11 @@ Configuration.quiet = ARGV.second == '-q'
12
12
  case ARGV.first
13
13
  when 'send'
14
14
  Send.run!
15
- when 'purge'
16
- Purge.run!
15
+ when 'test'
16
+ Configuration.dry_run = true
17
+ Send.run!
18
+ when 'skip'
19
+ Skip.run!
17
20
  else
18
21
  abort "Unknown parameters #{ARGV}."
19
22
  end
@@ -0,0 +1,40 @@
1
+ test:
2
+ quiet: true
3
+ dry_run: false
4
+ dry_run_email: test@mail.com
5
+ base_uri: http://test.ruslanledesma.com
6
+ feed: http://ruslanledesma.com/feed.xml # reset by env for end-to-end test
7
+ unsubscribe_uri: 'http://newsletter.ruslanledesma.com/unsubscribe/?email=<%= recipient %>'
8
+ confirmation_uri: http://newsletter.ruslanledesma.com/unsubscribed/
9
+ subject: 'Test <%= title %> - <%= date %>'
10
+ from: '<%= title %> <no-reply@ruslanledesma.com>'
11
+ html_template: templates/test.html.erb
12
+ plain_template: templates/test.txt.erb
13
+ smtp_host: localhost # reset by env for end-to-end test
14
+ smtp_port: 25 # reset by env for end-to-end test
15
+ smtp_user:
16
+ smtp_pass:
17
+ smtp_auth:
18
+ smtp_ttls: false
19
+
20
+ development: &dev
21
+ quiet: false
22
+ dry_run: false
23
+ dry_run_email: your.email@mail.com
24
+ base_uri: http://newsletter.ruslanledesma.com
25
+ feed: http://ruslanledesma.com/feed.xml
26
+ unsubscribe_uri: 'http://ruslanledesma.com/unsubscribe/?email=<%= recipient %>'
27
+ confirmation_uri: http://ruslanledesma.com/unsubscribed/
28
+ subject: '<%= title %>: newsletter for <%= date %>'
29
+ from: '<%= title %> <no-reply@ruslanledesma.com>'
30
+ html_template: templates/production.html.erb
31
+ plain_template: templates/production.txt.erb
32
+ smtp_host:
33
+ smtp_port:
34
+ smtp_user:
35
+ smtp_pass:
36
+ smtp_auth:
37
+ smtp_ttls:
38
+
39
+ production:
40
+ <<: *dev
@@ -2,13 +2,19 @@ DEFAULT_ENV = 'production'
2
2
  DEFAULT_CONFIG_FILE = 'config.yml'
3
3
 
4
4
  ENV['RACK_ENV'] ||= DEFAULT_ENV
5
- ENV['CONFIG_FILE'] ||= DEFAULT_CONFIG_FILE
5
+ ENV['CONFIG_FILE'] ||= File.expand_path "../#{DEFAULT_CONFIG_FILE}", __FILE__
6
6
 
7
7
  class Configuration
8
8
 
9
- CONFIG_KEYS = [
9
+ BOOLEAN_KEYS = [
10
10
  'QUIET',
11
+ 'DRY_RUN',
12
+ 'SMTP_TTLS'
13
+ ]
14
+ CONFIG_KEYS = [
15
+ 'DRY_RUN_EMAIL',
11
16
  'FEED',
17
+ 'UNSUBSCRIBE_URI',
12
18
  'CONFIRMATION_URI',
13
19
  'BASE_URI',
14
20
  'SUBJECT',
@@ -20,7 +26,7 @@ class Configuration
20
26
  'SMTP_USER',
21
27
  'SMTP_PASS',
22
28
  'SMTP_AUTH',
23
- 'SMTP_TTLS' ]
29
+ ] + BOOLEAN_KEYS
24
30
 
25
31
  class << self
26
32
  CONFIG_KEYS.each do |k|
@@ -30,19 +36,18 @@ class Configuration
30
36
 
31
37
  def self.load!
32
38
 
33
- config_file = File.expand_path "../#{ENV['CONFIG_FILE']}", __FILE__
34
- YAML.load_file(config_file)[ENV['RACK_ENV']].each_pair do |k, v|
35
- ENV[k.upcase] ||= v.to_s rescue abort "Cannot load configuration key #{k}."
36
- end rescue qputs "Could not load configuration file #{config_file}."
39
+ YAML.load_file(ENV['CONFIG_FILE'])[ENV['RACK_ENV']].each_pair do |k, v|
40
+ ENV[k.upcase] ||= v.to_s rescue abort("Cannot load configuration key #{k}.")
41
+ end rescue qputs "Cannot load configuration file #{ENV['CONFIG_FILE']}. Using configuration given by environment."
37
42
 
38
43
  CONFIG_KEYS.each do |k|
39
44
  case k
40
- when 'QUIET', 'SMTP_TTLS'
45
+ when *BOOLEAN_KEYS
41
46
  # Cannot store boolean values in ENV, thus this.
42
47
  self.send("#{k.downcase}=".to_sym, ENV[k] == 'true')
43
48
  when 'HTML_TEMPLATE', 'PLAIN_TEMPLATE'
44
- file = File.expand_path "../#{ENV[k]}", __FILE__
45
- template = File.read file rescue abort "Cannot load template #{ENV[k]}."
49
+ path = File.expand_path "../#{ENV[k]}", __FILE__
50
+ template = File.read path rescue abort "Cannot load template #{path}."
46
51
  self.send("#{k.downcase}=".to_sym, template)
47
52
  when 'SMTP_USER', 'SMTP_PASS'
48
53
  # For user name and password, Mail interprets '' as an input.
@@ -1,12 +1,13 @@
1
1
  require 'sinatra/base'
2
2
  require 'sinatra/activerecord'
3
+ require 'active_support/core_ext/hash'
3
4
  require 'correole/qputs'
4
5
  require 'correole/subscriber'
5
6
  require 'correole/item'
6
7
  require 'correole/feed'
7
8
  require 'correole/api'
8
9
  require 'correole/send'
9
- require 'correole/purge'
10
+ require 'correole/skip'
10
11
  require 'net/http'
11
12
  require 'mail'
12
13
  require 'configuration'
@@ -1,4 +1,4 @@
1
- class CreateDatabase < ActiveRecord::Migration
1
+ class CreateDatabase < ActiveRecord::Migration[6.0]
2
2
  def change
3
3
  create_table :subscribers do |t|
4
4
  t.string :email, null: false
@@ -1,4 +1,4 @@
1
- class CreateItems < ActiveRecord::Migration
1
+ class CreateItems < ActiveRecord::Migration[6.0]
2
2
  def change
3
3
  create_table :items do |t|
4
4
  t.string :title, null: false
@@ -9,12 +9,15 @@ class Api < Sinatra::Base
9
9
  set :server, :thin
10
10
  enable :logging
11
11
  disable :show_exceptions
12
- use ActiveRecord::ConnectionAdapters::ConnectionManagement
13
12
 
14
13
  before do
15
14
  content_type 'text/plain'
16
15
  end
17
16
 
17
+ after do
18
+ ActiveRecord::Base.clear_active_connections!
19
+ end
20
+
18
21
  def subscribe(params)
19
22
  response.headers['Access-Control-Allow-Origin'] = SUBSCRIBERS_ALLOWED_ORIGIN
20
23
  s = Subscriber.new(email: params[:email])
@@ -26,7 +29,7 @@ class Api < Sinatra::Base
26
29
  logger.info("Already subscribed #{params[:email]}.")
27
30
  Subscriber.find_by_email(params[:email]).touch
28
31
  end
29
- "#{params[:email]}\n"
32
+ [201, "#{params[:email]}\n"]
30
33
  end
31
34
 
32
35
  def unsubscribe(params)
@@ -44,16 +47,19 @@ class Api < Sinatra::Base
44
47
  end
45
48
 
46
49
  def subscribers_method_not_allowed
50
+ response.headers['Allow'] = SUBSCRIBERS_ALLOWED_METHODS
47
51
  response.headers['Access-Control-Allow-Methods'] = SUBSCRIBERS_ALLOWED_METHODS
48
52
  405
49
53
  end
50
54
 
51
55
  def unsubscribe_method_not_allowed
56
+ response.headers['Allow'] = UNSUBSCRIBE_ALLOWED_METHODS
52
57
  response.headers['Access-Control-Allow-Methods'] = UNSUBSCRIBE_ALLOWED_METHODS
53
58
  405
54
59
  end
55
60
 
56
61
  options '/subscribers/:email' do
62
+ response.headers['Allow'] = SUBSCRIBERS_ALLOWED_METHODS
57
63
  response.headers['Access-Control-Allow-Methods'] = SUBSCRIBERS_ALLOWED_METHODS
58
64
  response.headers['Access-Control-Allow-Origin'] = SUBSCRIBERS_ALLOWED_ORIGIN
59
65
  200
@@ -77,6 +83,7 @@ class Api < Sinatra::Base
77
83
  end
78
84
 
79
85
  options "#{UNSUBSCRIBE_PATH}/:email" do
86
+ response.headers['Allow'] = UNSUBSCRIBE_ALLOWED_METHODS
80
87
  response.headers['Access-Control-Allow-Methods'] = UNSUBSCRIBE_ALLOWED_METHODS
81
88
  response.headers['Access-Control-Allow-Origin'] = UNSUBSCRIBE_ALLOWED_ORIGIN
82
89
  200
@@ -33,5 +33,4 @@ class Feed
33
33
  return split_feed
34
34
  end
35
35
 
36
-
37
36
  end
@@ -12,47 +12,57 @@ class Send
12
12
  split_feed[:unsent_item].each_with_index { |i, j| qputs "[#{j+1}] #{i.link}" }
13
13
  html = compose_html split_feed
14
14
  plain = compose_plain split_feed
15
- count = Subscriber.count
16
- Subscriber.find_each.with_index do |s, i|
17
- html_s = personalize html, s.email
18
- plain_s = personalize plain, s.email
19
- qputs "[#{i+1}/#{count}] Send newsletter to #{s.email}."
15
+ rr = recipients
16
+ rr.each_with_index do |r, i|
17
+ html_r = personalize html, r.email
18
+ plain_r = personalize plain, r.email
19
+ qputs "[#{i+1}/#{rr.size}] Send newsletter to #{r.email}."
20
20
  begin
21
- send_out feed[:title], html_s, plain_s, s.email
21
+ send_out feed[:title], html_r, plain_r, r.email
22
22
  rescue => exc
23
- qputs "Could not send newsletter to #{s.email} for the following reason."
23
+ qputs "Could not send newsletter to #{r.email} for the following reason."
24
24
  qputs exc.message
25
25
  end
26
26
  end
27
- qputs 'Remember new items.'
28
- split_feed[:unsent_item].each { |i| i.save }
27
+ if not Configuration.dry_run
28
+ qputs 'Remember new items.'
29
+ split_feed[:unsent_item].each { |i| i.save }
30
+ end
29
31
  qputs 'Done.'
30
32
  end
31
33
 
32
34
  private
33
35
 
36
+ def self.recipients
37
+ if Configuration.dry_run
38
+ s = Subscriber.new(email: Configuration.dry_run_email)
39
+ return [s].each
40
+ end
41
+ return Subscriber.find_each
42
+ end
43
+
34
44
  def self.template_bindings(split_feed)
35
45
  title = split_feed[:title]
36
- unsent_items = split_feed[:unsent_item]
37
- sent_items = split_feed[:sent_item]
38
- unsubscribe_uri = nil # supress unused variable warning
39
- unsubscribe_uri = "#{Configuration.base_uri}#{Api::UNSUBSCRIBE_PATH}/<%= recipient %>"
40
46
  title = '' if !title.is_a?(String)
47
+ unsent_items = split_feed[:unsent_item]
41
48
  unsent_items = [] if !unsent_items.is_a?(Array)
42
- sent_items = [] if !unsent_items.is_a?(Array)
49
+ sent_items = split_feed[:sent_item]
50
+ sent_items = [] if !sent_items.is_a?(Array)
51
+ unsubscribe_uri = Configuration.unsubscribe_uri
52
+ if false then unsubscribe_uri end # suppress unused variable warning
43
53
  return binding
44
54
  end
45
55
 
46
56
  def self.compose_html(split_feed)
47
57
  template = Configuration.html_template
48
58
  bindings = template_bindings(split_feed)
49
- return ERB.new(template, nil, '-').result(bindings)
59
+ return ERB.new(template, trim_mode: '-').result(bindings)
50
60
  end
51
61
 
52
62
  def self.compose_plain(split_feed)
53
63
  template = Configuration.plain_template
54
64
  bindings = template_bindings(split_feed)
55
- return ERB.new(template, nil, '-').result(bindings)
65
+ return ERB.new(template, trim_mode: '-').result(bindings)
56
66
  end
57
67
 
58
68
  def self.personalize(message, recipient)
@@ -60,8 +70,8 @@ class Send
60
70
  end
61
71
 
62
72
  def self.send_out(title, html, plain, recipient)
63
- date = nil # supress unused variable warning
64
73
  date = Date.today.strftime('%a, %d %b %Y')
74
+ if false then date end # suppress unused variable warning
65
75
  Mail.deliver do
66
76
  to recipient
67
77
  from ERB.new(Configuration.from).result(binding)
@@ -1,4 +1,4 @@
1
- class Purge
1
+ class Skip
2
2
 
3
3
  def self.run!
4
4
  qputs "Fetch feed from #{Configuration.feed}."
@@ -10,7 +10,7 @@ class Purge
10
10
  end
11
11
  qputs "There are #{unsent_items.length} new items. The items are the following."
12
12
  unsent_items.each_with_index { |i, j| qputs "[#{j+1}] #{i.link}" }
13
- qputs 'Purge the new items by remembering them.'
13
+ qputs 'Skip the new items by remembering them.'
14
14
  unsent_items.each { |i| i.save }
15
15
  qputs 'Done.'
16
16
  end
@@ -1,4 +1,4 @@
1
1
  module Correole
2
- VERSION = '0.0.2'
3
- DATE = '2016-07-26'
2
+ VERSION = '0.0.7'
3
+ DATE = '2020-07-19'
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: correole
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ruslan Ledesma Garza
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-26 00:00:00.000000000 Z
11
+ date: 2020-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sinatra
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.4'
19
+ version: '2.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.4'
26
+ version: '2.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: thin
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -58,42 +58,42 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '4.2'
61
+ version: '6.0'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '4.2'
68
+ version: '6.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: activesupport
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '4.2'
75
+ version: '6.0'
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '4.2'
82
+ version: '6.0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: mail
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '2.6'
89
+ version: '2.7'
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '2.6'
96
+ version: '2.7'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: pg
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -114,42 +114,42 @@ dependencies:
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '1.3'
117
+ version: '1.4'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: '1.3'
124
+ version: '1.4'
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: minitest
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: '5.9'
131
+ version: '5.14'
132
132
  type: :development
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: '5.9'
138
+ version: '5.14'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: rack-test
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: '0.6'
145
+ version: '1.1'
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
- version: '0.6'
152
+ version: '1.1'
153
153
  - !ruby/object:Gem::Dependency
154
154
  name: mini-smtp-server
155
155
  requirement: !ruby/object:Gem::Requirement
@@ -184,14 +184,14 @@ dependencies:
184
184
  requirements:
185
185
  - - "~>"
186
186
  - !ruby/object:Gem::Version
187
- version: '11.2'
187
+ version: '13.0'
188
188
  type: :development
189
189
  prerelease: false
190
190
  version_requirements: !ruby/object:Gem::Requirement
191
191
  requirements:
192
192
  - - "~>"
193
193
  - !ruby/object:Gem::Version
194
- version: '11.2'
194
+ version: '13.0'
195
195
  description: |
196
196
  Correole is a webservice that subscribes and unsubscribes readers from
197
197
  a newsletter.
@@ -202,23 +202,22 @@ extensions: []
202
202
  extra_rdoc_files: []
203
203
  files:
204
204
  - bin/correole
205
+ - config/config.yml
205
206
  - config/configuration.rb
206
207
  - config/database.yml
207
208
  - config/dependencies.rb
208
- - config/example.config.yml
209
- - config/production.html.erb
210
- - config/production.txt.erb
211
- - config/test.config.yml
212
- - config/test.html.erb
213
- - config/test.txt.erb
209
+ - config/templates/production.html.erb
210
+ - config/templates/production.txt.erb
211
+ - config/templates/test.html.erb
212
+ - config/templates/test.txt.erb
214
213
  - db/migrate/0001_create_database.rb
215
214
  - db/migrate/0002_create_items.rb
216
215
  - lib/correole/api.rb
217
216
  - lib/correole/feed.rb
218
217
  - lib/correole/item.rb
219
- - lib/correole/purge.rb
220
218
  - lib/correole/qputs.rb
221
219
  - lib/correole/send.rb
220
+ - lib/correole/skip.rb
222
221
  - lib/correole/subscriber.rb
223
222
  - lib/correole/version.rb
224
223
  homepage: http://ruslanledesma.com/
@@ -228,20 +227,20 @@ metadata: {}
228
227
  post_install_message:
229
228
  rdoc_options: []
230
229
  require_paths:
230
+ - config
231
231
  - lib
232
232
  required_ruby_version: !ruby/object:Gem::Requirement
233
233
  requirements:
234
234
  - - "~>"
235
235
  - !ruby/object:Gem::Version
236
- version: 2.3.1
236
+ version: 2.7.1
237
237
  required_rubygems_version: !ruby/object:Gem::Requirement
238
238
  requirements:
239
239
  - - ">="
240
240
  - !ruby/object:Gem::Version
241
241
  version: '0'
242
242
  requirements: []
243
- rubyforge_project:
244
- rubygems_version: 2.5.1
243
+ rubygems_version: 3.1.2
245
244
  signing_key:
246
245
  specification_version: 4
247
246
  summary: A newsletter webservice
@@ -1,18 +0,0 @@
1
- production: &prod
2
- quiet: false
3
- base_uri: http://newsletter.ruslanledesma.com
4
- feed: http://ruslanledesma.com/feed.xml
5
- confirmation_uri: http://ruslanledesma.com/unsubscribed/
6
- subject: '<%= title %>: newsletter for <%= date %>'
7
- from: '<%= title %> <no-reply@ruslanledesma.com>'
8
- html_template: production.html.erb
9
- plain_template: production.txt.erb
10
- smtp_host:
11
- smtp_port:
12
- smtp_user:
13
- smtp_pass:
14
- smtp_auth:
15
- smtp_ttls:
16
-
17
- development:
18
- <<: *prod
@@ -1,15 +0,0 @@
1
- test:
2
- quiet: true
3
- base_uri: http://test.ruslanledesma.com
4
- feed: http://ruslanledesma.com/feed.xml # reset by env for end-to-end test
5
- confirmation_uri: http://newsletter.ruslanledesma.com
6
- subject: 'Test <%= title %> - <%= date %>'
7
- from: '<%= title %> <no-reply@ruslanledesma.com>'
8
- html_template: test.html.erb
9
- plain_template: test.txt.erb
10
- smtp_host: localhost # reset by env for end-to-end test
11
- smtp_port: 25 # reset by env for end-to-end test
12
- smtp_user:
13
- smtp_pass:
14
- smtp_auth:
15
- smtp_ttls: false