feedcellar 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 90de9f0e20628fe9c0296ceb73a55e068124996b
4
- data.tar.gz: 35318c5da10ecd18d85c37f0e00c2dcf10c907ad
3
+ metadata.gz: 9478a7d588e3f1c7be9402dfcf37e49b112452cd
4
+ data.tar.gz: bb63a40e9fd82a57c69e618a3a1c985b1c672399
5
5
  SHA512:
6
- metadata.gz: dc398b74be7d927be4cdb120878ce6b556099d01ca675c18fd1e39c08ee61fe7ff7a278870b1af7a57db6210beda04e3c7265b94305d9e5df472e080847ce426
7
- data.tar.gz: 3d92d30d502af29ccb90a1347ea7bf1463d26ad9635683cd8d0eb655733302c77dbc256862f03dcdc67bed8c7e2ef44f261935d9f053d3de7dcab9bd6d50ce33
6
+ metadata.gz: d83937efa958d9357fa558d759c189d43b45a34a8c5c10527f5b0282e2ae1bae35bd8e1f1f9fa0382d4e0f68ac20d351e382e819fd98d21d3e66de4760157079
7
+ data.tar.gz: 7086249c6bee9a405b9aa4dc9bf0518ba6c80aa50a1985c78dc51d906232f9ac2c4b109a4b1077ec4364c88b817ce9f58e841e8557f4eb45a7b3091795097698
data/NEWS.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # NEWS
2
2
 
3
+ ## 0.3.1: 2013-07-04
4
+
5
+ The release that supported a rich view by curses.
6
+
7
+ ### Changes
8
+
9
+ * Improvements
10
+ * Removed browser option.
11
+ * Supported rich view by curses.
12
+ * Extracted groonga_searcher for use with API.
13
+
14
+ * Fixes
15
+ * Fixed default order.
16
+
3
17
  ## 0.3.0: 2013-06-23
4
18
 
5
19
  Database schema improved release!
data/README.md CHANGED
@@ -48,6 +48,16 @@ Word search from titles and descriptions
48
48
 
49
49
  $ feedcellar search ruby
50
50
 
51
+ Rich view by curses (set as default since 0.4.0)
52
+
53
+ $ feedcellar search ruby --curses
54
+
55
+ Keybind:
56
+ j: down
57
+ k: up
58
+ f, ENTER: open link on firefox
59
+ q: quit
60
+
51
61
  Delete database
52
62
 
53
63
  $ rm -r ~/.feedcellar
@@ -1,6 +1,7 @@
1
1
  require "thor"
2
2
  require "feedcellar/version"
3
3
  require "feedcellar/groonga_database"
4
+ require "feedcellar/groonga_searcher"
4
5
  require "feedcellar/opml"
5
6
  require "feedcellar/feed"
6
7
  require "feedcellar/resource"
@@ -105,11 +106,11 @@ module Feedcellar
105
106
  end
106
107
 
107
108
  desc "search WORD", "Search feeds from local database."
108
- option :browser, :type => :boolean, :desc => "open *ALL* links in browser"
109
109
  option :long, :type => :boolean, :aliases => "-l", :desc => "use a long listing format"
110
110
  option :reverse, :type => :boolean, :aliases => "-r", :desc => "reverse order while sorting"
111
111
  option :mtime, :type => :numeric, :desc => "feed's data was last modified n*24 hours ago."
112
112
  option :resource, :type => :string, :desc => "search of partial match by feed's resource url"
113
+ option :curses, :type => :boolean, :desc => "rich view for easy web browse"
113
114
  def search(*words)
114
115
  if words.empty? &&
115
116
  (options["resource"].nil? || options["resource"].empty?)
@@ -117,65 +118,24 @@ module Feedcellar
117
118
  return 1
118
119
  end
119
120
 
120
- if options[:browser]
121
- unless GUI.available?
122
- $stderr.puts "WARNING: browser option required \"gtk2\"."
123
- end
124
- end
125
-
126
121
  GroongaDatabase.new.open(@database_dir) do |database|
