rss2mail 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README +1 -1
- data/Rakefile +1 -1
- data/bin/rss2mail +3 -91
- data/lib/rss2mail/cli.rb +144 -0
- data/lib/rss2mail/feed.rb +17 -8
- data/lib/rss2mail/transport.rb +26 -15
- data/lib/rss2mail/version.rb +1 -1
- data/lib/rss2mail.rb +16 -0
- metadata +10 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fdea9e96f8edf94d5ee97696867166ba486f9782
|
4
|
+
data.tar.gz: 8ed7b8c15cb8efe8b3fbb7faca729801b77e81e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 469f61866f232d6f8112f5d858e872931015f6c77fb859aac281f83f55a35fe714901fc63f37033ef0cd005cfba0e1730a2507746ba058d7da9beca08175abe7
|
7
|
+
data.tar.gz: 4d69774ae5c80083fdb056079ffcc4e6f058854af32284e99df3086a19d973355aebaff2377449591b80fd22903f7810568b9a2e78ba22cdb6ad1bb1077cca1f
|
data/README
CHANGED
data/Rakefile
CHANGED
@@ -13,7 +13,7 @@ begin
|
|
13
13
|
:license => %q{AGPL-3.0},
|
14
14
|
:homepage => :blackwinter,
|
15
15
|
:extra_files => FileList['templates/*'].to_a,
|
16
|
-
:dependencies => %w[nokogiri
|
16
|
+
:dependencies => %w[nokogiri simple-rss sinatra unidecoder] << ['ruby-nuggets', '>= 0.9.6']
|
17
17
|
}
|
18
18
|
}}
|
19
19
|
rescue LoadError => err
|
data/bin/rss2mail
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
# #
|
6
6
|
# rss2mail -- Send RSS feeds as e-mail #
|
7
7
|
# #
|
8
|
-
# Copyright (C) 2007-
|
8
|
+
# Copyright (C) 2007-2014 Jens Wille #
|
9
9
|
# #
|
10
10
|
# Authors: #
|
11
11
|
# Jens Wille <jens.wille@gmail.com> #
|
@@ -26,93 +26,5 @@
|
|
26
26
|
###############################################################################
|
27
27
|
#++
|
28
28
|
|
29
|
-
require '
|
30
|
-
|
31
|
-
require 'nuggets/env/user_home'
|
32
|
-
|
33
|
-
require 'rss2mail'
|
34
|
-
|
35
|
-
base = File.expand_path('../..', __FILE__)
|
36
|
-
|
37
|
-
USAGE = "Usage: #{$0} [options] <target>"
|
38
|
-
abort USAGE if ARGV.empty?
|
39
|
-
|
40
|
-
options = {
|
41
|
-
:files => nil,
|
42
|
-
:reload => false,
|
43
|
-
:verbose => false,
|
44
|
-
:debug => false
|
45
|
-
}
|
46
|
-
|
47
|
-
OptionParser.new { |opts|
|
48
|
-
opts.banner = USAGE
|
49
|
-
opts.separator ''
|
50
|
-
|
51
|
-
opts.on('-d', '--directory DIRECTORY', 'Process all feeds in directory') { |d|
|
52
|
-
abort "Not a directory: #{d}" unless File.directory?(d)
|
53
|
-
abort "Can't read directory: #{d}" unless File.readable?(d)
|
54
|
-
|
55
|
-
options[:files] = Dir[File.join(d, '*.yaml')]
|
56
|
-
}
|
57
|
-
|
58
|
-
opts.on('-r', '--reload', 'Reload feeds') {
|
59
|
-
options[:reload] = true
|
60
|
-
}
|
61
|
-
|
62
|
-
opts.on('-v', '--verbose', 'Be verbose') {
|
63
|
-
options[:verbose] = true
|
64
|
-
}
|
65
|
-
|
66
|
-
opts.on('-D', '--debug', "Print debug output and don't send any mails") {
|
67
|
-
options[:debug] = true
|
68
|
-
}
|
69
|
-
|
70
|
-
opts.on('-h', '--help', 'Print this help message and exit') {
|
71
|
-
abort opts.to_s
|
72
|
-
}
|
73
|
-
|
74
|
-
opts.on('--version', 'Print program version and exit') {
|
75
|
-
abort "#{File.basename($0)} v#{RSS2Mail::VERSION}"
|
76
|
-
}
|
77
|
-
}.parse!
|
78
|
-
|
79
|
-
if target = ARGV.shift
|
80
|
-
target = target.to_sym
|
81
|
-
else
|
82
|
-
abort "No feeds target given\n#{USAGE}"
|
83
|
-
end
|
84
|
-
|
85
|
-
templates = Hash.new { |h, k|
|
86
|
-
h[k] = begin
|
87
|
-
File.read(File.join(base, 'templates', "#{k}.erb"))
|
88
|
-
rescue Errno::ENOENT
|
89
|
-
# silently ignore
|
90
|
-
end
|
91
|
-
}
|
92
|
-
|
93
|
-
feeds_files = options.delete(:files) || if File.directory?(d = File.join(ENV.user_home, '.rss2mail'))
|
94
|
-
Dir[File.join(d, '*.yaml')]
|
95
|
-
else
|
96
|
-
[File.join(base, 'feeds.yaml')]
|
97
|
-
end
|
98
|
-
|
99
|
-
feeds_files.each { |feeds_file|
|
100
|
-
feeds = begin
|
101
|
-
YAML.load_file(feeds_file)
|
102
|
-
rescue Errno::ENOENT
|
103
|
-
warn "Feeds file not found: #{feeds_file}"
|
104
|
-
next
|
105
|
-
end
|
106
|
-
|
107
|
-
unless target_feeds = feeds[target]
|
108
|
-
warn "Feeds target not found: #{target} (in #{feeds_file})"
|
109
|
-
next
|
110
|
-
end
|
111
|
-
|
112
|
-
target_feeds.each { |feed|
|
113
|
-
RSS2Mail::Feed.new(feed, options).deliver(templates) unless feed[:skip]
|
114
|
-
}
|
115
|
-
|
116
|
-
# write updated feed information
|
117
|
-
File.open(feeds_file, 'w') { |file| YAML.dump(feeds, file) } unless options[:debug]
|
118
|
-
}
|
29
|
+
require 'rss2mail/cli'
|
30
|
+
RSS2Mail::CLI.execute
|
data/lib/rss2mail/cli.rb
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
#--
|
2
|
+
###############################################################################
|
3
|
+
# #
|
4
|
+
# A component of rss2mail, the RSS to e-mail forwarder. #
|
5
|
+
# #
|
6
|
+
# Copyright (C) 2007-2014 Jens Wille #
|
7
|
+
# #
|
8
|
+
# Authors: #
|
9
|
+
# Jens Wille <jens.wille@gmail.com> #
|
10
|
+
# #
|
11
|
+
# rss2mail is free software; you can redistribute it and/or modify it under #
|
12
|
+
# the terms of the GNU Affero General Public License as published by the Free #
|
13
|
+
# Software Foundation; either version 3 of the License, or (at your option) #
|
14
|
+
# any later version. #
|
15
|
+
# #
|
16
|
+
# rss2mail is distributed in the hope that it will be useful, but WITHOUT ANY #
|
17
|
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS #
|
18
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for #
|
19
|
+
# more details. #
|
20
|
+
# #
|
21
|
+
# You should have received a copy of the GNU Affero General Public License #
|
22
|
+
# along with rss2mail. If not, see <http://www.gnu.org/licenses/>. #
|
23
|
+
# #
|
24
|
+
###############################################################################
|
25
|
+
#++
|
26
|
+
|
27
|
+
require 'nuggets/cli'
|
28
|
+
|
29
|
+
require 'rss2mail'
|
30
|
+
|
31
|
+
module RSS2Mail
|
32
|
+
|
33
|
+
class CLI < Nuggets::CLI
|
34
|
+
|
35
|
+
class << self
|
36
|
+
|
37
|
+
def defaults
|
38
|
+
super.merge(
|
39
|
+
:files => nil,
|
40
|
+
:smtp => nil,
|
41
|
+
:lmtp => nil,
|
42
|
+
:reload => false,
|
43
|
+
:verbose => false,
|
44
|
+
:debug => false
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
def usage
|
51
|
+
"#{super} <target>"
|
52
|
+
end
|
53
|
+
|
54
|
+
def run(arguments)
|
55
|
+
if target = arguments.shift
|
56
|
+
target = target.to_sym
|
57
|
+
else
|
58
|
+
quit 'Feeds target is required!'
|
59
|
+
end
|
60
|
+
|
61
|
+
quit unless arguments.empty?
|
62
|
+
|
63
|
+
templates = Hash.new { |h, k|
|
64
|
+
h[k] = begin
|
65
|
+
File.read(File.join(TEMPLATE_PATH, "#{k}.erb"))
|
66
|
+
rescue Errno::ENOENT
|
67
|
+
# silently ignore
|
68
|
+
end
|
69
|
+
}
|
70
|
+
|
71
|
+
(options.delete(:files) || default_files).each { |feeds_file|
|
72
|
+
feeds = begin
|
73
|
+
YAML.load_file(feeds_file)
|
74
|
+
rescue Errno::ENOENT
|
75
|
+
warn "Feeds file not found: #{feeds_file}"
|
76
|
+
next
|
77
|
+
end
|
78
|
+
|
79
|
+
unless target_feeds = feeds[target]
|
80
|
+
warn "Feeds target not found in #{feeds_file}: #{target}"
|
81
|
+
next
|
82
|
+
end
|
83
|
+
|
84
|
+
target_feeds.each { |feed|
|
85
|
+
Feed.new(feed, options).deliver(templates) unless feed[:skip]
|
86
|
+
}
|
87
|
+
|
88
|
+
unless options[:debug]
|
89
|
+
File.open(feeds_file, 'w') { |file| YAML.dump(feeds, file) }
|
90
|
+
end
|
91
|
+
}
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def opts(opts)
|
97
|
+
opts.on('-d', '--directory DIRECTORY', 'Process all feeds in directory') { |dir|
|
98
|
+
quit "#{dir}: No such file or directory" unless File.directory?(dir)
|
99
|
+
quit "#{dir}: Permission denied" unless File.readable?(dir)
|
100
|
+
|
101
|
+
options[:files] = Dir[File.join(dir, '*.yaml')]
|
102
|
+
}
|
103
|
+
|
104
|
+
opts.separator ''
|
105
|
+
|
106
|
+
%w[smtp lmtp].each { |type|
|
107
|
+
klass = Transport.const_get(type.upcase)
|
108
|
+
|
109
|
+
opts.on("-#{type[0, 1]}", "--#{type} [HOST[:PORT]]",
|
110
|
+
"Send mail through #{type.upcase} server",
|
111
|
+
"[Default host: #{klass::DEFAULT_HOST}, default port: #{klass::DEFAULT_PORT}]") { |host|
|
112
|
+
options[type.to_sym] = host.to_s
|
113
|
+
}
|
114
|
+
}
|
115
|
+
|
116
|
+
opts.separator ''
|
117
|
+
|
118
|
+
opts.on('-r', '--reload', 'Reload feeds') {
|
119
|
+
options[:reload] = true
|
120
|
+
}
|
121
|
+
end
|
122
|
+
|
123
|
+
def generic_opts(opts)
|
124
|
+
opts.on('-v', '--verbose', 'Be verbose') {
|
125
|
+
options[:verbose] = true
|
126
|
+
}
|
127
|
+
|
128
|
+
opts.on('-D', '--debug', "Print debug output; don't send any mails") {
|
129
|
+
options[:debug] = true
|
130
|
+
}
|
131
|
+
|
132
|
+
opts.separator ''
|
133
|
+
|
134
|
+
super
|
135
|
+
end
|
136
|
+
|
137
|
+
def default_files
|
138
|
+
File.directory?(dir = DEFAULT_FEEDS_PATH) ?
|
139
|
+
Dir[File.join(dir, '*.yaml')] : [DEFAULT_FEEDS_FILE]
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
data/lib/rss2mail/feed.rb
CHANGED
@@ -24,8 +24,6 @@
|
|
24
24
|
###############################################################################
|
25
25
|
#++
|
26
26
|
|
27
|
-
require 'erb'
|
28
|
-
|
29
27
|
module RSS2Mail
|
30
28
|
|
31
29
|
class Feed
|
@@ -110,12 +108,23 @@ module RSS2Mail
|
|
110
108
|
private
|
111
109
|
|
112
110
|
def transport_from(options)
|
113
|
-
if lmtp = options[:lmtp]
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
111
|
+
if lmtp = options[:lmtp] or smtp = options[:smtp]
|
112
|
+
klass = smtp ? Transport::SMTP : Transport::LMTP
|
113
|
+
|
114
|
+
case @smtp = lmtp || smtp
|
115
|
+
when Array # ok
|
116
|
+
when true then @smtp = []
|
117
|
+
when Fixnum then @smtp = [nil, @smtp]
|
118
|
+
when String then @smtp = @smtp.split(':')
|
119
|
+
else raise TypeError, "Array expected, got #{@smtp.class}"
|
120
|
+
end
|
121
|
+
|
122
|
+
host, port = @smtp.shift, @smtp.shift
|
123
|
+
|
124
|
+
host = klass::DEFAULT_HOST if host.nil? || host.empty?
|
125
|
+
port = klass::DEFAULT_PORT if port.nil?
|
126
|
+
|
127
|
+
[klass, @smtp.unshift(port.to_i).unshift(host)[0, 4].join(':')]
|
119
128
|
else
|
120
129
|
[klass = Transport::Mail, "#{klass::CMD} = #{klass::BIN.inspect}"]
|
121
130
|
end
|
data/lib/rss2mail/transport.rb
CHANGED
@@ -66,25 +66,34 @@ module RSS2Mail
|
|
66
66
|
require 'net/smtp'
|
67
67
|
require 'securerandom'
|
68
68
|
|
69
|
+
DEFAULT_HOST = 'localhost'.freeze
|
70
|
+
DEFAULT_PORT = Net::SMTP.default_port
|
71
|
+
|
72
|
+
MESSAGE_TEMPLATE = <<-EOT
|
73
|
+
<%= FROM %>
|
74
|
+
To: <%= Array(to).join(', ') %>
|
75
|
+
Date: <%= Time.now.rfc822 %>
|
76
|
+
Subject: <%= subject %>
|
77
|
+
Message-Id: <%= SecureRandom.uuid %>
|
78
|
+
<%= type %>
|
79
|
+
|
80
|
+
<%= body %>
|
81
|
+
EOT
|
82
|
+
|
69
83
|
def deliver_mail(to, *args)
|
70
|
-
deliver_smtp(Net::SMTP,
|
84
|
+
deliver_smtp(Net::SMTP, [to], *args)
|
71
85
|
end
|
72
86
|
|
73
87
|
private
|
74
88
|
|
75
|
-
def deliver_smtp(klass,
|
76
|
-
klass.start(
|
77
|
-
|
78
|
-
smtp.send_message(
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
Message-Id: #{SecureRandom.uuid}
|
84
|
-
#{type}
|
85
|
-
|
86
|
-
#{body}
|
87
|
-
EOT
|
89
|
+
def deliver_smtp(klass, tos, subject, body, type)
|
90
|
+
klass.start(*@smtp) { |smtp|
|
91
|
+
tos.each { |to|
|
92
|
+
smtp.send_message(
|
93
|
+
ERB.new(MESSAGE_TEMPLATE).result(binding),
|
94
|
+
FROM,
|
95
|
+
*to
|
96
|
+
)
|
88
97
|
}
|
89
98
|
}
|
90
99
|
end
|
@@ -95,8 +104,10 @@ Message-Id: #{SecureRandom.uuid}
|
|
95
104
|
|
96
105
|
include SMTP
|
97
106
|
|
107
|
+
DEFAULT_PORT = SMTP::DEFAULT_PORT - 1
|
108
|
+
|
98
109
|
def deliver_mail(to, *args)
|
99
|
-
deliver_smtp(Net::LMTP,
|
110
|
+
deliver_smtp(Net::LMTP, to, *args)
|
100
111
|
end
|
101
112
|
|
102
113
|
end
|
data/lib/rss2mail/version.rb
CHANGED
data/lib/rss2mail.rb
CHANGED
@@ -24,12 +24,28 @@
|
|
24
24
|
###############################################################################
|
25
25
|
#++
|
26
26
|
|
27
|
+
require 'erb'
|
28
|
+
require 'nuggets/env/user_home'
|
29
|
+
|
27
30
|
require 'rss2mail/transport'
|
28
31
|
require 'rss2mail/util'
|
29
32
|
require 'rss2mail/feed'
|
30
33
|
require 'rss2mail/rss'
|
31
34
|
|
32
35
|
module RSS2Mail
|
36
|
+
|
37
|
+
BASE_PATH = ENV['RSS2MAIL_BASE_PATH'] ||
|
38
|
+
File.expand_path('../..', __FILE__)
|
39
|
+
|
40
|
+
TEMPLATE_PATH = ENV['RSS2MAIL_TEMPLATE_PATH'] ||
|
41
|
+
File.join(BASE_PATH, 'templates')
|
42
|
+
|
43
|
+
DEFAULT_FEEDS_PATH = ENV['RSS2MAIL_DEFAULT_FEEDS_PATH'] ||
|
44
|
+
File.join(ENV.user_home, '.rss2mail')
|
45
|
+
|
46
|
+
DEFAULT_FEEDS_FILE = ENV['RSS2MAIL_DEFAULT_FEEDS_FILE'] ||
|
47
|
+
File.join(BASE_PATH, 'feeds.yaml')
|
48
|
+
|
33
49
|
end
|
34
50
|
|
35
51
|
require 'nuggets/pluggable'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rss2mail
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.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: 2014-03-
|
11
|
+
date: 2014-03-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -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: simple-rss
|
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: sinatra
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: unidecoder
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
@@ -67,19 +67,19 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: ruby-nuggets
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 0.9.6
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: 0.9.6
|
83
83
|
description: Send RSS feeds as e-mail
|
84
84
|
email: jens.wille@gmail.com
|
85
85
|
executables:
|
@@ -99,6 +99,7 @@ files:
|
|
99
99
|
- example/feeds.yaml
|
100
100
|
- lib/rss2mail.rb
|
101
101
|
- lib/rss2mail/app.rb
|
102
|
+
- lib/rss2mail/cli.rb
|
102
103
|
- lib/rss2mail/feed.rb
|
103
104
|
- lib/rss2mail/rss.rb
|
104
105
|
- lib/rss2mail/transport.rb
|
@@ -113,7 +114,7 @@ metadata: {}
|
|
113
114
|
post_install_message:
|
114
115
|
rdoc_options:
|
115
116
|
- "--title"
|
116
|
-
- rss2mail Application documentation (v0.
|
117
|
+
- rss2mail Application documentation (v0.4.0)
|
117
118
|
- "--charset"
|
118
119
|
- UTF-8
|
119
120
|
- "--line-numbers"
|