feed2email 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -1
- data/README.md +124 -59
- data/bin/f2e +9 -0
- data/bin/feed2email +4 -6
- data/bin/feed2email-migrate-feedlist +36 -0
- data/lib/feed2email.rb +16 -11
- data/lib/feed2email/cli.rb +158 -0
- data/lib/feed2email/config.rb +8 -3
- data/lib/feed2email/configurable.rb +7 -0
- data/lib/feed2email/feed.rb +87 -99
- data/lib/feed2email/feed_autodiscoverer.rb +55 -0
- data/lib/feed2email/feed_history.rb +63 -9
- data/lib/feed2email/feed_list.rb +147 -0
- data/lib/feed2email/lazy_smtp_connection.rb +6 -5
- data/lib/feed2email/loggable.rb +7 -0
- data/lib/feed2email/mail.rb +23 -39
- data/lib/feed2email/redirection_checker.rb +38 -0
- data/lib/feed2email/version.rb +1 -1
- metadata +61 -15
- data/TODO.md +0 -16
- data/lib/feed2email/feed_data_file.rb +0 -65
- data/lib/feed2email/feed_meta.rb +0 -28
- data/lib/feed2email/feeds.rb +0 -77
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 51069bce6917475aa8499384d330396eebde34c1
|
4
|
+
data.tar.gz: cde703782a959046c866aa459123d050e6df5fc2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 702e5ab54cd401d097b572bfdea2acfc48af045382ddc988135a1f93d8b100790c950b1cf1c32a0405feab4ae8d746c289fffd3ed328ff6974e2418eef87f383
|
7
|
+
data.tar.gz: 271c7c5d97acbc461dcdf24ac481255d0ddd6a387535c8fb9dc1fef58fcb6783aed9235c87d7a089de6e625036e06ae6399ec2f3b861486af257c697bb526f0f
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
### 0.8.0
|
2
|
+
|
3
|
+
* Command-line interface for managing feeds (c20bf0c, e5c6dec)
|
4
|
+
* Perform feed autodiscovery in `add` command (46523ee)
|
5
|
+
* Store feed metadata in feed list, so no more feed files (cfbd725)
|
6
|
+
* Add `f2e` symlink to `feed2email` binary for running convenience (6add6b9)
|
7
|
+
* Improve send delay between entry processing (2118aef)
|
8
|
+
* Fix feed fetching exception handling (8eb68cf)
|
9
|
+
* Sync feed metadata only if all entries are processed (73f0947)
|
10
|
+
* Record entry to history only if email was sent (db59e77)
|
11
|
+
* Always fetch feed when permanently redirected (4fb147f)
|
12
|
+
* Ignore redirections to the same location (26513d1e)
|
13
|
+
* Major rewrite of README file with new instructions
|
14
|
+
|
1
15
|
### 0.7.0
|
2
16
|
|
3
17
|
* Prevent simultaneous running instances
|
@@ -11,7 +25,7 @@
|
|
11
25
|
* Render text/plain body as Markdown
|
12
26
|
* Cache feed fetching with Last-Modified and ETag HTTP headers
|
13
27
|
* Update feed URI on permanent redirect
|
14
|
-
* Make sender a required config option
|
28
|
+
* Make `sender` a required config option
|
15
29
|
* Maintain a separate history file per feed
|
16
30
|
|
17
31
|
### 0.5.0
|
data/README.md
CHANGED
@@ -1,22 +1,25 @@
|
|
1
1
|
# feed2email [![Gem Version](https://badge.fury.io/rb/feed2email.svg)](http://badge.fury.io/rb/feed2email)
|
2
2
|
|
3
|
-
RSS/Atom feed updates in your email
|
4
|
-
|
5
|
-
## Why
|
6
|
-
|
7
|
-
I don't like having a separate application for feeds when I'm already checking
|
8
|
-
my email. I also never read a thing when feeds are kept in a separate place.
|
9
|
-
|
10
3
|
feed2email is a [headless][] RSS/Atom feed aggregator that sends feed entries
|
11
|
-
via email. It was written
|
4
|
+
via email. It was initially written as a replacement of [rss2email][] and aims
|
12
5
|
to be simple, fast and easy to use.
|
13
6
|
|
14
7
|
[headless]: http://en.wikipedia.org/wiki/Headless_software
|
15
8
|
[rss2email]: http://www.allthingsrss.com/rss2email/
|
16
9
|
|
10
|
+
## Features
|
11
|
+
|
12
|
+
* Easy command-line feed management (add, remove, enable/disable)
|
13
|
+
* Feed fetching caching
|
14
|
+
* Feed autodiscovery
|
15
|
+
* Support for sending email with SMTP or a local MTA (e.g. sendmail)
|
16
|
+
* _text/html_ and _text/plain_ (Markdown) multipart emails
|
17
|
+
* Support for feed permanent redirections
|
18
|
+
* Auto-fixing relative feed entry permalinks
|
19
|
+
|
17
20
|
## Installation
|
18
21
|
|
19
|
-
|
22
|
+
As a [gem][] from [RubyGems][]:
|
20
23
|
|
21
24
|
~~~ sh
|
22
25
|
$ gem install feed2email
|
@@ -27,19 +30,24 @@ $ gem install feed2email
|
|
27
30
|
|
28
31
|
## Configuration
|
29
32
|
|
30
|
-
Through a [YAML][] file at `~/.feed2email/config.yml`.
|
33
|
+
Through a [YAML][] file that you create at `~/.feed2email/config.yml`.
|
31
34
|
|
32
35
|
[YAML]: http://en.wikipedia.org/wiki/YAML
|
33
36
|
|
34
37
|
Each line in the configuration file contains a key-value pair. Each key-value
|
35
|
-
pair is separated with a colon
|
38
|
+
pair is separated with a colon, e.g.: `foo: bar`
|
36
39
|
|
37
|
-
###
|
40
|
+
### General options
|
38
41
|
|
39
42
|
* `recipient` (required) is the email address to send email to
|
40
43
|
* `sender` (required) is the email address to send email from (can be any)
|
41
44
|
* `send_delay` (optional) is the number of seconds to wait between each email to
|
42
45
|
avoid SMTP server throttling errors (default is `10`; use `0` to disable)
|
46
|
+
* `max_entries` (optional) is the maximum number of entries to process per feed
|
47
|
+
(default is `20`; use `0` for unlimited)
|
48
|
+
|
49
|
+
### Logging options
|
50
|
+
|
43
51
|
* `log_path` (optional) is the _absolute_ path to the log file (default is
|
44
52
|
`true` which logs to standard output; use `false` to disable logging)
|
45
53
|
* `log_level` (optional) is the logging verbosity level and can be `fatal`
|
@@ -50,15 +58,15 @@ pair is separated with a colon: `foo: bar`
|
|
50
58
|
* `log_shift_size` (optional) is the maximum log file size in _megabytes_ and it
|
51
59
|
only applies when `log_shift_age` is a number greater than zero (default is
|
52
60
|
`1`)
|
53
|
-
|
54
|
-
|
61
|
+
|
62
|
+
### Delivery options
|
55
63
|
|
56
64
|
It is possible to send email via SMTP or an [MTA][] (default). If `config.yml`
|
57
65
|
contains options for both, feed2email will use SMTP.
|
58
66
|
|
59
67
|
[MTA]: http://en.wikipedia.org/wiki/Message_transfer_agent
|
60
68
|
|
61
|
-
|
69
|
+
#### SMTP
|
62
70
|
|
63
71
|
For this method you need to have access to an SMTP service. [Mailgun][] has a
|
64
72
|
free plan.
|
@@ -76,11 +84,11 @@ free plan.
|
|
76
84
|
**Warning:** Unless it has correct restricted permissions, anyone with access in
|
77
85
|
your system will be able to read `config.yml` and your password. To prevent
|
78
86
|
this, feed2email will not run and complain if it detects the wrong permissions.
|
79
|
-
To set the correct permissions, issue `chmod 600 ~/.feed2email/config.yml
|
87
|
+
To set the correct permissions, issue `chmod 600 ~/.feed2email/config.yml`.
|
80
88
|
|
81
89
|
[Mailgun]: http://www.mailgun.com/
|
82
90
|
|
83
|
-
|
91
|
+
#### MTA
|
84
92
|
|
85
93
|
For this method you need to have an [MTA][] with a [Sendmail][]-compatible
|
86
94
|
interface set up and working in your system like [msmtp][] or [Postfix][].
|
@@ -96,68 +104,125 @@ interface set up and working in your system like [msmtp][] or [Postfix][].
|
|
96
104
|
|
97
105
|
### Managing feeds
|
98
106
|
|
99
|
-
|
100
|
-
|
107
|
+
First, add some feeds:
|
108
|
+
|
109
|
+
~~~ sh
|
110
|
+
$ feed2email add https://github.com/agorf.atom
|
111
|
+
Added feed https://github.com/agorf.atom at index 0
|
112
|
+
$ feed2email add https://github.com/agorf/feed2email/commits.atom
|
113
|
+
Added feed https://github.com/agorf/feed2email/commits.atom at index 1
|
114
|
+
~~~
|
115
|
+
|
116
|
+
**Tip:** You only have to type a feed2email command until it is unambiguous e.g.
|
117
|
+
instead of `feed2email list`, you can simply issue `feed2email l` as long as
|
118
|
+
there is no other command beginning with an `l`.
|
101
119
|
|
102
|
-
|
103
|
-
|
120
|
+
It is also possible to pass a website URL and let feed2email autodiscover any
|
121
|
+
feeds:
|
122
|
+
|
123
|
+
~~~ sh
|
124
|
+
$ feed2email add http://www.rubyinside.com/
|
125
|
+
0: http://www.rubyinside.com/feed/ "Ruby Inside" (application/rss+xml)
|
126
|
+
Please enter a feed to subscribe to: 0
|
127
|
+
Added feed http://www.rubyinside.com/feed/ at index 2
|
128
|
+
$ feed2email add http://thechangelog.com/137/
|
129
|
+
0: http://thechangelog.com/137/feed/ "The Changelog » #137: Better GitHub Issues with HuBoard and Ryan Rauh Comments Feed" (application/rss+xml)
|
130
|
+
1: http://thechangelog.com/feed/ "RSS 2.0 Feed" (application/rss+xml)
|
131
|
+
Please enter a feed to subscribe to: 1
|
132
|
+
Added feed http://thechangelog.com/feed/ at index 3
|
133
|
+
$ feed2email add http://thechangelog.com/137/
|
134
|
+
0: http://thechangelog.com/137/feed/ "The Changelog » #137: Better GitHub Issues with HuBoard and Ryan Rauh Comments Feed" (application/rss+xml)
|
135
|
+
Please enter a feed to subscribe to: ^C
|
136
|
+
~~~
|
137
|
+
|
138
|
+
Note that on the last command, feed2email autodiscovers the same two feeds as in
|
139
|
+
the second command, but only lists the ones that haven't been already added.
|
140
|
+
Autodiscovery is then cancelled by pressing `Ctrl-C`.
|
141
|
+
|
142
|
+
The feed list so far:
|
143
|
+
|
144
|
+
~~~ sh
|
145
|
+
$ feed2email list
|
146
|
+
0: https://github.com/agorf.atom
|
147
|
+
1: https://github.com/agorf/feed2email/commits.atom
|
148
|
+
2: http://www.rubyinside.com/feed/
|
149
|
+
3: http://thechangelog.com/feed/
|
150
|
+
~~~
|
151
|
+
|
152
|
+
To disable a feed so that it is not processed with `feed2email process`, toggle
|
153
|
+
it:
|
154
|
+
|
155
|
+
~~~ sh
|
156
|
+
$ feed2email toggle 1
|
157
|
+
Disabled feed at index 1
|
158
|
+
$ feed2email list
|
159
|
+
0: https://github.com/agorf.atom
|
160
|
+
1: DISABLED https://github.com/agorf/feed2email/commits.atom
|
161
|
+
2: http://www.rubyinside.com/feed/
|
162
|
+
3: http://thechangelog.com/feed/
|
104
163
|
~~~
|
105
164
|
|
106
|
-
|
165
|
+
It is also possible to remove it from the list:
|
107
166
|
|
108
|
-
~~~
|
109
|
-
|
167
|
+
~~~ sh
|
168
|
+
$ feed2email remove 1
|
169
|
+
Removed feed at index 1
|
170
|
+
Warning: Feed list indices have changed!
|
110
171
|
~~~
|
111
172
|
|
112
|
-
|
173
|
+
It has been removed, but what is that weird warning?
|
113
174
|
|
114
|
-
|
175
|
+
Since the feed that got removed was at index 1, every feed below it got
|
176
|
+
reindexed. So feed2email warns you that the feed indices have changed: the feed
|
177
|
+
at index 2 is now at index 1 and the feed at index 3 is now at index 2.
|
115
178
|
|
116
|
-
|
117
|
-
* `~/.feed2email/history-<digest>.yml` is created for each feed containing these
|
118
|
-
(old) entries, where `<digest>` is the MD5 hex digest of the feed URL
|
179
|
+
Indeed:
|
119
180
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
181
|
+
~~~ sh
|
182
|
+
$ feed2email list
|
183
|
+
0: https://github.com/agorf.atom
|
184
|
+
1: http://www.rubyinside.com/feed/
|
185
|
+
2: http://thechangelog.com/feed/
|
186
|
+
~~~
|
125
187
|
|
126
|
-
|
188
|
+
**Tip:** feed2email installs `f2e` as a symbolic link to the feed2email binary,
|
189
|
+
so you can use that to avoid typing the whole name every time, e.g.: `f2e list`
|
190
|
+
or even `f2e l`.
|
127
191
|
|
128
|
-
|
129
|
-
1. Run feed2email once so that the feed's history file is generated
|
130
|
-
1. Remove the entries you want to receive from the feed's history (i.e. with
|
131
|
-
your text editor)
|
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
|
192
|
+
### Running
|
134
193
|
|
135
|
-
|
136
|
-
|
194
|
+
~~~ sh
|
195
|
+
$ feed2email process
|
196
|
+
~~~
|
137
197
|
|
138
|
-
|
198
|
+
When run, feed2email will go through your feed list, fetch each feed (if
|
199
|
+
necessary) and send an email for each new entry. Any output is logged to the
|
200
|
+
standard output, unless configured otherwise.
|
139
201
|
|
140
|
-
|
141
|
-
|
142
|
-
|
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).
|
202
|
+
**Warning:** Prior to version 0.8.0 where a command-line interface was
|
203
|
+
introduced, the way to run feed2email was simply `feed2email`. Now this will
|
204
|
+
just print helpful text on how to use it.
|
146
205
|
|
147
|
-
|
206
|
+
When a new feed is detected (which is the case when feed2email runs for the
|
207
|
+
first time on your feed list), all of its entries are skipped and no email is
|
208
|
+
sent. This is so that you don't get spammed when you add a feed for the first
|
209
|
+
time.
|
148
210
|
|
149
|
-
|
211
|
+
If you want to receive a specific entry from a newly added feed, edit the feed's
|
212
|
+
history file with `feed2email history` and remove the entry. Then issue
|
213
|
+
`feed2email fetch` to clear the feed's fetch cache. Next time
|
214
|
+
`feed2email process` runs, the entry will be treated as new and will be
|
215
|
+
processed.
|
150
216
|
|
151
|
-
|
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.
|
217
|
+
### Getting help
|
155
218
|
|
156
|
-
|
219
|
+
Issue `feed2email` or `feed2email help` at any point to get helpful text on how
|
220
|
+
to use feed2email.
|
157
221
|
|
158
|
-
|
222
|
+
## Contributing
|
159
223
|
|
160
|
-
[
|
224
|
+
Using feed2email and want to help? Just [contact me](http://agorf.gr/) and
|
225
|
+
describe how you use it and if you have any ideas on how it can be improved.
|
161
226
|
|
162
227
|
## License
|
163
228
|
|
data/bin/f2e
ADDED
data/bin/feed2email
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require 'feed2email'
|
4
|
-
require 'feed2email/feed'
|
5
|
-
|
6
3
|
if File.new('/tmp/feed2email.lock', 'w').flock(File::LOCK_NB | File::LOCK_EX)
|
7
|
-
|
4
|
+
require 'feed2email/cli'
|
5
|
+
Feed2Email::Cli.start(ARGV)
|
8
6
|
else
|
9
|
-
|
10
|
-
exit 1
|
7
|
+
abort 'An instance of feed2email is already running. Exiting...'
|
11
8
|
end
|
9
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
CONFIG_DIR = File.expand_path('~/.feed2email')
|
6
|
+
FEEDS_FILE = File.join(CONFIG_DIR, 'feeds.yml')
|
7
|
+
|
8
|
+
if !File.exist?(FEEDS_FILE)
|
9
|
+
$stderr.puts "Missing feed list file #{FEEDS_FILE}"
|
10
|
+
exit 1
|
11
|
+
end
|
12
|
+
|
13
|
+
feeds_data = YAML.load(open(FEEDS_FILE))
|
14
|
+
|
15
|
+
unless feeds_data.is_a?(Array) && feeds_data.all? {|data| data.is_a?(String) }
|
16
|
+
$stderr.puts "Invalid data type for feed list file #{FEEDS_FILE}"
|
17
|
+
exit 2
|
18
|
+
end
|
19
|
+
|
20
|
+
File.rename(FEEDS_FILE, "#{FEEDS_FILE}.bak")
|
21
|
+
|
22
|
+
begin
|
23
|
+
open(FEEDS_FILE, 'w') do |f|
|
24
|
+
f.write(
|
25
|
+
feeds_data.map {|uri|
|
26
|
+
{ uri: uri, enabled: true }
|
27
|
+
}.to_yaml
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
puts "Migrated feed list file #{FEEDS_FILE}"
|
32
|
+
puts "Renamed #{FEEDS_FILE} to #{FEEDS_FILE}.bak"
|
33
|
+
rescue
|
34
|
+
File.rename("#{FEEDS_FILE}.bak", FEEDS_FILE)
|
35
|
+
raise
|
36
|
+
end
|
data/lib/feed2email.rb
CHANGED
@@ -1,22 +1,27 @@
|
|
1
1
|
require 'feed2email/config'
|
2
|
+
require 'feed2email/feed_list'
|
2
3
|
require 'feed2email/lazy_smtp_connection'
|
3
4
|
require 'feed2email/logger'
|
4
5
|
|
5
6
|
module Feed2Email
|
6
|
-
CONFIG_DIR = File.
|
7
|
+
CONFIG_DIR = File.join(ENV['HOME'], '.feed2email')
|
7
8
|
|
8
|
-
def self.config
|
9
|
-
|
10
|
-
def self.logger
|
11
|
-
@logger.logger # delegate
|
9
|
+
def self.config
|
10
|
+
@config ||= Config.new(File.join(CONFIG_DIR, 'config.yml'))
|
12
11
|
end
|
13
12
|
|
14
|
-
def self.
|
15
|
-
|
16
|
-
|
13
|
+
def self.feed_list
|
14
|
+
@feed_list ||= FeedList.new(File.join(CONFIG_DIR, 'feeds.yml'))
|
15
|
+
end
|
17
16
|
|
18
|
-
|
19
|
-
|
17
|
+
def self.logger
|
18
|
+
@logger ||= Logger.new(
|
19
|
+
config['log_path'], config['log_level'], config['log_shift_age'],
|
20
|
+
config['log_shift_size']
|
21
|
+
).logger
|
22
|
+
end
|
20
23
|
|
21
|
-
|
24
|
+
def self.smtp_connection
|
25
|
+
@smtp_connection ||= LazySMTPConnection.new
|
26
|
+
end
|
22
27
|
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'feed2email'
|
3
|
+
require 'feed2email/feed_autodiscoverer'
|
4
|
+
require 'feed2email/redirection_checker'
|
5
|
+
|
6
|
+
module Feed2Email
|
7
|
+
class Cli < Thor
|
8
|
+
desc 'add URL', 'subscribe to feed at URL'
|
9
|
+
def add(uri)
|
10
|
+
uri = handle_permanent_redirection(uri)
|
11
|
+
uri = perform_feed_autodiscovery(uri)
|
12
|
+
|
13
|
+
begin
|
14
|
+
feed_list << uri
|
15
|
+
rescue FeedList::DuplicateFeedError => e
|
16
|
+
abort e.message
|
17
|
+
end
|
18
|
+
|
19
|
+
if feed_list.sync
|
20
|
+
puts "Added feed #{uri} at index #{feed_list.size - 1}"
|
21
|
+
else
|
22
|
+
abort 'Failed to add feed'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
desc 'fetch FEED', 'clear fetch cache for feed at index FEED'
|
27
|
+
def fetch(index)
|
28
|
+
index = check_feed_index(index, in: (0...feed_list.size))
|
29
|
+
feed_list.clear_fetch_cache(index)
|
30
|
+
|
31
|
+
if feed_list.sync
|
32
|
+
puts "Cleared fetch cache for feed at index #{index}"
|
33
|
+
else
|
34
|
+
abort "Failed to clear fetch cache for feed at index #{index}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
desc 'history FEED', 'edit history file of feed at index FEED with $EDITOR'
|
39
|
+
def history(index)
|
40
|
+
abort '$EDITOR not set' unless ENV['EDITOR']
|
41
|
+
|
42
|
+
index = check_feed_index(index, in: (0...feed_list.size))
|
43
|
+
require 'feed2email/feed_history'
|
44
|
+
history_path = FeedHistory.new(feed_list[index][:uri]).path
|
45
|
+
exec(ENV['EDITOR'], history_path)
|
46
|
+
end
|
47
|
+
|
48
|
+
desc 'remove FEED', 'unsubscribe from feed at index FEED'
|
49
|
+
def remove(index)
|
50
|
+
index = check_feed_index(index, in: (0...feed_list.size))
|
51
|
+
deleted = feed_list.delete_at(index)
|
52
|
+
|
53
|
+
if deleted && feed_list.sync
|
54
|
+
puts "Removed feed at index #{index}"
|
55
|
+
|
56
|
+
if feed_list.size != index # feed was not the last
|
57
|
+
puts 'Warning: Feed list indices have changed!'
|
58
|
+
end
|
59
|
+
else
|
60
|
+
abort "Failed to remove feed at index #{index}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
desc 'toggle FEED', 'enable/disable feed at index FEED'
|
65
|
+
def toggle(index)
|
66
|
+
index = check_feed_index(index, in: (0...feed_list.size))
|
67
|
+
toggled = feed_list.toggle(index)
|
68
|
+
enabled = feed_list[index][:enabled]
|
69
|
+
|
70
|
+
if toggled && feed_list.sync
|
71
|
+
puts "#{enabled ? 'En' : 'Dis'}abled feed at index #{index}"
|
72
|
+
else
|
73
|
+
abort "Failed to #{enabled ? 'en' : 'dis'}able feed at index #{index}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
desc 'list', 'list feed subscriptions'
|
78
|
+
def list
|
79
|
+
puts feed_list
|
80
|
+
end
|
81
|
+
|
82
|
+
desc 'process', 'process feed subscriptions'
|
83
|
+
def process
|
84
|
+
feed_list.process
|
85
|
+
end
|
86
|
+
|
87
|
+
desc 'version', 'show feed2email version'
|
88
|
+
def version
|
89
|
+
require 'feed2email/version'
|
90
|
+
puts "feed2email #{Feed2Email::VERSION}"
|
91
|
+
end
|
92
|
+
|
93
|
+
no_commands do
|
94
|
+
def check_feed_index(index, options = {})
|
95
|
+
if index.to_i.to_s != index ||
|
96
|
+
(options[:in] && !options[:in].include?(index.to_i))
|
97
|
+
puts if index.nil? # Ctrl-D
|
98
|
+
abort 'Invalid index'
|
99
|
+
end
|
100
|
+
|
101
|
+
index.to_i
|
102
|
+
end
|
103
|
+
|
104
|
+
def feed_list
|
105
|
+
Feed2Email.feed_list # delegate
|
106
|
+
end
|
107
|
+
|
108
|
+
def handle_permanent_redirection(uri)
|
109
|
+
checker = RedirectionChecker.new(uri)
|
110
|
+
|
111
|
+
if checker.permanently_redirected?
|
112
|
+
puts "Got permanently redirected to #{checker.location}"
|
113
|
+
checker.location
|
114
|
+
else
|
115
|
+
uri
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def perform_feed_autodiscovery(uri)
|
120
|
+
discoverer = FeedAutodiscoverer.new(uri)
|
121
|
+
|
122
|
+
discovered_feeds = discoverer.feeds.reject {|feed|
|
123
|
+
feed_list.include?(feed[:uri])
|
124
|
+
}
|
125
|
+
|
126
|
+
if discovered_feeds.empty?
|
127
|
+
if discoverer.content_type == 'text/html'
|
128
|
+
puts 'Could not find any new feeds'
|
129
|
+
exit
|
130
|
+
end
|
131
|
+
|
132
|
+
return uri
|
133
|
+
end
|
134
|
+
|
135
|
+
justify = discovered_feeds.size.to_s.size
|
136
|
+
|
137
|
+
discovered_feeds.each_with_index do |feed, i|
|
138
|
+
puts '%{index}: %{uri} %{title}(%{content_type})' % {
|
139
|
+
index: i.to_s.rjust(justify),
|
140
|
+
uri: feed[:uri],
|
141
|
+
title: feed[:title] ? "\"#{feed[:title]}\" " : '',
|
142
|
+
content_type: feed[:content_type]
|
143
|
+
}
|
144
|
+
end
|
145
|
+
|
146
|
+
begin
|
147
|
+
response = ask('Please enter a feed to subscribe to:')
|
148
|
+
rescue Interrupt # Ctrl-C
|
149
|
+
puts
|
150
|
+
exit
|
151
|
+
end
|
152
|
+
|
153
|
+
index = check_feed_index(response, in: (0...discovered_feeds.size))
|
154
|
+
discovered_feeds[index][:uri]
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|