torrent_search 0.0.1 → 0.0.2

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: bd9610eafd270094d42cb2941cf33f3523c464de
4
- data.tar.gz: 46672a36018da5016f2236cb46d5b14ac8f69aac
3
+ metadata.gz: 12ddba74cad73e48b10325bc3d675c3847ace3dd
4
+ data.tar.gz: 2596e6a414aa0ab60d4a2648ea8d6949a499f1d1
5
5
  SHA512:
6
- metadata.gz: b4639cc8accc906700b3ff859bc9b0365d8a783225cb20a1f67aeb5d84d2ac30701caabb4fea8b9eebf4b58ebc46c14ff0baa4974a3d670023863a7ee0ad5b32
7
- data.tar.gz: 0f5635af0ebf544af3ad8b478a133dd8aa614be1f6752e7465f7226cc3fb7c6aa0f731d62bb41a065ea2b1485f97e8b47e922121eb93b35e8d126b36a724c57d
6
+ metadata.gz: a277fc48659c4c2d040081f594f095bb44ac16ab03cc63bf5bab8605f30e247971dfea548b6e7659480795541776c41db38e678f3eed18924a7439d2dd6c69a2
7
+ data.tar.gz: 2ed1dae9c1625eae4e7d6147404686940295344027646cc41ce2e83a256c9de5161ac16e30dcebb21c8f84294949bea0983900d72f2d2189efc7ada9edb96047
data/.gitignore CHANGED
@@ -7,7 +7,6 @@ Gemfile.lock
7
7
  InstalledFiles
8
8
  _yardoc
9
9
  coverage
10
- doc/
11
10
  lib/bundler/man
12
11
  pkg
13
12
  rdoc
