Class: CloudFS::Item

Inherits:
Object
  • Object
show all
Defined in:
lib/cloudfs/item.rb

Overview

An object managed by CloudFS. An item can be either a file or folder.

Item is the base class for File, Container whereas Folder is derived from Container Provides common APIs for files, folders

Direct Known Subclasses

Container, File

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(rest_adapter, parent: nil, parent_state: nil, in_trash: false, in_share: false, old_version: false, **properties) ⇒ Item

Returns a new instance of Item.

Parameters:

  • rest_adapter (RestAdapter)

    RESTful Client instance

  • parent (Item, String) (defaults to: nil)

    default: ("/") parent folder item or url

  • in_trash (Boolean) (defaults to: false)

    set true to specify item exists in trash

  • in_share (Boolean) (defaults to: false)

    set true to specify item exists in share

  • old_version (Boolean) (defaults to: false)

    set true to specify item is an old version

  • properties (Hash)

    metadata of item @option properties [String] :id path id of item @option properties [String] :parent_id (nil) pathid of parent of item @option properties [String] :type (nil) type of item either file, folder @option properties [String] :name (nil) @option properties [Timestamp] :date_created (nil) @option properties [Timestamp] :date_meta_last_modified (nil) @option properties [Timestamp] :date_content_last_modified (nil) @option properties [Fixnum] :version (nil) @option properties [Boolean] :is_mirrored (nil) @option properties [String] :mime (nil) applicable to item type file only @option properties [String] :blocklist_key (nil) applicable to item type file only @option properties [String] :blocklist_id (nil) applicable to item type file only @option properties [Fixnum] :size (nil) applicable to item of type file only @option properties [Hash] :application_data ({}) extra metadata of item

  • parent_state (Hash) (defaults to: nil)

    a customizable set of options

Options Hash (parent_state:):

  • parent_state (Hash)

    the parent state of the item

Raises:



143
144
145
146
147
148
149
150
151
# File 'lib/cloudfs/item.rb', line 143

def initialize(rest_adapter, parent: nil, parent_state: nil, in_trash: false,
               in_share: false, old_version: false, ** properties)
  fail RestAdapter::Errors::ArgumentError,
       'Invalid RestAdapter, input type must be CloudFS::RestAdapter' unless rest_adapter.is_a?(RestAdapter)

  @rest_adapter = rest_adapter
  set_item_properties(parent: parent, parent_state: parent_state, in_trash: in_trash,
                      in_share: in_share, old_version: old_version, ** properties)
end

Instance Attribute Details

#blocklist_idString (readonly)

Returns blocklist_id of file.

Returns:

  • (String)

    blocklist_id of file



32
33
34
# File 'lib/cloudfs/item.rb', line 32

def blocklist_id
  @blocklist_id
end

#blocklist_keyString (readonly)

Returns blocklist_key of file.

Returns:

  • (String)

    blocklist_key of file



29
30
31
# File 'lib/cloudfs/item.rb', line 29

def blocklist_key
  @blocklist_key
end

#date_content_last_modifiedTime (readonly)

Time when item's content was last modified

Returns time when content was last modified.

Returns:

  • (Time)

    time when content was last modified



89
90
91
92
93
94
95
# File 'lib/cloudfs/item.rb', line 89

def date_content_last_modified
  if @date_content_last_modified
    Time.at(@date_content_last_modified)
  else
    nil
  end
end

#date_createdTime (readonly)

Time when item was created

Returns creation time.

Returns:

  • (Time)

    creation time



65
66
67
68
69
70
71
# File 'lib/cloudfs/item.rb', line 65

def date_created
  if @date_created
    Time.at(@date_created)
  else
    nil
  end
end

#date_meta_last_modifiedTime (readonly)

Time when item's metadata was last modified

Returns time when metadata was last modified.

Returns:

  • (Time)

    time when metadata was last modified



77
78
79
80
81
82
83
# File 'lib/cloudfs/item.rb', line 77

def date_meta_last_modified
  if @date_meta_last_modified
    Time.at(@date_meta_last_modified)
  else
    nil
  end
end

#idString (readonly)

Returns the internal id of item that is right most path segment in url.

Returns:

  • (String)

    the internal id of item that is right most path segment in url



14
15
16
# File 'lib/cloudfs/item.rb', line 14

def id
  @id
end

#is_mirroredBoolean (readonly)

Returns indicating whether the item was created by mirroring a file.

