コード例 #1
0
def test_info_and_referrers(fs):
    doc = """---
title: A Note
created: 2012-01-02 03:04:05
...
I link to [two](two.md) and [three](../otherdir/three.md#heading) and have #two #tags."""
    path1 = '/notes/dir/one.md'
    path2 = '/notes/dir/two.md'
    path3 = '/notes/otherdir/three.md'
    fs.create_file(path1, contents=doc)
    fs.create_file(path2, contents='---\ntitle: Note 2\n...\n')
    repo = config().instantiate()
    assert repo.info(path1, FileInfoReq.full()) == FileInfo(
        path1,
        title='A Note',
        created=datetime(2012, 1, 2, 3, 4, 5),
        tags={'tags', 'two'},
        links=[
            LinkInfo(path1, h)
            for h in ['../otherdir/three.md#heading', 'two.md']
        ])
    assert repo.info(path2, FileInfoReq.full()) == FileInfo(
        path2, title='Note 2', backlinks=[LinkInfo(path1, 'two.md')])
    assert repo.info(path3, FileInfoReq.full()) == FileInfo(
        path3, backlinks=[LinkInfo(path1, '../otherdir/three.md#heading')])
コード例 #2
0
def test_change(fs):
    fs.cwd = '/notes'
    path1 = '/notes/one.md'
    path2 = '/notes/two.md'
    path3 = '/notes/moved.md'
    fs.create_file(path1, contents='[1](old)')
    fs.create_file(path2, contents='[2](foo)')
    edits = [SetTitleCmd(path1, 'New Title'),
             ReplaceHrefCmd(path1, 'old', 'new'),
             MoveCmd(path1, path3),
             ReplaceHrefCmd(path2, 'foo', 'bar')]
    repo = config().instantiate()
    repo.change(edits)
    assert not Path(path1).exists()
    assert Path(path3).read_text() == '---\ntitle: New Title\n...\n[1](new)'
    assert Path(path2).read_text() == '[2](bar)'
    assert repo.info(path1, FileInfoReq.full()) == FileInfo(path1)
    assert repo.info(path3, FileInfoReq.full()) == FileInfo(path3, title='New Title', links=[LinkInfo(path3, 'new')])
    assert repo.info(path2, FileInfoReq.full()) == FileInfo(path2, links=[LinkInfo(path2, 'bar')])
    assert repo.info('old', FileInfoReq.full()) == FileInfo('/notes/old')
    assert repo.info('foo', FileInfoReq.full()) == FileInfo('/notes/foo')
    assert repo.info('new', FileInfoReq.full()) == FileInfo('/notes/new', backlinks=[LinkInfo(path3, 'new')])
    assert repo.info('bar', FileInfoReq.full()) == FileInfo('/notes/bar', backlinks=[LinkInfo(path2, 'bar')])
    # regression test for bug where invalidate removed entries for files that were referred to
    # only by files that had not been changed
    repo.invalidate()
    assert repo.info('new', FileInfoReq.full()) == FileInfo('/notes/new', backlinks=[LinkInfo(path3, 'new')])
    assert repo.info('bar', FileInfoReq.full()) == FileInfo('/notes/bar', backlinks=[LinkInfo(path2, 'bar')])
