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 +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +2 -2
- data/lib/feed2email.rb +39 -5
- data/lib/feed2email/cli.rb +20 -24
- data/lib/feed2email/config.rb +2 -1
- data/lib/feed2email/database.rb +3 -18
- data/lib/feed2email/entry.rb +15 -8
- data/lib/feed2email/feed.rb +2 -1
- data/lib/feed2email/version.rb +1 -1
- metadata +16 -4
- data/lib/feed2email/logger.rb +0 -25
- data/lib/feed2email/smtp_connection.rb +0 -59
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dbcdf4e12f0075c8ecdb50cbbf4e4fdb9fef1959
|
4
|
+
data.tar.gz: f47dae1909bc87274d37eade561c68caa6e5f8b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8e7c27a67e616639c4e1bc9957e6b0189e7f7aaf9f5f55ad7f6f351196852671fa2c6690d0e30a797fcd02aead4adcc6ba0ab210748b4925451d4852f9468d3b
|
7
|
+
data.tar.gz: d063673ffa118876f8e9ec1d5728ec4be95c6688539320868fd96f0f43b274dc51c12ca2edf97466404ebabeb3838fa2262bce4dd53b3ee711d2129140dbdfea
|
data/CHANGELOG.md
CHANGED
@@ -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 [](http://badge.fury.io/rb/feed2email)
|
1
|
+
# feed2email [](http://badge.fury.io/rb/feed2email) [](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
|
data/lib/feed2email.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'net/smtp'
|
1
3
|
require 'pathname'
|
2
4
|
require 'feed2email/config'
|
3
|
-
require 'feed2email/
|
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
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
data/lib/feed2email/cli.rb
CHANGED
@@ -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
|
107
|
-
puts "
|
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 "
|
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
|
|
data/lib/feed2email/config.rb
CHANGED
@@ -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
|
-
|
63
|
+
'Invalid permissions for config file' +
|
64
|
+
"\nTo fix it, issue: chmod 600 #{path}"
|
64
65
|
end
|
65
66
|
end
|
66
67
|
|
data/lib/feed2email/database.rb
CHANGED
@@ -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
|
-
|
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(
|
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
|
data/lib/feed2email/entry.rb
CHANGED
@@ -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
|
-
|
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
|
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
|
data/lib/feed2email/feed.rb
CHANGED
@@ -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
|
data/lib/feed2email/version.rb
CHANGED
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.
|
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-
|
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:
|
data/lib/feed2email/logger.rb
DELETED
@@ -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
|