cline 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -6,10 +6,10 @@
6
6
  gem install cline
7
7
  cline init
8
8
  echo "Cline.out_stream = Cline::OutStreams::WithGrowl.new($stdout)" > ~/.cline/config # growlnotify required
9
- echo "Cline.fetchers << Cline::Fetchers::Feed" >> ~/.cline/config
9
+ echo "Cline.collectors << Cline::Collector::Feed" >> ~/.cline/config
10
10
  curl http://foo.examle.com/url/to/opml.xml > ~/.cline/feeds.xml
11
11
 
12
- cline fetch
12
+ cline collect
13
13
  cline tick --offset 0 --interval 5
14
14
  ~~~~
15
15
 
@@ -31,21 +31,21 @@ in ~/.screenrc
31
31
 
32
32
  ## Reload
33
33
 
34
- `fetch`command fetch new notifications from `Cline.fetchers`.
34
+ `collect`command collect new notifications from `Cline.collectors`.
35
35
 
36
36
  ~~~~
37
- cline fetch
37
+ cline collect
38
38
  ~~~~
39
39
 
40
- ### Custom Fetcher
40
+ ### Custom Collector
41
41
 
42
- *fetcher* required `fetch` method.
42
+ *collector* required `collect` method.
43
43
 
44
44
  example:
45
45
 
46
46
  ~~~~ruby
47
- class MyFetcher
48
- def self.fetch
47
+ class MyCollector
48
+ def self.collect
49
49
  new.sources.each do |source|
50
50
  Cline::Notification.find_by_message(source.body) || Cline::Notification.create!(message: source.body, time: source.created_at)
51
51
  end
@@ -62,8 +62,8 @@ example:
62
62
  in ~/.cline/config
63
63
 
64
64
  ~~~~ruby
65
- require 'path/to/my_fetcher'
66
- Cline.fetchers << MyFetcher
65
+ require 'path/to/my_collector'
66
+ Cline.collectors << MyCollector
67
67
  ~~~~
68
68
 
69
69
  ## Notifier
data/cline.gemspec CHANGED
@@ -11,6 +11,21 @@ Gem::Specification.new do |s|
11
11
  s.summary = %q{CLI Line Notifier}
12
12
  s.description = %q{Cline - CLI Line Notifier}
13
13
 
14
+ s.post_install_message = <<-EOM
15
+ **Important** Some APIs name have changed.
16
+
17
+ s/fetch/collect/g
18
+
19
+ * Command
20
+ $ cline fetch
21
+ => $ cline collect
22
+
23
+ * Classes And Modules
24
+ Cline.fechers => Cline.collectors
25
+ Cline::Fetchers => Cline::Collectors
26
+ Cline::Fetchers::Feed.fetch => Cline::Fetchers::Feed.collect
27
+ EOM
28
+
14
29
  #s.rubyforge_project = "cline"
15
30
 
16
31
  s.files = `git ls-files`.split("\n")
