Exemplo n.º 1
0
def add_link(filepath, url, name, tags):
    db = Database(filepath, create=True)

    if tags is None:
        Link.add(db, name=name, url=url)
        return 0

    link = Link(name=name, url=url)
    new_tags = []

    for t in tags:
        existing = Tag.get(db, name=t)

        if existing is not None:
            link.tags.append(existing)
            continue

        tag = Tag(name=t)
        link.tags.append(tag)
        new_tags.append(tag)

    Link.add(db, items=[link], commit=False)

    if len(new_tags) > 0:
        Tag.add(db, items=new_tags, commit=False)

    db.commit()
Exemplo n.º 2
0
def test_link_add_single():
    """Ensure that we can add a single link to the database."""

    db = Database(":memory:", create=True, verbose=True)

    Link.add(db, name="Github", url="https://www.github.com/")
    assert Link.get(db, 1) == Link(id=1, name="Github", url="https://www.github.com/")
Exemplo n.º 3
0
def test_link_search_by_tag():
    """Ensure that it is possible to search for a link based on tags."""

    db = Database(":memory:", create=True, verbose=True)
    session = db.session

    function = Tag(name="function")
    python = Tag(name="python")

    enumerate_ = Link(name="enumerate", url="https://docs.python.org/3/enumerate.html")
    enumerate_.tags.append(python)
    enumerate_.tags.append(function)

    malloc = Link(name="malloc", url="https://docs.c.org/c11/malloc.html")
    malloc.tags.append(function)

    github = Link(name="Github", url="https://github.com")

    for item in [python, function, enumerate_, malloc, github]:
        session.add(item)

    db.commit()

    links = Link.search(db, tags=["function"])
    assert {l.url for l in links} == {
        "https://docs.python.org/3/enumerate.html",
        "https://docs.c.org/c11/malloc.html",
    }

    # Ensure multiple tags are ANDed
    assert len(Link.search(db, tags=["function", "c"])) == 0
Exemplo n.º 4
0
        def open_link(event):
            cursor = self.selection.content.text
            idx = len(cursor)

            selected = self.ids.col.text[idx - 1]
            link_id = int(selected[1])

            Link.open(self.db, link_id)
Exemplo n.º 5
0
def test_link_add_default_visits():
    """Ensure that the visits field on a link is initialised to a sane value."""

    db = Database(":memory:", create=True, verbose=True)
    Link.add(db, name="Github", url="https://github.com/")

    link = Link.get(db, 1)
    assert link.visits == 0
Exemplo n.º 6
0
def test_link_search_basic():
    """Ensure that the simplest search just returns records in the db."""

    db = Database(":memory:", create=True, verbose=True)
    links = [Link(name=f"Link {i}", url=f"https://{i}") for i in range(20)]
    Link.add(db, items=links)

    results = Link.search(db)
    assert len(results) == 10
Exemplo n.º 7
0
def test_link_search_top():
    """Ensure that the number of search results can be set."""

    db = Database(":memory:", create=True, verbose=True)
    links = [Link(name=f"Link {i}", url=f"https://{i}") for i in range(20)]
    Link.add(db, items=links)

    results = Link.search(db, top=15)
    assert len(results) == 15
Exemplo n.º 8
0
def test_link_search_large_top():
    """Ensure that we can safely handle a page size larger than the number of
    results."""

    db = Database(":memory:", create=True, verbose=True)
    links = [Link(name=f"Link {i}", url=f"https://{i}") for i in range(20)]
    Link.add(db, items=links)

    results = Link.search(db, top=25)
    assert len(results) == 20
Exemplo n.º 9
0
def test_link_open():
    """Ensure that we can open a link in the database"""

    db = Database(":memory:", create=True, verbose=True)
    Link.add(db, name="Github", url="https://www.github.com")

    with mock.patch("llyfrau.data.webbrowser") as m_webbrowser:
        Link.open(db, 1)

    m_webbrowser.open.assert_called_with("https://www.github.com")
Exemplo n.º 10
0
def test_link_requires_url():
    """Ensure that a link requires a url before it can be added to the database"""

    db = Database(":memory:", create=True, verbose=True)
    link = Link(name="Google")

    with py.test.raises(IntegrityError) as err:
        Link.add(db, items=[link])

    assert "links.url" in str(err.value)
    assert "NOT NULL" in str(err.value)
Exemplo n.º 11
0
def test_link_requires_name():
    """Ensure that a link requires a name before it can be added to the database"""

    db = Database(":memory:", create=True, verbose=True)
    link = Link(url="https://www.google.com")

    with py.test.raises(IntegrityError) as err:
        Link.add(db, items=[link])

    assert "links.name" in str(err.value)
    assert "NOT NULL" in str(err.value)
