def readdir(self, path, offset): """A generator returning one base filename at a time.""" # We expect "offset" to always be (0). if offset != 0: _logger.warning("readdir() has been invoked for path [%s] and " "non-zero offset (%d). This is not allowed.", path, offset) # TODO: Once we start working on the cache, make sure we don't make this call, # constantly. path_relations = PathRelations.get_instance() try: entry_clause = path_relations.get_clause_from_path(path) except GdNotFoundError: _logger.exception("Could not process [%s] (readdir).") raise FuseOSError(ENOENT) except: _logger.exception("Could not get clause from path [%s] " "(readdir)." % (path)) raise FuseOSError(EIO) if not entry_clause: raise FuseOSError(ENOENT) try: entry_tuples = path_relations.get_children_entries_from_entry_id \ (entry_clause[CLAUSE_ID]) except: _logger.exception("Could not render list of filenames under path " "[%s].", path) raise FuseOSError(EIO) yield utility.translate_filename_charset('.') yield utility.translate_filename_charset('..') for (filename, entry) in entry_tuples: # Decorate any file that -requires- a mime-type (all files can # merely accept a mime-type) if entry.requires_mimetype: filename += utility.translate_filename_charset('#') yield (filename, self.__build_stat_from_entry(entry), 0)
def readdir(self, path, offset): """A generator returning one base filename at a time.""" # We expect "offset" to always be (0). if offset != 0: _logger.warning( "readdir() has been invoked for path [%s] and " "non-zero offset (%d). This is not allowed.", path, offset) # TODO: Once we start working on the cache, make sure we don't make this call, # constantly. path_relations = PathRelations.get_instance() try: entry_clause = path_relations.get_clause_from_path(path) except GdNotFoundError: _logger.exception("Could not process [%s] (readdir).") raise FuseOSError(ENOENT) except: _logger.exception("Could not get clause from path [%s] " "(readdir)." % (path)) raise FuseOSError(EIO) if not entry_clause: raise FuseOSError(ENOENT) try: entry_tuples = path_relations.get_children_entries_from_entry_id \ (entry_clause[CLAUSE_ID]) except: _logger.exception( "Could not render list of filenames under path " "[%s].", path) raise FuseOSError(EIO) yield utility.translate_filename_charset('.') yield utility.translate_filename_charset('..') for (filename, entry) in entry_tuples: # Decorate any file that -requires- a mime-type (all files can # merely accept a mime-type) if entry.requires_mimetype: filename += utility.translate_filename_charset('#') yield (filename, self.__build_stat_from_entry(entry), 0)
def __convert(self, data): if isinstance(data, dict): list_ = [] for key, value in data.items(): phrase = \ 'K({})=V({})'.format( self.__convert(key), self.__convert(value)) list_.append(phrase) final = '; '.join(list_) return final elif isinstance(data, list): final = ', '.join([('LI(%s)' % (self.__convert(element))) \ for element \ in data]) return final elif isinstance(data, str): return utility.translate_filename_charset(data) elif isinstance(data, Number): return str(data) elif isinstance(data, datetime): return get_flat_normal_fs_time_from_dt(data) else: return data
def __convert(self, data): if isinstance(data, dict): list_ = [("K(%s)=V(%s)" % (self.__convert(key), self.__convert(value))) \ for key, value \ in data.iteritems()] final = '; '.join(list_) return final elif isinstance(data, list): final = ', '.join([('LI(%s)' % (self.__convert(element))) \ for element \ in data]) return final elif isinstance(data, unicode): return utility.translate_filename_charset(data) elif isinstance(data, Number): return str(data) elif isinstance(data, datetime): return get_flat_normal_fs_time_from_dt(data) else: return data
def __update_display_name(self): # This is encoded for displaying locally. self.__info['title_fs'] = utility.translate_filename_charset(self.__info['title'])
def register_entry(self, normalized_entry): # self.__log.debug("We're registering entry with ID [%s] [%s]." % # (normalized_entry.id, normalized_entry.title)) with PathRelations.rlock: if not normalized_entry.is_visible: # self.__log.debug("We will not register entry with ID [%s] " # "because it's not visible." % # (normalized_entry.id)) return None if normalized_entry.__class__ is not NormalEntry: raise Exception("PathRelations expects to register an object " "of type NormalEntry, not [%s]." % (type(normalized_entry))) entry_id = normalized_entry.id # self.__log.debug("Registering entry with ID [%s] within path-" # "relations.", entry_id) if self.is_cached(entry_id, include_placeholders=False): # self.__log.debug("Entry to register with ID [%s] already " # "exists within path-relations, and will be " # "removed in lieu of update." % (entry_id)) # self.__log.debug("Removing existing entries.") self.remove_entry_recursive(entry_id, True) # self.__log.debug("Doing add of entry with ID [%s]." % (entry_id)) cache = EntryCache.get_instance().cache cache.set(normalized_entry.id, normalized_entry) # We do a linked list using object references. # ( # normalized_entry, # [ parent clause, ... ], # [ child clause, ... ], # entry-ID, # < boolean indicating that we know about all children > # ) if self.is_cached(entry_id, include_placeholders=True): # self.__log.debug("Placeholder exists for entry-to-register " # "with ID [%s]." % (entry_id)) entry_clause = self.entry_ll[entry_id] entry_clause[CLAUSE_ENTRY] = normalized_entry entry_clause[CLAUSE_PARENT] = [ ] else: # self.__log.debug("Entry does not yet exist in LL.") entry_clause = [normalized_entry, [ ], [ ], entry_id, False] self.entry_ll[entry_id] = entry_clause entry_parents = entry_clause[CLAUSE_PARENT] title_fs = normalized_entry.title_fs # self.__log.debug("Registering entry with title [%s]." % (title_fs)) parent_ids = normalized_entry.parents if normalized_entry.parents \ is not None else [] # self.__log.debug("Parents are: %s" % (', '.join(parent_ids))) for parent_id in parent_ids: # self.__log.debug("Processing parent with ID [%s] of entry " # "with ID [%s]." % (parent_id, entry_id)) # If the parent hasn't yet been loaded, install a placeholder. if self.is_cached(parent_id, include_placeholders=True): # self.__log.debug("Parent has an existing entry.") parent_clause = self.entry_ll[parent_id] else: # self.__log.debug("Parent is not yet registered.") parent_clause = [None, None, [ ], parent_id, False] self.entry_ll[parent_id] = parent_clause if parent_clause not in entry_parents: entry_parents.append(parent_clause) parent_children = parent_clause[CLAUSE_CHILDREN] filename_base = title_fs # Register among the children of this parent, but make sure we # have a unique filename among siblings. i = 0 current_variation = filename_base elected_variation = None while i <= 255: if not [ child_name_tuple for child_name_tuple in parent_children if child_name_tuple[0] == current_variation ]: elected_variation = current_variation break i += 1 current_variation = filename_base + \ utility.translate_filename_charset( ' (%d)' % (i)) if elected_variation == None: self.__log.error("Could not register entry with ID [%s]. " "There are too many duplicate names in " "that directory." % (entry_id)) return # self.__log.debug("Final filename is [%s]." % # (current_variation)) # Register us in the list of children on this parents # child-tuple list. parent_children.append((elected_variation, entry_clause)) # self.__log.debug("Entry registration complete.") return entry_clause
def __update_display_name(self): # This is encoded for displaying locally. self.__info['title_fs'] = utility.translate_filename_charset( self.__info['title'])
def register_entry(self, normalized_entry): with PathRelations.rlock: if not normalized_entry.is_visible: return None if normalized_entry.__class__ is not NormalEntry: raise Exception("PathRelations expects to register an object " "of type NormalEntry, not [%s]." % (type(normalized_entry))) entry_id = normalized_entry.id # self.__log.debug("Registering entry with ID [%s] within path-" # "relations.", entry_id) if self.is_cached(entry_id, include_placeholders=False): self.remove_entry_recursive(entry_id, True) cache = EntryCache.get_instance().cache cache.set(normalized_entry.id, normalized_entry) # We do a linked list using object references. # ( # normalized_entry, # [ parent clause, ... ], # [ child clause, ... ], # entry-ID, # < boolean indicating that we know about all children > # ) if self.is_cached(entry_id, include_placeholders=True): entry_clause = self.entry_ll[entry_id] entry_clause[CLAUSE_ENTRY] = normalized_entry entry_clause[CLAUSE_PARENT] = [] else: entry_clause = [normalized_entry, [], [], entry_id, False] self.entry_ll[entry_id] = entry_clause entry_parents = entry_clause[CLAUSE_PARENT] title_fs = normalized_entry.title_fs parent_ids = normalized_entry.parents if normalized_entry.parents \ is not None else [] for parent_id in parent_ids: # If the parent hasn't yet been loaded, install a placeholder. if self.is_cached(parent_id, include_placeholders=True): parent_clause = self.entry_ll[parent_id] else: parent_clause = [None, None, [], parent_id, False] self.entry_ll[parent_id] = parent_clause if parent_clause not in entry_parents: entry_parents.append(parent_clause) parent_children = parent_clause[CLAUSE_CHILDREN] filename_base = title_fs # Register among the children of this parent, but make sure we # have a unique filename among siblings. i = 0 current_variation = filename_base elected_variation = None while i <= 255: if not [ child_name_tuple for child_name_tuple in parent_children if child_name_tuple[0] == current_variation ]: elected_variation = current_variation break i += 1 current_variation = filename_base + \ utility.translate_filename_charset( ' (%d)' % (i)) if elected_variation == None: _logger.error("Could not register entry with ID [%s]. " "There are too many duplicate names in " "that directory." % (entry_id)) return # Register us in the list of children on this parents # child-tuple list. parent_children.append((elected_variation, entry_clause)) return entry_clause
def readdir(self, path, offset): """A generator returning one base filename at a time.""" # We expect "offset" to always be (0). if offset != 0: _logger.warning("readdir() has been invoked for path [%s] and " "non-zero offset (%d). This is not allowed.", path, offset) # TODO: Once we start working on the cache, make sure we don't make this call, # constantly. path_relations = PathRelations.get_instance() try: entry_clause = path_relations.get_clause_from_path(path) except GdNotFoundError: _logger.exception("Could not process [%s] (readdir).") raise FuseOSError(ENOENT) except: _logger.exception("Could not get clause from path [%s] " "(readdir)." % (path)) raise FuseOSError(EIO) if not entry_clause: raise FuseOSError(ENOENT) try: entry_tuples = path_relations.get_children_entries_from_entry_id \ (entry_clause[CLAUSE_ID]) except: _logger.exception("Could not render list of filenames under path " "[%s].", path) raise FuseOSError(EIO) # Yield filenames. yield utility.translate_filename_charset('.') yield utility.translate_filename_charset('..') # Yield filenames with stat information. for (filename, entry) in entry_tuples: # Decorate any file that -requires- a mime-type (all files can # merely accept a mime-type) if entry.requires_mimetype: filename += utility.translate_filename_charset('#') # TODO(dustin): We get an "Input/output error" from the FUSE library when there's a slash in the name. We're not sure what we can do here. https://github.com/fusepy/fusepy/issues/133 if '/' in filename: _logger.warning("Skipping entry with slash in the name: " "[{}]".format(path)) continue attrs = self.__build_stat_from_entry(entry) ye = _YIELDED_ENTRY( filename=filename, attrs=attrs, offset=0) yield ye
def register_entry(self, normalized_entry): with PathRelations.rlock: if not normalized_entry.is_visible: return None if normalized_entry.__class__ is not NormalEntry: raise Exception("PathRelations expects to register an object " "of type NormalEntry, not [%s]." % (type(normalized_entry))) entry_id = normalized_entry.id # self.__log.debug("Registering entry with ID [%s] within path-" # "relations.", entry_id) if self.is_cached(entry_id, include_placeholders=False): self.remove_entry_recursive(entry_id, True) cache = EntryCache.get_instance().cache cache.set(normalized_entry.id, normalized_entry) # We do a linked list using object references. # ( # normalized_entry, # [ parent clause, ... ], # [ child clause, ... ], # entry-ID, # < boolean indicating that we know about all children > # ) if self.is_cached(entry_id, include_placeholders=True): entry_clause = self.entry_ll[entry_id] entry_clause[CLAUSE_ENTRY] = normalized_entry entry_clause[CLAUSE_PARENT] = [ ] else: entry_clause = [normalized_entry, [ ], [ ], entry_id, False] self.entry_ll[entry_id] = entry_clause entry_parents = entry_clause[CLAUSE_PARENT] title_fs = normalized_entry.title_fs parent_ids = normalized_entry.parents if normalized_entry.parents \ is not None else [] for parent_id in parent_ids: # If the parent hasn't yet been loaded, install a placeholder. if self.is_cached(parent_id, include_placeholders=True): parent_clause = self.entry_ll[parent_id] else: parent_clause = [None, None, [ ], parent_id, False] self.entry_ll[parent_id] = parent_clause if parent_clause not in entry_parents: entry_parents.append(parent_clause) parent_children = parent_clause[CLAUSE_CHILDREN] filename_base = title_fs # Register among the children of this parent, but make sure we # have a unique filename among siblings. i = 0 current_variation = filename_base elected_variation = None while i <= 255: if not [ child_name_tuple for child_name_tuple in parent_children if child_name_tuple[0] == current_variation ]: elected_variation = current_variation break i += 1 current_variation = filename_base + \ utility.translate_filename_charset( ' (%d)' % (i)) if elected_variation == None: _logger.error("Could not register entry with ID [%s]. " "There are too many duplicate names in " "that directory." % (entry_id)) return # Register us in the list of children on this parents # child-tuple list. parent_children.append((elected_variation, entry_clause)) return entry_clause