Merge branch 'master' into 3188-remove-selected-button
[arvados.git] / apps / workbench / app / models / collection.rb
1 class Collection < ArvadosBase
2   MD5_EMPTY = 'd41d8cd98f00b204e9800998ecf8427e'
3
4   def default_name
5     if Collection.is_empty_blob_locator? self.uuid
6       "Empty Collection"
7     else
8       super
9     end
10   end
11
12   # Return true if the given string is the locator of a zero-length blob
13   def self.is_empty_blob_locator? locator
14     !!locator.to_s.match("^#{MD5_EMPTY}(\\+.*)?\$")
15   end
16
17   def self.goes_in_projects?
18     true
19   end
20
21   def content_summary
22     ApplicationController.helpers.human_readable_bytes_html(total_bytes) + " " + super
23   end
24
25   def total_bytes
26     if files
27       tot = 0
28       files.each do |file|
29         tot += file[2]
30       end
31       tot
32     else
33       0
34     end
35   end
36
37   def files_tree
38     return [] if files.empty?
39     tree = files.group_by { |file_spec| File.split(file_spec.first) }
40     # Fill in entries for empty directories.
41     tree.keys.map { |basedir, _| File.split(basedir) }.each do |splitdir|
42       until tree.include?(splitdir)
43         tree[splitdir] = []
44         splitdir = File.split(splitdir.first)
45       end
46     end
47     dir_to_tree = lambda do |dirname|
48       # First list subdirectories, with their files inside.
49       subnodes = tree.keys.select { |bd, td| (bd == dirname) and (td != '.') }
50         .sort.flat_map do |parts|
51         [parts + [nil]] + dir_to_tree.call(File.join(parts))
52       end
53       # Then extend that list with files in this directory.
54       subnodes + tree[File.split(dirname)]
55     end
56     dir_to_tree.call('.')
57   end
58
59   def attribute_editable? attr, *args
60     if %w(name description manifest_text).include? attr.to_s
61       true
62     else
63       super
64     end
65   end
66
67   def self.creatable?
68     false
69   end
70
71   def provenance
72     arvados_api_client.api "collections/#{self.uuid}/", "provenance"
73   end
74
75   def used_by
76     arvados_api_client.api "collections/#{self.uuid}/", "used_by"
77   end
78
79   def uuid
80     if self[:uuid].nil?
81       return self[:portable_data_hash]
82     else
83       super
84     end
85   end
86
87   def portable_data_hash
88     if self[:portable_data_hash].nil?
89       return self[:uuid]
90     else
91       super
92     end
93   end
94
95   def friendly_link_name
96     if self.respond_to? :name
97       self.name
98     else
99       self.portable_data_hash
100     end
101   end
102
103 end