Exemplo n.º 12
0
def test_link_open_updates_stats():
    """Ensure that when we visit a link, its stats are updated."""

    db = Database(":memory:", create=True, verbose=True)
    Link.add(db, name="Github", url="https://www.github.com", visits=1)

    with mock.patch("llyfrau.data.webbrowser") as m_webbrowser:
        Link.open(db, 1)

    m_webbrowser.open.assert_called_with("https://www.github.com")

    link = Link.get(db, 1)
    assert link.visits == 2
Exemplo n.º 13
0
def test_add_link(workdir):
    """Ensure that we can add a link to the database"""

    filepath = pathlib.Path(workdir.name, "links.db")
    add_link(str(filepath),
             url="https://www.github.com",
             name="Github",
             tags=None)

    db = Database(str(filepath), create=False)
    assert Link.get(db, 1) == Link(id=1,
                                   name="Github",
                                   url="https://www.github.com")
Exemplo n.º 14
0
def test_link_open_with_prefix():
    """Ensure that we can open a link that has a prefix on its source"""

    db = Database(":memory:", create=True, verbose=True)

    Source.add(
        db,
        name="Numpy",
        prefix="https://docs.scipy.org/doc/numpy/",
        uri="sphinx://https://docs.scipy.org/doc/numpy/",
    )
    Link.add(db, name="Reference Guide", url="reference/", source_id=1)

    with mock.patch("llyfrau.data.webbrowser") as m_webbrowser:
        Link.open(db, 1)

    m_webbrowser.open.assert_called_with("https://docs.scipy.org/doc/numpy/reference/")
Exemplo n.º 15
0
def test_link_add_many_dicts():
    """Ensure that we can add many links to the database using a dictionary
    representation."""

    db = Database(":memory:", create=True, verbose=True)

    links = [
        {"name": "Github", "url": "https://www.github.com/"},
        {"name": "Google", "url": "https://google.com"},
        {"name": "Python", "url": "https://python.org"},
    ]

    Link.add(db, items=links)

    links[0]["id"] = 1
    links[1]["id"] = 2
    links[2]["id"] = 3

    assert Link.search(db) == [Link(**args) for args in links]
Exemplo n.º 16
0
def test_link_source_reference():
    """Ensure that a link can reference to source it was added by"""

    db = Database(":memory:", create=True, verbose=True)
    Source.add(
        db,
        name="Numpy",
        prefix="https://docs.scipy.org/doc/numpy/",
        uri="sphinx://https://docs.scipy.org/doc/numpy/",
    )

    Link.add(db, name="Reference Guide", url="reference/", source_id=1)

    link = Link.get(db, 1)
    assert link.source_id == 1

    source = Source.get(db, 1)
    assert source.links == [link]
    assert link.source == source
Exemplo n.º 17
0
def test_tag_link():
    """Ensure that it is possible to associate a tag with a link."""

    db = Database(":memory:", create=True, verbose=True)
    session = db.session

    tag = Tag(name="search-engine")
    link = Link(name="Google", url="https://www.google.com/")

    link.tags.append(tag)

    session.add(tag)
    session.add(link)
    db.commit()

    tag.id = 1
    link = Link.get(db, 1)

    assert link.tags[0] == tag
    assert tag.links[0] == link
Exemplo n.º 18
0
def test_add_link_with_existing_tags(workdir):
    """Ensure that we can add a link with tags that already exist in the database"""

    filepath = pathlib.Path(workdir.name, "links.db")
    add_link(
        str(filepath),
        url="https://docs.python.org/3/argparse.html",
        name="Argparse",
        tags=["python", "docs"],
    )

    add_link(
        str(filepath),
        url="https://docs.python.org/3/optparse.html",
        name="Optparse",
        tags=["python", "docs"],
    )

    db = Database(str(filepath), create=False)

    link1 = Link.search(db, name="Argparse")[0]
    link2 = Link.search(db, name="Optparse")[0]
    assert set(link1.tags) == set(link2.tags)
Exemplo n.º 19
0
def test_sphinx_import(workdir):
    """Ensure that the sphinx importer imports links correctly"""

    filepath = str(pathlib.Path(workdir.name, "sphinx.db"))

    inv = soi.Inventory()
    inv.project = "Python"
    inv.version = "1.0"
    inv.objects.append(
        soi.DataObjStr(
            name="print",
            domain="py",
            priority="1",
            role="function",
            uri="builtins.html#$",
            dispname="-",
        ))
    inv.objects.append(
        soi.DataObjStr(
            name="enumeration",
            domain="py",
            priority="1",
            role="label",
            uri="concepts.html#$",
            dispname="Enumeration",
        ))

    with mock.patch("llyfrau.importers.soi.Inventory",
                    return_value=inv) as m_inv:
        sphinx(filepath, "https://docs.python.org/")

    m_inv.assert_called_with(url="https://docs.python.org/objects.inv")

    db = Database(filepath)

    source = Source.search(db, name="Python v1.0")[0]
    assert source.name == "Python v1.0 Documentation"
    assert source.prefix == "https://docs.python.org/"

    links = Link.search(db, source=source)

    assert links[0].name == "print"
    assert links[0].url == "builtins.html#print"
    assert {t.name for t in links[0].tags} == {"sphinx", "py", "function"}

    assert links[1].name == "Enumeration"
    assert links[1].url == "concepts.html#enumeration"
    assert {t.name for t in links[1].tags} == {"sphinx", "py", "label"}
