browse-everything 0.6.3 → 0.7.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.
- checksums.yaml +5 -13
- data/.travis.yml +2 -1
- data/Gemfile +6 -0
- data/HISTORY.md +5 -0
- data/README.md +35 -3
- data/Rakefile +2 -1
- data/app/assets/javascripts/browse_everything/behavior.js.coffee +58 -18
- data/app/views/browse_everything/_auth.html.erb +1 -1
- data/app/views/browse_everything/_file.html.erb +10 -8
- data/app/views/browse_everything/_files.html.erb +11 -6
- data/app/views/browse_everything/index.html.erb +5 -4
- data/browse-everything.gemspec +2 -0
- data/lib/browse_everything.rb +1 -0
- data/lib/browse_everything/driver/box.rb +2 -2
- data/lib/browse_everything/driver/drop_box.rb +1 -1
- data/lib/browse_everything/driver/file_system.rb +4 -2
- data/lib/browse_everything/driver/google_drive.rb +7 -2
- data/lib/browse_everything/driver/sky_drive.rb +1 -1
- data/lib/browse_everything/retriever.rb +60 -0
- data/lib/browse_everything/version.rb +1 -1
- data/spec/fixtures/vcr_cassettes/dropbox.yml +83 -0
- data/spec/fixtures/vcr_cassettes/retriever.yml +77 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/{support → test_app_templates}/lib/generators/test_app_generator.rb +9 -9
- data/spec/unit/file_system_spec.rb +2 -2
- data/spec/unit/retriever_spec.rb +83 -0
- data/tasks/ci.rake +2 -4
- metadata +81 -51
- data/spec/rake/app_spec.rb +0 -121
- data/tasks/browse-everything-dev.rake +0 -70
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
NTg2NmE1MWZlMjQzZGUwYzAyZjljNWNmZTJlYjlhODdiMGY4NTIyYw==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6a4e41392cdc521780aedf3a678593444dd23663
|
4
|
+
data.tar.gz: a34d71298ffa7a50258c4b7e9f1129c71bfa7b9c
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
ZjQxMWMyYmM4NWZhN2E4NTQyMmVlZDVhOWI5NmNiYjVkNDU3ODhiNjgyZDFk
|
11
|
-
MmE2ZWFhMmNjMzRmNjIzZjYyZDdkZjUwNDE2MTA3YWVlMTU4MWU=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
NjAxMDg3M2JmZmRiZTAwMWE4NTc4YTU0MmI0NmQzNTI5OTQ5YzNlZjZhY2Nk
|
14
|
-
N2MxOTBiZjAzMzljOGVkYjk5NzRkOTY4Njg0YTMzZTI3YzVjMmFkOTcwYmVh
|
15
|
-
NjhmMmE1NDRjMThjODE5NjhiOGIwYzVmYmZhOTNhZjM0ZGY2MTE=
|
6
|
+
metadata.gz: a92791fc15d5ea12d87ee7d33716cc1b5cf7e14507a7127b99bb2d7faf12747db4d652012cfbc15d16182593302e9a833ea767ee235f985d329c3b1c3e03ff63
|
7
|
+
data.tar.gz: 4cd5134d5e4204172e18dc5dff19d057b20f69a595c769f3666fdb8b08ad6cdfc63d893d8d13dc3045ad3f6010828ca8c5a1007713f1022ec2587d7cb1f0f435
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -4,3 +4,9 @@ source 'https://rubygems.org'
|
|
4
4
|
gemspec
|
5
5
|
|
6
6
|
gem 'spring', group: :development
|
7
|
+
|
8
|
+
file = File.expand_path("Gemfile", ENV['ENGINE_CART_DESTINATION'] || ENV['RAILS_ROOT'] || File.expand_path("../spec/internal", __FILE__))
|
9
|
+
if File.exists?(file)
|
10
|
+
puts "Loading #{file} ..." if $DEBUG # `ruby -d` or `bundle -v`
|
11
|
+
instance_eval File.read(file)
|
12
|
+
end
|
data/HISTORY.md
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
[](http://badge.fury.io/rb/browse-everything)
|
2
|
-
[](https://travis-ci.org/projecthydra-labs/browse-everything)
|
3
3
|
|
4
4
|
# BrowseEverything
|
5
5
|
|
@@ -12,6 +12,8 @@ The gem uses [OAuth](http://oauth.net/) to connect to a user's account and
|
|
12
12
|
generate a list of single use urls that your application can then use to
|
13
13
|
download the files.
|
14
14
|
|
15
|
+
**This gem does not depend on hydra-head**
|
16
|
+
|
15
17
|
## Installation
|
16
18
|
|
17
19
|
Add this line to your application's Gemfile:
|
@@ -121,7 +123,7 @@ If you initialized browse-everything via JavaScript, the results data passed to
|
|
121
123
|
}, {
|
122
124
|
"url": "https://dl.dropbox.com/fake/Getting%20Started.pdf",
|
123
125
|
"expires": "2014-03-31T20:37:36.731Z",
|
124
|
-
"file_name": "Getting
|
126
|
+
"file_name": "Getting Started.pdf"
|
125
127
|
}
|
126
128
|
]
|
127
129
|
```
|
@@ -138,11 +140,37 @@ If you initialized browse-everything via data-attributes and set the _target_ op
|
|
138
140
|
"1"=>{
|
139
141
|
"url"=>"https://dl.dropbox.com/fake/Getting%20Started.pdf",
|
140
142
|
"expires"=>"2014-03-31T20:37:36.731Z",
|
141
|
-
"file_name"=>"Getting
|
143
|
+
"file_name"=>"Getting Started.pdf"
|
142
144
|
}
|
143
145
|
}
|
144
146
|
```
|
145
147
|
|
148
|
+
### Retrieving Files
|
149
|
+
|
150
|
+
The `BrowseEverything::Retriever` class has two methods, `#retrieve` and `#download`, that
|
151
|
+
can be used to retrieve selected content. `#retrieve` streams the file by yielding it, chunk
|
152
|
+
by chunk, to a block, while `#download` saves it to a local file.
|
153
|
+
|
154
|
+
Given the above response data:
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
retriever = BrowseEverything::Retriever.new
|
158
|
+
download_spec = params['selected_files']['1']
|
159
|
+
|
160
|
+
# Retrieve the file, yielding each chunk to a block
|
161
|
+
retriever.retrieve(download_spec) do |chunk, retrieved, total|
|
162
|
+
# do something with the `chunk` of data received, and/or
|
163
|
+
# display some progress using `retrieved` and `total` bytes.
|
164
|
+
end
|
165
|
+
|
166
|
+
# Download the file. If `target_file` isn't specified, the
|
167
|
+
# retriever will create a tempfile and return the name.
|
168
|
+
retriever.download(download_spec, target_file) do |filename, retrieved, total|
|
169
|
+
# The block is still useful for showing progress, but the
|
170
|
+
# first argument is the filename instead of a chunk of data.
|
171
|
+
end
|
172
|
+
```
|
173
|
+
|
146
174
|
### Examples
|
147
175
|
|
148
176
|
See `spec/support/app/views/file_handler/index.html` for an example use case. You can also run `rake app:generate` to
|
@@ -156,3 +184,7 @@ create a fully-functioning demo app in `spec/internal` (though you will have to
|
|
156
184
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
157
185
|
4. Push to the branch (`git push origin my-new-feature`)
|
158
186
|
5. Create new Pull Request
|
187
|
+
|
188
|
+
## Help
|
189
|
+
|
190
|
+
For help with Questioning Authority, contact <hydra-tech@googlegroups.com>.
|
data/Rakefile
CHANGED
@@ -3,7 +3,8 @@ $ ->
|
|
3
3
|
|
4
4
|
initialize = (obj,options) ->
|
5
5
|
if $('div#browse-everything').length == 0
|
6
|
-
dialog = $('<div id="browse-everything" class="ev-browser modal fade"></div>').hide().appendTo('body')
|
6
|
+
dialog = $('<div tabindex="-1" id="browse-everything" class="ev-browser modal fade" aria-live="polite" role="dialog" aria-labelledby="beModalLabel"></div>').hide().appendTo('body')
|
7
|
+
|
7
8
|
dialog.modal
|
8
9
|
backdrop: 'static'
|
9
10
|
show: false
|
@@ -25,7 +26,7 @@ $ ->
|
|
25
26
|
toHiddenFields = (data) ->
|
26
27
|
fields = $.param(data)
|
27
28
|
.split('&')
|
28
|
-
.map (t) -> t.split('=',2)
|
29
|
+
.map (t) -> t.replace('+',' ','g').split('=',2)
|
29
30
|
elements = $(fields).map () ->
|
30
31
|
$("<input type='hidden'/>")
|
31
32
|
.attr('name',decodeURIComponent(this[0]))
|
@@ -45,22 +46,29 @@ $ ->
|
|
45
46
|
onNodeExpand: ->
|
46
47
|
node = this
|
47
48
|
$('body').css('cursor','wait')
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
49
|
+
$("html").addClass("wait")
|
50
|
+
size = $(node.row).find('td.ev-file-size').text().trim()
|
51
|
+
start = 1
|
52
|
+
increment = 1
|
53
|
+
if (size.indexOf("MB") >-1)
|
54
|
+
start = 10
|
55
|
+
increment = 5
|
56
|
+
if (size.indexOf("KB") >-1)
|
57
|
+
start = 50
|
58
|
+
increment = 10
|
59
|
+
setProgress(start)
|
60
|
+
progressIntervalID = setInterval (->
|
61
|
+
start = start + increment
|
62
|
+
if start > 99
|
63
|
+
start = 99
|
64
|
+
setProgress(start)
|
65
|
+
), 2000
|
66
|
+
setTimeout (->
|
67
|
+
loadFiles(node, table, progressIntervalID)
|
68
|
+
), 10
|
69
|
+
$("#file-list tr:first").focus()
|
62
70
|
sizeColumns(table)
|
63
|
-
|
71
|
+
|
64
72
|
sizeColumns = (table) ->
|
65
73
|
full_width = $('.ev-files').width()
|
66
74
|
table.width(full_width)
|
@@ -71,6 +79,32 @@ $ ->
|
|
71
79
|
set_size '.ev-kind', 0.3
|
72
80
|
set_size '.ev-date', 0.2
|
73
81
|
|
82
|
+
loadFiles = (node, table, progressIntervalID)->
|
83
|
+
$.ajax
|
84
|
+
async: true # Must be false, otherwise loadBranch happens after showChildren?
|
85
|
+
url: $('a.ev-link',node.row).attr('href')
|
86
|
+
data:
|
87
|
+
parent: node.row.data('tt-id')
|
88
|
+
accept: dialog.data('context').opts.accept
|
89
|
+
context: dialog.data('context').opts.context
|
90
|
+
.done (html) ->
|
91
|
+
setProgress('100')
|
92
|
+
clearInterval progressIntervalID
|
93
|
+
rows = $('tbody tr',$(html))
|
94
|
+
table.treetable("loadBranch", node, rows)
|
95
|
+
$(node).show()
|
96
|
+
sizeColumns(table)
|
97
|
+
indicateSelected()
|
98
|
+
.always ->
|
99
|
+
clearInterval progressIntervalID
|
100
|
+
$('body').css('cursor','default')
|
101
|
+
$("html").removeClass("wait")
|
102
|
+
|
103
|
+
setProgress = (done)->
|
104
|
+
$('#loading_progress').css('width',done+'%')
|
105
|
+
$('#loading_progress').html(done+'% complete')
|
106
|
+
$('#loading_progress').attr('aria-valuenow', done)
|
107
|
+
|
74
108
|
refreshFiles = ->
|
75
109
|
$('.ev-providers select').change()
|
76
110
|
|
@@ -86,6 +120,7 @@ $ ->
|
|
86
120
|
setTimeout refreshFiles, 500
|
87
121
|
ctx.callbacks.show.fire()
|
88
122
|
dialog.modal('show')
|
123
|
+
|
89
124
|
if ctx
|
90
125
|
ctx.callback_proxy
|
91
126
|
else
|
@@ -125,6 +160,7 @@ $ ->
|
|
125
160
|
.always ->
|
126
161
|
$('body').css('cursor','default')
|
127
162
|
$('.ev-browser').modal('hide')
|
163
|
+
$('#browse-btn').focus()
|
128
164
|
|
129
165
|
$(document).on 'click', '.ev-files table tr', (event) ->
|
130
166
|
$('a.ev-link',this).click() unless event.target.nodeName == 'A'
|
@@ -148,9 +184,13 @@ $ ->
|
|
148
184
|
.done (data) ->
|
149
185
|
$('.ev-files').html(data)
|
150
186
|
indicateSelected();
|
187
|
+
$('#provider_auth').focus();
|
151
188
|
tableSetup($('table#file-list'))
|
152
189
|
.fail (xhr,status,error) ->
|
153
|
-
|
190
|
+
if (xhr.responseText.indexOf("Refresh token has expired")>-1)
|
191
|
+
$('.ev-files').html("Your sessison has expired please clear your cookies.")
|
192
|
+
else
|
193
|
+
$('.ev-files').html(xhr.responseText)
|
154
194
|
.always ->
|
155
195
|
$('body').css('cursor','default')
|
156
196
|
|
@@ -1,3 +1,3 @@
|
|
1
1
|
<h2><%=t('browse_everything.auth_prompt.head', provider: provider.name)%></h2>
|
2
2
|
<p><%=t('browse_everything.auth_prompt.text', provider: provider.name)%></p>
|
3
|
-
<p><%= link_to t('browse_everything.auth_prompt.button_text', provider: provider.name), auth_link, class:"btn btn-primary ev-auth", target:'blank' %></p>
|
3
|
+
<p><%= link_to t('browse_everything.auth_prompt.button_text', provider: provider.name), auth_link, class:"btn btn-primary ev-auth", target:'blank', id:'provider_auth' %></p>
|
@@ -1,17 +1,19 @@
|
|
1
1
|
<% unless file.relative_parent_path? %>
|
2
|
-
<tr data-ev-location="<%= file.location %>" data-tt-id="<%=path%>" data-tt-parent-id="<%=parent%>" data-tt-branch="<%=file.container? ? 'true' : 'false'%>">
|
3
|
-
<td class="<%=file.container? ? 'ev-container' : 'ev-file'%> ev-file-name">
|
4
|
-
|
5
|
-
|
6
|
-
|
2
|
+
<tr role="row" tabindex="-1" data-ev-location="<%= file.location %>" data-tt-id="<%=path%>" data-tt-parent-id="<%=parent%>" data-tt-branch="<%=file.container? ? 'true' : 'false'%>">
|
3
|
+
<td role="gridcell" class="<%=file.container? ? 'ev-container' : 'ev-file'%> ev-file-name">
|
4
|
+
<%= link_to browse_everything_engine.contents_path(provider_name,file.id), {:class=>'ev-link'} do %>
|
5
|
+
<span class="<%=file.container? ? 'folder' : 'file'%>" aria-hidden="true"/>
|
6
|
+
<%= file.name %>
|
7
|
+
<span class="sr-only"><%= file.container? ? ', folder' : ', file' %> </span>
|
8
|
+
<% end %>
|
7
9
|
</td>
|
8
|
-
<td class="ev-file-size">
|
10
|
+
<td role="gridcell" class="ev-file-size">
|
9
11
|
<%= number_to_human_size(file.size).sub(/Bytes/,'bytes') %>
|
10
12
|
</td>
|
11
|
-
<td class="ev-file-kind">
|
13
|
+
<td role="gridcell" class="ev-file-kind">
|
12
14
|
<%= file.type %>
|
13
15
|
</td>
|
14
|
-
<td class="ev-file-date">
|
16
|
+
<td role="gridcell" class="ev-file-date">
|
15
17
|
<%= file.mtime.strftime('%F %R') %>
|
16
18
|
</td>
|
17
19
|
</tr>
|
@@ -1,11 +1,16 @@
|
|
1
1
|
<% if provider.present? %>
|
2
|
-
<
|
2
|
+
<div class="progress" id="loading_progress" aria-live="polite">
|
3
|
+
<div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 100%;">
|
4
|
+
100% Complete
|
5
|
+
</div>
|
6
|
+
</div>
|
7
|
+
<table id="file-list" role="grid" tabindex="-1" title="Choose files to upload from the table below" aria-live="polite">
|
3
8
|
<thead>
|
4
|
-
<tr>
|
5
|
-
<th>Name</th>
|
6
|
-
<th>Size</th>
|
7
|
-
<th>Kind</th>
|
8
|
-
<th>Modified</th>
|
9
|
+
<tr role="row" tabindex="-1">
|
10
|
+
<th role="columnheader">Name</th>
|
11
|
+
<th role="columnheader">Size</th>
|
12
|
+
<th role="columnheader">Kind</th>
|
13
|
+
<th role="columnheader">Modified</th>
|
9
14
|
</tr>
|
10
15
|
</thead>
|
11
16
|
<% provider.contents(browse_path).each_with_index do |file,index| %>
|
@@ -1,11 +1,12 @@
|
|
1
|
-
<% if bootstrap_three? %><div class="modal-content"><% end %>
|
1
|
+
<% if bootstrap_three? %><div class="modal-dialog"><div class="modal-content"><% end %>
|
2
2
|
<div class="modal-header">
|
3
|
+
<h4 class="sr-only" id="beModalLabel">Select a provider in the list to browse your files.</h4>
|
3
4
|
<div class="ev-providers">
|
4
5
|
<%= render :partial => 'providers' %>
|
5
6
|
</div>
|
6
7
|
</div>
|
7
|
-
<div class="modal-body ev-body">
|
8
|
-
<div class="ev-browser row<%=bs2('-fluid')%>">
|
8
|
+
<div class="modal-body ev-body" tabindex="-1">
|
9
|
+
<div class="ev-browser row<%=bs2('-fluid')%>" aria-live="polite">
|
9
10
|
<div class="<%=fa3or4('fa3','fa4')%> <%=bs2or3('bs2 span','bs3 col-xs-')%>12 ev-files list">
|
10
11
|
<%= render :partial => 'files' %>
|
11
12
|
</div>
|
@@ -19,4 +20,4 @@
|
|
19
20
|
<button class="ev-submit btn btn-primary" data-loading-text="Loading..."><%= t('browse_everything.modal_form.submit')%></button>
|
20
21
|
<% end %>
|
21
22
|
</div>
|
22
|
-
<% if bootstrap_three? %></div><% end %>
|
23
|
+
<% if bootstrap_three? %></div></div><% end %>
|
data/browse-everything.gemspec
CHANGED
@@ -27,6 +27,7 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.add_dependency "bootstrap-sass"
|
28
28
|
spec.add_dependency "font-awesome-rails"
|
29
29
|
spec.add_dependency "google-api-client"
|
30
|
+
spec.add_dependency "httparty"
|
30
31
|
spec.add_development_dependency "rspec", "~> 3.0"
|
31
32
|
spec.add_development_dependency "rspec-rails"
|
32
33
|
spec.add_development_dependency "rspec-its"
|
@@ -38,5 +39,6 @@ Gem::Specification.new do |spec|
|
|
38
39
|
spec.add_development_dependency "vcr"
|
39
40
|
spec.add_development_dependency "sqlite3"
|
40
41
|
spec.add_development_dependency "factory_girl_rails"
|
42
|
+
spec.add_development_dependency "engine_cart"
|
41
43
|
|
42
44
|
end
|
data/lib/browse_everything.rb
CHANGED
@@ -43,7 +43,7 @@ module BrowseEverything
|
|
43
43
|
file = box_client.file(path)
|
44
44
|
download_url = file.download_url
|
45
45
|
auth_header = {'Authorization' => "Bearer #{@token}"}
|
46
|
-
extras = { auth_header: auth_header, expires: 1.hour.from_now, file_name:file.name }
|
46
|
+
extras = { auth_header: auth_header, expires: 1.hour.from_now, file_name: file.name, file_size: file.size.to_i }
|
47
47
|
[download_url,extras]
|
48
48
|
end
|
49
49
|
|
@@ -120,4 +120,4 @@ module BrowseEverything
|
|
120
120
|
end
|
121
121
|
|
122
122
|
end
|
123
|
-
end
|
123
|
+
end
|
@@ -38,7 +38,7 @@ module BrowseEverything
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def link_for(path)
|
41
|
-
[client.media(path)['url'], { expires: 4.hours.from_now, file_name: File.basename(path) }]
|
41
|
+
[client.media(path)['url'], { expires: 4.hours.from_now, file_name: File.basename(path), file_size: client.metadata(path)['bytes'].to_i }]
|
42
42
|
end
|
43
43
|
|
44
44
|
def details(path)
|
@@ -50,7 +50,9 @@ module BrowseEverything
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def link_for(path)
|
53
|
-
|
53
|
+
full_path = File.expand_path(path)
|
54
|
+
file_size = File.size(full_path).to_i rescue 0
|
55
|
+
["file://#{full_path}", { file_name: File.basename(path), file_size: file_size }]
|
54
56
|
end
|
55
57
|
|
56
58
|
def authorized?
|
@@ -59,4 +61,4 @@ module BrowseEverything
|
|
59
61
|
end
|
60
62
|
|
61
63
|
end
|
62
|
-
end
|
64
|
+
end
|
@@ -61,7 +61,12 @@ module BrowseEverything
|
|
61
61
|
api_result = oauth_client.execute(api_method: api_method, parameters: {fileId: id})
|
62
62
|
download_url = JSON.parse(api_result.response.body)["downloadUrl"]
|
63
63
|
auth_header = {'Authorization' => "Bearer #{oauth_client.authorization.access_token.to_s}"}
|
64
|
-
extras = {
|
64
|
+
extras = {
|
65
|
+
auth_header: auth_header,
|
66
|
+
expires: 1.hour.from_now,
|
67
|
+
file_name: api_result.data.title,
|
68
|
+
file_size: api_result.data.fileSize.to_i
|
69
|
+
}
|
65
70
|
[download_url, extras]
|
66
71
|
end
|
67
72
|
|
@@ -123,4 +128,4 @@ module BrowseEverything
|
|
123
128
|
end
|
124
129
|
|
125
130
|
end
|
126
|
-
end
|
131
|
+
end
|
@@ -47,7 +47,7 @@ module BrowseEverything
|
|
47
47
|
|
48
48
|
def link_for(path)
|
49
49
|
response = Skydrive::Client.new(rehydrate_token).get("/#{real_id(path)}/")
|
50
|
-
[response.download_link, {expires: 1.hour.from_now, file_name: File.basename(path)}]
|
50
|
+
[response.download_link, {expires: 1.hour.from_now, file_name: File.basename(path), file_size: response.size.to_i}]
|
51
51
|
end
|
52
52
|
|
53
53
|
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'tempfile'
|
3
|
+
|
4
|
+
module BrowseEverything
|
5
|
+
class Retriever
|
6
|
+
attr_accessor :chunk_size
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@chunk_size = 16384
|
10
|
+
end
|
11
|
+
|
12
|
+
def download(spec, target=nil)
|
13
|
+
if target.nil?
|
14
|
+
ext = File.extname(spec['file_name'])
|
15
|
+
base = File.basename(spec['file_name'],ext)
|
16
|
+
target = Dir::Tmpname.create([base,ext]) {}
|
17
|
+
end
|
18
|
+
|
19
|
+
File.open(target, 'wb') do |output|
|
20
|
+
self.retrieve(spec) do |chunk, retrieved, total|
|
21
|
+
output.write(chunk)
|
22
|
+
yield(target, retrieved, total) if block_given?
|
23
|
+
end
|
24
|
+
end
|
25
|
+
return target
|
26
|
+
end
|
27
|
+
|
28
|
+
def retrieve(spec, &block)
|
29
|
+
if spec.has_key?('expires') and Time.parse(spec['expires']) < Time.now
|
30
|
+
raise ArugumentError, "Download spec expired at #{spec['expires']}"
|
31
|
+
end
|
32
|
+
|
33
|
+
url = URI.parse(spec['url'])
|
34
|
+
retrieved = 0
|
35
|
+
case url.scheme
|
36
|
+
when 'file'
|
37
|
+
File.open(url.path,'rb') do |f|
|
38
|
+
while not f.eof?
|
39
|
+
chunk = f.read(chunk_size)
|
40
|
+
retrieved += chunk.length
|
41
|
+
yield(chunk, retrieved, spec['file_size'].to_i)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
when /https?/
|
45
|
+
headers = spec['auth_header'] || {}
|
46
|
+
headers.each_pair do |k,v|
|
47
|
+
headers[k] = v.gsub(/\+/,' ')
|
48
|
+
end
|
49
|
+
|
50
|
+
HTTParty.get(url.to_s, headers: headers) do |chunk|
|
51
|
+
retrieved += chunk.length
|
52
|
+
yield(chunk, retrieved, spec['file_size'].to_i)
|
53
|
+
end
|
54
|
+
else
|
55
|
+
raise URI::BadURIError, "Unknown URI scheme: #{uri.scheme}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|