correole 0.0.2 → 0.0.7

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