xunlei 0.0.12 → 0.0.13
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -0
- data/README.md +2 -12
- data/bin/xunlei +15 -57
- data/lib/xunlei.rb +0 -1
- data/lib/xunlei/engine.rb +123 -116
- data/lib/xunlei/helpers/cli_helper.rb +8 -4
- data/lib/xunlei/helpers/cookie_helper.rb +10 -0
- data/lib/xunlei/version.rb +1 -1
- data/spec/spec_helper.rb +3 -1
- data/spec/xunlei/engine_spec.rb +0 -1
- data/spec/xunlei/helpers/cli_helper_spec.rb +2 -2
- data/spec/xunlei/helpers/cookie_helper_spec.rb +25 -0
- metadata +20 -17
- data/lib/xunlei/search.rb +0 -62
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/README.md
CHANGED
@@ -6,6 +6,8 @@ lixian.vip.xunlei.com utility script for Mac OS X users
|
|
6
6
|
Summary:
|
7
7
|
-----------
|
8
8
|
|
9
|
+
[![Build Status](https://secure.travis-ci.org/forresty/xunlei.png?branch=master)](http://travis-ci.org/forresty/xunlei)
|
10
|
+
|
9
11
|
This is a browser script for lixian.vip.xunlei.com.
|
10
12
|
It drives Google Chrome with [chromedriver](http://code.google.com/p/selenium/wiki/ChromeDriver) to do automation tasks for you,
|
11
13
|
so please make sure you have Google Chrome installed first.
|
@@ -50,18 +52,6 @@ Add all ed2k or magnet links on given web page as new tasks
|
|
50
52
|
|
51
53
|
xunlei add_page http://page_with_a_chunk_load_of_links/
|
52
54
|
|
53
|
-
Google for ed2k and magnet links
|
54
|
-
|
55
|
-
xunlei google Repulsion --with 720p
|
56
|
-
|
57
|
-
Search simplecd.org for ed2k links
|
58
|
-
|
59
|
-
xunlei simplecd Vendetta 720p
|
60
|
-
|
61
|
-
I am feeling lucky :)
|
62
|
-
|
63
|
-
xunlei lucky KEYWORDS
|
64
|
-
|
65
55
|
Pass --help to see more tasks and options
|
66
56
|
|
67
57
|
xunlei --help
|
data/bin/xunlei
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
require "xunlei"
|
4
4
|
require "commander/import"
|
5
|
+
require "nokogiri"
|
6
|
+
require "open-uri"
|
5
7
|
|
6
8
|
require "xunlei/helpers/cli_helper"
|
7
9
|
include Xunlei::Helper::CLIHelper
|
@@ -88,13 +90,15 @@ command :download do |c|
|
|
88
90
|
c.option "--only PATTERN", String, "only download files which names include PATTERN"
|
89
91
|
c.option "--except PATTERN", String, "do not download files which names include PATTERN"
|
90
92
|
c.option "--reverse", "download files in reverse order"
|
93
|
+
c.option '--limit NUM', Integer, 'limit the number of files to download'
|
91
94
|
|
92
95
|
c.action do |args, options|
|
93
|
-
options.default :only => nil, :except => nil
|
96
|
+
options.default :only => nil, :except => nil, :limit => 65535
|
94
97
|
|
95
98
|
files = filter_files(YAML.load_file(xunlei_tasks_path), options)
|
96
99
|
|
97
100
|
files.reverse! if options.reverse
|
101
|
+
files = files[0, options.limit]
|
98
102
|
|
99
103
|
if files.empty?
|
100
104
|
puts "Nothing to do."
|
@@ -138,55 +142,10 @@ command :config do |c|
|
|
138
142
|
end
|
139
143
|
end
|
140
144
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
c.option "--without WORDS", String, "exclude additional info when Googling"
|
146
|
-
c.action do |args, options|
|
147
|
-
options.default :with => nil, :without => nil
|
148
|
-
puts "Searching the web for '#{args.join(" ")}'..."
|
149
|
-
puts
|
150
|
-
search = Xunlei::Search.new
|
151
|
-
links = search.google(args, options)
|
152
|
-
puts
|
153
|
-
puts "#{links.count} links found."
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
command :simplecd do |c|
|
158
|
-
c.syntax = "simplecd KEYWORD"
|
159
|
-
c.description = "search simplecd for ed2k links using given KEYWORD"
|
160
|
-
c.option "--with WORDS", String, "include additional info when searching"
|
161
|
-
c.option "--without WORDS", String, "exclude additional info when searching"
|
162
|
-
c.action do |args, options|
|
163
|
-
options.default :with => nil, :without => nil
|
164
|
-
puts "Searching simplecd.org for '#{args.join(" ")}'..."
|
165
|
-
puts
|
166
|
-
search = Xunlei::Search.new
|
167
|
-
links = search.google_simplecd(args, options)
|
168
|
-
puts
|
169
|
-
puts "#{links.count} links found."
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
command :lucky do |c|
|
174
|
-
c.syntax = "lucky KEYWORD"
|
175
|
-
c.description = "search simplecd for ed2k links using given KEYWORD and create new tasks :)"
|
176
|
-
c.action do |args, options|
|
177
|
-
puts "Searching simplecd.org for '#{args.join(" ")}'..."
|
178
|
-
puts
|
179
|
-
search = Xunlei::Search.new
|
180
|
-
links = search.google_simplecd(args, options)
|
181
|
-
puts
|
182
|
-
puts "#{links.count} links found."
|
183
|
-
|
184
|
-
execute_dump_action(args, options) do |engine, args|
|
185
|
-
links.each do |link|
|
186
|
-
engine.add_task(link)
|
187
|
-
end
|
188
|
-
end
|
189
|
-
end
|
145
|
+
def find_links_in_page(page_url, options)
|
146
|
+
doc = Nokogiri::HTML(open(page_url) { |p| p.read })
|
147
|
+
links = doc.css("a").select { |a| !a['href'].nil? && a['href'] =~ /ed2k:|magnet:/ }.map { |a| a['href'] }
|
148
|
+
filter_names(links, options).tap { |links| links.map { |l| puts l } }
|
190
149
|
end
|
191
150
|
|
192
151
|
command :add_page do |c|
|
@@ -198,14 +157,15 @@ command :add_page do |c|
|
|
198
157
|
options.default :only => nil, :except => nil
|
199
158
|
puts "Adding page '#{args.first}'..."
|
200
159
|
puts
|
201
|
-
|
202
|
-
links = search.add_page(args.first, options)
|
160
|
+
links = find_links_in_page(args.first, options)
|
203
161
|
puts
|
204
162
|
puts "#{links.count} links found."
|
205
163
|
|
206
|
-
|
207
|
-
|
208
|
-
|
164
|
+
if links.count > 0
|
165
|
+
execute_dump_action(args, options) do |engine, args|
|
166
|
+
links.each do |link|
|
167
|
+
engine.add_task(link)
|
168
|
+
end
|
209
169
|
end
|
210
170
|
end
|
211
171
|
end
|
@@ -213,5 +173,3 @@ end
|
|
213
173
|
|
214
174
|
alias_command :down, :download
|
215
175
|
alias_command :dump, :dump_tasks
|
216
|
-
alias_command :search, :google
|
217
|
-
alias_command :scd, :simplecd
|
data/lib/xunlei.rb
CHANGED
data/lib/xunlei/engine.rb
CHANGED
@@ -6,66 +6,35 @@ module Xunlei
|
|
6
6
|
def initialize(username, password, driver = :chrome)
|
7
7
|
@browser = Watir::Browser.new driver
|
8
8
|
@browser.goto "http://lixian.vip.xunlei.com"
|
9
|
-
|
10
|
-
|
11
|
-
@browser.text_field(:id => "p_show").when_present.set(password)
|
12
|
-
@browser.button(:id => "button_submit4reg").when_present.click
|
13
|
-
|
14
|
-
# temp fix for stupid cloud VOD popup
|
15
|
-
wait_until_all_loaded
|
16
|
-
#@browser.div(:class => "p_rw_pop p_sc_pop p_yuntips").p(:class => 'p_btm_aline').as.first.when_present.click
|
9
|
+
signin(username, password)
|
10
|
+
wait_till_all_loaded
|
17
11
|
end
|
18
12
|
|
13
|
+
require "xunlei/helpers/cookie_helper"
|
14
|
+
include ::Xunlei::Helper::CookieHelper
|
19
15
|
def dump_cookies
|
20
|
-
|
21
|
-
|
22
|
-
cookies = []
|
23
|
-
@browser.driver.manage.all_cookies.each do |cookie|
|
24
|
-
domain = cookie[:domain]
|
25
|
-
path = cookie[:path]
|
26
|
-
expires = cookie[:expires] ? cookie[:expires].strftime("%s") : "0"
|
27
|
-
name = cookie[:name]
|
28
|
-
value = cookie[:value]
|
29
|
-
cookies << "#{domain}\tTRUE\t#{path}\tFALSE\t#{expires}\t#{name}\t#{value}\n"
|
30
|
-
end
|
31
|
-
|
32
|
-
cookies
|
16
|
+
wait_till_all_loaded
|
17
|
+
@browser.driver.manage.all_cookies.inject([]) { |all_cookies, c| all_cookies << format_cookie(c) }
|
33
18
|
end
|
34
19
|
|
35
20
|
def dump_tasks
|
36
|
-
all_files =
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end while next_page
|
42
|
-
|
21
|
+
all_files = dump_current_page
|
22
|
+
while next_page?
|
23
|
+
next_page!
|
24
|
+
all_files += dump_current_page
|
25
|
+
end
|
43
26
|
all_files
|
44
27
|
end
|
45
28
|
|
46
29
|
def add_task(target_address)
|
47
|
-
puts "Adding new task..."
|
48
|
-
# open('|pbcopy', 'w') { |io| io << target_address }
|
49
|
-
|
50
30
|
@browser.execute_script("add_task_new(0)")
|
51
|
-
|
52
31
|
@browser.text_field(:id => 'task_url').wait_until_present
|
53
|
-
|
54
|
-
# @browser.send_keys [:command, 'v']
|
55
32
|
@browser.execute_script("document.getElementById('task_url').value = '#{target_address}'")
|
56
33
|
|
57
|
-
|
58
|
-
expire_count = 0
|
59
|
-
sleep(2.0)
|
60
|
-
while !(@browser.button(:id => 'down_but').enabled? && expire_count <= 5000)
|
61
|
-
expire_count += 1
|
62
|
-
end
|
63
|
-
if expire_count <= 5000
|
64
|
-
print "Submitting... "
|
34
|
+
if added_successfully?
|
65
35
|
@browser.button(:id => 'down_but').when_present.click
|
66
|
-
puts "Done."
|
67
36
|
else
|
68
|
-
puts "
|
37
|
+
puts "Operation timed out."
|
69
38
|
end
|
70
39
|
end
|
71
40
|
|
@@ -73,111 +42,149 @@ module Xunlei
|
|
73
42
|
@browser.close
|
74
43
|
end
|
75
44
|
|
76
|
-
|
45
|
+
private
|
77
46
|
|
78
|
-
def
|
79
|
-
|
47
|
+
def added_successfully?
|
48
|
+
10.times do
|
49
|
+
sleep 1
|
50
|
+
return true if @browser.button(:id => 'down_but').enabled?
|
51
|
+
end
|
52
|
+
false
|
80
53
|
end
|
81
54
|
|
82
|
-
def
|
83
|
-
|
84
|
-
|
85
|
-
|
55
|
+
def signin(username, password)
|
56
|
+
@browser.text_field(:id => "u").when_present.set(username)
|
57
|
+
@browser.text_field(:id => "p_show_err").click
|
58
|
+
@browser.text_field(:id => "p_show").when_present.set(password)
|
59
|
+
@browser.a(:id => "button_submit4reg").click
|
86
60
|
end
|
87
61
|
|
88
|
-
def
|
89
|
-
|
62
|
+
def wait_till_all_loaded
|
63
|
+
get_task_list
|
64
|
+
end
|
90
65
|
|
91
|
-
|
66
|
+
def get_task_list
|
67
|
+
@browser.div(:id => "rowbox_list").tap { |list| list.wait_until_present }
|
68
|
+
end
|
92
69
|
|
93
|
-
|
70
|
+
def next_page?
|
71
|
+
@browser.li(:class => "next").present?
|
72
|
+
end
|
94
73
|
|
95
|
-
|
74
|
+
def next_page!
|
75
|
+
@browser.li(:class => "next").a.click
|
76
|
+
wait_till_all_loaded
|
96
77
|
end
|
97
78
|
|
98
|
-
def
|
99
|
-
get_task_list.divs(:class => "rw_inter").inject([]) do |
|
100
|
-
|
79
|
+
def dump_current_page
|
80
|
+
get_task_list.divs(:class => "rw_inter").inject([]) do |result, div|
|
81
|
+
@current_task_id = div.parent.id.gsub(/\D+/, "")
|
82
|
+
result += dump_task
|
101
83
|
end
|
102
84
|
end
|
103
85
|
|
104
|
-
def
|
105
|
-
|
86
|
+
def bt_task?
|
87
|
+
task_div.div(:class => "w03img").img.src == "http://cloud.vip.xunlei.com/160/img/icon_type/tpimg_bt.png"
|
88
|
+
end
|
106
89
|
|
107
|
-
|
90
|
+
def expand_task_div!
|
91
|
+
task_div.click
|
92
|
+
task_div.a(:class => "rwbtn ic_redownloca").wait_until_present
|
93
|
+
end
|
108
94
|
|
95
|
+
def wait_till_task_loaded
|
96
|
+
task_div.wait_until_present
|
109
97
|
@browser.execute_script("document.getElementById('#{task_div.parent.id}').scrollIntoView()")
|
98
|
+
end
|
110
99
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
100
|
+
def task_div
|
101
|
+
@browser.div(:id => "tr_c#{@current_task_id}").div(:class => "rw_inter")
|
102
|
+
end
|
103
|
+
|
104
|
+
def dump_task
|
105
|
+
return [] unless task_finished?
|
115
106
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
end
|
107
|
+
expand_task_div!
|
108
|
+
|
109
|
+
if bt_task?
|
110
|
+
dump_bt_task
|
121
111
|
else
|
122
|
-
|
112
|
+
dump_normal_task
|
123
113
|
end
|
114
|
+
end
|
124
115
|
|
125
|
-
|
116
|
+
def task_finished?
|
117
|
+
wait_till_task_loaded
|
118
|
+
task_div.em(:class => "loadnum").text == "100%" rescue false
|
126
119
|
end
|
127
120
|
|
128
|
-
def
|
129
|
-
|
121
|
+
def dump_normal_task
|
122
|
+
[{
|
123
|
+
:name => task_div.span(:class => "namelink").as.first.text.gsub(/'|\\/,""),
|
124
|
+
:url => task_div.input(:id => "dl_url" + @current_task_id).value,
|
125
|
+
:size => task_div.span(:id => "size#{@current_task_id}").text
|
126
|
+
}]
|
130
127
|
end
|
131
128
|
|
132
|
-
def
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
129
|
+
def dump_bt_task
|
130
|
+
enter_bt_task!
|
131
|
+
|
132
|
+
task_files = bt_dump_current_page
|
133
|
+
|
134
|
+
(1...bt_num_pages).each do |current_page|
|
135
|
+
bt_next_page!(current_page)
|
136
|
+
task_files += bt_dump_current_page
|
137
|
+
end
|
138
|
+
|
139
|
+
go_back_from_bt_task!
|
140
|
+
|
141
|
+
task_files
|
137
142
|
end
|
138
143
|
|
139
|
-
def
|
144
|
+
def bt_folder_list
|
145
|
+
@browser.div(:id => "rwbox_bt_list").tap { |folder_list| folder_list.wait_until_present }
|
146
|
+
end
|
147
|
+
|
148
|
+
def bt_dump_current_page
|
140
149
|
task_files = []
|
141
|
-
task_div.a(:class => "rwbtn ic_open").when_present.click
|
142
150
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
folder_list.spans(:class => "namelink").each do |span|
|
150
|
-
s = span.spans.first
|
151
|
-
size = folder_list.input(:id => "bt_size#{index}").attribute_value('value')
|
152
|
-
task_files << { :name => s.title, :url => s.attribute_value('href'), :size => size }
|
153
|
-
index += 1
|
154
|
-
end
|
155
|
-
# to check if there is a next page
|
156
|
-
next_bt_link = @browser.a(:title => "下一页")
|
157
|
-
break unless next_bt_link.exists?
|
158
|
-
|
159
|
-
next_page_exists = next_bt_link.attribute_value("class") != "a_up"
|
160
|
-
@browser.execute_script next_bt_link.attribute_value("onclick")
|
161
|
-
time0 = Time.new
|
162
|
-
begin
|
163
|
-
if folder_list.spans(:class => "namelink").first.spans.first.title != @browser.div(:id => "rwbox_bt_list").spans(:class => "namelink").first.spans.first.title
|
164
|
-
break
|
165
|
-
end
|
166
|
-
rescue
|
167
|
-
break
|
168
|
-
end while next_page_exists && Time.now - time0 < 5
|
169
|
-
sleep 1
|
170
|
-
end while next_page_exists
|
151
|
+
bt_folder_list.spans(:class => "namelink").each_with_index do |s, index|
|
152
|
+
size = bt_folder_list.input(:id => "bt_size#{index}").attribute_value('value')
|
153
|
+
task_files << { :name => s.span.title, :url => s.span.attribute_value('href'), :size => size }
|
154
|
+
end
|
155
|
+
task_files
|
156
|
+
end
|
171
157
|
|
172
|
-
|
158
|
+
def bt_next_page_link
|
159
|
+
@browser.a(:title => "下一页")
|
160
|
+
end
|
173
161
|
|
174
|
-
|
162
|
+
def bt_num_pages
|
163
|
+
bt_next_page_link.exists? ? @browser.as(:class => 'palink').map(&:text).last.to_i : 1
|
164
|
+
end
|
165
|
+
|
166
|
+
def bt_next_page!(current_page)
|
167
|
+
bt_next_page_link.click
|
168
|
+
wait_till_bt_next_page_loaded(current_page)
|
175
169
|
end
|
176
170
|
|
177
|
-
def
|
178
|
-
|
179
|
-
|
180
|
-
|
171
|
+
def wait_till_bt_next_page_loaded(current_page)
|
172
|
+
20.times do
|
173
|
+
sleep 0.5
|
174
|
+
return if @browser.as(:class => 'palink').map(&:text).map(&:to_i).include?(current_page)
|
175
|
+
end
|
176
|
+
raise "BT task timed out when trying to fetch next page"
|
177
|
+
end
|
178
|
+
|
179
|
+
def enter_bt_task!
|
180
|
+
task_div.a(:class => "rwbtn ic_open").when_present.click
|
181
|
+
end
|
182
|
+
|
183
|
+
def go_back_from_bt_task!
|
184
|
+
@browser.div(:id => "view_bt_list_nav").tap do |back_div|
|
185
|
+
back_div.wait_until_present
|
186
|
+
back_div.li(:class => "main_link main_linksub").a(:class => "btn_m").click
|
187
|
+
end
|
181
188
|
end
|
182
189
|
end
|
183
190
|
end
|
@@ -6,15 +6,19 @@ module Xunlei
|
|
6
6
|
require "xunlei/configurator"
|
7
7
|
include ::Xunlei::Config
|
8
8
|
|
9
|
-
def filtered?(
|
9
|
+
def filtered?(name, options)
|
10
10
|
return false unless options
|
11
|
-
return true if !options.only.nil? and !(
|
12
|
-
return true if !options.except.nil? and
|
11
|
+
return true if !options.only.nil? and !(name =~ /#{options.only}/i)
|
12
|
+
return true if !options.except.nil? and name =~ /#{options.except}/i
|
13
13
|
false
|
14
14
|
end
|
15
15
|
|
16
16
|
def filter_files(files, options=nil)
|
17
|
-
files.select{ |file| !filtered?(file, options) }.inject([], :<<)
|
17
|
+
files.select { |file| !filtered?(file[:name], options) }.inject([], :<<)
|
18
|
+
end
|
19
|
+
|
20
|
+
def filter_names(names, options=nil)
|
21
|
+
names.select { |name| !filtered?(name, options) }.inject([], :<<)
|
18
22
|
end
|
19
23
|
|
20
24
|
def total_size(file_sizes)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Xunlei
|
2
|
+
module Helper
|
3
|
+
module CookieHelper
|
4
|
+
def format_cookie(cookie)
|
5
|
+
expires = cookie[:expires] ? cookie[:expires].strftime("%s") : "0"
|
6
|
+
"#{cookie[:domain]}\tTRUE\t#{cookie[:path]}\tFALSE\t#{expires}\t#{cookie[:name]}\t#{cookie[:value]}\n"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
data/lib/xunlei/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
data/spec/xunlei/engine_spec.rb
CHANGED
@@ -13,7 +13,7 @@ describe Xunlei::Helper::CLIHelper do
|
|
13
13
|
|
14
14
|
describe "filtered?" do
|
15
15
|
before(:each) do
|
16
|
-
@file =
|
16
|
+
@file = "MatRiX"
|
17
17
|
end
|
18
18
|
|
19
19
|
it "should have a filtered? method" do
|
@@ -48,7 +48,7 @@ describe Xunlei::Helper::CLIHelper do
|
|
48
48
|
it "should have a total_size method" do
|
49
49
|
@main.should respond_to(:total_size)
|
50
50
|
end
|
51
|
-
|
51
|
+
|
52
52
|
it "should calculate total size correctly" do
|
53
53
|
@main.total_size(%w{1.1G 300M 512K}).should == 1.1 * 1000 + 300 + 1
|
54
54
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Xunlei
|
4
|
+
module Helper
|
5
|
+
describe CookieHelper do
|
6
|
+
let(:helper) { Class.new { include CookieHelper }.new }
|
7
|
+
|
8
|
+
describe "format_cookie" do
|
9
|
+
it "should format_cookie" do
|
10
|
+
expected = ".vip.xunlei.com\tTRUE\t/\tFALSE\t0\tlx_referfrom\t\n"
|
11
|
+
cookie_hash = {
|
12
|
+
:name => "lx_referfrom",
|
13
|
+
:value => "",
|
14
|
+
:path => "/",
|
15
|
+
:domain => ".vip.xunlei.com",
|
16
|
+
:expires => nil,
|
17
|
+
:secure => false
|
18
|
+
}
|
19
|
+
|
20
|
+
helper.format_cookie(cookie_hash).should == expected
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
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.
|
4
|
+
version: 0.0.13
|
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: 2012-
|
12
|
+
date: 2012-05-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
requirement: &
|
16
|
+
requirement: &70234773620780 !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: *70234773620780
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
requirement: &
|
27
|
+
requirement: &70234773620360 !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: *70234773620360
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: simplecov
|
38
|
-
requirement: &
|
38
|
+
requirement: &70234773619940 !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: *70234773619940
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: watir-webdriver
|
49
|
-
requirement: &
|
49
|
+
requirement: &70234773619520 !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: *70234773619520
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: commander
|
60
|
-
requirement: &
|
60
|
+
requirement: &70234773619100 !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: *70234773619100
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: nokogiri
|
71
|
-
requirement: &
|
71
|
+
requirement: &70234773618660 !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: *70234773618660
|
80
80
|
description: A browser script to access lixian.vip.xunlei.com tasks automatically
|
81
81
|
email:
|
82
82
|
- afu@forresty.com
|
@@ -86,6 +86,7 @@ extensions: []
|
|
86
86
|
extra_rdoc_files: []
|
87
87
|
files:
|
88
88
|
- .gitignore
|
89
|
+
- .rspec
|
89
90
|
- .travis.yml
|
90
91
|
- Gemfile
|
91
92
|
- Gemfile.ci
|
@@ -96,11 +97,12 @@ files:
|
|
96
97
|
- lib/xunlei/configurator.rb
|
97
98
|
- lib/xunlei/engine.rb
|
98
99
|
- lib/xunlei/helpers/cli_helper.rb
|
99
|
-
- lib/xunlei/
|
100
|
+
- lib/xunlei/helpers/cookie_helper.rb
|
100
101
|
- lib/xunlei/version.rb
|
101
102
|
- spec/spec_helper.rb
|
102
103
|
- spec/xunlei/engine_spec.rb
|
103
104
|
- spec/xunlei/helpers/cli_helper_spec.rb
|
105
|
+
- spec/xunlei/helpers/cookie_helper_spec.rb
|
104
106
|
- xunlei.gemspec
|
105
107
|
homepage: ''
|
106
108
|
licenses: []
|
@@ -116,7 +118,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
116
118
|
version: '0'
|
117
119
|
segments:
|
118
120
|
- 0
|
119
|
-
hash: -
|
121
|
+
hash: -147464010807530780
|
120
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
123
|
none: false
|
122
124
|
requirements:
|
@@ -125,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
125
127
|
version: '0'
|
126
128
|
segments:
|
127
129
|
- 0
|
128
|
-
hash: -
|
130
|
+
hash: -147464010807530780
|
129
131
|
requirements: []
|
130
132
|
rubyforge_project: xunlei
|
131
133
|
rubygems_version: 1.8.11
|
@@ -136,3 +138,4 @@ test_files:
|
|
136
138
|
- spec/spec_helper.rb
|
137
139
|
- spec/xunlei/engine_spec.rb
|
138
140
|
- spec/xunlei/helpers/cli_helper_spec.rb
|
141
|
+
- spec/xunlei/helpers/cookie_helper_spec.rb
|
data/lib/xunlei/search.rb
DELETED
@@ -1,62 +0,0 @@
|
|
1
|
-
require "Nokogiri"
|
2
|
-
require "uri"
|
3
|
-
require "open-uri"
|
4
|
-
|
5
|
-
module Xunlei
|
6
|
-
class Search
|
7
|
-
def initialize(driver = :chrome)
|
8
|
-
end
|
9
|
-
|
10
|
-
def google(keywords, options)
|
11
|
-
do_google(keywords, options, "http://www.google.com/search?q=", 10)
|
12
|
-
end
|
13
|
-
|
14
|
-
def google_simplecd(keywords, options)
|
15
|
-
do_google(keywords, options, "http://www.google.com/search?q=site:simplecd.org+", 1)
|
16
|
-
end
|
17
|
-
|
18
|
-
def add_page(page_url, options)
|
19
|
-
doc = Nokogiri::HTML(open(page_url) { |page| page.read })
|
20
|
-
links = []
|
21
|
-
|
22
|
-
doc.css("a").select do |a|
|
23
|
-
!a['href'].nil? && a['href'] =~ /ed2k:|magnet:/
|
24
|
-
end.map do |a|
|
25
|
-
a['href']
|
26
|
-
end.uniq.each do |link|
|
27
|
-
if !options.only.nil?
|
28
|
-
links << link if link =~ /#{options.only}/i
|
29
|
-
elsif !options.except.nil?
|
30
|
-
links << link unless link =~ /#{options.except}/i
|
31
|
-
else
|
32
|
-
links << link
|
33
|
-
end
|
34
|
-
end
|
35
|
-
links.each { |link| puts link }
|
36
|
-
links
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def do_google(keywords, options, prefix, limit)
|
42
|
-
q = [keywords, options.with, "ed2k"].flatten.join("+")
|
43
|
-
q += "+-" + options.without unless options.without.nil?
|
44
|
-
|
45
|
-
search_result = Nokogiri::HTML(open("#{prefix}#{q}") { |page| page.read })
|
46
|
-
page_links = search_result.css(".g h3 a").map { |a| "http://www.google.com" + a['href'] }[0, limit]
|
47
|
-
|
48
|
-
ed2k_links = []
|
49
|
-
|
50
|
-
page_links.each do |page_link|
|
51
|
-
doc = Nokogiri::HTML(open(page_link) { |page| page.read })
|
52
|
-
ed2k_links += doc.css("a").select do |a|
|
53
|
-
!a['href'].nil? && a['href'] =~ /ed2k:|magnet:/
|
54
|
-
end.map do |a|
|
55
|
-
a['href'].tap { |a| puts a }
|
56
|
-
end.uniq
|
57
|
-
end
|
58
|
-
|
59
|
-
ed2k_links
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|