diff --git a/.rubocop.yml b/.rubocop.yml
index 88c237bf..3363bb79 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -29,6 +29,10 @@ Metrics/BlockLength:
Exclude:
- '*.gemspec'
- 'spec/**/*'
+Metrics/ClassLength:
+ Exclude:
+ - 'lib/browse_everything/retriever.rb'
+ - 'lib/browse_everything/driver/google_drive.rb'
Metrics/MethodLength:
Exclude:
- 'app/controllers/browse_everything_controller.rb'
diff --git a/app/assets/javascripts/browse_everything/behavior.js b/app/assets/javascripts/browse_everything/behavior.js
index a83a1e5b..e9ec801b 100644
--- a/app/assets/javascripts/browse_everything/behavior.js
+++ b/app/assets/javascripts/browse_everything/behavior.js
@@ -13,28 +13,51 @@ function BrowseEverythingForm(form) {
* Append a hidden element for the form for a file entry
* @param resource {BrowseEverythingResource}
*/
-BrowseEverythingForm.prototype.appendFileInputElement = function(resource) {
+BrowseEverythingForm.prototype.appendFileInputElements = function(resource) {
// Add the location
- var hidden_input = $("").val(resource.getLocation());
- this.$form.append(hidden_input);
+ var location_input = $("").val(resource.getLocation());
+ this.$form.append(location_input);
// Add the name
- var hidden_input = $("").val(resource.getName());
- this.$form.append(hidden_input);
+ var name_input = $("").val(resource.getName());
+ this.$form.append(name_input);
// Add the size
- var hidden_input = $("").val(resource.getSize());
- this.$form.append(hidden_input);
+ var size_input = $("").val(resource.getSize());
+ this.$form.append(size_input);
+ // Add the type
+ var type_input = $("").val(false);
+ this.$form.append(type_input);
+
+ var provider_input = $("").val( resource.$element.data('ev-provider') );
+ this.$form.append(provider_input);
};
/**
* Append a hidden element for the form for a directory entry
* @param resource {BrowseEverythingResource}
*/
-BrowseEverythingForm.prototype.appendDirectoryInputElement = function(resource) {
- var hidden_input = $("").val(resource.getLocation());
- this.$form.append(hidden_input);
+BrowseEverythingForm.prototype.appendDirectoryInputElements = function(resource) {
+ // Add the location
+ var location_input = $("").val(resource.getLocation());
+ this.$form.append(location_input);
+
+ // Add the name
+ var name_input = $("").val(resource.getName());
+ this.$form.append(name_input);
+
+ // Add the size
+ var size_input = $("").val(resource.getSize());
+ this.$form.append(size_input);
+
+ // Add the type
+ var type_input = $("").val(true);
+ this.$form.append(type_input);
+
+ // Add the provider
+ var provider_input = $("").val( resource.$element.data('ev-provider') );
+ this.$form.append(provider_input);
};
/**
@@ -62,6 +85,22 @@ BrowseEverythingResource.prototype.getLocation = function () {
return this.$element.data('ev-location');
};
+/*
+ *
+ * @return {string}
+ */
+BrowseEverythingResource.prototype.getName = function () {
+ return this.$element.data('ev-file-name');
+};
+
+/*
+ *
+ * @return {string}
+ */
+BrowseEverythingResource.prototype.getSize = function () {
+ return this.$element.data('ev-file-size');
+};
+
/*
* Static factory method for building objects
* @param element {Element|jQuery}
diff --git a/app/controllers/browse_everything_controller.rb b/app/controllers/browse_everything_controller.rb
index 5b83bc84..bb514ea6 100644
--- a/app/controllers/browse_everything_controller.rb
+++ b/app/controllers/browse_everything_controller.rb
@@ -81,24 +81,22 @@ def resolve
selected_links = []
selected_directories = []
payload = {}
- last_provider_key = nil
selected_files.each do |file|
- binding.pry
location = file[:location]
provider_key_value, id = location.split(/:/)
provider_key = provider_key_value.to_sym
+ provider = browser.providers[provider_key]
- values = browser.providers[provider_key].link_for(id, file[:name], file[:size])
+ values = provider.link_for(id, file[:name], file[:size], file[:container] == "true")
values.each do |value|
(url, extra) = value
result = { url: url }
result.merge!(extra) unless extra.nil?
selected_links << result unless result.fetch(:directory, false)
+ # These are being ignored
selected_directories << result if result.fetch(:directory, false) && !selected_directories.include?(result)
end
-
- last_provider_key = provider_key
end
payload = selected_links
@@ -167,7 +165,7 @@ def provider_name
# Hence, a Browser must be reinstantiated for each request using the state provided in the Rails session
# @return [BrowseEverything::Browser]
def browser
- BrowserFactory.build(session: session, url_options: url_options)
+ BrowseEverything.current_browser = BrowserFactory.build(session: session, url_options: url_options)
end
# Retrieves a cached provider, or, defaults to the first configured provider
diff --git a/app/views/browse_everything/_files.html.erb b/app/views/browse_everything/_files.html.erb
index d7164f18..f19c2d20 100644
--- a/app/views/browse_everything/_files.html.erb
+++ b/app/views/browse_everything/_files.html.erb
@@ -18,9 +18,67 @@
<% provider_contents.each_with_index do |file, index| %>
<% next if file.nil? %>
- <%= render partial: 'file', locals: { file: file, index: index, path: browse_everything_engine.contents_path(provider_name, file.id), parent: parent, disabled: disabled?(file: file) } %>
<% path = browse_everything_engine.contents_path(provider_name, file.id) %>
<% disabled = disabled?(file: file) %>
+
+
+ data-ev-provider="<%= file.provider_name %>"
+ data-tt-id="<%= path %>"
+ data-tt-parent-id="<%= parent %>"
+ data-tt-branch="<%= file.container? ? 'true' : 'false' %>">
+
+
+ <% if disabled %>
+
+ <%= file.name %>
+
+ <%= file.container? ? ', folder' : ', file' %>
+ <% else %>
+ <%= link_to(path, class: 'ev-link') do %>
+
+ <%= file.name %>
+ <%= file.container? ? ', folder' : ', file' %>
+ <% end %>
+ <% end %>
+ |
+ <% if file.container? %>
+
+ <%= check_box_tag(:select_all, "0", false, class: "ev-select-all") %>
+ |
+ <% else %>
+
+ <%= check_box_tag(file.id.to_s.parameterize, "0", false, class: "ev-select-file") %>
+ |
+ <% end %>
+
+ <% if file.size %>
+
+ <%= number_to_human_size(file.size).sub(/Bytes/,'bytes') %>
+ |
+ <% else %>
+ Unknown |
+ <% end %>
+
+
+ <%= file.type %>
+ |
+
+ <% if file.mtime %>
+
+ <%= file.mtime.strftime('%F %R') %>
+ |
+ <% else %>
+ Unknown |
+ <% end %>
+
<% end %>
<%= render partial: 'files_pages' %>
diff --git a/lib/browse_everything.rb b/lib/browse_everything.rb
index 41376c8b..de408dbf 100644
--- a/lib/browse_everything.rb
+++ b/lib/browse_everything.rb
@@ -52,9 +52,15 @@ class NotAuthorizedError < StandardError; end
class << self
attr_writer :config
+ attr_accessor :current_browser
+
+ def current_provider
+ current_browser.session
+ end
def configure(value)
return if value.nil?
+
if value.is_a?(Hash)
@config = ActiveSupport::HashWithIndifferentAccess.new value
elsif value.is_a?(String)
@@ -78,10 +84,10 @@ def configure(value)
end
def config
- if @config.nil?
- config_path = Rails.root.join 'config', 'browse_everything_providers.yml'
- configure config_path.to_s
- end
+ return @config unless @config.nil?
+
+ config_path = Rails.root.join('config', 'browse_everything_providers.yml')
+ configure(config_path.to_s)
@config
end
end
diff --git a/lib/browse_everything/browser.rb b/lib/browse_everything/browser.rb
index 24cf4314..2b841341 100644
--- a/lib/browse_everything/browser.rb
+++ b/lib/browse_everything/browser.rb
@@ -5,20 +5,27 @@ class Browser
attr_reader :providers
def initialize(opts = {})
- url_options = {}
+ config = BrowseEverything.config
+
if opts.key?(:url_options)
url_options = opts.delete(:url_options)
+ # config = config.merge(opts.deep_stringify_keys)
+ config = config.merge(opts)
else
url_options = opts
- opts = BrowseEverything.config
end
@providers = ActiveSupport::HashWithIndifferentAccess.new
- opts.each_pair do |driver_key, config|
+
+ # This iterates through the configuration for each provider
+ config.each_pair do |driver_key, driver_config|
begin
driver = driver_key.to_s
- driver_klass = BrowseEverything::Driver.const_get((config[:driver] || driver).camelize.to_sym)
- @providers[driver_key] = driver_klass.new(config.merge(url_options: url_options))
+ driver_name = driver_config[:driver] || driver
+ driver_const = driver_name.camelize.to_sym
+ driver_klass = BrowseEverything::Driver.const_get(driver_const)
+ driver_args = driver_config.merge(url_options: url_options)
+ @providers[driver_key] = driver_klass.new(driver_args)
rescue NameError
Rails.logger.warn "Unknown provider: #{driver}"
end
diff --git a/lib/browse_everything/driver/base.rb b/lib/browse_everything/driver/base.rb
index c62ec5e1..81b19d76 100644
--- a/lib/browse_everything/driver/base.rb
+++ b/lib/browse_everything/driver/base.rb
@@ -33,6 +33,19 @@ def default_sorter
def inherited(subclass)
subclass.sorter = sorter
end
+
+ # Determine the content media/MIME type from the file extension name
+ # @param [String] extname
+ # @return [String]
+ def mime_type(extname)
+ Rack::Mime.mime_type(extname)
+ end
+
+ # Generate the default content media/MIME type for a container resource
+ # @return [String]
+ def container_mime_type
+ 'application/x-directory'
+ end
end
# Constructor
diff --git a/lib/browse_everything/driver/box.rb b/lib/browse_everything/driver/box.rb
index 76fe42b5..ae6bb9ed 100644
--- a/lib/browse_everything/driver/box.rb
+++ b/lib/browse_everything/driver/box.rb
@@ -60,7 +60,13 @@ def link_for(id)
file = box_client.file_by_id(id)
download_url = file.download_url
auth_header = { 'Authorization' => "Bearer #{@token}" }
- extras = { auth_header: auth_header, expires: 1.hour.from_now, file_name: file.name, file_size: file.size.to_i }
+ extras = {
+ auth_token: @token,
+ auth_header: auth_header,
+ expires: 1.hour.from_now,
+ file_name: file.name,
+ file_size: file.size.to_i
+ }
[download_url, extras]
end
@@ -147,7 +153,16 @@ def expiration_time
# @param file [String] ID to the file resource
# @return [BrowseEverything::File]
def directory_entry(file)
- BrowseEverything::FileEntry.new(file.id, "#{key}:#{file.id}", file.name, file.size, file.created_at, file.type == 'folder')
+ BrowseEverything::FileEntry.new(
+ file.id,
+ "#{key}:#{file.id}",
+ file.name,
+ file.size,
+ file.created_at,
+ file.type == 'folder',
+ nil,
+ 'box'
+ )
end
end
end
diff --git a/lib/browse_everything/driver/file_system.rb b/lib/browse_everything/driver/file_system.rb
index 6bf2e224..8dfd5652 100644
--- a/lib/browse_everything/driver/file_system.rb
+++ b/lib/browse_everything/driver/file_system.rb
@@ -3,6 +3,10 @@
module BrowseEverything
module Driver
class FileSystem < Base
+ def self.container_mime_type
+ 'application/x-directory'
+ end
+
def icon
'file'
end
@@ -11,42 +15,74 @@ def validate_config
raise BrowseEverything::InitializationError, 'FileSystem driver requires a :home argument' if config[:home].blank?
end
- def contents(path = '', _page_index = 0)
- real_path = File.join(config[:home], path)
+ def contents(path = '', _page_index = 0, _auth_token = nil)
+ real_path = if path == '/' || !File.exist?(path)
+ File.join(home_path, path)
+ else
+ path
+ end
+
values = if File.directory?(real_path)
make_directory_entry real_path
else
[details(real_path)]
end
+
@entries = values.compact
@sorter.call(@entries)
end
+ # Generate the attributes Hash for a FileEntry object
+ # This should be moved to FileEntry#attributes
+ # @param [BrowseEverything::FileEntry] file_entry
+ # @param [String] access_token
+ # @return [Hash]
+ def attributes_for(file_entry, _access_token = nil)
+ full_path = File.expand_path(file_entry.id)
+ uri = "file://#{full_path}"
+
+ {
+ id: file_entry.id,
+ url: uri,
+ file_name: file_entry.name,
+ file_size: file_entry.size,
+ container: file_entry.container?,
+ provider: file_entry.provider_name
+ }
+ end
+
+ # Links need to be restructured as first-order objects
+ class Link < OpenStruct
+ def container?
+ directory.present?
+ end
+ end
+
# Retrieve an array of link attributes for a resource path
# @param path [String]
# @return [Array]
- def link_for(path)
+ def link_for(path, _file_name = '', _file_size = 0, _container = false, _access_token = nil)
full_path = File.expand_path(path)
+ return [] if hidden?(full_path)
- # Recurse if this is a directory
- if File.directory?(full_path)
- entries = []
- directory_entries = Dir.entries(full_path)
-
- directory_entries.sort.map do |file_path|
- next if /^\.\.?$/ =~ file_path
-
- entries << ["file://#{full_path}", { file_name: File.basename(full_path), file_size: 0, directory: true }]
- full_file_path = File.join(full_path, file_path)
- entries += link_for(full_file_path)
- end
- entries
- else
- return [] if hidden?(full_path)
- file_size = file_size(full_path)
- [["file://#{full_path}", { file_name: File.basename(path), file_size: file_size, directory: false }]]
- end
+ uri = "file://#{full_path}"
+ # Ignore the argument
+ file_name = File.basename(full_path)
+ # Ignore the argument
+ file_size = calculate_file_size(full_path)
+ container = File.directory?(full_path)
+
+ link_attributes = {
+ id: full_path,
+ file_name: file_name,
+ file_size: file_size,
+ container: container,
+ directory: container,
+ provider: 'file_system'
+ }
+
+ [[uri, link_attributes]]
end
def authorized?
@@ -59,14 +95,17 @@ def authorized?
# @return [BrowseEverything::FileEntry]
def details(path, display = File.basename(path))
return unless File.exist?(path)
+
info = File::Stat.new(path)
BrowseEverything::FileEntry.new(
- make_pathname(path),
+ path,
[key, path].join(':'),
display,
info.size,
info.mtime,
- info.directory?
+ info.directory?,
+ nil,
+ 'file_system'
)
end
@@ -81,14 +120,17 @@ def make_directory_entry(real_path)
Dir.glob(pattern).collect { |f| details(f) }
end
+ def home_path
+ Pathname.new(config[:home])
+ end
+
def make_pathname(path)
- home_path = Pathname.new(config[:home])
expanded = File.expand_path(path)
file_entry_path = Pathname.new(expanded)
file_entry_path.relative_path_from(home_path)
end
- def file_size(path)
+ def calculate_file_size(path)
File.size(path).to_i
rescue StandardError => error
Rails.logger.error "Failed to find the file size for #{path}: #{error}"
diff --git a/lib/browse_everything/driver/google_drive.rb b/lib/browse_everything/driver/google_drive.rb
index ddb94d2e..63cecf5f 100644
--- a/lib/browse_everything/driver/google_drive.rb
+++ b/lib/browse_everything/driver/google_drive.rb
@@ -120,7 +120,9 @@ def details(file, _path = '')
file.size.to_i,
file.modified_time || Time.new,
mime_folder,
- mime_folder ? 'directory' : file.mime_type
+ mime_folder ? 'directory' : file.mime_type,
+ 'google_drive',
+ credentials.access_token
)
end
@@ -159,50 +161,73 @@ def list_files(drive, request_params, path: '', page_token:)
# Retrieve the files for any given resource on Google Drive
# @param path [String] the root or Folder path for which to list contents
# @return [Array] file entries for the path
- def contents(path = '', page_token = nil)
+ def contents(path = '', page_token = nil, access_token = nil)
# Return the cached response if its been indexed into memory
path = 'root' if path.blank?
pages = pages_for_path(path)
return pages[page_token] if pages.indexed? page_token
request_params = Auth::Google::RequestParameters.new
+ request_params.q += " and '#{path}' in parents " if path.present?
+
+ restore_credentials(access_token) if @credentials.nil?
list_files(drive_service, request_params, path: path, page_token: page_token)
page_index = page_token || pagination_klass::FIRST_PAGE_TOKEN
@sorter.call(pages[page_index])
end
+ # Generates the authorization header for an access token
+ # @param [String] access_token
+ # @return [String] the JSON-encoded authorization header
+ def self.authorization_header(access_token)
+ JSON.generate(
+ "Authorization" => "Bearer #{access_token}"
+ )
+ end
+
+ # Generate the attributes Hash for a FileEntry object
+ # This should be moved to FileEntry#attributes
+ # @param [BrowseEverything::FileEntry] file_entry
+ # @param [String] access_token
+ # @return [Hash]
+ def attributes_for(file_entry, access_token = nil)
+ access_token = credentials.access_token if access_token.nil?
+ auth_header = self.class.authorization_header(access_token)
+ file_entry_url = download_url(file_entry.id)
+
+ {
+ id: file_entry.id,
+ url: file_entry_url,
+ auth_token: access_token,
+ auth_header: auth_header,
+ file_name: file_entry.name,
+ file_size: file_entry.size,
+ container: file_entry.container?,
+ provider: file_entry.provider_name
+ }
+ end
+
# Retrieve a link for a resource
# @param id [String] identifier for the resource
# @return [Array] authorized link to the resource
- def link_for(id, file_name = '', file_size = 0)
+ def link_for(id, file_name = '', file_size = 0, container = false, access_token = nil)
# This should be all that is needed
- auth_header = { 'Authorization' => "Bearer #{credentials.access_token}" }
+ access_token = credentials.access_token if access_token.nil?
+ auth_header = self.class.authorization_header(access_token)
+
extras = {
- auth_header: auth_header,
+ id: id,
expires: 1.hour.from_now,
file_name: file_name,
- file_size: file_size
+ file_size: file_size,
+ container: container,
+ provider: :google_drive,
+ auth_token: access_token,
+ auth_header: auth_header
}
- return [[download_url(id), extras]]
- file = drive_service.get_file(id, fields: 'id, name, size, mimeType')
- if file.mime_type == 'application/vnd.google-apps.folder'
- entries = []
- contents(file.id).map do |drive_file|
- entries += link_for(drive_file.id)
- end
- entries
- else
- auth_header = { 'Authorization' => "Bearer #{credentials.access_token}" }
- extras = {
- auth_header: auth_header,
- expires: 1.hour.from_now,
- file_name: file.name,
- file_size: file.size.to_i
- }
- [[download_url(id), extras]]
- end
+ [[download_url(id), extras]]
end
# Provides a URL for authorizing against Google Drive
@@ -298,7 +323,7 @@ def client_secrets
# @see http://www.rubydoc.info/gems/googleauth/Google/Auth/Stores/FileTokenStore FileTokenStore for googleauth
# @return [Tempfile] temporary file within which to cache credentials
def file_token_store_path
- Tempfile.new('gdrive.yaml')
+ Rails.root.join('tmp', 'gdrive.yaml')
end
# Provide the scope for the service granted access to the Google Drive
@@ -308,7 +333,7 @@ def scope
end
# Provides the user ID for caching access tokens
- #
+ #
# (This is a hack which attempts to anonymize the access tokens)
# @return [String] the ID for the user
def user_id
diff --git a/lib/browse_everything/driver/s3.rb b/lib/browse_everything/driver/s3.rb
index 30fc6c20..a311b75f 100644
--- a/lib/browse_everything/driver/s3.rb
+++ b/lib/browse_everything/driver/s3.rb
@@ -120,7 +120,16 @@ def client
# @param dir [String]
# @return [BrowseEverything::FileEntry]
def entry_for(name, size, date, dir)
- BrowseEverything::FileEntry.new(name, [key, name].join(':'), File.basename(name), size, date, dir)
+ BrowseEverything::FileEntry.new(
+ name,
+ [key, name].join(':'),
+ File.basename(name),
+ size,
+ date,
+ dir,
+ nil,
+ 's3'
+ )
end
# Populate the entries with FileEntry objects from an S3 listing
diff --git a/lib/browse_everything/file_entry.rb b/lib/browse_everything/file_entry.rb
index 2ab6c192..f711e4db 100644
--- a/lib/browse_everything/file_entry.rb
+++ b/lib/browse_everything/file_entry.rb
@@ -2,17 +2,23 @@
module BrowseEverything
class FileEntry
- attr_reader :id, :location, :name, :size, :mtime, :type
+ attr_reader :id, :location, :name, :size, :mtime, :type, :provider_name, :auth_token
- def initialize(id, location, name, size, mtime, container, type = nil)
+ # rubocop:disable Metrics/ParameterLists
+ def initialize(id, location, name, size, mtime, container, type = nil, provider_name = nil, auth_token = nil)
@id = id
@location = location
@name = name
@size = size
@mtime = mtime
@container = container
- @type = type || (@container ? 'application/x-directory' : Rack::Mime.mime_type(File.extname(name)))
+ @type = type
+ @provider_name = provider_name
+ @auth_token = auth_token
+
+ @type = default_type if @type.nil?
end
+ # rubocop:enable Metrics/ParameterLists
def relative_parent_path?
name =~ /^\.\.?$/ ? true : false
@@ -21,5 +27,37 @@ def relative_parent_path?
def container?
@container
end
+
+ def provider
+ return @provider unless @provider.nil?
+
+ provider = BrowserFactory.for(name: provider_name)
+ return BrowseEverything::Driver::Base.new({}) if provider.nil?
+
+ @provider = provider
+ end
+
+ def mime_type
+ extname = File.extname(name)
+ provider.class.mime_type(extname)
+ end
+
+ def default_type
+ return provider.class.container_mime_type if container?
+
+ mime_type
+ end
+
+ def url
+ return unless provider.respond_to?(:download_url)
+
+ provider.download_url(id)
+ end
+
+ def auth_header
+ return unless provider.respond_to?(:auth_header)
+
+ provider.auth_header(auth_token)
+ end
end
end
diff --git a/lib/browse_everything/retriever.rb b/lib/browse_everything/retriever.rb
index b80f4a6f..f1ac0aa1 100644
--- a/lib/browse_everything/retriever.rb
+++ b/lib/browse_everything/retriever.rb
@@ -49,7 +49,7 @@ def initialize
# Download a file or resource
# @param options [Hash]
# @param target [String, nil] system path to the downloaded file (defaults to a temporary file)
- def download(spec, target = nil)
+ def download_resource(spec, target = nil)
if target.nil?
ext = File.extname(spec['file_name'])
base = File.basename(spec['file_name'], ext)
@@ -65,6 +65,86 @@ def download(spec, target = nil)
target
end
+ # Construct the Provider object
+ # @param [String] name
+ # @return [BrowseEverything::Driver::Base]
+ def self.build_provider(name)
+ BrowserFactory.for(name: name)
+ end
+
+ # Retrieve the resources for directory or container resource
+ # @param spec [Hash] structure containing the download for the asset
+ # @return [Array]
+ def contents(container_attributes)
+ provider = self.class.build_provider(container_attributes.provider)
+ provider.contents(container_attributes.id, nil, container_attributes.auth_token)
+ end
+
+ class ResourceAttributes < OpenStruct
+ def container?
+ container == true || (container.is_a?(String) && container.casecmp('true').zero?)
+ end
+ end
+
+ # List member resources for a container resource
+ # @param [Hash] attrs structure containing the download for the container or
+ # single resource
+ # @option attrs [Boolean, String] :container
+ # @option attrs [String] :provider
+ # @option attrs [String] :path
+ # @option attrs [String] :auth_token
+ # @param [String] auth_token
+ # @return [Array]
+ def member_resources(attrs, auth_token = nil)
+ container_attributes = ResourceAttributes.new(attrs)
+
+ return [] unless container_attributes.container? && !container_attributes.provider.nil?
+ # Work-around, this should be removed
+ if auth_token.nil?
+ auth_token = container_attributes.auth_token
+ else
+ # This needs to be removed
+ container_attributes.auth_token = auth_token
+ end
+
+ member_entries = contents(container_attributes)
+ members = []
+ member_entries.each do |file_entry|
+ # This should be restructured to file_entry.provider
+ provider = self.class.build_provider(file_entry.provider_name)
+ member_attributes = provider.attributes_for(file_entry, auth_token)
+ if file_entry.container?
+ members += member_resources(member_attributes, auth_token)
+ else
+ members << member_attributes
+ end
+ end
+
+ members
+ end
+
+ # Download assets to a file
+ # @param spec [Hash] structure containing the download for the container or
+ # single resource
+ # @return [Array]
+ def download_resources(spec, target = nil)
+ if spec['container'] == 'true' && spec['provider']
+ downloaded = []
+ list_files(spec).each do |child_spec|
+ downloaded += download(child_spec)
+ end
+ downloaded
+ else
+ downloaded_file = download_file(spec, target)
+ [downloaded_file]
+ end
+ end
+
+ # Download an asset to a file
+ # @param spec [Hash] structure containing the download for the asset
+ # @return [Array]
+ alias download download_resource
+
# Retrieve the resource from the storage service
# @param options [Hash]
def retrieve(options, &block)
diff --git a/spec/controllers/browse_everything_controller_spec.rb b/spec/controllers/browse_everything_controller_spec.rb
index acdfaf2b..4e14d4dd 100644
--- a/spec/controllers/browse_everything_controller_spec.rb
+++ b/spec/controllers/browse_everything_controller_spec.rb
@@ -123,7 +123,26 @@
describe '#resolve' do
routes { BrowseEverything::Engine.routes }
- let(:selected_files) { ['file_system:/my/test/file.txt'] }
+ # let(:selected_files) { ['file_system:/my/test/file.txt'] }
+
+ # params["browse_everything"]["selected_files"]
+ # => ["file_system:/Users/griffinj/src/pulibrary/workspace5/figgy/staged_files/audio_file.wav", "name"=>"audio_file.wav", "size"=>"147550", "container"=>"false", "provider"=>"file_system"} permitted: false>]
+
+ let(:selected_files) do
+ [
+ location: "file_system:/my/test/file.txt",
+ name: "file.txt",
+ size: "147",
+ container: "false",
+ provider: "file_system"
+ ]
+ end
+
+ let(:params) do
+ {
+ selected_files: selected_files
+ }
+ end
before do
allow(provider).to receive(:token).and_return(nil)
@@ -141,10 +160,12 @@
json_response = JSON.parse(response.body)
expect(json_response).not_to be_empty
resolved = json_response.first
+ expect(resolved).to include "container" => false
expect(resolved).to include "directory" => false
expect(resolved).to include "file_name" => "file.txt"
- expect(resolved).to include "file_size" => 0
expect(resolved).to include "url" => "file:///my/test/file.txt"
+ expect(resolved).to include "id" => "/my/test/file.txt"
+ expect(resolved).to include "provider" => "file_system"
end
end
end
diff --git a/spec/lib/browse_everything/driver/file_system_spec.rb b/spec/lib/browse_everything/driver/file_system_spec.rb
index 1a105370..03688b4e 100644
--- a/spec/lib/browse_everything/driver/file_system_spec.rb
+++ b/spec/lib/browse_everything/driver/file_system_spec.rb
@@ -20,12 +20,12 @@
end
describe 'simple properties' do
- subject { provider }
+ subject { provider }
its(:name) { is_expected.to eq('File System') }
its(:key) { is_expected.to eq('file_system') }
- its(:icon) { is_expected.to be_a(String) }
- specify { is_expected.to be_authorized }
+ its(:icon) { is_expected.to be_a(String) }
+ specify { is_expected.to be_authorized }
end
describe '#contents' do
@@ -33,7 +33,9 @@
let(:contents) { provider.contents('/') }
context 'when there is one directory' do
- subject { contents[0] }
+ subject do
+ contents[0]
+ end
its(:name) { is_expected.to eq('dir_1') }
specify { is_expected.to be_container }
@@ -104,9 +106,20 @@
subject { provider.link_for('/path/to/file') }
it {
- is_expected.to eq([
- ['file:///path/to/file', { directory: false, file_name: 'file', file_size: 0 }]
- ])
+ is_expected.to eq(
+ [
+ [
+ 'file:///path/to/file', {
+ directory: false,
+ container: false,
+ file_name: 'file',
+ file_size: 0,
+ id: '/path/to/file',
+ provider: 'file_system'
+ }
+ ]
+ ]
+ )
}
end
end
diff --git a/spec/lib/browse_everything/driver/google_drive_spec.rb b/spec/lib/browse_everything/driver/google_drive_spec.rb
index 1b3524c9..3094d1eb 100644
--- a/spec/lib/browse_everything/driver/google_drive_spec.rb
+++ b/spec/lib/browse_everything/driver/google_drive_spec.rb
@@ -222,10 +222,14 @@
expect(link).to be_an Array
expect(link.first).to eq 'https://www.googleapis.com/drive/v3/files/asset-id2?alt=media'
expect(link.last).to be_a Hash
- expect(link.last).to include auth_header: { 'Authorization' => 'Bearer access-token' }
+ expect(link.last).to include auth_header: JSON.generate('Authorization' => 'Bearer access-token')
+ expect(link.last).to include auth_token: 'access-token'
+ expect(link.last).to include container: false
expect(link.last).to include :expires
- expect(link.last).to include file_name: 'asset-name2.pdf'
+ expect(link.last).to include :file_name
+ expect(link.last).to include id: 'asset-id2'
expect(link.last).to include file_size: 0
+ expect(link.last).to include provider: :google_drive
end
end