Class: Node

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/node.rb

Constant Summary collapse

DIRECTORY =
0
VARIABLE =
1
IMAGE =
2
KNOWLEDGE =
3
FUNCTION =
4
DRAW_METHOD =
5
NODE_TYPES =
%w(directory variable image knowledge function draw_method)
LOCAL_DRIVE =
100
OPENDAP =
101
RESERVED_NAMES =
%w(children parent edit analysis draw)
@@parent =
Hash.new

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.conditions_to_read(user, prefix = '') ⇒ Object

protected ARGUMENTS

  • user : a User or nil (assuming non-login case) or :all. Do not use :all, if you do not understand what this means.

  • prefix (String) : Use this if you neede to explicitly specify the name of the node table. (Useful if you use find_by_sql.) E.g. ‘nodes.’,



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'app/models/node.rb', line 139

def conditions_to_read(user, prefix='')
  if String === user
    user = User.(user)
  end
  if User === user
    if user.super_user
      conditions = nil
    else
      groups = user.groups
      if groups == 0
        # the user is not a member of any group
        conditions = "( (#{prefix}owner_id = #{user.id}) OR " + boolean_condition("#{prefix}other_readable") + ")"
      else
        conditions = "( (#{prefix}owner_id = #{user.id}) OR NOT ((#{prefix}groups_readable & #{groups}) = 0) OR " + boolean_condition("#{prefix}other_readable") + ')'
      end
    end
  elsif user == :all
    conditions = nil
  elsif user.nil?
    conditions = '(' + boolean_condition("#{prefix}other_readable") + ')'
  else
    raise ArgumentError, "invalid user argument #{user.inspect}"
  end
  conditions
end

.count(*args) ⇒ Object



61
62
63
64
65
66
67
68
# File 'app/models/node.rb', line 61

def count(*args)
  args.push(Hash.new) unless Hash === args[-1]
  hash = args[-1]
  user = hash.delete(:user)
  conditions = conditions_to_read(user) and \
      hash[:conditions] = add_conditions(hash[:conditions], conditions)
  super(*args)
end

.find(*args) ⇒ Object



52
53
54
55
56
57
58
59
# File 'app/models/node.rb', line 52

def find(*args)
  args.push(Hash.new) unless Hash === args[-1]
  hash = args[-1]
  user = hash.delete(:user)
  conditions = conditions_to_read(user) and \
      hash[:conditions] = add_conditions(hash[:conditions], conditions)
  super(*args)
end

.make_user_directory(path, user, other_mode = 0, rgroups = 0) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'app/models/node.rb', line 99

