def get_temp_file(self, path, mode="rw"): """Like get_file() except that it uses a parallel file as its source, resorting to get_file() when the parallel file does not exist.""" if "../" in path: raise BadValue("Relative directories are not allowed") # Load from the temp file first file_loc = self.location / get_temp_file_name(self.name, path) if file_loc.exists(): log.debug("get_temp_file path=%s" % file_loc) return str(file_loc.bytes()) # Otherwise, go for data from the real file file_obj = File(self, path) if file_obj.exists(): log.debug("fallback get_temp_file path=%s" % path) return str(file_obj.data) # If we still don't have something then this must be a new (temp) file if file_loc.isdir(): raise FileConflict( "Cannot save file at %s in project " "%s, because there is already a directory with that name." % (destpath, self.name)) log.debug("New file - creating temp space") file_dir = file_loc.dirname() if not file_dir.exists(): file_dir.makedirs() _save(file_loc, "") return ""
def save_temp_file(self, destpath, contents=None): """Saves the contents to the file path provided, creating directories as needed in between. If last_edit is not provided, the file must not be opened for editing. Otherwise, the last_edit parameter should include the last edit ID received by the user.""" if "../" in destpath: raise BadValue("Relative directories are not allowed") # chop off any leading slashes while destpath and destpath.startswith("/"): destpath = destpath[1:] temp_name = get_temp_file_name(self.name, destpath) file_loc = self.location.parent / temp_name if file_loc.isdir(): raise FileConflict( "Cannot save file at %s in project " "%s, because there is already a directory with that name." % (destpath, self.name)) file_dir = file_loc.dirname() if not file_dir.exists(): file_dir.makedirs() log.debug("save_temp_file to %s", file_loc) _save(file_loc, contents)
def __init__(self, project, name): if "../" in name: raise BadValue("Relative directories are not allowed") # chop off any leading slashes while name and name.startswith("/"): name = name[1:] self.project = project self.name = name self.location = project.location / name self._info = None
def create_directory(self, destpath): """Create a new directory""" if "../" in destpath: raise BadValue("Relative directories are not allowed") # chop off any leading slashes while destpath and destpath.startswith("/"): destpath = destpath[1:] file_loc = self.location / destpath if file_loc.exists(): if file_loc.isfile(): raise FileConflict("Cannot create directory %s " "because there is already a file there." % destpath) else: file_loc.makedirs()
def __init__(self, project, name): if "../" in name: raise BadValue("Relative directories are not allowed") # chop off any leading slashes while name and name.startswith("/"): name = name[1:] self.project = project self.name = name self.location = project.location / name self._info = None if self.location.islink(): raise FSException( "That path is a symlink, and symlinks are not supported.") if self.location.isdir(): raise FSException( "Directory found where file was expected. (When referring to a directory, use a trailing slash.)" )
def find_member(self, member): """When a user refers to X, is this a reference to a user or a group or even the everyone setting""" if isinstance(member, User): return member if isinstance(member, Group): return member if isinstance(member, str): if member == 'everyone': return member else: group = self.get_group(member) if group != None: return group else: user = User.find_user(member) if user != None: return user raise BadValue("No groups or users found called '%s'" % (member))
def save_file(self, destpath, contents=None): """Saves the contents to the file path provided, creating directories as needed in between. If last_edit is not provided, the file must not be opened for editing. Otherwise, the last_edit parameter should include the last edit ID received by the user.""" if "../" in destpath: raise BadValue("Relative directories are not allowed") # chop off any leading slashes while destpath and destpath.startswith("/"): destpath = destpath[1:] saved_size = len(contents) if contents is not None else 0 if not self.owner.check_save(saved_size): raise OverQuota() file_loc = self.location / destpath if file_loc.isdir(): raise FileConflict( "Cannot save file at %s in project " "%s, because there is already a directory with that name." % (destpath, self.name)) file_dir = file_loc.dirname() if not file_dir.exists(): file_dir.makedirs() file = File(self, destpath) if file.exists(): size_delta = saved_size - file.saved_size else: size_delta = saved_size self.metadata.cache_add(destpath) config.c.stats.incr("files") file.save(contents) self.owner.amount_used += size_delta return file
def __init__(self, project, name): if "../" in name: raise BadValue("Relative directories are not allowed") if not name.endswith("/"): name += "/" # chop off any leading slashes while name and name.startswith("/"): name = name[1:] self.name = name self.location = project.location / name # we can only properly check directory entries as being symlinks # if they don't have the trailing slash, which we ensured is there # a couple lines ago if path_obj(self.location[:-1]).islink(): raise FSException( "That path points to a symlink, and symlinks are not supported." )
def install_template(self, template="template", other_vars=None): """Installs a set of template files into a new project. The template directory will be found by searching config.c.template_path to find a matching directory name. The files inside of that directory will be installed into the project, with the common root for the files chopped off. Additionally, filenames containing { will be treated as JSON Template templates and the contents of files will be treated as JSON Template templates. This means that the filenames can contain variables that are substituted when the template is installed into the user's project. The contents of the files can also have variables and small amounts of logic. These JSON Template templates automatically have the following variables: * project: the project name * username: the project owner's username * filename: the name of the file being generated You can pass in a dictionary for other_vars and those values will also be available in the templates. """ log.debug("Installing template %s for user %s as project %s", template, self.owner, self.name) if "/" in template or "." in template: raise BadValue("Template names cannot include '/' or '.'") found = False for p in config.c.template_path: source_dir = path_obj(p) / template if source_dir.isdir(): found = True break if not found: raise FSException("Unknown project template: %s" % template) if other_vars is not None: variables = LenientUndefinedDict(other_vars) else: variables = LenientUndefinedDict() variables['project'] = self.name variables['username'] = self.owner.username common_path_len = len(source_dir) + 1 for dirpath, dirnames, filenames in os.walk(source_dir): destdir = dirpath[common_path_len:] if '.svn' in destdir: continue for f in filenames: if "{" in f: dest_f = jsontemplate.expand(f, variables) else: dest_f = f if destdir: destpath = "%s/%s" % (destdir, dest_f) else: destpath = dest_f contents = open(os.path.join(dirpath, f)).read() variables['filename'] = dest_f contents = jsontemplate.expand(contents, variables) self.save_file(destpath, contents)
def __init__(self, group, user): if group.id == None: raise BadValue("Null group.id for " + group.name) self.group_id = group.id self.user_id = user.id