picky-client 2.1.2 → 2.2.0

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.
@@ -0,0 +1,225 @@
1
+ module Picky
2
+
3
+ # A simple terminal based search.
4
+ #
5
+ class Terminal
6
+
7
+ attr_reader :client
8
+
9
+ def initialize given_uri, id_amount = nil
10
+ check_highline_gem
11
+ check_picky_client_gem
12
+
13
+ require 'uri'
14
+ uri = URI.parse given_uri
15
+
16
+ # If the user gave a whole url without http, add that and reparse.
17
+ #
18
+ unless uri.path
19
+ uri = URI.parse "http://#{given_uri}"
20
+ end
21
+
22
+ # If the user gave a path without / in front, add one.
23
+ #
24
+ unless uri.path =~ /^\//
25
+ uri.path = "/#{uri.path}"
26
+ end
27
+
28
+ @searches = 0
29
+ @durations = 0
30
+ @current_text = ''
31
+ @cursor_offset = 0
32
+ @last_ids = ''
33
+ @id_amount = id_amount && Integer(id_amount) || 20
34
+ @client = Picky::Client.new :host => (uri.host || 'localhost'), :port => (uri.port || 8080), :path => uri.path
35
+
36
+ install_trap
37
+ end
38
+ def check_highline_gem # :nodoc:
39
+ require "highline/system_extensions"
40
+ extend HighLine::SystemExtensions
41
+ rescue LoadError
42
+ warn_gem_missing 'highline', 'the terminal interface'
43
+ exit 1
44
+ end
45
+ def check_picky_client_gem # :nodoc:
46
+ require 'picky-client'
47
+ rescue LoadError
48
+ warn_gem_missing 'picky-client', 'the terminal interface'
49
+ exit 1
50
+ end
51
+
52
+ # Install the Ctrl-C handler.
53
+ #
54
+ def install_trap
55
+ Signal.trap('INT') do
56
+ print "\e[100D"
57
+ flush
58
+ puts "\n"
59
+ puts "You performed #{@searches} searches, totalling #{"%.3f" % @durations} seconds."
60
+ print "\e[100D"
61
+ flush
62
+ exit
63
+ end
64
+ end
65
+
66
+ # Flush to STDOUT.
67
+ #
68
+ def flush
69
+ STDOUT.flush
70
+ end
71
+
72
+ # Position cursor amount to the left.
73
+ #
74
+ def left amount = 1
75
+ print "\e[#{amount}D"
76
+ flush
77
+ end
78
+
79
+ # Position cursor amount to the right.
80
+ #
81
+ def right amount = 1
82
+ print "\e[#{amount}C"
83
+ flush
84
+ end
85
+
86
+ # Move cursor to position.
87
+ #
88
+ def move_to position
89
+ relative = position - @cursor_offset
90
+ if relative > 0
91
+ right relative
92
+ else
93
+ left relative
94
+ end
95
+ @cursor_offset = position
96
+ flush
97
+ end
98
+
99
+ # Delete one character.
100
+ #
101
+ def backspace
102
+ chop_text
103
+ print "\e[1D \e[1D"
104
+ flush
105
+ end
106
+
107
+ # Write the text to the input area.
108
+ #
109
+ def write text
110
+ @cursor_offset += text.size
111
+ print text
112
+ flush
113
+ end
114
+
115
+ # Chop off one character.
116
+ #
117
+ def chop_text
118
+ @current_text.chop!
119
+ end
120
+
121
+ # Add the given text to the current text.
122
+ #
123
+ def add_text text
124
+ @current_text << text
125
+ end
126
+
127
+ # Type the given text into the input area.
128
+ #
129
+ def type_search character
130
+ add_text character
131
+ write character
132
+ end
133
+
134
+ # Write the amount of result ids.
135
+ #
136
+ def write_results results
137
+ move_to 0
138
+ write "%9d" % (results && results.total || 0)
139
+ move_to 10 + @current_text.size
140
+ end
141
+
142
+ # Move to the id area.
143
+ #
144
+ def move_to_ids
145
+ move_to 12 + @current_text.size
146
+ end
147
+
148
+ # Write the result ids.
149
+ #
150
+ def write_ids results
151
+ move_to_ids
152
+ write "=> #{results.total ? results.ids(@id_amount) : []}"
153
+ rescue StandardError => e
154
+ p e.message
155
+ p e.backtrace
156
+ end
157
+
158
+ # Clear the result ids.
159
+ #
160
+ def clear_ids
161
+ move_to_ids
162
+ write @ids_clearing_string ||= " "*200
163
+ end
164
+
165
+ # Log a search.
166
+ #
167
+ def log results
168
+ @searches += 1
169
+ @durations += (results[:duration] || 0)
170
+ end
171
+
172
+ # Perform a search.
173
+ #
174
+ def search full = false
175
+ client.search @current_text, :ids => (full ? @id_amount : 0)
176
+ end
177
+
178
+ # Perform a search and write the results.
179
+ #
180
+ # Handles 404s and connection problems.
181
+ #
182
+ def search_and_write full = false
183
+ results = search full
184
+ results.extend Picky::Convenience
185
+
186
+ log results
187
+
188
+ full ? write_ids(results) : clear_ids
189
+
190
+ write_results results
191
+ rescue Errno::ECONNREFUSED => e
192
+ write "Please start a Picky server listening to #{@client.path}."
193
+ rescue Yajl::ParseError => e
194
+ write "Got a 404. Maybe the path #{@client.path} isn't a correct one?"
195
+ end
196
+
197
+ # Run the terminal.
198
+ #
199
+ # Note: Uses a simple loop to handle input.
200
+ #
201
+ def run
202
+ puts "Type and see the result count update. Press enter for the first #{@id_amount} result ids."
203
+ puts "Break with Ctrl-C."
204
+
205
+ search_and_write
206
+
207
+ loop do
208
+ input = get_character
209
+
210
+ case input
211
+ when 127
212
+ backspace
213
+ search_and_write
214
+ when 13
215
+ search_and_write true
216
+ else # All other.
217
+ type_search input.chr
218
+ search_and_write
219
+ end
220
+ end
221
+ end
222
+
223
+ end
224
+
225
+ end
@@ -0,0 +1,150 @@
1
+ # encoding: utf-8
2
+ #
3
+ require 'spec_helper'
4
+
5
+ # We need to load the Statistics file explicitly as the Statistics
6
+ # are not loaded with the Loader (not needed in the server, only for script runs).
7
+ #
8
+ require File.expand_path '../../../../lib/picky-client/aux/terminal', __FILE__
9
+
10
+ describe Picky::Terminal do
11
+
12
+ let(:terminal) { described_class.new('/some/url') }
13
+
14
+ describe 'backspace' do
15
+ it 'works correctly' do
16
+ terminal.should_receive(:chop_text).once.ordered.with()
17
+ terminal.should_receive(:print).once.ordered.with "\e[1D \e[1D"
18
+ terminal.should_receive(:flush).once.ordered.with()
19
+
20
+ terminal.backspace
21
+ end
22
+ end
23
+
24
+ describe 'write_results' do
25
+ it 'works correctly' do
26
+ terminal.should_receive(:move_to).once.ordered.with 0
27
+ terminal.should_receive(:write).once.ordered.with " 0"
28
+ terminal.should_receive(:move_to).once.ordered.with 10
29
+
30
+ terminal.write_results nil
31
+ end
32
+ it 'works correctly' do
33
+ terminal.should_receive(:move_to).once.ordered.with 0
34
+ terminal.should_receive(:write).once.ordered.with "123456789"
35
+ terminal.should_receive(:move_to).once.ordered.with 10
36
+
37
+ terminal.write_results stub(:results, :total => 123456789)
38
+ end
39
+ end
40
+
41
+ describe 'search' do
42
+ before(:each) do
43
+ @client = stub :client
44
+ terminal.stub! :client => @client
45
+
46
+ terminal.add_text 'hello'
47
+ end
48
+ it 'searches full correctly' do
49
+ @client.should_receive(:search).once.with 'hello', :ids => 20
50
+
51
+ terminal.search true
52
+ end
53
+ it 'searches full correctly' do
54
+ terminal = described_class.new('/some/url', 33)
55
+ terminal.stub! :client => @client
56
+
57
+ @client.should_receive(:search).once.with '', :ids => 33
58
+
59
+ terminal.search true
60
+ end
61
+ it 'searches live correctly' do
62
+ @client.should_receive(:search).once.with 'hello', :ids => 0
63
+
64
+ terminal.search
65
+ end
66
+ it 'searches live correctly' do
67
+ @client.should_receive(:search).once.with 'hello', :ids => 0
68
+
69
+ terminal.search false
70
+ end
71
+ end
72
+
73
+ describe 'clear_ids' do
74
+ it 'moves to the ids, then clears all' do
75
+ terminal.should_receive(:move_to_ids).once.with()
76
+ terminal.should_receive(:write).once.with " "*200
77
+
78
+ terminal.clear_ids
79
+ end
80
+ end
81
+
82
+ describe 'write_ids' do
83
+ it 'writes the result\'s ids' do
84
+ terminal.should_receive(:move_to_ids).once.with()
85
+ terminal.should_receive(:write).once.with "=> []"
86
+
87
+ terminal.write_ids stub(:results, :total => nil)
88
+ end
89
+ it 'writes the result\'s ids' do
90
+ terminal.should_receive(:move_to_ids).once.with()
91
+ terminal.should_receive(:write).once.with "=> [1, 2, 3]"
92
+
93
+ terminal.write_ids stub(:results, :total => 3, :ids => [1, 2, 3])
94
+ end
95
+ end
96
+
97
+ describe 'move_to_ids' do
98
+ it 'moves to a specific place' do
99
+ terminal.should_receive(:move_to).once.with 12
100
+
101
+ terminal.move_to_ids
102
+ end
103
+ it 'moves to a specific place' do
104
+ terminal.add_text 'test'
105
+
106
+ terminal.should_receive(:move_to).once.with 16
107
+
108
+ terminal.move_to_ids
109
+ end
110
+ end
111
+
112
+ describe 'left' do
113
+ it 'moves by amount' do
114
+ terminal.should_receive(:print).once.ordered.with "\e[13D"
115
+ terminal.should_receive(:flush).once.ordered
116
+
117
+ terminal.left 13
118
+ end
119
+ it 'default is 1' do
120
+ terminal.should_receive(:print).once.ordered.with "\e[1D"
121
+ terminal.should_receive(:flush).once.ordered
122
+
123
+ terminal.left
124
+ end
125
+ end
126
+
127
+ describe 'right' do
128
+ it 'moves by amount' do
129
+ terminal.should_receive(:print).once.ordered.with "\e[13C"
130
+ terminal.should_receive(:flush).once.ordered
131
+
132
+ terminal.right 13
133
+ end
134
+ it 'default is 1' do
135
+ terminal.should_receive(:print).once.ordered.with "\e[1C"
136
+ terminal.should_receive(:flush).once.ordered
137
+
138
+ terminal.right
139
+ end
140
+ end
141
+
142
+ describe 'flush' do
143
+ it 'flushes STDOUT' do
144
+ STDOUT.should_receive(:flush).once.with()
145
+
146
+ terminal.flush
147
+ end
148
+ end
149
+
150
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: picky-client
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 2.1.2
5
+ version: 2.2.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Florian Hanke
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-04-11 00:00:00 +10:00
13
+ date: 2011-04-14 00:00:00 +10:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -33,6 +33,7 @@ extensions: []
33
33
  extra_rdoc_files:
34
34
  - README.rdoc
35
35
  files:
36
+ - lib/picky-client/aux/terminal.rb
36
37
  - lib/picky-client/client.rb
37
38
  - lib/picky-client/convenience.rb
38
39
  - lib/picky-client/helper.rb
@@ -45,6 +46,7 @@ files:
45
46
  - javascripts/jquery-1.5.0.min.js
46
47
  - javascripts/picky.min.js
47
48
  - README.rdoc
49
+ - spec/picky-client/aux/terminal_spec.rb
48
50
  - spec/picky-client/client_spec.rb
49
51
  - spec/picky-client/convenience_spec.rb
50
52
  - spec/picky-client/helper_spec.rb
@@ -77,6 +79,7 @@ signing_key:
77
79
  specification_version: 3
78
80
  summary: picky Ruby Search Engine Client
79
81
  test_files:
82
+ - spec/picky-client/aux/terminal_spec.rb
80
83
  - spec/picky-client/client_spec.rb
81
84
  - spec/picky-client/convenience_spec.rb
82
85
  - spec/picky-client/helper_spec.rb