picky-client 2.1.2 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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