@@ -0,0 +1,72 @@
1
+ # coding: utf-8
2
+
3
+ module Cline::Collectors
4
+ class Feed
5
+ class << self
6
+ def collect
7
+ entries = new(opml_path.read).collect
8
+
9
+ entries.each do |entry|
10
+ begin
11
+ Cline::Notification.instance_exec entry do |entry|
12
+ message = normalize_message("#{entry.title} #{entry.url}").encode(Encoding::UTF_8)
13
+
14
+ find_by_message(message) || create(message: message, time: entry.published)
15
+ end
16
+ rescue ActiveRecord::StatementInvalid => e
17
+ puts e.class, e.message
18
+ end
19
+ end
20
+ end
21
+
22
+ def opml_path
23
+ opml = Pathname.new("#{Cline.cline_dir}/feeds.xml")
24
+ end
25
+ end
26
+
27
+ def initialize(opml_str)
28
+ require 'rexml/document'
29
+ require 'feedzirra'
30
+
31
+ @opml = REXML::Document.new(opml_str)
32
+ @feeds = parse_opml(@opml.elements['opml/body'])
33
+ end
34
+
35
+ def collect
36
+ entries = []
37
+
38
+ @feeds.map { |feed_url|
39
+ Thread.fork {
40
+ begin
41
+ feed = Feedzirra::Feed.fetch_and_parse(feed_url)
42
+
43
+ if feed.is_a?(Feedzirra::FeedUtilities)
44
+ feed.entries.each { |entry| entries << entry }
45
+ end
46
+ rescue
47
+ puts $!.class, $!.message
48
+ ensure
49
+ Thread.pass
50
+ end
51
+ }
52
+ }.map(&:join)
53
+
54
+ entries
55
+ end
56
+
57
+ def parse_opml(opml_node)
58
+ feeds = []
59
+
60
+ opml_node.elements.each('outline') do |el|
61
+ unless el.elements.size.zero?
62
+ feeds += parse_opml(el)
63
+ else
64
+ url = el.attributes['xmlUrl']
65
+ feeds << url if url
66
+ end
67
+ end
68
+
69
+ feeds
70
+ end
71
+ end
72
+ end
data/lib/cline/command.rb CHANGED
@@ -10,7 +10,7 @@ module Cline
10
10
  map '-s' => :show,
11
11
  '-t' => :tick,
12
12
  '-s' => :status,
13
- '-f' => :fetch,
13
+ '-c' => :collect,
14
14
  '-i' => :init,
15
15
  '-v' => :version
16
16
 
@@ -35,9 +35,9 @@ module Cline
35
35
  say "total : #{Notification.count}", :cyan
36
36
  end
37
37
 
38
- desc 'fetch', 'Fetch sources'
39
- def fetch
40
- Cline.fetchers.each &:fetch
38
+ desc 'collect', 'Collect sources'
39
+ def collect
40
+ Cline.collectors.each &:collect
41
41
  end
42
42
 
43
43
  desc 'init', 'Init database'
@@ -12,10 +12,18 @@ module Cline
12
12
 
13
13
  scope :displayed, where('display_count > 0')
14
14
 
15
+ def message=(m)
16
+ super Notification.normalize_message(m)
17
+ end
18
+
15
19
  class << self
16
20
  def display(offset)
17
21
  earliest(1, offset).first.display
18
22
  end
23
+
24
+ def normalize_message(m)
25
+ m.gsub(/[\r\n]/, '')
26
+ end
19
27
  end
20
28
 
21
29
  def display
data/lib/cline/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Cline
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/cline.rb CHANGED
@@ -43,8 +43,8 @@ module Cline
43
43
  @out_stream = stream
44
44
  end
45
45
 
46
- fetchers = []
47
- define_method(:fetchers) { fetchers }
46
+ collectors = []
47
+ define_method(:collectors) { collectors }
48
48
  end
49
49
  end
50
50
 
@@ -57,5 +57,5 @@ require 'active_record'
57
57
  require "cline/version"
58
58
  require "cline/notification"
59
59
  require "cline/command"
60
- require "cline/fetchers"
60
+ require "cline/collectors"
61
61
  require "cline/out_streams"
@@ -7,13 +7,13 @@ describe Cline do
7
7
  let(:config) { Pathname.new(Cline.cline_dir).join('config') }
8
8
 
9
9
  before do
10
- config.open('w') {|f| f.puts "Cline.fetchers << Cline::Fetchers::Feed" }
10
+ config.open('w') {|f| f.puts "Cline.collectors << Cline::Collectors::Feed" }
11
11
 
12
12
  Cline.boot
13
13
  end
14
14
 
15
15
  specify "config file should loaded" do
16
- Cline.fetchers.should include Cline::Fetchers::Feed
16
+ Cline.collectors.should include Cline::Collectors::Feed
17
17
  end
18
18
 
19
19
  after do
