feed2email 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ *.yml
3
+ .bundle
4
+ Gemfile.lock
5
+ pkg/
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,9 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2013 Aggelos Orfanakos
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # feed2email
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 my email. I also never read a thing when feeds are kept in a separate place.
8
+
9
+ The script was written primarily as a replacement of the [rss2email][] program which is rather big, slow, bloated and hard to use.
10
+
11
+ [rss2email]: http://www.allthingsrss.com/rss2email/
12
+
13
+ ## Installation
14
+
15
+ Install as a [gem][] from [RubyGems][]:
16
+
17
+ ~~~ sh
18
+ $ gem install feed2email
19
+ ~~~
20
+
21
+ You also need to have [Sendmail][] working in your system to send mail. I use [msmtp][] which is a nice alternative with a compatible Sendmail interface.
22
+
23
+ [gem]: http://rubygems.org/gems/feed2email
24
+ [RubyGems]: http://rubygems.org/
25
+ [Sendmail]: http://en.wikipedia.org/wiki/Sendmail
26
+ [msmtp]: http://msmtp.sourceforge.net/
27
+
28
+ ## Use
29
+
30
+ Create `~/.feed2email/feeds.yml` and add the address of each feed you want to subscribe to, prefixed with a dash and a space.
31
+
32
+ When run for the first time, the script enters "dry run" mode and exits almost immediately. During dry run mode:
33
+
34
+ * No feeds are fetched and, thus, no email is sent (existing feed entries are considered already seen)
35
+ * `~/.feed2email/cache.yml` is created containing the timestamp of when each feed was last fetched
36
+
37
+ If you want to receive existing entries from a specific feed, you can alter the timestamp for that feed in `cache.yml` to a value in the past. Next time you run the script, all entries published past that timestamp will be sent with email.
38
+
39
+ Here's how to run the script:
40
+
41
+ ~~~ sh
42
+ $ MAILTO=agorfatagorfdotgr feed2email
43
+ ~~~
44
+
45
+ It's also possible to override the path to the [Sendmail][] binary:
46
+
47
+ ~~~ sh
48
+ $ SENDMAIL=/path/to/sendmail MAILTO=agorfatagorfdotgr feed2email
49
+ ~~~
50
+
51
+ **Note:** Email symbols in the above examples have been replaced with words to avoid spam.
52
+
53
+ You can use [cron][] to run the script e.g. once every hour.
54
+
55
+ [cron]: http://en.wikipedia.org/wiki/Cron
56
+
57
+ ## License
58
+
59
+ Licensed under the MIT license (see `LICENSE.txt`).
60
+
61
+ ## Author
62
+
63
+ Aggelos Orfanakos, <http://agorf.gr/>
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
data/bin/feed2email ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'feed2email'
4
+
5
+ Feed2Email::Feed.process_all
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'feed2email/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = 'feed2email'
8
+ gem.version = Feed2Email::VERSION
9
+
10
+ gem.authors = ['Aggelos Orfanakos']
11
+ gem.date = Date.today
12
+ gem.email = ['agorf@agorf.gr']
13
+ gem.homepage = 'http://github.com/agorf/feed2email'
14
+
15
+ gem.description = %q{RSS/Atom feed updates in your email}
16
+ gem.summary = gem.description
17
+
18
+ gem.files = `git ls-files`.split($/)
19
+ gem.executables = gem.files.grep(%r{^bin/}).map {|f| File.basename(f) }
20
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
21
+ gem.require_paths = ['lib']
22
+
23
+ gem.add_dependency 'feedzirra'
24
+ gem.add_dependency 'mail'
25
+ end
data/feeds.yml.sample ADDED
@@ -0,0 +1,3 @@
1
+ ---
2
+ - http://feeds.feedburner.com/agorf
3
+ - http://api.twitter.com/1/statuses/user_timeline.rss?screen_name=agorf
@@ -0,0 +1,5 @@
1
+ class String
2
+ def escape_html
3
+ CGI.escapeHTML(self)
4
+ end
5
+ end
@@ -0,0 +1,44 @@
1
+ module Feed2Email
2
+ class Entry
3
+ attr_reader :feed
4
+
5
+ def self.process(data, feed)
6
+ Entry.new(data, feed).process
7
+ end
8
+
9
+ def initialize(data, feed)
10
+ @data = data
11
+ @feed = feed
12
+ end
13
+
14
+ def author
15
+ @data.author
16
+ end
17
+
18
+ def content
19
+ @data.content || @data.summary
20
+ end
21
+
22
+ def process
23
+ to_mail.send if new?
24
+ end
25
+
26
+ def title
27
+ @data.title
28
+ end
29
+
30
+ def url
31
+ @data.url
32
+ end
33
+
34
+ private
35
+
36
+ def new?
37
+ @data.published > @feed.fetch_time
38
+ end
39
+
40
+ def to_mail
41
+ Mail.new(self)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,72 @@
1
+ module Feed2Email
2
+ FEEDS_FILE = File.expand_path('~/.feed2email/feeds.yml')
3
+ CACHE_FILE = File.expand_path('~/.feed2email/cache.yml')
4
+ USER_AGENT = "feed2email/#{VERSION}"
5
+
6
+ class Feed
7
+ def self.process(uri)
8
+ Feed.new(uri).process
9
+ end
10
+
11
+ def self.process_all
12
+ Dir.mkdir(File.dirname(CACHE_FILE)) rescue nil
13
+
14
+ @@fetch_times = YAML.load(open(CACHE_FILE)) rescue {}
15
+
16
+ feed_uris = YAML.load(open(FEEDS_FILE)) rescue []
17
+ feed_uris.each {|uri| Feed.process(uri) }
18
+
19
+ open(CACHE_FILE, 'w') {|f| f.write(@@fetch_times.to_yaml) }
20
+ end
21
+
22
+ def initialize(uri)
23
+ @uri = uri
24
+ end
25
+
26
+ def fetch_time
27
+ @@fetch_times[@uri]
28
+ end
29
+
30
+ def process
31
+ process_entries if seen_before? && fetched? && have_entries?
32
+ sync_fetch_time if !seen_before? || fetched?
33
+ end
34
+
35
+ def title
36
+ data.title
37
+ end
38
+
39
+ private
40
+
41
+ def data
42
+ @fetched_at ||= Time.now
43
+ @data ||= Feedzirra::Feed.fetch_and_parse(@uri, :user_agent => USER_AGENT)
44
+ end
45
+
46
+ def entries
47
+ data.entries
48
+ end
49
+
50
+ def fetched?
51
+ data.respond_to?(:entries)
52
+ end
53
+
54
+ def have_entries?
55
+ data.entries.any?
56
+ end
57
+
58
+ def process_entries
59
+ entries.each do |entry_data|
60
+ Entry.process(entry_data, self)
61
+ end
62
+ end
63
+
64
+ def seen_before?
65
+ fetch_time.is_a?(Time)
66
+ end
67
+
68
+ def sync_fetch_time
69
+ @@fetch_times[@uri] = @fetched_at || Time.now
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,70 @@
1
+ module Feed2Email
2
+ SENDMAIL = ENV['SENDMAIL'] || '/usr/sbin/sendmail'
3
+ MAILTO = ENV['MAILTO'] || ENV['USER']
4
+
5
+ class Mail
6
+ def initialize(entry)
7
+ @entry = entry
8
+ end
9
+
10
+ def body
11
+ body_data = {
12
+ :url => @entry.url.escape_html,
13
+ :title => @entry.title.escape_html,
14
+ :content => @entry.content,
15
+ }
16
+ %{
17
+ <html>
18
+ <body>
19
+ <h1><a href="%{url}">%{title}</a></h1>
20
+ %{content}
21
+ <p><a href="%{url}">%{url}</a></p>
22
+ </body>
23
+ </html>
24
+ }.gsub(/^\s+/, '') % body_data
25
+ end
26
+
27
+ def from
28
+ from_data = {
29
+ :name => @entry.feed.title,
30
+ :email => @entry.author,
31
+ }
32
+
33
+ if from_data[:email].nil? || from_data[:email]['@'].nil?
34
+ from_data[:email] = to
35
+ end
36
+
37
+ '"%{name}" <%{email}>' % from_data
38
+ end
39
+
40
+ def html_part
41
+ part = ::Mail::Part.new
42
+ part.content_type = 'text/html; charset=UTF-8'
43
+ part.body = body
44
+ part
45
+ end
46
+
47
+ def mail
48
+ ::Mail.new.tap do |m|
49
+ m.from = from
50
+ m.to = to
51
+ m.subject = subject
52
+ m.html_part = html_part
53
+ end
54
+ end
55
+
56
+ def send
57
+ open("|#{SENDMAIL} #{to}", 'w') do |f|
58
+ f.write(mail)
59
+ end
60
+ end
61
+
62
+ def subject
63
+ @entry.title
64
+ end
65
+
66
+ def to
67
+ MAILTO
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,3 @@
1
+ module Feed2Email
2
+ VERSION = '0.0.1'
3
+ end
data/lib/feed2email.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'cgi'
2
+ require 'feedzirra'
3
+ require 'mail'
4
+ require 'yaml'
5
+
6
+ require 'feed2email/version'
7
+ require 'feed2email/core_ext'
8
+ require 'feed2email/mail'
9
+ require 'feed2email/entry'
10
+ require 'feed2email/feed'
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: feed2email
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Aggelos Orfanakos
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: feedzirra
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: mail
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: RSS/Atom feed updates in your email
47
+ email:
48
+ - agorf@agorf.gr
49
+ executables:
50
+ - feed2email
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - .gitignore
55
+ - Gemfile
56
+ - LICENSE.txt
57
+ - README.md
58
+ - Rakefile
59
+ - bin/feed2email
60
+ - feed2email.gemspec
61
+ - feeds.yml.sample
62
+ - lib/feed2email.rb
63
+ - lib/feed2email/core_ext.rb
64
+ - lib/feed2email/entry.rb
65
+ - lib/feed2email/feed.rb
66
+ - lib/feed2email/mail.rb
67
+ - lib/feed2email/version.rb
68
+ homepage: http://github.com/agorf/feed2email
69
+ licenses: []
70
+ post_install_message:
71
+ rdoc_options: []
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubyforge_project:
88
+ rubygems_version: 1.8.23
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: RSS/Atom feed updates in your email
92
+ test_files: []