rrimm 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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