data/README.md CHANGED
@@ -1,24 +1,31 @@
1
- # TorrentSearch
2
-
3
- TODO: Write a gem description
4
-
5
- ## Installation
6
-
7
- Add this line to your application's Gemfile:
1
+ [![Gem Version](https://badge.fury.io/rb/torrent_search.png)](http://badge.fury.io/rb/torrent_search)
2
+ [![Dependency Status](https://gemnasium.com/joenas/torrent_search.png)](https://gemnasium.com/joenas/torrent_search)
8
3
 
9
- gem 'torrent_search'
10
4
 
11
- And then execute:
5
+ # TorrentSearch
12
6
 
13
- $ bundle
7
+ Search for torrents and download from command line. Trackers will be added, PRs are welcome!
14
8
 
15
- Or install it yourself as:
9
+ ## Installation
16
10
 
17
11
  $ gem install torrent_search
18
12
 
19
13
  ## Usage
20
14
 
21
- TODO: Write usage instructions here
15
+ ![cli usage](https://raw.github.com/joenas/torrent_search/master/doc/screenshot.png)
16
+
17
+ ```shell
18
+ Usage:
19
+ tsearch [TERMS]
20
+
21
+ Options:
22
+ -l, [--limit=N] # Limit search results, default 10
23
+
24
+ Commands:
25
+ tsearch [TERMS] # tsearch help search for options
26
+ tsearch help [COMMAND] # Describe available commands or one specific command
27
+ tsearch version # Shows version
28
+ ```
22
29
 
23
30
  ## Contributing
24
31
 
data/bin/tsearch CHANGED
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
  require "torrent_search"
3
- require "torrent_search/cli"
4
3
 
5
4
  TorrentSearch::CLI.start
Binary file
@@ -1,6 +1,23 @@
1
- require "torrent_search/version"
1
+ require 'thor'
2
+ require 'torrent_search/default_command'
3
+ require 'torrent_search/cli'
4
+
2
5
  require "torrent_search/trackers/kick_ass/kick_ass"
3
6
 
7
+ require 'torrent_search/views/base'
8
+ require 'torrent_search/views/download'
9
+ require 'torrent_search/views/menu'
10
+ require 'torrent_search/views/search'
11
+
12
+ require 'torrent_search/services/download'
13
+
14
+ require 'torrent_search/controllers/download'
15
+ require 'torrent_search/controllers/search'
16
+
17
+ require 'torrent_search/result_table'
18
+
19
+ require "torrent_search/version"
20
+
4
21
  module TorrentSearch
5
22
  # Your code goes here...
6
23
  end
@@ -1,10 +1,3 @@
1
- require 'thor'
2
- require 'torrent_search/default_command'
3
- require 'torrent_search/download'
4
- require 'torrent_search/result_table'
5
- require 'torrent_search/menu'
6
- require 'torrent_search/version'
7
-
8
1
  module TorrentSearch
9
2
  class CLI < Thor
10
3
  include Thor::Actions
@@ -28,10 +21,7 @@ module TorrentSearch
28
21
  desc: 'Limit search results, default 10'
29
22
 
30
23
  def search(*search_terms)
31
- search_result = Trackers::KickAss::Scraper.new(search_terms, options).search
32
- Menu.new(self, search_result).display
33
- rescue SocketError
34
- error 'No network connection?'
24
+ Controllers::Search.new.search search_terms, options
35
25
  end
36
26
 
37
27
  end
@@ -0,0 +1,47 @@
1
+ module TorrentSearch
2
+ module Controllers
3
+ class Download
4
+ DEFAULT_DIR = '.'
5
+
6
+ def initialize(search_result, view = Views::Download.new)
7
+ @search_result = search_result
8
+ @view = view
9
+ end
10
+
11
+ def download
12
+ perform_download choose_torrent!, choose_path!
13
+ end
14
+
15
+ private
16
+ def perform_download(torrent, path)
17
+ @view.downloading! torrent
18
+ Services::Download.new(path, torrent).perform @view
19
+ end
20
+
21
+ def choose_torrent!
22
+ while
23
+ index = @view.torrent?(search_result_range.max)
24
+ return @search_result[index.to_i] if valid_choice?(index)
25
+ @view.invalid_option!
26
+ end
27
+ end
28
+
29
+ def choose_path!
30
+ path = @view.directory? DEFAULT_DIR
31
+ path.empty? ? DEFAULT_DIR : path
32
+ end
33
+
34
+ def valid_choice?(index)
35
+ index.match(/\A\d+\z/) && is_in_search_result?(index)
36
+ end
37
+
38
+ def is_in_search_result?(index)
39
+ search_result_range.member?(index.to_i)
40
+ end
41
+
42
+ def search_result_range
43
+ @range ||= Range.new(0, @search_result.length, true)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,56 @@
1
+ module TorrentSearch
2
+ module Controllers
3
+ class Search
4
+ ACTIONS = {
5
+ d: :download,
6
+ s: :search,
7
+ q: :quit
8
+ }
9
+
10
+ def initialize(view = Views::Search.new)
11
+ @view = view
12
+ end
13
+
14
+ def search(search_terms = nil, options = {})
15
+ search_terms ||= @view.search_terms?
16
+ perform_search search_terms, options
17
+ display_menu
18
+ choose_action!
19
+ rescue SocketError
20
+ error 'No network connection?'
21
+ end
22
+
23
+
24
+ private
25
+ def perform_search(search_terms, options)
26
+ @search_result = Trackers::KickAss::Scraper.new(search_terms, options).search
27
+ end
28
+
29
+ def display_menu
30
+ Views::Menu.new(available_actions, @search_result).display
31
+ end
32
+
33
+ def download
34
+ Download.new(@search_result).download
35
+ end
36
+
37
+ def quit
38
+ CLI::quit
39
+ end
40
+
41
+ def choose_action!
42
+ chosen = @view.action?
43
+ send available_actions.fetch(chosen, :invalid_command)
44
+ end
45
+
46
+ def invalid_command
47
+ @view.invalid_command!
48
+ choose_action!
49
+ end
50
+
51
+ def available_actions
52
+ ACTIONS.dup.tap {|hash| hash.delete(:d) unless @search_result.any? }
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,40 @@
1
+ require "httparty"
2
+
3
+ module TorrentSearch
4
+ module Services
5
+ class Download
6
+ def initialize(path, torrent)
7
+ @path = path
8
+ @torrent = torrent
9
+ end
10
+
11
+ def perform(view)
12
+ if success?
13
+ save!
14
+ view.success
15
+ else
16
+ view.failure response, @torrent.href
17
+ end
18
+ end
19
+
20
+ private
21
+ def success?
22
+ response.code == 200
23
+ end
24
+
25
+ def filename
26
+ File.join(@path, "#{@torrent.filename}.torrent")
27
+ end
28
+
29
+ def save!
30
+ File.open(filename, "wb") do |file|
31
+ file.write response.parsed_response
32
+ end
33
+ end
34
+
35
+ def response
36
+ @response ||= HTTParty.get(@torrent.href)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -1,3 +1,3 @@
1
1
  module TorrentSearch
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,19 @@
1
+ module TorrentSearch
2
+ module Views
3
+ class Base
4
+ include Thor::Shell
5
+ include Thor::Actions
6
+
7
+ def initialize
8
+ end
9
+
10
+ def invalid_option!
11
+ say 'Invalid option', :red
12
+ end
13
+
14
+ def invalid_command!
15
+ say 'Invalid command', :red
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ module TorrentSearch
2
+ module Views
3
+ class Download < Base
4
+
5
+ def torrent?(max)
6
+ ask("Torrent (0-#{max}):")
7
+ end
8
+
9
+ def directory?(default)
10
+ ask "Directory to save file (default '#{default}'):"
11
+ end
12
+
13
+ def downloading!(torrent)
14
+ say "Downloading #{torrent.name}...", :blue
15
+ end
16
+
17
+ def success
18
+ say 'Complete', :green
19
+ end
20
+
21
+ def failure(error, href)
22
+ say "Error: #{error.message} - #{href}", :red
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,34 @@
1
+ module TorrentSearch
2
+ module Views
3
+
4
+ class Menu < Base
5
+ def initialize(actions, search_result)
6
+ @actions = actions
7
+ @search_result = search_result
8
+ end
9
+
10
+ def display
11
+ say_status "\n[Results]", '', :green
12
+ if results?
13
+ print_search_result_table
14
+ else
15
+ say 'Nothing found'
16
+ end
17
+ say_status "\n[Actions]", action_menu, :blue
18
+ end
19
+
20
+ private
21
+ def results?
22
+ @search_result.any?
23
+ end
24
+
25
+ def print_search_result_table
26
+ print_table ResultTable.new(@search_result)
27
+ end
28
+
29
+ def action_menu
30
+ @actions.map {|hash| hash.join(": ")}.join("\t")
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,14 @@
1
+ module TorrentSearch
2
+ module Views
3
+ class Search < Base
4
+
5
+ def action?
6
+ ask("Choose:").to_sym
7
+ end
8
+
9
+ def search_terms?
10
+ ask("Search for:").split
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe TorrentSearch::Controllers::Download do
4
+ Given(:search_result){['asdf']}
5
+ Given(:view){double 'view'}
6
+ Given{view.stub(:downloading!)}
7
+
8
+ subject{described_class.new(search_result, view)}
9
+
10
+ describe '#download' do
11
+ Given(:torrent){search_result.first}
12
+ Given(:path){'.'}
13
+ Given(:download_double){double 'download'}
14
+
15
+ Given{view.stub(:directory?).and_return(path)}
16
+
17
+ Given{TorrentSearch::Services::Download.should_receive(:new).with(path, torrent).and_return(download_double)}
18
+ Given{download_double.should_receive(:perform).with(view)}
19
+
20
+ When{subject.download}
21
+
22
+ describe 'choosing download dir' do
23
+ Given{view.stub(:torrent?).and_return('0')}
24
+
25
+ context 'with default dir' do
26
+ Given(:path){described_class::DEFAULT_DIR}
27
+ Given{view.stub(:directory?).and_return('')}
28
+ Then{}
29
+ end
30
+
31
+ context 'given a dir' do
32
+ Given(:path){'/tmp'}
33
+ Then{}
34
+ end
35
+ end
36
+
37
+ describe 'choosing torrent' do
38
+ context 'with invalid choice then valid choice' do
39
+ Given{view.stub(:torrent?).and_return('1', '0')}
40
+ Given{view.should_receive(:invalid_option!)}
41
+ Then{}
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,58 @@
1
+ require 'spec_helper'
2
+
3
+ describe TorrentSearch::Controllers::Search do
4
+
5
+ Given(:view){double 'view'}
6
+
7
+ subject{described_class.new(view)}
8
+
9
+ describe '#search' do
10
+ Given(:search_terms){'asdf'}
11
+ Given(:options){{}}
12
+ Given(:scraper_double){double 'scraper'}
13
+
14
+ Given{TorrentSearch::Trackers::KickAss::Scraper.should_receive(:new).with(search_terms, options).and_return(scraper_double)}
15
+ Given{scraper_double.should_receive(:search).and_return(search_result)}
16
+
17
+ When{subject.search(search_terms, options)}
18
+
19
+ context 'with no search result' do
20
+ Given(:search_result){[]}
21
+
22
+ context 'with invalid command then quit' do
23
+ Given{view.stub(:action?).and_return(:d, :q)}
24
+ Given{view.stub(:invalid_command!)}
25
+
26
+ Given{TorrentSearch::CLI.should_receive(:quit)}
27
+ Then{}
28
+ end
29
+
30
+ context 'with search again then quit' do
31
+ Given(:new_search_terms){'fdsa'}
32
+
33
+ Given{view.stub(:action?).and_return(:s, :q)}
34
+ Given{view.stub(:search_terms?).and_return(new_search_terms)}
35
+
36
+ Given{TorrentSearch::Trackers::KickAss::Scraper.should_receive(:new).with(new_search_terms, options).and_return(scraper_double)}
37
+ Given{scraper_double.should_receive(:search).and_return(search_result)}
38
+ Given{TorrentSearch::CLI.should_receive(:quit)}
39
+ Then{}
40
+ end
41
+ end
42
+
43
+ context 'with search result' do
44
+ Given(:search_result){[OpenStruct.new(name: '', size:'', seeders: '', leechers:'')]}
45
+
46
+ describe 'download' do
47
+ Given{view.stub(:action?).and_return(:d)}
48
+
49
+ Given(:download_double){double 'download'}
50
+ Given{TorrentSearch::Controllers::Download.should_receive(:new).with(search_result).and_return(download_double)}
51
+ Given{download_double.should_receive :download}
52
+ Then{}
53
+ end
54
+ end
55
+
56
+ end
57
+
58
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe TorrentSearch::Services::Download do
4
+ Given(:path){File.join(Dir.pwd, 'spec/tmp')}
5
+ Given(:torrent){OpenStruct.new(href: 'http://asdf.com', filename: 'asdf')}
6
+ Given(:created_file){File.join(path, "#{torrent.filename}.torrent")}
7
+ Given(:view){double 'view'}
8
+
9
+ subject{described_class.new(path, torrent)}
10
+
11
+ before :each do
12
+ FileUtils.rm created_file, force: true
13
+ end
14
+
15
+ describe '#perform' do
16
+ When{subject.perform view}
17
+
18
+ context 'with 200 success' do
19
+ Given{stub_request(:any, "asdf.com").to_return(status: 200, body: 'abc')}
20
+ Given{view.should receive(:success)}
21
+ Then{a_request(:get, "asdf.com").should have_been_made.once}
22
+ And{File.read(created_file).should eq 'abc'}
23
+ end
24
+
25
+ context 'with 404 not found' do
26
+ Given{stub_request(:any, "asdf.com").to_return(status: 404)}
27
+ Given{view.should receive(:failure)}
28
+ Then{a_request(:get, "asdf.com").should have_been_made.once}
29
+ And{File.exists?(created_file).should be_false}
30
+ end
31
+
32
+ context 'with 500 error' do
33
+ Given{stub_request(:any, "asdf.com").to_return(status: 500)}
34
+ Given{view.should receive(:failure)}
35
+ Then{a_request(:get, "asdf.com").should have_been_made.once}
36
+ And{File.exists?(created_file).should be_false}
37
+ end
38
+ end
39
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'torrent_search'
2
2
  require 'rspec-given'
3
3
  require 'vcr'
4
- require 'fakeweb'
4
+ require 'webmock/rspec'
5
5
 
6
6
  Dir[File.dirname(__FILE__) + "/support/*.rb"].each{|file| require file}
7
7
 
@@ -10,6 +10,13 @@ RSpec.configure do |config|
10
10
  config.run_all_when_everything_filtered = true
11
11
  config.filter_run :focus
12
12
 
13
+ config.before :all do
14
+ path = File.join(Dir.pwd, 'spec/tmp')
15
+ FileUtils.mkdir path unless File.exists? path
16
+ end
17
+
18
+
19
+
13
20
  # Run specs in random order to surface order dependencies. If you find an
14
21
  # order dependency and want to debug it, you can fix the order by providing
15
22
  # the seed, which is printed after each run.
@@ -1,7 +1,7 @@
1
1
  # spec/support/vcr_setup.rb
2
2
  VCR.configure do |c|
3
3
  c.cassette_library_dir = 'spec/vcr'
4
- c.hook_into :fakeweb
4
+ c.hook_into :webmock
5
5
  c.configure_rspec_metadata!
6
6
  c.allow_http_connections_when_no_cassette = true
7
7
  c.default_cassette_options = { :match_requests_on => [:query, :method, :uri, :body], record: :new_episodes }
@@ -29,6 +29,6 @@ Gem::Specification.new do |spec|
29
29
  spec.add_development_dependency "guard", ">=1.6"
30
30
  spec.add_development_dependency "guard-rspec", ">=2.4"
31
31
  spec.add_development_dependency "vcr"
32
- spec.add_development_dependency "fakeweb"
32
+ spec.add_development_dependency "webmock"
33
33
 
34
34
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: torrent_search
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Neverland
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-23 00:00:00.000000000 Z
11
+ date: 2013-12-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -151,7 +151,7 @@ dependencies:
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
153
  - !ruby/object:Gem::Dependency
154
- name: fakeweb
154
+ name: webmock
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
157
  - - '>='
@@ -180,16 +180,25 @@ files:
180
180
  - README.md
181
181
  - Rakefile
182
182
  - bin/tsearch
183
+ - doc/screenshot.png
183
184
  - lib/torrent_search.rb
184
185
  - lib/torrent_search/cli.rb
186
+ - lib/torrent_search/controllers/download.rb
187
+ - lib/torrent_search/controllers/search.rb
185
188
  - lib/torrent_search/default_command.rb
186
- - lib/torrent_search/download.rb
187
- - lib/torrent_search/menu.rb
188
189
  - lib/torrent_search/result_table.rb
190
+ - lib/torrent_search/services/download.rb
189
191
  - lib/torrent_search/trackers/kick_ass/kick_ass.rb
190
192
  - lib/torrent_search/trackers/kick_ass/scraper.rb
191
193
  - lib/torrent_search/trackers/kick_ass/torrent.rb
192
194
  - lib/torrent_search/version.rb
195
+ - lib/torrent_search/views/base.rb
196
+ - lib/torrent_search/views/download.rb
197
+ - lib/torrent_search/views/menu.rb
198
+ - lib/torrent_search/views/search.rb
199
+ - spec/lib/torrent_search/controllers/download_spec.rb
200
+ - spec/lib/torrent_search/controllers/search_spec.rb
201
+ - spec/lib/torrent_search/services/download_spec.rb
193
202
  - spec/lib/torrent_search/trackers/kick_ass/scraper_spec.rb
194
203
  - spec/spec_helper.rb
195
204
  - spec/support/vcr_setup.rb
@@ -219,6 +228,9 @@ signing_key:
219
228
  specification_version: 4
220
229
  summary: Search various torrent sites
221
230
  test_files:
231
+ - spec/lib/torrent_search/controllers/download_spec.rb
232
+ - spec/lib/torrent_search/controllers/search_spec.rb
233
+ - spec/lib/torrent_search/services/download_spec.rb
222
234
  - spec/lib/torrent_search/trackers/kick_ass/scraper_spec.rb
223
235
  - spec/spec_helper.rb
224
236
  - spec/support/vcr_setup.rb
@@ -1,38 +0,0 @@
1
- require "httparty"
2
-
3
- module TorrentSearch
4
- DEFAULT_DIR = '.'
5
-
6
- class Download
7
- def initialize(view, torrent)
8
- @view = view
9
- @torrent = torrent
10
- end
11
-
12
- def perform
13
- save! filename
14
- say 'Complete', :green
15
- end
16
-
17
- private
18
- def filename
19
- File.join(path, "#{@torrent.filename}.torrent")
20
- end
21
-
22
- def path
23
- path = @view.ask "Directory to save file (default '#{DEFAULT_DIR}'):"
24
- path.empty? ? DEFAULT_DIR : path
25
- end
26
-
27
- def save!(filename)
28
- say "Downloading #{@torrent.name}...", :green
29
- File.open(filename, "wb") do |file|
30
- file.write HTTParty.get(@torrent.href).parsed_response
31
- end
32
- end
33
-
34
- def say(*args)
35
- @view.say *args
36
- end
37
- end
38
- end
@@ -1,80 +0,0 @@
1
- module TorrentSearch
2
-
3
- ACTIONS = {
4
- d: :download,
5
- s: :search,
6
- q: :quit
7
- }
8
-
9
- class Menu < SimpleDelegator
10
- def initialize(view, search_result)
11
- @view = view
12
- @search_result = search_result
13
- super @view
14
- end
15
-
16
- def display
17
- say_status "\n[Results]", '', :green
18
- if results?
19
- print_table result_table
20
- else
21
- say 'Nothing found'
22
- end
23
- say_status "\n[Actions]", actions, :blue
24
- choose_action!
25
- end
26
-
27
- private
28
- def results?
29
- @search_result.any?
30
- end
31
-
32
- def result_table
33
- ResultTable.new(@search_result)
34
- end
35
-
36
- def available_actions
37
- ACTIONS.dup.tap {|hash| hash.delete(:d) unless results? }
38
- end
39
-
40
- def actions
41
- available_actions.map {|hash| hash.join(": ")}.join("\t")
42
- end
43
-
44
- def choose_action!
45
- chosen = ask("Choose:").to_sym
46
- send available_actions.fetch(chosen, :invalid_command)
47
- end
48
-
49
- def invalid_command
50
- say 'Invalid command', :red
51
- choose_action!
52
- end
53
-
54
- def quit
55
- CLI::quit
56
- end
57
-
58
- def search
59
- super ask("Search for:").split
60
- end
61
-
62
- def download
63
- index = ask("Torrent (0-#{search_result_range.max}):")
64
- unless index.match(/\A\d+\z/) && is_in_search_result?(index)
65
- say 'Invalid option', :red
66
- download
67
- end
68
- torrent = @search_result[index.to_i]
69
- Download.new(@view, torrent).perform
70
- end
71
-
72
- def is_in_search_result?(index)
73
- search_result_range.member?(index.to_i)
74
- end
75
-
76
- def search_result_range
77
- @range ||= Range.new(0, @search_result.length, true)
78
- end
79
- end
80
- end