Module: U3d::Utils
- Defined in:
- lib/u3d/utils.rb
Overview
Several different utility methods rubocop:disable ModuleLength
Constant Summary collapse
- CSIDL_LOCAL_APPDATA =
Regex to capture each part of a version string (0.0.0x0)
0x001c
- UNITY_VERSION_REGEX =
/(\d+)(?:\.(\d+)(?:\.(\d+))?)?(?:(\w)(?:(\d+))?)?/
Class Method Summary collapse
-
.download_file(path, url, size: nil) ⇒ Object
size a hint of the expected size.
- .ensure_dir(dir) ⇒ Object
- .final_url(url, redirect_limit: 10) ⇒ Object
- .follow_redirects(url, redirect_limit: 10, http_method: :get, request_headers: {}, &block) ⇒ Object
-
.get_ssl(url, redirect_limit: 10, request_headers: {}) ⇒ Object
FIXME: alias deprecated.
- .get_url_content_length(url) ⇒ Object
- .get_write_access(dir) ⇒ Object
- .hashfile(file_path, blocksize: 65_536) ⇒ Object
- .http_request_class(method, uri) ⇒ Object
- .page_content(url, redirect_limit: 10, request_headers: {}) ⇒ Object
- .parse_unity_version(version) ⇒ Object
- .pretty_filesize(filesize) ⇒ Object
-
.print_progress(current, total, started_at) ⇒ Object
if total is nil (unknown, falls back to print_progress_nosize).
- .print_progress_nosize(current, started_at) ⇒ Object
-
.strings(path) ⇒ Object
Ruby implementation of binutils strings.
- .windows_local_appdata ⇒ Object
- .windows_path(path) ⇒ Object
Class Method Details
.download_file(path, url, size: nil) ⇒ Object
size a hint of the expected size
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/u3d/utils.rb', line 90 def download_file(path, url, size: nil) File.open(path, 'wb') do |f| uri = URI(url) current = 0 last_print_update = 0 print_progress = UI.interactive? || U3dCore::Globals.verbose? Net::HTTP.start(uri.host, uri.port, http_opts(use_ssl: uri.scheme == 'https')) do |http| request = Net::HTTP::Get.new uri http.request request do |response| begin # override with actual results, this should help with # innacurrate declared sizes, especially on Windows platform size = Integer(response['Content-Length']) rescue ArgumentError UI.verbose 'Unable to get length of file in download' end started_at = Time.now.to_i - 1 response.read_body do |segment| f.write(segment) current += segment.length # wait for Net::HTTP buffer on slow networks # FIXME revisits, this slows down download on fast network # sleep 0.08 # adjust to reduce CPU next unless print_progress print_progress_now = Time.now.to_f - last_print_update > 0.5 # force printing when done downloading print_progress_now = true if !print_progress_now && size && current >= size next unless print_progress_now last_print_update = Time.now.to_f Utils.print_progress(current, size, started_at) print "\n" unless UI.interactive? end end end print "\n" if print_progress end end |
.ensure_dir(dir) ⇒ Object
150 151 152 |
# File 'lib/u3d/utils.rb', line 150 def ensure_dir(dir) FileUtils.mkpath(dir) unless File.directory?(dir) end |
.final_url(url, redirect_limit: 10) ⇒ Object
37 38 39 40 41 |
# File 'lib/u3d/utils.rb', line 37 def final_url(url, redirect_limit: 10) follow_redirects(url, redirect_limit: redirect_limit, http_method: :head) do |request, _response| request.uri.to_s end end |
.follow_redirects(url, redirect_limit: 10, http_method: :get, request_headers: {}, &block) ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/u3d/utils.rb', line 54 def follow_redirects(url, redirect_limit: 10, http_method: :get, request_headers: {}, &block) raise 'Too many redirections' if redirect_limit.zero? response = nil request = nil uri = URI(url) begin use_ssl = /^https/.match(url) Net::HTTP.start(uri.host, uri.port, http_opts(use_ssl: use_ssl)) do |http| request = http_request_class http_method, uri request_headers.each do |k, v| request[k] = v end response = http.request request end rescue OpenSSL::OpenSSLError => ssl_error UI.error 'SSL has faced an error, you may want to check our README to fix it' raise ssl_error end case response when Net::HTTPSuccess then yield(request, response) when Net::HTTPRedirection then UI.verbose "Redirected to #{response['location']}" follow_redirects(response['location'], redirect_limit: redirect_limit - 1, http_method: http_method, request_headers: request_headers, &block) else raise "Request failed with status #{response.code}" end end |
.get_ssl(url, redirect_limit: 10, request_headers: {}) ⇒ Object
FIXME: alias deprecated
44 45 46 |
# File 'lib/u3d/utils.rb', line 44 def get_ssl(url, redirect_limit: 10, request_headers: {}) page_content(url, redirect_limit: redirect_limit, request_headers: request_headers) end |
.get_url_content_length(url) ⇒ Object
128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/u3d/utils.rb', line 128 def get_url_content_length(url) UI.verbose "get_url_content_length #{url}" uri = URI(url) size = nil Net::HTTP.start(uri.host, uri.port, http_opts) do |http| response = http.request_head url size = Integer(response['Content-Length']) end UI.verbose "get_url_content_length #{url}: #{size}" size end |
.get_write_access(dir) ⇒ Object
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/u3d/utils.rb', line 154 def get_write_access(dir) if U3dCore::Helper. == :win yield else stat_command = if U3dCore::Helper. == :linux "stat -c \"%U,%a\" #{dir}" elsif U3dCore::Helper. == :mac "stat -f \"%Su,%A\" #{dir}" end owner, access = U3dCore::CommandExecutor.execute(command: stat_command, admin: false).strip.split(',') current_user = U3dCore::CommandExecutor.execute(command: 'whoami', admin: false) U3dCore::CommandExecutor.execute(command: "chown #{current_user}: #{dir}", admin: true) U3dCore::CommandExecutor.execute(command: "chmod u+w #{dir}", admin: true) begin yield ensure U3dCore::CommandExecutor.execute(command: "chown #{owner}: #{dir}", admin: true) U3dCore::CommandExecutor.execute(command: "chmod #{access} #{dir}", admin: true) end end end |
.hashfile(file_path, blocksize: 65_536) ⇒ Object
140 141 142 143 144 145 146 147 148 |
# File 'lib/u3d/utils.rb', line 140 def hashfile(file_path, blocksize: 65_536) require 'digest' raise ArgumentError, 'Not a file' unless File.file?(file_path) md5 = Digest::MD5.new File.open(file_path, 'r') do |f| md5 << f.read(blocksize) until f.eof? end md5.hexdigest end |
.http_request_class(method, uri) ⇒ Object
83 84 85 86 87 |
# File 'lib/u3d/utils.rb', line 83 def http_request_class(method, uri) return Net::HTTP::Get.new uri if method == :get return Net::HTTP::Head.new uri if method == :head raise "Unknown method #{method}" end |
.page_content(url, redirect_limit: 10, request_headers: {}) ⇒ Object
48 49 50 51 52 |
# File 'lib/u3d/utils.rb', line 48 def page_content(url, redirect_limit: 10, request_headers: {}) follow_redirects(url, redirect_limit: redirect_limit, request_headers: request_headers) do |_request, response| response.body end end |
.parse_unity_version(version) ⇒ Object
198 199 200 201 202 203 204 205 |
# File 'lib/u3d/utils.rb', line 198 def parse_unity_version(version) ver = UNITY_VERSION_REGEX.match(version) if ver.nil? raise ArgumentError, "Version (#{version}) does not match the Unity "\ 'version format 0.0.0x0' end [ver[1], ver[2], ver[3], ver[4], ver[5]] end |
.pretty_filesize(filesize) ⇒ Object
223 224 225 |
# File 'lib/u3d/utils.rb', line 223 def pretty_filesize(filesize) Filesize.from(filesize.round.to_s + ' B').pretty end |
.print_progress(current, total, started_at) ⇒ Object
if total is nil (unknown, falls back to print_progress_nosize)
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/u3d/utils.rb', line 177 def print_progress(current, total, started_at) if total.nil? print_progress_nosize(current, started_at) return end ratio = [current.to_f / total, 1.0].min percent = (ratio * 100.0).round(1) arrow = (ratio * 20.0).floor time_spent = Time.now.to_i - started_at print("\r[") print('=' * [arrow - 1, 0].max) print('>') print('.' * (20 - arrow)) print("] #{pretty_filesize(current)}/#{pretty_filesize(total)} (#{percent}% at #{pretty_filesize(current.to_f / time_spent)}/s) ") end |
.print_progress_nosize(current, started_at) ⇒ Object
193 194 195 196 |
# File 'lib/u3d/utils.rb', line 193 def print_progress_nosize(current, started_at) time_spent = Time.now.to_i - started_at print("\r>#{pretty_filesize(current)} downloaded at #{pretty_filesize(current.to_f / time_spent)}/s) ") end |
.strings(path) ⇒ Object
Ruby implementation of binutils strings
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/u3d/utils.rb', line 233 def strings(path) min = 4 Enumerator.new do |y| File.open(path, "rb") do |f| s = "" f.each_char do |c| if c =~ /[[:print:]]/ # is there a cleaner way to do this check? s += c next else y.yield s if s.length >= min s = "" end end y.yield s if s.length >= min end end end |
.windows_local_appdata ⇒ Object
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/u3d/utils.rb', line 207 def windows_local_appdata require 'win32api' windir = ' ' * 261 getdir = Win32API.new('shell32', 'SHGetFolderPath', 'LLLLP', 'L') result = getdir.call(0, CSIDL_LOCAL_APPDATA, 0, 0, windir) raise "Unable to get Local Appdata directory, returned with value #{result}" unless result.zero? windir.rstrip! windir = windir.encode("UTF-8", Encoding.find('filesystem')) windir = File.(windir.rstrip) return windir if Dir.exist? windir raise "Local Appdata retrieved (#{windir}) is not correct" end |
.windows_path(path) ⇒ Object
227 228 229 230 |
# File 'lib/u3d/utils.rb', line 227 def windows_path(path) UI.deprecated("Use U3dCore::Helper.windows_path") U3dCore::Helper.windows_path(path) end |