Returns:

  • (Boolean)

    indicating whether the item was created by mirroring a file



26
27
28
# File 'lib/cloudfs/item.rb', line 26

def is_mirrored
  @is_mirrored
end

#nameObject

name of item



48
49
50
# File 'lib/cloudfs/item.rb', line 48

def name
  @name
end

#parent_idString (readonly)

Returns id of parent of item.

Returns:

  • (String)

    id of parent of item



17
18
19
# File 'lib/cloudfs/item.rb', line 17

def parent_id
  @parent_id
end

#typeString (readonly)

Returns type of item, either file or folder.

Returns:

  • (String)

    type of item, either file or folder



20
21
22
# File 'lib/cloudfs/item.rb', line 20

def type
  @type
end

#urlString (readonly)

Returns absolute path of item in user's account.

Returns:

  • (String)

    absolute path of item in user's account



35
36
37
# File 'lib/cloudfs/item.rb', line 35

def url
  @url
end

#versionString (readonly)

Returns known current version of item.

Returns:

  • (String)

    known current version of item



23
24
25
# File 'lib/cloudfs/item.rb', line 23

def version
  @version
end

Instance Method Details

#application_dataObject



97
98
99
100
101
102
103
# File 'lib/cloudfs/item.rb', line 97

def application_data
  if @application_data
    Marshal.load(Marshal.dump(@application_data))
  else
    {}
  end
end

#application_data=(hash = {}) ⇒ Object



105
106
107
108
109
110
111
112
113
114
# File 'lib/cloudfs/item.rb', line 105

def application_data=(hash={})
  FileSystemCommon.validate_item_state(self)
  if @application_data
    @application_data.merge!(hash)
  else
    @application_data = hash.dup
  end
  @changed_properties[:application_data].merge!(hash)
  change_attributes(@changed_properties)
end

#change_attributes(values, if_conflict: 'FAIL') ⇒ Boolean

Changes the attributes of a given file or folder.

Parameters:

  • values (Hash)

    attribute changes.

  • if_conflict (String) (defaults to: 'FAIL')

    ('FAIL', 'IGNORE') action to take if the version on this item does not match the version on the server.

Returns:

  • (Boolean)

    based on the success or fail status of the action.



615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
# File 'lib/cloudfs/item.rb', line 615

def change_attributes(values, if_conflict: 'FAIL')
  if @type == 'folder'
    response = @rest_adapter.alter_folder_meta(
        @url,
        @version,
        version_conflict: if_conflict,
        ** values)
  else
    response = @rest_adapter.alter_file_meta(
        @url,
        @version,
        version_conflict: if_conflict,
        ** values)
  end

  parent_url = ::File.dirname(@url)
  set_item_properties(parent: parent_url, ** response)
  response.has_key?(:id)
end

#copy(destination, name: nil, exists: 'RENAME') ⇒ Item

Note:

Locally changed properties are not copied

Copy this item to destination

Parameters:

  • destination (Item, String)

    destination to copy item to, should be folder

  • name (String) (defaults to: nil)

    (nil) new name of copied item

  • exists (String) (defaults to: 'RENAME')

    ('FAIL', 'OVERWRITE', 'RENAME') action to take in case of a conflict with an existing folder, default 'RENAME'

Returns:

  • (Item)

    new instance of copied item

Raises:



276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
# File 'lib/cloudfs/item.rb', line 276

def copy(destination, name: nil, exists: 'RENAME')
  FileSystemCommon.validate_item_state(self)
  FileSystemCommon.validate_item_state(destination)

  destination_url = FileSystemCommon.get_folder_url(destination)
  name = @name unless name

  if @type == 'folder'
    response = @rest_adapter.copy_folder(
        @url,
        destination_url,
        name,
        exists: exists)
  else
    response = @rest_adapter.copy_file(
        @url,
        destination_url,
        name,
        exists: exists)
  end
  FileSystemCommon.create_item_from_hash(
      @rest_adapter,
      parent: destination_url,
      ** response)
end

#delete(commit: false, force: false, raise_exception: false) ⇒ Boolean

Note:

Updates this item if operation is successful

Note:

Locally changed properties get discarded

Delete this item RestAdapter::Errors::InvalidItemError, RestAdapter::Errors::OperationNotAllowedError]

if raise_exception is true

