rss2mail 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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:
|