wrolpi/wrolpi
lrnselfreliance adbcf944a5
playlists.yaml imports by diffing (#869)
* playlists.yaml imports by diffing

playlists.yaml declares two sections: playlists, keyed by name, and
their items, keyed by what each points to (a file's or Zim's
media-relative path and entry, or a URL) with position and title
compared.  A playlist has at most one item per reference, so a moved
item changes only its position and keeps its row; an unchanged import
writes nothing (every import deleted and re-created every item).

prepare skips items whose file or Zim is not indexed before the write
(their place is kept), drops a Tag that no longer exists once tags.yaml
is imported (the config is then saved), and, without deletes, keeps the
database's order and adds the file's other items after the item that
precedes them.

Moving a FileGroup in a playlist counts as a playlists.yaml change (ORM,
the bulk move, and a refresh that changes the primary file).

media_relative moves to wrolpi.config_import for both configs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Playlist items: keep database order without deletes; empty lists delete

Without a database version, every playlist with an added or changed item
keeps the database's order (the file's new items go after their
predecessor; only titles come from the file), and a row whose merged
position and title equal the database's is not written.  Before, only
playlists that gained an item were merged, so a file that only reordered
(or lacked an item the database had) gave two items one position.

A section can say it is present without rows (`ConfigSection.present`):
a listed playlist with an empty items list has its items removed; an
empty or missing playlists list still removes nothing.  An item that
cannot be read, or repeats another, is counted in import_skipped, so the
config is not saved over it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 09:42:26 -06:00
..
blobs zim: ship a default fallback Zim and honor the configured Zim directory 2026-07-20 19:09:57 -06:00
collections playlists.yaml imports by diffing (#869) 2026-10-25 09:42:26 -06:00
files playlists.yaml imports by diffing (#869) 2026-10-25 09:42:26 -06:00
scripts zim: address PR review — config race, YAML null, path traversal, pinned build 2026-07-20 19:10:09 -06:00
static/extensions Bump extension to v0.2.4 2026-06-01 19:23:39 -06:00
test tags.yaml imports by diffing (#868) 2026-10-24 20:16:39 -06:00
__init__.py Removing WROLPi admin functionality that is now in Controller. 2025-12-19 18:41:27 -07:00
api_utils.py API JSON: encode paths without a lookup per path (#810) 2026-10-09 19:45:43 -06:00
bookmarks.py Bookmarks: a nav menu of user links, stored in bookmarks.yaml (#729) 2026-09-26 13:11:36 -06:00
bookmarks_api.py Bookmarks: a nav menu of user links, stored in bookmarks.yaml (#729) 2026-09-26 13:11:36 -06:00
captions.py videos: address review — atomic caption write + strict YouTube host gate 2026-07-16 18:51:51 -06:00
cmd.py which() prefers the executable found in $PATH (#852) 2026-10-21 16:49:41 -06:00
common.py playlists.yaml imports by diffing (#869) 2026-10-25 09:42:26 -06:00
config_api.py Database configs carry a version the database keeps too (#866) 2026-10-24 14:58:18 -06:00
config_import.py playlists.yaml imports by diffing (#869) 2026-10-25 09:42:26 -06:00
config_schema.py Backup configs can be restored in the UI. User can choose between Merge or Overwrite, the UI displays a comparison. Configs are compared when user opens the restore modal, configs which won't cause changes are marked. 2026-03-10 20:30:46 -06:00
config_version.py Database configs carry a version the database keeps too (#866) 2026-10-24 14:58:18 -06:00
conftest.py Database configs carry a version the database keeps too (#866) 2026-10-24 14:58:18 -06:00
contexts.py Track how far the user is through a file, kept in recently_viewed.yaml (#787) 2026-10-08 16:15:25 -06:00
dates.py Postgres -> SQLite hard cutover: the database moves into the media directory. 2026-07-12 14:09:37 -06:00
db.py Tests fail when a request writes outside request.ctx.db.write() (#864) 2026-10-23 17:09:39 -06:00
db_bootstrap.py A library on the internal disk gets a database (#832) 2026-10-14 16:15:33 -06:00
db_query.py Database schema lists each column's foreign key (#822) 2026-10-11 19:38:39 -06:00
downloader.py tags.yaml imports by diffing (#868) 2026-10-24 20:16:39 -06:00
errors.py Read-only SQL query endpoint for advanced users (#820) 2026-10-11 17:34:00 -06:00
events.py Map search added to global search. Preview cards are displayed for all results in new Map tab. 2026-04-13 12:17:08 -06:00
flags.py A library on the internal disk gets a database (#832) 2026-10-14 16:15:33 -06:00
fts.py Upgrade to SQLAlchemy 2.0 (synchronous) (#803) 2026-10-09 15:08:40 -06:00
jobs.py api: run the perpetual loops in one Sanic-managed process (#718) 2026-09-23 07:53:53 -06:00
lang.py Including Country/Region codes in caption file names. 2024-10-16 18:56:31 -06:00
log_levels.py Reworking and unifying log levels. 2025-12-16 19:20:04 -07:00
logging_extra.py Not throwing error when checking for empty message. 2026-06-28 13:23:42 -06:00
media_path.py Upgrade to SQLAlchemy 2.0 (synchronous) (#803) 2026-10-09 15:08:40 -06:00
perpetual.py perpetual: clear in-progress flags after a crash, downloads only in the perpetual process, KillMode=mixed (#726) 2026-09-26 11:22:58 -06:00
roland@learningselfreliance.com.gpg Updating git signing gpg key. 2024-10-16 18:57:06 -06:00
root_api.py Download and tag requests wait for a concurrent writer (#848) 2026-10-21 16:48:16 -06:00
schema.py Add a Repos module that mirrors git repositories (#783) 2026-10-07 15:16:58 -06:00
schema_ddl.py Upgrade to SQLAlchemy 2.0 (synchronous) (#803) 2026-10-09 15:08:40 -06:00
scrape_downloader.py Scrape: fix multiple suffixes and relative link resolution (#801) 2026-10-08 20:05:59 -06:00
speedtest.py Speed Test calculator: ping, download, and upload against the API (#708) 2026-09-13 18:47:18 -06:00
switches.py Fix API stalls: non-blocking switch worker, threaded searches, indexed Videos page (#678) 2026-08-29 16:17:53 -06:00
tags.py playlists.yaml imports by diffing (#869) 2026-10-25 09:42:26 -06:00
test_media_path.py Add Docs module for searching and organizing PDFs and EPUBs 2026-03-20 14:17:06 -06:00
upgrade.py api: run the perpetual loops in one Sanic-managed process (#718) 2026-09-23 07:53:53 -06:00
vars.py Rename skip_circleci to skip_ci (#797) 2026-10-08 17:28:13 -06:00
version.py upgrade: report git branch via --show-current so a stale release tag can't break upgrades 2026-07-29 16:03:33 -06:00
version.txt Bump version to 0.30.1-beta 2026-10-15 19:57:29 -06:00