rss2mail 0.1.4 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog +2 -0
- data/README +1 -1
- data/Rakefile +1 -1
- data/example/config.ru +6 -0
- data/lib/rss2mail/app.rb +147 -0
- data/lib/rss2mail/rss.rb +6 -14
- data/lib/rss2mail/util.rb +9 -14
- data/lib/rss2mail/version.rb +2 -2
- metadata +23 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49e011a01e55c46ab776dff195817d5fe7716503
|
4
|
+
data.tar.gz: 7a036e2c3d8db37ce9cccea15e3a1583ef04ff5f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 24992fc5fb61a447dfe005769ab27abf9adfb4dfad5d7814527351afd63526afa19941d4293f68c4edb1f8c08a34ff3b4f200afb11ff3decb583fdada9b9826e
|
7
|
+
data.tar.gz: 74a0c2bbc0a020b013ea81e74c97673e969cf007d38213de778ae7208b37236ee0a95d4468872e097b068a67c41fba04f8673d6ea1329b8bc668cf0269ad43ee
|
data/ChangeLog
CHANGED
data/README
CHANGED
data/Rakefile
CHANGED
@@ -12,7 +12,7 @@ begin
|
|
12
12
|
:email => %q{jens.wille@gmail.com},
|
13
13
|
:homepage => :blackwinter,
|
14
14
|
:extra_files => FileList['templates/*'].to_a,
|
15
|
-
:dependencies => %w[
|
15
|
+
:dependencies => %w[nokogiri unidecode ruby-nuggets simple-rss sinatra]
|
16
16
|
}
|
17
17
|
}}
|
18
18
|
rescue LoadError => err
|
data/example/config.ru
ADDED
data/lib/rss2mail/app.rb
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#--
|
4
|
+
###############################################################################
|
5
|
+
# #
|
6
|
+
# A component of rss2mail, the RSS to e-mail forwarder. #
|
7
|
+
# #
|
8
|
+
# Copyright (C) 2007-2013 Jens Wille #
|
9
|
+
# #
|
10
|
+
# Authors: #
|
11
|
+
# Jens Wille <jens.wille@gmail.com> #
|
12
|
+
# #
|
13
|
+
# rss2mail is free software; you can redistribute it and/or modify it under #
|
14
|
+
# the terms of the GNU Affero General Public License as published by the Free #
|
15
|
+
# Software Foundation; either version 3 of the License, or (at your option) #
|
16
|
+
# any later version. #
|
17
|
+
# #
|
18
|
+
# rss2mail is distributed in the hope that it will be useful, but WITHOUT ANY #
|
19
|
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
20
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for #
|
21
|
+
# more details. #
|
22
|
+
# #
|
23
|
+
# You should have received a copy of the GNU Affero General Public License #
|
24
|
+
# along with rss2mail. If not, see <http://www.gnu.org/licenses/>. #
|
25
|
+
# #
|
26
|
+
###############################################################################
|
27
|
+
#++
|
28
|
+
|
29
|
+
require 'yaml'
|
30
|
+
require 'sinatra'
|
31
|
+
require 'rss2mail/util'
|
32
|
+
|
33
|
+
use Rack::Auth::Basic do |user, pass|
|
34
|
+
@auth ||= begin
|
35
|
+
file = File.join(settings.root, 'auth.yaml')
|
36
|
+
File.readable?(file) ? YAML.load_file(file) : {}
|
37
|
+
end
|
38
|
+
|
39
|
+
@auth[user] == pass
|
40
|
+
end
|
41
|
+
|
42
|
+
helpers ERB::Util
|
43
|
+
|
44
|
+
get '/' do
|
45
|
+
prepare
|
46
|
+
|
47
|
+
if @feed_url = RSS2Mail::Util.discover_feed(@url = params[:url])
|
48
|
+
@title = Nokogiri.HTML(open(@feed_url)).at_css('title').content rescue nil
|
49
|
+
end
|
50
|
+
|
51
|
+
erb :index
|
52
|
+
end
|
53
|
+
|
54
|
+
post '/' do
|
55
|
+
prepare
|
56
|
+
|
57
|
+
@feed_url = params[:feed_url] or error(400)
|
58
|
+
|
59
|
+
@target = params[:target]
|
60
|
+
@target = @targets.find { |t| t.to_s == @target } || :daily
|
61
|
+
|
62
|
+
@title, @to = params[:title] || '', params[:to]
|
63
|
+
@title = @feed_url[/[^\/]+\z/][/[\w.]+/] if @title.empty?
|
64
|
+
|
65
|
+
unless (feeds = @feeds[@target]).find { |f| f[:url] == @feed_url }
|
66
|
+
feeds << { :url => @feed_url, :title => @title, :to => @to }
|
67
|
+
File.open(@feeds_file, 'w') { |f| YAML.dump(@feeds, f) }
|
68
|
+
end
|
69
|
+
|
70
|
+
erb :index
|
71
|
+
end
|
72
|
+
|
73
|
+
def prepare
|
74
|
+
user = request.env['REMOTE_USER'] or error(400)
|
75
|
+
|
76
|
+
@feeds_file = File.join(settings.root, 'feeds.d', "#{user}.yaml")
|
77
|
+
@feeds = File.readable?(@feeds_file) ? YAML.load_file(@feeds_file) : {}
|
78
|
+
@targets = @feeds.keys.sort_by { |t, _| t.to_s }
|
79
|
+
end
|
80
|
+
|
81
|
+
__END__
|
82
|
+
@@index
|
83
|
+
<?xml version="1.0" encoding="utf-8"?>
|
84
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
85
|
+
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
86
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
87
|
+
<head>
|
88
|
+
<meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8" />
|
89
|
+
<title><%=h settings.title || 'rss2mail' %></title>
|
90
|
+
<% if settings.style %>
|
91
|
+
<link rel="stylesheet" type="text/css" href="<%=h settings.style %>" />
|
92
|
+
<% end %>
|
93
|
+
<style type="text/css">a.skip { text-decoration: line-through; }</style>
|
94
|
+
</head>
|
95
|
+
<body>
|
96
|
+
<h1>rss2mail - send rss feeds as e-mail</h1>
|
97
|
+
|
98
|
+
<h2>subscribe</h2>
|
99
|
+
|
100
|
+
<form method="post">
|
101
|
+
<input type="text" id="feed_url" name="feed_url" value="<%= @feed_url || @url %>" size="54" />
|
102
|
+
<% if @url.nil? || @url.empty? %>
|
103
|
+
<label for="feed_url">»url«</label>
|
104
|
+
<% else %>
|
105
|
+
[<a href="<%= @url %>">link</a><% if @feed_url %> | <a href="<%= @feed_url %>">feed</a><% end %>]
|
106
|
+
<% end %>
|
107
|
+
<br />
|
108
|
+
<input type="text" id="title" name="title" value="<%=h @title %>" size="54" />
|
109
|
+
<label for="title">»title«</label>
|
110
|
+
<br />
|
111
|
+
<input type="text" id="to" name="to" value="<%=h @to %>" size="54" />
|
112
|
+
<label for="to">»to«</label>
|
113
|
+
<br />
|
114
|
+
<select id="target" name="target">
|
115
|
+
<% for target in @targets %>
|
116
|
+
<option<%= target == @target ? ' selected="selected"' : '' %>><%=h target %></option>
|
117
|
+
<% end %>
|
118
|
+
</select>
|
119
|
+
<br />
|
120
|
+
<input type="submit" value="subscribe!" style="margin-top: 0.6em; font-weight: bold" />
|
121
|
+
</form>
|
122
|
+
|
123
|
+
<h2>subscriptions</h2>
|
124
|
+
|
125
|
+
<ul>
|
126
|
+
<% for target in @targets %>
|
127
|
+
<li>
|
128
|
+
<strong><%=h target %></strong> (<%= @feeds[target].size %>)
|
129
|
+
|
130
|
+
<ul>
|
131
|
+
<% for feed in @feeds[target].sort_by { |f| f[:title].downcase } %>
|
132
|
+
<li>
|
133
|
+
<a href="<%= feed[:url] %>" class="<%= 'skip' if feed[:skip] %>"><%=h feed[:title] %></a>
|
134
|
+
<small>(<%=h Array(feed[:to]).join(', ') %>)</small>
|
135
|
+
</li>
|
136
|
+
<% end %>
|
137
|
+
</ul>
|
138
|
+
</li>
|
139
|
+
<% end %>
|
140
|
+
</ul>
|
141
|
+
|
142
|
+
<p><em>
|
143
|
+
powered by <a href="http://blackwinter.github.com/rss2mail">RSS2Mail</a>
|
144
|
+
and <a href="http://sinatrarb.com">Sinatra</a> -- v<%=h RSS2Mail::VERSION %>
|
145
|
+
</em></p>
|
146
|
+
</body>
|
147
|
+
</html>
|
data/lib/rss2mail/rss.rb
CHANGED
@@ -27,16 +27,11 @@
|
|
27
27
|
#++
|
28
28
|
|
29
29
|
require 'rss'
|
30
|
-
require '
|
30
|
+
require 'nokogiri'
|
31
31
|
require 'unidecode'
|
32
|
+
require 'simple-rss'
|
32
33
|
require 'nuggets/i18n'
|
33
34
|
|
34
|
-
begin
|
35
|
-
require 'hpricot'
|
36
|
-
rescue LoadError => err
|
37
|
-
warn err
|
38
|
-
end
|
39
|
-
|
40
35
|
module RSS2Mail
|
41
36
|
|
42
37
|
class RSS
|
@@ -185,16 +180,13 @@ module RSS2Mail
|
|
185
180
|
body.gsub!(/<\/?(.*?)>/) { |m| m if KEEP.include?($1.split.first.downcase) }
|
186
181
|
body.gsub!(/<a\s+href=['"](?!http:).*?>(.*?)<\/a>/mi, '\1')
|
187
182
|
|
188
|
-
|
183
|
+
body.encode!(encoding) if encoding
|
184
|
+
body
|
189
185
|
end
|
190
186
|
|
191
187
|
def extract_body(expr, attribute = nil)
|
192
|
-
|
193
|
-
|
194
|
-
attribute ? elem[attribute] : elem.to_s
|
195
|
-
else
|
196
|
-
open_feed(link).read
|
197
|
-
end
|
188
|
+
elem = Nokogiri.HTML(open_feed(link)).at(expr)
|
189
|
+
attribute ? elem[attribute] : elem.to_s
|
198
190
|
end
|
199
191
|
|
200
192
|
def clean_subject(str)
|
data/lib/rss2mail/util.rb
CHANGED
@@ -24,9 +24,8 @@
|
|
24
24
|
###############################################################################
|
25
25
|
#++
|
26
26
|
|
27
|
-
require 'uri'
|
28
27
|
require 'open-uri'
|
29
|
-
require '
|
28
|
+
require 'nokogiri'
|
30
29
|
|
31
30
|
require 'rss2mail/version'
|
32
31
|
|
@@ -40,26 +39,22 @@ module RSS2Mail
|
|
40
39
|
|
41
40
|
FEED_RE = %r{\Aapplication/(?:atom|rss)\+xml\z}i
|
42
41
|
|
42
|
+
URI_RE = URI.regexp(%w[http https])
|
43
|
+
|
43
44
|
# cf. <http://www.rssboard.org/rss-autodiscovery>
|
44
45
|
def discover_feed(url, or_self = false)
|
45
|
-
default = or_self ? url : nil
|
46
|
-
|
47
46
|
unless url.nil? || url.empty? || url == 'about:blank'
|
48
|
-
doc =
|
49
|
-
|
50
|
-
if feed_element = doc.search('//link[@rel="alternate"').find { |link|
|
51
|
-
link[:type] =~ FEED_RE
|
52
|
-
}
|
53
|
-
if feed_href = feed_element[:href]
|
54
|
-
return feed_href if feed_href =~ URI.regexp(%w[http https])
|
47
|
+
doc = Nokogiri.HTML(open_feed(url))
|
55
48
|
|
56
|
-
|
57
|
-
|
49
|
+
if link = doc.xpath('//link[@rel="alternate"]').find { |i| i[:type] =~ FEED_RE }
|
50
|
+
if href = link[:href]
|
51
|
+
return href =~ URI_RE ? href :
|
52
|
+
URI.join((base = doc.at_xpath('//base')) && base[:href] || url, href).to_s
|
58
53
|
end
|
59
54
|
end
|
60
55
|
end
|
61
56
|
|
62
|
-
|
57
|
+
url if or_self
|
63
58
|
end
|
64
59
|
|
65
60
|
def open_feed(url, options = {}, &block)
|
data/lib/rss2mail/version.rb
CHANGED
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rss2mail
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jens Wille
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-06-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: nokogiri
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - '>='
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: unidecode
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - '>='
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: ruby-nuggets
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - '>='
|
@@ -53,7 +53,21 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: simple-rss
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: sinatra
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
73
|
- - '>='
|
@@ -77,6 +91,7 @@ extra_rdoc_files:
|
|
77
91
|
- ChangeLog
|
78
92
|
files:
|
79
93
|
- lib/rss2mail.rb
|
94
|
+
- lib/rss2mail/app.rb
|
80
95
|
- lib/rss2mail/feed.rb
|
81
96
|
- lib/rss2mail/rss.rb
|
82
97
|
- lib/rss2mail/util.rb
|
@@ -88,6 +103,7 @@ files:
|
|
88
103
|
- ChangeLog
|
89
104
|
- README
|
90
105
|
- Rakefile
|
106
|
+
- example/config.ru
|
91
107
|
- example/feeds.yaml
|
92
108
|
homepage: http://github.com/blackwinter/rss2mail
|
93
109
|
licenses: []
|
@@ -99,7 +115,7 @@ rdoc_options:
|
|
99
115
|
- --line-numbers
|
100
116
|
- --all
|
101
117
|
- --title
|
102
|
-
- rss2mail Application documentation (v0.
|
118
|
+
- rss2mail Application documentation (v0.2.0)
|
103
119
|
- --main
|
104
120
|
- README
|
105
121
|
require_paths:
|