127
- feeds = database.feeds
128
- feeds = feeds.select do |feed|
129
- expression = nil
130
- words.each do |word|
131
- sub_expression = (feed.title =~ word) |
132
- (feed.description =~ word)
133
- if expression.nil?
134
- expression = sub_expression
135
- else
136
- expression &= sub_expression
137
- end
138
- end
139
-
140
- if options[:mtime]
141
- base_date = (Time.now - (options[:mtime] * 60 * 60 * 24))
142
- mtime_expression = feed.date > base_date
143
- if expression.nil?
144
- expression = mtime_expression
145
- else
146
- expression &= mtime_expression
147
- end
148
- end
149
-
150
- if options[:resource]
151
- resource_expression = feed.resource =~ options[:resource]
152
- if expression.nil?
153
- expression = resource_expression
122
+ sorted_feeds = GroongaSearcher.search(database, words, options)
123
+
124
+ if options[:curses]
125
+ require "feedcellar/curses_view"
126
+ CursesView.run(sorted_feeds)
127
+ else
128
+ sorted_feeds.each do |feed|
129
+ title = feed.title.gsub(/\n/, " ")
130
+ if options[:long]
131
+ date = feed.date.strftime("%Y/%m/%d %H:%M")
132
+ resource = feed.resource.title
133
+ puts "#{date} #{title} - #{resource} / #{feed.link}"
154
134
  else
155
- expression &= resource_expression
135
+ date = feed.date.strftime("%Y/%m/%d")
136
+ puts "#{date} #{title}"
156
137
  end
157
138
  end
158
-
159
- expression
160
- end
161
-
162
- order = options[:reverse] ? "descending" : "ascending"
163
- sorted_feeds = feeds.sort([{:key => "date", :order => order}])
164
-
165
- sorted_feeds.each do |feed|
166
- title = feed.title.gsub(/\n/, " ")
167
- if options[:long]
168
- date = feed.date.strftime("%Y/%m/%d %H:%M")
169
- resource = feed.resource.title
170
- puts "#{date} #{title} - #{resource} / #{feed.link}"
171
- else
172
- date = feed.date.strftime("%Y/%m/%d")
173
- puts "#{date} #{title}"
174
- end
175
-
176
- if options[:browser]
177
- GUI.show_uri(feed.link)
178
- end
179
139
  end
180
140
  end
181
141
  end
@@ -0,0 +1,42 @@
1
+ require "curses"
2
+
3
+ module Feedcellar
4
+ module CursesView
5
+ module_function
6
+ def run(feeds)
7
+ Curses.init_screen
8
+ Curses.noecho
9
+ Curses.nonl
10
+
11
+ feeds.each_with_index do |feed, i|
12
+ Curses.setpos(i, 0)
13
+ title = feed.title.gsub(/\n/, " ")
14
+ date = feed.date.strftime("%Y/%m/%d")
15
+ Curses.addstr("#{date} #{title}")
16
+ end
17
+ Curses.setpos(0, 0)
18
+
19
+ pos = 0
20
+ begin
21
+ loop do
22
+ case Curses.getch
23
+ when "j"
24
+ pos += 1 if pos < Curses.lines - 1
25
+ Curses.setpos(pos, 0)
26
+ when "k"
27
+ pos -= 1 if pos > 0
28
+ Curses.setpos(pos, 0)
29
+ when "f", 13
30
+ spawn("firefox",
31
+ feeds[pos + 1].link,
32
+ [:out, :err] => "/dev/null")
33
+ when "q"
34
+ break
35
+ end
36
+ end
37
+ ensure
38
+ Curses.close_screen
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,47 @@
1
+ module Feedcellar
2
+ class GroongaSearcher
3
+ class << self
4
+ def search(database, words, options)
5
+ feeds = database.feeds
6
+ feeds = feeds.select do |feed|
7
+ expression = nil
8
+ words.each do |word|
9
+ sub_expression = (feed.title =~ word) |
10
+ (feed.description =~ word)
11
+ if expression.nil?
12
+ expression = sub_expression
13
+ else
14
+ expression &= sub_expression
15
+ end
16
+ end
17
+
18
+ if options[:mtime]
19
+ base_date = (Time.now - (options[:mtime] * 60 * 60 * 24))
20
+ mtime_expression = feed.date > base_date
21
+ if expression.nil?
22
+ expression = mtime_expression
23
+ else
24
+ expression &= mtime_expression
25
+ end
26
+ end
27
+
28
+ if options[:resource]
29
+ resource_expression = feed.resource =~ options[:resource]
30
+ if expression.nil?
31
+ expression = resource_expression
32
+ else
33
+ expression &= resource_expression
34
+ end
35
+ end
36
+
37
+ expression
38
+ end
39
+
40
+ order = options[:reverse] ? "ascending" : "descending"
41
+ sorted_feeds = feeds.sort([{:key => "date", :order => order}])
42
+
43
+ sorted_feeds
44
+ end
45
+ end
46
+ end
47
+ end
@@ -1,3 +1,3 @@
1
1
  module Feedcellar
