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