Exemplo n.º 20
0
def test_link_search_by_name():
    """Ensure that we can filter search results by name and the search is case
    insensitive."""

    db = Database(":memory:", create=True, verbose=True)

    links = [
        Link(name="link 1", url="https://1"),
        Link(name="LiNk 2", url="https://2"),
        Link(name="BLINK3", url="https://3"),
        Link(name="item 4", url="https://4"),
        Link(name="9linkz", url="https://5"),
    ]

    Link.add(db, items=links)
    results = Link.search(db, name="link")

    assert len(results) == 4
    assert all(["link" in l.name.lower() for l in results])
Exemplo n.º 21
0
def test_link_search_by_name_returns_nothing():
    """Ensure that if the name matches nothing then nothing is returned."""

    db = Database(":memory:", create=True, verbose=True)

    links = [
        Link(name="link 1", url="https://1"),
        Link(name="LiNk 2", url="https://2"),
        Link(name="LINK3", url="https://3"),
        Link(name="item 4", url="https://4"),
    ]

    Link.add(db, items=links)
    results = Link.search(db, name="kiln")

    assert len(results) == 0
Exemplo n.º 22
0
def test_add_link_with_new_tags(workdir):
    """Ensure that we can add a link with tags that don't exist in te database"""

    filepath = pathlib.Path(workdir.name, "links.db")
    add_link(
        str(filepath),
        url="https://www.google.com",
        name="Google",
        tags=["search", "google"],
    )

    db = Database(str(filepath), create=False)

    link = Link.search(db, name="Google")[0]
    assert link.url == "https://www.google.com"

    tags = {Tag.get(db, name="search"), Tag.get(db, name="google")}
    assert set(link.tags) == tags
Exemplo n.º 23
0
def test_link_search_sort_by_visits():
    """Ensure that we can sort results by the number of times they have been visited."""

    db = Database(":memory:", create=True, verbose=True)

    links = [
        Link(name="link 1", url="https://1", visits=1),
        Link(name="LiNk 2", url="https://2", visits=0),
        Link(name="LINK3", url="https://3", visits=1),
        Link(name="item 4", url="https://4", visits=2),
    ]

    Link.add(db, items=links)
    results = Link.search(db, sort="visits")

    assert results[0].url == "https://4"
    assert results[1].url == "https://1"
    assert results[2].url == "https://3"
    assert results[3].url == "https://2"
Exemplo n.º 24
0
    def _do_search(self, inpt: Buffer = None):
        self.selection.content.text = [("", CURSOR)]
        self.ids.clear()
        self.names.clear()
        self.tags.clear()
        self.sources.clear()
        self.urls.clear()

        name = None
        tags = None

        if inpt is not None and len(inpt.text) > 0:
            terms = inpt.text.split(" ")

            tags = [t.replace("#", "") for t in terms if t.startswith("#")]
            name = " ".join(n for n in terms if not n.startswith("#"))

        links = Link.search(self.db,
                            name=name,
                            top=10,
                            tags=tags,
                            sort="visits")

        for idx, link in enumerate(links):

            newline = "\n" if idx < len(links) - 1 else ""

            self.ids.col.text.append(("", f"{link.id}{newline}"))
            self.names.col.text.append(("", f"{link.name}{newline}"))
            self.urls.col.text.append(("", f"{link.url_expanded}{newline}"))

            tags = ", ".join(f"#{t.name}" for t in link.tags)
            self.tags.col.text.append(("", f"{tags}{newline}"))

            source = "" if not link.source else link.source.name
            self.sources.col.text.append(("", f"{source}{newline}"))

        self.app.layout.focus(self.selection)
Exemplo n.º 25
0
def test_link_add_many_instances():
    """Ensure that we can add many links to the database using instances of the link
    class."""

    db = Database(":memory:", create=True, verbose=True)

    links = [
        Link(name="Github", url="https://www.github.com"),
        Link(name="Google", url="https://www.google.com"),
        Link(name="Python", url="https://www.python.org"),
    ]

    Link.add(db, items=links)

    links[0].id = 1
    links[1].id = 2
    links[2].id = 3

    assert Link.search(db) == links