feed2email 0.9.1 → 0.10.0

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
2
  SHA1:
3
- metadata.gz: e69b799d3cbd8ab553fedc851e4439103379867e
4
- data.tar.gz: ec73447b756ec375b735a827c9a843de960829ac
3
+ metadata.gz: dbcdf4e12f0075c8ecdb50cbbf4e4fdb9fef1959
4
+ data.tar.gz: f47dae1909bc87274d37eade561c68caa6e5f8b9
5
5
  SHA512:
6
- metadata.gz: 58ff89046e9cd04c210e9467ff31ccc176dffbe12a537a48d15bd21d857527ce70c55fd4be162fc4bf061942c7b91e54e0944b44baf52c080d273cd0b0f95cd6
7
- data.tar.gz: 4c83c6c595369c8a50ff535b18cd00a6b36387c26c4f3b0ccd1620097d57301db68438926e362a772d25629641c06a0f26efd13e13a73c56dbbedd891c92662c
6
+ metadata.gz: 8e7c27a67e616639c4e1bc9957e6b0189e7f7aaf9f5f55ad7f6f351196852671fa2c6690d0e30a797fcd02aead4adcc6ba0ab210748b4925451d4852f9468d3b
7
+ data.tar.gz: d063673ffa118876f8e9ec1d5728ec4be95c6688539320868fd96f0f43b274dc51c12ca2edf97466404ebabeb3838fa2262bce4dd53b3ee711d2129140dbdfea
@@ -1,3 +1,13 @@
1
+ ### 0.10.0
2
+
3
+ * Do not strip `nil` entry title to prevent exceptions
4
+ * Skip entries with missing data
5
+ * Fix relative URI fix mistaking a protocol-relative URI as relative
6
+ * Fix relative URI fix by converting it to String
7
+ * Confirm feed removal
8
+ * Show number of subscribed feeds in list command
9
+ * Print command to fix config file permissions
10
+
1
11
  ### 0.9.1
2
12
 
3
13
  * Fix feed type detection for secure feed URLs in OPML export
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # feed2email [![Gem Version](https://badge.fury.io/rb/feed2email.svg)](http://badge.fury.io/rb/feed2email)
1
+ # feed2email [![Gem Version](https://badge.fury.io/rb/feed2email.svg)](http://badge.fury.io/rb/feed2email) [![Build Status](https://travis-ci.org/agorf/feed2email.png?branch=master)](https://travis-ci.org/agorf/feed2email)
2
2
 
3
3
  feed2email is a [headless][] RSS/Atom feed aggregator that sends feed entries
4
4
  via email. It was initially written as a replacement of [rss2email][] and aims
@@ -31,7 +31,7 @@ $ gem install feed2email
31
31
  ~~~
32
32
 
33
33
  If the above command fails due to missing headers, make sure the following
34
- packages for [curb][] and [sqlite3][] gems are installed:
34
+ packages for [curb][] and [sqlite3][] gems are installed. For Debian, issue:
35
35
 
36
36
  ~~~ sh
37
37
  $ sudo apt-get install libcurl4-openssl-dev libsqlite3-dev
@@ -1,6 +1,8 @@
1
+ require 'logger'
2
+ require 'net/smtp'
1
3
  require 'pathname'
2
4
  require 'feed2email/config'
3
- require 'feed2email/logger'
5
+ require 'feed2email/database'
4
6
 
5
7
  module Feed2Email
6
8
  def self.config
@@ -16,10 +18,42 @@ module Feed2Email
16
18
  end
17
19
 
18
20
  def self.logger
19
- @logger ||= Logger.new(
20
- config['log_path'], config['log_level'], config['log_shift_age'],
21
- config['log_shift_size']
22
- ).logger
21
+ return @logger if @logger
22
+
23
+ if config['log_path'] == true
24
+ logdev = $stdout
25
+ elsif config['log_path'] # truthy but not true (a path)
26
+ logdev = File.expand_path(config['log_path'])
27
+ end
28
+
29
+ @logger = Logger.new(logdev, config['log_shift_age'],
30
+ config['log_shift_size'].megabytes)
31
+ @logger.level = Logger.const_get(config['log_level'].upcase)
32
+ @logger
33
+ end
34
+
35
+ def self.setup_database
36
+ @db ||= Database.new(
37
+ adapter: 'sqlite',
38
+ database: database_path,
39
+ loggers: [logger],
40
+ sql_log_level: :debug
41
+ )
42
+ end
43
+
44
+ def self.smtp_connection
45
+ return @smtp if @smtp
46
+
47
+ @smtp = Net::SMTP.new(config['smtp_host'], config['smtp_port'])
48
+ @smtp.enable_starttls if config['smtp_starttls']
49
+ @smtp.start('localhost',
50
+ config['smtp_user'],
51
+ config['smtp_pass'],
52
+ config['smtp_auth'].to_sym
53
+ )
54
+ at_exit { @smtp.finish }
55
+
56
+ @smtp
23
57
  end
