mirror of
https://github.com/lrnselfreliance/wrolpi.git
synced 2026-10-26 19:01:39 -04:00
Create your own off-grid library
https://wrolpi.org
Four things, three cosmetic and one a real legibility bug. * Tags were square chips. They now have a pointed left edge and an eyelet, like a tag tied to a garment -- the shape Semantic gave them, and the reason a tag reads as a tag rather than as a small button. The point is a square rotated behind the left edge, sized so its diagonal equals the body height and its two edges meet the body at the corners. Only where something is actually a tag. `Label` carries the count badges in the Tags table too -- file, zim, channel and domain counts -- and a point on a number reads as an arrow, so the shape is behind a `tag` prop and `NameToTagLabel` opts in. * They were smaller than what they replaced: 11.5px text with 3px of padding, against Semantic's 12px and ~7px. Now 12.5px and 5px, which also keeps them a reasonable thing to tap. * Wrapped rows of tags sat on the row above, so they carry a bottom margin, plus a left margin for the point to occupy. * The text colour was unreadable in night and wrong in amber. Tags.js calculates black-or-light against the colour the user chose for each tag, and wrote the answer to `color` inline -- a declaration no stylesheet rule can outrank. Night turns a tag into an outline over a near-black page, so a near-white tag kept the black text calculated for its fill and was left legible only by its border: 1.1:1, measured. Amber replaces every fill with its own bright orange and was painting `#dddddd` on `#ff9500`, about 1.9:1, and a neutral grey in a theme whose whole point is that no other hue reaches the eye. The fix is to stop hard-coding `color` so the theme can decide: the calculated colour goes into `--label-text`, and night and amber override it alongside the fill they already override. There is no second contrast function to write, which is what this looked like it needed -- once a theme has discarded the user's colour there is nothing left to calculate against, and the answer is just the theme's own token. `.wrolpi-label-white` and `-black` moved to the same variable. Setting `color` there outranked the base rule, so amber was painting `--white` on `--text`: light orange on orange. `contrastingColor` was also picking the worse of its two options. It compared a brightness figure against a threshold, and the figure weighted the gamma-encoded bytes without linearising them, so Semantic's blue `#2185d0` got light text at 2.9:1 where dark text gives 5.3:1. Every mid-tone blue, teal and purple a user might pick sat in that band. It now measures the WCAG contrast ratio of both candidates and returns the better one, which needs no threshold at all. Tests ----- `Tags.test.js` is new, and covers the chip nothing covered: every other spec takes `NameToTagLabel` from `tagsContextFixture`, which stubs it as a function returning the name. That is how a tag could be unreadable without a single test noticing. Two of these were verified red against the inline `color`. `cy.contrastRatio()` measures text against the surface *actually* behind it, walking up to the first ancestor that paints something -- a transparent tag has no background of its own, so a naive check reads rgba(0,0,0,0) and concludes anything is legible. Twelve cases, three tag colours across four themes, at WCAG AA. Plus a test asserting the old inline-`color` version still measures below 1.5:1, so the check is provably able to fail. The gallery had label swatches in theme colours and no user-coloured tag, which is why none of this was visible in it. It has eleven now, spanning the range where the black-or-light decision flips. |
||
|---|---|---|
| .circleci | ||
| .github | ||
| .run | ||
| alembic | ||
| app | ||
| controller | ||
| debian-live-config | ||
| docker | ||
| etc | ||
| modules | ||
| pi-gen | ||
| release | ||
| scripts | ||
| test | ||
| wrolpi | ||
| .coveragerc | ||
| .dockerignore | ||
| .gitignore | ||
| .gitmodules | ||
| .gitpod.yml | ||
| .mcp.json.example | ||
| alembic.ini | ||
| conftest.py | ||
| demo_link.jpg | ||
| docker-compose.yml | ||
| help.sh | ||
| icon.ico | ||
| icon.png | ||
| INSTALL.md | ||
| install.sh | ||
| join_discord.png | ||
| LICENSE | ||
| main.py | ||
| pytest.ini | ||
| README.md | ||
| repair.sh | ||
| requirements.txt | ||
| test_all.sh | ||
| UPGRADE.md | ||
| upgrade.sh | ||
WROLPi
Create your own off-grid library.
WROLPi is a self-contained collection of software to help you survive the world Without Rule of Law.
WROLPi is intended to be run on a Raspberry Pi with an optional external drive attached. It serves up it's own Wi-Fi network so that any user with a laptop/tablet/phone can connect and use the library created by the maintainer.
Table of Contents
Features
- Videos
- Web Archives
- Maps
- Wikipedia
- File search
- eBooks (EPUB / PDFs)
- Wi-Fi Hotspot
- Universal search
- Food Inventory management
- One-Time pad generator, encrypter/decrypter
- Synchronizer/duplicator
- Food storage calculator
Module features matrix
| Module | View | Search | Download | Project |
|---|---|---|---|---|
| Videos | yes | yes | yes | yt-dlp |
| Web Archives | yes | yes | yes | Singlefile |
| Wikipedia | yes | yes | yes | Kiwix |
| eBooks | yes | yes | planned | EPUB/PDF |
| Map | yes | yes | yes | Protomaps |
| Podcasts/Audio | yes | planned | planned |
Demo
Download
Images are available at wrolpi.org
Try WROLPi!
You can try out WROLPi by running the docker containers.
- Install docker-ce and docker-compose
- Copy the latest WROLPi code.
git clone https://github.com/lrnselfreliance/wrolpi.git
- Change directory into the code base.
cd wrolpi
- Initialize git submodules
git submodule update --init
- Build the containers.
docker-compose build --parallel
- Create volumes.
docker volume create --name=openstreetmap-datadocker volume create --name=openstreetmap-rendered-tiles
- Initialize the database (SQLite in the media directory).
docker-compose run --rm api db upgrade
- Start the docker containers.
docker-compose up
- Browse to WROLPi.
More Docker documentation is available in docker/README.md
Install WROLPi
Full installation instructions are in INSTALL.md. Pick the option that matches your hardware:
- WROLPi Portable (Live USB) — boot a complete WROLPi from a USB stick on any x86 PC or laptop. Nothing is installed to the computer; the first boot creates a persistence partition on the USB so your library, database, and configuration survive reboots.
- Debian 12 — install WROLPi onto an x86 PC or laptop.
- Raspberry Pi — install WROLPi onto a Raspberry Pi with an external drive.
- Docker — run the WROLPi containers on an existing Linux host.
Charter
Guiding Principals
- Storage is cheaper than power.
- Two is one, one is none.
- Run silently.
- Primary, secondary, tertiary.
- Secure as a bookshelf in your home.
Physical properties
- A WROLPi instance should be capable of running with a minimal of hardware:
- Raspberry Pi
- SD card
- External USB hard drive
- Power supply and cables
- Wi-Fi USER device such as a phone, tablet, or laptop.
- A WROLPi instance should consume a minimal amount of electricity during WROL event. It is expected power will be scarce when WROLPi is needed most.
User expectations
- A WROLPi instance should be run and maintained by a person (MAINTAINER) with a moderate amount of Linux and Raspberry Pi experience. It is expected that they should be able to do this using only the documentation on their WROLPi.
Software properties and capabilities
- A WROLPi instance should be able to "factory-reset" itself without any outside services.
- WROLPi should function completely without any internet services.
- A user should have easy access to their data if WROLPi fails:
- For example, a user can watch their videos by navigating a short and intuitive directory structure and opening the video in their preferred video player.
- WROLPi should be self-documented. The UI should contain a tutorial for USERS as well as the MAINTAINER.
- If the UI isn't functional, the code should be documented such that a user can restore functionality.
- WROLPi should favor pre-processing, rather than processing during a WROL event. Such as re-encoding a video, or processing captions. This is to ensure that when a user adds content during non-WROL time, the processing for optimum performance is already done for a WROL event.
Join!