@@ -30,6 +30,21 @@ describe Cline::Notification do
30
30
  it { should == [notification2] }
31
31
  end
32
32
 
33
+ describe '#message=' do
34
+ let(:notification) { Fabricate(:notification, display_count: 0) }
35
+
36
+ before do
37
+ notification.message = <<-EOM
38
+ line feed
39
+ spoooooky
40
+ EOM
41
+ end
42
+
43
+ subject { notification }
44
+
45
+ its(:message) { should_not match /\n/ }
46
+ end
47
+
33
48
  describe '#display' do
34
49
  let!(:notification) { Fabricate(:notification, display_count: 0) }
35
50
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cline
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-08 00:00:00.000000000 Z
12
+ date: 2011-11-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
16
- requirement: &70162540537320 !ruby/object:Gem::Requirement
16
+ requirement: &70186568998880 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.14.6
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70162540537320
24
+ version_requirements: *70186568998880
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: activerecord
27
- requirement: &70162540536780 !ruby/object:Gem::Requirement
27
+ requirement: &70186568997980 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 3.1.1
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70162540536780
35
+ version_requirements: *70186568997980
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: sqlite3
38
- requirement: &70162540536240 !ruby/object:Gem::Requirement
38
+ requirement: &70186568997040 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 1.3.4
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70162540536240
46
+ version_requirements: *70186568997040
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: feedzirra
49
- requirement: &70162540535740 !ruby/object:Gem::Requirement
49
+ requirement: &70186568996160 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 0.0.31
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70162540535740
57
+ version_requirements: *70186568996160
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rake
60
- requirement: &70162540535160 !ruby/object:Gem::Requirement
60
+ requirement: &70186568995020 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 0.9.2
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70162540535160
68
+ version_requirements: *70186568995020
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: ir_b
71
- requirement: &70162540534560 !ruby/object:Gem::Requirement
71
+ requirement: &70186568993800 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: 1.4.0
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70162540534560
79
+ version_requirements: *70186568993800
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: tapp
82
- requirement: &70162540533880 !ruby/object:Gem::Requirement
82
+ requirement: &70186568979320 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: 1.1.0
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70162540533880
90
+ version_requirements: *70186568979320
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: rspec
93
- requirement: &70162540532500 !ruby/object:Gem::Requirement
93
+ requirement: &70186568974480 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: 2.6.0
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *70162540532500
101
+ version_requirements: *70186568974480
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: rr
104
- requirement: &70162540532020 !ruby/object:Gem::Requirement
104
+ requirement: &70186568948220 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ! '>='
@@ -109,10 +109,10 @@ dependencies:
109
109
  version: 1.0.4
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *70162540532020
112
+ version_requirements: *70186568948220
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: fabrication
115
- requirement: &70162540531480 !ruby/object:Gem::Requirement
115
+ requirement: &70186568942920 !ruby/object:Gem::Requirement
116
116
  none: false
117
117
  requirements:
118
118
  - - ! '>='
@@ -120,10 +120,10 @@ dependencies:
120
120
  version: 1.2.0
121
121
  type: :development
122
122
  prerelease: false
123
- version_requirements: *70162540531480
123
+ version_requirements: *70186568942920
124
124
  - !ruby/object:Gem::Dependency
125
125
  name: fuubar
126
- requirement: &70162540530720 !ruby/object:Gem::Requirement
126
+ requirement: &70186568942200 !ruby/object:Gem::Requirement
127
127
  none: false
128
128
  requirements:
129
129
  - - ! '>='
@@ -131,10 +131,10 @@ dependencies:
131
131
  version: 0.0.6
132
132
  type: :development
133
133
  prerelease: false
134
- version_requirements: *70162540530720
134
+ version_requirements: *70186568942200
135
135
  - !ruby/object:Gem::Dependency
136
136
  name: simplecov
137
- requirement: &70162540529960 !ruby/object:Gem::Requirement
137
+ requirement: &70186568876900 !ruby/object:Gem::Requirement
138
138
  none: false
