feedcellar 0.3.0 → 0.3.1

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,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