Parameters:

  • commit (Boolean) (defaults to: false)

    (false) set true to remove item permanently, else will be moved to trash, RestAdapter::Errors::InvalidItemError is raised for subsequent operation if commit: true

  • force (Boolean) (defaults to: false)

    (false) set true to delete non-empty folder

  • raise_exception (Boolean) (defaults to: false)

    (false) method suppresses exceptions and returns false if set to false, added so that consuming application can control behaviour

Returns:

  • (Boolean)

    whether operation is successful

Raises:



322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
# File 'lib/cloudfs/item.rb', line 322

def delete(commit: false, force: false, raise_exception: false)
  FileSystemCommon.validate_item_state(self, in_trash: false)

  if @in_trash
    # @review NOOP if commit is false since item is already in trash, return true
    if commit
      @rest_adapter.delete_trash_item(path: @url)
      @exists = false
      @in_trash = false
    end
    return true
  end

  if @type == 'folder'
    @rest_adapter.delete_folder(@url, commit: commit, force: force)
  else
    @rest_adapter.delete_file(@url, commit: commit)
  end

  if commit
    @exists = false
    @in_trash = false
  else
    @application_data[:_bitcasa_original_path] = ::File.dirname(@url)
    set_url(nil)
    @in_trash = true
  end
  changed_properties_reset
  true
rescue RestAdapter::Errors::SessionNotLinked, RestAdapter::Errors::ServiceError,
    RestAdapter::Errors::OperationNotAllowedError, RestAdapter::Errors::InvalidItemError
  raise $! if raise_exception
  false
end

#exists?Boolean

Returns whether item exists, false if item has been deleted permanently.

Returns:

  • (Boolean)

    whether item exists, false if item has been deleted permanently



210
211
212
# File 'lib/cloudfs/item.rb', line 210

def exists?
  @exists
end

#in_share?Boolean

Returns whether the item exists in share.

Returns:

  • (Boolean)

    whether the item exists in share



204
205
206
# File 'lib/cloudfs/item.rb', line 204

def in_share?
  @in_share
end

#in_trash?Boolean

Returns whether the item exists in trash.

Returns:

  • (Boolean)

    whether the item exists in trash



199
200
201
# File 'lib/cloudfs/item.rb', line 199

def in_trash?
  @in_trash
end

#move(destination, name: nil, exists: 'RENAME') ⇒ Item

Note:

Updates this item and it's reference is returned.

Note:

Locally changed properties get discarded

Move this item to destination folder

Parameters:

  • destination (Item, String)

    destination to move item to, should be folder

  • name (String) (defaults to: nil)

    (nil) new name of moved item

  • exists (String) (defaults to: 'RENAME')

    ('FAIL', 'OVERWRITE', 'RENAME') action to take in case of a conflict with an existing folder, default 'RENAME'

Returns:

  • (Item)

    returns self

Raises:



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# File 'lib/cloudfs/item.rb', line 235

def move(destination, name: nil, exists: 'RENAME')
  FileSystemCommon.validate_item_state(self)
  FileSystemCommon.validate_item_state(destination)

  destination_url = FileSystemCommon.get_folder_url(destination)
  name ||= @name

  if @type == 'folder'
    response = @rest_adapter.move_folder(
        @url,
        destination_url,
        name,
        exists: exists)
  else
    response = @rest_adapter.move_file(
        @url,
        destination_url,
        name,
        exists: exists)
  end
  # Overwrite this item's properties with Moved Item's properties
  set_item_properties(parent: destination_url, ** response)
  self
end

#old_version?Boolean

Returns whether the item is an older version.

Returns:

  • (Boolean)

    whether the item is an older version



194
195
196
# File 'lib/cloudfs/item.rb', line 194

def old_version?
  @old_version
end

#pathString

Returns absolute path of item in user's account.

Returns:

  • (String)

    absolute path of item in user's account



38
39
40
# File 'lib/cloudfs/item.rb', line 38

def path
  @url
end

#refreshItem

Note:

Locally changed properties get discarded

Refresh this item's properties from server

RestAdapter::Errors::InvalidItemError,

RestAdapter::Errors::OperationNotAllowedError]

Returns:

  • (Item)

    returns self

Raises:



380
381
382
383
384
385
386
387
388
389
390
391
392
# File 'lib/cloudfs/item.rb', line 380

def refresh
  FileSystemCommon.validate_item_state(self, in_trash: false, in_share: false)

  properties = get_properties_from_server
  parent_url = ::File.dirname(@url)

  set_item_properties(
      parent: parent_url,
      in_trash: @in_trash,
      in_share: @in_share,
      ** properties)
  self
