rrimm 0.4.0 → 0.5.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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NmQzYTUzZjAyMWExYTJhZjQ5M2YyZmEzMzBkZDY1ZjY5MzNlZGQxZQ==
4
+ YjVmZjhiNTQwODZhMDc1YTFkMmE1MjU2NDdiMWMxOTFmMGRjYjQ4Yg==
5
5
  data.tar.gz: !binary |-
6
- NzQ4N2YwM2Q5NzIzZjdkZDZmNDFlNDdlOWY4NmU4ZDZjZWFhMDI2MQ==
6
+ NGViNGJlOGFiYWYxODU2MWE1OTk3MmNkN2JjY2I4Njk5MGMyODNmYw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NDAxYmVhMWU0NjRhM2JjMDdiZTgyODdmMDQwYzI1NTY5NTM3NTBkNjUwODYz
10
- NTg3NGRiYTM4NGJmYTQ3ZjhlNmUyMTgyNDk0ZjUyYmFlYWZjZjg2N2YyNzI1
11
- YmYwZDVjZjllN2Y4MjM3NTdlYzZhYTJmY2Y1MDFhZWI2NWQwYjI=
9
+ MzEzMGE3NTIzNjU2MTViOTI4ZmNlZTRhZGI5YzYzOWM5M2M0Yzc0MGEwNDc4
10
+ MTNlMjJlZGVjNWZkMzcyYmRiZTkyOWU5ODU5YzZkZTc3N2E1NGI4YjQ2ZTYz
11
+ M2UyOGQ2ZWEzMDJmNzdkYWFjMzJiNDJiMjc1OWI2MTE5MTRkMDM=
12
12
  data.tar.gz: !binary |-
13
- NzlhYTc2NDI4MzhjNGI1MDAzYWFiNzUzOWQ1MzI1ZDhjOTIxZDhiYjE0NjUz
14
- MzQyMDNmOTZjYzQ3MWNjMGEwYTQ0MWRkMmY2ZDJjNzRjNTZjMTRjODhkNDBm
15
- NjQ1ODFiYmMwYTM3ZTAxNzM1MjY4YmEzZTliZGQzOTc3OTE0ZTI=
13
+ ZTY4YjFiMzNjYjE5ZjU1YjZiMDlmY2IzM2MzMzY4ZTJjZjJhYTU4ZmZhNDY2
14
+ OTRhMzNmOTBlZGZiNmM5ZjVlMzljODllNjZjNmVhYzliZTBjM2E4NGVjYzU1
15
+ NWU3NTNjY2VkYThjMWVkNWY1YmJhMjBlY2U4ODg3MmFlMjE3Yjc=
@@ -4,6 +4,9 @@ rvm:
4
4
  - 2.0.0
5
5
  - 2.1.0
6
6
  - ruby-head
7
+ addons:
8
+ code_climate:
9
+ repo_token: 80336b2292acc1d2838cc43c583642601efa411f78917a5bd257ee8233a7de1d
7
10
  script: bundle exec rspec spec
8
11
  deploy:
9
12
  provider: rubygems
@@ -0,0 +1,8 @@
1
+ How-to
2
+ ------
3
+
4
+ There are several ways to contribute and all kinds are welcome.
5
+
6
+ Report bugs : open a github issue, describe the issue and how to reproduce it
7
+ Feature request : open a github issue, describe the feature of your dreams
8
+ Propose a patch : open a PR
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rrimm (0.4.0)
4
+ rrimm (0.5.0)
5
5
  colorize
6
6
  feedzirra
7
7
  open_uri_redirections
@@ -10,6 +10,8 @@ PATH
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
+ codeclimate-test-reporter (0.3.0)
14
+ simplecov (>= 0.7.1, < 1.0.0)
13
15
  colorize (0.7.0)
14
16
  coveralls (0.7.0)
15
17
  multi_json (~> 1.3)
@@ -59,6 +61,7 @@ PLATFORMS
59
61
  ruby
60
62
 
61
63
  DEPENDENCIES
64
+ codeclimate-test-reporter
62
65
  coveralls
63
66
  rrimm!
