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 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
@@ -1,3 +1,10 @@
1
+ ### 0.3.0
2
+
3
+ * Add logging
4
+ * Do not sync fetch time if there was an error
5
+ * Extract email address from entry author
6
+ * Prepend feed URI to path entry permalinks
7
+
1
8
  ### 0.2.3
2
9
 
3
10
  * Isolate feed processing failures
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- feed2email (0.2.3)
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.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.5)
26
- json (1.8.0)
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.4)
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.24)
33
- mini_portile (0.5.1)
34
- multi_json (1.7.9)
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.1.0)
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.15)
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
- avoid SMTP server throttling errors (default is `10`; use `0` to turn off)
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
- Then run it:
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'
@@ -20,7 +20,14 @@ module Feed2Email
20
20
  end
21
21
 
22
22
  def process
23
- to_mail.send if to_be_sent?
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
- @data.url
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 to_be_sent?
41
- published_at &&
42
- published_at.past? && # respect entry future pubDate
43
- published_at > @feed.fetch_time
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
@@ -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 do |uri|
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
- process_entries if seen_before? && fetched? && have_entries?
43
- sync_fetch_time if !seen_before? || fetched?
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
@@ -50,7 +50,7 @@ module Feed2Email
50
50
 
51
51
  def from_address
52
52
  if @entry.author && @entry.author['@']
53
- @entry.author
53
+ @entry.author[/\S+@\S+/]
54
54
  elsif send_with_smtp?
55
55
  '%{user}@%{host}' % {
56
56
  :user => config['smtp_user'],
@@ -1,3 +1,3 @@
1
1
  module Feed2Email
2
- VERSION = '0.2.3'
2
+ VERSION = '0.3.0'
3
3
  end
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.2.3
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-21 00:00:00.000000000 Z
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: 1.8.23
85
+ rubygems_version: 2.0.3
98
86
  signing_key:
99
- specification_version: 3
87
+ specification_version: 4
100
88
  summary: RSS/Atom feed updates in your email
101
89
  test_files: []
data/feeds.yml.sample DELETED
@@ -1,3 +0,0 @@
1
- ---
2
- - http://feeds.feedburner.com/agorf
3
- - http://api.twitter.com/1/statuses/user_timeline.rss?screen_name=agorf