nyaa 0.1.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitattributes +1 -0
- data/AUTHORS +4 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +24 -0
- data/HACKING +13 -0
- data/LICENSE +2 -0
- data/README.md +28 -2
- data/Rakefile +12 -2
- data/bin/nyaa +5 -4
- data/lib/nyaa.rb +3 -189
- data/lib/nyaa/browser.rb +212 -0
- data/lib/nyaa/version.rb +2 -2
- data/nyaa.gemspec +9 -7
- data/screenshots/screenshot_1.png +0 -0
- data/screenshots/screenshot_2.png +0 -0
- data/screenshots/screenshot_3.png +0 -0
- data/test/lib/nyaa/browser_test.rb +4 -0
- data/test/lib/nyaa/version_test.rb +7 -0
- data/test/test_helper.rb +2 -0
- metadata +27 -12
data/.gitattributes
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.rb diff=ruby
|
data/AUTHORS
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
nyaa (0.1.2)
|
5
|
+
formatador (~> 0.2.3)
|
6
|
+
nokogiri (~> 1.5.5)
|
7
|
+
rest-client (~> 1.6.7)
|
8
|
+
trollop (~> 1.16.2)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: http://rubygems.org/
|
12
|
+
specs:
|
13
|
+
formatador (0.2.3)
|
14
|
+
mime-types (1.19)
|
15
|
+
nokogiri (1.5.5)
|
16
|
+
rest-client (1.6.7)
|
17
|
+
mime-types (>= 1.16)
|
18
|
+
trollop (1.16.2)
|
19
|
+
|
20
|
+
PLATFORMS
|
21
|
+
ruby
|
22
|
+
|
23
|
+
DEPENDENCIES
|
24
|
+
nyaa!
|
data/HACKING
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Contributing
|
2
|
+
======================
|
3
|
+
|
4
|
+
Coding Style
|
5
|
+
------------
|
6
|
+
|
7
|
+
1. All code should be indented with spaces. This is effectively the following VIM modeline:
|
8
|
+
/* vim: set ai ts=2 sw=2 et: */
|
9
|
+
|
10
|
+
2. Recommend removing trailing whitespace. Here is an example for .vimrc
|
11
|
+
autocmd BufWritePre *.py normal m`:%s/\s\+$//e ``
|
12
|
+
|
13
|
+
3. Wrap lines at 80 characters MAXIMUM
|
data/LICENSE
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
Copyright (C) 2012 David Palma
|
2
2
|
|
3
|
+
MIT License
|
4
|
+
|
3
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
6
|
|
5
7
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# Nyaa
|
2
2
|
|
3
3
|
Nyaa is a CLI to NyaaTorrents. You can browse, search, and download. Nifty.
|
4
4
|
|
@@ -8,6 +8,32 @@ Nyaa is a CLI to NyaaTorrents. You can browse, search, and download. Nifty.
|
|
8
8
|
|
9
9
|
## Usage
|
10
10
|
|
11
|
+
To start browsing immediately, simply run `nyaa`. The default category is english anime.
|
12
|
+
|
13
|
+
![](https://github.com/mistofvongola/nyaa/raw/master/screenshots/screenshot_1.png)
|
14
|
+
|
15
|
+
Nyaa supports all the aspects of search of the main site. You can search by category and/or filters. Nyaa also shows a summary of seeders, leechers, total filesize, and number of downloads. To download an item, simply enter the number of the result.
|
16
|
+
|
17
|
+
nyaa -c anime_english -f trusted_only 'guilty crown'
|
18
|
+
|
19
|
+
![](https://github.com/mistofvongola/nyaa/raw/master/screenshots/screenshot_2.png)
|
20
|
+
|
21
|
+
For a list of categories and filters, see `nyaa -h`.
|
22
|
+
|
23
|
+
![](https://github.com/mistofvongola/nyaa/raw/master/screenshots/screenshot_3.png)
|
24
|
+
|
25
|
+
## Contributing
|
26
|
+
0. See HACKING file for style guidelines
|
27
|
+
1. Fork it
|
28
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
29
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
30
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
31
|
+
5. Create new Pull Request
|
32
|
+
|
11
33
|
## License
|
12
34
|
|
13
|
-
See LICENSE
|
35
|
+
See LICENSE file.
|
36
|
+
|
37
|
+
## Authors
|
38
|
+
|
39
|
+
See AUTHORS file.
|
data/Rakefile
CHANGED
@@ -1,10 +1,20 @@
|
|
1
|
-
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require 'bundler/gem_tasks'
|
3
|
+
require 'rake/testtask'
|
4
|
+
|
5
|
+
task :default => :test
|
6
|
+
|
7
|
+
Rake::TestTask.new do |t|
|
8
|
+
t.libs << 'lib/nyaa'
|
9
|
+
t.test_files = FileList['test/lib/nyaa/*_test.rb']
|
10
|
+
t.verbose = true
|
11
|
+
end
|
2
12
|
|
3
13
|
gemspec = eval(File.read(Dir["*.gemspec"].first))
|
4
14
|
|
5
15
|
desc "Validate the gemspec"
|
6
16
|
task :gemspec do
|
7
|
-
|
17
|
+
gemspec.validate
|
8
18
|
end
|
9
19
|
|
10
20
|
desc "Build gem locally"
|
data/bin/nyaa
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'nyaa'
|
4
|
+
require 'trollop'
|
4
5
|
|
5
6
|
opts = Trollop::options do
|
6
|
-
version "nyaa
|
7
|
+
version "nyaa v#{Nyaa::VERSION} (c) 2012 David Palma http://github.com/mistofvongola"
|
7
8
|
banner <<-EOM
|
8
9
|
The nyaa gem is a simple CLI browser for NyaaTorrents.
|
9
10
|
Usage:
|
@@ -31,16 +32,16 @@ Options:
|
|
31
32
|
opt :help, "Show this information and exit."
|
32
33
|
end
|
33
34
|
|
34
|
-
unless Nyaa::CATS.has_key?(opts[:category])
|
35
|
+
unless Nyaa::Browser::CATS.has_key?(opts[:category])
|
35
36
|
Trollop::die :category, "is not a valid category"
|
36
37
|
end
|
37
|
-
unless Nyaa::FILS.has_key?(opts[:filter])
|
38
|
+
unless Nyaa::Browser::FILS.has_key?(opts[:filter])
|
38
39
|
Trollop::die :filter, "is not a valid filter"
|
39
40
|
end
|
40
41
|
query = ARGV.join(' ')
|
41
42
|
|
42
43
|
begin
|
43
|
-
n = Nyaa.new query, opts
|
44
|
+
n = Nyaa::Browser.new query, opts
|
44
45
|
n.search
|
45
46
|
rescue Interrupt
|
46
47
|
puts "\nInterrupt received. Exiting."
|
data/lib/nyaa.rb
CHANGED
@@ -1,191 +1,5 @@
|
|
1
|
-
|
1
|
+
require 'nyaa/version'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
require 'trollop'
|
6
|
-
require 'formatador'
|
7
|
-
require 'uri'
|
8
|
-
|
9
|
-
class Nyaa
|
10
|
-
BASE_URL = 'http://www.nyaa.eu/?page=torrents'
|
11
|
-
PSIZE = 100
|
12
|
-
CATS = {
|
13
|
-
'anime_all' => '1_0',
|
14
|
-
'anime_raw' => '1_11',
|
15
|
-
'anime_english' => '1_37',
|
16
|
-
'anime_nonenglish' => '1_38',
|
17
|
-
'anime_music_video' => '1_32',
|
18
|
-
'books_all' => '2_0',
|
19
|
-
'books_raw' => '2_13',
|
20
|
-
'books_english' => '2_12',
|
21
|
-
'books_nonenglish' => '2_39',
|
22
|
-
'audio_all' => '3_0',
|
23
|
-
'audio_lossless' => '3_14',
|
24
|
-
'audio_lossy' => '3_15',
|
25
|
-
'pictures_all' => '4_0',
|
26
|
-
'pictures_photos' => '4_17',
|
27
|
-
'pictures_graphics' => '4_18',
|
28
|
-
'live_all' => '5_0',
|
29
|
-
'live_raw' => '5_20',
|
30
|
-
'live_english' => '5_19',
|
31
|
-
'live_nonenglish' => '5_21',
|
32
|
-
'live_promo' => '5_22',
|
33
|
-
'software_all' => '6_0',
|
34
|
-
'software_apps' => '6_23',
|
35
|
-
'software_games' => '6_24',
|
36
|
-
}
|
37
|
-
FILS = {
|
38
|
-
'show_all' => '0',
|
39
|
-
'filter_remakes' => '1',
|
40
|
-
'trusted_only' => '2',
|
41
|
-
'aplus_only' => '3',
|
42
|
-
}
|
43
|
-
|
44
|
-
def initialize(query, opts)
|
45
|
-
@query = URI.escape(query)
|
46
|
-
@opts = opts
|
47
|
-
@opts[:size] = PSIZE if opts[:size] > PSIZE
|
48
|
-
@opts[:size] = 1 if opts[:size] <= 1
|
49
|
-
@marker = 0
|
50
|
-
end
|
51
|
-
|
52
|
-
def search
|
53
|
-
data = harvest(@query, @opts[:page])
|
54
|
-
part = partition(data, 0, @opts[:size])
|
55
|
-
display(data, part)
|
56
|
-
end
|
57
|
-
|
58
|
-
def harvest(query, page)
|
59
|
-
url = "#{BASE_URL}"
|
60
|
-
url << "&cats=#{CATS[@opts[:category]]}" if @opts[:category]
|
61
|
-
url << "&filter=#{FILS[@opts[:filter]]}" if @opts[:filter]
|
62
|
-
url << "&offset=#{page}" if @opts[:page]
|
63
|
-
url << "&term=#{query}" unless @query.empty?
|
64
|
-
doc = Nokogiri::HTML(RestClient.get(url))
|
65
|
-
items = []
|
66
|
-
rows = doc.css('div#main div.content table.tlist tr.tlistrow')
|
67
|
-
#puts "DEBUG: Row: #{rows[0].to_s}"
|
68
|
-
rows.each do |row|
|
69
|
-
items << {
|
70
|
-
:cat => row.css('td.tlisticon').at('a')['title'],
|
71
|
-
:name => row.css('td.tlistname').at('a').text.strip,
|
72
|
-
:dl => row.css('td.tlistdownload').at('a')['href'],
|
73
|
-
:size => row.css('td.tlistsize').text,
|
74
|
-
:se => row.css('td.tlistsn').text,
|
75
|
-
:le => row.css('td.tlistln').text,
|
76
|
-
:dls => row.css('td.tlistdn').text,
|
77
|
-
:msg => row.css('td.tlistmn').text,
|
78
|
-
# TODO: The status hashkey is broken
|
79
|
-
:status =>
|
80
|
-
if row.at('tr.trusted')
|
81
|
-
'trusted'
|
82
|
-
elsif row.at('tr.remake')
|
83
|
-
'remake'
|
84
|
-
elsif row.at('tr.aplus')
|
85
|
-
'aplus'
|
86
|
-
else
|
87
|
-
'normal'
|
88
|
-
end
|
89
|
-
}
|
90
|
-
end
|
91
|
-
items
|
92
|
-
end
|
93
|
-
|
94
|
-
def partition(ary, start, size)
|
95
|
-
start = 0 if start < 0
|
96
|
-
# update marker
|
97
|
-
@marker = start
|
98
|
-
size = PSIZE if size > PSIZE
|
99
|
-
|
100
|
-
part = ary[start, size]
|
101
|
-
part
|
102
|
-
end
|
103
|
-
|
104
|
-
def display(data, results)
|
105
|
-
f = Formatador.new
|
106
|
-
f.display_line( "\t[yellow]NyaaTorrents >> Browse | Anime, manga, and music[/]\n" )
|
107
|
-
|
108
|
-
if data[0].nil? || results[0].nil?
|
109
|
-
f.display_line( "[normal]No matches found. 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]}[/] [bold]SE: [green]#{item[:se]}[/] [bold]LE: [red]#{item[:le]}[/] [bold]DLs: [yellow]#{item[:dls]}[/] [bold]Msg: [blue]#{item[:msg]}[/]" )
|
130
|
-
f.display_line( "[green]#{item[:dl]}[/]" )
|
131
|
-
}
|
132
|
-
end
|
133
|
-
|
134
|
-
start_count = @marker + 1
|
135
|
-
start_count = PSIZE if start_count > PSIZE
|
136
|
-
end_count = @marker + @opts[:size]
|
137
|
-
end_count = PSIZE if end_count > PSIZE
|
138
|
-
|
139
|
-
f.display_line("\n\t[yellow]Displaying results #{start_count} through #{end_count} of #{PSIZE} (Page #{@opts[:page]})\n")
|
140
|
-
|
141
|
-
prompt(data, results)
|
142
|
-
end
|
143
|
-
|
144
|
-
def prompt(data, results)
|
145
|
-
f = Formatador.new
|
146
|
-
f.display_line("[yellow]Help: q to quit, n/p for pagination, or a number to download that choice.")
|
147
|
-
# prompt
|
148
|
-
f.display("[bold]>[/] ")
|
149
|
-
|
150
|
-
# handle input
|
151
|
-
choice = STDIN.gets
|
152
|
-
if choice.nil?
|
153
|
-
choice = ' '
|
154
|
-
else
|
155
|
-
choice.strip
|
156
|
-
end
|
157
|
-
|
158
|
-
case
|
159
|
-
when choice[0] == 'q'
|
160
|
-
exit
|
161
|
-
when choice[0] == 'n'
|
162
|
-
if @marker + @opts[:size] == 100
|
163
|
-
@opts[:page] += 1
|
164
|
-
f.indent { f.display_line("[purple][blink_fast]! Loading more results...[/]") }
|
165
|
-
data = harvest(@query, @opts[:page])
|
166
|
-
part = partition(data, 0, @opts[:size])
|
167
|
-
else
|
168
|
-
part = partition(data, @marker + @opts[:size], @opts[:size])
|
169
|
-
end
|
170
|
-
display(data, part)
|
171
|
-
when choice[0] == 'p'
|
172
|
-
if @marker < 1
|
173
|
-
f.indent { f.display_line("[purple]! Already at page one.[/]") }
|
174
|
-
input(data, results)
|
175
|
-
else
|
176
|
-
part = partition(data, @marker - @opts[:size], @opts[:size])
|
177
|
-
display(data, part)
|
178
|
-
end
|
179
|
-
when choice[0].match(/\d/)
|
180
|
-
/(\d+)(\s*\|(.*))*/.match(choice) do |str|
|
181
|
-
num = str[1].to_i - 1
|
182
|
-
download(data[num][:dl], @opts[:outdir])
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
def download(url, output_path)
|
188
|
-
get_cmd = "curl -J -O '#{url}'"
|
189
|
-
`cd #{output_path} && #{get_cmd}`
|
190
|
-
end
|
3
|
+
module Nyaa
|
4
|
+
autoload :Browser, 'nyaa/browser'
|
191
5
|
end
|
data/lib/nyaa/browser.rb
ADDED
@@ -0,0 +1,212 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'rest_client'
|
3
|
+
require 'formatador'
|
4
|
+
require 'uri'
|
5
|
+
|
6
|
+
module Nyaa
|
7
|
+
class Browser
|
8
|
+
BASE_URL = 'http://www.nyaa.eu/?page=torrents'
|
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)
|
44
|
+
@opts = opts
|
45
|
+
@opts[:size] = PSIZE if opts[:size] > PSIZE
|
46
|
+
@opts[:size] = 1 if opts[:size] <= 1
|
47
|
+
@marker = 0
|
48
|
+
end
|
49
|
+
|
50
|
+
def search
|
51
|
+
data = harvest(@query, @opts[:page])
|
52
|
+
part = partition(data, 0, @opts[:size])
|
53
|
+
display(data, part)
|
54
|
+
end
|
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
|
90
|
+
end
|
91
|
+
|
92
|
+
def partition(ary, start, size)
|
93
|
+
start = 0 if start < 0
|
94
|
+
# update marker
|
95
|
+
@marker = start
|
96
|
+
size = PSIZE if size > PSIZE
|
97
|
+
|
98
|
+
part = ary[start, size]
|
99
|
+
part
|
100
|
+
end
|
101
|
+
|
102
|
+
def display(data, results)
|
103
|
+
f = Formatador.new
|
104
|
+
f.display_line( "\t[yellow]NyaaTorrents >> "\
|
105
|
+
"Browse | Anime, manga, and music[/]\n" )
|
106
|
+
|
107
|
+
if data[0].nil? || results[0].nil?
|
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
|
+
}
|
136
|
+
end
|
137
|
+
|
138
|
+
start_count = @marker + 1
|
139
|
+
start_count = PSIZE if start_count > PSIZE
|
140
|
+
end_count = @marker + @opts[:size]
|
141
|
+
end_count = PSIZE if end_count > PSIZE
|
142
|
+
|
143
|
+
f.display_line("\n\t[yellow]Displaying results "\
|
144
|
+
"#{start_count} through #{end_count} of #{PSIZE} "\
|
145
|
+
"#(Page #{@opts[:page]})\n")
|
146
|
+
|
147
|
+
prompt(data, results)
|
148
|
+
end
|
149
|
+
|
150
|
+
def prompt(data, results)
|
151
|
+
f = Formatador.new
|
152
|
+
f.display_line("[yellow]Help: q to quit, "\
|
153
|
+
"n/p for pagination, "\
|
154
|
+
"or a number to download that choice.")
|
155
|
+
# prompt
|
156
|
+
f.display("[bold]>[/] ")
|
157
|
+
|
158
|
+
# handle input
|
159
|
+
choice = STDIN.gets
|
160
|
+
if choice.nil?
|
161
|
+
choice = ' '
|
162
|
+
else
|
163
|
+
choice.strip
|
164
|
+
end
|
165
|
+
|
166
|
+
case
|
167
|
+
when choice[0] == 'q'
|
168
|
+
exit
|
169
|
+
when choice[0] == 'n'
|
170
|
+
if @marker + @opts[:size] == 100
|
171
|
+
@opts[:page] += 1
|
172
|
+
f.indent { f.display_line("[purple][blink_fast]! "\
|
173
|
+
"Loading more results...[/]") }
|
174
|
+
data = harvest(@query, @opts[:page])
|
175
|
+
part = partition(data, 0, @opts[:size])
|
176
|
+
else
|
177
|
+
part = partition(data, @marker + @opts[:size], @opts[:size])
|
178
|
+
end
|
179
|
+
display(data, part)
|
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
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def download(url, output_path)
|
197
|
+
resp = RestClient.get(url)
|
198
|
+
|
199
|
+
# Get filename from Content-Disposition header
|
200
|
+
disp_fname = resp.headers[:content_disposition].
|
201
|
+
split(/;\s+/).
|
202
|
+
select { |v| v =~ /filename\s*=/ }[0]
|
203
|
+
local_fname = /([""'])(?:(?=(\\?))\2.)*?\1/.
|
204
|
+
match(disp_fname).
|
205
|
+
to_s.gsub(/\A['"]+|['"]+\Z/, "")
|
206
|
+
|
207
|
+
File.open("#{output_path}/#{local_fname}", 'w') do
|
208
|
+
|f| f.write(resp.body)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
data/lib/nyaa/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION = '0.
|
1
|
+
module Nyaa
|
2
|
+
VERSION = '0.3.0'
|
3
3
|
end
|
data/nyaa.gemspec
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/nyaa/version', __FILE__)
|
2
3
|
|
3
4
|
Gem::Specification.new do |s|
|
4
5
|
s.name = 'nyaa'
|
@@ -10,12 +11,13 @@ Gem::Specification.new do |s|
|
|
10
11
|
s.authors = ['David Palma']
|
11
12
|
s.email = 'requiem.der.seele@gmail.com'
|
12
13
|
|
13
|
-
s.executables = ['nyaa']
|
14
14
|
s.files = `git ls-files`.split("\n")
|
15
|
-
s.
|
15
|
+
s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
16
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
17
|
+
s.require_path = ['lib']
|
16
18
|
|
17
|
-
s.add_runtime_dependency 'trollop', '
|
18
|
-
s.add_runtime_dependency 'formatador', '
|
19
|
-
s.add_runtime_dependency 'nokogiri', '
|
20
|
-
s.add_runtime_dependency 'rest-client', '
|
19
|
+
s.add_runtime_dependency 'trollop', '~> 1.16.2'
|
20
|
+
s.add_runtime_dependency 'formatador', '~> 0.2.3'
|
21
|
+
s.add_runtime_dependency 'nokogiri', '~> 1.5.5'
|
22
|
+
s.add_runtime_dependency 'rest-client', '~> 1.6.7'
|
21
23
|
end
|
Binary file
|
Binary file
|
Binary file
|
data/test/test_helper.rb
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nyaa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,14 +9,14 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-08-
|
12
|
+
date: 2012-08-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: trollop
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
21
|
version: 1.16.2
|
22
22
|
type: :runtime
|
@@ -24,7 +24,7 @@ dependencies:
|
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: 1.16.2
|
30
30
|
- !ruby/object:Gem::Dependency
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
none: false
|
34
34
|
requirements:
|
35
|
-
- -
|
35
|
+
- - ~>
|
36
36
|
- !ruby/object:Gem::Version
|
37
37
|
version: 0.2.3
|
38
38
|
type: :runtime
|
@@ -40,7 +40,7 @@ dependencies:
|
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
|
-
- -
|
43
|
+
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: 0.2.3
|
46
46
|
- !ruby/object:Gem::Dependency
|
@@ -48,7 +48,7 @@ dependencies:
|
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
49
49
|
none: false
|
50
50
|
requirements:
|
51
|
-
- -
|
51
|
+
- - ~>
|
52
52
|
- !ruby/object:Gem::Version
|
53
53
|
version: 1.5.5
|
54
54
|
type: :runtime
|
@@ -56,7 +56,7 @@ dependencies:
|
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
none: false
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: 1.5.5
|
62
62
|
- !ruby/object:Gem::Dependency
|
@@ -64,7 +64,7 @@ dependencies:
|
|
64
64
|
requirement: !ruby/object:Gem::Requirement
|
65
65
|
none: false
|
66
66
|
requirements:
|
67
|
-
- -
|
67
|
+
- - ~>
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: 1.6.7
|
70
70
|
type: :runtime
|
@@ -72,7 +72,7 @@ dependencies:
|
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
73
|
none: false
|
74
74
|
requirements:
|
75
|
-
- -
|
75
|
+
- - ~>
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: 1.6.7
|
78
78
|
description: Browse and download from NyaaTorrents from the command-line. Supports
|
@@ -83,21 +83,33 @@ executables:
|
|
83
83
|
extensions: []
|
84
84
|
extra_rdoc_files: []
|
85
85
|
files:
|
86
|
+
- .gitattributes
|
86
87
|
- .gitignore
|
87
88
|
- .travis.yml
|
89
|
+
- AUTHORS
|
90
|
+
- Gemfile
|
91
|
+
- Gemfile.lock
|
92
|
+
- HACKING
|
88
93
|
- LICENSE
|
89
94
|
- README.md
|
90
95
|
- Rakefile
|
91
96
|
- bin/nyaa
|
92
97
|
- lib/nyaa.rb
|
98
|
+
- lib/nyaa/browser.rb
|
93
99
|
- lib/nyaa/version.rb
|
94
100
|
- nyaa.gemspec
|
101
|
+
- screenshots/screenshot_1.png
|
102
|
+
- screenshots/screenshot_2.png
|
103
|
+
- screenshots/screenshot_3.png
|
104
|
+
- test/lib/nyaa/browser_test.rb
|
105
|
+
- test/lib/nyaa/version_test.rb
|
106
|
+
- test/test_helper.rb
|
95
107
|
homepage: https://github.com/mistofvongola/nyaa
|
96
108
|
licenses: []
|
97
109
|
post_install_message:
|
98
110
|
rdoc_options: []
|
99
111
|
require_paths:
|
100
|
-
- lib
|
112
|
+
- - lib
|
101
113
|
required_ruby_version: !ruby/object:Gem::Requirement
|
102
114
|
none: false
|
103
115
|
requirements:
|
@@ -116,4 +128,7 @@ rubygems_version: 1.8.23
|
|
116
128
|
signing_key:
|
117
129
|
specification_version: 3
|
118
130
|
summary: The nyaa gem is a CLI to NyaaTorrents.
|
119
|
-
test_files:
|
131
|
+
test_files:
|
132
|
+
- test/lib/nyaa/browser_test.rb
|
133
|
+
- test/lib/nyaa/version_test.rb
|
134
|
+
- test/test_helper.rb
|