1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: AGPL-3.0
7 class Collection < ArvadosBase
8 MD5_EMPTY = 'd41d8cd98f00b204e9800998ecf8427e'
11 if Collection.is_empty_blob_locator? self.uuid
18 # Return true if the given string is the locator of a zero-length blob
19 def self.is_empty_blob_locator? locator
20 !!locator.to_s.match("^#{MD5_EMPTY}(\\+.*)?\$")
23 def self.goes_in_projects?
28 if @manifest.nil? or manifest_text_changed?
29 @manifest = Keep::Manifest.new(manifest_text || "")
35 # This method provides backwards compatibility for code that relied on
36 # the old files field in API results. New code should use manifest
43 ApplicationController.helpers.human_readable_bytes_html(total_bytes) + " " + super
45 super + " modified at " + modified_at.to_s
50 manifest.files.inject(0) { |sum, filespec| sum + filespec.last }
54 tree = manifest.files.group_by do |file_spec|
55 File.split(file_spec.first)
57 return [] if tree.empty?
58 # Fill in entries for empty directories.
59 tree.keys.map { |basedir, _| File.split(basedir) }.each do |splitdir|
60 until tree.include?(splitdir)
62 splitdir = File.split(splitdir.first)
65 dir_to_tree = lambda do |dirname|
66 # First list subdirectories, with their files inside.
67 subnodes = tree.keys.select { |bd, td| (bd == dirname) and (td != '.') }
68 .sort.flat_map do |parts|
69 [parts + [nil]] + dir_to_tree.call(File.join(parts))
71 # Then extend that list with files in this directory.
72 subnodes + tree[File.split(dirname)]
77 def editable_attributes
78 %w(name description manifest_text filename)
82 arvados_api_client.api "collections/#{self.uuid}/", "provenance"
86 arvados_api_client.api "collections/#{self.uuid}/", "used_by"
91 return self[:portable_data_hash]
97 def friendly_link_name lookup=nil
98 name || portable_data_hash
101 def textile_attributes
106 arvados_api_client.api(self.class, "/#{self.uuid}/untrash", {"ensure_unique_name" => true})