xunlei 0.0.1

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/.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