24
58
 
25
59
  def self.root
@@ -1,12 +1,15 @@
1
1
  require 'thor'
2
+ require 'feed2email'
3
+ require 'feed2email/feed'
4
+ require 'feed2email/feed_autodiscoverer'
5
+ require 'feed2email/opml_exporter'
6
+ require 'feed2email/opml_importer'
7
+ require 'feed2email/version'
2
8
 
3
9
  module Feed2Email
4
10
  class Cli < Thor
5
11
  desc 'add URL', 'Subscribe to feed at URL'
6
12
  def add(uri)
7
- require 'feed2email/feed'
8
- require 'feed2email/feed_autodiscoverer'
9
-
10
13
  uri = autodiscover_feeds(uri)
11
14
 
12
15
  if feed = Feed[uri: uri]
@@ -24,14 +27,12 @@ module Feed2Email
24
27
 
25
28
  desc 'backend', 'Open an SQLite console to the database'
26
29
  def backend
27
- require 'feed2email/database'
28
30
  exec('sqlite3', Feed2Email.database_path)
29
31
  end
30
32
 
31
33
  desc 'config', 'Open configuration file with $EDITOR'
32
34
  def config
33
35
  if ENV['EDITOR']
34
- require 'feed2email'
35
36
  exec(ENV['EDITOR'], Feed2Email.config_path)
36
37
  else
37
38
  abort 'EDITOR not set'
@@ -40,15 +41,11 @@ module Feed2Email
40
41
 
41
42
  desc 'export PATH', 'Export feed subscriptions as OPML to PATH'
42
43
  def export(path)
43
- require 'feed2email/feed'
44
-
45
44
  if Feed.empty?
46
45
  abort 'No feeds to export'
47
46
  end
48
47
 
49
48
  unless File.exist?(path)
50
- require 'feed2email/opml_exporter'
51
-
52
49
  puts 'This may take a bit. Please wait...'
53
50
 
54
51
  if n = OPMLExporter.export(path)
@@ -64,8 +61,6 @@ module Feed2Email
64
61
  desc 'import PATH', 'Import feed subscriptions as OPML from PATH'
65
62
  def import(path)
66
63
  if File.exist?(path)
67
- require 'feed2email/opml_importer'
68
-
69
64
  puts 'Importing...'
70
65
 
71
66
  if n = OPMLImporter.import(path)
@@ -82,10 +77,9 @@ module Feed2Email
82
77
 
83
78
  desc 'list', 'List feed subscriptions'
84
79
  def list
85
- require 'feed2email/feed'
86
-
87
80
  if Feed.any?
88
81
  puts Feed.by_smallest_id.to_a
82
+ puts "\nSubscribed to #{'feed'.pluralize(Feed.count)}"
89
83
  else
90
84
  puts 'No feeds'
91
85
  end
@@ -93,27 +87,32 @@ module Feed2Email
93
87
 
94
88
  desc 'process', 'Process feed subscriptions'
95
89
  def process
96
- require 'feed2email/feed'
97
90
  Feed.enabled.by_smallest_id.each(&:process)
98
91
  end
99
92
 
100
93
  desc 'remove ID', 'Unsubscribe from feed with id ID'
101
94
  def remove(id)
102
- require 'feed2email/feed'
103
-
104
95
  feed = Feed[id]
105
96
 
106
- if feed && feed.delete
107
- puts "Removed feed: #{feed}"
97
+ if feed
98
+ puts "Remove feed: #{feed}"
99
+
100
+ if ask('Are you sure? (yes/no)') == 'yes'
101
+ if feed.delete
102
+ puts 'Removed'
103
+ else
104
+ abort 'Failed to remove feed'
105
+ end
106
+ else
107
+ puts 'Not removed'
108
+ end
108
109
  else
109
- abort "Failed to remove feed. Is #{id} a valid id?"
110
+ abort "Feed not found. Is #{id} a valid id?"
110
111
  end
111
112
  end
112
113
 
113
114
  desc 'toggle ID', 'Enable/disable feed with id ID'
114
115
  def toggle(id)
115
- require 'feed2email/feed'
116
-
117
116
  feed = Feed[id]