def make_user_directory(path, user, other_mode=0, rgroups=0)
  /(\/usr)\/(.+)/ =~ path or 
         raise(ArgumentError, "#{path} cannot be a user directory")
  full_path = $1    # initially /usr
  reldir = $2
  parent = Node.find(:first,:conditions=>["path=?",full_path]) or
         raise("Cannot find #{full_path}")
  dir = nil
  reldir.split(/\//).each do |dname|
    full_path = File.join(full_path, dname)
    dir = Directory.find(:first, :conditions=>["path=?",full_path], 
                         :user=>user)
    unless dir
      dir = Directory.new
      dir.name = dname
      dir.path = full_path
      dir.parent = parent
      dir.owner = user
      dir.other_mode = other_mode
      if rgroups.is_a?(Integer)
        dir.rgroups = rgroups
      else  
        # assume an array of groups
        dir.set_rgroups(*rgroups)
      end
      FileUtils.makedirs(dir.fname) or raise("failed to makedir")
      dir.save!
    end
    parent = dir.node
  end
  dir
end

.size2str(size) ⇒ Object

size [Integer] size in bytes or nil



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'app/models/node.rb', line 79

def size2str(size)
  if size.nil?
    ''
  elsif size < 1000
    size.to_s
  elsif size < 10000
    (size / 100.0).round.to_s.insert(1,'.') + 'K'
  elsif size < 1000000
    (size / 1000).to_s + 'K'
  elsif size < 10000000
    (size / 1e5).round.to_s.insert(1,'.') + 'M'
  elsif size < 1000000000
    (size / 1000000).to_s + 'M'
  elsif size < 1e10
    (size / 1e8).round.to_s.insert(1,'.') + 'G'
  else
    (size / 1000000000).to_s + 'G'
  end
end

.top_directory_nodesObject



70
71
72
73
74
75
76
# File 'app/models/node.rb', line 70

def top_directory_nodes
  nodes = Node.find(:all, :conditions => "parent_id is NULL AND node_type=#{Node::DIRECTORY}", :order => 'path')
  if nodes.length == 0
    nodes = Node.find(:all, :conditions => "parent_id=0 AND node_type=#{Node::DIRECTORY}", :order => 'path')
  end
  return nodes
end

Instance Method Details

#_childrenObject



179
# File 'app/models/node.rb', line 179

alias _children children

#add_prefix(name) ⇒ Object



312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
# File 'app/models/node.rb', line 312

def add_prefix(name)
  if /^temporary:(.*)/ =~ name
    name = $1
    if variable? || image?
      return GFDNAVI_WORK_PATH + name
    else
      raise "[bug]"
    end
  elsif /^http:\/\// =~ name
    return name
  elsif /^\/usr(.*)/ =~ name
    if $1
      GFDNAVI_USER_PATH + $1
    else
      GFDNAVI_USER_PATH.dup
    end
  else
    return GFDNAVI_DATA_PATH + name
  end
end

#children(reload = false, hash = {}) ⇒ Object



180
181
182
183
184
185
186
187
188
189
190
191
# File 'app/models/node.rb', line 180

def children(reload=false, hash={})
  user = hash.delete(:user)
  if inc = hash.delete(:include)
    ch = Node.find(:all, :conditions=>["parent_id=?",self.id], :include=>inc, :user=>user)
  else
    ch = _children(reload,hash)
    if user
      ch = ch.find(:all, :user=>user, :include=>inc)
    end
  end
  return ch
end

#entityObject



199
200
201
202
203
204
205
206
207
208
# File 'app/models/node.rb', line 199

def entity
  return @entity if @entity
  NODE_TYPES.each {|typ|
    if node_type == Node.const_get(typ.upcase)
      @entity = ActiveRecord.class_eval(typ.classify)._find(:first,:conditions=>"node_id=#{self.id}")
      return @entity
    end
  }
  return nil
end

#entity=(ent) ⇒ Object



210
211
212
# File 'app/models/node.rb', line 210

def entity=(ent)
  @entity = ent
end

#fnameObject



291
292
293
294
295
296
297
# File 'app/models/node.rb', line 291

def fname
  if self.file && self.file!="NULL"
    return add_prefix(self.file)
  else
    return add_prefix(path)
  end
end

#full_pathObject



362
363
364
# File 'app/models/node.rb', line 362

def full_path
  "localhost@#{path}"
end

#opendap?Boolean

Returns:

  • (Boolean)


303
304
305
# File 'app/models/node.rb', line 303

def opendap?
  remote?  # equivalent at this moment
end

#parentObject



194
195
196
197
# File 'app/models/node.rb', line 194

def parent
  return nil if parent_id == 0
  return @@parent[parent_id] ||= parent_id && Node.find(:first,:conditions=>["id=?",parent_id],:user=>:all)
end

#remote?Boolean

Returns:

  • (Boolean)


299
300
301
# File 'app/models/node.rb', line 299

def remote?
  /^http:\/\// =~ fname
end

#set_rgroups(*groups) ⇒ Object

<< instance methods >>



169
170
171
172
# File 'app/models/node.rb', line 169

def set_rgroups(*groups)
  groups = groups[0] if groups.length==1 and groups[0].is_a?(Array)
  self.rgroups = Group.bit_mask_for(*groups)
end

#set_wgroups(*groups) ⇒ Object



173
174
175
176
# File 'app/models/node.rb', line 173

def set_wgroups(*groups)
  groups = groups[0] if groups.length==1 and groups[0].is_a?(Array)
  self.wgroups = Group.bit_mask_for(*groups)
end

#stdname(name) ⇒ Object



366
367
368
# File 'app/models/node.rb', line 366

def stdname(name)
  self.keyword_attributes.find_by_stdname(name)
end

#targetObject



307
308
309
310
# File 'app/models/node.rb', line 307

def target
  # for bug of rails
  self
end

#to_xml(opts = {}) ⇒ Object



333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
# File 'app/models/node.rb', line 333

def to_xml(opts={})
  opts = opts.dup
  user = opts.delete(:user)
  num_dirs = opts.delete(:num_dirs)
  uri_prefix = opts.delete(:uri_prefix)
  opts.update :except => [:parent_id, :node_type, :owner_id, :other_mode, :rgroups, :wgroups, :guest_owner_id, :file, :other_readable, :groups_readable]
  super(opts) do |xml|
    xml.node_type Node::NODE_TYPES[self.node_type]
    xml.children({"uri" => File.join(uri_prefix,"data/")+File.join(path,"children.xml")})
    xml.keyword_attributes({"uri" => File.join(uri_prefix,"data/")+File.join(path,"keyword_attributes.xml")})
    if user && (user.super_user? || self.owner == user)
      xml.owner self.owner.
      xml.other_mode self.other_mode
      xml.rgroups Group.find_by_bit_flag(self.rgroups)
      xml.wgroups Group.find_by_bit_flag(self.wgroups)
    end
    if num_dirs
      xml.num_dirs self.count_directory_nodes(:user=>user)
    end
    if image?
      xml.img_src File.join(uri_prefix, "data", path)
    end
    if directory? && entity.downloadable?
      xml.dl_url File.join(uri_prefix, "data", path)
    end
    yield(xml) if block_given?
  end
end