def read_file(self, object_tree_root, path, size, offset): log.debug( u'read_file: {0}, {1}, {2}'. format(util.string_from_path_elements(path), size, offset) ) try: object_tree_folder = self._object_tree.get_folder(path, object_tree_root) except ONEDriveException: pass else: if len(path) > 0: if path[-1] == object_tree_folder.get_help_name(): return self._getFolderHelp(object_tree_folder, size, offset) #return object_tree_folder.get_help_text(size, offset) raise onedrive_exceptions.PathException(u'Invalid file') object_tree_path, root_name, controlled_path = self._split_path_by_reserved_name( path ) try: object_tree_folder = self._object_tree.get_folder( object_tree_path, object_tree_root ) except ONEDriveException: raise onedrive_exceptions.PathException(u'Invalid folder') if self._is_readme_file([root_name]): return self._generate_readme_text(object_tree_path)[offset:offset + size] return self._resolvers[root_name].read_file( object_tree_folder, controlled_path, size, offset )
def _split_path_by_reserved_name(self, path): """Return: object_tree_path, resolver, controlled_path """ for i, e in enumerate(path): if e in self._resolvers or e == self._get_readme_filename(): return path[:i], path[i], path[i + 1:] raise onedrive_exceptions.PathException(u'Invalid folder: %s' % str(path))
def read_file(self, object_tree_folder, path, size, offset): log.debug(u'read_file: {0}, {1}, {2}'.format( util.string_from_path_elements(path), size, offset)) if self._is_readme_file(path): return self._get_readme_text(size, offset) if len(path) <= 2: raise onedrive_exceptions.PathException(u'Invalid file') return self._resource_map_resolver.read_file(path[2:], size, offset)
def get_attributes(self, object_tree_root, path): log.debug( u'get_attributes: {0}'.format(util.string_from_path_elements(path)) ) # All items rendered by the ObjectTree Resolver are folders. Anything else is # deferred to one of the child resolvers. # To determine where the path transitions from the object_tree to the # controlled hierarchy, we check for the controlled hierarchy root names. # This means that those names are reserved. They can not be used as # object_tree folder names by the user. try: object_tree_folder = self._object_tree.get_folder(path, object_tree_root) except ONEDriveException: pass else: return attributes.Attributes(is_dir=True) #if len(path) > 0: # if path[-1] == self._get_help_name(): # return attributes.Attributes(size=self._folderHelpSize(object_tree_folder), # is_dir=False) # If the path is not to a object_tree folder root, a valid path must go to a # controlled hierarchy root or subfolder THROUGH a object_tree folder root. In # that case, the first path element that matches the reserved name of one of # the controlled hierarchy roots becomes the separator between the two # sections and determines which resolver to use for the tail section of the # path. object_tree_path, root_name, controlled_path = self._split_path_by_reserved_name( path ) # If the object_tree_path is not valid now and is not the readme file, then # the path is invalid. try: object_tree_folder = self._object_tree.get_folder( object_tree_path, object_tree_root ) except ONEDriveException: raise onedrive_exceptions.PathException(u'Invalid folder') if self._is_readme_file([root_name]): return self._get_readme_file_attributes(object_tree_path) # Now have all information required for gathering information about all the # objects in the object_tree folder and dispatching to a controlled hierarchy # resolver. #object_tree_folder = ObjectTreeFolderObjects(self._object_tree, object_tree_folder) return self._resolvers[root_name].get_attributes( object_tree_folder, controlled_path )
def _validate_and_split_decade_range(self, decade): try: first_year, last_year = decade.split('-') if len(first_year) != 4 or len(last_year) != 4: raise ValueError first_year, last_year = int(first_year), int(last_year) if first_year > last_year: raise ValueError except ValueError: raise onedrive_exceptions.PathException( u'Expected decade range on form yyyy-yyyy') else: return first_year, last_year
def get_directory(self, object_tree_root, path, preconfigured_query=None): # the directory will typically be in the cache. already retrieved by # get_attributes, since get_attributes() needs to know how many items # there are in the directory, in order to return that count. log.debug( u'get_directory: {0}'.format(util.string_from_path_elements(path)) ) # To determine where the path transitions from the object_tree to the # controlled hierarchy, we check for the controlled hierarchy root names. # This means that those names are reserved. They can not be used as # object_tree folder names by the user. try: object_tree_folder = self._object_tree.get_folder(path, object_tree_root) except ONEDriveException: pass else: res = self._resolve_object_tree_folder(object_tree_folder) # All object_tree folders have a readme. res.append(self._get_readme_filename()) return res # If the path is not to a object_tree folder root, a valid path must go to a # controlled hierarchy root or subfolder THROUGH a object_tree folder root. In # that case, the first path element that matches the reserved name of one of # the controlled hierarchy roots becomes the separator between the two # sections and determines which resolver to use for the tail section of the # path. object_tree_path, root_name, controlled_path = self._split_path_by_reserved_name( path ) # If the object_tree_path is not valid now, then the path is invalid. try: object_tree_folder = self._object_tree.get_folder( object_tree_path, object_tree_root ) except ONEDriveException: raise onedrive_exceptions.PathException(u'Invalid folder') log.debug('controlled path: {0}'.format(controlled_path)) #log.debug('object_tree folder: {0}'.format(object_tree_folder)) # Now have all information required for gathering information about all the # objects in the object_tree folder and dispatching to a controlled hierarchy # resolver. return self._resolvers[root_name].get_directory( object_tree_folder, controlled_path )
def _resolve_author(self, author, object_tree_folder): d = directory.Directory() for pid in object_tree_folder['items']: try: record = self._object_tree.get_object_record(pid) if record['author'] == author: d.append(record['id']) except KeyError: pass # As each author folder in the root has at least one object, an empty folder # here can only be due to an invalid path. if not d: raise onedrive_exceptions.PathException(u'Invalid author') return d
def _get_directory(self, object_tree_folder, path): if len(path) == 0: return self._resolve_decades(object_tree_folder) elif len(path) == 1: decade_range_str = path[0] return self._resolve_years_in_decade(decade_range_str, object_tree_folder) else: try: year = int(path[1]) except ValueError: raise onedrive_exceptions.PathException( u'Expected year element in path') else: return self._resolve_objects_in_year(year, object_tree_folder)
def _resolve_taxa_classification_value(self, classification, value, object_tree_folder): d = directory.Directory() for pid in object_tree_folder.get_records['items']: record = self._object_tree.get_object_record(pid) try: if value in record[classification]: d.append(record['id']) except KeyError: pass # As empty folders in the taxa tree are pruned in the root and first level, # an empty folder here can only be due to an invalid path. if not len(d): raise onedrive_exceptions.PathException( u'Invalid taxonomic classification value') return d
def _get_region_tree_item_and_unconsumed_path( self, region_tree, path, parent_key='' ): """Return the region_tree item specified by path. An item can be a a folder (represented by a dictionary) or a PID (represented by None). This function is also used for determining which section of a path is within the region tree and which section should be passed to the next resolver. To support this, the logic is as follows: - If the path points to an item in the region tree, the item is returned and the path, having been fully consumed, is returned as an empty list. - If the path exits through a valid PID in the region tree, the PID is returned for the item and the section of the path that was not consumed within the region tree is returned. - If the path exits through a valid folder in the region tree, an "invalid path" PathException is raised. This is because only the PIDs are valid "exit points" in the tree. - If the path goes to an invalid location within the region tree, an "invalid path" PathException is raised. """ # Handle valid item within region tree. if not path: if region_tree is None: return parent_key, [] else: return region_tree, [] # Handle valid exit through PID. if region_tree is None: return parent_key, path # Handle next level in path. if path[0] in region_tree.keys(): return self._get_region_tree_item_and_unconsumed_path( region_tree[path[0]], path[1:], path[0] ) else: raise onedrive_exceptions.PathException('Invalid path')
def _raise_invalid_pid(self, pid): raise onedrive_exceptions.PathException( u'Invalid PID: {0}'.format(pid))
def _raise_exception_if_empty_directory(self, directory, msg=None): """In hierarchies where ONEDrive dynamically renders directories only after having determined that there are contents for them, an empty directory means that the path is invalid.""" if len(directory) <= 2: raise onedrive_exceptions.PathException(msg)
def _raise_if_os_special_file(self, path): # For each file of "name", Finder on Mac OS X attempts to access ".name". if path[-1] in self._options.ignore_special: log.debug('Ignored file: {0}'.format(path[-1])) raise onedrive_exceptions.PathException(u'Ignored OS special file')
def _resolver_lookup(self, path): try: return self._resolvers[path[0]] except KeyError: raise onedrive_exceptions.PathException(u'Invalid root directory')