Example #1
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)
Example #2
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)
Example #3
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
Example #4
0
    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
Example #5
0
    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
Example #6
0
 def __update_display_name(self):
     # This is encoded for displaying locally.
     self.__info['title_fs'] = utility.translate_filename_charset(self.__info['title'])
Example #7
0
    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
Example #8
0
 def __update_display_name(self):
     # This is encoded for displaying locally.
     self.__info['title_fs'] = utility.translate_filename_charset(
         self.__info['title'])
Example #9
0
    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
Example #10
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 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
Example #11
0
    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