xunlei 0.0.3 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
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.each do |task|
142
- puts task[:name]
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 '#{file[:name]}'"
178
- break unless system(cmd)
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).each do |file|
194
- puts file[:name]
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 OPTIONS", String, "include additional info when Googling"
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.with)
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
- # wait until cookies are ready
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
- if next_li.present?
60
- next_li.as.first.click
61
- true
62
- else
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
- task_list = get_task_list
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 ic_down").wait_until_present
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
- normal_task_input = task_div.input(:id => "dl_url" + task_div.id.gsub(/\D+/, ""))
107
- { :name => normal_task_a.text, :url => normal_task_input.value }
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
- folder_list.as(:name => "bturls").each do |a|
118
- task_files << { :name => a.text, :url => a.href }
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=nil)
11
- @browser.goto "http://www.google.com/search?q=#{[keywords, options, "ed2k"].flatten.join("+")}"
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
- href = link['href']
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
@@ -1,3 +1,3 @@
1
1
  module Xunlei
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.5"
3
3
  end
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.3
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-10-21 00:00:00.000000000Z
12
+ date: 2011-12-03 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
16
- requirement: &70191331322300 !ruby/object:Gem::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: *70191331322300
24
+ version_requirements: *70300705578980
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &70191331321880 !ruby/object:Gem::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: *70191331321880
35
+ version_requirements: *70300705578560
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: simplecov
38
- requirement: &70191331321320 !ruby/object:Gem::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: *70191331321320
46
+ version_requirements: *70300705578140
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: watir-webdriver
49
- requirement: &70191331320640 !ruby/object:Gem::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: *70191331320640
57
+ version_requirements: *70300705577720
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: commander
60
- requirement: &70191331319880 !ruby/object:Gem::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: *70191331319880
68
+ version_requirements: *70300705577300
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: nokogiri
71
- requirement: &70191331319100 !ruby/object:Gem::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: *70191331319100
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.10
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