2
- VERSION = "0.3.0"
2
+ VERSION = "0.3.1"
3
3
  end
data/test/test-command.rb CHANGED
@@ -5,42 +5,50 @@ require "feedcellar/command"
5
5
  require "feedcellar/groonga_database"
6
6
 
7
7
  class CommandTest < Test::Unit::TestCase
8
- def setup
9
- @tmpdir = File.join(File.dirname(__FILE__), "tmp", "database")
10
- FileUtils.mkdir_p(@tmpdir)
11
- @command = Feedcellar::Command.new
12
- @command.instance_variable_set(:@database_dir, @tmpdir)
8
+ class << self
9
+ def startup
10
+ @@tmpdir = File.join(File.dirname(__FILE__), "tmp", "database")
11
+ FileUtils.rm_rf(@@tmpdir)
12
+ FileUtils.mkdir_p(@@tmpdir)
13
+ @@command = Feedcellar::Command.new
14
+ @@command.instance_variable_set(:@database_dir, @@tmpdir)
15
+ end
16
+
17
+ def shutdown
18
+ FileUtils.rm_rf(@@tmpdir)
19
+ end
13
20
  end
14
21
 
15
- def test_command
16
- # confirm version command
22
+ def test_version
17
23
  s = ""
18
24
  io = StringIO.new(s)
19
25
  $stdout = io
20
- @command.version
26
+ @@command.version
21
27
  assert_equal("#{Feedcellar::VERSION}\n", s)
22
28
  $stdout = STDOUT
29
+ end
23
30
 
31
+ def test_command
24
32
  # confirm register command if invalid URL
25
33
  s = ""
26
34
  io = StringIO.new(s)
27
35
  $stderr = io
28
- assert_equal(1, @command.register("hoge"))
36
+ assert_equal(1, @@command.register("hoge"))
29
37
  assert_equal("ERROR: Invalid URL\n", s)
30
38
  $stderr = STDERR
31
39
 
32
40
  # confirm register command
33
- @command.register("http://myokoym.github.io/entries.rss")
34
- @command.register("https://rubygems.org/gems/mister_fairy/versions.atom")
35
- Feedcellar::GroongaDatabase.new.open(@tmpdir) do |database|
41
+ @@command.register("http://myokoym.github.io/entries.rss")
42
+ @@command.register("https://rubygems.org/gems/mister_fairy/versions.atom")
43
+ Feedcellar::GroongaDatabase.new.open(@@tmpdir) do |database|
36
44
  assert_equal(2, database.resources.size)
37
45
  end
38
46
 
39
47
  # confirm import command
40
48
  file = File.join(File.dirname(__FILE__), "fixtures", "subscriptions.xml")
