-
Notifications
You must be signed in to change notification settings - Fork 0
/
symlinkstorage.py
executable file
·56 lines (44 loc) · 2.19 KB
/
symlinkstorage.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
import os
from django.conf import settings
from django.core.files.storage import FileSystemStorage
__doc__ = """
I needed to efficiently create a mirror of a directory tree (so that
"origin pull" CDNs can automatically pull files). The trick was that
some files could be modified, and some could be identical to the original.
Of course it doesn't make sense to store the exact same data twice on the
file system. So I created SymlinkStorage.
SymlinkStorage allows you to symlink a file when it's identical to
the original file and to copy the file if it's modified.
Of course, it's impossible to know if a file is modified just by looking
at the file, without knowing what the original file was.
That's what the symlinkWithin parameter is for. It accepts one or more paths
(if multiple, they should be concatenated using a colon (:)).
Files that will be saved using SymlinkStorage are then checked on their
location: if they are within one of the symlink_within directories,
they will be symlinked, otherwise they will be copied.
The rationale is that unmodified files will exist in their original location,
e.g. /htdocs/example.com/image.jpg and modified files will be stored in
a temporary directory, e.g. /tmp/image.jpg.
"""
class SymlinkStorage(FileSystemStorage):
"""Stores symlinks to files instead of actual files whenever possible
When a file that's being saved is currently stored in the symlink_within
directory, then symlink the file. Otherwise, copy the file.
"""
def _save(self, name, content):
full_path_dst = self.path(name)
directory = os.path.dirname(full_path_dst)
if not os.path.exists(directory):
os.makedirs(directory)
elif not os.path.isdir(directory):
raise IOError("%s exists and is not a directory." % directory)
#print content.__class__
full_path_src = os.path.abspath(content.name)
symlinked = False
# Only symlink if the current platform supports it.
if getattr(os, "symlink", False):
os.symlink(full_path_src, full_path_dst)
symlinked = True
if not symlinked:
super(SymlinkStorage, self)._save(name, content)
return name