118
117
 
119
118
  if feed && feed.toggle
@@ -125,8 +124,6 @@ module Feed2Email
125
124
 
126
125
  desc 'uncache ID', 'Clear fetch cache for feed with id ID'
127
126
  def uncache(id)
128
- require 'feed2email/feed'
129
-
130
127
  feed = Feed[id]
131
128
 
132
129
  if feed && feed.uncache
@@ -138,7 +135,6 @@ module Feed2Email
138
135
 
139
136
  desc 'version', 'Show feed2email version'
140
137
  def version
141
- require 'feed2email/version'
142
138
  puts "feed2email #{Feed2Email::VERSION}"
143
139
  end
144
140
 
@@ -60,7 +60,8 @@ module Feed2Email
60
60
  def check_permissions
61
61
  if '%o' % (File.stat(path).mode & 0777) != '600'
62
62
  raise InvalidConfigPermissionsError,
63
- "Invalid permissions for config file #{path}"
63
+ 'Invalid permissions for config file' +
64
+ "\nTo fix it, issue: chmod 600 #{path}"
64
65
  end
65
66
  end
66
67
 
@@ -1,31 +1,18 @@
1
1
  require 'sequel'
2
- require 'feed2email'
3
2
 
4
3
  module Feed2Email
5
4
  class Database
6
- def self.setup
7
- new(
8
- adapter: 'sqlite',
9
- database: Feed2Email.database_path,
10
- loggers: [Feed2Email.logger],
11
- sql_log_level: :debug
12
- )
13
- end
14
-
15
5
  def initialize(connect_options)
16
- @connect_options = connect_options
17
- setup_connection
6
+ setup_connection(connect_options)
18
7
  setup_schema
19
8
  end
20
9
 
21
10
  private
22
11
 
23
- def connect_options; @connect_options end
24
-
25
12
  def connection; @connection end
26
13
 
27
- def setup_connection
28
- @connection = Sequel::Model.db = Sequel.connect(connect_options)
14
+ def setup_connection(options)
15
+ @connection = Sequel::Model.db = Sequel.connect(options)
29
16
  end
30
17
 
31
18
  def setup_schema
@@ -49,7 +36,5 @@ module Feed2Email
49
36
  Time :updated_at
50
37
  end
51
38
  end
52
-
53
- setup
54
39
  end
55
40
  end
@@ -4,15 +4,11 @@ require 'uri'
4
4
  require 'feed2email'
5
5
  require 'feed2email/configurable'
6
6
  require 'feed2email/core_ext'
7
- require 'feed2email/database'
8
7
  require 'feed2email/loggable'
9
8
  require 'feed2email/version'
10
9
 
11
10
  module Feed2Email
12
- if config['send_method'] == 'smtp'
13
- require 'feed2email/smtp_connection'
14
- SMTPConnection.setup
15
- end
11
+ setup_database
16
12
 
17
13
  class Entry < Sequel::Model(:entries)
18
14
  plugin :timestamps
@@ -31,6 +27,11 @@ module Feed2Email
31
27
  attr_accessor :feed_uri
32
28
 
33
29
  def process
30
+ if missing_data?
31
+ logger.warn 'Skipping entry with missing data...'
32
+ return false
33
+ end
34
+
34
35
  unless feed.old?
35
36
  logger.debug 'Skipping new feed entry...'
36
37
  save # record as seen
@@ -130,6 +131,10 @@ module Feed2Email
130
131
  Entry.last_email_sent_at = time
131
132
  end
132
133
 
134
+ def missing_data?
135
+ [content, feed_title, title, uri].include?(nil)
136
+ end
137
+
133
138
  def old?
134
139
  feed.entries_dataset.where(uri: uri).any?
135
140
  end
@@ -157,7 +162,9 @@ module Feed2Email
157
162
  end
158
163
 
159
164
  def title
160
- data.title.strip
165
+ if data.title
166
+ data.title.strip
167
+ end
161
168
  end
162
169
 
163
170
  def uri
@@ -166,8 +173,8 @@ module Feed2Email
166
173
  @uri = data.url
167
174
 
168
175
  # Make relative entry URL absolute by prepending feed URL