コード例 #3
0
ファイル: test_markdown.py プロジェクト: dendronhq/notesdir
def test_ignore_fenced_code_blocks(fs):
    doc = """#tag1 [link](link1.md)
```foo
#tag2 #tag3
text [link](link1.md)
```
  #tag3 [link](link2.md)

   ```
   [link](link3.md)
   ```"""
    path = '/fakenotes/text.md'
    fs.create_file(path, contents=doc)
    acc = MarkdownAccessor(path)
    info = acc.info()
    assert info.tags == {'tag1', 'tag3'}
    assert info.links == [
        LinkInfo(path, 'link1.md'),
        LinkInfo(path, 'link2.md')
    ]
    acc.edit(ReplaceHrefCmd(path, 'link1.md', 'CHANGED1'))
    acc.edit(ReplaceHrefCmd(path, 'link2.md', 'CHANGED2'))
    acc.edit(ReplaceHrefCmd(path, 'link3.md', 'CHANGED3'))
    acc.edit(DelTagCmd(path, 'tag3'))
    acc.edit(DelTagCmd(path, 'tag2'))
    acc.save()
    assert Path(path).read_text() == """#tag1 [link](CHANGED1)
コード例 #4
0
def test_duplicate_links(fs):
    doc = """I link to [two](two.md) [two](two.md) times."""
    path1 = '/notes/one.md'
    path2 = '/notes/two.md'
    fs.create_file(path1, contents=doc)
    repo = config().instantiate()
    assert repo.info(path1).links == [LinkInfo(path1, 'two.md'), LinkInfo(path1, 'two.md')]
    assert repo.info(path2, 'backlinks').backlinks == [LinkInfo(path1, 'two.md'), LinkInfo(path1, 'two.md')]
コード例 #5
0
def test_ignore(fs):
    path1 = '/notes/one.md'
    path2 = '/notes/.two.md'
    fs.create_file(path1, contents='I link to [two](.two.md)')
    fs.create_file(path2, contents='I link to [one](one.md)')
    repo = DirectRepoConf(root_paths={'/notes'}).instantiate()
    assert list(repo.query()) == [repo.info(path1)]
    assert not repo.info(path1, FileInfoReq.full()).backlinks
    assert repo.info(path2, FileInfoReq.full()).backlinks == [LinkInfo(path1, '.two.md')]
    repo.conf.ignore = lambda _1, _2: False
    assert list(repo.query()) == [repo.info(path1), repo.info(path2)]
    assert repo.info(path1, FileInfoReq.full()).backlinks == [LinkInfo(path2, 'one.md')]
    assert repo.info(path2, FileInfoReq.full()).backlinks == [LinkInfo(path1, '.two.md')]
コード例 #6
0
def test_ignore(fs):
    path1 = '/notes/one.md'
    path2 = '/notes/.two.md'
    fs.create_file(path1, contents='I link to [two](.two.md)')
    fs.create_file(path2, contents='I link to [one](one.md)')
    with config().instantiate() as repo:
        assert list(repo.query()) == [repo.info(path1)]
        assert not repo.info(path1, FileInfoReq.full()).backlinks
        assert repo.info(path2, FileInfoReq.full()).backlinks == [LinkInfo(path1, '.two.md')]
    conf = config()
    conf.ignore = lambda _1, _2: False
    with conf.instantiate() as repo:
        assert list(repo.query()) == [repo.info(path1), repo.info(path2)]
        assert repo.info(path1, FileInfoReq.full()).backlinks == [LinkInfo(path2, 'one.md')]
        assert repo.info(path2, FileInfoReq.full()).backlinks == [LinkInfo(path1, '.two.md')]
コード例 #7
0
ファイル: markdown.py プロジェクト: dendronhq/notesdir
 def _info(self, info: FileInfo):
     info.title = self.meta.get('title')
     info.created = self.meta.get('created')
     info.tags = {k.lower()
                  for k in self.meta.get('keywords', [])
                  }.union(self._hashtags)
     info.links = [LinkInfo(self.path, r.href) for r in sorted(self.hrefs)]
コード例 #8
0
ファイル: test_html.py プロジェクト: dendronhq/notesdir
def test_info(fs):
    doc = """<html>
    <head>
        <title>I Am A Strange Knot</title>
        <meta name="keywords" content="mind, Philosophy, cOnsciOusNess"/>
        <meta name="created" content="2019-10-03 23:31:14 -0800"/>
    </head>
    <body>
        No #extra tags in the body for now! And <a href="#nope">this will never be a tag.</a>
        Here's a <a href="../Another%20Note.md">link to another note</a>, and here's
        an image: <img src="me.html.resources/A%20Picture.png" />
    </body>
