Change to background of "empty_space", it now uses an image
[mediagoblin.git] / mediagoblin / workbench.py
1 # GNU MediaGoblin -- federated, autonomous media hosting
2 # Copyright (C) 2011 MediaGoblin contributors. See AUTHORS.
3 #
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.
8 #
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.
13 #
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/>.
16
17 import os
18 import shutil
19 import tempfile
20
21
22 DEFAULT_WORKBENCH_DIR = os.path.join(
23 tempfile.gettempdir(), u'mgoblin_workbench')
24
25
26 # Actual workbench stuff
27 # ----------------------
28
29 class Workbench(object):
30 """
31 Represent the directory for the workbench
32
33 WARNING: DO NOT create Workbench objects on your own,
34 let the WorkbenchManager do that for you!
35 """
36 def __init__(self, dir):
37 """
38 WARNING: DO NOT create Workbench objects on your own,
39 let the WorkbenchManager do that for you!
40 """
41 self.dir = dir
42
43 def __unicode__(self):
44 return unicode(self.dir)
45
46 def __str__(self):
47 return str(self.dir)
48
49 def __repr__(self):
50 return repr(self.dir)
51
52 def joinpath(self, *args):
53 return os.path.join(self.dir, *args)
54
55 def localized_file(self, storage, filepath,
56 filename_if_copying=None,
57 keep_extension_if_copying=True):
58 """
59 Possibly localize the file from this storage system (for read-only
60 purposes, modifications should be written to a new file.).
61
62 If the file is already local, just return the absolute filename of that
63 local file. Otherwise, copy the file locally to the workbench, and
64 return the absolute path of the new file.
65
66 If it is copying locally, we might want to require a filename like
67 "source.jpg" to ensure that we won't conflict with other filenames in
68 our workbench... if that's the case, make sure filename_if_copying is
69 set to something like 'source.jpg'. Relatedly, if you set
70 keep_extension_if_copying, you don't have to set an extension on
71 filename_if_copying yourself, it'll be set for you (assuming such an
72 extension can be extacted from the filename in the filepath).
73
74 Returns:
75 localized_filename
76
77 Examples:
78 >>> wb_manager.localized_file(
79 ... '/our/workbench/subdir', local_storage,
80 ... ['path', 'to', 'foobar.jpg'])
81 u'/local/storage/path/to/foobar.jpg'
82
83 >>> wb_manager.localized_file(
84 ... '/our/workbench/subdir', remote_storage,
85 ... ['path', 'to', 'foobar.jpg'])
86 '/our/workbench/subdir/foobar.jpg'
87
88 >>> wb_manager.localized_file(
89 ... '/our/workbench/subdir', remote_storage,
90 ... ['path', 'to', 'foobar.jpg'], 'source.jpeg', False)
91 '/our/workbench/subdir/foobar.jpeg'
92
93 >>> wb_manager.localized_file(
94 ... '/our/workbench/subdir', remote_storage,
95 ... ['path', 'to', 'foobar.jpg'], 'source', True)
96 '/our/workbench/subdir/foobar.jpg'
97 """
98 if storage.local_storage:
99 return storage.get_local_path(filepath)
100 else:
101 if filename_if_copying is None:
102 dest_filename = filepath[-1]
103 else:
104 orig_filename, orig_ext = os.path.splitext(filepath[-1])
105 if keep_extension_if_copying and orig_ext:
106 dest_filename = filename_if_copying + orig_ext
107 else:
108 dest_filename = filename_if_copying
109
110 full_dest_filename = os.path.join(
111 self.dir, dest_filename)
112
113 # copy it over
114 storage.copy_locally(
115 filepath, full_dest_filename)
116
117 return full_dest_filename
118
119 def destroy_self(self):
120 """
121 Destroy this workbench! Deletes the directory and all its contents!
122
123 WARNING: Does no checks for a sane value in self.dir!
124 """
125 # just in case
126 workbench = os.path.abspath(self.dir)
127
128 shutil.rmtree(workbench)
129
130 del self.dir
131
132
133 class WorkbenchManager(object):
134 """
135 A system for generating and destroying workbenches.
136
137 Workbenches are actually just subdirectories of a temporary storage space
138 for during the processing stage.
139 """
140
141 def __init__(self, base_workbench_dir):
142 self.base_workbench_dir = os.path.abspath(base_workbench_dir)
143 if not os.path.exists(self.base_workbench_dir):
144 os.makedirs(self.base_workbench_dir)
145
146 def create_workbench(self):
147 """
148 Create and return the path to a new workbench (directory).
149 """
150 return Workbench(tempfile.mkdtemp(dir=self.base_workbench_dir))