7403b9a15abfab21650f93b3779349cad063a8d1
[arvados.git] / services / api / app / models / collection.rb
1 class Collection < ArvadosModel
2   include AssignUuid
3   include KindAndEtag
4   include CommonApiTemplate
5
6   api_accessible :superuser, :extend => :common do |t|
7     t.add :data_size
8     t.add :files
9   end
10
11   def redundancy_status
12     if redundancy_confirmed_as.nil?
13       'unconfirmed'
14     elsif redundancy_confirmed_as < redundancy
15       'degraded'
16     else
17       if redundancy_confirmed_at.nil?
18         'unconfirmed'
19       elsif Time.now - redundancy_confirmed_at < 7.days
20         'OK'
21       else
22         'stale'
23       end
24     end
25   end
26
27   def assign_uuid
28     if self.manifest_text.nil? and self.uuid.nil?
29       super
30     elsif self.manifest_text and self.uuid
31       if self.uuid.gsub(/\+[^,]+/,'') == Digest::MD5.hexdigest(self.manifest_text)
32         true
33       else
34         errors.add :uuid, 'uuid does not match checksum of manifest_text'
35         false
36       end
37     elsif self.manifest_text
38       errors.add :uuid, 'checksum for manifest_text not supplied in uuid'
39       false
40     else
41       errors.add :manifest_text, 'manifest_text not supplied'
42       false
43     end
44   end
45
46   def data_size
47     inspect_manifest_text if @data_size.nil? or manifest_text_changed?
48     @data_size
49   end
50
51   def files
52     inspect_manifest_text if @files.nil? or manifest_text_changed?
53     @files
54   end
55
56   def inspect_manifest_text
57     if !manifest_text
58       @data_size = false
59       @files = []
60       return
61     end
62     @data_size = 0
63     @files = []
64     manifest_text.split("\n").each do |stream|
65       toks = stream.split(" ")
66       toks[1..-1].each do |tok|
67         if (re = tok.match /^[0-9a-f]{32}/)
68           blocksize = nil
69           tok.split('+')[1..-1].each do |hint|
70             if !blocksize and hint.match /^\d+$/
71               blocksize = hint.to_i
72             end
73             if (re = hint.match /^GS(\d+)$/)
74               blocksize = re[1].to_i
75             end
76           end
77           @data_size = false if !blocksize
78           @data_size += blocksize if @data_size
79         else
80           if (re = tok.match /^(\d+):(\d+):(\S+)$/)
81             @files << [toks[0], re[3], re[2].to_i]
82           end
83         end
84       end
85     end
86   end
87 end