end

#restore(destination, method: 'FAIL', restore_argument: nil, raise_exception: false) ⇒ Boolean

Note:

This item's properties are updated if successful

Note:

exist: 'RECREATE' with named path is expensive operation as items in named path hierarchy are traversed in order to fetch Restored item's properties.

Restore this item from trash

Examples:

item.restore
item.restore("/FOPqySw3ToK_25y-gagUfg", exists: 'RESCUE')
item.restore(folderobj, exists: 'RESCUE')
item.restore("/depth1/depth2", exists: 'RECREATE')

Parameters:

  • destination (Folder, String)

    ('RESCUE' (default root), RECREATE(named path)) destination folder path depending on exists option to place item into if the original path does not exist.

  • method (String) (defaults to: 'FAIL')

    ('FAIL', 'RESCUE', 'RECREATE') action to take if the recovery operation encounters issues, default 'FAIL'

  • raise_exception (Boolean) (defaults to: false)

    (false) method suppresses exceptions and returns false if set to false, added so that consuming application can control behaviour

  • restore_argument (String) (defaults to: nil)

    update this item after it has been restored

Returns:

  • (Boolean)

    true/false

Raises:



473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
# File 'lib/cloudfs/item.rb', line 473

def restore(destination, method: 'FAIL', restore_argument: nil, raise_exception: false) # restore argument.
  fail RestAdapter::Errors::OperationNotAllowedError,
       'Item needs to be in trash for Restore operation' unless @in_trash
  FileSystemCommon.validate_item_state(destination)

  destination_url = FileSystemCommon.get_folder_url(destination)
  @rest_adapter.recover_trash_item(
      @url,
      destination: destination_url,
      restore: method)

  if restore_argument
    set_restored_item_properties(destination_url, method)
  end

  true
rescue RestAdapter::Errors::SessionNotLinked, RestAdapter::Errors::ServiceError,
    RestAdapter::Errors::ArgumentError, RestAdapter::Errors::InvalidItemError,
    RestAdapter::Errors::OperationNotAllowedError
  raise $! if raise_exception
  false
end

#save(version_conflict: 'FAIL') ⇒ Item

Save this item's current state. Locally changed properties are committed to this item in user's account

RestAdapter::Errors::OperationNotAllowedError]

Parameters:

  • version_conflict (String) (defaults to: 'FAIL')

    ('FAIL', 'IGNORE') action to take if the version on this item does not match the version on the server

Returns:

  • (Item)

    returns self

Raises:



544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
# File 'lib/cloudfs/item.rb', line 544

def save(version_conflict: 'FAIL')
  FileSystemCommon.validate_item_state(self)
  return self if RestAdapter::Utils.is_blank?(@changed_properties)

  if @type == 'folder'
    response = @rest_adapter.alter_folder_meta(
        @url,
        @version,
        version_conflict: version_conflict,
        ** @changed_properties)
  else
    response = @rest_adapter.alter_file_meta(
        @url,
        @version,
        version_conflict: version_conflict,
        ** @changed_properties)
  end

  parent_url = ::File.dirname(@url)
  set_item_properties(parent: parent_url, ** response)
  self
end

#versions(start_version: 0, stop_version: nil, limit: 10) ⇒ Array<Item>

Note:

The list of files returned are mostly non-functional, though their meta-data is correct.

List versions of this item if file.

Parameters:

  • start_version (Fixnum) (defaults to: 0)

    version number to begin listing file versions

  • stop_version (Fixnum) (defaults to: nil)

    version number from which to stop listing file versions

  • limit (Fixnum) (defaults to: 10)

    how many versions to list in the result set. It can be negative to list items prior to given start version

Returns:

  • (Array<Item>)

    listed versions

Raises:

REVIEW:

  • confirm if versions should be allowed for items in trash, in share



513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
# File 'lib/cloudfs/item.rb', line 513

def versions(start_version: 0, stop_version: nil, limit: 10)
  FileSystemCommon.validate_item_state(self, in_trash: false, in_share: false)
  fail OperationNotAllowedError,
       "Operation not allowed for item of type #{@type}" unless @type == 'file'

  response = @rest_adapter.list_file_versions(
      @url,
      start_version: start_version,
      stop_version: stop_version,
      limit: limit)

  FileSystemCommon.create_items_from_hash_array(
      response, @rest_adapter,
      parent: @url,
      in_share: @in_share,
      in_trash: @in_trash,
      old_version: true)
end