uwace 1.0.0

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.
Files changed (2) hide show
  1. data/bin/angel +173 -0
  2. metadata +114 -0
@@ -0,0 +1,173 @@
1
+ #!/usr/bin/env ruby -rubygems
2
+
3
+ require 'mechanize'
4
+ require 'net/https'
5
+ require 'highline/import'
6
+ require 'uri'
7
+ require 'fileutils'
8
+ require 'rainbow'
9
+
10
+ class AngelAccess
11
+ class InvalidLogin < StandardError; end
12
+
13
+ def initialize
14
+ @agent = Mechanize.new
15
+ end
16
+
17
+ def angel_get(path)
18
+ @agent.get "https://uwangel.uwaterloo.ca/uwangel/#{path}"
19
+ end
20
+
21
+ def login
22
+ @username ||= ask("Username: ")
23
+ @password ||= ask("Password: ") {|q| q.echo = '*'}
24
+
25
+ say "Logging in ..."
26
+
27
+ login_page = angel_get 'home.asp'
28
+ form = login_page.form_with(:name => "frmLogon")
29
+ form.username = @username
30
+ form.password = @password
31
+
32
+ login_submit_page = @agent.submit form
33
+
34
+ if login_submit_page.uri.to_s.include? 'authenticate.asp'
35
+ raise InvalidLogin
36
+ end
37
+ rescue InvalidLogin
38
+ say 'Invalid Username/Password'
39
+ exit
40
+ end
41
+
42
+ def get_course_links
43
+ class_list_page = angel_get 'default.asp'
44
+ class_list_page.links_with(:href => /section\/default/)
45
+ end
46
+
47
+ def get_node_type(li_node)
48
+ li_node['class'].split(' ').find{|c| c =~ /^cmType/}.gsub(/^cmType/,'').downcase
49
+ end
50
+
51
+ def get_node_name(li_node)
52
+ li_node.css('div.title a').children.find{|c| c.class == Nokogiri::XML::Text}.content
53
+ end
54
+
55
+ def get_download_path(page_url)
56
+ dl_page = @agent.get((@agent.get page_url).iframes.first.src)
57
+ dl_page.link_with(:href => /AngelUploads/).href
58
+ rescue NoMethodError
59
+ nil
60
+ end
61
+
62
+ def dir_sanitize(dirname)
63
+ dirname.gsub(/[^a-zA-Z0-9 _]/,'').strip
64
+ end
65
+
66
+ def traverse(dir_listing_page)
67
+ tree = []
68
+
69
+ dir_listing_page.parser.css('ul.directory li').collect do |li|
70
+ node_type = get_node_type(li)
71
+ node_name = get_node_name(li)
72
+
73
+ targ_href = li.css('div.title a').first['href']
74
+
75
+ {
76
+ :type => node_type,
77
+ :name => node_name,
78
+ :url => targ_href,
79
+ :children => (node_type == 'folder')? traverse(@agent.get targ_href) : []
80
+ }
81
+ end
82
+ end
83
+
84
+ def get_directory_tree(course_link)
85
+ course_page = @agent.click course_link
86
+ content_page = @agent.click course_page.link_with(:href => /content/)
87
+ traverse(content_page)
88
+ end
89
+
90
+ def print_directory_tree(dir_tree,depth = 0)
91
+ dir_tree.each do |node|
92
+ print "%s%s %s\n" % [
93
+ "\t" * depth,
94
+ (node[:children].size > 0)?'+':'-',
95
+ node[:name],
96
+ ]
97
+ print_directory_tree(node[:children],depth+1)
98
+ end
99
+ end
100
+
101
+ def download_tree(dir_tree,basedir,depth=0)
102
+ FileUtils.mkdir_p(basedir)
103
+ dir_tree.each do |node|
104
+ if node[:type] == 'file'
105
+
106
+ download_path = get_download_path node[:url]
107
+
108
+ if download_path.nil?
109
+ puts "%s- %s - Failed (Skipping...)".color(:red) % ["\t" * depth, node[:name]]
110
+ next
111
+ end
112
+
113
+ basename = File.basename(download_path)
114
+ save_path = File.join(basedir, basename)
115
+
116
+ print "%s- %s - " % ["\t" * depth, basename]
117
+
118
+ if File.exists? save_path
119
+ puts "Skipping...".color(:yellow)
120
+ next
121
+ else
122
+ print "Saving... "
123
+ end
124
+
125
+ uri = URI.parse("https://uwangel.uwaterloo.ca")
126
+ https = Net::HTTP.new(uri.host, uri.port)
127
+ https.use_ssl = true
128
+ https.verify_mode = OpenSSL::SSL::VERIFY_NONE
129
+
130
+ request = Net::HTTP::Get.new(uri.request_uri)
131
+
132
+ begin
133
+ response = https.request(request)
134
+ rescue
135
+ puts "Failed.".color(:red)
136
+ next
137
+ end
138
+
139
+ open(save_path,"wb") do |file|
140
+ file.write(response.body)
141
+ end
142
+
143
+ puts "Done.".color(:green)
144
+ elsif node[:type] == 'folder'
145
+ puts "%s+ %s".color(:cyan) % ["\t" * depth, node[:name]]
146
+ download_tree(node[:children],File.join(basedir, dir_sanitize(node[:name])),depth+1)
147
+ end
148
+ end
149
+ end
150
+
151
+ def download_all
152
+ login
153
+
154
+ get_course_links.each do |course_link|
155
+ puts course_link.text.color(:cyan)
156
+ puts ('='*course_link.text.length).color(:cyan)
157
+ if (course_link.text.downcase =~ /pdeng/)
158
+ puts "Skipping PDEng Course...".color(:yellow)
159
+ next
160
+ end
161
+
162
+ if (course_link.text.downcase =~ /co-op/)
163
+ puts "Skipping Co-Op Course...".color(:yellow)
164
+ next
165
+ end
166
+ dir_tree = get_directory_tree(course_link)
167
+
168
+ download_tree(dir_tree,File.join("uwace_#{@username}",dir_sanitize(course_link.text)))
169
+ end
170
+ end
171
+ end
172
+
173
+ AngelAccess.new.download_all
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: uwace
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Jamie Wong
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-11-09 00:00:00 -05:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: highline
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 13
30
+ segments:
31
+ - 1
32
+ - 6
33
+ - 1
34
+ version: 1.6.1
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: mechanize
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 23
46
+ segments:
47
+ - 1
48
+ - 0
49
+ - 0
50
+ version: 1.0.0
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: rainbow
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 13
62
+ segments:
63
+ - 1
64
+ - 1
65
+ version: "1.1"
66
+ type: :runtime
67
+ version_requirements: *id003
68
+ description: Download all files from UWAce, skipping ones already saved
69
+ email:
70
+ - jamie.lf.wong@gmail.com
71
+ executables:
72
+ - angel
73
+ extensions: []
74
+
75
+ extra_rdoc_files: []
76
+
77
+ files:
78
+ - bin/angel
79
+ has_rdoc: true
80
+ homepage: https://github.com/phleet/UWAngel-CLI
81
+ licenses: []
82
+
83
+ post_install_message:
84
+ rdoc_options: []
85
+
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ hash: 3
94
+ segments:
95
+ - 0
96
+ version: "0"
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ hash: 3
103
+ segments:
104
+ - 0
105
+ version: "0"
106
+ requirements: []
107
+
108
+ rubyforge_project:
109
+ rubygems_version: 1.3.7
110
+ signing_key:
111
+ specification_version: 3
112
+ summary: Download UWAce
113
+ test_files: []
114
+