137
from common import (util, studpath, zip)
137
from common import (util, studpath)
139
139
# Make a Subversion client object
140
140
svnclient = pysvn.Client()
179
179
raise ActionError("Unknown action")
180
180
action(req, fields)
182
def actionpath_to_urlpath(req, path):
183
"""Determines the URL path (relative to the student home) upon which the
184
action is intended to act. See actionpath_to_local.
188
elif len(path) > 0 and path[0] == os.sep:
189
# Relative to student home
192
# Relative to req.path
193
return os.path.join(req.path, path)
195
182
def actionpath_to_local(req, path):
196
183
"""Determines the local path upon which an action is intended to act.
197
184
Note that fileservice actions accept two paths: the request path,
209
196
Does not mutate req.
211
_, r = studpath.url_to_local(actionpath_to_urlpath(req, path))
200
elif len(path) > 0 and path[0] == os.sep:
201
# Relative to student home
204
# Relative to req.path
205
path = os.path.join(req.path, path)
207
_, r = studpath.url_to_local(path)
213
209
raise ActionError("Invalid path")
293
289
Reads fields: 'path', 'data' (file upload)
295
# TODO: Read field "unpack".
296
291
# Important: Data is "None" if the file submitted is empty.
297
292
path = fields.getfirst('path')
298
293
data = fields.getfirst('data')
311
306
raise ActionError("Could not write to target file")
313
def action_putfiles(req, fields):
314
"""Writes data to one or more files in a directory, overwriting them if
317
Reads fields: 'path', 'data' (file upload, multiple), 'unpack'
319
# Important: Data is "None" if the file submitted is empty.
320
path = fields.getfirst('path')
321
data = fields.getlist('data')
322
unpack = fields.getfirst('unpack')
328
raise ActionError("Required field missing")
329
path = actionpath_to_urlpath(req, path)
333
# Each of the uploaded files
334
filepath = os.path.join(path, datum.filename)
335
filedata = datum.file
337
if unpack and datum.filename.lower().endswith(".zip"):
338
# A zip file - unpack it instead of just copying
339
# TODO: Use the magic number instead of file extension
340
# Note: Just unzip into the current directory (ignore the
343
zip.unzip(path, filedata)
344
except (OSError, IOError):
348
_, filepath_local = studpath.url_to_local(filepath)
349
if filepath_local is None:
350
raise ActionError("Invalid path")
352
# Copy the contents of file object 'data' to the path 'path'
354
dest = open(filepath_local, 'wb')
356
shutil.copyfileobj(filedata, dest)
362
raise ActionError("Could not write to target file")
365
"Could not write to one or more of the target files")
367
308
def action_copy_or_cut(req, fields, mode):
368
309
"""Marks specified files on the clipboard, stored in the
369
310
browser session. Sets clipboard for either a cut or copy operation