Class: FC::Item
Instance Attribute Summary
Attributes inherited from DbBase
#additional_fields, #database_fields, #id
Class Method Summary collapse
-
.create_from_local(local_path, item_name, policy, options = {}, &block) ⇒ Object
Create item by local path.
Instance Method Summary collapse
- #copy_item_storage(src, storage, item_storage, remove_local = false, speed_limit = nil) ⇒ Object
- #dir? ⇒ Boolean
- #get_available_storages ⇒ Object
- #get_item_storages ⇒ Object
-
#immediate_delete ⇒ Object
mark item and his items_storages for immediate delete.
- #item_storage_status_set(item_storage, status) ⇒ Object
- #make_item_storage(storage, status = 'new') ⇒ Object
-
#mark_deleted ⇒ Object
mark item and his items_storages for deferred delete real delete after policy.delete_deferred_time.
- #url ⇒ Object
- #urls ⇒ Object
Methods inherited from DbBase
create_from_fiels, #delete, find, #initialize, #reload, #save, set_table, where
Constructor Details
This class inherits a constructor from FC::DbBase
Class Method Details
.create_from_local(local_path, item_name, policy, options = {}, &block) ⇒ Object
Create item by local path. Additional options:
:replace=true - replace item if it exists
:remove_local=true - delete local_path file/dir after add
:additional_fields - hash of additional FC:Item fields
:no_md5 - don't use md5
:speed_limit - limit copy speed
If item_name is part of local_path it processed as inplace - local_path is valid path to the item for policy
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/fc/item.rb', line 17 def self.create_from_local(local_path, item_name, policy, ={}, &block) raise 'Path not exists' unless File.exists?(local_path) raise 'Policy is not FC::Policy' unless policy.instance_of?(FC::Policy) item_params = .merge({ :name => item_name.to_s.gsub('//', '/').sub(/\/$/, '').sub(/^\//, '').strip, :policy_id => policy.id, :dir => File.directory?(local_path), :size => FC::Storage.new(:host => FC::Storage.curr_host).file_size(local_path), :md5 => nil }) item_params[:md5] = FC::Storage.new( :host => FC::Storage.curr_host ).md5_sum(local_path) unless item_params[:no_md5] item_params.delete(:replace) item_params.delete(:remove_local) item_params.delete(:not_local) item_params.delete(:no_md5) item_params.delete(:speed_limit) raise 'Name is empty' if item_params[:name].empty? raise 'Zero size path' if item_params[:size] == 0 if local_path.include?(item_name) && ![:not_local] storage = policy.get_create_storages.detect do |s| s.host == FC::Storage.curr_host && local_path.index(s.path) == 0 && local_path.sub(s.path, '').sub(/\/$/, '').sub(/^\//, '') == item_params[:name] end FC::Error.raise "local_path #{local_path} is not valid path for policy ##{policy.id}" unless storage end # new item? item = FC::Item.where('name=? AND policy_id=?', item_params[:name], policy.id).first if item if [:replace] || storage # replace all fields item_params.each{|key, val| item.send("#{key}=", val)} else FC::Error.raise 'Item already exists', :item_id => item.id end else item = FC::Item.new(item_params) end item.save if storage item_storage = item.make_item_storage(storage, 'ready') item.reload else if item.copies.to_i > 0 # find storage in item.item_storages storages_names = item.get_item_storages.select{|s| s.status == 'ready'}.map(&:storage_name) storage = FC::Storage.select_proper_storage_for_create(policy.get_create_storages, item.size) do |storages| storages.select{|s| storages_names.detect(s.name)} end end if block_given? storage ||= FC::Storage.select_proper_storage_for_create(policy.get_create_storages, item.size, &block) else storage ||= policy.get_proper_storage_for_create(item.size, local_path) end FC::Error.raise 'No available storage', :item_id => item.id unless storage # mark delete item_storages on replace FC::DB.query("UPDATE #{FC::ItemStorage.table_name} SET status='delete' WHERE item_id = #{item.id} AND storage_name <> '#{storage.name}'") if [:replace] item_storage = item.make_item_storage(storage) item.copy_item_storage(local_path, storage, item_storage, [:remove_local], [:speed_limit]) end return item end |
Instance Method Details
#copy_item_storage(src, storage, item_storage, remove_local = false, speed_limit = nil) ⇒ Object
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 131 132 133 134 |
# File 'lib/fc/item.rb', line 102 def copy_item_storage(src, storage, item_storage, remove_local = false, speed_limit = nil) begin if src.instance_of?(FC::Storage) src.copy_to_local(name, "#{storage.path}#{name}", speed_limit) else storage.copy_path(src, name, remove_local, speed_limit) end md5_on_storage = storage.md5_sum(name) if md5 rescue Exception => e item_storage_status_set(item_storage, 'error') FC::Error.raise "Copy error: #{e.}", :item_id => id, :item_storage_id => item_storage.id else begin item_storage.reload rescue Exception => e FC::Error.raise "After copy error: #{e.}", :item_id => id, :item_storage_id => item_storage.id else if md5 && md5_on_storage != md5 item_storage_status_set(item_storage, 'error') FC::Error.raise "Check md5 after copy error", :item_id => id, :item_storage_id => item_storage.id else item_storage_status_set(item_storage, 'ready') if remove_local && !src.instance_of?(FC::Storage) && File.exists?(src) if File.directory?(src) FileUtils.rm_r(src) else File.delete(src) end end end end end end |
#dir? ⇒ Boolean
159 160 161 |
# File 'lib/fc/item.rb', line 159 def dir? dir.to_i == 1 end |
#get_available_storages ⇒ Object
167 168 169 170 171 |
# File 'lib/fc/item.rb', line 167 def get_available_storages r = FC::DB.query("SELECT st.* FROM #{FC::Storage.table_name} as st, #{FC::ItemStorage.table_name} as ist WHERE ist.item_id = #{id} AND ist.status='ready' AND ist.storage_name = st.name") r.map{|data| FC::Storage.create_from_fiels(data)}.select {|storage| storage.up? && storage.url_weight.to_i >= 0} end |
#get_item_storages ⇒ Object
163 164 165 |
# File 'lib/fc/item.rb', line 163 def get_item_storages FC::ItemStorage.where("item_id = #{id}") end |
#immediate_delete ⇒ Object
mark item and his items_storages for immediate delete
153 154 155 156 157 |
# File 'lib/fc/item.rb', line 153 def immediate_delete FC::DB.query("UPDATE #{FC::ItemStorage.table_name} SET status='delete' WHERE item_id = #{id}") self.status = 'delete' save end |
#item_storage_status_set(item_storage, status) ⇒ Object
136 137 138 139 140 141 142 143 |
# File 'lib/fc/item.rb', line 136 def item_storage_status_set(item_storage, status) reload marked_for_delete = self.status == 'deferred_delete' item_storage.status = status item_storage.save reload mark_deleted if marked_for_delete end |
#make_item_storage(storage, status = 'new') ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/fc/item.rb', line 88 def make_item_storage(storage, status = 'new') # new storage_item? item_storage = FC::ItemStorage.where('item_id=? AND storage_name=?', id, storage.name).first if item_storage item_storage.delete storage.size = storage.size.to_i - size.to_i end item_storage = FC::ItemStorage.new({:item_id => id, :storage_name => storage.name, :status => status}) item_storage.save storage.size = storage.size.to_i + size.to_i item_storage end |
#mark_deleted ⇒ Object
mark item and his items_storages for deferred delete real delete after policy.delete_deferred_time
147 148 149 150 |
# File 'lib/fc/item.rb', line 147 def mark_deleted self.status = 'deferred_delete' save end |
#url ⇒ Object
177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/fc/item.rb', line 177 def url available_storages = get_available_storages() # sort by random(url_weight) best_storage = available_storages.map{ |storage| [storage, Kernel.rand(storage.url_weight.to_i * 100)] }.sort{ |a, b| a[1] <=> b[1] }.map{|el| el[0]}.last best_storage = available_storages.sample unless best_storage raise "URL find - no avable storage for item #{id}" unless best_storage File.join(best_storage.url, name) end |
#urls ⇒ Object
173 174 175 |
# File 'lib/fc/item.rb', line 173 def urls get_available_storages.map{|storage| File.join(storage.url, name)} end |