rrimm 0.12.1 → 0.14.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 +5 -13
- data/.travis.yml +1 -2
- data/bin/rrimm +13 -4
- data/lib/rrimm.rb +1 -0
- data/lib/rrimm/cache.rb +5 -0
- data/lib/rrimm/config.rb +22 -5
- data/lib/rrimm/feed_config.rb +14 -9
- data/lib/rrimm/feed_config_extensions.rb +1 -1
- data/lib/rrimm/fetcher.rb +27 -13
- data/lib/rrimm/item_formatter/mail.rb +1 -0
- data/lib/rrimm/publisher.rb +14 -0
- data/lib/rrimm/publisher/pipe.rb +17 -0
- data/lib/rrimm/publisher/reddit.rb +91 -0
- data/rrimm.gemspec +7 -4
- data/spec/fetcher_spec.rb +10 -6
- data/spec/spec_helper.rb +3 -8
- data/spec/xkcd_spec.rb +16 -5
- metadata +33 -30
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
NzkzYmRlMDQyZWQxZGY1OWI0MTIwNzk2MmExZmFiMmM5OGUxNTFiYw==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5f7bc3ce30144cdbcb0b14be5c1675b380cb402f
|
4
|
+
data.tar.gz: b22cb2e5b1e9081c47803012314bf94e8b4c0bb1
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
MTRjZGJmNTY5ZjcyYzhiMTdhNTZjZWIzMTZkMDJkMGU4M2ExYTgyNjdkYTlh
|
11
|
-
OWUyNmEwYmRlZTI1MGE0MDBiMzkzZWYzMzZiMTBiMWVjY2FmMDc=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
NDdhMjM1MmI5ZjE4OTcwM2RlMDEyZGE5NjhkZTY3MTc5NWE1YTJhOTY2NTNi
|
14
|
-
YWIxODY5YTM5YzUwODMyNDkxNGRhZDM3MmU1ZTQyNDUxNTgzMjhhNjY3NzRj
|
15
|
-
YTFiNjVhZGE3Y2NmN2M4YWQ2NjFiNTk3YjRmZWM5OGRiNzE2OGI=
|
6
|
+
metadata.gz: 1f72cb03ac4097e5d807686560f7ddd9b8cf00e24a7e866e56b83f598812a42373564f7496ee708eb05c59a1332ca9a66915c8a74ddf9b6f5bcfd26656a93d22
|
7
|
+
data.tar.gz: fcbb75d848374d7f384a96a4842b5a064a6240540ed251ad63c2b6e5b35f71362bd2543188d5bdaf14eb22e3ca4840a4ea4909597533da3ab2ec2a2274793bd0
|
data/.travis.yml
CHANGED
data/bin/rrimm
CHANGED
@@ -30,13 +30,18 @@ OptionParser.new do |opts|
|
|
30
30
|
options['quiet'] = true
|
31
31
|
end
|
32
32
|
|
33
|
+
opts.on('-V', '--verbose',
|
34
|
+
'Verbose mode') do
|
35
|
+
options['verbose'] = true
|
36
|
+
end
|
37
|
+
|
33
38
|
opts.on('--category CATEGORY',
|
34
39
|
'Run action only on one category"') do |cat|
|
35
40
|
options['category'] = cat
|
36
41
|
end
|
37
42
|
|
38
|
-
opts.on('-a', '--action [action]', [:sync, :show, :status],
|
39
|
-
'Specify what to do: "sync" feeds, "show" config, display feed "status"') do |action|
|
43
|
+
opts.on('-a', '--action [action]', [:sync, :show, :status, :reset],
|
44
|
+
'Specify what to do: "sync" feeds, "show" config, display feed "status, reset feed cache"') do |action|
|
40
45
|
options['action'] = action
|
41
46
|
end
|
42
47
|
|
@@ -51,11 +56,11 @@ end.parse!(ARGV)
|
|
51
56
|
conf = RRImm::Config.new
|
52
57
|
conf.load(options['conf_file'])
|
53
58
|
|
54
|
-
fetcher = RRImm::Fetcher.new(conf)
|
59
|
+
fetcher = RRImm::Fetcher.new(conf, options)
|
55
60
|
IO.open STDOUT.fileno do |ios|
|
56
61
|
case options['action']
|
57
62
|
when :sync
|
58
|
-
fetcher.fetch
|
63
|
+
fetcher.fetch
|
59
64
|
when :show
|
60
65
|
conf.show(ios, options['category'])
|
61
66
|
when :status
|
@@ -64,5 +69,9 @@ IO.open STDOUT.fileno do |ios|
|
|
64
69
|
six_months_ago = Time.now.to_i - 6 * one_month
|
65
70
|
|
66
71
|
conf.status(ios, one_month_ago, six_months_ago, false, options['category'])
|
72
|
+
when :reset
|
73
|
+
time = ARGV.shift.to_i
|
74
|
+
puts "Will reset cache files more recent than #{Time.at(time)} to this date."
|
75
|
+
conf.reset_caches(time)
|
67
76
|
end
|
68
77
|
end
|
data/lib/rrimm.rb
CHANGED
data/lib/rrimm/cache.rb
CHANGED
@@ -42,6 +42,7 @@ module RRImm
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def save(feed, timestamp, force=true)
|
45
|
+
ensure_cache_dir!
|
45
46
|
file_path = cache_file(feed)
|
46
47
|
File.write(file_path, timestamp) if (force or timestamp != read(feed))
|
47
48
|
end
|
@@ -55,5 +56,9 @@ module RRImm
|
|
55
56
|
memo.gsub(pattern, '')
|
56
57
|
end
|
57
58
|
end
|
59
|
+
|
60
|
+
def ensure_cache_dir!
|
61
|
+
@cache_dir_exists ||= Dir.exists?(path) || Dir.mkdir(path)
|
62
|
+
end
|
58
63
|
end
|
59
64
|
end
|
data/lib/rrimm/config.rb
CHANGED
@@ -3,7 +3,7 @@ require 'colorize'
|
|
3
3
|
module RRImm
|
4
4
|
class Config
|
5
5
|
attr :feeds, :cache
|
6
|
-
attr :default_formatter, :
|
6
|
+
attr :default_formatter, :publisher
|
7
7
|
attr_accessor :output
|
8
8
|
|
9
9
|
def initialize
|
@@ -11,7 +11,7 @@ module RRImm
|
|
11
11
|
cache "default cache" do
|
12
12
|
path File.join(ENV['HOME'], '.cache', 'rrimm')
|
13
13
|
end
|
14
|
-
@
|
14
|
+
@publisher = RRImm::Pipe.new('cat')
|
15
15
|
end
|
16
16
|
|
17
17
|
def feeds
|
@@ -41,6 +41,15 @@ module RRImm
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
+
def reset_caches(timestamp)
|
45
|
+
@feeds.each do |name, f|
|
46
|
+
if get_cache.read(f) > timestamp
|
47
|
+
get_cache.save(f, timestamp)
|
48
|
+
puts "Reset #{name}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
44
53
|
def status(ios, old_timestamp, very_old_timestamp, display_old_only, category=nil)
|
45
54
|
@feeds.values.
|
46
55
|
select { |f| category.nil? || f.category == category }.
|
@@ -64,7 +73,7 @@ module RRImm
|
|
64
73
|
existing_feed = @feeds[feed_name]
|
65
74
|
new_feed = (existing_feed || FeedConfig.new(feed_name))
|
66
75
|
new_feed.formatter = default_formatter if default_formatter
|
67
|
-
new_feed.
|
76
|
+
new_feed.publisher= publisher if publisher
|
68
77
|
new_feed.instance_eval(&block) if block
|
69
78
|
new_feed
|
70
79
|
end
|
@@ -76,11 +85,19 @@ module RRImm
|
|
76
85
|
@default_formatter
|
77
86
|
end
|
78
87
|
|
88
|
+
def publisher(arg=nil)
|
89
|
+
if arg
|
90
|
+
@publisher = arg
|
91
|
+
end
|
92
|
+
@publisher
|
93
|
+
end
|
94
|
+
|
95
|
+
# compatibility with "pipe" method
|
79
96
|
def pipe(arg=nil)
|
80
97
|
if arg
|
81
|
-
|
98
|
+
publisher(RRImm::Pipe.new(arg))
|
82
99
|
end
|
83
|
-
|
100
|
+
publisher.command
|
84
101
|
end
|
85
102
|
|
86
103
|
def feed(name, *args, &block)
|
data/lib/rrimm/feed_config.rb
CHANGED
@@ -8,7 +8,7 @@ module RRImm
|
|
8
8
|
attr_accessor :uri
|
9
9
|
attr_accessor :formatter_class, :formatter
|
10
10
|
attr_accessor :category
|
11
|
-
attr_accessor :
|
11
|
+
attr_accessor :publisher
|
12
12
|
attr_accessor :massages
|
13
13
|
|
14
14
|
def initialize(name, &block)
|
@@ -37,14 +37,11 @@ module RRImm
|
|
37
37
|
|
38
38
|
def format(feed, item)
|
39
39
|
@formatter ||= @formatter_class.new
|
40
|
-
|
41
|
-
StringIO.open(
|
40
|
+
formatted_feed = ""
|
41
|
+
StringIO.open(formatted_feed) do |str|
|
42
42
|
@formatter.format(feed,item, self, str)
|
43
43
|
end
|
44
|
-
|
45
|
-
cmd.run_command
|
46
|
-
puts cmd.stderr if cmd.error?
|
47
|
-
cmd.error!
|
44
|
+
publisher.publish(formatted_feed, feed, item)
|
48
45
|
end
|
49
46
|
|
50
47
|
def category(arg=nil)
|
@@ -72,11 +69,19 @@ module RRImm
|
|
72
69
|
@formatter_class
|
73
70
|
end
|
74
71
|
|
72
|
+
def publisher(arg=nil)
|
73
|
+
if arg
|
74
|
+
@publisher = arg
|
75
|
+
end
|
76
|
+
@publisher
|
77
|
+
end
|
78
|
+
|
79
|
+
# compat with old pipe
|
75
80
|
def pipe(arg=nil)
|
76
81
|
if arg
|
77
|
-
|
82
|
+
publisher RRImm::Pipe.new(arg)
|
78
83
|
end
|
79
|
-
|
84
|
+
publisher.command
|
80
85
|
end
|
81
86
|
|
82
87
|
end
|
data/lib/rrimm/fetcher.rb
CHANGED
@@ -7,24 +7,25 @@ require 'timeout'
|
|
7
7
|
module RRImm
|
8
8
|
class Fetcher
|
9
9
|
|
10
|
-
attr_accessor :config
|
10
|
+
attr_accessor :config, :options
|
11
11
|
|
12
|
-
def initialize(config)
|
13
|
-
@config
|
12
|
+
def initialize(config, options)
|
13
|
+
@config = config
|
14
|
+
@options = options
|
15
|
+
@quiet = options['quiet']
|
16
|
+
@category = options['category']
|
14
17
|
end
|
15
18
|
|
16
|
-
def fetch(
|
17
|
-
|
18
|
-
|
19
|
-
if concurrency
|
20
|
-
parallel_fetch(concurrency)
|
19
|
+
def fetch()
|
20
|
+
if options['concurrency']
|
21
|
+
parallel_fetch
|
21
22
|
else
|
22
23
|
linear_fetch
|
23
24
|
end
|
24
25
|
end
|
25
26
|
|
26
|
-
def parallel_fetch
|
27
|
-
Parallel.map(feeds, :in_threads => concurrency, :progress => "fetching") do |name,feed_config|
|
27
|
+
def parallel_fetch
|
28
|
+
Parallel.map(feeds, :in_threads => options['concurrency'], :progress => "fetching") do |name,feed_config|
|
28
29
|
@quiet = true
|
29
30
|
fetch_feed(name, feed_config)
|
30
31
|
end
|
@@ -40,10 +41,19 @@ module RRImm
|
|
40
41
|
@config.feeds.select { |f,conf| @category.nil? || conf.category == @category }
|
41
42
|
end
|
42
43
|
|
44
|
+
def debug(message)
|
45
|
+
puts message if options['verbose']
|
46
|
+
end
|
47
|
+
|
43
48
|
def fetch_feed(name, feed_config)
|
44
49
|
begin
|
45
50
|
Timeout::timeout(30) do
|
46
|
-
|
51
|
+
begin
|
52
|
+
fetch_feed_no_timeout(name, feed_config)
|
53
|
+
rescue => e
|
54
|
+
puts "Received #{e.class.name} #{e.message} for #{name}"
|
55
|
+
raise
|
56
|
+
end
|
47
57
|
end
|
48
58
|
rescue Timeout::Error
|
49
59
|
puts "#{name} timeout after 30 seconds"
|
@@ -51,16 +61,20 @@ module RRImm
|
|
51
61
|
end
|
52
62
|
|
53
63
|
def fetch_feed_no_timeout(name, feed_config)
|
64
|
+
debug "-> #{name}: reading cache"
|
54
65
|
last_read = Time.at(@config.get_cache.read(feed_config))
|
55
66
|
print name unless @quiet
|
56
|
-
|
57
|
-
feed = Feedjira::Feed.fetch_and_parse(feed_config.uri
|
67
|
+
debug "-> #{name}: fetching and parsing"
|
68
|
+
feed = Feedjira::Feed.fetch_and_parse(feed_config.uri)
|
69
|
+
debug "-> #{name}: fetched and parsed (#{feed.class})"
|
58
70
|
if feed.respond_to? :entries
|
59
71
|
items = feed.entries.select { |item| item.published > last_read }
|
60
72
|
last_read = items.collect { |item| item.published }.max unless items.empty?
|
61
73
|
feed_config.massage(items).each do |item|
|
74
|
+
debug "-> #{name}: format an item"
|
62
75
|
feed_config.format(feed, item)
|
63
76
|
end
|
77
|
+
debug "-> #{name}: saving cache"
|
64
78
|
@config.get_cache.save(feed_config, last_read.to_i, false)
|
65
79
|
end
|
66
80
|
puts " (#{items.size rescue nil})" unless @quiet
|
@@ -33,6 +33,7 @@ module RRImm
|
|
33
33
|
pipe.write "Date: #{item.published.rfc2822}\n"
|
34
34
|
pipe.write "Subject: #{subject(feed, item, feed_config)}\n"
|
35
35
|
pipe.write "Content-Type: text/html;\n"
|
36
|
+
pipe.write "X-Source-Uri: #{feed_config.uri}\n"
|
36
37
|
pipe.write "\n"
|
37
38
|
pipe.write item.url
|
38
39
|
pipe.write "\n\n"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module RRImm
|
2
|
+
class Publisher
|
3
|
+
# will receive in order:
|
4
|
+
# - formatted item
|
5
|
+
# - raw feed
|
6
|
+
# - raw item
|
7
|
+
def publish(*args)
|
8
|
+
raise "You have to implement this method"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
require_relative 'publisher/pipe'
|
14
|
+
require_relative 'publisher/reddit'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module RRImm
|
2
|
+
class Pipe < Publisher
|
3
|
+
def initialize(command)
|
4
|
+
super()
|
5
|
+
@command = command
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_reader :command
|
9
|
+
|
10
|
+
def publish(input, *args)
|
11
|
+
cmd = Mixlib::ShellOut.new(command, input: input)
|
12
|
+
cmd.run_command
|
13
|
+
puts cmd.stderr if cmd.error?
|
14
|
+
cmd.error!
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module RRImm
|
2
|
+
class Reddit < Publisher
|
3
|
+
def initialize
|
4
|
+
require 'redd' # avoid requirment if necessary HACK
|
5
|
+
|
6
|
+
# patch redd to allow creating subreddits
|
7
|
+
Redd::Models::Subreddit.class_eval do
|
8
|
+
def create(**params)
|
9
|
+
@client.post('/api/site_admin', params)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
@subreddits = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :subreddits
|
17
|
+
|
18
|
+
def feed2sr(feed)
|
19
|
+
"rss_#{feed.title.gsub(/[\. ]+/, '')}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def publish(input, feed, item)
|
23
|
+
subreddit = subreddits[feed.title] || check_subreddit!(feed)
|
24
|
+
subreddits[feed.title] = subreddit
|
25
|
+
puts "Will submit #{item.title} (from #{feed.title}) to #{subreddit.display_name}"
|
26
|
+
subreddit.submit(item.title, url: item.url)
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
def check_subreddit!(feed)
|
31
|
+
begin
|
32
|
+
sr(feed2sr(feed)).tap { |s| s.subscribe }
|
33
|
+
rescue Redd::NotFound
|
34
|
+
create_subreddit!(feed)
|
35
|
+
retry
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def create_subreddit!(feed)
|
40
|
+
puts "Will create subreddit named #{feed2sr(feed)}"
|
41
|
+
sr(feed2sr(feed)).create(
|
42
|
+
allow_discovery: true,
|
43
|
+
allow_images: true,
|
44
|
+
allow_top: true,
|
45
|
+
allow_videos: true,
|
46
|
+
api_type: 'json',
|
47
|
+
collapse_deleted_comments: true,
|
48
|
+
comment_score_hide_mins: 0,
|
49
|
+
description: "RSS feed from #{feed.url} posted by RRImm",
|
50
|
+
exclude_banned_modqueue: true,
|
51
|
+
free_form_reports: false,
|
52
|
+
"header-title": "RSS feed from #{feed.url} posted by RRImm",
|
53
|
+
hide_ads: false,
|
54
|
+
lang: 'FR-fr',
|
55
|
+
link_type: 'link',
|
56
|
+
name: feed2sr(feed),
|
57
|
+
over_18: false,
|
58
|
+
public_description: "RSS feed from #{feed.url} posted by RRImm",
|
59
|
+
show_media: true,
|
60
|
+
show_media_preview: true,
|
61
|
+
spam_comments: 'high',
|
62
|
+
spam_links: 'high',
|
63
|
+
spam_selfposts: 'high',
|
64
|
+
spoilers_enabled: false,
|
65
|
+
submit_link_label: "This reddit is not made to posted to by humans",
|
66
|
+
submit_text: "This reddit is not made to posted to by humans",
|
67
|
+
submit_text_label: "This reddit is not made to posted to by humans",
|
68
|
+
suggested_comment_sort: "confidence",
|
69
|
+
title: "RSS feed from #{feed.url} posted by RRImm",
|
70
|
+
type: "public",
|
71
|
+
wiki_edit_age: 0,
|
72
|
+
wiki_edit_karma: 100,
|
73
|
+
wikimode: 'disabled'
|
74
|
+
)
|
75
|
+
end
|
76
|
+
|
77
|
+
def sr(name)
|
78
|
+
reddit.subreddit(name)
|
79
|
+
end
|
80
|
+
|
81
|
+
def reddit
|
82
|
+
@reddit ||= Redd.it(
|
83
|
+
user_agent: 'Redd:RRImm:v1.0.0 (by /u/kamaradclimber)',
|
84
|
+
client_id: ENV['REDDIT_CLIENT_ID'],
|
85
|
+
secret: ENV['REDDIT_SECRET'],
|
86
|
+
username: ENV['REDDIT_USERNAME'],
|
87
|
+
password: ENV['REDDIT_PASSWORD']
|
88
|
+
)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/rrimm.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'rrimm'
|
3
|
-
s.version = '0.
|
3
|
+
s.version = '0.14.0'
|
4
4
|
s.licenses = ['Apache Licence v2']
|
5
5
|
s.summary = "RSS to email tool"
|
6
6
|
s.description = "imm reboot in ruby. Retrieve rss feeds and send them by email"
|
@@ -14,11 +14,14 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.add_dependency 'open_uri_redirections'
|
15
15
|
s.add_dependency 'parallel'
|
16
16
|
s.add_dependency 'ruby-progressbar'
|
17
|
-
s.add_dependency 'feedjira', '
|
17
|
+
s.add_dependency 'feedjira', '>= 2'
|
18
18
|
s.add_dependency 'colorize'
|
19
19
|
s.add_dependency 'mixlib-shellout'
|
20
20
|
|
21
|
+
s.add_dependency 'redd' if ENV['WITH_REDDIT']
|
22
|
+
|
21
23
|
s.add_development_dependency 'rspec'
|
22
|
-
s.add_development_dependency '
|
23
|
-
|
24
|
+
s.add_development_dependency 'webmock'
|
25
|
+
|
26
|
+
|
24
27
|
end
|
data/spec/fetcher_spec.rb
CHANGED
@@ -2,8 +2,12 @@ require_relative 'spec_helper'
|
|
2
2
|
|
3
3
|
describe RRImm::Fetcher do
|
4
4
|
let(:basic_conf) do
|
5
|
-
xkcd_file = File.join(
|
6
|
-
|
5
|
+
xkcd_file = File.join(File.dirname(__FILE__), 'xkcd.xml')
|
6
|
+
xkcd_uri = 'http://toto.com/xkcd.xml'
|
7
|
+
|
8
|
+
stub_request(:get, xkcd_uri).
|
9
|
+
to_return(status: 200, body: File.read(xkcd_file))
|
10
|
+
feed = RRImm::FeedConfig.new xkcd_uri do
|
7
11
|
pipe 'cat > /dev/null'
|
8
12
|
end
|
9
13
|
cache = double('cache_mock')
|
@@ -20,18 +24,18 @@ describe RRImm::Fetcher do
|
|
20
24
|
|
21
25
|
describe '#initialize' do
|
22
26
|
it 'createscorrectly' do
|
23
|
-
expect { RRImm::Fetcher.new
|
27
|
+
expect { RRImm::Fetcher.new(basic_conf, {}) }.not_to raise_error
|
24
28
|
end
|
25
29
|
end
|
26
30
|
|
27
31
|
describe '#fetch' do
|
28
32
|
it 'fetches correctly' do
|
29
|
-
fetcher = RRImm::Fetcher.new basic_conf
|
33
|
+
fetcher = RRImm::Fetcher.new basic_conf, {}
|
30
34
|
expect { fetcher.fetch }.not_to raise_error
|
31
35
|
end
|
32
36
|
it 'fetches correctly when using concurrency' do
|
33
|
-
fetcher = RRImm::Fetcher.new basic_conf
|
34
|
-
expect { fetcher.fetch
|
37
|
+
fetcher = RRImm::Fetcher.new basic_conf, {'concurrency' => 5}
|
38
|
+
expect { fetcher.fetch }.not_to raise_error
|
35
39
|
end
|
36
40
|
end
|
37
41
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,10 +1,5 @@
|
|
1
|
-
require "codeclimate-test-reporter"
|
2
|
-
CodeClimate::TestReporter.start
|
3
|
-
require 'coveralls'
|
4
|
-
Coveralls.wear!
|
5
|
-
|
6
|
-
SimpleCov.minimum_coverage 95
|
7
|
-
SimpleCov.formatter = SimpleCov::Formatter::HTMLFormatter
|
8
|
-
|
9
1
|
require 'rspec'
|
10
2
|
require_relative '../lib/rrimm'
|
3
|
+
require 'webmock/rspec'
|
4
|
+
|
5
|
+
WebMock.disable_net_connect!(allow: 'www.example.org')
|
data/spec/xkcd_spec.rb
CHANGED
@@ -7,15 +7,22 @@ describe RRImm::ItemFormatter::Mail do
|
|
7
7
|
from: 'from@example.com',
|
8
8
|
to: 'to@example.com'
|
9
9
|
)
|
10
|
-
xkcd_file = File.join(
|
11
|
-
|
10
|
+
xkcd_file = File.join(File.dirname(__FILE__), 'xkcd.xml')
|
11
|
+
xkcd_uri = 'http://toto.com/xkcd.xml'
|
12
|
+
|
13
|
+
stub_request(:get, xkcd_uri).
|
14
|
+
to_return(status: 200, body: File.read(xkcd_file))
|
15
|
+
|
16
|
+
feed = Feedjira::Feed.fetch_and_parse(xkcd_uri)
|
12
17
|
expect(feed.entries.size).to be > 0
|
13
18
|
s = StringIO.new
|
14
19
|
config = double('config')
|
15
20
|
expect(config).to receive(:category).twice.and_return nil
|
16
21
|
expect(config).to receive(:default_name?).and_return(true, false)
|
22
|
+
expect(config).to receive(:uri).at_least(1).and_return(xkcd_uri)
|
23
|
+
|
17
24
|
mail_formatter.format(feed, feed.entries.first, config, s)
|
18
|
-
expect(s.string).to eq "From: RRImm <from@example.com>\nTo: to@example.com\nDate: Fri, 07 Mar 2014 05:00:00 -0000\nSubject: When You Assume\nContent-Type: text/html;\n\nhttp://xkcd.com/1339/\n\n<img src=\"http://imgs.xkcd.com/comics/when_you_assume.png\" title=\"You know what happens when you assert--you make an ass out of the emergency response team.\" alt=\"You know what happens when you assert--you make an ass out of the emergency response team.\" />\n"
|
25
|
+
expect(s.string).to eq "From: RRImm <from@example.com>\nTo: to@example.com\nDate: Fri, 07 Mar 2014 05:00:00 -0000\nSubject: When You Assume\nContent-Type: text/html;\nX-Source-Uri: http://toto.com/xkcd.xml\n\nhttp://xkcd.com/1339/\n\n<img src=\"http://imgs.xkcd.com/comics/when_you_assume.png\" title=\"You know what happens when you assert--you make an ass out of the emergency response team.\" alt=\"You know what happens when you assert--you make an ass out of the emergency response team.\" />\n"
|
19
26
|
s = StringIO.new
|
20
27
|
|
21
28
|
expect(config).to receive(:name).and_return "Randall Munroe"
|
@@ -26,8 +33,12 @@ end
|
|
26
33
|
describe RRImm::ItemFormatter::Default do
|
27
34
|
it 'formats correctly xkcd feed' do
|
28
35
|
default_formatter = RRImm::ItemFormatter::Default.new
|
29
|
-
xkcd_file = File.join(
|
30
|
-
|
36
|
+
xkcd_file = File.join(File.dirname(__FILE__), 'xkcd.xml')
|
37
|
+
xkcd_uri = 'http://toto.com/xkcd.xml'
|
38
|
+
|
39
|
+
stub_request(:get, xkcd_uri).
|
40
|
+
to_return(status: 200, body: File.read(xkcd_file))
|
41
|
+
feed = Feedjira::Feed.fetch_and_parse(xkcd_uri)
|
31
42
|
expect(feed.entries.size).to be > 0
|
32
43
|
s = StringIO.new
|
33
44
|
default_formatter.format(feed, feed.entries.first, nil, s)
|
metadata
CHANGED
@@ -1,139 +1,139 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rrimm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Grégoire Seux
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-09-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: open_uri_redirections
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: parallel
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: ruby-progressbar
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: feedjira
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '2'
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '2'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: colorize
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
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
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: mixlib-shellout
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: redd
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- -
|
101
|
+
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '0'
|
104
|
-
type: :
|
104
|
+
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- -
|
108
|
+
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
112
|
+
name: rspec
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - ">="
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: '0'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- -
|
122
|
+
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
126
|
+
name: webmock
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
|
-
- -
|
129
|
+
- - ">="
|
130
130
|
- !ruby/object:Gem::Version
|
131
131
|
version: '0'
|
132
132
|
type: :development
|
133
133
|
prerelease: false
|
134
134
|
version_requirements: !ruby/object:Gem::Requirement
|
135
135
|
requirements:
|
136
|
-
- -
|
136
|
+
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
139
|
description: imm reboot in ruby. Retrieve rss feeds and send them by email
|
@@ -143,9 +143,9 @@ executables:
|
|
143
143
|
extensions: []
|
144
144
|
extra_rdoc_files: []
|
145
145
|
files:
|
146
|
-
- .coveralls.yml
|
147
|
-
- .gitignore
|
148
|
-
- .travis.yml
|
146
|
+
- ".coveralls.yml"
|
147
|
+
- ".gitignore"
|
148
|
+
- ".travis.yml"
|
149
149
|
- CONTRIBUTING.md
|
150
150
|
- Gemfile
|
151
151
|
- LICENSE
|
@@ -162,6 +162,9 @@ files:
|
|
162
162
|
- lib/rrimm/item_formatter.rb
|
163
163
|
- lib/rrimm/item_formatter/default.rb
|
164
164
|
- lib/rrimm/item_formatter/mail.rb
|
165
|
+
- lib/rrimm/publisher.rb
|
166
|
+
- lib/rrimm/publisher/pipe.rb
|
167
|
+
- lib/rrimm/publisher/reddit.rb
|
165
168
|
- rakefile
|
166
169
|
- rrimm.gemspec
|
167
170
|
- script/setup
|
@@ -183,17 +186,17 @@ require_paths:
|
|
183
186
|
- lib
|
184
187
|
required_ruby_version: !ruby/object:Gem::Requirement
|
185
188
|
requirements:
|
186
|
-
- -
|
189
|
+
- - ">="
|
187
190
|
- !ruby/object:Gem::Version
|
188
191
|
version: '0'
|
189
192
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
190
193
|
requirements:
|
191
|
-
- -
|
194
|
+
- - ">="
|
192
195
|
- !ruby/object:Gem::Version
|
193
196
|
version: '0'
|
194
197
|
requirements: []
|
195
198
|
rubyforge_project:
|
196
|
-
rubygems_version: 2.
|
199
|
+
rubygems_version: 2.5.2
|
197
200
|
signing_key:
|
198
201
|
specification_version: 4
|
199
202
|
summary: RSS to email tool
|