41
- @command.import(file)
42
- @command.collect
43
- Feedcellar::GroongaDatabase.new.open(@tmpdir) do |database|
49
+ @@command.import(file)
50
+ @@command.collect
51
+ Feedcellar::GroongaDatabase.new.open(@@tmpdir) do |database|
44
52
  # NOTE: a tag of outline is not register.
45
53
  assert_equal(3, database.resources.size)
46
54
  assert_true(database.feeds.count > 0)
@@ -50,7 +58,7 @@ class CommandTest < Test::Unit::TestCase
50
58
  s = ""
51
59
  io = StringIO.new(s)
52
60
  $stdout = io
53
- @command.export
61
+ @@command.export
54
62
  assert_equal(1, s.scan(/<opml/).size)
55
63
  assert_equal(3, s.scan(/<outline/).size)
56
64
  $stdout = STDOUT
@@ -59,17 +67,17 @@ class CommandTest < Test::Unit::TestCase
59
67
  s = ""
60
68
  io = StringIO.new(s)
61
69
  $stdout = io
62
- @command.search("ruby")
70
+ @@command.search("ruby")
63
71
  assert_true(s.size > 100)
64
72
  $stdout = STDOUT
65
73
 
66
74
  # confirm unregister command
67
- @command.unregister("my_letter")
68
- Feedcellar::GroongaDatabase.new.open(@tmpdir) do |database|
75
+ @@command.unregister("my_letter")
76
+ Feedcellar::GroongaDatabase.new.open(@@tmpdir) do |database|
69
77
  assert_equal(2, database.resources.size)
70
78
  end
71
- @command.unregister("https://rubygems.org/gems/mister_fairy/versions.atom")
72
- Feedcellar::GroongaDatabase.new.open(@tmpdir) do |database|
79
+ @@command.unregister("https://rubygems.org/gems/mister_fairy/versions.atom")
80
+ Feedcellar::GroongaDatabase.new.open(@@tmpdir) do |database|
73
81
  assert_equal(1, database.resources.size)
74
82
  end
75
83
 
@@ -77,12 +85,8 @@ class CommandTest < Test::Unit::TestCase
77
85
  s = ""
78
86
  io = StringIO.new(s)
79
87
  $stdout = io
80
- @command.latest
88
+ @@command.latest
81
89
  assert_true(s.size > 0)
82
90
  $stdout = STDOUT
83
91
  end
84
-
85
- def teardown
86
- FileUtils.rm_rf(@tmpdir)
87
- end
88
92
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: feedcellar
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masafumi Yokoyama
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-06-23 00:00:00.000000000 Z
11
+ date: 2013-07-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rroonga
@@ -127,9 +127,10 @@ files:
127
127
  - feedcellar.gemspec
128
128
  - lib/feedcellar.rb
129
129
  - lib/feedcellar/command.rb
130
+ - lib/feedcellar/curses_view.rb
130
131
  - lib/feedcellar/feed.rb
131
132
  - lib/feedcellar/groonga_database.rb
132
- - lib/feedcellar/gui.rb
133
+ - lib/feedcellar/groonga_searcher.rb
133
134
  - lib/feedcellar/opml.rb
134
135
  - lib/feedcellar/resource.rb
135
136
  - lib/feedcellar/version.rb
@@ -1,27 +0,0 @@
1
- module Feedcellar
2
- class GUI
3
- class << self
4
- def available?
5
- gtk_available?
6
- end
7
-
8
- def show_uri(uri)
9
- Gtk.show_uri(uri) if gtk_available?
10
- end
11
-
12
- private
13
- def gtk_available?
14
- if @gtk_available.nil?
15
- begin
16
- require "gtk2"
17
- rescue LoadError
18
- @gtk_available = false
19
- else
20
- @gtk_available = true
21
- end
22
- end
23
- @gtk_available
24
- end
25
- end
26
- end
27
- end