Class: Library

Inherits:
ApplicationRecord show all
Includes:
ChangeDetection, MemoWise, Problematic, PublicIDable
Defined in:
app/models/library.rb

Constant Summary collapse

STORAGE_SERVICES =
[
  "filesystem", # i18n-tasks-use t("libraries.storage_services.filesystem")
  "s3" # i18n-tasks-use t("libraries.storage_services.s3")
]

Constants inherited from ApplicationRecord

ApplicationRecord::SAFE_NAME_LENGTH

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ChangeDetection

#filter_out_common_subfolders, #folders_with_changes, #indexable_files, #indexed_files, #sample

Methods included from PublicIDable

#to_param

Methods inherited from ApplicationRecord

find_param

Class Method Details

.default ⇒ Object



176
177
178
# File 'app/models/library.rb', line 176

def self.default
  Library.find_by(id: SiteSettings.default_library) || Library.first
end

.register_all_storage ⇒ Object



118
119
120
121
122
# File 'app/models/library.rb', line 118

def self.register_all_storage
  find_each(&:register_storage)
rescue ActiveRecord::StatementInvalid, NameError
  nil # migrations probably haven't run yet to create library table
end

Instance Method Details

#create_model_from_path_later(path, delay: 0.seconds) ⇒ Object



197
198
199
# File 'app/models/library.rb', line 197

def create_model_from_path_later(path, delay: 0.seconds)
  Scan::Library::CreateModelFromPathJob.set(wait: delay).perform_later(id, path)
end

#create_path_if_not_on_disk=(val) ⇒ Object



166
167
168
169
170
171
172
173
174
# File 'app/models/library.rb', line 166

def create_path_if_not_on_disk=(val)
  if val == "1" && storage_service == "filesystem" && path.presence
    begin
      FileUtils.makedirs(path)
    rescue Errno::EROFS, Errno::EACCES
      errors.add(:path, :non_writable)
    end
  end
end

#default? ⇒ Boolean

Returns:

  • (Boolean)


180
181
182
# File 'app/models/library.rb', line 180

def default?
  SiteSettings.default_library == id
end

#detect_filesystem_changes_later(delay: 0.seconds) ⇒ Object



193
194
195
# File 'app/models/library.rb', line 193

def detect_filesystem_changes_later(delay: 0.seconds)
  Scan::Library::DetectFilesystemChangesJob.set(wait: delay).perform_later(id)
end

#file_last_modified(file) ⇒ Object



155
156
157
158
159
160
161
162
163
164
# File 'app/models/library.rb', line 155

def file_last_modified(file)
  case storage_service
  when "filesystem"
    File.mtime(File.join(path, file))
  when "s3"
    storage.bucket.object(file).last_modified
  else
    raise "Invalid storage service: #{storage_service}"
  end
end

#free_space ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
# File 'app/models/library.rb', line 70

def free_space
  case storage_service
  when "filesystem"
    stat = Sys::Filesystem.stat(path)
    stat.bytes_available
  when "s3"
    nil
  else
    raise "Invalid storage service: #{storage_service}"
  end
end

#has_file?(path) ⇒ Boolean

Returns:

  • (Boolean)


142
143
144
# File 'app/models/library.rb', line 142

def has_file?(path)
  storage.exists?(path)
end

#has_folder?(path) ⇒ Boolean

Returns:

  • (Boolean)


146
147
148
149
150
151
152
153
# File 'app/models/library.rb', line 146

def has_folder?(path)
  case storage_service
  when "s3"
    storage.bucket.objects(prefix: path).count > 0
  else
    storage.exists?(path)
  end
end

#init ⇒ Object



50
51
52
# File 'app/models/library.rb', line 50

def init
  self.name = nil if name == ""
end

#list_files(pattern, flags = 0) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'app/models/library.rb', line 124

def list_files(pattern, flags = 0)
  files = case storage_service
  when "filesystem"
    Dir.glob(pattern, flags, base: path).filter { File.file?(File.join(path, it)) }
  when "s3"
    keys = []
    pattern_array = [pattern].flatten
    storage.bucket.objects.each do |object|
      keys << object.key if pattern_array.any? { File.fnmatch?(it, object.key, File::FNM_EXTGLOB) }
    end
    keys
  else
    raise "Invalid storage service: #{storage_service}"
  end
  # Filter out files that should be ignored
  files.uniq.reject { |str| SiteSettings.ignored_file?(str) }
end

#make_default ⇒ Object



184
185
186
# File 'app/models/library.rb', line 184

def make_default
  SiteSettings.default_library = id
end

#name ⇒ Object



46
47
48
# File 'app/models/library.rb', line 46

def name
  self[:name] || (path ? File.basename(path) : "")
end

#register_storage ⇒ Object



114
115
116
# File 'app/models/library.rb', line 114

def register_storage
  ModelFileUploader.storages[storage_key] = storage
end

#reset_default_library ⇒ Object



188
189
190
191
# File 'app/models/library.rb', line 188

def reset_default_library
  new_default = Library.where.not(id: id).first # rubocop:disable Pundit/UsePolicyScope
  new_default ? new_default.make_default : SiteSettings.default_library = nil
end

#storage ⇒ Object



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'app/models/library.rb', line 94

def storage
  case storage_service
  when "filesystem"
    Shrine::Storage::FileSystem.new(path)
  when "s3"
    Shrine::Storage::S3.new(
      endpoint: s3_endpoint,
      bucket: s3_bucket,
      region: s3_region,
      access_key_id: s3_access_key_id,
      secret_access_key: s3_secret_access_key,
      force_path_style: s3_endpoint.present? && s3_path_style,
      use_accelerate_endpoint: s3_endpoint.blank?
    )
  else
    raise "Invalid storage service: #{storage_service}"
  end
end

#storage_exists? ⇒ Boolean

Returns:

  • (Boolean)


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

def storage_exists?
  case storage_service
  when "filesystem"
    Dir.exist?(path)
  when "s3"
    storage.bucket.exists?
  else
    raise "Invalid storage service: #{storage_service}"
  end
end

#storage_key ⇒ Object



82
83
84
# File 'app/models/library.rb', line 82

def storage_key
  :"library_#{id}"
end

#storage_origin ⇒ Object



86
87
88
89
90
91
# File 'app/models/library.rb', line 86

def storage_origin
  case storage_service
  when "s3"
    URI.parse(storage.presign(nil)[:url]).origin
  end
end

#storage_service ⇒ Object

Backwards compatibility for use during migrations



55
56
57
# File 'app/models/library.rb', line 55

def storage_service
  attributes["storage_service"] || "filesystem"
end