169
- if @uri && @uri.start_with?('/')
170
- @uri = URI.join(feed_uri[%r{https?://[^/]+}], @uri)
176
+ if @uri && @uri.start_with?('/') && !@uri.start_with?('//')
177
+ @uri = URI.join(feed_uri[%r{https?://[^/]+}], @uri).to_s
171
178
  end
172
179
 
173
180
  @uri
@@ -6,7 +6,6 @@ require 'feed2email'
6
6
  require 'feed2email/config'
7
7
  require 'feed2email/configurable'
8
8
  require 'feed2email/core_ext'
9
- require 'feed2email/database'
10
9
  require 'feed2email/entry'
11
10
  require 'feed2email/loggable'
12
11
  require 'feed2email/open-uri'
@@ -14,6 +13,8 @@ require 'feed2email/redirection_checker'
14
13
  require 'feed2email/version'
15
14
 
16
15
  module Feed2Email
16
+ setup_database
17
+
17
18
  class Feed < Sequel::Model(:feeds)
18
19
  plugin :dirty
19
20
  plugin :timestamps
@@ -1,3 +1,3 @@
1
1
  module Feed2Email
2
- VERSION = '0.9.1'
2
+ VERSION = '0.10.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: feed2email
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aggelos Orfanakos
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-25 00:00:00.000000000 Z
11
+ date: 2015-04-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: feedzirra
@@ -192,6 +192,20 @@ dependencies:
192
192
  - - ">="
193
193
  - !ruby/object:Gem::Version
194
194
  version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: aruba
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: 0.6.2
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: 0.6.2
195
209
  description:
196
210
  email: me@agorf.gr
197
211
  executables:
@@ -217,7 +231,6 @@ files:
217
231
  - lib/feed2email/feed.rb
218
232
  - lib/feed2email/feed_autodiscoverer.rb
219
233
  - lib/feed2email/loggable.rb
220
- - lib/feed2email/logger.rb
221
234
  - lib/feed2email/migrate/convert_feeds_migration.rb
222
235
  - lib/feed2email/migrate/feeds_import_migration.rb
223
236
  - lib/feed2email/migrate/history_import_migration.rb
@@ -227,7 +240,6 @@ files:
227
240
  - lib/feed2email/opml_exporter.rb
228
241
  - lib/feed2email/opml_importer.rb
229
242
  - lib/feed2email/redirection_checker.rb
230
- - lib/feed2email/smtp_connection.rb
231
243
  - lib/feed2email/version.rb
232
244
  homepage: https://github.com/agorf/feed2email
233
245
  licenses:
@@ -1,25 +0,0 @@
1
- require 'logger'
2
- require 'feed2email/core_ext'
3
-
4
- module Feed2Email
5
- class Logger
6
- attr_reader :logger
7
-
8
- def initialize(log_path, log_level, log_shift_age, log_shift_size)
9
- @log_path = log_path
10
- @logger = ::Logger.new(log_to(log_path), log_shift_age,
11
- log_shift_size.megabytes)
12
- @logger.level = ::Logger.const_get(log_level.upcase)
13
- end
14
-
15
- private
16
-
17
- def log_to(log_path)
18
- if log_path == true
19
- $stdout
20
- elsif log_path # truthy but not true (a path)
21
- File.expand_path(log_path)
22
- end
23
- end
24
- end
25
- end
@@ -1,59 +0,0 @@
1
- require 'net/smtp'
2
- require 'feed2email/configurable'
3
-
4
- module Feed2Email
5
- def self.smtp_connection
6
- @smtp_connection
7
- end
8
-
9
- def self.smtp_connection=(smtp_connection)
10
- @smtp_connection = smtp_connection
11
- end
12
-
13
- class SMTPConnection
14
- extend Configurable
15
-
16
- def self.setup
17
- Feed2Email.smtp_connection = new(
18
- config.slice(*config.keys.grep(/\Asmtp_/))
19
- )
20
- at_exit { Feed2Email.smtp_connection.finish }
21
- end
22
-
23
- def initialize(options)
24
- @options = options
25
- end
26
-
27
- def finish
28
- smtp.finish if started?
29
- end
30
-
31
- def sendmail(*args, &block)
32
- start unless started?
33
- smtp.sendmail(*args, &block) # delegate
34
- end
35
-
36
- private
37
-
38
- def options; @options end
39
-
40
- def smtp
41
- return @smtp if @smtp
42
- @smtp = Net::SMTP.new(options['smtp_host'], options['smtp_port'])
43
- @smtp.enable_starttls if options['smtp_starttls']
44
- @smtp
45
- end
46
-
47
- def start
48
- smtp.start('localhost',
49
- options['smtp_user'],
50
- options['smtp_pass'],
51
- options['smtp_auth'].to_sym
52
- )
53
- end
54
-
55
- def started?
56
- smtp.started? # delegate
57
- end
58
- end
59
- end