64
67
  rspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Grégoire Seux
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -6,6 +6,7 @@ About rrimm
6
6
  [![Gem Version](https://badge.fury.io/rb/rrimm.png)](http://badge.fury.io/rb/rrimm)
7
7
  [![Dependency Status](https://gemnasium.com/kamaradclimber/rrimm.png)](https://gemnasium.com/kamaradclimber/rrimm)
8
8
  [![Coverage Status](https://coveralls.io/repos/kamaradclimber/rrimm/badge.png?branch=master)](https://coveralls.io/r/kamaradclimber/rrimm?branch=master)
9
+ [![Code Climate](https://codeclimate.com/github/kamaradclimber/rrimm.png)](https://codeclimate.com/github/kamaradclimber/rrimm)
9
10
 
10
11
  In a nutshell
11
12
  -------------
data/bin/rrimm CHANGED
@@ -25,6 +25,11 @@ OptionParser.new do |opts|
25
25
  options['concurrency'] = c.to_i
26
26
  end
27
27
 
28
+ opts.on('-q', '--quiet',
29
+ 'Activate quiet mode, will only print errors') do
30
+ options['quiet'] = true
31
+ end
32
+
28
33
  opts.on('-a', '--action [action]', [:sync, :show, :status],
29
34
  'Specify what to do: "sync" feeds, "show" config, display feed "status"') do |action|
30
35
  options['action'] = action
@@ -42,16 +47,17 @@ conf = RRImm::Config.new
42
47
  conf.load(options['conf_file'])
43
48
 
44
49
  fetcher = RRImm::Fetcher.new(conf)
45
-
46
- case options['action']
47
- when :sync
48
- fetcher.fetch(options['concurrency'])
49
- when :show
50
- conf.show
51
- when :status
52
- one_month = 30 * 86400
53
- one_month_ago = Time.now.to_i - one_month
54
- six_months_ago = Time.now.to_i - 6 * one_month
55
-
56
- conf.status(one_month_ago, six_months_ago, false)
50
+ IO.open STDOUT.fileno do |ios|
51
+ case options['action']
52
+ when :sync
53
+ fetcher.fetch(options['concurrency'], options['quiet'])
54
+ when :show
55
+ conf.show(ios)
56
+ when :status
57
+ one_month = 30 * 86400
58
+ one_month_ago = Time.now.to_i - one_month
59
+ six_months_ago = Time.now.to_i - 6 * one_month
60
+
61
+ conf.status(ios, one_month_ago, six_months_ago, false)
62
+ end
57
63
  end
@@ -3,22 +3,30 @@ default_formatter RRImm::ItemFormatter::Mail.new(
3
3
  to: 'me@me.com'
4
4
  )
5
5
  pipe "msmtp -t --read-envelope-from"
6
- #pipe "cat"
7
6
 
8
- feed "http://planet.haskell.org/rss20.xml"
7
+ # most simple declaration : feed [uri]
9
8
  feed "http://www.archlinux.org/feeds/news/"
10
- feed "http://alan.petitepomme.net/cwn/cwn.rss"
11
9
 
10
+ # full declaration feed [name] do [block] end
12
11
  feed "xkcd" do
13
12
  uri "http://xkcd.com/rss.xml"
14
13
  category "webcomics"
15
14
  end
15
+
16
16
  feed 'Cartesian comics' do
17
17
  uri 'http://feeds.feedburner.com/CartesianClosedComic?format=xml'
18
18
  category "webcomics"
19
19
  end
20
+
20
21
  feed 'SMBC' do
21
22
  uri "http://www.smbc-comics.com/rss.php"
22
23
  category 'webcomics'
23
24
  end
24
25
 
26
+ # namespace by category (and soon with all attributes)
27
+ category 'languages' do
28
+ feed 'ocaml' do
29
+ uri 'http://alan.petitepomme.net/cwn/cwn.rss'
30
+ end
31
+ feed "http://planet.haskell.org/rss20.xml"
32
+ end
@@ -4,6 +4,7 @@ module RRImm
4
4
  class Config
5
5
  attr :feeds, :cache
6
6
  attr :default_formatter, :pipe
7
+ attr_accessor :output
7
8
 
8
9
  def initialize
9
10
  @feeds = {}
@@ -21,38 +22,32 @@ module RRImm
21
22
  @cache
22
23
  end
23
24
 
24
- def show
25
- puts "Cache: #{@cache.name}"
26
- puts " path: #{@cache.path}" unless @cache.path.eql? @cache.name
25
+ def show(ios)
26
+ ios.write "Cache: #{@cache.name}\n"
27
+ ios.write " path: #{@cache.path}\n" unless @cache.path.eql? @cache.name
27
28
 
28
- puts "Default formatter: #{default_formatter}" if default_formatter
29
+ ios.write "Default formatter: #{default_formatter}\n" if default_formatter
29
30
 
30
- puts "Feeds:"
31
+ ios.write "Feeds:\n"
31
32
  @feeds.values.group_by { |f| f.category }.map do |cat, feeds|
32
- if cat.nil? or cat.empty?
33
- puts ""
34
- else
35
- puts "#{cat}:"
36
- end
33
+ ios.write "#{cat || "unamed category"}:\n"
37
34
  feeds.each do |feed|
38
- fqdn = [feed.name]
39
- fqdn << feed.uri unless feed.name.eql? feed.uri
40
- puts "- #{fqdn.join ': '}"
35
+ fqdn = [feed.name, feed.uri].uniq
36
+ ios.write "- #{fqdn.join ': '}\n"
41
37
  end
42
38
  end
43
39
  end
44
40
 
45
- def status(old_timestamp, very_old_timestamp, display_old_only)
46
- ordered_feeds = @feeds.values.map { |f| [get_cache.read(f), f] }.sort_by { |el| el.first }
47
- ordered_feeds.each do |el|
48
- f = el[1]
49
- case el.first
41
+ def status(ios, old_timestamp, very_old_timestamp, display_old_only)
42
+ @feeds.values.map { |f| [ Time.at(get_cache.read(f)), f] }.sort_by { |el| el.first }.each do |el|
43
+ date, f = el
44
+ case date.to_i
50
45
  when 0..very_old_timestamp
51
- puts "#{Time.at(el.first)} #{f.name}".colorize(:red)
46
+ ios.write "#{date} #{f.name}\n".red
52
47
  when very_old_timestamp..old_timestamp
53
- puts "#{Time.at(el.first)} #{f.name}".colorize(:yellow)
48
+ ios.write "#{date} #{f.name}\n".yellow
54
49
  else
55
- puts "#{Time.at(el.first)} #{f.name}".colorize(:green) unless display_old_only
50
+ ios.write "#{date} #{f.name}\n".green unless display_old_only
56
51
  end
57
52
  end
58
53
  end
@@ -7,10 +7,11 @@ module RRImm
7
7
  attr_accessor :category
8
8
  attr_accessor :pipe
9
9
 
10
- def initialize(name)
10
+ def initialize(name, &block)
11
11
  @name = name
12
12
  @uri = name
13
13
  @formatter_class = RRImm::ItemFormatter::Default
14
+ self.instance_eval(&block) if block
14
15
  end
15
16
 
16
17
  def format(feed, item)
@@ -12,7 +12,8 @@ module RRImm
12
12
  @config = config
13
13
  end
14
14
 
15
- def fetch(concurrency=nil)
15
+ def fetch(concurrency=nil, quiet=false)
16
+ @quiet ||= quiet
16
17
  if concurrency
17
18
  parallel_fetch(concurrency)
18
19
  else
@@ -34,7 +35,7 @@ module RRImm
34
35
 
35
36
  def fetch_feed(name, feed_config)
36
37
  last_read = Time.at(@config.get_cache.read(feed_config))
37
- puts name
38
+ puts name unless @quiet
38
39
  feed = Feedzirra::Feed.fetch_and_parse(feed_config.uri)
39
40
  items = feed.entries.select { |item| item.published > last_read }
40
41
  last_read = items.collect { |item| item.published }.max unless items.empty?
@@ -0,0 +1,5 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ RSpec::Core::RakeTask.new(:spec)
4
+
5
+ task :default => :spec
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'rrimm'
3
- s.version = '0.4.0'
3
+ s.version = '0.5.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"
@@ -18,4 +18,5 @@ Gem::Specification.new do |s|
18
18
 
19
19
  s.add_development_dependency 'rspec'
20
20
  s.add_development_dependency 'coveralls'
21
+ s.add_development_dependency 'codeclimate-test-reporter'
21
22
  end
@@ -0,0 +1,6 @@
1
+ #!/bin/bash
2
+
3
+ set -e
4
+
5
+ which bundle > /dev/null 2>&1 || echo "You need ruby and bundler installed. "
6
+ bundle install
@@ -0,0 +1,3 @@
1
+ #!/bin/bash
2
+
3
+ rspec
@@ -8,5 +8,42 @@ describe RRImm::Config do
8
8
  conf.load(File.join(File.dirname(__FILE__), '..', 'examples', 'most_simple_config.rb'))
9
9
  expect(conf.feeds.size).to be 2
10
10
  end
11
+
12
+ it 'loads feeds properly with complex conf' do
13
+ conf = RRImm::Config.new
14
+ expect(conf.feeds.size).to be 0
15
+ conf.load(File.join(File.dirname(__FILE__), '..', 'examples', 'complete_config.rb'))
16
+ expect(conf.feeds.size).to be 6
17
+ expect(conf.feeds['SMBC'].category).to eq 'webcomics'
18
+ expect(conf.feeds['ocaml'].category).to eq 'languages'
19
+ end
20
+ end
21
+
22
+ describe 'show' do
23
+ it 'displays config properly' do
24
+ ios = StringIO.new
25
+ conf = RRImm::Config.new
26
+ conf.load(File.join(File.dirname(__FILE__), '..', 'examples', 'complete_config.rb'))
27
+ expect{ conf.show(ios) }.not_to raise_error
28
+ expect(ios.string).to include "default cache"
29
+ end
30
+ end
31
+
32
+ describe 'status' do
33
+ it 'prints status properly' do
34
+ cache = double('cache')
35
+ allow(cache).to receive(:read).and_return(1, 4, 7)
36
+ allow(cache).to receive(:path)
37
+ ios = StringIO.new
38
+ allow(RRImm::Cache).to receive(:new).and_return(cache)
39
+ conf = RRImm::Config.new
40
+ conf.feeds['1_very_old'] = RRImm::Feed.new 'very_old'
41
+ conf.feeds['3_old'] = RRImm::Feed.new 'old'
42
+ conf.feeds['7_recent'] = RRImm::Feed.new 'recent'
43
+ expect{ conf.status(ios, 5, 3, false) }.not_to raise_error
44
+ expect(ios.string).to include "#{Time.at(1)} very_old\n".red
45
+ expect(ios.string).to include "#{Time.at(4)} old\n".yellow
46
+ expect(ios.string).to include "#{Time.at(7)} recent\n".green
47
+ end
11
48
  end
12
49
  end
@@ -6,7 +6,27 @@ describe RRImm::Feed do
6
6
  f = RRImm::Feed.new 'a random feed'
7
7
  expect(f.name).to eq('a random feed')
8
8
  expect(f.uri).to eq('a random feed')
9
+ expect(f.default_name?).to be true
10
+ end
11
+
12
+ it 'calls the block if one is specifed' do
13
+ f = RRImm::Feed.new 'a another feed' do
14
+ pipe "cat | cat"
15
+ formatter_class RRImm::ItemFormatter::Mail
16
+ end
17
+ expect(f.pipe).to eq "cat | cat"
18
+ expect(f.formatter_class).to eq RRImm::ItemFormatter::Mail
9
19
  end
10
20
  end
11
21
 
22
+ describe ".format" do
23
+ it 'calls formatter' do
24
+ formatter = double('formatter')
25
+ f = RRImm::Feed.new 'a random feed'
26
+ f.pipe "cat /dev/null"
27
+ f.formatter = formatter
28
+ expect(formatter).to receive(:format)
29
+ expect { f.format(nil, nil) }.not_to raise_error
30
+ end
31
+ end
12
32
  end
@@ -0,0 +1,37 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe RRImm::Fetcher do
4
+ let(:basic_conf) do
5
+ xkcd_file = File.join('file://', File.dirname(__FILE__), 'xkcd.xml')
6
+ feed = RRImm::Feed.new xkcd_file do
7
+ pipe 'cat > /dev/null'
8
+ end
9
+ cache = double('cache_mock')
10
+ allow(RRImm::Cache).to receive(:new).and_return(cache)
11
+ allow(cache).to receive(:path)
12
+
13
+ allow(cache).to receive(:read).and_return(3829)
14
+ allow(cache).to receive(:save)
15
+
16
+ config = RRImm::Config.new
17
+ config.feeds['local_xkcd'] = feed
18
+ config
19
+ end
20
+
21
+ describe '#initialize' do
22
+ it 'createscorrectly' do
23
+ expect { RRImm::Fetcher.new basic_conf }.not_to raise_error
24
+ end
25
+ end
26
+
27
+ describe '#fetch' do
28
+ it 'fetches correctly' do
29
+ fetcher = RRImm::Fetcher.new basic_conf
30
+ expect { fetcher.fetch }.not_to raise_error
31
+ end
32
+ it 'fetches correctly when using concurrency' do
33
+ fetcher = RRImm::Fetcher.new basic_conf
34
+ expect { fetcher.fetch(5) }.not_to raise_error
35
+ end
36
+ end
37
+ end
@@ -1,5 +1,10 @@
1
+ require "codeclimate-test-reporter"
2
+ CodeClimate::TestReporter.start
1
3
  require 'coveralls'
2
4
  Coveralls.wear!
3
5
 
6
+ SimpleCov.minimum_coverage 95
7
+ SimpleCov.formatter = SimpleCov::Formatter::HTMLFormatter
8
+
4
9
  require 'rspec'
5
10
  require_relative '../lib/rrimm'
@@ -12,11 +12,14 @@ describe RRImm::ItemFormatter::Mail do
12
12
  expect(feed.entries.size).to be > 0
13
13
  s = StringIO.new
14
14
  config = double('config')
15
- config.should_receive(:category).and_return nil
16
- config.should_receive(:default_name?).and_return(true)
15
+ config.should_receive(:category).twice.and_return nil
16
+ config.should_receive(:default_name?).and_return(true, false)
17
17
  mail_formatter.format(feed, feed.entries.first, config, s)
18
- s.close
19
18
  expect(s.string).to eq "From: RRImm <from@example.com>\nTo: to@example.com\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"
19
+ s = StringIO.new
20
+
21
+ config.should_receive(:name).and_return "Randall Munroe"
22
+ mail_formatter.format(feed, feed.entries.first, config, s)
20
23
  end
21
24
  end
22
25
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rrimm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.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: 2014-03-16 00:00:00.000000000 Z
11
+ date: 2014-03-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: open_uri_redirections
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ! '>='
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: codeclimate-test-reporter
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
97
111
  description: imm reboot in ruby. Retrieve rss feeds and send them by email
98
112
  email: rrimm@familleseux.net
99
113
  executables:
@@ -104,8 +118,10 @@ files:
104
118
  - .coveralls.yml
105
119
  - .gitignore
106
120
  - .travis.yml
121
+ - CONTRIBUTING.md
107
122
  - Gemfile
108
123
  - Gemfile.lock
124
+ - LICENSE
109
125
  - README.md
110
126
  - bin/rrimm
111
127
  - examples/complete_config.rb
@@ -118,10 +134,14 @@ files:
118
134
  - lib/rrimm/item_formatter.rb
119
135
  - lib/rrimm/item_formatter/default.rb
120
136
  - lib/rrimm/item_formatter/mail.rb
137
+ - rakefile
121
138
  - rrimm.gemspec
139
+ - script/setup
140
+ - script/test
122
141
  - spec/cache_spec.rb
123
142
  - spec/config_spec.rb
124
143
  - spec/feed_spec.rb
144
+ - spec/fetcher_spec.rb
125
145
  - spec/spec_helper.rb
126
146
  - spec/xkcd.xml
127
147
  - spec/xkcd_spec.rb
@@ -153,6 +173,7 @@ test_files:
153
173
  - spec/cache_spec.rb
154
174
  - spec/config_spec.rb
155
175
  - spec/feed_spec.rb
176
+ - spec/fetcher_spec.rb
156
177
  - spec/spec_helper.rb
157
178
  - spec/xkcd.xml
158
179
  - spec/xkcd_spec.rb