</html>"""
    path = Path('/fakenotes/test.html')
    fs.create_file(path, contents=doc)
    info = HTMLAccessor(str(path)).info()
    assert info.path == str(path)
    assert info.title == 'I Am A Strange Knot'
    assert info.tags == {'mind', 'philosophy', 'consciousness'}
    assert info.created == datetime(2019, 10, 3, 23, 31, 14, 0,
                                    timezone(timedelta(hours=-8)))
    assert info.links == [
        LinkInfo(str(path), href) for href in sorted([
            '../Another%20Note.md', 'me.html.resources/A%20Picture.png',
            '#nope'
        ])
    ]
コード例 #9
0
ファイル: test_direct.py プロジェクト: brokensandals/notesdir
def test_backlinks(fs):
    fs.cwd = '/notes/foo'
    fs.create_file('/notes/foo/subject.md')
    fs.create_file('/notes/bar/baz/r1.md',
                   contents='[1](no) [2](../../foo/subject.md)')
    fs.create_file('/notes/bar/baz/no.md', contents='[3](../../foo/bogus')
    fs.create_file('/notes/r2.md',
                   contents='[4](foo/subject.md) [5](foo/bogus)')
    fs.create_file('/notes/foo/r3.md', contents='[6](subject.md)')
    repo = DirectRepoConf(root_paths={'/notes'}).instantiate()
    info = repo.info('subject.md', 'backlinks')
    assert info.backlinks == [
        LinkInfo('/notes/bar/baz/r1.md', '../../foo/subject.md'),
        LinkInfo('/notes/foo/r3.md', 'subject.md'),
        LinkInfo('/notes/r2.md', 'foo/subject.md'),
    ]
コード例 #10
0
 def _info(self, info: FileInfo):
     info.title = self._title()
     info.created = self._created()
     info.tags = self._tags()
     info.links = [
         LinkInfo(self.path, href) for href in sorted(self._link_els.keys())
     ]
コード例 #11
0
ファイル: test_markdown.py プロジェクト: dendronhq/notesdir
def test_info(fs):
    doc = """---
title: An Examination of the Navel
created: 2019-06-04 10:12:13-08:00
keywords:
  - TrulyProfound
...
#personal #book-draft
# Preface: Reasons for #journaling

