Skip to content
davcromPublic

About

A light-weight reference manager.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Latest commit

 

History

131 Commits

Folders and files

Repository files navigation

Biblo Baggins

A vibe-coded BibTeX reference manager built with Python and PyQt6.

Biblo Baggins is a desktop application for managing academic reference libraries. It stores entries as a flat CSV file (easy to version control, diff, and edit outside the app) and can import/export standard BibTeX format.

Status

In development. Tested on Linux (Ubuntu 22.04) with Python 3.10.

Contributions welcome.

Features

  • Load libraries from CSV; every change is written back to the CSV immediately, with "Save As" to choose a new file and BibTeX export kept manual
  • Add entries by pasting BibTeX or filling fields manually
  • Search and filter by title, author, abstract, year, type, tags, and project
  • Sort results by any column
  • Edit entries inline (single or bulk tag/project assignment)
  • Import references from Firefox tabs and bookmarks (citation data from CrossRef, abstracts from Europe PMC), rank them by similarity to your library or a probe sentence, and save the list to resume triage in a later session; lookups are also scriptable from Python
  • Rename PDFs to match library entries
  • Detect and resolve duplicate keys
  • Find & Fix Entries: scan chosen fields for empty or malformed values (prefixed DOIs, and others author lists) and repair them from CrossRef (abstracts from Europe PMC), with a preview and its own git commit
  • Semantic map of your library using SPECTER embeddings and UMAP (optional)

Installation

git clone https://github.com/davcrom/biblobag.git
cd biblobag
python -m venv .venv
source .venv/bin/activate
pip install -e .

For embedding/semantic map features:

pip install -e ".[embeddings]"

Usage

biblobag

Or equivalently:

python -m biblobag

First launch

Click New in the Library group to create an empty library, then start adding entries.

Configuration

Copy the template and set your default library path:

cp config.template.json config.json

Edit config.json:

{
    "default_library_path": "/path/to/your/library.csv"
}

The app will load this library automatically on startup.

Optionally, set "crossref_mailto" to your email address. It is sent to CrossRef (and only CrossRef) with each lookup, which moves the import into CrossRef's "polite" pool: 10 requests per second and 3 at once instead of 5 and 1, and CrossRef contacts you rather than blocking you if something goes wrong. config.json is ignored by git, so the address stays on your machine; leave it empty to send none.

Adding entries

Two ways to add a reference:

  1. From BibTeX — paste a BibTeX entry, click "Parse". Edit any fields, then click "Add".
  2. Manual entry — type a key, fill in the fields directly, click "Add".

The form clears itself once the entry is added (or once "Save" succeeds on a loaded entry), ready for the next one. Buttons that cannot act on the current form are faded out: "Add" needs a key and no loaded entry; "Save" and "Remove" need an entry loaded from the table.

When you edit a field of an entry loaded from the table, the change is saved as soon as you leave that field (click elsewhere, press Tab, switch tabs). Changing the entry key still needs "Save".

Searching

Type in the search bar to filter by title, author, or abstract. Use the filter row for year range, entry type, tags, or project.

Click any column header to sort.

Editing

Check one or more entries in the table, then switch to the Edit tab. Single entries show all fields; multiple entries allow bulk tag/project assignment.

Checks stay put when you search, save or refresh: an entry a search hides is still checked when it shows again. It stays checked until you uncheck it, bulk-tag it or remove it; Export leaves checks alone, and renaming a checked entry's key keeps it checked. "Select None" clears every check, hidden entries included; "Select All" adds the entries currently shown. Bulk tagging, "Batch Remove" and Export act on every checked entry, shown or not. Loading or creating a library clears all checks.

Importing from Firefox

Click Firefox on the Import tab to fetch citation data for papers open or bookmarked in your browser. The dropdown lists your tab groups and bookmark folders under two headers; check any mix of them, then click Fetch. The importer extracts DOIs from publisher URLs (or, failing that, searches CrossRef by title) and looks each DOI up in the sources ticked under Import from:. CrossRef is always ticked and supplies the citation fields. CrossRef rarely has abstracts, so Europe PMC (ticked by default) fills in the abstract where it has one, mostly for biomedical papers and preprints. Abstracts make the embeddings behind Rank more informative than titles alone. The ticks reset each time the dialog opens.

Each row's Status column says how its lookup went:

Status Meaning
OK Citation fields found, plus an abstract if Europe PMC was ticked
OK, no abstract Citation fields found; Europe PMC was ticked but had no abstract (or was down)
No DOI found Neither the URL nor a title search gave a DOI; only the title is filled in
DOI not found in CrossRef CrossRef has no record for the DOI (often a DOI misread from the URL); only the title is filled in
Network error (ReadTimeout), Network error (ConnectionError), … CrossRef could not be reached (timeout, no connection) or returned a server error (HTTPError); select these rows and Fetch Again later. A Europe PMC failure only means OK, no abstract
Lookup failed (…) An unexpected error on this row; the traceback is printed to the terminal and the fetch carries on

Status is for information only: any row can be edited, embedded, ranked, removed or added, whatever its status. The Select: dropdown ticks None, All, or every row with a given status (each status is listed with its row count), so you can deal with incomplete rows as a group. Fetch Again looks up the ticked rows again with the sources ticked now, replacing each row in place; use it after an outage or after ticking Europe PMC. Edits to the Title, Author, Journal and Year cells are kept and used when the row is added.

Add Selected to Library treats a row as a duplicate when its DOI is already in the library (rows without a DOI never are); Skip duplicates and Apply to duplicates act on the library entry with that DOI. The import table shows no keys: each row's key is generated from the first author's surname and the year at the moment it is added, so it never clashes with the library. To change it afterwards, load the entry from the library table, edit its key and click "Save". With no author, the first word of the title (after a leading "a", "an" or "the") stands in for the surname, and Untitled when there is no title either.

Tab groups with the same name in different windows count as one and import together. Only folders with bookmarks directly inside them are listed, and a checked folder contributes those bookmarks only, not its subfolders'. A URL that appears in several checked sources is fetched once. If Firefox's session or bookmarks can't be read, a warning says which, and that header is marked "(unavailable)".

Triage can span several sessions. Save writes the list, with any embeddings computed so far, to an .npz file you name; Open… loads one back, replacing the list on screen. Embed computes embeddings for rows that lack them, so a later Rank only scores. Fetching into an open list adds new rows: bookmarks whose URL is already listed are not looked up again, and results whose DOI is already listed are dropped. Rows leave the list when Add Selected to Library adds them (or skips them as duplicates) and when Remove Selected removes them. After either, the file last opened or saved is rewritten automatically, so the next session starts from what is left. Fetch, Embed and Rank do not save; click Save to keep their results.

Find & Fix Entries

Find & Fix Entries on the Organize tab checks the fields you tick for empty or malformed values. Scan lists the entries with defects; tick the ones to repair and click Fix to look them up again (by DOI, else URL, else title) and preview the proposed changes before applying them in their own git commit. The same Import from: checkboxes as the Firefox importer choose the sources, so with Europe PMC ticked an empty abstract can be filled in. Fix all fields overwrites every field the lookup returns (except tags and project), not just the defective ones.

Python API

The lookups behind the import dialog need no GUI, so you can script them:

from biblobag.importutils import list_bookmark_folders, get_bookmarks, resolve_item

folder_id = list_bookmark_folders()[0]["id"]  # each folder is {"id", "path"}
rows = [resolve_item(item, sources=("crossref", "europepmc"))
        for item in get_bookmarks(folder_id)]  # each item is {"title", "url"}

Each result is a dict:

Key Value
title, url The bookmark's own title and URL
doi The DOI found, or None
method How the DOI was found: "url", "title_search", or None
fields Citation fields (author, title, journal, year, abstract, ...); only title when the lookup failed
error "No DOI found", "DOI not found in CrossRef", "Network error (<exception>)", or None
status One of the Status values above

get_tabs(group_name) returns the same {"title", "url"} items for a Firefox tab group (list_groups() names them). resolve_item waits delay seconds (default 0.1) after each request to stay polite to the APIs; requests themselves take about 0.5 s, so this keeps well under CrossRef's limit of 5 requests per second. Pass sources=("crossref",) to skip Europe PMC. Set importutils.CROSSREF_MAILTO = "you@example.org" to send CrossRef a contact email (see Configuration). To add results to a library, generate a key with Library.generate_citation_key(author, year, title) and call Library.add_entry(key, fields).

Running tests

pip install pytest
pytest tests/

Project structure

biblobag/
  library.py      — Backend: parsing, storage, search, file I/O
  gui.py          — Frontend: PyQt6 interface
  embeddings.py   — SPECTER embeddings and UMAP (optional)
  importutils.py  — Firefox tab/bookmark reading, DOI extraction, metadata lookup (CrossRef, Europe PMC)
  __main__.py     — Application entry point
config.json       — User settings (not tracked, copy from template)
config.template.json — Config template
tests/            — Test suite
specs/            — Feature specifications

About

A light-weight reference manager.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages