Hobbes OS/2 Archive - Changelog
================================
v1.03 (2026-03-24)
------------------
NEW: Meta Merge tool (Admin / Editor, /admin/meta-merge)
- Upload a .txt file to bulk-import metadata into existing archive
entries without re-uploading the files themselves.
- Parses two formats automatically:
hobbes.txt: dashed-separator blocks with DIR / FILE / DESC fields.
pmmail.txt: aligned key: value pairs (Archive Filename, Short
Description, Long Description, Proposed directory,
Your name, Program URL, Operating System/Version,
Additional requirements).
- Matches entries to archive files by normalising the DIR path to
slugified category segments and comparing against each file's
stored category_upload_path + original_name.
- Three-phase workflow: upload -> review report -> apply.
- Review page shows:
Matched entries — before/after diff table per field; individual
checkboxes to include or exclude each entry.
Unmatched entries — filename-only suggestions drawn from the
archive, manual file-ID input, or Skip.
Skipped summary — entries marked skip listed for reference.
- Merge mode options: fill blank/"Unknown" fields only (default), or
overwrite all existing values.
- Approved files are re-indexed in the search index after merge.
- Temporary sessions stored in data/merges/ and auto-expired at 2 h.
NEW: Bulk Delete tool (Admin only, /admin/bulk-delete)
- Select any category to list its files (approved and pending).
- Per-page selector: 25 / 50 / 100 / All.
Warning banner shown when "All" is chosen with > 250 files.
- "Select all on this page" checkbox.
- "Select ALL N files in this category (all pages)" checkbox
triggers server-side deletion of every file in the category
regardless of pagination, so nothing is missed.
- Listing shows filename, title, size, download count, date,
and approved/pending status.
- JavaScript confirmation dialog shows the deletion count before
committing; blocks submission when nothing is selected.
- Removes physical file from disk, metadata JSON from data/files/,
and all entries from the search index.
- Empty category upload directories are pruned after deletion.
NEW: Single-file delete from edit page (Admin only)
- Danger Zone section added at the bottom of /file/edit/{id}.
- Visible to admin role only; hidden from editors.
- Confirmation dialog includes the filename.
- Handled by POST /admin/file-delete/{id}; redirects to the file's
category browse page after deletion.
NEW: Download counter displayed in all views
- browse.php: "DLs" column added to the file listing table.
- file.php: "Downloads" row added to the file detail info table.
- search.php: "DLs" column added to search results table.
- Counter has been tracked since v1.01; this release makes it
visible to all users including unauthenticated OS/2 guests.
NEW: Approve All Web Uploads button (/pool)
- A green summary bar appears at the top of the pool when one or more
web-uploaded files are pending approval.
- "Approve All Web Uploads" button approves every pending web upload
in a single action (POST /pool/approve_all, CSRF-protected).
- FTP single files and FTP folder imports are intentionally excluded
as they require metadata to be filled in or imported first.
- Each approved file is immediately indexed in the search index.
- JavaScript confirmation dialog shows the count before committing.
CHANGED: Admin dashboard links updated
- "Meta Merge" button added to the Site Management panel.
- "Bulk Delete" button (styled red) added to the Site Management panel.
v1.02
-----
NEW: FTP folder batch import (Editor+, /pool)
- Drop an entire directory tree into data/pool/ via FTP.
- The pool listing now detects folders and presents a Batch Import
Folder button alongside individual file imports.
- Sub-folders are mapped to nested categories using
category_find_or_create(), which creates missing categories on
the fly (slugified, de-duplicated) without overwriting existing ones.
- Files receive titles derived from their filenames; required fields
default to "Unknown" and can be corrected post-import.
- Approve-immediately checkbox available for trusted bulk imports.
- The pool folder is recursively removed after a successful import.
- Reject & Delete Folder button purges the folder without importing.
NEW: "Hobbes OG" CSS preset (Admin > CSS)
- Fourth built-in color preset added.
- Deep navy blue palette inspired by the original hobbes.nmsu.edu
color scheme: dark blue panels, cream text, teal accents.
ADDED: category_find_or_create() (includes/functions.php)
- Looks up a category by name + parent in the live category list;
creates it with a unique slug if absent. Used by folder import.
ADDED: category_upload_path_from_cats() (includes/functions.php)
- Variant of category_upload_path() that accepts an explicit array
instead of the static-cached categories_load() result. Required
during batch import when the category list has been mutated but not
yet written to disk.
ADDED: rmdir_recursive() (includes/functions.php)
- Recursively removes a directory tree. Used to clean up pool folders
after import and rejected folder deletion.
ADDED: pool_folder_file_count(), pool_folder_files() (includes/storage.php)
- Helper functions for counting and listing files inside pool folders
during the batch import workflow.
FIXED: Pool route regex (index.php)
- Changed [a-z]+ to [a-z_]+ so that import_folder and reject_folder
action names are matched correctly.
v1.01 (initial release)
------------------------
Core archive system:
- Flat-file JSON storage; no database required.
- Atomic file writes via temp file + rename() (no flock()).
- Custom PHP session handler using the same atomic pattern.
Browsing and downloads:
- Category tree browser (/browse, /browse/{slug}).
- File detail page with full metadata display.
- Download streaming in 64 KB chunks with per-file download counter.
- Canonical URL scheme: /files/{cat/path}/{filename} and
/download/{cat/path}/{filename}.
- Legacy /file/{id} redirects (301) to canonical URL.
Search:
- Inverted keyword index (data/index/search.json).
- AND search with OR fallback; stop-word filter; minimum 3 characters.
- Index updated on approval and on metadata edit.
- Admin: Rebuild Search Index action.
User system:
- Four roles: guest, contributor, editor, admin.
- OS/2 User-Agent auto-detection for guest browse access.
- Invite-code registration (invite generates code, recipient redeems).
- Open registration toggle in site settings.
- Password hashing via bcrypt (PASSWORD_BCRYPT).
Uploads and approval:
- Web upload form for contributors (/upload).
- FTP pool import for single files (/pool).
- Optional .meta.json companion file to pre-fill pool import forms.
- Editor approval workflow: approve, reject, or edit before publishing.
- File stored using category slug path (uploads/{cat}/{subcat}/file).
File editing and organisation:
- Edit metadata for any approved file (/file/edit/{id}).
- Category change moves physical file on disk and updates stored_name.
- Legacy per-file id/ directory layout supported and cleaned up on move.
Admin tools:
- Site settings: name, tagline, open registration.
- CSS theme editor: 26 individually configurable colors.
- Three CSS presets: OS/2 Classic, Dark Mode, Green Terminal.
- Category manager: add, rename, nest, delete.
- User manager: list, change role, deactivate.
- Landing page and splash screen Markdown editors.