As I have explained at length in [another note](../Another%20Note.md) and also
published about online (see [this article](http://example.com/blah) among many others), ...
"""
    path = '/fakenotes/test.md'
    fs.create_file(path, contents=doc)
    info = MarkdownAccessor(path).info()
    assert info.path == path
    assert info.links == [
        LinkInfo(path, r)
        for r in sorted(['../Another%20Note.md', 'http://example.com/blah'])
    ]
    assert info.tags == {
        'trulyprofound', 'personal', 'book-draft', 'journaling'
    }
    assert info.title == 'An Examination of the Navel'
    assert info.created == datetime(2019, 6, 4, 10, 12, 13, 0,
                                    timezone(timedelta(hours=-8)))
コード例 #12
0
ファイル: sqlite.py プロジェクト: dendronhq/notesdir
 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
コード例 #13
0
def test_invalidate(fs):
    repo = config().instantiate()
    path = '/notes/one.md'
    assert repo.info(path, FileInfoReq.full()) == FileInfo(path)
    fs.create_file(path, contents='#hello [link](foo.md)')
    assert repo.info(path, FileInfoReq.full()) == FileInfo(path)
    repo.invalidate()
    assert repo.info(path, FileInfoReq.full()) == FileInfo(
        path, tags={'hello'}, links=[LinkInfo(path, 'foo.md')])
    repo.invalidate()
    Path(path).write_text('#goodbye')
    repo.invalidate()
    assert repo.info(path, FileInfoReq.full()) == FileInfo(path,
                                                           tags={'goodbye'})
コード例 #14
0
def test_apply_sorting():
    data = [
        FileInfo('/a/one',
                 tags={'baz'},
                 backlinks=[LinkInfo(referrer='whatever', href='whatever')]),
        FileInfo('/b/two', title='Beta', created=datetime(2010, 1, 15)),
        FileInfo('/c/Three',
                 title='Gamma',
                 created=datetime(2012, 1, 9),
                 backlinks=[
                     LinkInfo(referrer='whatever', href='whatever'),
                     LinkInfo(referrer='whatever', href='whatever')
                 ]),
        FileInfo('/d/four',
                 title='delta',
                 created=datetime(2012, 1, 9),
                 tags={'foo', 'bar'})
    ]

    assert FileQuery.parse('sort:path').apply_sorting(data) == data
    assert FileQuery.parse('sort:-path').apply_sorting(data) == list(
        reversed(data))
    assert FileQuery.parse('sort:filename').apply_sorting(data) == [
        data[3], data[0], data[2], data[1]
    ]
    assert FileQuery(sort_by=[
        FileQuerySort(FileQuerySortField.FILENAME, ignore_case=False)
    ]).apply_sorting(data) == [data[2], data[3], data[0], data[1]]

    assert FileQuery.parse('sort:title').apply_sorting(data) == [
        data[1], data[3], data[2], data[0]
    ]
    assert FileQuery(
        sort_by=[FileQuerySort(FileQuerySortField.TITLE, ignore_case=False)
                 ]).apply_sorting(data) == [
                     data[1], data[2], data[3], data[0]
                 ]
    assert FileQuery(
        sort_by=[FileQuerySort(FileQuerySortField.TITLE, missing_first=True)
                 ]).apply_sorting(data) == [
                     data[0], data[1], data[3], data[2]
                 ]
    assert FileQuery(sort_by=[
        FileQuerySort(
            FileQuerySortField.TITLE, missing_first=True, reverse=True)
    ]).apply_sorting(data) == [data[2], data[3], data[1], data[0]]

    assert FileQuery.parse('sort:created').apply_sorting(data) == [
        data[1], data[2], data[3], data[0]
    ]
    assert FileQuery.parse('sort:-created').apply_sorting(data) == [
        data[0], data[2], data[3], data[1]
    ]
    assert FileQuery(sort_by=[
        FileQuerySort(FileQuerySortField.CREATED, missing_first=True)
    ]).apply_sorting(data) == [data[0], data[1], data[2], data[3]]

    assert FileQuery.parse('sort:-tags').apply_sorting(data) == [
        data[3], data[0], data[1], data[2]
    ]

    assert FileQuery.parse('sort:-backlinks').apply_sorting(data) == [
        data[2], data[0], data[1], data[3]
    ]

    assert FileQuery.parse('sort:created,title').apply_sorting(data) == [
        data[1], data[3], data[2], data[0]
    ]
    assert FileQuery.parse('sort:created,-title').apply_sorting(data) == [
        data[1], data[2], data[3], data[0]
    ]
コード例 #15
0
def test_referent_skips_invalid_urls():
    assert LinkInfo('foo', 'file://no[').referent() is None
コード例 #16
0
def test_referent_self():
    assert LinkInfo('/foo/bar', 'bar#baz').referent() == '/foo/bar'
    assert LinkInfo('/foo/bar', '#baz').referent() == '/foo/bar'
コード例 #17
0
def test_referent_handles_special_characters():
    assert LinkInfo('/foo', 'hi%20there%21').referent() == '/hi there!'
    assert LinkInfo('/foo', 'hi+there%21').referent() == '/hi there!'
コード例 #18
0
def test_referent_resolves_relative_to_referrer(fs):
    fs.cwd = '/meh'
    assert LinkInfo('/foo/bar',
                    'baz').referent() == os.path.realpath('../foo/baz')
コード例 #19
0
def test_referent_ignores_query_and_fragment():
    assert LinkInfo('/foo', 'bar#baz').referent() == '/bar'
    assert LinkInfo('/foo', 'bar?baz').referent() == '/bar'
コード例 #20
0
def test_referent_resolves_symlinks(fs):
    fs.cwd = '/cwd'
    fs.create_symlink('/cwd/bar', '/cwd/target')
    assert LinkInfo('foo', 'bar/baz').referent() == '/cwd/target/baz'
コード例 #21
0
def test_referent_matches_relative_paths():
    assert LinkInfo('/baz/foo', 'bar').referent() == '/baz/bar'
コード例 #22
0
def test_referent_matches_absolute_paths():
    assert LinkInfo('foo', '/bar').referent() == '/bar'
    assert LinkInfo('foo', 'file:///bar').referent() == '/bar'
    assert LinkInfo('foo', 'file://localhost/bar').referent() == '/bar'
コード例 #23
0
def test_referent_skips_non_local_hosts():
    assert LinkInfo('foo', 'file://example.com/bar').referent() is None
コード例 #24
0
def test_referent_skips_non_file_schemes():
    assert LinkInfo('foo', 'http:///bar').referent() is None
コード例 #25
0
def test_referrers_self(fs):
    fs.create_file('/notes/subject.md', contents='[1](subject.md)')
    repo = DirectRepoConf(root_paths={'/notes'}).instantiate()
    info = repo.info('/notes/subject.md', 'backlinks')
    assert info.backlinks == [LinkInfo('/notes/subject.md', 'subject.md')]