Class: Shrine::Storage::FileSystem

Inherits:
Object
  • Object
show all
Defined in:
lib/shrine/storage/file_system.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(directory, prefix: nil, host: nil, clean: true, permissions: 0644, directory_permissions: 0755) ⇒ FileSystem

Initializes a storage for uploading to the filesystem.

:prefix : The directory relative to ‘directory` to which files will be stored,

and it is included in the URL.

:permissions : The UNIX permissions applied to created files. Can be set to ‘nil`,

in which case the default permissions will be applied. Defaults to
`0644`.

:directory_permissions : The UNIX permissions applied to created directories. Can be set to

`nil`, in which case the default permissions will be applied. Defaults
to `0755`.

:clean : By default empty folders inside the directory are automatically

deleted, but if it happens that it causes too much load on the
filesystem, you can set this option to `false`.


31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/shrine/storage/file_system.rb', line 31

def initialize(directory, prefix: nil, host: nil, clean: true, permissions: 0644, directory_permissions: 0755)
  Shrine.deprecation("The :host option to Shrine::Storage::FileSystem#initialize is deprecated and will be removed in Shrine 3. Pass :host to FileSystem#url instead, you can also use default_url_options plugin.") if host

  if prefix
    @prefix = Pathname(relative(prefix))
    @directory = Pathname(directory).join(@prefix).expand_path
  else
    @directory = Pathname(directory).expand_path
  end

  @host = host
  @permissions = permissions
  @directory_permissions = directory_permissions
  @clean = clean

  unless @directory.exist?
    @directory.mkpath
    @directory.chmod(directory_permissions) if directory_permissions
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object

Catches the deprecated ‘#download` method.



132
133
134
135
136
137
138
# File 'lib/shrine/storage/file_system.rb', line 132

def method_missing(name, *args, &block)
  case name
  when :download then deprecated_download(*args, &block)
  else
    super
  end
end

Instance Attribute Details

#directoryObject (readonly)

Returns the value of attribute directory.



9
10
11
# File 'lib/shrine/storage/file_system.rb', line 9

def directory
  @directory
end

#directory_permissionsObject (readonly)

Returns the value of attribute directory_permissions.



9
10
11
# File 'lib/shrine/storage/file_system.rb', line 9

def directory_permissions
  @directory_permissions
end

#hostObject (readonly)

Returns the value of attribute host.



9
10
11
# File 'lib/shrine/storage/file_system.rb', line 9

def host
  @host
end

#permissionsObject (readonly)

Returns the value of attribute permissions.



9
10
11
# File 'lib/shrine/storage/file_system.rb', line 9

def permissions
  @permissions
end

#prefixObject (readonly)

Returns the value of attribute prefix.



9
10
11
# File 'lib/shrine/storage/file_system.rb', line 9

def prefix
  @prefix
end

Instance Method Details

#clear!(older_than: nil) ⇒ Object

Deletes all files from the #directory. If ‘:older_than` is passed in (a `Time` object), deletes all files which were last modified before that time.



112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/shrine/storage/file_system.rb', line 112

def clear!(older_than: nil)
  if older_than
    # add trailing slash to make it work with symlinks
    Pathname("#{directory}/").find do |path|
      if path.file? && path.mtime < older_than
        path.delete
        clean(path) if clean?
      end
    end
  else
    directory.children.each(&:rmtree)
  end
end

#delete(id) ⇒ Object

Delets the file, and by default deletes the containing directory if it’s empty.



92
93
94
95
96
97
# File 'lib/shrine/storage/file_system.rb', line 92

def delete(id)
  path = path(id)
  path.delete
  clean(path) if clean?
rescue Errno::ENOENT
end

#exists?(id) ⇒ Boolean

Returns true if the file exists on the filesystem.

Returns:

  • (Boolean)


86
87
88
# File 'lib/shrine/storage/file_system.rb', line 86

def exists?(id)
  path(id).exist?
end

#movable?(io, id) ⇒ Boolean

Returns true if the file is a ‘File` or a UploadedFile uploaded by the FileSystem storage.

Returns:

  • (Boolean)


74
75
76
77
# File 'lib/shrine/storage/file_system.rb', line 74

def movable?(io, id)
  io.respond_to?(:path) ||
    (io.is_a?(UploadedFile) && io.storage.is_a?(Storage::FileSystem))
end

#move(io, id, shrine_metadata: {}, **upload_options) ⇒ Object

Moves the file to the given location. This gets called by the ‘moving` plugin.



62
63
64
65
66
67
68
69
70
# File 'lib/shrine/storage/file_system.rb', line 62

def move(io, id, shrine_metadata: {}, **upload_options)
  if io.respond_to?(:path)
    FileUtils.mv io.path, path!(id)
  else
    FileUtils.mv io.storage.path(io.id), path!(id)
    io.storage.clean(io.storage.path(io.id)) if io.storage.clean?
  end
  path(id).chmod(permissions) if permissions
end

#open(id, **options, &block) ⇒ Object

Opens the file on the given location in read mode. Accepts additional ‘File.open` arguments.



81
82
83
# File 'lib/shrine/storage/file_system.rb', line 81

def open(id, **options, &block)
  path(id).open(binmode: true, **options, &block)
end

#path(id) ⇒ Object

Returns the full path to the file.



127
128
129
# File 'lib/shrine/storage/file_system.rb', line 127

def path(id)
  directory.join(id.gsub("/", File::SEPARATOR))
end

#upload(io, id, shrine_metadata: {}, **upload_options) ⇒ Object

Copies the file into the given location.



53
54
55
56
57
58
# File 'lib/shrine/storage/file_system.rb', line 53

def upload(io, id, shrine_metadata: {}, **upload_options)
  bytes_copied = IO.copy_stream(io, path!(id))
  path(id).chmod(permissions) if permissions

  ["size"] ||= bytes_copied
end

#url(id, host: self.host, **options) ⇒ Object

If #prefix is not present, returns a path composed of #directory and the given ‘id`. If #prefix is present, it excludes the #directory part from the returned path (e.g. #directory can be set to “public” folder). Both cases accept a `:host` value which will be prefixed to the generated path.



104
105
106
107
# File 'lib/shrine/storage/file_system.rb', line 104

def url(id, host: self.host, **options)
  path = (prefix ? relative_path(id) : path(id)).to_s
  host ? host + path : path
end