rrimm 0.12.1 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ODgwNzU2ZTBmNTM2OTM0NDAwYTc1MmMzMjY3OGQ3NTMwZmFhNjg4Yw==
5
- data.tar.gz: !binary |-
6
- NzkzYmRlMDQyZWQxZGY1OWI0MTIwNzk2MmExZmFiMmM5OGUxNTFiYw==
2
+ SHA1:
3
+ metadata.gz: 5f7bc3ce30144cdbcb0b14be5c1675b380cb402f
4
+ data.tar.gz: b22cb2e5b1e9081c47803012314bf94e8b4c0bb1
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- NGRiYzgyNDVhNjY1NDhhNWY4ZGE3ODkzYTY2MDIwZGI4MmM0NzBjNjczYWZm
10
- MTRjZGJmNTY5ZjcyYzhiMTdhNTZjZWIzMTZkMDJkMGU4M2ExYTgyNjdkYTlh
11
- OWUyNmEwYmRlZTI1MGE0MDBiMzkzZWYzMzZiMTBiMWVjY2FmMDc=
12
- data.tar.gz: !binary |-
13
- NDdhMjM1MmI5ZjE4OTcwM2RlMDEyZGE5NjhkZTY3MTc5NWE1YTJhOTY2NTNi
14
- YWIxODY5YTM5YzUwODMyNDkxNGRhZDM3MmU1ZTQyNDUxNTgzMjhhNjY3NzRj
15
- YTFiNjVhZGE3Y2NmN2M4YWQ2NjFiNTk3YjRmZWM5OGRiNzE2OGI=
6
+ metadata.gz: 1f72cb03ac4097e5d807686560f7ddd9b8cf00e24a7e866e56b83f598812a42373564f7496ee708eb05c59a1332ca9a66915c8a74ddf9b6f5bcfd26656a93d22
7
+ data.tar.gz: fcbb75d848374d7f384a96a4842b5a064a6240540ed251ad63c2b6e5b35f71362bd2543188d5bdaf14eb22e3ca4840a4ea4909597533da3ab2ec2a2274793bd0
@@ -1,7 +1,6 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1.0
4
- - ruby-head
3
+ - 2.4
5
4
  addons:
6
5
  code_climate:
7
6
  repo_token: 80336b2292acc1d2838cc43c583642601efa411f78917a5bd257ee8233a7de1d
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(options['concurrency'], options['quiet'], options['category'])
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
@@ -1,3 +1,4 @@
1
+ require_relative 'rrimm/publisher'
1
2
  require_relative 'rrimm/feed_config'
2
3
  require_relative 'rrimm/feed_config_extensions'
3
4
  require_relative 'rrimm/config'
@@ -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
@@ -3,7 +3,7 @@ require 'colorize'
3
3
  module RRImm
4
4
  class Config
5
5
  attr :feeds, :cache
6
- attr :default_formatter, :pipe
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
- @pipe = "cat"
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.pipe = pipe if pipe
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
- @pipe = arg
98
+ publisher(RRImm::Pipe.new(arg))
82
99
  end
83
- @pipe
100
+ publisher.command
84
101
  end
85
102
 
86
103
  def feed(name, *args, &block)
@@ -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 :pipe
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
- s = ""
41
- StringIO.open(s) do |str|
40
+ formatted_feed = ""
41
+ StringIO.open(formatted_feed) do |str|
42
42
  @formatter.format(feed,item, self, str)
43
43
  end
44
- cmd = Mixlib::ShellOut.new(pipe, :input => s)
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
- @pipe = arg
82
+ publisher RRImm::Pipe.new(arg)
78
83
  end
79
- @pipe
84
+ publisher.command
80
85
  end
81
86
 
82
87
  end
@@ -8,7 +8,7 @@ module RRImm
8
8
  if Enumerable.instance_methods(false).include? name
9
9
  @massages << { name => block }
10
10
  else
11
- raise NoMethodError
11
+ raise NoMethodError, "#{name} does not exist"
12
12
  end
13
13
  self
14
14
  end
@@ -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 = 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(concurrency=nil, quiet=false, category=nil)
17
- @quiet ||= quiet
18
- @category ||= category
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(concurrency)
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
- fetch_feed_no_timeout(name, feed_config)
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
- options = { compress: true }
57
- feed = Feedjira::Feed.fetch_and_parse(feed_config.uri, options)
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
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'rrimm'
3
- s.version = '0.12.1'
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', '< 2'
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 'coveralls'
23
- s.add_development_dependency 'codeclimate-test-reporter'
24
+ s.add_development_dependency 'webmock'
25
+
26
+
24
27
  end
@@ -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('file://', File.dirname(__FILE__), 'xkcd.xml')
6
- feed = RRImm::FeedConfig.new xkcd_file do
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 basic_conf }.not_to raise_error
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(5) }.not_to raise_error
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
@@ -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')
@@ -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('file://', File.dirname(__FILE__), 'xkcd.xml')
11
- feed = Feedjira::Feed.fetch_and_parse(xkcd_file)
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('file://', File.dirname(__FILE__), 'xkcd.xml')
30
- feed = Feedjira::Feed.fetch_and_parse(xkcd_file)
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.12.1
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: 2015-08-16 00:00:00.000000000 Z
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: rspec
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: :development
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: coveralls
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: codeclimate-test-reporter
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.4.5
199
+ rubygems_version: 2.5.2
197
200
  signing_key:
198
201
  specification_version: 4
199
202
  summary: RSS to email tool