xunlei 0.0.3 → 0.0.5
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/README.md +0 -10
- data/bin/xunlei +76 -11
- data/lib/xunlei/engine.rb +19 -22
- data/lib/xunlei/search.rb +8 -3
- data/lib/xunlei/version.rb +1 -1
- metadata +21 -15
data/README.md
CHANGED
@@ -13,16 +13,6 @@ so please make sure you have Google Chrome installed first.
|
|
13
13
|
It can automatically dump task file names and urls as well as browser cookies,
|
14
14
|
so that it can delegate to wget to download files for you.
|
15
15
|
|
16
|
-
It can handle both normal tasks and BT tasks, and won't complain even if you
|
17
|
-
have pages and pages of tasks on http://lixian.vip.xunlei.com
|
18
|
-
|
19
|
-
And since it uses wget -c option,
|
20
|
-
you don't need to worry about interrupted downloads
|
21
|
-
or completely downloaded files been overwritten any more.
|
22
|
-
|
23
|
-
Oh, did I mention it also handles Chinese/Japanese/Korean characters
|
24
|
-
in file names without any problems?
|
25
|
-
|
26
16
|
WARNING:
|
27
17
|
it stores your USERNAME and PASSWORD for
|
28
18
|
lixian.vip.xunlei.com as PLAINTEXT at ~/.xunlei/credentials.yml
|
data/bin/xunlei
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require "xunlei"
|
4
|
+
# require File.expand_path("lib/xunlei/version.rb")
|
5
|
+
# require File.expand_path("lib/xunlei/engine.rb")
|
4
6
|
require "yaml"
|
5
7
|
require "commander/import"
|
6
8
|
|
@@ -44,6 +46,12 @@ def do_dump_cookies(c)
|
|
44
46
|
end
|
45
47
|
end
|
46
48
|
|
49
|
+
def all_downloaded_tasks
|
50
|
+
system("touch #{xunlei_downloaded_tasks_path}")
|
51
|
+
|
52
|
+
YAML.load_file(xunlei_downloaded_tasks_path) || []
|
53
|
+
end
|
54
|
+
|
47
55
|
def xunlei_cookies_path
|
48
56
|
File.join(xunlei_folder_path, "cookies.txt")
|
49
57
|
end
|
@@ -56,6 +64,10 @@ def xunlei_credential_file_path
|
|
56
64
|
File.join(xunlei_folder_path, "credentials.yml")
|
57
65
|
end
|
58
66
|
|
67
|
+
def xunlei_downloaded_tasks_path
|
68
|
+
File.join(xunlei_folder_path, "downloaded.yml")
|
69
|
+
end
|
70
|
+
|
59
71
|
def xunlei_folder_name
|
60
72
|
"~/.xunlei"
|
61
73
|
end
|
@@ -125,6 +137,45 @@ def check_for_config_files
|
|
125
137
|
check_for_credentials
|
126
138
|
end
|
127
139
|
|
140
|
+
def move_to_downloaded_file(task)
|
141
|
+
puts "#{task[:name]} successfully downloaded."
|
142
|
+
|
143
|
+
downloaded = all_downloaded_tasks
|
144
|
+
downloaded << task[:name]
|
145
|
+
File.open(xunlei_downloaded_tasks_path, "w") do |file|
|
146
|
+
file.write(downloaded.to_yaml)
|
147
|
+
end
|
148
|
+
|
149
|
+
all_tasks = YAML.load_file(xunlei_tasks_path)
|
150
|
+
all_tasks.delete(task)
|
151
|
+
File.open(xunlei_tasks_path, "w") do |file|
|
152
|
+
file.write(all_tasks.to_yaml)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def total_size(file_sizes)
|
157
|
+
total_megabytes = 0
|
158
|
+
|
159
|
+
file_sizes.each do |file_size|
|
160
|
+
if file_size =~ /G/
|
161
|
+
total_megabytes += 1000 * file_size.to_f
|
162
|
+
else
|
163
|
+
total_megabytes += file_size.to_f
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
total_megabytes
|
168
|
+
end
|
169
|
+
|
170
|
+
def show_files(files)
|
171
|
+
files.each do |file|
|
172
|
+
puts "#{file[:size]}\t#{file[:name]}"
|
173
|
+
end
|
174
|
+
|
175
|
+
puts
|
176
|
+
puts "Total: #{files.size} files, #{total_size(files.map { |file| file[:size] })} MB (estimated)"
|
177
|
+
end
|
178
|
+
|
128
179
|
command :dump_tasks do |c|
|
129
180
|
c.syntax= "dump_tasks"
|
130
181
|
c.description = "dump all files to #{xunlei_tasks_path}"
|
@@ -132,16 +183,26 @@ command :dump_tasks do |c|
|
|
132
183
|
do_dump_cookies(c) do |engine|
|
133
184
|
tasks = engine.dump_tasks
|
134
185
|
|
186
|
+
current_downloaded_tasks = all_downloaded_tasks & tasks.map { |task| task[:name] }
|
187
|
+
tasks.reject! { |task| current_downloaded_tasks.include?(task[:name]) }
|
188
|
+
|
135
189
|
File.open(xunlei_tasks_path, "w") do |file|
|
136
190
|
file.write(tasks.to_yaml)
|
137
191
|
end
|
138
192
|
|
139
193
|
puts "Successfully dumped following tasks:"
|
140
194
|
puts
|
141
|
-
tasks
|
142
|
-
|
143
|
-
end
|
195
|
+
show_files(tasks)
|
196
|
+
|
144
197
|
puts
|
198
|
+
|
199
|
+
unless current_downloaded_tasks.empty?
|
200
|
+
puts "Finished downloads: (you should delete them on website)"
|
201
|
+
puts
|
202
|
+
current_downloaded_tasks.each do |task_name|
|
203
|
+
puts task_name
|
204
|
+
end
|
205
|
+
end
|
145
206
|
end
|
146
207
|
end
|
147
208
|
|
@@ -174,8 +235,12 @@ command :download do |c|
|
|
174
235
|
|
175
236
|
if agree("\nConfirm? (yes or no)")
|
176
237
|
filter_files(options).each do |file|
|
177
|
-
cmd = "wget --load-cookies=#{xunlei_cookies_path} '#{file[:url]}' -c -O
|
178
|
-
|
238
|
+
cmd = "wget --load-cookies=#{xunlei_cookies_path} '#{file[:url]}' -c -O \"#{file[:name]}\""
|
239
|
+
if system(cmd)
|
240
|
+
move_to_downloaded_file(file)
|
241
|
+
else
|
242
|
+
break
|
243
|
+
end
|
179
244
|
end
|
180
245
|
end
|
181
246
|
end
|
@@ -190,9 +255,8 @@ command :show do |c|
|
|
190
255
|
options.default :only => nil, :except => nil
|
191
256
|
puts "You have following files in your #{xunlei_tasks_path}:"
|
192
257
|
puts
|
193
|
-
filter_files(options)
|
194
|
-
|
195
|
-
end
|
258
|
+
files = filter_files(options)
|
259
|
+
show_files(files)
|
196
260
|
end
|
197
261
|
end
|
198
262
|
|
@@ -207,13 +271,14 @@ end
|
|
207
271
|
command :google do |c|
|
208
272
|
c.syntax = "google KEYWORD"
|
209
273
|
c.description = "google for ed2k links using given KEYWORD"
|
210
|
-
c.option "--with
|
274
|
+
c.option "--with WORDS", String, "include additional info when Googling"
|
275
|
+
c.option "--without WORDS", String, "exclude additional info when Googling"
|
211
276
|
c.action do |args, options|
|
212
|
-
options.default :with => nil
|
277
|
+
options.default :with => nil, :without => nil
|
213
278
|
puts "Searching the web for #{args.join(" ")}..."
|
214
279
|
puts
|
215
280
|
search = Xunlei::Search.new
|
216
|
-
links = search.google(args, options
|
281
|
+
links = search.google(args, options)
|
217
282
|
puts
|
218
283
|
puts "#{links.count} links found."
|
219
284
|
end
|
data/lib/xunlei/engine.rb
CHANGED
@@ -12,8 +12,7 @@ module Xunlei
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def dump_cookies
|
15
|
-
|
16
|
-
get_task_list
|
15
|
+
wait_until_all_loaded
|
17
16
|
|
18
17
|
cookies = []
|
19
18
|
@browser.driver.manage.all_cookies.each do |cookie|
|
@@ -42,7 +41,7 @@ module Xunlei
|
|
42
41
|
@browser.close
|
43
42
|
end
|
44
43
|
|
45
|
-
private
|
44
|
+
private
|
46
45
|
|
47
46
|
def wait_until_all_loaded
|
48
47
|
get_task_list
|
@@ -56,24 +55,16 @@ module Xunlei
|
|
56
55
|
|
57
56
|
def next_page
|
58
57
|
next_li = @browser.li(:class => "next")
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
false
|
64
|
-
end
|
58
|
+
|
59
|
+
return false unless next_li.present?
|
60
|
+
|
61
|
+
next_li.as.first.click
|
65
62
|
end
|
66
63
|
|
67
64
|
def process_current_page
|
68
|
-
|
69
|
-
|
70
|
-
all_files = []
|
71
|
-
|
72
|
-
task_list.divs(:class => "rw_list").each do |task_div|
|
65
|
+
get_task_list.divs(:class => "rw_list").inject([]) do |all_files, task_div|
|
73
66
|
all_files += process_task(task_div)
|
74
67
|
end
|
75
|
-
|
76
|
-
all_files
|
77
68
|
end
|
78
69
|
|
79
70
|
def process_task(task_div)
|
@@ -81,9 +72,10 @@ module Xunlei
|
|
81
72
|
|
82
73
|
task_div.wait_until_present
|
83
74
|
|
84
|
-
if task_is_ready?(task_div)
|
75
|
+
if task_is_ready?(task_div)
|
76
|
+
# puts "task is ready"
|
85
77
|
task_div.click
|
86
|
-
task_div.a(:class => "rwbtn
|
78
|
+
task_div.a(:class => "rwbtn ic_redownloca").wait_until_present
|
87
79
|
|
88
80
|
if task_div.div(:class => "w03img").imgs.first.src == "http://cloud.vip.xunlei.com/160/img/icon_type/tpimg_bt.png"
|
89
81
|
task_files += process_bt_task(task_div)
|
@@ -103,8 +95,9 @@ module Xunlei
|
|
103
95
|
|
104
96
|
def process_normal_task(task_div)
|
105
97
|
normal_task_a = task_div.span(:class => "namelink").as.first
|
106
|
-
|
107
|
-
|
98
|
+
task_id = task_div.id.gsub(/\D+/, "")
|
99
|
+
normal_task_input = task_div.input(:id => "dl_url" + task_id)
|
100
|
+
{ :name => normal_task_a.text.gsub(/'|\\/,""), :url => normal_task_input.value, :size => task_div.span(:id => "size#{task_id}").text }
|
108
101
|
end
|
109
102
|
|
110
103
|
def process_bt_task(task_div)
|
@@ -114,8 +107,12 @@ module Xunlei
|
|
114
107
|
folder_list = @browser.div(:id => "rwbox_bt_list")
|
115
108
|
folder_list.wait_until_present
|
116
109
|
|
117
|
-
|
118
|
-
|
110
|
+
index = 0
|
111
|
+
folder_list.spans(:class => "namelink").each do |span|
|
112
|
+
s = span.spans.first
|
113
|
+
size = folder_list.input(:id => "bt_size#{index}").attribute_value('value')
|
114
|
+
task_files << { :name => s.title, :url => s.attribute_value('href'), :size => size }
|
115
|
+
index += 1
|
119
116
|
end
|
120
117
|
|
121
118
|
go_back_from_bt_task
|
data/lib/xunlei/search.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "watir-webdriver"
|
2
2
|
require "Nokogiri"
|
3
|
+
require "uri"
|
3
4
|
|
4
5
|
module Xunlei
|
5
6
|
class Search
|
@@ -7,8 +8,11 @@ module Xunlei
|
|
7
8
|
@browser = Watir::Browser.new driver
|
8
9
|
end
|
9
10
|
|
10
|
-
def google(keywords, options
|
11
|
-
|
11
|
+
def google(keywords, options)
|
12
|
+
q = [keywords, options.with, "ed2k"].flatten.join("+")
|
13
|
+
q += "+-" + options.without unless options.without.nil?
|
14
|
+
|
15
|
+
@browser.goto "http://www.google.com/search?q=#{q}"
|
12
16
|
|
13
17
|
@browser.div(:id => "ires").wait_until_present
|
14
18
|
|
@@ -20,7 +24,8 @@ module Xunlei
|
|
20
24
|
@browser.goto page_link
|
21
25
|
doc = Nokogiri::HTML(@browser.html)
|
22
26
|
doc.css("a").each do |link|
|
23
|
-
|
27
|
+
next if link['href'].nil?
|
28
|
+
href = URI.escape(link['href'])
|
24
29
|
if href =~ /ed2k:|magnet:/ && !ed2k_links.include?(href)
|
25
30
|
puts href
|
26
31
|
ed2k_links << href
|
data/lib/xunlei/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xunlei
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-12-03 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
requirement: &
|
16
|
+
requirement: &70300705578980 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70300705578980
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
requirement: &
|
27
|
+
requirement: &70300705578560 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70300705578560
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: simplecov
|
38
|
-
requirement: &
|
38
|
+
requirement: &70300705578140 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70300705578140
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: watir-webdriver
|
49
|
-
requirement: &
|
49
|
+
requirement: &70300705577720 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70300705577720
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: commander
|
60
|
-
requirement: &
|
60
|
+
requirement: &70300705577300 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :runtime
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70300705577300
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: nokogiri
|
71
|
-
requirement: &
|
71
|
+
requirement: &70300705576880 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,7 +76,7 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :runtime
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70300705576880
|
80
80
|
description: A browser script to access lixian.vip.xunlei.com tasks automatically
|
81
81
|
email:
|
82
82
|
- afu@forresty.com
|
@@ -113,15 +113,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
113
113
|
- - ! '>='
|
114
114
|
- !ruby/object:Gem::Version
|
115
115
|
version: '0'
|
116
|
+
segments:
|
117
|
+
- 0
|
118
|
+
hash: 2684566908890057272
|
116
119
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
120
|
none: false
|
118
121
|
requirements:
|
119
122
|
- - ! '>='
|
120
123
|
- !ruby/object:Gem::Version
|
121
124
|
version: '0'
|
125
|
+
segments:
|
126
|
+
- 0
|
127
|
+
hash: 2684566908890057272
|
122
128
|
requirements: []
|
123
129
|
rubyforge_project: xunlei
|
124
|
-
rubygems_version: 1.8.
|
130
|
+
rubygems_version: 1.8.11
|
125
131
|
signing_key:
|
126
132
|
specification_version: 3
|
127
133
|
summary: A browser script to access lixian.vip.xunlei.com tasks automatically
|