Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Virtual collection #24

Open
wants to merge 9 commits into
base: dev
Choose a base branch
from
80 changes: 79 additions & 1 deletion BrainPortal/app/controllers/userfiles_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class UserfilesController < ApplicationController

around_action :permission_check, :only => [
:download, :update_multiple, :delete_files,
:create_collection, :change_provider, :quality_control,
:create_collection, :create_virtual_collection, :change_provider, :quality_control,
:export_file_list
]

Expand Down Expand Up @@ -1040,6 +1040,84 @@ def create_collection #:nodoc:

end

#Create a collection from the selected files.
def create_virtual_collection #:nodoc:
filelist = params[:file_ids].uniq || []
data_provider_id = params[:data_provider_id_for_collection]
collection_name = params[:collection_name]
file_group = current_assignable_group.id

if data_provider_id.blank?
flash[:error] = "No data provider selected.\n"
redirect_to :action => :index
return
end

# Handle collection name
if collection_name.blank?
suffix = Time.now.to_i
while Userfile.where(:user_id => current_user.id, :name => "VirtualCollection-#{suffix}").first.present?
suffix += 1
end
collection_name = "VirtualCollection-#{suffix}"
end

if ! Userfile.is_legal_filename?(collection_name)
flash[:error] = "Error: collection name '#{collection_name}' is not acceptable (illegal characters?)."
redirect_to :action => :index, :format => request.format.to_sym
return
end

# Check if the collection name chosen by the user already exists for this user on the data_provider
if current_user.userfiles.exists?(:name => collection_name, :data_provider_id => data_provider_id)
flash[:error] = "Error: collection with name '#{collection_name}' already exists."
redirect_to :action => :index, :format => request.format.to_sym
return
end

userfiles = Userfile.find_accessible_by_user(filelist, current_user, :access_requested => :read)

# todo double check how 0 is possible, bad files should cause exception
if userfiles.count == 0
flash[:error] = "Error: Inaccessible files selected."
redirect_to :action => :index, :format => request.format.to_sym
return
end

collection = VirtualFileCollection.new(
:user_id => current_user.id,
:group_id => file_group,
:data_provider_id => data_provider_id,
:name => collection_name
)

collection.save!
collection.cache_prepare
coldir = collection.cache_full_path
Dir.mkdir(coldir)

collection.set_virtual_file_collection(userfiles)

# Save the content and DB model

collection.sync_to_provider
collection.save
collection.set_size

# Find the files
userfiles = Userfile
.find_all_accessible_by_user(current_user, :access_requested => :read)
.where(:id => filelist).all.to_a

if userfiles.empty?
flash[:error] = "You need to select some files first."
redirect_to(:action => :index)
return
end
redirect_to(:controller => :userfiles, :action => :show, :id => collection.id)

end

# Copy or move files to a new provider.
def change_provider #:nodoc:

