feed2email 0.2.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile.lock +11 -12
- data/README.md +15 -3
- data/lib/feed2email.rb +3 -0
- data/lib/feed2email/entry.rb +40 -6
- data/lib/feed2email/feed.rb +55 -9
- data/lib/feed2email/logger.rb +37 -0
- data/lib/feed2email/mail.rb +1 -1
- data/lib/feed2email/version.rb +1 -1
- metadata +16 -28
- data/feeds.yml.sample +0 -3
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bf67c31096e64a3b8e790b968fbd7fecd5384c78
|
4
|
+
data.tar.gz: 0a7567b5e3b8aa17aa9977d9a5485fa5d6fec138
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e187b0d14d5687d410b9860b6ab5cbeed2fe5d38764d95da23f460a198f607547cc8b35e5faae8b65a74c2d0add7259ab37cfec13607ff9c3de0643d0264eda6
|
7
|
+
data.tar.gz: 4d735364a8a9f84d6a66de1c3a7f622056517ec72dd04f648c2a9fad9966ea188f44dea1c5222f9b1c3ff7f64ae64f81f66970e5b4733272ec8b5e0c10f65907
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
feed2email (0.
|
4
|
+
feed2email (0.3.0)
|
5
5
|
feedzirra
|
6
6
|
mail
|
7
7
|
|
@@ -10,7 +10,7 @@ GEM
|
|
10
10
|
specs:
|
11
11
|
activesupport (3.1.12)
|
12
12
|
multi_json (~> 1.0)
|
13
|
-
builder (3.2.
|
13
|
+
builder (3.2.0)
|
14
14
|
curb (0.7.18)
|
15
15
|
feedzirra (0.1.3)
|
16
16
|
activesupport (~> 3.1.1)
|
@@ -22,25 +22,24 @@ GEM
|
|
22
22
|
rake (>= 0.8.7)
|
23
23
|
rdoc (~> 3.8)
|
24
24
|
sax-machine (~> 0.1.0)
|
25
|
-
i18n (0.6.
|
26
|
-
json (1.
|
25
|
+
i18n (0.6.4)
|
26
|
+
json (1.7.7)
|
27
27
|
loofah (1.2.1)
|
28
28
|
nokogiri (>= 1.4.4)
|
29
|
-
mail (2.5.
|
29
|
+
mail (2.5.3)
|
30
|
+
i18n (>= 0.4.0)
|
30
31
|
mime-types (~> 1.16)
|
31
32
|
treetop (~> 1.4.8)
|
32
|
-
mime-types (1.
|
33
|
-
|
34
|
-
|
35
|
-
nokogiri (1.6.0)
|
36
|
-
mini_portile (~> 0.5.0)
|
33
|
+
mime-types (1.22)
|
34
|
+
multi_json (1.7.2)
|
35
|
+
nokogiri (1.5.9)
|
37
36
|
polyglot (0.3.3)
|
38
|
-
rake (10.
|
37
|
+
rake (10.0.4)
|
39
38
|
rdoc (3.12.2)
|
40
39
|
json (~> 1.4)
|
41
40
|
sax-machine (0.1.0)
|
42
41
|
nokogiri (> 0.0.0)
|
43
|
-
treetop (1.4.
|
42
|
+
treetop (1.4.12)
|
44
43
|
polyglot
|
45
44
|
polyglot (>= 0.3.1)
|
46
45
|
|
data/README.md
CHANGED
@@ -42,7 +42,9 @@ pair is separated with a colon: `foo: bar`
|
|
42
42
|
|
43
43
|
* `recipient` (required) is the email address to send email to
|
44
44
|
* `send_delay` (optional) is the number of seconds to wait between each email to
|
45
|
-
|
45
|
+
avoid SMTP server throttling errors (default is `10`; use `0` to disable)
|
46
|
+
* `log_path` (optional) is the _absolute_ path to the log file (default is
|
47
|
+
`true` which logs to standard output; use `false` to disable)
|
46
48
|
|
47
49
|
### SMTP
|
48
50
|
|
@@ -74,9 +76,19 @@ interface setup and working in your system. I suggest [msmtp][] or [Postfix][].
|
|
74
76
|
## Use
|
75
77
|
|
76
78
|
Create `~/.feed2email/feeds.yml` and add the address of each feed you want to
|
77
|
-
subscribe to, prefixed with a dash and a space
|
79
|
+
subscribe to, prefixed with a dash and a space:
|
78
80
|
|
79
|
-
|
81
|
+
~~~ yaml
|
82
|
+
- https://github.com/agorf/feed2email/commits.atom
|
83
|
+
~~~
|
84
|
+
|
85
|
+
To disable a feed temporarily, comment it:
|
86
|
+
|
87
|
+
~~~ yaml
|
88
|
+
#- https://github.com/agorf/feed2email/commits.atom
|
89
|
+
~~~
|
90
|
+
|
91
|
+
You are now ready to run the program:
|
80
92
|
|
81
93
|
~~~ sh
|
82
94
|
$ feed2email
|
data/lib/feed2email.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
require 'cgi'
|
2
2
|
require 'feedzirra'
|
3
3
|
require 'fileutils'
|
4
|
+
require 'logger'
|
4
5
|
require 'mail'
|
5
6
|
require 'net/smtp'
|
7
|
+
require 'singleton'
|
6
8
|
require 'yaml'
|
7
9
|
|
8
10
|
require 'feed2email/config'
|
11
|
+
require 'feed2email/logger'
|
9
12
|
require 'feed2email/version'
|
10
13
|
require 'feed2email/core_ext'
|
11
14
|
require 'feed2email/mail'
|
data/lib/feed2email/entry.rb
CHANGED
@@ -20,7 +20,14 @@ module Feed2Email
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def process
|
23
|
-
|
23
|
+
log :debug, "Processing entry #{uri} ..."
|
24
|
+
|
25
|
+
if send?
|
26
|
+
log :debug, 'Sending email...'
|
27
|
+
to_mail.send
|
28
|
+
else
|
29
|
+
log :debug, 'Entry should not be sent; skipping...'
|
30
|
+
end
|
24
31
|
end
|
25
32
|
|
26
33
|
def title
|
@@ -28,19 +35,46 @@ module Feed2Email
|
|
28
35
|
end
|
29
36
|
|
30
37
|
def uri
|
31
|
-
@
|
38
|
+
@uri ||= begin
|
39
|
+
if @data.url[0] == '/'
|
40
|
+
@feed.uri.chomp('/') + @data.url
|
41
|
+
else
|
42
|
+
@data.url
|
43
|
+
end
|
44
|
+
end
|
32
45
|
end
|
33
46
|
|
34
47
|
private
|
35
48
|
|
49
|
+
def log(*args)
|
50
|
+
Feed2Email::Logger.instance.log(*args)
|
51
|
+
end
|
52
|
+
|
36
53
|
def published_at
|
37
54
|
@data.published
|
38
55
|
end
|
39
56
|
|
40
|
-
def
|
41
|
-
published_at
|
42
|
-
|
43
|
-
|
57
|
+
def send?
|
58
|
+
if published_at
|
59
|
+
log :debug, 'Entry has publication timestamp'
|
60
|
+
|
61
|
+
if published_at.past? # respect entries published in the future
|
62
|
+
log :debug, 'Entry published in the past'
|
63
|
+
|
64
|
+
if published_at > @feed.fetch_time
|
65
|
+
log :debug, 'Entry not seen before'
|
66
|
+
return true
|
67
|
+
else
|
68
|
+
log :debug, 'Entry seen before'
|
69
|
+
end
|
70
|
+
else
|
71
|
+
log :warn, "Entry #{uri} published in the future"
|
72
|
+
end
|
73
|
+
else
|
74
|
+
log :warn, "Entry #{uri} does not have publication timestamp"
|
75
|
+
end
|
76
|
+
|
77
|
+
false
|
44
78
|
end
|
45
79
|
|
46
80
|
def to_mail
|
data/lib/feed2email/feed.rb
CHANGED
@@ -3,6 +3,14 @@ module Feed2Email
|
|
3
3
|
FEEDS_FILE = File.join(CONFIG_DIR, 'feeds.yml')
|
4
4
|
STATE_FILE = File.join(CONFIG_DIR, 'state.yml')
|
5
5
|
|
6
|
+
def self.log(*args)
|
7
|
+
Feed2Email::Logger.instance.log(*args)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.pluralize(n, singular, plural)
|
11
|
+
"#{n} #{n == 1 ? singular : plural}"
|
12
|
+
end
|
13
|
+
|
6
14
|
def self.process(uri)
|
7
15
|
Feed.new(uri).process
|
8
16
|
end
|
@@ -10,6 +18,7 @@ module Feed2Email
|
|
10
18
|
def self.process_all
|
11
19
|
Feed2Email::Config.instance.read!
|
12
20
|
|
21
|
+
log :debug, 'Loading feed subscriptions...'
|
13
22
|
feed_uris = YAML.load(open(FEEDS_FILE)) rescue nil
|
14
23
|
|
15
24
|
if !feed_uris.is_a? Array
|
@@ -17,19 +26,19 @@ module Feed2Email
|
|
17
26
|
exit 4
|
18
27
|
end
|
19
28
|
|
29
|
+
log :info, "Subscribed to #{pluralize(feed_uris.size, 'feed', 'feeds')}"
|
30
|
+
|
31
|
+
log :debug, 'Loading fetch times...'
|
20
32
|
@@fetch_times = YAML.load(open(STATE_FILE)) rescue {}
|
21
33
|
|
22
|
-
feed_uris.each
|
23
|
-
begin
|
24
|
-
Feed.process(uri)
|
25
|
-
rescue
|
26
|
-
# TODO log failure
|
27
|
-
end
|
28
|
-
end
|
34
|
+
feed_uris.each {|uri| Feed.process(uri) }
|
29
35
|
|
36
|
+
log :debug, 'Writing fetch times...'
|
30
37
|
open(STATE_FILE, 'w') {|f| f.write(@@fetch_times.to_yaml) }
|
31
38
|
end
|
32
39
|
|
40
|
+
attr_reader :uri
|
41
|
+
|
33
42
|
def initialize(uri)
|
34
43
|
@uri = uri
|
35
44
|
end
|
@@ -38,9 +47,41 @@ module Feed2Email
|
|
38
47
|
@@fetch_times[@uri]
|
39
48
|
end
|
40
49
|
|
50
|
+
def pluralize(*args)
|
51
|
+
Feed2Email::Feed.pluralize(*args) # delegate
|
52
|
+
end
|
53
|
+
|
41
54
|
def process
|
42
|
-
|
43
|
-
|
55
|
+
log :info, "Processing feed #{@uri} ..."
|
56
|
+
|
57
|
+
if seen_before?
|
58
|
+
log :debug, 'Feed seen before'
|
59
|
+
|
60
|
+
if fetched?
|
61
|
+
log :debug, 'Feed is fetched'
|
62
|
+
|
63
|
+
if have_entries?
|
64
|
+
log :info, "Processing #{pluralize(entries.size, 'entry', 'entries')}..."
|
65
|
+
|
66
|
+
begin
|
67
|
+
process_entries
|
68
|
+
rescue => e
|
69
|
+
log :error, "#{e.class}: #{e.message.strip}"
|
70
|
+
end
|
71
|
+
else
|
72
|
+
log :warn, 'Feed does not have entries'
|
73
|
+
end
|
74
|
+
else
|
75
|
+
log :error, 'Feed could not be fetched'
|
76
|
+
end
|
77
|
+
else
|
78
|
+
log :info, 'Feed not seen before; skipping...'
|
79
|
+
end
|
80
|
+
|
81
|
+
if e.nil? && (!seen_before? || fetched?)
|
82
|
+
log :debug, 'Syncing fetch time...'
|
83
|
+
sync_fetch_time
|
84
|
+
end
|
44
85
|
end
|
45
86
|
|
46
87
|
def title
|
@@ -51,6 +92,7 @@ module Feed2Email
|
|
51
92
|
|
52
93
|
def data
|
53
94
|
if @data.nil?
|
95
|
+
log :debug, 'Fetching and parsing feed...'
|
54
96
|
@data = Feedzirra::Feed.fetch_and_parse(@uri,
|
55
97
|
:user_agent => "feed2email/#{VERSION}",
|
56
98
|
:compress => true
|
@@ -73,6 +115,10 @@ module Feed2Email
|
|
73
115
|
entries.any?
|
74
116
|
end
|
75
117
|
|
118
|
+
def log(*args)
|
119
|
+
Feed2Email::Feed.log(*args) # delegate
|
120
|
+
end
|
121
|
+
|
76
122
|
def process_entries
|
77
123
|
entries.each do |entry_data|
|
78
124
|
Entry.process(entry_data, self)
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Feed2Email
|
2
|
+
class Logger
|
3
|
+
include Singleton
|
4
|
+
|
5
|
+
def log(severity, message)
|
6
|
+
logger.add(::Logger.const_get(severity.upcase), message) if log?
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def config
|
12
|
+
Feed2Email::Config.instance.config
|
13
|
+
end
|
14
|
+
|
15
|
+
def log?
|
16
|
+
log_path != false
|
17
|
+
end
|
18
|
+
|
19
|
+
def log_path
|
20
|
+
config['log_path']
|
21
|
+
end
|
22
|
+
|
23
|
+
def log_to
|
24
|
+
if log_path.nil? || log_path == true
|
25
|
+
STDOUT
|
26
|
+
else
|
27
|
+
log_path
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def logger
|
32
|
+
@logger ||= ::Logger.new(log_to)
|
33
|
+
@logger.level = ::Logger::INFO
|
34
|
+
@logger
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/feed2email/mail.rb
CHANGED
data/lib/feed2email/version.rb
CHANGED
metadata
CHANGED
@@ -1,48 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: feed2email
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.3.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Aggelos Orfanakos
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-08-
|
11
|
+
date: 2013-08-25 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: feedzirra
|
16
|
-
type: :runtime
|
17
15
|
requirement: !ruby/object:Gem::Requirement
|
18
|
-
none: false
|
19
16
|
requirements:
|
20
|
-
- -
|
17
|
+
- - '>='
|
21
18
|
- !ruby/object:Gem::Version
|
22
19
|
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
23
22
|
version_requirements: !ruby/object:Gem::Requirement
|
24
|
-
none: false
|
25
23
|
requirements:
|
26
|
-
- -
|
24
|
+
- - '>='
|
27
25
|
- !ruby/object:Gem::Version
|
28
26
|
version: '0'
|
29
|
-
prerelease: false
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: mail
|
32
|
-
type: :runtime
|
33
29
|
requirement: !ruby/object:Gem::Requirement
|
34
|
-
none: false
|
35
30
|
requirements:
|
36
|
-
- -
|
31
|
+
- - '>='
|
37
32
|
- !ruby/object:Gem::Version
|
38
33
|
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
39
36
|
version_requirements: !ruby/object:Gem::Requirement
|
40
|
-
none: false
|
41
37
|
requirements:
|
42
|
-
- -
|
38
|
+
- - '>='
|
43
39
|
- !ruby/object:Gem::Version
|
44
40
|
version: '0'
|
45
|
-
prerelease: false
|
46
41
|
description: RSS/Atom feed updates in your email
|
47
42
|
email:
|
48
43
|
- agorf@agorf.gr
|
@@ -60,42 +55,35 @@ files:
|
|
60
55
|
- Rakefile
|
61
56
|
- bin/feed2email
|
62
57
|
- feed2email.gemspec
|
63
|
-
- feeds.yml.sample
|
64
58
|
- lib/feed2email.rb
|
65
59
|
- lib/feed2email/config.rb
|
66
60
|
- lib/feed2email/core_ext.rb
|
67
61
|
- lib/feed2email/entry.rb
|
68
62
|
- lib/feed2email/feed.rb
|
63
|
+
- lib/feed2email/logger.rb
|
69
64
|
- lib/feed2email/mail.rb
|
70
65
|
- lib/feed2email/version.rb
|
71
66
|
homepage: http://github.com/agorf/feed2email
|
72
67
|
licenses: []
|
68
|
+
metadata: {}
|
73
69
|
post_install_message:
|
74
70
|
rdoc_options: []
|
75
71
|
require_paths:
|
76
72
|
- lib
|
77
73
|
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
-
none: false
|
79
74
|
requirements:
|
80
|
-
- -
|
75
|
+
- - '>='
|
81
76
|
- !ruby/object:Gem::Version
|
82
77
|
version: '0'
|
83
|
-
segments:
|
84
|
-
- 0
|
85
|
-
hash: -4353394670092365916
|
86
78
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
-
none: false
|
88
79
|
requirements:
|
89
|
-
- -
|
80
|
+
- - '>='
|
90
81
|
- !ruby/object:Gem::Version
|
91
82
|
version: '0'
|
92
|
-
segments:
|
93
|
-
- 0
|
94
|
-
hash: -4353394670092365916
|
95
83
|
requirements: []
|
96
84
|
rubyforge_project:
|
97
|
-
rubygems_version:
|
85
|
+
rubygems_version: 2.0.3
|
98
86
|
signing_key:
|
99
|
-
specification_version:
|
87
|
+
specification_version: 4
|
100
88
|
summary: RSS/Atom feed updates in your email
|
101
89
|
test_files: []
|
data/feeds.yml.sample
DELETED