예제 #1
0
    def info(self,
             path: str,
             fields: FileInfoReqIsh = FileInfoReq.internal(),
             path_resolved=False,
             skip_parse=None) -> FileInfo:
        if not path_resolved:
            path = os.path.abspath(path)
        if skip_parse is None:
            skip_parse = self._should_skip_parse(path)
        fields = FileInfoReq.parse(fields)

        if skip_parse or not os.path.exists(path):
            info = FileInfo(path)
        else:
            try:
                info = self.accessor_factory(path).info()
            except Exception as ex:
                raise IOError(f'Unable to parse {path}') from ex

        if fields.backlinks:
            for other in self.query(fields=FileInfoReq(path=True, links=True)):
                info.backlinks.extend(link for link in other.links
                                      if link.referent() == path)
            info.backlinks.sort(key=attrgetter('referrer', 'href'))

        return info
예제 #2
0
파일: base.py 프로젝트: dendronhq/notesdir
    def info(
        self, path: str,
        fields: FileInfoReqIsh = FileInfoReq.internal()) -> FileInfo:
        """Looks up the specified fields for the given file or folder.

        Additional fields might or might not be populated.

        May raise a :exc:`notesdir.accessors.base.ParseError` or IO-related exception, but otherwise will
        always return an instance. If no file or folder exists at the given path, or if the file type is unrecognized,
        it can still populate the ``path`` and ``backlinks`` attributes.
        """
        raise NotImplementedError()
예제 #3
0
 def query(self, query: FileQueryIsh = FileQuery(), fields: FileInfoReqIsh = FileInfoReq.internal())\
         -> Iterator[FileInfo]:
     fields = dataclasses.replace(FileInfoReq.parse(fields),
                                  tags=(fields.tags or query.include_tags
                                        or query.exclude_tags))
     query = FileQuery.parse(query)
     filtered = query.apply_filtering(
         self.info(e.dir_entry.path,
                   fields,
                   path_resolved=True,
                   skip_parse=e.skip_parse) for e in self._paths())
     yield from query.apply_sorting(filtered)
예제 #4
0
 def query(self, query: FileQueryIsh = FileQuery(), fields: FileInfoReqIsh = FileInfoReq.internal())\
         -> Iterator[FileInfo]:
     self._refresh_if_needed()
     query = FileQuery.parse(query)
     cursor = self.connection.cursor()
     cursor.execute('SELECT path FROM files WHERE existent = TRUE')
     # TODO: Obviously, this is super lazy and inefficient. We should do as much filtering and data loading in
     #       the query as we reasonably can.
     fields = dataclasses.replace(FileInfoReq.parse(fields),
                                  tags=(fields.tags or query.include_tags
                                        or query.exclude_tags))
     filtered = query.apply_filtering(
         self.info(path, fields, path_resolved=True) for (path, ) in cursor)
     yield from query.apply_sorting(filtered)
예제 #5
0
 def info(self,
          path: str,
          fields: FileInfoReqIsh = FileInfoReq.internal(),
          path_resolved=False) -> FileInfo:
     self._refresh_if_needed()
     if not path_resolved:
         path = os.path.abspath(path)
     fields = FileInfoReq.parse(fields)
     cursor = self.connection.cursor()
     cursor.execute('SELECT id, title, created FROM files WHERE path = ?',
                    (path, ))
     file_row = cursor.fetchone()
     info = FileInfo(path)
     if file_row:
         file_id = file_row[0]
         info.title = file_row[1]
         time_field = file_row[2]
         if time_field:
             if time_field.isnumeric():
                 info.created = datetime.utcfromtimestamp(
                     int(time_field) / 1000)
             else:
                 info.created = datetime.fromisoformat(time_field)
         if fields.tags:
             cursor.execute('SELECT tag FROM file_tags WHERE file_id = ?',
                            (file_id, ))
             info.tags = {r[0] for r in cursor}
         if fields.links:
             cursor.execute(
                 'SELECT href FROM file_links WHERE referrer_id = ?',
                 (file_id, ))
             info.links = [
                 LinkInfo(path, href)
                 for href in sorted(r[0] for r in cursor)
             ]
         if fields.backlinks:
             cursor.execute(
                 'SELECT referrers.path, file_links.href'
                 ' FROM files referrers'
                 '  INNER JOIN file_links ON referrers.id = file_links.referrer_id'
                 ' WHERE file_links.referent_id = ?', (file_id, ))
             info.backlinks = [
                 LinkInfo(referrer, href) for referrer, href in cursor
             ]
             info.backlinks.sort(key=attrgetter('referrer', 'href'))
     return info
예제 #6
0
파일: base.py 프로젝트: dendronhq/notesdir
 def query(self, query: FileQueryIsh = FileQuery(), fields: FileInfoReqIsh = FileInfoReq.internal())\
         -> Iterator[FileInfo]:
     """Returns the requested fields for all files matching the given query."""
     raise NotImplementedError()