Expand Down
4 changes: 2 additions & 2 deletions BrainPortal/app/helpers/userfiles_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,11 @@ def data_link(file_name, userfile, replace_div_id="sub_viewer_filecollection_cbr
end
elsif display_name =~ /\.html$/i # TODO: this will never happen if we ever create a HtmlFile model with at least one viewer
link_to "#{display_name}",
stream_userfile_path(@userfile, :file_path => file_name, :disposition => 'inline'),
stream_userfile_path(userfile, :file_path => file_name, :disposition => 'inline'),
:target => '_BLANK'
else
link_to h(display_name),
url_for(:action => :content, :content_loader => :collection_file, :arguments => file_name)
url_for(:action => :content, :id => userfile.id, :content_loader => :collection_file, :arguments => file_name)
end
end

Expand Down
30 changes: 30 additions & 0 deletions BrainPortal/app/views/userfiles/_dialogs.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,36 @@
</form>
</div>

<div id="virtual-collection-dialog" class="dlg-dialog" title="New virtual collection">
<form action="<%= create_virtual_collection_userfiles_path %>" method="post">
<label for="co-name" class="dlg-fld-lbl">Name</label>
<input id="co-name"
class="dlg-fld"
type="text"
name="collection_name"
value="NewVirtualCollection"
/>
<span id="co-invalid-name" class="dlg-msg-err">
&#9888; Invalid!
</span>
<br />

<label for="co-dp" class="dlg-fld-lbl">Provider</label>
<%=
data_provider_select('data_provider_id_for_collection',
{ :data_providers => writable_dps },
{
:id => 'co-dp',
:class => 'dlg-fld',
:'data-placeholder' => "A data provider..."
}
)
%>
<br /><br />
</form>
</div>


<div id="delete-confirm"
class="dlg-dialog dlg-cfrm"
title="Delete"
Expand Down
11 changes: 11 additions & 0 deletions BrainPortal/app/views/userfiles/_file_menu.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,17 @@
</li>
<li class="menu-separator dyn-item">-</li>

<li id="col-item"
class="act-item dyn-item"
data-dialog="virtual-collection-dialog"
>
<div>
New virtual collection
<span class="ui-icon ui-icon-folder-collapsed"></span>
</div>
</li>
<li class="menu-separator dyn-item">-</li>

<li id="exp-item"
class="act-item"
data-url="<%= userfiles_path(:format => :csv) %>"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@

<%-
#
# CBRAIN Project
#
# Copyright (C) 2008-2012
# The Royal Institution for the Advancement of Learning
# McGill University
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-%>

<% limit = 500 %>
<% base_dir = base_directory rescue params[:base_directory] %>
<% base_dir = base_dir.presence || "." %>

<% file_list ||= ( @userfile.list_linked_files(base_dir, [:regular, :directory, :link]) rescue [] ) %>

<% if file_list.blank? %>

<tr class="<%= cycle("list-odd", "list-even") %>">
<td></td>
<td colspan="2"> (<span class="warning">Empty</span>) </td>
<td></td>
</tr>

<% else %>

<% for file in file_list[0,limit] %>
<% fname = file.name %>
<% fname = fname.delete_prefix(@userfile.name + '/') unless @userfile.id == file.userfile.id %>
<% if file.symbolic_type == :directory %>
<%= on_click_ajax_replace( { :element => "tr",
:url => url_for(
:id => file.userfile.id,
:action => :display,
:viewer => "directory_contents",
:viewer_userfile_class => "FileCollection",
:base_directory => ".",
:apply_div => "false"
),
:position => "after",
:before => "<td colspan='4' class='loading_message'>Loading...</td>"
},
{ :class => "#{cycle("list-odd", "list-even")}",
:id => file.name.gsub(/\W+/, "_")
}
) do %>
<%= render :file => @viewer.partial_path(:plain_file_list_row), :locals => {:file => file} %>
<% end %>
<% else %>
<tr class="<%= cycle("list-odd", "list-even") %>">
<%= render :file => @viewer.partial_path(:plain_file_list_row), :locals => {:file => file} %>
</tr>
<% end %>
<% end %>

<% if file_list.size > limit %>
<tr class="<%= cycle("list-odd", "list-even") %>">
<td></td>
<td colspan="2" class="left"> <%= ("&nbsp;" * 6 * file_list.first.depth).html_safe %> ... <%= image_tag "/images/lotsa_files_icon.png" %> <%= pluralize(file_list.size-limit, "more entry") %></td>
<td></td>
</tr>
<% end %>

<% end %>


<script>
$(document).ready(function() {
// removes first column (checkboxes)
// there is no point to extract constituents userfiles of they already exist as separate entity
// and if user need sub-files of constituents, he or she can go below

// Function to delete the first column with checkbox
function deleteFirstColumn() {
$('.plain_file_list tr').each(function() {
firstCell = $(this).find('td:first, th:first'); // Select the first cell
cellContent = firstCell.text().trim(); // Get trimmed content of the first cell

// Check if the first cell contains a checkbox or is empty/whitespace
if (firstCell.find('input[type="checkbox"]').length || cellContent === '') {
firstCell.remove(); // Remove the cell
}
});
alarm('done');
}

// Create a mutation observer to address newly added rows
const observer = new MutationObserver(deleteFirstColumn);

// Start observing the table body for changes
observer.observe(document.getElementsByClassName('plain_file_list')[0].querySelector('tbody'), {
childList: true,
subtree: true
});

// Initial call to remove the first column
deleteFirstColumn();
});
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

<%-
#
# CBRAIN Project
#
# Copyright (C) 2008-2012
# The Royal Institution for the Advancement of Learning
# McGill University
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-%>

<%
# This partial can be invoked directly as a viewer from the display action,
# or rendered as part of another piece of view code. As such it will
# accept a "base_directory" either as a params[] or as a local variable
base_dir = base_directory rescue params[:base_directory]
%>

<%= render :file => VirtualFileCollection.view_path(:file_collection_form),
:locals => { :base_directory => base_dir } %>

<div id="sub_viewer_filecollection_cbrain"></div>

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<%= @userfile.list_linked_files.to_json %>

Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@

<%-
#
# CBRAIN Project
#
# Copyright (C) 2008-2012
# The Royal Institution for the Advancement of Learning
# McGill University
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-%>

<%
# This partial requires one local variable:
#
# base_directory : the subdirectory inside the userfile where we start to render the directory content
%>

<% if @userfile.num_files && @userfile.num_files > 0 %>


<%= form_for @userfile, :as => :userfile,
:url => { :controller => :userfiles,
:action => :extract_from_collection
},
:html => { :method => :post,
:id => "userfile_edit_#{@userfile.id}_#{base_directory}"
} do |f| %>

<%= ajax_element(display_userfile_path(@userfile,
:viewer => :file_collection_top_table,
:viewer_userfile_class => :VirtualFileCollection,
:base_directory => base_directory,
), :class => "loading_message") do %>
<br>
Loading...
<br>
<% end %>



<% end %>

<% end %>

Loading
Loading