fix: harden classroom presentations
This commit is contained in:
+28
-20
@@ -52,6 +52,8 @@ hash.
|
||||
This is not a new renderer. LibreOffice does exactly the rendering
|
||||
Impress would have done live — it is the same engine — and poppler does
|
||||
what every PDF viewer does. The classroom's own code displays a PNG.
|
||||
Because playback is made from static page images, PowerPoint animations,
|
||||
video, audio and other interactive content are not supported.
|
||||
What it buys:
|
||||
|
||||
* **A teacher can never reach an editor**, because no editor ever runs
|
||||
@@ -74,14 +76,15 @@ interactive runs, so no UI integration package is needed.
|
||||
## Where things are
|
||||
|
||||
```
|
||||
~/Downloads/ the teacher's own download. NEVER touched.
|
||||
~/Downloads/ completed presentations move from here
|
||||
~/Downloads/Wonder Ink/ Wonder Ink's worksheets. NEVER touched.
|
||||
|
||||
~/.local/share/ekklesia-classroom/presentations/
|
||||
imported.json which downloads have been dealt with
|
||||
<id>/
|
||||
presentation.json title, pages, thumbnail slide, timers
|
||||
Session 7 - Romans.pptx the managed copy, original name kept
|
||||
original/
|
||||
Session 7 - Romans.pptx the one original, name kept
|
||||
slides.pdf what everything is rendered from
|
||||
pages/page-001.png ... one per slide, 1920px wide
|
||||
thumbnail.png the card picture, from the chosen slide
|
||||
@@ -108,20 +111,22 @@ A file is imported when **all** of these hold:
|
||||
* its fingerprint — path, size, modification time — is not already in
|
||||
`imported.json`.
|
||||
|
||||
Two downloads of the same name are two presentations. The second gets
|
||||
`(2)` after its title; neither overwrites the other.
|
||||
Two downloads of the same name are two presentations in separate id
|
||||
directories. The second gets `(2)` after its title; neither overwrites the
|
||||
other.
|
||||
|
||||
**Crash safety.** The metadata is written saying `importing` *before* any
|
||||
work, and the fingerprint is recorded at the same moment so a file that
|
||||
crashes the converter cannot be retried forever. On startup the importer
|
||||
sweeps every directory still saying `importing`, deletes it and forgets
|
||||
its fingerprint, so an import interrupted by a reboot simply happens
|
||||
again. A presentation becomes visible to a teacher only once every file
|
||||
**Move and crash safety.** On one filesystem the completed download is
|
||||
renamed atomically. Across filesystems it is copied to a hidden temporary,
|
||||
flushed, published atomically, and only then removed from Downloads. The
|
||||
metadata and transaction fingerprint are written first. On startup, an
|
||||
interruption before the source was removed discards the partial destination
|
||||
and retries; an interruption after the move resumes conversion from the
|
||||
managed original. A presentation becomes ready only once every derived file
|
||||
it needs is on disk.
|
||||
|
||||
A file that cannot be converted gets a card saying so, offering only
|
||||
**Remove**. The teacher's download is untouched, which is what the card
|
||||
says.
|
||||
**Remove**. Its managed original remains recoverable even when PDF or page
|
||||
generation fails.
|
||||
|
||||
## The three things kept apart
|
||||
|
||||
@@ -129,7 +134,7 @@ This is the part most worth not breaking.
|
||||
|
||||
| | Changed by | Never changed by |
|
||||
| --- | --- | --- |
|
||||
| **Library thumbnail** | *Use this slide as the picture* in Quick Look | presenting, importing |
|
||||
| **Library cover** | *Use as cover* in Quick Look | presenting, importing |
|
||||
| **Starting slide** | nothing — always slide 1 | choosing a thumbnail |
|
||||
| **Retention** | a slide actually reaching the screen | Quick Look, opening the library, choosing a thumbnail, preview generation, a viewer that failed to start |
|
||||
|
||||
@@ -159,8 +164,9 @@ The cleanup runs hourly in the importer and:
|
||||
directory so a crash cannot make a presentation permanently
|
||||
un-removable;
|
||||
* only ever removes a directory under the library root;
|
||||
* never touches `~/Downloads`, and therefore never a Wonder Ink
|
||||
worksheet;
|
||||
* removes the managed original and all derived assets together;
|
||||
* never touches unrelated files in `~/Downloads`, and therefore never a
|
||||
Wonder Ink worksheet;
|
||||
* tolerates a directory that is already half gone.
|
||||
|
||||
## The presenter
|
||||
@@ -181,11 +187,13 @@ Page Up and Page Down are what the clicker in the cupboard sends.
|
||||
Going past the last slide finishes, rather than showing a black "click to
|
||||
exit" slide.
|
||||
|
||||
**Fullscreen is re-asserted, not assumed.** Measured in the lab: focusing
|
||||
another window on the same workspace dropped the slideshow to half the
|
||||
screen with the library beside it. `window-state-event` puts it back for
|
||||
as long as the presentation is running, and stops the moment Escape is
|
||||
pressed so it can never fight the teacher's way out.
|
||||
**Fullscreen is re-asserted, not assumed.** The presenter requests
|
||||
fullscreen after its Wayland surface is mapped, and its stable `Presenting`
|
||||
title lets a presenter-only KWin rule apply fullscreen and remove the border
|
||||
without affecting the library or Quick Look. `window-state-event` reasserts
|
||||
the state for as long as the presentation is running and stops the moment
|
||||
Escape is pressed. The library is hidden during playback and restored on
|
||||
exit; the Plasma panel itself is never hidden or reconfigured.
|
||||
|
||||
## Fonts
|
||||
|
||||
|
||||
Reference in New Issue
Block a user