xunlei 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ coverage
6
+ *.log
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ rvm:
2
+ - 1.9.2
3
+ - 1.8.7
4
+ gemfile: Gemfile.ci
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.ci ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,5 @@
1
+ guard 'rspec', :version => 2 do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ end
data/README.md ADDED
@@ -0,0 +1,40 @@
1
+ xunlei gem
2
+ ===========
3
+
4
+ lixian.vip.xunlei.com utility script for Mac OS X users
5
+
6
+ Summary:
7
+ -----------
8
+
9
+ This is a browser script for lixian.vip.xunlei.com.
10
+ It drives Google Chrome to do automation tasks for you, so please
11
+ make sure you have Google Chrome installed first.
12
+
13
+ WARNING:
14
+ it stores your USERNAME and PASSWORD for
15
+ lixian.vip.xunlei.com as PLAINTEXT at ~/.xunlei/credentials.yml
16
+
17
+ Install:
18
+ -----------
19
+
20
+ gem install xunlei
21
+
22
+ Usage:
23
+ -----------
24
+
25
+ Dump all tasks from web:
26
+
27
+ xunlei dump_tasks
28
+
29
+ Download files
30
+
31
+ xunlei download
32
+
33
+ Download files according to pattern in file names
34
+
35
+ xunlei download --only matrix
36
+ xunlei download --except bourne
37
+
38
+ Pass --help to see more tasks and options
39
+
40
+ xunlei --help
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/xunlei ADDED
@@ -0,0 +1,199 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "xunlei"
4
+ require "yaml"
5
+ require "commander/import"
6
+
7
+ program :name, "Xunlei"
8
+ program :version, Xunlei::VERSION
9
+ program :description, "lixian.vip.xunlei.com utility script"
10
+
11
+ def filter_files(options = nil)
12
+ files = []
13
+ YAML.load_file(xunlei_tasks_path).each do |file|
14
+ if !options.only.nil?
15
+ files << file if file[:name] =~ /#{options.only}/i
16
+ elsif !options.except.nil?
17
+ files << file unless file[:name] =~ /#{options.except}/i
18
+ else
19
+ files << file
20
+ end
21
+ end
22
+ files
23
+ end
24
+
25
+ def do_dump_cookies(c)
26
+ c.option "--driver DRIVER", String, "use a different webdriver (e.g. firefox). default is chrome"
27
+ c.action do |args, options|
28
+ options.default :driver => "chrome"
29
+
30
+ check_for_config_files
31
+ check_for_chromedriver
32
+ credentials = YAML.load_file(xunlei_credential_file_path)
33
+ engine = Xunlei::Engine.new(credentials[:username], credentials[:password], options.driver.downcase.to_sym)
34
+
35
+ File.open(xunlei_cookies_path, "w") do |file|
36
+ engine.dump_cookies.each do |line|
37
+ file.write(line)
38
+ end
39
+ end
40
+
41
+ yield(engine) if block_given?
42
+
43
+ engine.stop
44
+ end
45
+ end
46
+
47
+ def xunlei_cookies_path
48
+ File.join(xunlei_folder_path, "cookies.txt")
49
+ end
50
+
51
+ def xunlei_tasks_path
52
+ File.join(xunlei_folder_path, "all_tasks.yml")
53
+ end
54
+
55
+ def xunlei_credential_file_path
56
+ File.join(xunlei_folder_path, "credentials.yml")
57
+ end
58
+
59
+ def xunlei_folder_name
60
+ "~/.xunlei"
61
+ end
62
+
63
+ def xunlei_folder_path
64
+ File.expand_path(xunlei_folder_name)
65
+ end
66
+
67
+ def xunlei_folder_exists?
68
+ Dir.exists?(xunlei_folder_path)
69
+ end
70
+
71
+ def credential_file_exists?
72
+ File.exists?(xunlei_credential_file_path)
73
+ end
74
+
75
+ def create_xunlei_folder
76
+ Dir.mkdir(xunlei_folder_path)
77
+ end
78
+
79
+ def ask_for_credentials
80
+ puts "#{xunlei_credential_file_path} not exists. Now creating one."
81
+ puts "*** WARNING: your USERNAME and PASSWORD will be stored as PLAINTEXT at #{xunlei_credential_file_path} ***"
82
+
83
+ username = ask("Username: ")
84
+ password = ask("Password: ") { |q| q.echo = "*" }
85
+ File.open(xunlei_credential_file_path, "w") do |file|
86
+ file.write({ :username => username, :password => password }.to_yaml)
87
+ end
88
+
89
+ puts "#{xunlei_credential_file_path} successfully created."
90
+ end
91
+
92
+ def check_for_credentials
93
+ ask_for_credentials unless credential_file_exists?
94
+ end
95
+
96
+ def chromedriver_zip_name
97
+ "chromedriver_mac.zip"
98
+ end
99
+
100
+ def check_for_chromedriver
101
+ unless system("which chromedriver > /dev/null 2>&1")
102
+ puts "chromedriver not found in your PATH"
103
+ if agree("Would you like me to try download it for you? (yes or no)")
104
+ if system("wget 'http://chromium.googlecode.com/files/chromedriver_mac_16.0.902.0.zip' -O #{chromedriver_zip_name}")
105
+ if system("unzip #{chromedriver_zip_name}")
106
+ puts "moving chromedriver to /usr/local/bin ..."
107
+ system("mv -v chromedriver /usr/local/bin")
108
+
109
+ puts "deleting temporary files..."
110
+ system("rm -v #{chromedriver_zip_name}")
111
+ else
112
+ puts "`unzip` not found in your PATH. Try manually unzip #{chromedriver_zip_name} and move it to /usr/local/bin"
113
+ exit
114
+ end
115
+ end
116
+ else
117
+ puts "OK. You can download it manually here: http://code.google.com/p/chromium/downloads"
118
+ exit
119
+ end
120
+ end
121
+ end
122
+
123
+ def check_for_config_files
124
+ create_xunlei_folder unless xunlei_folder_exists?
125
+ check_for_credentials
126
+ end
127
+
128
+ command :dump_tasks do |c|
129
+ c.syntax= "dump_tasks"
130
+ c.description = "dump all files to #{xunlei_tasks_path}"
131
+
132
+ do_dump_cookies(c) do |engine|
133
+ tasks = engine.dump_tasks
134
+
135
+ File.open(xunlei_tasks_path, "w") do |file|
136
+ file.write(tasks.to_yaml)
137
+ end
138
+
139
+ puts "Successfully dumped following tasks:"
140
+ puts
141
+ tasks.each do |task|
142
+ puts task[:name]
143
+ end
144
+ end
145
+ end
146
+
147
+ command :dump_cookies do |c|
148
+ c.syntax = "dump_cookies"
149
+ c.description = "dump cookies to #{xunlei_cookies_path}"
150
+
151
+ do_dump_cookies(c)
152
+ end
153
+
154
+ command :download do |c|
155
+ c.syntax = "download"
156
+ c.description = "download all files in #{xunlei_tasks_path}"
157
+ c.option "--only PATTERN", String, "only download files which names include PATTERN"
158
+ c.option "--except PATTERN", String, "do not download files which names include PATTERN"
159
+
160
+ c.action do |args, options|
161
+ options.default :only => nil, :except => nil
162
+
163
+ files = filter_files(options)
164
+
165
+ if files.empty?
166
+ puts "Nothing to do."
167
+ else
168
+ puts "\nAbout to download following files:"
169
+ puts
170
+ filter_files(options).each do |file|
171
+ puts file[:name]
172
+ end
173
+
174
+ if agree("\nConfirm? (yes or no)")
175
+ filter_files(options).each do |file|
176
+ cmd = "wget --load-cookies=#{xunlei_cookies_path} '#{file[:url]}' -c -O '#{file[:name]}'"
177
+ break unless system(cmd)
178
+ end
179
+ end
180
+ end
181
+ end
182
+ end
183
+
184
+ command :show do |c|
185
+ c.syntax = "show"
186
+ c.description = "show files in #{xunlei_tasks_path}"
187
+
188
+ c.action do |args, options|
189
+ options.default :only => nil, :except => nil
190
+ puts "You have following files in your #{xunlei_tasks_path}:"
191
+ puts
192
+ filter_files(options).each do |file|
193
+ puts file[:name]
194
+ end
195
+ end
196
+ end
197
+
198
+ alias_command :down, :download
199
+ alias_command :dump, :dump_tasks
data/lib/xunlei.rb ADDED
@@ -0,0 +1,3 @@
1
+ require "xunlei/version"
2
+ require "xunlei/engine"
3
+
@@ -0,0 +1,132 @@
1
+ require "watir-webdriver"
2
+
3
+ module Xunlei
4
+ class Engine
5
+ def initialize(username, password, driver = :chrome)
6
+ @browser = Watir::Browser.new driver
7
+ @browser.goto "http://lixian.vip.xunlei.com"
8
+
9
+ @browser.text_field(:id => "u").when_present.set(username)
10
+ @browser.text_field(:id => "p_show").when_present.set(password)
11
+ @browser.button(:id => "button_submit4reg").when_present.click
12
+ end
13
+
14
+ def dump_cookies
15
+ # wait until cookies are ready
16
+ get_task_list
17
+
18
+ cookies = []
19
+ @browser.driver.manage.all_cookies.each do |cookie|
20
+ domain = cookie[:domain]
21
+ path = cookie[:path]
22
+ expires = cookie[:expires] ? cookie[:expires].strftime("%s") : "0"
23
+ name = cookie[:name]
24
+ value = cookie[:value]
25
+ cookies << "#{domain}\tTRUE\t#{path}\tFALSE\t#{expires}\t#{name}\t#{value}\n"
26
+ end
27
+
28
+ cookies
29
+ end
30
+
31
+ def dump_tasks
32
+ all_files = []
33
+
34
+ begin
35
+ all_files += process_current_page
36
+ end while next_page
37
+
38
+ all_files
39
+ end
40
+
41
+ def stop
42
+ @browser.close
43
+ end
44
+
45
+ private
46
+
47
+ def wait_until_all_loaded
48
+ get_task_list
49
+ end
50
+
51
+ def get_task_list
52
+ task_list = @browser.div(:id => "rowbox_list")
53
+ task_list.wait_until_present
54
+ task_list
55
+ end
56
+
57
+ def next_page
58
+ 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
65
+ end
66
+
67
+ 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|
73
+ all_files += process_task(task_div)
74
+ end
75
+
76
+ all_files
77
+ end
78
+
79
+ def process_task(task_div)
80
+ task_files = []
81
+
82
+ task_div.wait_until_present
83
+
84
+ if task_is_ready?(task_div)
85
+ task_div.click
86
+ task_div.a(:class => "rwbtn ic_down").wait_until_present
87
+
88
+ if task_div.a(:class => "rwbtn ic_open").present?
89
+ task_files += process_bt_task(task_div)
90
+ else
91
+ task_files << process_normal_task(task_div)
92
+ end
93
+ else
94
+ # still downloading
95
+ end
96
+
97
+ task_files
98
+ end
99
+
100
+ def task_is_ready?(task_div)
101
+ task_div.em(:class => "loadnum").text == "100%"
102
+ end
103
+
104
+ def process_normal_task(task_div)
105
+ 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 }
108
+ end
109
+
110
+ def process_bt_task(task_div)
111
+ task_files = []
112
+ task_div.a(:class => "rwbtn ic_open").when_present.click
113
+
114
+ folder_list = @browser.div(:id => "rwbox_bt_list")
115
+ folder_list.wait_until_present
116
+
117
+ folder_list.as(:name => "bturls").each do |a|
118
+ task_files << { :name => a.text, :url => a.href }
119
+ end
120
+
121
+ go_back_from_bt_task
122
+
123
+ task_files
124
+ end
125
+
126
+ def go_back_from_bt_task
127
+ back_div = @browser.div(:id => "view_bt_list_nav")
128
+ back_div.wait_until_present
129
+ back_div.lis(:class => "main_link main_linksub").first.a(:class => "btn_m").click
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,3 @@
1
+ module Xunlei
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,6 @@
1
+ require "simplecov"
2
+ SimpleCov.start
3
+
4
+ require "fakeweb"
5
+
6
+ FakeWeb.allow_net_connect = false
@@ -0,0 +1,3 @@
1
+ require "spec_helper"
2
+
3
+ # Sorry there's no spec here. Just hack around.
data/xunlei.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "xunlei/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "xunlei"
7
+ s.version = Xunlei::VERSION
8
+ s.authors = ["Forrest Ye"]
9
+ s.email = ["afu@forresty.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{A browser script to access lixian.vip.xunlei.com tasks automatically}
12
+ s.description = %q{A browser script to access lixian.vip.xunlei.com tasks automatically}
13
+
14
+ s.rubyforge_project = "xunlei"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_development_dependency "rake"
22
+
23
+ s.add_runtime_dependency "watir-webdriver"
24
+ s.add_runtime_dependency "commander"
25
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: xunlei
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Forrest Ye
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-10-16 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: &70288983816380 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70288983816380
25
+ - !ruby/object:Gem::Dependency
26
+ name: watir-webdriver
27
+ requirement: &70288983815740 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70288983815740
36
+ - !ruby/object:Gem::Dependency
37
+ name: commander
38
+ requirement: &70288983815280 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70288983815280
47
+ description: A browser script to access lixian.vip.xunlei.com tasks automatically
48
+ email:
49
+ - afu@forresty.com
50
+ executables:
51
+ - xunlei
52
+ extensions: []
53
+ extra_rdoc_files: []
54
+ files:
55
+ - .gitignore
56
+ - .travis.yml
57
+ - Gemfile
58
+ - Gemfile.ci
59
+ - Guardfile
60
+ - README.md
61
+ - Rakefile
62
+ - bin/xunlei
63
+ - lib/xunlei.rb
64
+ - lib/xunlei/engine.rb
65
+ - lib/xunlei/version.rb
66
+ - spec/spec_helper.rb
67
+ - spec/xunlei/engine_spec.rb
68
+ - xunlei.gemspec
69
+ homepage: ''
70
+ licenses: []
71
+ post_install_message:
72
+ rdoc_options: []
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ none: false
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ requirements: []
88
+ rubyforge_project: xunlei
89
+ rubygems_version: 1.8.10
90
+ signing_key:
91
+ specification_version: 3
92
+ summary: A browser script to access lixian.vip.xunlei.com tasks automatically
93
+ test_files:
94
+ - spec/spec_helper.rb
95
+ - spec/xunlei/engine_spec.rb