nyaa 0.3.0 → 1.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.
- data/.gitignore +3 -0
- data/Gemfile +2 -1
- data/README.md +31 -11
- data/Rakefile +7 -4
- data/bin/nyaa +70 -41
- data/lib/nyaa.rb +26 -3
- data/lib/nyaa/browser.rb +122 -163
- data/lib/nyaa/cli.rb +75 -0
- data/lib/nyaa/constants.rb +124 -0
- data/lib/nyaa/downloader.rb +65 -0
- data/lib/nyaa/search.rb +113 -0
- data/lib/nyaa/torrent.rb +65 -0
- data/lib/nyaa/ui.rb +260 -0
- data/lib/nyaa/version.rb +2 -1
- data/nyaa.gemspec +1 -3
- data/screenshots/v1.0.0_browse.png +0 -0
- data/screenshots/v1.0.0_help.png +0 -0
- data/screenshots/v1.0.0_search.png +0 -0
- metadata +14 -32
- data/.gitattributes +0 -1
- data/.travis.yml +0 -5
- data/AUTHORS +0 -4
- data/Gemfile.lock +0 -24
- data/HACKING +0 -13
- data/test/lib/nyaa/browser_test.rb +0 -4
- data/test/lib/nyaa/version_test.rb +0 -7
- data/test/test_helper.rb +0 -2
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,29 +1,49 @@
|
|
1
1
|
# Nyaa
|
2
2
|
|
3
|
-
Nyaa is a CLI to
|
3
|
+
Nyaa is a CLI to Nyaa.eu. You can browse, search, and download. Nifty.
|
4
|
+
|
5
|
+
## Features
|
6
|
+
|
7
|
+
* Ncurses interface
|
8
|
+
* Search by category, filter, page, and query
|
9
|
+
* Browsing with pagination
|
10
|
+
* Download it or open a browser window from the interface
|
11
|
+
* Nyaa status aware: (aplus, trusted, remake, etc.)
|
12
|
+
* Batch mode for scripts (first page only atm)
|
13
|
+
* Supports unicode characters (requires `libncursesw5-dev` and `ruby1.9`)
|
4
14
|
|
5
15
|
## Installation
|
6
16
|
|
17
|
+
Stable release:
|
18
|
+
|
7
19
|
gem install nyaa
|
8
20
|
|
9
|
-
|
21
|
+
Development release:
|
10
22
|
|
11
|
-
|
23
|
+
git clone git://github.com/mistofvongola/nyaa.git
|
12
24
|
|
13
|
-
|
25
|
+
## Browser Usage
|
26
|
+
|
27
|
+
To browse, simply run `nyaa`. The default category is english anime.
|
14
28
|
|
15
|
-
|
29
|
+

|
16
30
|
|
17
|
-
|
31
|
+
Nyaa supports all the aspects of search of the main site. You can search by category and/or filters. To download an item, highlight it, and type `g`. To open the description page in a browser, type `i`. A sample query:
|
18
32
|
|
19
|
-
|
33
|
+
nyaa -f trusted_only psycho pass
|
34
|
+

|
20
35
|
|
21
36
|
For a list of categories and filters, see `nyaa -h`.
|
22
37
|
|
23
|
-

|
39
|
+
|
40
|
+
## The old interface
|
41
|
+
|
42
|
+
The old nyaa interface is deprecated, but is still included. You can use the old interface using the `--classic` option.
|
43
|
+
|
44
|
+

