1 # GNU MediaGoblin -- federated, autonomous media hosting
2 # Copyright (C) 2011 Free Software Foundation, Inc
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU Affero General Public License for more details.
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 DEFAULT_WORKBENCH_DIR
= os
.path
.join(
23 tempfile
.gettempdir(), u
'mgoblin_workbench')
29 class WorkbenchOutsideScope(Exception):
31 Raised when a workbench is outside a WorkbenchManager scope.
36 # Actual workbench stuff
37 # ----------------------
39 class Workbench(object):
41 Represent the directory for the workbench
43 def __init__(self
, dir):
46 def __unicode__(self
):
47 return unicode(self
.dir)
53 def joinpath(self
, *args
):
54 return os
.path
.join(self
.dir, *args
)
56 def localized_file(self
, storage
, filepath
,
57 filename_if_copying
=None,
58 keep_extension_if_copying
=True):
60 Possibly localize the file from this storage system (for read-only
61 purposes, modifications should be written to a new file.).
63 If the file is already local, just return the absolute filename of that
64 local file. Otherwise, copy the file locally to the workbench, and
65 return the absolute path of the new file.
67 If it is copying locally, we might want to require a filename like
68 "source.jpg" to ensure that we won't conflict with other filenames in
69 our workbench... if that's the case, make sure filename_if_copying is
70 set to something like 'source.jpg'. Relatedly, if you set
71 keep_extension_if_copying, you don't have to set an extension on
72 filename_if_copying yourself, it'll be set for you (assuming such an
73 extension can be extacted from the filename in the filepath).
79 >>> wb_manager.localized_file(
80 ... '/our/workbench/subdir', local_storage,
81 ... ['path', 'to', 'foobar.jpg'])
82 u'/local/storage/path/to/foobar.jpg'
84 >>> wb_manager.localized_file(
85 ... '/our/workbench/subdir', remote_storage,
86 ... ['path', 'to', 'foobar.jpg'])
87 '/our/workbench/subdir/foobar.jpg'
89 >>> wb_manager.localized_file(
90 ... '/our/workbench/subdir', remote_storage,
91 ... ['path', 'to', 'foobar.jpg'], 'source.jpeg', False)
92 '/our/workbench/subdir/foobar.jpeg'
94 >>> wb_manager.localized_file(
95 ... '/our/workbench/subdir', remote_storage,
96 ... ['path', 'to', 'foobar.jpg'], 'source', True)
97 '/our/workbench/subdir/foobar.jpg'
99 if storage
.local_storage
:
100 return storage
.get_local_path(filepath
)
102 if filename_if_copying
is None:
103 dest_filename
= filepath
[-1]
105 orig_filename
, orig_ext
= os
.path
.splitext(filepath
[-1])
106 if keep_extension_if_copying
and orig_ext
:
107 dest_filename
= filename_if_copying
+ orig_ext
109 dest_filename
= filename_if_copying
111 full_dest_filename
= os
.path
.join(
112 self
.dir, dest_filename
)
115 storage
.copy_locally(
116 filepath
, full_dest_filename
)
118 return full_dest_filename
121 class WorkbenchManager(object):
123 A system for generating and destroying workbenches.
125 Workbenches are actually just subdirectories of a temporary storage space
126 for during the processing stage.
129 def __init__(self
, base_workbench_dir
):
130 self
.base_workbench_dir
= os
.path
.abspath(base_workbench_dir
)
131 if not os
.path
.exists(self
.base_workbench_dir
):
132 os
.makedirs(self
.base_workbench_dir
)
134 def create_workbench(self
):
136 Create and return the path to a new workbench (directory).
138 return Workbench(tempfile
.mkdtemp(dir=self
.base_workbench_dir
))
140 def destroy_workbench(self
, workbench
):
142 Destroy this workbench! Deletes the directory and all its contents!
144 Makes sure the workbench actually belongs to this manager though.
147 workbench
= os
.path
.abspath(workbench
.dir)
149 if not workbench
.startswith(self
.base_workbench_dir
):
150 raise WorkbenchOutsideScope(
151 "Can't destroy workbench outside the base workbench dir")
153 shutil
.rmtree(workbench
)