Skip to main content


hyprmuse

Random quotes from musicians, literary authors, poets and public-domain books, for your hyprlock screen.

Name a subject, hyprmuse harvests them from a fitting source into a local library, and prints a random quote on demand. Everything is stored offline, so the lockscreen never waits on the network.

Sources

Source Domain Covers Licence
wikiquote quotations authors, philosophers, scientists, films, TV, proverbs — any language edition CC BY-SA
genius music song lyrics for any artist scraped, personal use
poetrydb poetry ~130 classic poets, full poems public domain
gutenberg prose passages from public-domain books public domain

Sources fall into two kinds. Sliceable items (lyrics, poems) are quoted as a random window of consecutive lines taken from within one stanza, so a slice never runs from a verse into its chorus. Atomic items (a Wikiquote quotation, a prose passage) are quoted whole and word-wrapped.

Every pick is checked against the box it has to fit (width, max_lines, max_chars). A window that overflows is shortened a line at a time, and an item that cannot fit at all is skipped in favour of another. Only when nothing in the library fits does the output get cut off.

Libraries harvested before stanza breaks were stored still work, but slice as one long stanza. Run hyprmuse update --all once to pick the breaks up.

Setup

Download the Linux binary from the latest release, which needs no Python, and check it:

curl -LO https://github.com/DavidSiegl/hyprmuse/releases/latest/download/hyprmuse-linux-x86_64
curl -LO https://github.com/DavidSiegl/hyprmuse/releases/latest/download/hyprmuse-linux-x86_64.sha256
sha256sum -c hyprmuse-linux-x86_64.sha256
install -D -m 755 hyprmuse-linux-x86_64 ~/.local/bin/hyprmuse

Or run it from a checkout with uv sync, then uv run hyprmuse in place of hyprmuse below.

Usage

# add subjects — omit --source to search every source and pick from a list
hyprmuse add "Element of Crime" --source genius
hyprmuse add "Ingeborg Bachmann" --source wikiquote --lang de
hyprmuse add "Emily Dickinson" --source poetrydb
hyprmuse add "Frankenstein" --source gutenberg

hyprmuse search "Nietzsche" --lang de   # look without harvesting
hyprmuse list                           # what's stored
hyprmuse update --all                   # re-harvest everything
hyprmuse remove "genius:342499"

hyprmuse quote                          # a random quote
hyprmuse quote --domain poetry --width 50
hyprmuse quote --max-lines 4 --max-chars 160  # fit a small label
hyprmuse quote --source wikiquote --note
hyprmuse quote --seed 42                # deterministic

--lang selects the Wikiquote language edition (de, en, fr, …). Harvesting is throttled and cached; add is the slow step, quote reads only local files.

Hyprlock integration

label {
    monitor =
    text = cmd[update:0] ~/.local/bin/hyprmuse quote --width 60
    color = rgba(200, 200, 200, 1.0)
    font_size = 20
    font_family = Noto Sans
    position = 0, 80
    halign = center
    valign = center
}

From a checkout, the command is /path/to/hyprmuse/.venv/bin/hyprmuse. quote.py is kept as a compatibility shim, so an existing config pointing at /path/to/hyprmuse/quote.py keeps working — only the directory name changed.

Configuration

Optional, at ~/.config/hyprmuse/config.toml:

[quote]
lines = 3           # lines taken from sliceable items
width = 60          # wrap width, 0 disables wrapping
max_lines = 6       # most lines after wrapping, 0 disables
max_chars = 0       # most characters after wrapping, 0 disables
min_line_chars = 2  # skip lines shorter than this ("-", "I") when slicing
weighting = "subject"  # "subject" = every subject equally likely
                       # "quote"   = every quote equally likely
avoid_repeats = 20  # don't repeat within the last N quotes

# per-subject overrides, keyed as shown by `hyprmuse list`
[subjects."genius:342499"]
weight = 2.0
enabled = true

weighting = "subject" is the default so a 162-song band does not drown out an author with nine quotes.

Storage

~/.local/share/hyprmuse/subjects/*.json   one file per subject
~/.local/share/hyprmuse/recent.json       recently shown, for repeat avoidance
~/.config/hyprmuse/config.toml            optional settings

Harvested text lives outside the repository, so scraped content stays out of git.

Development

uv run pytest               # the tests
scripts/gate origin/main    # the tests with coverage, then octoflow-ai's quality gate on
                            # the change since origin/main, as Jenkins runs it; writes quality.md

Opening a pull request hands it over: once Jenkins passes it, one that changes only the package's or the tests' Python, or Markdown, merges into main without a human. docs/agents/README.md has the exact rule and how to hold a pull request back.

A merge into main that raises version in pyproject.toml releases it: Jenkins builds the binary with packaging/build-binary.sh and publishes it as release v<version>. The Jenkins job hyprmuse-pypi (packaging/pypi/Jenkinsfile) then builds that release's tag on a trusted node and uploads the sdist and wheel to PyPI, and hyprmuse-aur (packaging/aur/Jenkinsfile) pushes the AUR's hyprmuse-bin to that release with packaging/aur/publish.sh. To change the AUR package itself between releases, edit packaging/aur/PKGBUILD, run packaging/aur/update.sh with the latest released version, raise pkgrel, and run update.sh again to refresh .SRCINFO. Once merged, the change reaches the AUR on the job's next run, after the next build of main or within a day.

License

MIT; see LICENSE. The release binary also bundles Python, the packages hyprmuse depends on, and the C libraries linked into them, each under its own license; each release carries their notices as hyprmuse-third-party-licenses.txt.

Metadata

Release files for hyprmuse 0.3.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for hyprmuse 0.3.2
File Size Uploaded Provenance Actions
hyprmuse-0.3.2.tar.gz 32.4 kB Without provenance Details for hyprmuse-0.3.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for hyprmuse 0.3.2
File Interpreter ABI Platform Actions
hyprmuse-0.3.2-py3-none-any.whl Python 3 none any Details for hyprmuse-0.3.2-py3-none-any.whl

Total release size: 58.5 kB

Release files / hyprmuse-0.3.2.tar.gz

Download URL hyprmuse-0.3.2.tar.gz
Size 32.4 kB
Tags Source
SHA-256 checksum
How to use checksums
0559df759d62a9acc0410e4b7a879096182fc2f575f5c18adda7be7b71bfafd0
BLAKE2b-256 checksum
How to use checksums
bae92af360e3eaf132e608ec4a6731570af3b7f7fa825d136fe1b480c08c541b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / hyprmuse-0.3.2-py3-none-any.whl

Download URL hyprmuse-0.3.2-py3-none-any.whl
Size 26.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c87067e354db187d4dc6470517d9e31cf009995981d02c54ed82f04cde03c390
BLAKE2b-256 checksum
How to use checksums
69c26ddec99f18d4306d41eaff80542243cf19f7fa2c4f4428e243f605311b7f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for hyprmuse 0.3.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page