Skip to content

Commit

Permalink
Added new BACs: CleanCache, UnregisterFile
Browse files Browse the repository at this point in the history
  • Loading branch information
prioux committed Apr 5, 2024
1 parent ea0688d commit 4a40015
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 2 deletions.
14 changes: 13 additions & 1 deletion BrainPortal/app/controllers/background_activities_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def new #:nodoc:
def create #:nodoc:
@bac = BackgroundActivity.new(base_bac_params).class_update
@bac.status = 'Scheduled'
@bac.options = {}
@bac.options = {}.with_indifferent_access
@bac.configure_for_dynamic_items!

@bac.errors.add(:type, "is not a proper type") if @bac.class == BackgroundActivity # exact test
Expand Down Expand Up @@ -65,6 +65,7 @@ def create #:nodoc:
add_options_for_compress_file if @bac.is_a?(BackgroundActivity::CompressFile) || @bac.is_a?(BackgroundActivity::UncompressFile)
add_options_for_move_file if @bac.is_a?(BackgroundActivity::MoveFile) || @bac.is_a?(BackgroundActivity::CopyFile)
add_options_for_archive_task if @bac.is_a?(BackgroundActivity::ArchiveTaskWorkdir)
add_options_for_clean_cache if @bac.is_a?(BackgroundActivity::CleanCache)

if (@bac.errors.present?) || (! @bac.valid?) || (! @bac.save)
render :action => :new
Expand Down Expand Up @@ -178,4 +179,15 @@ def add_options_for_archive_task #:nodoc:
add_options_task_custom_filter_id()
end

def add_options_for_clean_cache #:nodoc:
opt = params_options.permit(
:days_older, # a string
:with_user_ids => [], :without_user_ids => [],
:with_types => [], :without_types => [] )
@bac.options.merge! opt.to_h.with_indifferent_access # use to_h, not to_hash !!!
if @bac.options[:days_older].to_s !~ /\A\d\z|\A[1-9]\d{1,2}\z/
@bac.errors.add(:options,'does not specify a number of days between 0 and 999')
end
end

end
66 changes: 66 additions & 0 deletions BrainPortal/app/models/background_activity/clean_cache.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@

#
# CBRAIN Project
#
# Copyright (C) 2008-2024
# 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/>.
#

# Clean cached userfiles
class BackgroundActivity::CleanCache < BackgroundActivity

Revision_info=CbrainFileRevision[__FILE__] #:nodoc:

validates_dynamic_bac_presence_of_option :days_older

def pretty_name
"Clean cache"
end

def process(item)
userfile = Userfile.find(item)
name = userfile.name
return [ false, "File #{name} is under transfer" ] if
userfile.local_sync_status&.status.to_s =~ /^To/
userfile.cache_erase
[ true, userfile.id ]
end

def prepare_dynamic_items
days_older = self.options[:days_older] || 30
with_user_ids = self.options[:with_user_ids]
without_user_ids = self.options[:without_user_ids]
with_types = self.options[:with_types]
without_types = self.options[:without_types]

# Base scopes: files cached locally and having been access longer that days_older
scope = Userfile.all.joins(:sync_status)
.where('sync_status.remote_resource_id' => self.remote_resource_id)
.where('sync_status.accessed_at < ?', days_older.to_i.days.ago)

# Add optional filters
scope = scope.where( 'userfiles.user_id' => with_user_ids) if with_user_ids.present?
scope = scope.where.not('userfiles.user_id' => without_user_ids) if without_user_ids.present?
scope = scope.where( 'userfiles.type' => with_types) if with_types.present?
scope = scope.where.not('userfiles.type' => without_types) if without_types.present?

# The IDs of these files are what we need to work on
self.items = scope.pluck('userfiles.id')
end

end

60 changes: 60 additions & 0 deletions BrainPortal/app/models/background_activity/unregister_file.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

#
# CBRAIN Project
#
# Copyright (C) 2008-2024
# 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/>.
#

# Unregister files on a browsable DP
class BackgroundActivity::UnregisterFile < BackgroundActivity

Revision_info=CbrainFileRevision[__FILE__] #:nodoc:

validates_dynamic_bac_presence_of_option :userfile_custom_filter_id

def pretty_name
"Unregister files"
end

# Helper for scheduling a copy of files immediately.
def self.setup!(user_id, userfile_ids, remote_resource_id=nil)
ba = self.local_new(user_id, userfile_ids, remote_resource_id)
ba.save!
ba
end

def process(item)
userfile = Userfile.find(item)
name = userfile.name
return [ false, "File #{name} is under transfer" ] if
userfile.sync_status.to_a.any? { |ss| ss.status =~ /^To/ }
return [ false, "File #{name} is not on a browsable DataProvider" ] if
! userfile.data_provider.is_browsable?
userfile.keep_dp_content_on_destroy = true
ok = userfile.destroy # only remove entries from DB, does not affect file content
[ ok, "File #{name} unregistered" ]
end

# Currently, there is no user interface to schedule
# this sort of operation.
def prepare_dynamic_items
populate_items_from_userfile_custom_filter
end

end

Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
-%>

<div class="menu_bar">
<%= show_hide_toggle "Help", ".bac_explanations", :class => 'button', :slide_effect => true, :slide_duration => 'fast' %>
<%= show_hide_toggle "About", ".bac_explanations", :class => 'button', :slide_effect => true, :slide_duration => 'fast' %>
<%= link_to "Refresh This List", background_activities_path, :class => "button" %>
<%= external_submit_button "Cancel Activities", "bac_form", :class => "button", :confirm => "Are you sure you want to cancel the selected background activities?" %>
<% if current_user.has_role? :admin_user %>
Expand Down
56 changes: 56 additions & 0 deletions BrainPortal/app/views/background_activities/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,62 @@
%>
</fieldset>

<fieldset>
<legend>
<%= f.radio_button :type, 'BackgroundActivity::CleanCache' %>
<%= f.label :type, 'Clean DataProvider Caches', :value => 'BackgroundActivity::CleanCache' %>
</legend>

<table class="simple">

<tr>
<td>
<%= label_tag 'background_activity[options][days_older]', "Files last accessed at least:" %>
</td>
<td>
<%= text_field_tag 'background_activity[options][days_older]', @bac.options[:days_older], :size => 3 %> days ago
</td>
</tr>

<tr>
<td>
<%= label_tag 'background_activity[options][with_user_ids][]', "Belonging to users:" %>
</td>
<td>
<%= user_select("background_activity[options][with_user_ids][]", { :selector => @bac.options[:with_user_ids] }, :multiple => true ) %>
</td>
</tr>

<tr>
<td>
<%= label_tag 'background_activity[options][without_user_ids][]', "But not to users:" %>
</td>
<td>
<%= user_select("background_activity[options][without_user_ids][]", { :selector => @bac.options[:without_user_ids] }, :multiple => true ) %>
</td>
</tr>

<tr>
<td>
<%= label_tag 'background_activity[options][with_types][]', "Of type:" %>
</td>
<td>
<%= userfile_type_select("background_activity[options][with_types][]", { :selector => @bac.options[:with_types] }, :multiple => true ) %>
</td>
</tr>

<tr>
<td>
<%= label_tag 'background_activity[options][without_types][]', "But not type:" %>
</td>
<td>
<%= userfile_type_select("background_activity[options][without_types][]", { :selector => @bac.options[:without_types] }, :multiple => true ) %>
</td>
</tr>

</table>
</fieldset>

<fieldset>
<legend>
<%= f.radio_button :type, 'BackgroundActivity::RandomActivity' %>
Expand Down

0 comments on commit 4a40015

Please sign in to comment.