feed2email 0.6.0 → 0.7.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 +8 -0
- data/README.md +37 -28
- data/TODO.md +4 -1
- data/bin/feed2email +6 -1
- data/lib/feed2email/config.rb +9 -7
- data/lib/feed2email/core_ext.rb +6 -0
- data/lib/feed2email/entry.rb +4 -0
- data/lib/feed2email/feed.rb +39 -35
- data/lib/feed2email/lazy_smtp_connection.rb +34 -0
- data/lib/feed2email/logger.rb +8 -25
- data/lib/feed2email/mail.rb +26 -31
- data/lib/feed2email/version.rb +1 -1
- data/lib/feed2email.rb +14 -10
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f18bbfd4e8a09cb263f70c7966af0fa9e6602a3c
|
|
4
|
+
data.tar.gz: fe00a0445e6010eca1d847861f33687beb7a8dc7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8fddbfd1416024208e32e65ba16a5eeb51c3e6537d6b39d0e49ba945ae8ab5c9bf9c8c14f3e976b173da9f06976e15b54ebc18ac73c62250727f2e3a58eafa1b
|
|
7
|
+
data.tar.gz: 0f1cbbdcba1768b9f75ad29c21b3c5c4d17cd55446dbaa1aed49fc72d9b63ec58a3c333dd1d8a0001e31f9cc6555ac106a8c40db764bcc127b004a2e0605f69c
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
### 0.7.0
|
|
2
|
+
|
|
3
|
+
* Prevent simultaneous running instances
|
|
4
|
+
* Support log rotation
|
|
5
|
+
* Show entry author and pubdate in email
|
|
6
|
+
* Use a single SMTP connection for all email sending
|
|
7
|
+
* Rename `smtp_tls` option to `smtp_starttls`
|
|
8
|
+
|
|
1
9
|
### 0.6.0
|
|
2
10
|
|
|
3
11
|
* Render text/plain body as Markdown
|
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# feed2email
|
|
1
|
+
# feed2email [](http://badge.fury.io/rb/feed2email)
|
|
2
2
|
|
|
3
3
|
RSS/Atom feed updates in your email
|
|
4
4
|
|
|
@@ -7,9 +7,11 @@ RSS/Atom feed updates in your email
|
|
|
7
7
|
I don't like having a separate application for feeds when I'm already checking
|
|
8
8
|
my email. I also never read a thing when feeds are kept in a separate place.
|
|
9
9
|
|
|
10
|
-
feed2email
|
|
11
|
-
|
|
10
|
+
feed2email is a [headless][] RSS/Atom feed aggregator that sends feed entries
|
|
11
|
+
via email. It was written primarily as a replacement of [rss2email][] and aims
|
|
12
|
+
to be simple, fast and easy to use.
|
|
12
13
|
|
|
14
|
+
[headless]: http://en.wikipedia.org/wiki/Headless_software
|
|
13
15
|
[rss2email]: http://www.allthingsrss.com/rss2email/
|
|
14
16
|
|
|
15
17
|
## Installation
|
|
@@ -27,13 +29,7 @@ $ gem install feed2email
|
|
|
27
29
|
|
|
28
30
|
Through a [YAML][] file at `~/.feed2email/config.yml`.
|
|
29
31
|
|
|
30
|
-
It is possible to send email via SMTP or an [MTA][] (default). If `config.yml`
|
|
31
|
-
contains options for both, feed2email will use SMTP.
|
|
32
|
-
|
|
33
32
|
[YAML]: http://en.wikipedia.org/wiki/YAML
|
|
34
|
-
[MTA]: http://en.wikipedia.org/wiki/Message_transfer_agent
|
|
35
|
-
|
|
36
|
-
### Format
|
|
37
33
|
|
|
38
34
|
Each line in the configuration file contains a key-value pair. Each key-value
|
|
39
35
|
pair is separated with a colon: `foo: bar`
|
|
@@ -48,9 +44,20 @@ pair is separated with a colon: `foo: bar`
|
|
|
48
44
|
`true` which logs to standard output; use `false` to disable logging)
|
|
49
45
|
* `log_level` (optional) is the logging verbosity level and can be `fatal`
|
|
50
46
|
(least verbose), `error`, `warn`, `info` (default) and `debug` (most verbose)
|
|
47
|
+
* `log_shift_age` (optional) is the number of _old_ log files to keep or the
|
|
48
|
+
frequency of rotation (`daily`, `weekly`, `monthly`; default is `0` so only
|
|
49
|
+
the current log file is kept)
|
|
50
|
+
* `log_shift_size` (optional) is the maximum log file size in _megabytes_ and it
|
|
51
|
+
only applies when `log_shift_age` is a number greater than zero (default is
|
|
52
|
+
`1`)
|
|
51
53
|
* `max_entries` (optional) is the maximum number of entries to process per feed
|
|
52
54
|
(default is `20`; use `0` for unlimited)
|
|
53
55
|
|
|
56
|
+
It is possible to send email via SMTP or an [MTA][] (default). If `config.yml`
|
|
57
|
+
contains options for both, feed2email will use SMTP.
|
|
58
|
+
|
|
59
|
+
[MTA]: http://en.wikipedia.org/wiki/Message_transfer_agent
|
|
60
|
+
|
|
54
61
|
### SMTP
|
|
55
62
|
|
|
56
63
|
For this method you need to have access to an SMTP service. [Mailgun][] has a
|
|
@@ -61,21 +68,22 @@ free plan.
|
|
|
61
68
|
* `smtp_user` (required) is the username of your email account
|
|
62
69
|
* `smtp_pass` (required) is the password of your email account (see the warning
|
|
63
70
|
below)
|
|
64
|
-
* `
|
|
71
|
+
* `smtp_starttls` (optional) controls STARTTLS (default is `true`; can also be
|
|
72
|
+
`false`)
|
|
65
73
|
* `smtp_auth` (optional) controls the authentication method (default is `login`;
|
|
66
74
|
can also be `plain` or `cram_md5`)
|
|
67
75
|
|
|
68
76
|
**Warning:** Unless it has correct restricted permissions, anyone with access in
|
|
69
77
|
your system will be able to read `config.yml` and your password. To prevent
|
|
70
78
|
this, feed2email will not run and complain if it detects the wrong permissions.
|
|
71
|
-
|
|
79
|
+
To set the correct permissions, issue `chmod 600 ~/.feed2email/config.yml`
|
|
72
80
|
|
|
73
81
|
[Mailgun]: http://www.mailgun.com/
|
|
74
82
|
|
|
75
83
|
### MTA
|
|
76
84
|
|
|
77
85
|
For this method you need to have an [MTA][] with a [Sendmail][]-compatible
|
|
78
|
-
interface
|
|
86
|
+
interface set up and working in your system like [msmtp][] or [Postfix][].
|
|
79
87
|
|
|
80
88
|
* `sendmail_path` (optional) is the path to the Sendmail binary (default is
|
|
81
89
|
`/usr/sbin/sendmail`)
|
|
@@ -88,26 +96,20 @@ interface setup and working in your system like [msmtp][] or [Postfix][].
|
|
|
88
96
|
|
|
89
97
|
### Managing feeds
|
|
90
98
|
|
|
91
|
-
Create `~/.feed2email/feeds.yml` and add the
|
|
99
|
+
Create or edit `~/.feed2email/feeds.yml` and add the URL of the feed you want to
|
|
92
100
|
subscribe to, prefixed with a dash and a space:
|
|
93
101
|
|
|
94
102
|
~~~ yaml
|
|
95
103
|
- https://github.com/agorf/feed2email/commits.atom
|
|
96
104
|
~~~
|
|
97
105
|
|
|
98
|
-
To disable a feed, comment it:
|
|
106
|
+
To disable a feed, comment its line by prefixing it with a hash symbol:
|
|
99
107
|
|
|
100
108
|
~~~ yaml
|
|
101
109
|
#- https://github.com/agorf/feed2email/commits.atom
|
|
102
110
|
~~~
|
|
103
111
|
|
|
104
|
-
### Running
|
|
105
|
-
|
|
106
|
-
Simply:
|
|
107
|
-
|
|
108
|
-
~~~ sh
|
|
109
|
-
$ feed2email
|
|
110
|
-
~~~
|
|
112
|
+
### Running for the first time
|
|
111
113
|
|
|
112
114
|
When feed2email runs for the first time or after adding a new feed:
|
|
113
115
|
|
|
@@ -121,14 +123,14 @@ provided migration script: `feed2email-migrate-history` If you don't, feed2email
|
|
|
121
123
|
will think it's run for the first time and will treat all entries as old (thus
|
|
122
124
|
no email will be sent and you may miss some entries).
|
|
123
125
|
|
|
124
|
-
|
|
126
|
+
### Receiving specific entries from a feed
|
|
125
127
|
|
|
126
|
-
1. Add
|
|
128
|
+
1. Add the feed URL to `~/.feed2email/feeds.yml`
|
|
127
129
|
1. Run feed2email once so that the feed's history file is generated
|
|
128
130
|
1. Remove the entries you want to receive from the feed's history (i.e. with
|
|
129
131
|
your text editor)
|
|
130
|
-
1. Remove the feed's meta file (`meta-<digest>.yml
|
|
131
|
-
caching
|
|
132
|
+
1. Remove the feed's meta file (`meta-<digest>.yml`, where `<digest>` is the MD5
|
|
133
|
+
hex digest of the feed URL) to bust feed fetching caching
|
|
132
134
|
|
|
133
135
|
Next time feed2email runs, these entries will be treated as new and will be
|
|
134
136
|
processed (sent as email).
|
|
@@ -138,12 +140,19 @@ processed (sent as email).
|
|
|
138
140
|
Before processing each feed, feed2email issues a [HEAD request][] to check
|
|
139
141
|
whether it has been permanently moved by looking for a _301 Moved Permanently_
|
|
140
142
|
HTTP status and its respective _Location_ header. In such case, feed2email
|
|
141
|
-
updates
|
|
142
|
-
email sent). If you do want to have some of them sent as email,
|
|
143
|
-
|
|
143
|
+
updates `~/.feed2email/feeds.yml` with the new location and all feed entries are
|
|
144
|
+
skipped (no email sent). If you do want to have some of them sent as email, see
|
|
145
|
+
[Receiving specific entries from a feed](#receiving-specific-entries-from-a-feed).
|
|
144
146
|
|
|
145
147
|
[HEAD request]: http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods
|
|
146
148
|
|
|
149
|
+
### Feed caching
|
|
150
|
+
|
|
151
|
+
feed2email caches fetched feeds with the _Last-Modified_ and _Etag_ HTTP
|
|
152
|
+
headers. If you want to force a feed to be fetched, remove the feed's meta file
|
|
153
|
+
(`~/.feed2email/meta-<digest>.yml`, where `<digest>` is the MD5 hex digest of
|
|
154
|
+
the feed URL). Next time feed2email runs, the feed will be fetched.
|
|
155
|
+
|
|
147
156
|
### Automating
|
|
148
157
|
|
|
149
158
|
You can use [cron][] to run feed2email automatically e.g. once every hour.
|
data/TODO.md
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
* Specs
|
|
4
4
|
* Do not mark entry as sent if email was not sent
|
|
5
|
-
* Show entry metadata in email (e.g. pubdate, author)
|
|
6
5
|
* Implement a command-line interface to manage feeds.yml
|
|
7
6
|
* Detect entry URI changes (maybe by comparing body hashes?)
|
|
8
7
|
* Filters (e.g. skip entries matching a pattern)
|
|
@@ -11,3 +10,7 @@
|
|
|
11
10
|
* Profiles (support many feed lists and recipients)
|
|
12
11
|
* Send email notifications to user (e.g. when a feed is not available anymore)
|
|
13
12
|
* Plugin architecture
|
|
13
|
+
* Integrate with Mail gem for email sending
|
|
14
|
+
* Do not consider fetched if there was an error
|
|
15
|
+
* begin ensure end
|
|
16
|
+
* Fix sleeping
|
data/bin/feed2email
CHANGED
|
@@ -3,4 +3,9 @@
|
|
|
3
3
|
require 'feed2email'
|
|
4
4
|
require 'feed2email/feed'
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
if File.new('/tmp/feed2email.lock', 'w').flock(File::LOCK_NB | File::LOCK_EX)
|
|
7
|
+
Feed2Email::Feed.process_all
|
|
8
|
+
else
|
|
9
|
+
$stderr.puts 'An instance of feed2email is already running. Exiting...'
|
|
10
|
+
exit 1
|
|
11
|
+
end
|
data/lib/feed2email/config.rb
CHANGED
|
@@ -87,13 +87,15 @@ module Feed2Email
|
|
|
87
87
|
|
|
88
88
|
def defaults
|
|
89
89
|
{
|
|
90
|
-
'log_level'
|
|
91
|
-
'log_path'
|
|
92
|
-
'
|
|
93
|
-
'
|
|
94
|
-
'
|
|
95
|
-
'
|
|
96
|
-
'
|
|
90
|
+
'log_level' => 'info',
|
|
91
|
+
'log_path' => true,
|
|
92
|
+
'log_shift_age' => 0,
|
|
93
|
+
'log_shift_size' => 1, # megabyte
|
|
94
|
+
'max_entries' => 20,
|
|
95
|
+
'send_delay' => 10,
|
|
96
|
+
'sendmail_path' => '/usr/sbin/sendmail',
|
|
97
|
+
'smtp_auth' => 'login',
|
|
98
|
+
'smtp_starttls' => true,
|
|
97
99
|
}
|
|
98
100
|
end
|
|
99
101
|
|
data/lib/feed2email/core_ext.rb
CHANGED
data/lib/feed2email/entry.rb
CHANGED
data/lib/feed2email/feed.rb
CHANGED
|
@@ -16,31 +16,34 @@ module Feed2Email
|
|
|
16
16
|
class Feed
|
|
17
17
|
extend Forwardable
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
extend Forwardable
|
|
19
|
+
def self.feed_uris; @feed_uris end
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
def self.logger
|
|
22
|
+
Feed2Email.logger # delegate
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
def self.smtp_connection
|
|
26
|
+
Feed2Email.smtp_connection # delegate
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
logger.debug 'Loading feed subscriptions...'
|
|
30
|
+
@feed_uris = Feeds.new(File.join(CONFIG_DIR, 'feeds.yml'))
|
|
31
|
+
logger.info "Subscribed to #{'feed'.pluralize(feed_uris.size)}"
|
|
32
|
+
|
|
25
33
|
def self.process_all
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
34
|
+
begin
|
|
35
|
+
feed_uris.each_with_index do |uri, i|
|
|
36
|
+
feed = new(uri)
|
|
37
|
+
feed.process
|
|
38
|
+
feed_uris[i] = feed.uri # persist possible permanent redirect
|
|
39
|
+
end
|
|
40
|
+
ensure
|
|
41
|
+
smtp_connection.finalize
|
|
30
42
|
end
|
|
31
43
|
|
|
32
44
|
feed_uris.sync
|
|
33
45
|
end
|
|
34
46
|
|
|
35
|
-
def self.feed_uris
|
|
36
|
-
return @feed_uris if @feed_uris
|
|
37
|
-
|
|
38
|
-
log :debug, 'Loading feed subscriptions...'
|
|
39
|
-
@feed_uris = Feeds.new(File.join(CONFIG_DIR, 'feeds.yml'))
|
|
40
|
-
log :info, "Subscribed to #{'feed'.pluralize(feed_uris.size)}"
|
|
41
|
-
@feed_uris
|
|
42
|
-
end
|
|
43
|
-
|
|
44
47
|
attr_reader :uri
|
|
45
48
|
|
|
46
49
|
def initialize(uri)
|
|
@@ -48,7 +51,7 @@ module Feed2Email
|
|
|
48
51
|
end
|
|
49
52
|
|
|
50
53
|
def process
|
|
51
|
-
|
|
54
|
+
logger.info "Processing feed #{uri} ..."
|
|
52
55
|
|
|
53
56
|
return unless fetch_and_parse_feed
|
|
54
57
|
|
|
@@ -57,14 +60,14 @@ module Feed2Email
|
|
|
57
60
|
history.sync
|
|
58
61
|
meta.sync
|
|
59
62
|
else
|
|
60
|
-
|
|
63
|
+
logger.warn 'Feed does not have entries'
|
|
61
64
|
end
|
|
62
65
|
end
|
|
63
66
|
|
|
64
67
|
private
|
|
65
68
|
|
|
66
69
|
def fetch_feed
|
|
67
|
-
|
|
70
|
+
logger.debug 'Fetching feed...'
|
|
68
71
|
|
|
69
72
|
begin
|
|
70
73
|
handle_permanent_redirection
|
|
@@ -82,13 +85,13 @@ module Feed2Email
|
|
|
82
85
|
end
|
|
83
86
|
rescue OpenURI::HTTPError => e
|
|
84
87
|
if e.message == '304 Not Modified'
|
|
85
|
-
|
|
88
|
+
logger.info 'Feed not modified; skipping...'
|
|
86
89
|
return false
|
|
87
90
|
end
|
|
88
91
|
|
|
89
92
|
raise
|
|
90
93
|
rescue => e
|
|
91
|
-
|
|
94
|
+
logger.error 'Failed to fetch feed'
|
|
92
95
|
log_exception(e)
|
|
93
96
|
return false
|
|
94
97
|
end
|
|
@@ -102,7 +105,8 @@ module Feed2Email
|
|
|
102
105
|
|
|
103
106
|
if response.code == '301' && response['location'] =~ %r{\Ahttps?://}
|
|
104
107
|
self.uri = response['location']
|
|
105
|
-
|
|
108
|
+
logger.warn(
|
|
109
|
+
"Got permanently redirected! Updated feed location to #{uri}")
|
|
106
110
|
end
|
|
107
111
|
end
|
|
108
112
|
|
|
@@ -139,12 +143,12 @@ module Feed2Email
|
|
|
139
143
|
end
|
|
140
144
|
|
|
141
145
|
def parse_feed(xml_data)
|
|
142
|
-
|
|
146
|
+
logger.debug 'Parsing feed...'
|
|
143
147
|
|
|
144
148
|
begin
|
|
145
149
|
Feedzirra::Feed.parse(xml_data)
|
|
146
150
|
rescue => e
|
|
147
|
-
|
|
151
|
+
logger.error 'Failed to parse feed'
|
|
148
152
|
log_exception(e)
|
|
149
153
|
return false
|
|
150
154
|
end
|
|
@@ -170,8 +174,8 @@ module Feed2Email
|
|
|
170
174
|
}
|
|
171
175
|
end
|
|
172
176
|
|
|
173
|
-
def
|
|
174
|
-
Feed2Email
|
|
177
|
+
def logger
|
|
178
|
+
Feed2Email.logger # delegate
|
|
175
179
|
end
|
|
176
180
|
|
|
177
181
|
def max_entries
|
|
@@ -179,25 +183,25 @@ module Feed2Email
|
|
|
179
183
|
end
|
|
180
184
|
|
|
181
185
|
def process_entries
|
|
182
|
-
|
|
186
|
+
logger.info "Processing #{'entry'.pluralize(entries.size, 'entries')}..."
|
|
183
187
|
entries.each {|entry| process_entry(entry) }
|
|
184
188
|
end
|
|
185
189
|
|
|
186
190
|
def process_entry(entry)
|
|
187
|
-
|
|
191
|
+
logger.info "Processing entry #{entry.uri} ..."
|
|
188
192
|
|
|
189
193
|
if history.any?
|
|
190
194
|
if history.include?(entry.uri)
|
|
191
|
-
|
|
195
|
+
logger.debug 'Skipping old entry...'
|
|
192
196
|
else
|
|
193
197
|
# Sleep between entry processing to avoid Net::SMTPServerBusy errors
|
|
194
198
|
if config['send_delay'] > 0
|
|
195
|
-
|
|
196
|
-
"Sleeping for #{'second'.pluralize(config['send_delay'])}"
|
|
199
|
+
logger.debug(
|
|
200
|
+
"Sleeping for #{'second'.pluralize(config['send_delay'])}")
|
|
197
201
|
sleep(config['send_delay'])
|
|
198
202
|
end
|
|
199
203
|
|
|
200
|
-
|
|
204
|
+
logger.debug 'Sending new entry...'
|
|
201
205
|
|
|
202
206
|
begin
|
|
203
207
|
entry.send_mail
|
|
@@ -212,7 +216,7 @@ module Feed2Email
|
|
|
212
216
|
e = nil
|
|
213
217
|
end
|
|
214
218
|
else
|
|
215
|
-
|
|
219
|
+
logger.debug 'Skipping new feed entry...'
|
|
216
220
|
history << entry.uri
|
|
217
221
|
end
|
|
218
222
|
end
|
|
@@ -226,8 +230,8 @@ module Feed2Email
|
|
|
226
230
|
end
|
|
227
231
|
|
|
228
232
|
def log_exception(error)
|
|
229
|
-
|
|
230
|
-
error.backtrace.each {|line|
|
|
233
|
+
logger.error "#{error.class}: #{error.message.strip}"
|
|
234
|
+
error.backtrace.each {|line| logger.debug line }
|
|
231
235
|
end
|
|
232
236
|
|
|
233
237
|
def_delegator :data, :title, :title
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require 'net/smtp'
|
|
2
|
+
|
|
3
|
+
module Feed2Email
|
|
4
|
+
class LazySMTPConnection
|
|
5
|
+
def config
|
|
6
|
+
Feed2Email.config # delegate
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def connect
|
|
10
|
+
smtp.start('localhost', config['smtp_user'], config['smtp_pass'],
|
|
11
|
+
config['smtp_auth'].to_sym)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def connected?
|
|
15
|
+
smtp.started?
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def finalize
|
|
19
|
+
smtp.finish if connected?
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def send_message(*args)
|
|
23
|
+
connect unless connected?
|
|
24
|
+
smtp.send_message(*args)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def smtp
|
|
28
|
+
return @smtp if @smtp
|
|
29
|
+
@smtp = Net::SMTP.new(config['smtp_host'], config['smtp_port'])
|
|
30
|
+
@smtp.enable_starttls if config['smtp_starttls']
|
|
31
|
+
@smtp
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
data/lib/feed2email/logger.rb
CHANGED
|
@@ -1,42 +1,25 @@
|
|
|
1
1
|
require 'logger'
|
|
2
|
+
require 'feed2email/core_ext'
|
|
2
3
|
|
|
3
4
|
module Feed2Email
|
|
4
5
|
class Logger
|
|
5
|
-
|
|
6
|
-
@log_path = log_path
|
|
7
|
-
@log_level = log_level
|
|
8
|
-
end
|
|
6
|
+
attr_reader :logger
|
|
9
7
|
|
|
10
|
-
def
|
|
11
|
-
|
|
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)
|
|
12
13
|
end
|
|
13
14
|
|
|
14
15
|
private
|
|
15
16
|
|
|
16
|
-
def log_to
|
|
17
|
+
def log_to(log_path)
|
|
17
18
|
if log_path == true
|
|
18
19
|
$stdout
|
|
19
20
|
elsif log_path # truthy but not true (a path)
|
|
20
21
|
File.expand_path(log_path)
|
|
21
22
|
end
|
|
22
23
|
end
|
|
23
|
-
|
|
24
|
-
def logger
|
|
25
|
-
return @logger if @logger
|
|
26
|
-
|
|
27
|
-
@logger = ::Logger.new(log_to)
|
|
28
|
-
|
|
29
|
-
if log_level
|
|
30
|
-
@logger.level = ::Logger.const_get(log_level.upcase)
|
|
31
|
-
else
|
|
32
|
-
@logger.level = ::Logger::INFO
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
@logger
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def log_path; @log_path end
|
|
39
|
-
|
|
40
|
-
def log_level; @log_level end
|
|
41
24
|
end
|
|
42
25
|
end
|
data/lib/feed2email/mail.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
require 'mail'
|
|
2
|
-
require '
|
|
2
|
+
require 'feed2email/version'
|
|
3
3
|
|
|
4
4
|
module Feed2Email
|
|
5
5
|
class Mail
|
|
@@ -24,6 +24,7 @@ module Feed2Email
|
|
|
24
24
|
<body>
|
|
25
25
|
<h1><a href="%{uri}">%{title}</a></h1>
|
|
26
26
|
%{content}
|
|
27
|
+
<p>%{published}</p>
|
|
27
28
|
<p><a href="%{uri}">%{uri}</a></p>
|
|
28
29
|
<p>--<br>
|
|
29
30
|
Sent by <a href="https://github.com/agorf/feed2email">feed2email
|
|
@@ -31,38 +32,30 @@ module Feed2Email
|
|
|
31
32
|
</body>
|
|
32
33
|
</html>
|
|
33
34
|
}.gsub(/^\s+/, '') % {
|
|
34
|
-
content:
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
content: entry.content,
|
|
36
|
+
published: published,
|
|
37
|
+
title: entry.title.strip_html,
|
|
38
|
+
uri: entry.uri.escape_html,
|
|
37
39
|
}
|
|
38
40
|
end
|
|
39
41
|
|
|
40
42
|
def body_text
|
|
41
|
-
|
|
42
|
-
# [%{title}](%{uri})
|
|
43
|
-
|
|
44
|
-
%{content}
|
|
45
|
-
|
|
46
|
-
%{uri}
|
|
47
|
-
|
|
48
|
-
--
|
|
49
|
-
Sent by feed2email #{VERSION} at #{Time.now}
|
|
50
|
-
}.gsub(/^\s+/, '') % {
|
|
51
|
-
content: @entry.content.to_markdown,
|
|
52
|
-
title: @entry.title.strip_html,
|
|
53
|
-
uri: @entry.uri,
|
|
54
|
-
}
|
|
43
|
+
body_html.to_markdown
|
|
55
44
|
end
|
|
56
45
|
|
|
57
46
|
def config
|
|
58
47
|
Feed2Email.config # delegate
|
|
59
48
|
end
|
|
60
49
|
|
|
50
|
+
def entry; @entry end
|
|
51
|
+
|
|
52
|
+
def feed_title; @feed_title end
|
|
53
|
+
|
|
61
54
|
def mail
|
|
62
55
|
::Mail.new.tap do |m|
|
|
63
|
-
m.from = %{"#{
|
|
56
|
+
m.from = %{"#{feed_title}" <#{config['sender']}>}
|
|
64
57
|
m.to = config['recipient']
|
|
65
|
-
m.subject =
|
|
58
|
+
m.subject = entry.title.strip_html
|
|
66
59
|
m.html_part = mail_part('text/html', body_html)
|
|
67
60
|
m.text_part = mail_part('text/plain', body_text)
|
|
68
61
|
end.to_s
|
|
@@ -75,6 +68,14 @@ module Feed2Email
|
|
|
75
68
|
part
|
|
76
69
|
end
|
|
77
70
|
|
|
71
|
+
def published
|
|
72
|
+
return nil unless entry.author || entry.published
|
|
73
|
+
text = 'Published'
|
|
74
|
+
text << " by #{entry.author}" if entry.author
|
|
75
|
+
text << " at #{entry.published}" if entry.published
|
|
76
|
+
text
|
|
77
|
+
end
|
|
78
|
+
|
|
78
79
|
def send_with_sendmail
|
|
79
80
|
open("|#{config['sendmail_path']} #{config['recipient']}", 'w') do |f|
|
|
80
81
|
f.write(mail)
|
|
@@ -82,17 +83,7 @@ module Feed2Email
|
|
|
82
83
|
end
|
|
83
84
|
|
|
84
85
|
def send_with_smtp
|
|
85
|
-
|
|
86
|
-
smtp.enable_starttls if config['smtp_tls']
|
|
87
|
-
|
|
88
|
-
smtp.start(
|
|
89
|
-
'localhost',
|
|
90
|
-
config['smtp_user'],
|
|
91
|
-
config['smtp_pass'],
|
|
92
|
-
config['smtp_auth'].to_sym
|
|
93
|
-
) do
|
|
94
|
-
smtp.send_message(mail, config['sender'], config['recipient'])
|
|
95
|
-
end
|
|
86
|
+
smtp_connection.send_message(mail, config['sender'], config['recipient'])
|
|
96
87
|
end
|
|
97
88
|
|
|
98
89
|
def smtp_configured?
|
|
@@ -101,5 +92,9 @@ module Feed2Email
|
|
|
101
92
|
config['smtp_user'] &&
|
|
102
93
|
config['smtp_pass']
|
|
103
94
|
end
|
|
95
|
+
|
|
96
|
+
def smtp_connection
|
|
97
|
+
Feed2Email.smtp_connection
|
|
98
|
+
end
|
|
104
99
|
end
|
|
105
100
|
end
|
data/lib/feed2email/version.rb
CHANGED
data/lib/feed2email.rb
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
|
+
require 'feed2email/config'
|
|
2
|
+
require 'feed2email/lazy_smtp_connection'
|
|
3
|
+
require 'feed2email/logger'
|
|
4
|
+
|
|
1
5
|
module Feed2Email
|
|
2
6
|
CONFIG_DIR = File.expand_path('~/.feed2email')
|
|
3
7
|
|
|
4
|
-
def self.config
|
|
5
|
-
@config ||= Config.new(File.join(CONFIG_DIR, 'config.yml'))
|
|
6
|
-
end
|
|
8
|
+
def self.config; @config end
|
|
7
9
|
|
|
8
10
|
def self.logger
|
|
9
|
-
@logger
|
|
11
|
+
@logger.logger # delegate
|
|
10
12
|
end
|
|
11
13
|
|
|
12
|
-
def self.
|
|
13
|
-
logger.log(*args) # delegate
|
|
14
|
-
end
|
|
15
|
-
end
|
|
14
|
+
def self.smtp_connection; @smtp_connection end
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
@config = Config.new(File.join(CONFIG_DIR, 'config.yml'))
|
|
17
|
+
|
|
18
|
+
@logger = Logger.new(config['log_path'], config['log_level'],
|
|
19
|
+
config['log_shift_age'], config['log_shift_size'])
|
|
20
|
+
|
|
21
|
+
@smtp_connection = LazySMTPConnection.new
|
|
22
|
+
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.
|
|
4
|
+
version: 0.7.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-
|
|
11
|
+
date: 2015-01-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: feedzirra
|
|
@@ -159,6 +159,7 @@ files:
|
|
|
159
159
|
- lib/feed2email/feed_history.rb
|
|
160
160
|
- lib/feed2email/feed_meta.rb
|
|
161
161
|
- lib/feed2email/feeds.rb
|
|
162
|
+
- lib/feed2email/lazy_smtp_connection.rb
|
|
162
163
|
- lib/feed2email/logger.rb
|
|
163
164
|
- lib/feed2email/mail.rb
|
|
164
165
|
- lib/feed2email/version.rb
|