|
24
45
|
|
25
46
|
## Contributing
|
26
|
-
0. See HACKING file for style guidelines
|
27
47
|
1. Fork it
|
28
48
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
29
49
|
3. Commit your changes (`git commit -am 'Added some feature'`)
|
@@ -32,8 +52,8 @@ For a list of categories and filters, see `nyaa -h`.
|
|
32
52
|
|
33
53
|
## License
|
34
54
|
|
35
|
-
See LICENSE file.
|
55
|
+
MIT License. See LICENSE file for details.
|
36
56
|
|
37
57
|
## Authors
|
38
58
|
|
39
|
-
|
59
|
+
David Palma
|
data/Rakefile
CHANGED
@@ -6,7 +6,7 @@ task :default => :test
|
|
6
6
|
|
7
7
|
Rake::TestTask.new do |t|
|
8
8
|
t.libs << 'lib/nyaa'
|
9
|
-
t.test_files = FileList['
|
9
|
+
t.test_files = FileList['spec/lib/nyaa/*_spec.rb']
|
10
10
|
t.verbose = true
|
11
11
|
end
|
12
12
|
|
@@ -17,19 +17,22 @@ task :gemspec do
|
|
17
17
|
gemspec.validate
|
18
18
|
end
|
19
19
|
|
20
|
-
desc "Build gem locally"
|
21
20
|
task :build => :gemspec do
|
22
21
|
system "gem build #{gemspec.name}.gemspec"
|
23
22
|
FileUtils.mkdir_p "pkg"
|
24
23
|
FileUtils.mv "#{gemspec.name}-#{gemspec.version}.gem", "pkg"
|
25
24
|
end
|
26
25
|
|
27
|
-
desc "Install gem locally"
|
28
26
|
task :install => :build do
|
29
27
|
system "gem install pkg/#{gemspec.name}-#{gemspec.version}"
|
30
28
|
end
|
31
29
|
|
32
|
-
desc "
|
30
|
+
desc "Purge the pkg directory"
|
33
31
|
task :clean do
|
34
32
|
FileUtils.rm_rf "pkg"
|
35
33
|
end
|
34
|
+
|
35
|
+
desc "Publish gem to rubygems.org"
|
36
|
+
task :publish do
|
37
|
+
system "gem push pkg/#{gemspec.name}-#{gemspec.version}.gem"
|
38
|
+
end
|
data/bin/nyaa
CHANGED
@@ -1,49 +1,78 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
|
4
|
+
|
3
5
|
require 'nyaa'
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
live_all, live_raw, live_english, live_nonenglish, live_promo
|
19
|
-
software_all, software_apps, software_games
|
20
|
-
|
21
|
-
Filters:
|
22
|
-
show_all, filter_remakes, trusted_only, aplus_only
|
23
|
-
|
24
|
-
Options:
|
25
|
-
EOM
|
26
|
-
opt :category, "Select a category to search in. See below for valid options.", :default => 'anime_english'
|
27
|
-
opt :filter, "Select a filter for your search. See below for valid options.", :default => 'show_all'
|
28
|
-
opt :outdir, "Select the download directory.", :default => File.expand_path('~/Downloads')
|
29
|
-
opt :size, "Show <i> results at a time. Must be between 1 and 100.", :type => :int, :default => 4
|
30
|
-
opt :page, "Start by showing the <i>th result page.", :type => :int, :default => 1
|
31
|
-
opt :version, "Print the version and exit."
|
32
|
-
opt :help, "Show this information and exit."
|
6
|
+
include Curses
|
7
|
+
|
8
|
+
|
9
|
+
@opts = Nyaa::CLI.parse(ARGV)
|
10
|
+
@search = Nyaa::Search.new(@opts[:query], @opts[:category], @opts[:filter])
|
11
|
+
|
12
|
+
def batch_mode
|
13
|
+
results = @search.more.get_results
|
14
|
+
results.each do |r|
|
15
|
+
puts "o #{r.name}"
|
16
|
+
puts "#{r.link}"
|
17
|
+
puts
|
18
|
+
end
|
19
|
+
exit
|
33
20
|
end
|
34
21
|
|
35
|
-
|
36
|
-
|
22
|
+
def browser_mode
|
23
|
+
begin
|
24
|
+
nyaa = Nyaa::Browser.new(@opts, @search)
|
25
|
+
rescue Interrupt
|
26
|
+
puts "\nInterrupt received. Exiting."
|
27
|
+
exit
|
28
|
+
end
|
37
29
|
end
|
38
|
-
|
39
|
-
|
30
|
+
|
31
|
+
def curses_mode
|
32
|
+
begin
|
33
|
+
yield
|
34
|
+
ensure
|
35
|
+
nocbreak
|
36
|
+
close_screen
|
37
|
+
end
|
40
38
|
end
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
n.search
|
46
|
-
rescue Interrupt
|
47
|
-
puts "\nInterrupt received. Exiting."
|
48
|
-
exit
|
39
|
+
|
40
|
+
# Batch mode
|
41
|
+
if @opts[:batch]
|
42
|
+
batch_mode
|
49
43
|
end
|
44
|
+
|
45
|
+
if @opts[:classic] # use old interface
|
46
|
+
browser_mode
|
47
|
+
else
|
48
|
+
nyaa = Nyaa::UI.new(@opts, @search)
|
49
|
+
cursor = 1
|
50
|
+
|
51
|
+
curses_mode do
|
52
|
+
#TODO: Gracefully handle window resizing
|
53
|
+
#Signal.trap('SIGWINCH', nyaa.status("Window size changed!", :failure))
|
54
|
+
loop do
|
55
|
+
nyaa.header
|
56
|
+
nyaa.status
|
57
|
+
nyaa.footer
|
58
|
+
nyaa.menu(cursor)
|
59
|
+
refresh
|
60
|
+
|
61
|
+
case getch
|
62
|
+
when Key::UP then cursor = nyaa.move(cursor, -1)
|
63
|
+
when Key::DOWN then cursor = nyaa.move(cursor, 1)
|
64
|
+
when 'k' then cursor = nyaa.move(cursor, -1)
|
65
|
+
when 'j' then cursor = nyaa.move(cursor, 1)
|
66
|
+
when '?' then nyaa.status('help not implemented!', :failure)
|
67
|
+
when 'g' then nyaa.get(cursor)
|
68
|
+
when 'i' then nyaa.open(cursor)
|
69
|
+
when 'n' then nyaa.next_page
|
70
|
+
when 'p' then nyaa.prev_page
|
71
|
+
when 'q' then @search.purge && break
|
72
|
+
#when Key::RESIZE then nyaa.status("Window size changed!", :failure)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
exit
|
data/lib/nyaa.rb
CHANGED
@@ -1,5 +1,28 @@
|
|
1
|
-
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
$:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
|
3
|
+
# stdlib
|
4
|
+
require 'optparse'
|
5
|
+
require 'open-uri'
|
6
|
+
require 'curses'
|
2
7
|
|
3
|
-
|
4
|
-
|
8
|
+
# third party
|
9
|
+
begin
|
10
|
+
require 'rubygems' # for ruby 1.8 compat
|
11
|
+
require 'nokogiri'
|
12
|
+
require 'rest_client'
|
13
|
+
require 'formatador'
|
14
|
+
rescue LoadError => e
|
15
|
+
puts "LoadError: #{e.message}"
|
5
16
|
end
|
17
|
+
|
18
|
+
# internal api
|
19
|
+
require 'nyaa/version'
|
20
|
+
require 'nyaa/cli'
|
21
|
+
require 'nyaa/constants'
|
22
|
+
require 'nyaa/torrent'
|
23
|
+
require 'nyaa/search'
|
24
|
+
|
25
|
+
# internal tools
|
26
|
+
require 'nyaa/browser' # old ui
|
27
|
+
require 'nyaa/ui' # new ui
|
28
|
+
require 'nyaa/downloader'
|
data/lib/nyaa/browser.rb
CHANGED
@@ -1,161 +1,98 @@
|
|
1
|
-
|
2
|
-
require 'rest_client'
|
3
|
-
require 'formatador'
|
4
|
-
require 'uri'
|
5
|
-
|
1
|
+
# -*- encoding : utf-8 -*-
|
6
2
|
module Nyaa
|
7
3
|
class Browser
|
8
|
-
|
9
|
-
PSIZE = 100
|
10
|
-
CATS = {
|
11
|
-
'anime_all' => '1_0',
|
12
|
-
'anime_raw' => '1_11',
|
13
|
-
'anime_english' => '1_37',
|
14
|
-
'anime_nonenglish' => '1_38',
|
15
|
-
'anime_music_video' => '1_32',
|
16
|
-
'books_all' => '2_0',
|
17
|
-
'books_raw' => '2_13',
|
18
|
-
'books_english' => '2_12',
|
19
|
-
'books_nonenglish' => '2_39',
|
20
|
-
'audio_all' => '3_0',
|
21
|
-
'audio_lossless' => '3_14',
|
22
|
-
'audio_lossy' => '3_15',
|
23
|
-
'pictures_all' => '4_0',
|
24
|
-
'pictures_photos' => '4_17',
|
25
|
-
'pictures_graphics' => '4_18',
|
26
|
-
'live_all' => '5_0',
|
27
|
-
'live_raw' => '5_20',
|
28
|
-
'live_english' => '5_19',
|
29
|
-
'live_nonenglish' => '5_21',
|
30
|
-
'live_promo' => '5_22',
|
31
|
-
'software_all' => '6_0',
|
32
|
-
'software_apps' => '6_23',
|
33
|
-
'software_games' => '6_24',
|
34
|
-
}
|
35
|
-
FILS = {
|
36
|
-
'show_all' => '0',
|
37
|
-
'filter_remakes' => '1',
|
38
|
-
'trusted_only' => '2',
|
39
|
-
'aplus_only' => '3',
|
40
|
-
}
|
41
|
-
|
42
|
-
def initialize(query, opts)
|
43
|
-
@query = URI.escape(query)
|
4
|
+
def initialize(opts, search)
|
44
5
|
@opts = opts
|
6
|
+
@opts[:size] = 4 if opts[:size].nil?
|
45
7
|
@opts[:size] = PSIZE if opts[:size] > PSIZE
|
46
8
|
@opts[:size] = 1 if opts[:size] <= 1
|
47
9
|
@marker = 0
|
10
|
+
@format = Formatador.new
|
11
|
+
@page = 0 # Current browser page
|
12
|
+
@search = search
|
13
|
+
start
|
48
14
|
end
|
49
15
|
|
50
|
-
def
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
def harvest(query, page)
|
57
|
-
url = "#{BASE_URL}"
|
58
|
-
url << "&cats=#{CATS[@opts[:category]]}" if @opts[:category]
|
59
|
-
url << "&filter=#{FILS[@opts[:filter]]}" if @opts[:filter]
|
60
|
-
url << "&offset=#{page}" if @opts[:page]
|
61
|
-
url << "&term=#{query}" unless @query.empty?
|
62
|
-
doc = Nokogiri::HTML(RestClient.get(url))
|
63
|
-
items = []
|
64
|
-
rows = doc.css('div#main div.content table.tlist tr.tlistrow')
|
65
|
-
#puts "DEBUG: Row: #{rows[0].to_s}"
|
66
|
-
rows.each do |row|
|
67
|
-
items << {
|
68
|
-
:cat => row.css('td.tlisticon').at('a')['title'],
|
69
|
-
:name => row.css('td.tlistname').at('a').text.strip,
|
70
|
-
:dl => row.css('td.tlistdownload').at('a')['href'],
|
71
|
-
:size => row.css('td.tlistsize').text,
|
72
|
-
:se => row.css('td.tlistsn').text,
|
73
|
-
:le => row.css('td.tlistln').text,
|
74
|
-
:dls => row.css('td.tlistdn').text,
|
75
|
-
:msg => row.css('td.tlistmn').text,
|
76
|
-
# TODO: The status hashkey is broken
|
77
|
-
:status =>
|
78
|
-
if row.at('tr.trusted')
|
79
|
-
'trusted'
|
80
|
-
elsif row.at('tr.remake')
|
81
|
-
'remake'
|
82
|
-
elsif row.at('tr.aplus')
|
83
|
-
'aplus'
|
84
|
-
else
|
85
|
-
'normal'
|
86
|
-
end
|
87
|
-
}
|
88
|
-
end
|
89
|
-
items
|
16
|
+
def start
|
17
|
+
#@search = Search.new(@opts[:query], @opts[:category], @opts[:filter])
|
18
|
+
page_results = @search.more.get_results
|
19
|
+
@page += 1
|
20
|
+
part = partition(page_results, 0, @opts[:size])
|
21
|
+
screen(page_results, part)
|
90
22
|
end
|
91
23
|
|
92
24
|
def partition(ary, start, size)
|
93
25
|
start = 0 if start < 0
|
94
|
-
# update marker
|
95
26
|
@marker = start
|
96
27
|
size = PSIZE if size > PSIZE
|
97
|
-
|
98
28
|
part = ary[start, size]
|
29
|
+
part = [] if part.nil?
|
99
30
|
part
|
100
31
|
end
|
101
32
|
|
102
|
-
def
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
f.display_line( "[normal]No matches found. "\
|
109
|
-
"Try another category. See --help.[/]\n")
|
110
|
-
f.display_line("\t[yellow]Exiting.[/]")
|
111
|
-
exit
|
112
|
-
end
|
113
|
-
f.display_line( "[bold]#{data[0][:cat]}\n[/]" )
|
114
|
-
|
115
|
-
results.each do |item|
|
116
|
-
case item[:status]
|
117
|
-
when 'aplus'
|
118
|
-
flag = 'blue'
|
119
|
-
when 'trusted'
|
120
|
-
flag = 'green'
|
121
|
-
when 'remake'
|
122
|
-
flag = 'red'
|
123
|
-
else
|
124
|
-
flag = 'normal'
|
125
|
-
end
|
126
|
-
f.display_line( "[#{flag}]#{data.index(item)+1}. #{item[:name]}[/]")
|
127
|
-
|
128
|
-
f.indent {
|
129
|
-
f.display_line( "[bold]Size: [purple]#{item[:size]}[/] "\
|
130
|
-
"[bold]SE: [green]#{item[:se]}[/] "\
|
131
|
-
"[bold]LE: [red]#{item[:le]}[/] "\
|
132
|
-
"[bold]DLs: [yellow]#{item[:dls]}[/] "\
|
133
|
-
"[bold]Msg: [blue]#{item[:msg]}[/]" )
|
134
|
-
f.display_line( "[green]#{item[:dl]}[/]" )
|
135
|
-
}
|
33
|
+
def torrent_info(page_results, torrent)
|
34
|
+
case torrent.status
|
35
|
+
when 'A+' then flag = 'blue'
|
36
|
+
when 'Trusted' then flag = 'green'
|
37
|
+
when 'Remake' then flag = 'red'
|
38
|
+
else flag = 'yellow'
|
136
39
|
end
|
137
40
|
|
41
|
+
@format.display_line("#{page_results.index(torrent)+1}. "\
|
42
|
+
"#{torrent.name[0..70]}[/]")
|
43
|
+
@format.indent {
|
44
|
+
@format.display_line(
|
45
|
+
"[bold]Size: [purple]#{torrent.filesize}[/] "\
|
46
|
+
"[bold]SE: [green]#{torrent.seeders}[/] "\
|
47
|
+
"[bold]LE: [red]#{torrent.leechers}[/] "\
|
48
|
+
"[bold]DLs: [yellow]#{torrent.downloads}[/] "\
|
49
|
+
"[bold]Msg: [blue]#{torrent.comments}[/]")
|
50
|
+
@format.display_line("[bold]DL:[/] [#{flag}]#{torrent.link}[/]")
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
def header_info
|
55
|
+
@format.display_line( "\t[yellow]NyaaTorrents >> "\
|
56
|
+
"Browse | Anime, manga, and music[/]\n" )
|
57
|
+
@format.display_line(
|
58
|
+
"[bold]#{CATS[@opts[:category].to_sym][:title]}\n[/]" )
|
59
|
+
end
|
60
|
+
|
61
|
+
def footer_info
|
138
62
|
start_count = @marker + 1
|
139
63
|
start_count = PSIZE if start_count > PSIZE
|
140
64
|
end_count = @marker + @opts[:size]
|
141
65
|
end_count = PSIZE if end_count > PSIZE
|
142
66
|
|
143
|
-
|
67
|
+
@format.display_line("\n\t[yellow]Displaying results "\
|
144
68
|
"#{start_count} through #{end_count} of #{PSIZE} "\
|
145
|
-
"
|
69
|
+
"(Page ##{@page})\n")
|
70
|
+
end
|
71
|
+
|
72
|
+
def screen(page_results, screen_items)
|
73
|
+
header_info
|
74
|
+
|
75
|
+
if screen_items.empty?
|
76
|
+
@format.display_line( "[normal]End of results.")
|
77
|
+
@format.display_line("For more search options, see --help.[/]\n")
|
78
|
+
exit
|
79
|
+
end
|
80
|
+
|
81
|
+
screen_items.each do |torrent|
|
82
|
+
torrent_info(page_results, torrent)
|
83
|
+
end
|
146
84
|
|
147
|
-
|
85
|
+
footer_info
|
86
|
+
prompt(page_results, screen_items)
|
148
87
|
end
|
149
88
|
|
150
|
-
def prompt(
|
151
|
-
|
152
|
-
|
89
|
+
def prompt(page_results, screen_items)
|
90
|
+
@format.display_line("[yellow]Help: q to quit, "\
|
91
|
+
"h for display help, "\
|
153
92
|
"n/p for pagination, "\
|
154
93
|
"or a number to download that choice.")
|
155
|
-
|
156
|
-
f.display("[bold]>[/] ")
|
94
|
+
@format.display("[bold]>[/] ")
|
157
95
|
|
158
|
-
# handle input
|
159
96
|
choice = STDIN.gets
|
160
97
|
if choice.nil?
|
161
98
|
choice = ' '
|
@@ -164,48 +101,70 @@ module Nyaa
|
|
164
101
|
end
|
165
102
|
|
166
103
|
case
|
167
|
-
when choice[0] == 'q'
|
168
|
-
|
169
|
-
when choice[0] == '
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
when choice[0] == 'p'
|
181
|
-
if @marker < 1
|
182
|
-
f.indent { f.display_line("[purple]! Already at page one.[/]") }
|
183
|
-
input(data, results)
|
184
|
-
else
|
185
|
-
part = partition(data, @marker - @opts[:size], @opts[:size])
|
186
|
-
display(data, part)
|
187
|
-
end
|
188
|
-
when choice[0].match(/\d/)
|
189
|
-
/(\d+)(\s*\|(.*))*/.match(choice) do |str|
|
190
|
-
num = str[1].to_i - 1
|
191
|
-
download(data[num][:dl], @opts[:outdir])
|
192
|
-
end
|
104
|
+
when choice[0] == 'q' then @search.purge && exit
|
105
|
+
when choice[0] == 'n' then paginate(page_results)
|
106
|
+
when choice[0] == 'p' then reverse_paginate(page_results, screen_items)
|
107
|
+
when choice[0].match(/\d/) then retrieve(choice, page_results, screen_items)
|
108
|
+
when choice[0] == 'h'
|
109
|
+
@format.display_line("[normal]The color of an entry's DL link "\
|
110
|
+
"represents its status:[/]")
|
111
|
+
@format.display_line("[blue]A+[/], [green]Trusted[/], "\
|
112
|
+
"[yellow]Normal[/], or [red]Remake[/]")
|
113
|
+
prompt(page_results, screen_items)
|
114
|
+
else
|
115
|
+
@format.display_line("[red]Unrecognized option.[/]")
|
116
|
+
prompt(page_results, screen_items)
|
193
117
|
end
|
194
118
|
end
|
195
119
|
|
196
|
-
def
|
197
|
-
|
120
|
+
def paginate(page_results)
|
121
|
+
if @marker + @opts[:size] == 100
|
122
|
+
@format.display_line("[yellow]Loading more results...[/]")
|
123
|
+
if @page == @search.offset
|
124
|
+
page_results = @search.more.get_results
|
125
|
+
else # @page < @search.offset
|
126
|
+
page_results = @search.cached(@page + 1)
|
127
|
+
end
|
128
|
+
@page += 1
|
129
|
+
part = partition(page_results, 0, @opts[:size])
|
130
|
+
else
|
131
|
+
part = partition(page_results, @marker + @opts[:size], @opts[:size])
|
132
|
+
end
|
133
|
+
screen(page_results, part)
|
134
|
+
end
|
198
135
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
136
|
+
def reverse_paginate(page_results, screen_items)
|
137
|
+
if @marker < 1
|
138
|
+
if @page == 1
|
139
|
+
@format.display_line("[red]Already at page one.[/]")
|
140
|
+
prompt(page_results, screen_items)
|
141
|
+
else # @page > 1
|
142
|
+
@format.display_line("[yellow]Loading results...[/]")
|
143
|
+
# TODO Bug: This fails with --size 100
|
144
|
+
# TODO Bug: reverse paginate sometimes only returns p1 cache
|
145
|
+
page_results = @search.cached(@page - 1)
|
146
|
+
@page -= 1
|
147
|
+
part = partition(page_results, PSIZE - @opts[:size], @opts[:size])
|
148
|
+
screen(page_results, part)
|
149
|
+
end
|
150
|
+
else
|
151
|
+
part = partition(page_results, @marker - @opts[:size], @opts[:size])
|
152
|
+
screen(page_results, part)
|
153
|
+
end
|
154
|
+
end
|
206
155
|
|
207
|
-
|
208
|
-
|
156
|
+
def retrieve(choice, page_results, screen_items)
|
157
|
+
/(\d+)(\s*\|(.*))*/.match(choice) do |str|
|
158
|
+
num = str[1].to_i - 1
|
159
|
+
download = Downloader.new(page_results[num].link, @opts[:outdir])
|
160
|
+
download.save
|
161
|
+
unless download.failed?
|
162
|
+
@format.display_line(
|
163
|
+
"[green]Downloaded '#{download.filename}' successfully.[/]")
|
164
|
+
else
|
165
|
+
@format.display_line("[red]Download failed (3 attempts).[/]")
|
166
|
+
end
|
167
|
+
prompt(page_results, screen_items)
|
209
168
|
end
|
210
169
|
end
|
211
170
|
end
|