feedcellar 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,49 @@
1
+ require "sinatra/base"
2
+ require "haml"
3
+ require "feedcellar/command"
4
+
5
+ module Feedcellar
6
+ class Web < Sinatra::Base
7
+ get "/" do
8
+ haml :index
9
+ end
10
+
11
+ get "/search" do
12
+ if params[:word]
13
+ words = params[:word].split(" ")
14
+ else
15
+ words = []
16
+ end
17
+ options ||= {}
18
+ options[:resource_id] = params[:resource_id] if params[:resource_id]
19
+ @feeds = search(words, options)
20
+ haml :index
21
+ end
22
+
23
+ helpers do
24
+ def search(words, options={})
25
+ database = GroongaDatabase.new
26
+ database.open(Command.new.database_dir)
27
+ GroongaSearcher.search(database, words, options)
28
+ end
29
+
30
+ def grouping(table)
31
+ key = "resource"
32
+ table.group(key).sort_by {|item| item.n_sub_records }.reverse
33
+ end
34
+
35
+ def markup_drilled_item(resource)
36
+ link = url("/search?resource_id=#{resource._id}&word=#{params[:word]}")
37
+ "<a href=#{link}>#{resource.title} (#{resource.n_sub_records})</a>"
38
+ end
39
+
40
+ def groonga_version
41
+ Groonga::VERSION[0..2].join(".")
42
+ end
43
+
44
+ def rroonga_version
45
+ Groonga::BINDINGS_VERSION.join(".")
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,166 @@
1
+ # Copyright (C) 2014 Masafumi Yokoyama <myokoym@gmail.com>
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License as published by the Free Software Foundation; either
6
+ # version 2.1 of the License, or (at your option) any later version.
7
+ #
8
+ # This library is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
+ # Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public
14
+ # License along with this library; if not, write to the Free Software
15
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
+
17
+ require "gtk2"
18
+ require "feedcellar/tree_view"
19
+ require "feedcellar/command"
20
+ require "feedcellar/groonga_database"
21
+ require "feedcellar/groonga_searcher"
22
+
23
+ module Feedcellar
24
+ class Window < Gtk::Window
25
+ def initialize(database_dir, options)
26
+ super()
27
+ @database = GroongaDatabase.new
28
+ @database.open(database_dir)
29
+ @options = options
30
+ self.title = "Feedcellar"
31
+ set_default_size(640, 480)
32
+ signal_connect("destroy") do
33
+ @database.close unless @database.closed?
34
+ Gtk.main_quit
35
+ end
36
+
37
+ @vbox = Gtk::VBox.new
38
+ add(@vbox)
39
+
40
+ @entry_hbox = Gtk::HBox.new
41
+ @vbox.pack_start(@entry_hbox, false, false, 0)
42
+
43
+ @entry = Gtk::Entry.new
44
+ @entry_hbox.add(@entry)
45
+ @search_button = Gtk::Button.new("Search")
46
+ @search_button.signal_connect("clicked") do
47
+ words = @entry.text.split(" ")
48
+ records = search(words, @options)
49
+ @tree_view.update_model(records)
50
+ end
51
+ @entry_hbox.add(@search_button)
52
+
53
+ @scrolled_window = Gtk::ScrolledWindow.new
54
+ @scrolled_window.set_policy(:automatic, :automatic)
55
+ @vbox.pack_start(@scrolled_window, true, true, 0)
56
+
57
+ records = all_records(options)
58
+
59
+ @tree_view = TreeView.new(records)
60
+ @scrolled_window.add(@tree_view)
61
+
62
+ @label = Gtk::Label.new
63
+ @label.text = "Double Click or Press Return: Open a Link into Browser/ Ctrl+d: Delete from Data Store"
64
+ @vbox.pack_start(@label, false, false, 0)
65
+
66
+ @tree_view.signal_connect("row-activated") do |tree_view, path, column|
67
+ show_uri(@tree_view.selected_link)
68
+ end
69
+
70
+ define_key_bindings
71
+ end
72
+
73
+ def run
74
+ show_all
75
+ Gtk.main
76
+ end
77
+
78
+ private
79
+ def search(words, options)
80
+ records = GroongaSearcher.search(@database, words, options)
81
+ if options[:lines]
82
+ records.take(options[:lines])
83
+ else
84
+ records
85
+ end
86
+ end
87
+
88
+ def all_records(options)
89
+ search(nil, options)
90
+ end
91
+
92
+ def define_key_bindings
93
+ signal_connect("key-press-event") do |widget, event|
94
+ handled = false
95
+
96
+ if event.state.control_mask?
97
+ handled = action_from_keyval_with_control_mask(event.keyval)
98
+ else
99
+ handled = action_from_keyval(event.keyval)
100
+ end
101
+
102
+ handled
103
+ end
104
+ end
105
+
106
+ def action_from_keyval(keyval)
107
+ case keyval
108
+ when Gdk::Keyval::GDK_KEY_n
109
+ @tree_view.next
110
+ when Gdk::Keyval::GDK_KEY_p
111
+ @tree_view.prev
112
+ when Gdk::Keyval::GDK_KEY_Return
113
+ show_uri(@tree_view.selected_link)
114
+ when Gdk::Keyval::GDK_KEY_h
115
+ @scrolled_window.hadjustment.value -= 17
116
+ when Gdk::Keyval::GDK_KEY_j
117
+ @scrolled_window.vadjustment.value += 17
118
+ when Gdk::Keyval::GDK_KEY_k
119
+ @scrolled_window.vadjustment.value -= 17
120
+ when Gdk::Keyval::GDK_KEY_l
121
+ @scrolled_window.hadjustment.value += 17
122
+ when Gdk::Keyval::GDK_KEY_q
123
+ destroy
124
+ else
125
+ return false
126
+ end
127
+ true
128
+ end
129
+
130
+ def action_from_keyval_with_control_mask(keyval)
131
+ case keyval
132
+ when Gdk::Keyval::GDK_KEY_n
133
+ 10.times { @tree_view.next }
134
+ when Gdk::Keyval::GDK_KEY_p
135
+ 10.times { @tree_view.prev }
136
+ when Gdk::Keyval::GDK_KEY_d
137
+ key = @tree_view.selected_key
138
+ if key
139
+ # TODO: don't want to use Command class.
140
+ GroongaDatabase.new.open(Command.new.database_dir) do |database|
141
+ database.delete(key)
142
+ end
143
+ @tree_view.remove_selected_record
144
+ end
145
+ else
146
+ return false
147
+ end
148
+ true
149
+ end
150
+
151
+ def show_uri(uri)
152
+ case RUBY_PLATFORM
153
+ when /darwin/
154
+ system("open", uri)
155
+ when /mswin|mingw|cygwin|bccwin/
156
+ system("start", uri)
157
+ else
158
+ if Gtk.respond_to?(:show_uri)
159
+ Gtk.show_uri(uri)
160
+ else
161
+ system("firefox", uri)
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end