139
139
  requirements:
140
140
  - - ! '>='
@@ -142,10 +142,10 @@ dependencies:
142
142
  version: 0.5.3
143
143
  type: :development
144
144
  prerelease: false
145
- version_requirements: *70162540529960
145
+ version_requirements: *70186568876900
146
146
  - !ruby/object:Gem::Dependency
147
147
  name: activesupport
148
- requirement: &70162540529440 !ruby/object:Gem::Requirement
148
+ requirement: &70186568874780 !ruby/object:Gem::Requirement
149
149
  none: false
150
150
  requirements:
151
151
  - - ! '>='
@@ -153,7 +153,7 @@ dependencies:
153
153
  version: 3.1.1
154
154
  type: :development
155
155
  prerelease: false
156
- version_requirements: *70162540529440
156
+ version_requirements: *70186568874780
157
157
  description: Cline - CLI Line Notifier
158
158
  email:
159
159
  - celluloid.key@gmail.com
@@ -171,8 +171,8 @@ files:
171
171
  - bin/cline
172
172
  - cline.gemspec
173
173
  - lib/cline.rb
174
+ - lib/cline/collectors.rb
174
175
  - lib/cline/command.rb
175
- - lib/cline/fetchers.rb
176
176
  - lib/cline/notification.rb
177
177
  - lib/cline/out_streams.rb
178
178
  - lib/cline/version.rb
@@ -184,7 +184,10 @@ files:
184
184
  - spec/tmp/.gitkeep
185
185
  homepage: https://github.com/hibariya/cline
186
186
  licenses: []
187
- post_install_message:
187
+ post_install_message: ! " **Important** Some APIs name have changed.\n\n s/fetch/collect/g\n\n
188
+ \ * Command\n $ cline fetch\n => $ cline collect\n\n *
189
+ Classes And Modules\n Cline.fechers => Cline.collectors\n Cline::Fetchers
190
+ => Cline::Collectors\n Cline::Fetchers::Feed.fetch => Cline::Fetchers::Feed.collect\n"
188
191
  rdoc_options: []
189
192
  require_paths:
190
193
  - lib
@@ -1,60 +0,0 @@
1
- # coding: utf-8
2
-
3
- module Cline::Fetchers
4
- class Feed
5
- def self.fetch
6
- opml = Pathname.new("#{Cline.cline_dir}/feeds.xml")
7
- entries = new(opml.read).fetch
8
-
9
- entries.each do |entry|
10
- message = "#{entry.title} #{entry.url}"
11
-
12
- begin
13
- Cline::Notification.tap {|n| n.find_by_message(message) || n.create(message: message, time: entry.published) }
14
- rescue ActiveRecord::StatementInvalid => e
15
- puts e.class, e.message
16
- end
17
- end
18
- end
19
-
20
- def initialize(opml_str)
21
- require 'rexml/document'
22
- require 'feedzirra'
23
-
24
- @opml = REXML::Document.new(opml_str)
25
- @feeds = parse_opml(@opml.elements['opml/body'])
26
- end
27
-
28
- def fetch
29
- entries = []
30
-
31
- @feeds.map { |feed_url|
32
- Thread.fork do
33
- begin
34
- feed = Feedzirra::Feed.fetch_and_parse(feed_url)
35
- entries += feed.entries if feed.is_a? Feedzirra::FeedUtilities
36
- rescue
37
- puts $!.class, $!.message
38
- end
39
- end
40
- }.map(&:join)
41
-
42
- entries
43
- end
44
-
45
- def parse_opml(opml_node)
46
- feeds = []
47
-
48
- opml_node.elements.each('outline') do |el|
49
- unless el.elements.size.zero?
50
- feeds += parse_opml(el)
51
- else
52
- url = el.attributes['xmlUrl']
53
- feeds << url if url
54
- end
55
- end
56
-
57
- feeds
58
- end
59
- end
60
- end