From 55f4c183c70492d70db39478a49fae68ff40434c Mon Sep 17 00:00:00 2001 From: ekklesia Date: Tue, 22 Sep 2026 20:21:19 -0500 Subject: [PATCH] feat: Presentations, for a teacher who downloaded tonight's session MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PRESENTATIONS_ENABLED, off by default, independent of everything else. A teacher downloads a session in ordinary Chrome and it is on the Presentations screen a few seconds later, ready for the television. No file manager, no import button, no Impress. WHY NOTHING LAUNCHES A DOCUMENT APPLICATION. The brief was to use existing presentation software, so the existing software was tried first, on Debian 13, before any of this was designed. `soffice --show` does start a real fullscreen slideshow — and needs XDG_SESSION_TYPE plus a VCL plugin or it dies with "Failed to open display", shows a splash, opened a "Tip of the Day: 1/225" dialog over the slides, and leaves the Impress editor when the show ends. `okular --presentation` opens THREE windows: the presentation, the ordinary document window behind it, and an information dialog. zathura is not a presenter. pdfpc is the closest and is another dependency with a presenter-console model. Every one of them leaves an application on screen that can open any file on the machine, and none of them knows there is a library to go back to. So LibreOffice converts once, headless, at import, with no window on any screen; poppler renders the pages; the classroom shows the pictures. Measured: 0.34s for a ten-slide PPTX, 0.03s for its ten thumbnails, 0.10s for one slide at 1920px. That is not a new renderer — it is the same engine Impress would have used live — and it means Escape is ours, presenting is instant, and a PDF exported from Google Slides skips the conversion entirely and keeps the appearance Google gave it. THE THREE THINGS KEPT APART. The library thumbnail, the starting slide and the retention clock are independent, because the first slide of a Bible study session is a generic opening shared by every session and the one that names it is usually the second. Quick Look chooses the picture; it does not change where the slideshow starts and it does not count as having presented anything. mark_presented() is called when a slide is actually drawn, not when Present is pressed: an intention is not a presentation, and a viewer that failed to start must not buy another thirty days. IMPORTING. The teacher's download is copied, never moved, renamed or deleted. A file with a .crdownload beside it is still arriving. Wonder Ink's own folder is not looked at. Two downloads of the same name are two presentations, the second titled (2) — found in the lab, where a PDF and a PPTX of one session both came out with the same name because the import being named was excluded from the taken-titles set BY TITLE, and a set holds one copy of a repeated string. Metadata is written saying "importing" before any work, so a reboot mid-conversion leaves a directory the next startup sweeps and imports again. A file that cannot be converted gets a card saying so, offering only Remove, with the teacher's download untouched. Retention: 180 days never presented, 30 days from the last presentation, every presentation starting the thirty over. The cleanup never touches a presentation being shown, never leaves the library directory, and never looks at Downloads. The dock order is unchanged: Presentations is appended after the disc player, so Wonder Ink, the browser and the player keep the places teachers have been reaching for. There is a test for exactly that. classroom-wonderink now asks feature() rather than carrying its own copy of the default, so the panel and the command cannot disagree. Co-Authored-By: Claude Opus 5 --- config/icons/ekklesia-presentations.svg | 35 + .../ekklesia-presentations.desktop | 28 + .../layouts/org.kde.plasma.desktop-layout.js | 43 +- docs/presentations.md | 220 +++++ .../presentations-after-escape.png | Bin 0 -> 48983 bytes docs/screenshots/presentations-library.png | Bin 0 -> 52358 bytes docs/screenshots/presentations-presenting.png | Bin 0 -> 32449 bytes docs/screenshots/presentations-quicklook.png | Bin 0 -> 68219 bytes .../presentations-thumbnail-chosen.png | Bin 0 -> 66946 bytes lib/classroom_config.py | 35 + lib/classroom_presentations.py | 807 ++++++++++++++++++ lib/classroom_style.py | 101 ++- packaging/debian/control.template | 24 +- packaging/debian/postinst | 7 + scripts/classroom-desktop-layout | 54 +- scripts/classroom-parent-call | 93 +- scripts/classroom-presentation-import | 339 ++++++++ scripts/classroom-presentations | 765 +++++++++++++++++ scripts/classroom-wonderink | 8 +- .../ekklesia-classroom-presentations.service | 28 + tests/test-classroom-desktop-layout.sh | 98 ++- tests/test-classroom-presentations.sh | 263 ++++++ tools/lab/make-presentation | 142 +++ 23 files changed, 2979 insertions(+), 111 deletions(-) create mode 100644 config/icons/ekklesia-presentations.svg create mode 100644 config/plasma/applications/ekklesia-presentations.desktop create mode 100644 docs/presentations.md create mode 100644 docs/screenshots/presentations-after-escape.png create mode 100644 docs/screenshots/presentations-library.png create mode 100644 docs/screenshots/presentations-presenting.png create mode 100644 docs/screenshots/presentations-quicklook.png create mode 100644 docs/screenshots/presentations-thumbnail-chosen.png create mode 100644 lib/classroom_presentations.py create mode 100755 scripts/classroom-presentation-import create mode 100755 scripts/classroom-presentations create mode 100644 systemd/user/ekklesia-classroom-presentations.service create mode 100755 tests/test-classroom-presentations.sh create mode 100755 tools/lab/make-presentation diff --git a/config/icons/ekklesia-presentations.svg b/config/icons/ekklesia-presentations.svg new file mode 100644 index 0000000..c9b1b01 --- /dev/null +++ b/config/icons/ekklesia-presentations.svg @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + diff --git a/config/plasma/applications/ekklesia-presentations.desktop b/config/plasma/applications/ekklesia-presentations.desktop new file mode 100644 index 0000000..9fa9d40 --- /dev/null +++ b/config/plasma/applications/ekklesia-presentations.desktop @@ -0,0 +1,28 @@ +[Desktop Entry] +Type=Application +Name=Presentations +GenericName=Slides +Comment=Show a presentation that was downloaded in the browser +# Drawn for this: a screen with a slide on it and a corner turned, which +# is a presentation rather than a document or a photograph. Breeze's +# view-presentation is a chart on a board, which in a church reads as a +# business meeting. Uses ColorScheme-Text like the classroom's other two +# marks, so it recolours with the session and needs no light-theme twin. +Icon=ekklesia-presentations +Exec=/usr/local/bin/classroom-presentations +Terminal=false +Categories=Office;Presentation; +StartupNotify=true +# How the panel matches the window on screen to this launcher. GTK sets +# the Wayland app id from GLib.set_prgname, which classroom-presentations +# sets to exactly this. A mismatch here is not an error anywhere — it is +# silently two buttons on the panel instead of one. +StartupWMClass=ekklesia-presentations +# One window. Pressing the panel button again brings the library forward +# rather than opening a second copy of it. +X-GNOME-SingleWindow=true +# Deliberately visible to the applications index, like the disc player and +# Parent Call: the panel resolves its launcher through that index, and an +# entry hidden from it gives the bar a blank page instead of the mark. +# There is no application menu in this classroom for it to clutter. +NoDisplay=false diff --git a/config/plasma/lookandfeel/contents/layouts/org.kde.plasma.desktop-layout.js b/config/plasma/lookandfeel/contents/layouts/org.kde.plasma.desktop-layout.js index 0b3020f..7c33924 100644 --- a/config/plasma/lookandfeel/contents/layouts/org.kde.plasma.desktop-layout.js +++ b/config/plasma/lookandfeel/contents/layouts/org.kde.plasma.desktop-layout.js @@ -12,19 +12,22 @@ // WHICH APPLICATIONS THIS DEVICE OFFERS. // -// classroom-desktop-layout rewrites the three lines between the markers -// to match device.conf and this machine's hardware, and nothing else in +// classroom-desktop-layout rewrites the lines between the markers to +// match device.conf and this machine's hardware, and nothing else in // this file. Each application is its own line because each is its own // setting: a laptop taking children's church needs Wonder Ink and a tower // used for Bible study does not, so the shape of the machine is never // allowed to decide what it is for. // -// All true here is the shipped default, which is what an existing -// classroom must come up as. +// The first three are true here, which is what an existing classroom must +// come up as. PRESENTATIONS is false, which is what an existing classroom +// must come up as too: no room has ever had it, and an upgrade may not +// put a button on a bar nobody asked for. /* CLASSROOM-FEATURES-BEGIN */ var WONDERINK = true; var DVD = true; var PARENT_CALL = true; +var PRESENTATIONS = false; /* CLASSROOM-FEATURES-END */ var WALLPAPER = "/usr/share/backgrounds/ekklesia/classroom-calm.png"; @@ -84,6 +87,27 @@ if (PARENT_CALL) { parentCall.writeConfig("maxSectionCount", 1); } +// HELP, beside Parent Call and not in the row with the applications. +// +// Every room gets it: the manual is the one thing that is never optional, +// because a teacher who needs it is by definition a teacher who does not +// know where to look. It shows only the pages for the features THIS +// device has — see classroom-manual — so the button means the same thing +// in every room while what it opens does not. +// +// On the left, with Parent Call, for the same reason Parent Call is +// there: it is not one of the room's applications, and putting it in the +// middle row would move buttons teachers reach for without looking. +var help = panel.addWidget("org.kde.plasma.quicklaunch"); +help.currentConfigGroup = ["General"]; +help.writeConfig( + "launcherUrls", + "file:///usr/share/applications/ekklesia-manual.desktop" +); +help.writeConfig("showLauncherNames", false); +help.writeConfig("enablePopup", false); +help.writeConfig("maxSectionCount", 1); + var leftGap = panel.addWidget("org.kde.plasma.panelspacer"); leftGap.currentConfigGroup = ["General"]; leftGap.writeConfig("expanding", true); @@ -114,6 +138,17 @@ if (DVD) { launchers.push("applications:ekklesia-dvd.desktop"); } +// LAST, AND THAT IS THE WHOLE REASON IT IS HERE. +// +// Every existing room has Wonder Ink, the browser and the disc player in +// that order, and teachers have been pressing them in that order for +// months. Appending keeps all three exactly where they are on every +// machine that upgrades; putting Presentations anywhere else in the row +// would move a button somebody reaches for without looking. +if (PRESENTATIONS) { + launchers.push("applications:ekklesia-presentations.desktop"); +} + tasks.writeConfig("launchers", launchers.join(",")); // THE ORDER STAYS PUT WHEN AN APPLICATION OPENS. diff --git a/docs/presentations.md b/docs/presentations.md new file mode 100644 index 0000000..719ed40 --- /dev/null +++ b/docs/presentations.md @@ -0,0 +1,220 @@ +# Presentations + +Optional per device, off by default. `PRESENTATIONS_ENABLED=true` in +`/etc/ekklesia-classroom/device.conf` puts a **Presentations** button on +the bar and starts the importer; nothing else in the room changes. + +It depends on nothing else. A machine may have Presentations with no +Wonder Ink, no drive, no Parent Call, on Wi-Fi or a cable, as a laptop or +a tower. The Bible study laptop is the first installation. + +## What was measured before any of this was designed + +The brief was to use existing presentation software. So the existing +presentation software was tried first, on Debian 13 in the Plasma lab, +against a ten-slide deck in both PPTX and PDF. **The critical +requirement is that a teacher who ends or cancels a slideshow lands back +in the library and never in an editor.** + +| Tried | What it actually did | +| --- | --- | +| `soffice --show deck.pptx` | Starts a real fullscreen slideshow — `app_id=libreoffice-impress`, `"Presenting: session7"`, `fullscreen=1`. But it needs `XDG_SESSION_TYPE=wayland` **and** `libreoffice-gtk3`/`-qt6`, or it dies with *"Failed to open display"*; it shows the LibreOffice splash on the way up; and a **"Tip of the Day: 1/225"** dialog opened on top of the slideshow on first run. Ending the show leaves the Impress editor. | +| `okular --presentation deck.pdf` | Opens **three** windows: the presentation, the ordinary Okular document window behind it, and an **"Information — Okular"** dialog. The full viewer UI — File, Open, Settings — sits behind the slides. | +| `zathura deck.pdf` | Opens windowed, not fullscreen. A document reader, not a presenter. | +| `pdfpc deck.pdf` | Single fullscreen window, the closest of the four. With `--single-screen` it came up windowed, and in the lab it did not respond to Right, Escape or `q`. A presenter-console tool with notes and a timer, and another dependency. | + +None of them returns a teacher to a library, because none of them knows +there is one. Every one of them leaves an application on the screen that +can open any file on the machine. + +### What was chosen instead + +**LibreOffice converts once, headless, at import. Poppler renders the +pages. The classroom shows the pictures.** + +``` +Session 7.pptx --soffice --headless --convert-to pdf--> slides.pdf +slides.pdf --pdftoppm -png -scale-to-x 1920--------> page-001.png ... +``` + +Measured on the same deck: + +| Step | Time | +| --- | --- | +| PPTX → PDF, ten slides | 0.34 s | +| All ten pages → PNG | 0.03 s | +| One page at 1920px | 0.10 s | + +Fonts embed correctly (`BAAAAA+LiberationSans`, subset, embedded) and the +text survives, which is where a title comes from when the filename is a +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. +What it buys: + +* **A teacher can never reach an editor**, because no editor ever runs + interactively. `soffice` runs once, with no window, at import. +* **Escape is ours.** The presenter is a window of the library's own + process, so ending a slideshow is the library raising itself, not a + second program being asked to exit. +* **Presenting is instant.** The pictures already exist; there is no + LibreOffice to start in front of a room. +* **PDF is first class.** A session exported from Google Slides as PDF + skips the conversion entirely and keeps exactly the appearance Google + gave it. PPT and PPTX join that path rather than having one of their + own. +* **Offline by construction.** Nothing after the download touches the + network. + +`libreoffice-gtk3` is deliberately *not* a dependency: nothing +interactive runs, so no UI integration package is needed. + +## Where things are + +``` +~/Downloads/ the teacher's own download. NEVER touched. +~/Downloads/Wonder Ink/ Wonder Ink's worksheets. NEVER touched. + +~/.local/share/ekklesia-classroom/presentations/ + imported.json which downloads have been dealt with + / + presentation.json title, pages, thumbnail slide, timers + Session 7 - Romans.pptx the managed copy, 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 +``` + +## Importing + +`ekklesia-classroom-presentations.service` (user) runs +`classroom-presentation-import`, which looks at `~/Downloads` every four +seconds. Polling, not inotify: a teacher waits the same few seconds +either way, and this cannot miss an event across a restart. + +A file is imported when **all** of these hold: + +* its extension is `.pdf`, `.pptx` or `.ppt`; +* it is not inside the `Wonder Ink` directory; +* there is no `.crdownload`, `.part`, `.partial`, `.download` or `.tmp` + sibling — Chrome writes `Session 7.pptx.crdownload` and renames it when + the transfer finishes, so that sibling is the authoritative "still + arriving"; +* it has not changed for six seconds, which catches a copy from a USB + stick that has no `.crdownload` to go by; +* it is not empty; and +* 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. + +**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 +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. + +## The three things kept apart + +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 | +| **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 | + +The first slide of a Bible study session is a generic opening shared by +every session; the one that names the session is usually the second. So +the thumbnail defaults to slide 1 and Quick Look exists to change it, and +changing it must not be mistaken for having presented anything. + +`Presenter.show_page` calls `mark_presented()` at the moment the first +slide is drawn, and not before. Pressing **Present** is an intention; a +picture on the screen is a presentation. + +## Retention + +| State | Kept | +| --- | --- | +| Never presented | 180 days from import | +| Presented | 30 days from the **last** presentation | + +Every presentation restarts the thirty days. No teacher-facing setting. + +The cleanup runs hourly in the importer and: + +* never removes a presentation whose id is in + `$XDG_RUNTIME_DIR/ekklesia-classroom-presenting` — the lock the + presenter holds while a slide is on the screen. In the runtime + 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; +* tolerates a directory that is already half gone. + +## The presenter + +A fullscreen `Gtk.Window` in the library's own process showing one +pre-rendered page at a time, letterboxed — never cropped, never +stretched. + +| Key | Does | +| --- | --- | +| Space, →, ↓, Page Down, Return, `n` | Next slide | +| ←, ↑, Page Up, Backspace, `p` | Previous slide | +| Home / End | First / last slide | +| Escape, `q`, F5 | Finish, back to the library | + +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. + +## Fonts + +The pastor's material comes from Google Slides. These are all in Debian +main and install without a question: + +| Package | Covers | +| --- | --- | +| `fonts-liberation2` | Arial, Times New Roman, Courier New — metric compatible | +| `fonts-crosextra-carlito` | Calibri | +| `fonts-crosextra-caladea` | Cambria | +| `fonts-croscore` | the same three under their Chrome OS names | +| `fonts-liberation-sans-narrow` | Arial Narrow | +| `fonts-roboto`, `fonts-open-sans`, `fonts-lato`, `fonts-montserrat` | the web fonts Google Slides offers | +| `fonts-urw-base35` | the PostScript standard 35 | + +`ttf-mscorefonts-installer` is deliberately **absent**. It is in contrib, +it downloads from a third party at install time, and it shows an EULA +prompt — which an unattended classroom upgrade cannot answer. + +## Checking a machine + +``` +classroom-presentation-import --status what the library holds +classroom-presentation-import --once one pass, then stop +classroom-presentation-import --cleanup apply retention now +classroom-manual --features which manual pages this device shows +``` + +`--status` prints titles, slide counts, the chosen thumbnail slide, both +timers and the expiry date. It is the fastest way to answer "why has this +gone" and "why has this not appeared". diff --git a/docs/screenshots/presentations-after-escape.png b/docs/screenshots/presentations-after-escape.png new file mode 100644 index 0000000000000000000000000000000000000000..61c4c8b9b4d2f1930050d035f2e102d3be7cc2c7 GIT binary patch literal 48983 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 v^3RP7BA%bI!+%%g_jAR58m|A6Nru6i& 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

K? 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 literal 0 HcmV?d00001 diff --git a/docs/screenshots/presentations-thumbnail-chosen.png b/docs/screenshots/presentations-thumbnail-chosen.png new file mode 100644 index 0000000000000000000000000000000000000000..51a9ba0c7b9890a56de3798551488c1e6590a724 GIT binary patch literal 66946 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

Wac1e|>9m?)aBrbfh z=}uA8&L_>*=A4J5&=Ls(WIwys{A}5~#3H=rvV@p@({uD+XJ1R~>eDny>du*G&Vi+1KJQg&&mlUz2XbH|-TN3J7G{QGJqBrp?Bb5v>YN9WPwFPT3Z|_bA2T?w?&zn0CRDp+JZ#DO+ z5Nbyx%j7jZGm5Usb=k-hxMsz?B6KjOafW6}HPpIscg}Dx7U4}gd#AgWeCU8(H4b}SE8zv6d4{uF@I%{8K!{PSNAGGn! z-ctT}CrWMc(NVxz%~WkvSxLU#5K)sMUA7OlE|RLv$)&UU{(F;DA{;*u(qrmQDJU@^ zq`NW-*4z=yFp^vRRXEikv~sX?q>v?D{Ntd0^u=Zg+J+S12_`OCgMQm-b$Ccs2Y$EhpT9p~!(Lq7b(wecMu`vZ3B>zE-vRmvb z3+^{iMIOzjC`jDuuHe!CZc>wZ?9{KSuFDw5w7W#D{}}(H0y?;y2_yVDwE4~-t+u?#dYLP*O$N#7*HioLH%lzm3;4qzWzn2_T8W+a zut$anHyxC4kC7G66yCI0d>1Jaf{2uLj zB50sDW>q6EvDl(CafSvmTSxbdc;*}FD3!KOtw_9l1?H+gv{kUVCWMvr4EYe~&^hH> zUO%m4&jtDs^|aNE(Sw)J6Pu>WcLg)*FjfY{m2ggvV)a!im7G3zX5mA%mUnYf@EvLe z6Hbr9Pi%Hz}o7u z;@N$NT{*$$&|V^>YKdiPcY&trx7!W+am$Blc}U<<+Cbqw_a%8nb85dojIpTw`XPJr z?%Mab{4evztv>PSU_wlj;wukF4&qa(G`=-F zmvWtYTsPG3zGWGy1}=#D$vTYq^Jj?_Hdq#v{m+Rn?KsdzHhp=4^)ka4q=rqb;U4iD z3=*DlSIR`g+P6v$7N#n^diu?w-}qKl?k()zH^XLI{PvMHE>932dt|; zE(d-biRquBxZz>@Wd@MpoL=6#lA zR4q1Riw1)(QE+j@1x-49Vy-(A_*g%Y0dxiqp8L8Xsyh6OPo<)=bGlPHYi4=g6!Pp` z(5TV{26mrlq1kq*Fkw|`a&o&#=>`mK%{&rUvSbZWJ_&ioEV;iTIUk0108C?63#h{t zVk#}n7blmN2;ZB6WUMd~)N-Rjl{M$WIv<{buzh8@q(T)Kj%riY=Q}!OR^<#Ar z;@u3h&P^z82nm+Ap#AF*l{d$t{D-d}#FN%NRavB%55S49-}3`1SWi0=_{|7j26^#R z>%^i1x==N&6rneFvy9GRMRZ*S@<`eA@tetZmb=CMXM#ngXJnMRK4@S!{DEt9VL{R0 zO)}hTX}kLrXGGn?xt?*{(4~GzyX&P3k^Bz}Y3@nIT8ionue>Qj-UcQr8U`>&C#5Ck&}C(GS0zUAKO0>NhY#fH`-QAE za+^Jw=8?DlvOo2H`QM7ALc4n;N}EK?9ky58%yr*Xz0{tVaeU;ic+ zqo3XN%0-enrn3fE$Nj4O3ZH_}+kwlnc3~<-Y)m)k`&FYlnQ^fGFM2c(wYQSY;gxb207WK;_M2Bp( zABHpE~U563{N%AkgRbG=v;BL zCLJf%-s(LD-LTbO&)OTx314TmTmOjY=0$IKNHR0SE_hgf1y;Psb~Qs?_2NR1<(W~? z)BS4mk_~3`x()(xbGKj!7RHGu_d|5w?1SWxF;}3|$VM7CFdW3_hVcgQ`1bi2HdhH|(2cxX zK^ubE

NB#NmhvY_#8o&NM(osO( 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%0AJROJCE2 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 3 and not re.fullmatch(r"[\W\d_]+", cleaned): + # Long enough to be a name and not purely punctuation and digits. + return cleaned[:80] + + # The filename told us nothing. The first readable line of the + # document itself is a better answer than "a4f39c2e". + for line in (fallback_text or "").splitlines(): + line = re.sub(r"\s+", " ", line).strip() + + if len(line) >= 3: + return line[:80] + + return "Presentation" + + +def unique_title(title, taken): + """A title that is not already on another card. + + Two files of the same name are two presentations, never one + overwriting the other, so the second has to be tellable from the + first on a wall of cards. + """ + if title not in taken: + return title + + for number in range(2, 100): + candidate = f"{title} ({number})" + + if candidate not in taken: + return candidate + + return f"{title} ({uuid.uuid4().hex[:6]})" + + +# -------------------------------------------------------- the library + +class Presentation: + """One entry in the library, and the directory holding it.""" + + def __init__(self, directory, data): + self.directory = Path(directory) + self.data = data + + # -- identity ------------------------------------------------- + + @property + def id(self): + return self.data.get("id") or self.directory.name + + @property + def title(self): + return self.data.get("title") or "Presentation" + + @property + def pages(self): + try: + return max(0, int(self.data.get("pages") or 0)) + except (TypeError, ValueError): + return 0 + + @property + def state(self): + return self.data.get("state") or "importing" + + @property + def ready(self): + return self.state == "ready" and self.slides.exists() + + @property + def failed(self): + return self.state == "failed" + + @property + def error(self): + return self.data.get("error") or "" + + # -- files ---------------------------------------------------- + + @property + def slides(self): + """The PDF everything is presented and rendered from.""" + return self.directory / "slides.pdf" + + @property + def pages_directory(self): + return self.directory / "pages" + + def page_image(self, number): + return self.pages_directory / f"page-{number:03d}.png" + + @property + def thumbnail(self): + return self.directory / "thumbnail.png" + + @property + def managed_copy(self): + name = self.data.get("managed_copy") + + return self.directory / name if name else None + + # -- what a teacher chose ------------------------------------- + + @property + def thumbnail_page(self): + """Which slide is the card's picture. + + Independent of where a presentation starts, and independent of + whether it has ever been presented. Changing it is not a + presentation and does not touch a retention timer — the three are + kept apart on purpose, because the first slide of a Bible study + session is a generic opening shared by every session and the one + that names the session is usually the second. + """ + try: + chosen = int(self.data.get("thumbnail_page") or 1) + except (TypeError, ValueError): + return 1 + + return min(max(chosen, 1), self.pages or 1) + + # -- retention ------------------------------------------------ + + @property + def imported_at(self): + return parse_stamp(self.data.get("imported_at")) + + @property + def last_presented_at(self): + return parse_stamp(self.data.get("last_presented_at")) + + @property + def times_presented(self): + try: + return max(0, int(self.data.get("times_presented") or 0)) + except (TypeError, ValueError): + return 0 + + def expires_at(self): + """When the cleanup may remove this, or None if it cannot say. + + Two clocks, and only ever one of them running. A presentation + that has never been shown is kept for six months from the day it + arrived. One that has been shown is kept for a month from the + last time it was actually shown, and every showing starts that + month again. + """ + presented = self.last_presented_at + + if presented is not None: + return presented + timedelta(days=AFTER_PRESENTING_DAYS) + + imported = self.imported_at + + if imported is None: + return None + + return imported + timedelta(days=NEVER_PRESENTED_DAYS) + + def expired(self, moment=None): + due = self.expires_at() + + return due is not None and (moment or now()) >= due + + # -- writing -------------------------------------------------- + + @property + def metadata_path(self): + return self.directory / "presentation.json" + + def save(self): + write_json(self.metadata_path, self.data) + + def set_thumbnail_page(self, number): + """Choose the slide the library card shows. + + Deliberately writes nothing else. This is not a presentation, it + is not an import, and it must not move a retention timer. + """ + number = min(max(int(number), 1), self.pages or 1) + self.data["thumbnail_page"] = number + self.save() + + source = self.page_image(number) + + if source.exists(): + render_thumbnail(source, self.thumbnail) + + return number + + def mark_presented(self, moment=None): + """Record that this was really shown to a room. + + Called only after the presenter has a slide on the screen. Quick + Look, opening the library, generating previews and choosing a + thumbnail all deliberately do not call it, and neither does a + viewer that failed to start — a presentation that did not happen + must not buy another thirty days. + """ + self.data["last_presented_at"] = stamp(moment) + self.data["times_presented"] = self.times_presented + 1 + self.save() + + +def load(directory): + directory = Path(directory) + data = read_json(directory / "presentation.json") + + if not isinstance(data, dict): + return None + + return Presentation(directory, data) + + +def library(root=None): + """Every presentation, newest import first. + + A directory that is half written — an import interrupted by a reboot, + say — has no readable metadata and is simply not in the list. The + importer clears those up; the library never shows a card it cannot + open. + """ + root = Path(root) if root is not None else library_root() + + if not root.is_dir(): + return [] + + found = [] + + for entry in sorted(root.iterdir()): + if not entry.is_dir(): + continue + + presentation = load(entry) + + if presentation is not None: + found.append(presentation) + + found.sort(key=lambda p: (p.data.get("imported_at") or ""), reverse=True) + + return found + + +def titles_in_use(root=None, exclude=None): + """Every title already on a card, optionally ignoring one presentation. + + Excluded BY ID rather than by title, which is not a detail. The import + being named is already in the library — it is written before the + conversion starts so an interruption is recoverable — so its own + provisional title has to come out of the set. Taking it out by title + removed the other presentation's identical title along with it, a set + holding one copy of a repeated string, and two files whose names + differ only in their extension both came out called "Session 7 - + Romans". Found in the lab, importing a PDF and a PPTX of the same + session, which is exactly what tomorrow's test does. + """ + return { + presentation.title + for presentation in library(root) + if exclude is None or presentation.id != exclude + } + + +# ------------------------------------------------------------ imports + +def is_partial(path): + """Whether this file is still arriving.""" + path = Path(path) + + if path.name.startswith("."): + return True + + if path.suffix.lower() in PARTIAL_SUFFIXES: + return True + + # Chrome's in-progress file sits beside the finished name. + for suffix in PARTIAL_SUFFIXES: + if path.with_name(path.name + suffix).exists(): + return True + + return False + + +def settled(path, seconds=SETTLE_SECONDS): + """Whether the file has stopped being written to.""" + try: + stat = Path(path).stat() + except OSError: + return False + + return (time.time() - stat.st_mtime) >= seconds and stat.st_size > 0 + + +def importable(path): + """Whether this is a finished file the library should take.""" + path = Path(path) + + if path.suffix.lower() not in SUPPORTED: + return False + + if not path.is_file(): + return False + + return not is_partial(path) and settled(path) + + +def within_wonderink(path, downloads=None): + """Whether this file belongs to Wonder Ink's own download workflow. + + Wonder Ink puts a lesson's worksheets in a directory of its own + inside Downloads. They are worksheets, not presentations: they are + not imported, and nothing in the library ever removes one. + """ + downloads = Path(downloads) if downloads is not None else downloads_root() + + try: + relative = Path(path).resolve().relative_to(downloads.resolve()) + except (OSError, ValueError): + return False + + return WONDERINK_DOWNLOADS in relative.parts + + +def candidates(downloads=None): + """Finished presentation files sitting in the teacher's Downloads. + + The top level only. Nothing recurses into Wonder Ink's directory, + and nothing looks anywhere else on the machine: a library that + imported from the whole home directory would be a file manager. + """ + downloads = Path(downloads) if downloads is not None else downloads_root() + + if not downloads.is_dir(): + return [] + + found = [] + + try: + entries = sorted(downloads.iterdir()) + except OSError: + return [] + + for entry in entries: + if entry.is_dir(): + continue + + if within_wonderink(entry, downloads): + continue + + if importable(entry): + found.append(entry) + + return found + + +def fingerprint(path): + """What makes this exact download this exact download. + + Path, size and modification time. Enough that re-downloading the same + session tomorrow is a new presentation, and that a reboot does not + import everything in Downloads all over again. + """ + try: + stat = Path(path).stat() + except OSError: + return None + + return f"{Path(path).resolve()}|{stat.st_size}|{int(stat.st_mtime)}" + + +def ledger_path(root=None): + root = Path(root) if root is not None else library_root() + + return root / "imported.json" + + +def ledger(root=None): + data = read_json(ledger_path(root), default={}) + + return data if isinstance(data, dict) else {} + + +def remember(mark, value, root=None): + """Record that this download has been dealt with. + + Kept even after a teacher removes the presentation, so that Remove + means removed rather than removed-until-the-next-scan. The original + download is still in Downloads — untouched, as always — and without + this the importer would put it straight back. + """ + data = ledger(root) + data[mark] = value + write_json(ledger_path(root), data) + + +# ----------------------------------------------------- rendering + +# Everything below shells out. Nothing here draws a slide: LibreOffice +# converts a deck to PDF exactly as Impress would have rendered it live, +# and poppler turns PDF pages into pictures. The classroom's own code +# only ever displays a picture one of them produced. + +SOFFICE = "soffice" +PDFTOPPM = "pdftoppm" +PDFINFO = "pdfinfo" +PDFTOTEXT = "pdftotext" + +# A large deck on a slow machine. Generous, because the alternative to +# waiting is a half-converted file presented to a room. +CONVERT_TIMEOUT = 300 +RENDER_TIMEOUT = 600 + + +def _run(command, timeout, **kwargs): + import subprocess + + try: + return subprocess.run( + command, capture_output=True, text=True, timeout=timeout, + check=False, **kwargs) + except (OSError, subprocess.SubprocessError) as error: + class Failed: + returncode = 127 + stdout = "" + stderr = str(error) + + return Failed() + + +def convert_to_pdf(source, destination): + """Turn a PPT or PPTX into the PDF everything else works from. + + Headless, in a profile of its own, with no window on any screen. A + teacher never sees LibreOffice: not its splash, not its first-run + dialog, and above all not its editor. It runs once, at import, and + then never again for that presentation. + + A separate -env:UserInstallation is not optional. LibreOffice takes + an exclusive lock on its user profile, so a conversion running while + anything else on the machine uses LibreOffice would fail, and the + failure would arrive as a presentation that never finished importing. + """ + source = Path(source) + destination = Path(destination) + destination.parent.mkdir(parents=True, exist_ok=True) + + workspace = destination.parent / "convert" + profile = destination.parent / "loprofile" + + if workspace.exists(): + shutil.rmtree(workspace, ignore_errors=True) + + workspace.mkdir(parents=True, exist_ok=True) + profile.mkdir(parents=True, exist_ok=True) + + result = _run( + [ + SOFFICE, + f"-env:UserInstallation=file://{profile}", + "--headless", "--norestore", "--nologo", "--nolockcheck", + "--nodefault", "--nofirststartwizard", + "--convert-to", "pdf:impress_pdf_Export", + "--outdir", str(workspace), + str(source), + ], + CONVERT_TIMEOUT, + ) + + produced = sorted(workspace.glob("*.pdf")) + + if not produced: + shutil.rmtree(profile, ignore_errors=True) + shutil.rmtree(workspace, ignore_errors=True) + + return False, (result.stderr or result.stdout or + "the file could not be opened").strip() + + os.replace(produced[0], destination) + shutil.rmtree(profile, ignore_errors=True) + shutil.rmtree(workspace, ignore_errors=True) + + return True, "" + + +def page_count(pdf): + """How many slides, according to poppler.""" + result = _run([PDFINFO, str(pdf)], 60) + + for line in (result.stdout or "").splitlines(): + if line.startswith("Pages:"): + try: + return int(line.split(":", 1)[1].strip()) + except ValueError: + return 0 + + return 0 + + +def first_text(pdf, pages=2): + """A little of the document's own words, for a title of last resort.""" + result = _run([PDFTOTEXT, "-f", "1", "-l", str(pages), str(pdf), "-"], 60) + + return result.stdout or "" + + +def render_pages(pdf, directory, width=SLIDE_WIDTH, progress=None): + """Every slide as a picture, at the size a television shows it. + + One pdftoppm run for the whole document rather than one per page: + measured in the lab at 0.03s for ten pages, against a process launch + each time. `progress` is called with the number rendered so far, so a + library window can show a large import filling in rather than freeze. + """ + pdf = Path(pdf) + directory = Path(directory) + directory.mkdir(parents=True, exist_ok=True) + + import subprocess + + command = [ + PDFTOPPM, "-png", + "-scale-to-x", str(width), "-scale-to-y", "-1", + str(pdf), str(directory / "page"), + ] + + try: + process = subprocess.Popen( + command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, + text=True) + except OSError as error: + return 0, str(error) + + deadline = time.monotonic() + RENDER_TIMEOUT + + while process.poll() is None: + if time.monotonic() > deadline: + process.kill() + return 0, "rendering took too long" + + if progress is not None: + progress(len(list(directory.glob("page-*.png")))) + + time.sleep(0.4) + + if process.returncode != 0: + return 0, (process.stderr.read() if process.stderr else + "the slides could not be rendered") + + # pdftoppm numbers by the page count's width: page-1 for a nine-page + # document, page-01 for a ninety-page one. The library asks for + # page-001, so they are renamed into one shape and nothing that reads + # them has to know how many there were. + rendered = sorted(directory.glob("page-*.png")) + + for number, path in enumerate(rendered, start=1): + wanted = directory / f"page-{number:03d}.png" + + if path != wanted: + os.replace(path, wanted) + + return len(rendered), "" + + +def render_thumbnail(source, destination, width=THUMBNAIL_WIDTH): + """The small picture on a library card, from an already rendered page.""" + source = Path(source) + destination = Path(destination) + + if not source.exists(): + return False + + try: + import gi + + gi.require_version("GdkPixbuf", "2.0") + from gi.repository import GdkPixbuf + + pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale( + str(source), width, -1, True) + temporary = destination.with_name(destination.name + ".new") + pixbuf.savev(str(temporary), "png", [], []) + os.replace(temporary, destination) + + return True + except Exception: # noqa: BLE001 - a card without a picture is fine + # A thumbnail is a convenience. A library that refused to show a + # presentation because it could not shrink a picture would be + # worse than one showing a card with no picture on it. + return False diff --git a/lib/classroom_style.py b/lib/classroom_style.py index 8197dce..ecc6081 100644 --- a/lib/classroom_style.py +++ b/lib/classroom_style.py @@ -1,9 +1,11 @@ -"""The classroom stylesheet, resolved at the room's UI scale. +"""The classroom's look: its measurements and its palette. -The dock and the DVD control bar share this so they cannot drift apart: -one template, one set of measurements, one look. +The DVD control bar, Parent Call and the Presentations library all draw +themselves, and they share this so they cannot drift apart: one set of +measurements, one palette, one look. """ +import os from pathlib import Path from classroom_config import scaled @@ -34,3 +36,96 @@ def render(scale, template=None): css = css.replace(f"@{token}@", str(scaled(value, scale))) return css + + +# ---------------------------------------------------------- the palette + +def load_colours(): + """The session's own palette, read from the colour scheme in use. + + There is one set of design tokens in this classroom, and they live in + a Plasma colour scheme. Reading them here rather than repeating them + means this card follows classroom-theme light and dark without + knowing that either exists. + """ + palette = { + "window": "#141c20", "view": "#0f171a", "text": "#e6edef", + "dim": "#93a5aa", "accent": "#4fb3a8", "on_accent": "#0e1518", + "negative": "#e36a6a", "neutral": "#e0b15c", "positive": "#6fcf97", + "line": "#25333a", + } + + scheme = "EkklesiaDark" + + for path in ( + os.path.expanduser("~/.config/kdeglobals"), + "/etc/ekklesia-classroom/xdg/kdeglobals", + "/etc/xdg/kdeglobals", + ): + try: + with open(path, "r", encoding="utf-8") as handle: + section = None + for line in handle: + line = line.strip() + if line.startswith("["): + section = line + elif section and section.startswith("[General]") and \ + line.startswith("ColorScheme="): + scheme = line.split("=", 1)[1].strip() + break + except OSError: + continue + else: + if scheme: + break + + def rgb(value): + parts = [part.strip() for part in value.split(",")] + if len(parts) != 3: + return None + try: + return "#%02x%02x%02x" % tuple(int(part) for part in parts) + except ValueError: + return None + + try: + with open(f"/usr/share/color-schemes/{scheme}.colors", "r", + encoding="utf-8") as handle: + group = None + for line in handle: + line = line.strip() + if line.startswith("["): + group = line + continue + if "=" not in line or group is None: + continue + key, value = (part.strip() for part in line.split("=", 1)) + colour = rgb(value) + if colour is None: + continue + if group == "[Colors:Window]": + if key == "BackgroundNormal": + palette["window"] = colour + elif key == "ForegroundNormal": + palette["text"] = colour + elif key == "ForegroundInactive": + palette["dim"] = colour + elif key == "ForegroundNegative": + palette["negative"] = colour + elif key == "ForegroundNeutral": + palette["neutral"] = colour + elif key == "ForegroundPositive": + palette["positive"] = colour + elif key == "BackgroundAlternate": + palette["line"] = colour + elif group == "[Colors:View]" and key == "BackgroundNormal": + palette["view"] = colour + elif group == "[Colors:Selection]": + if key == "BackgroundNormal": + palette["accent"] = colour + elif key == "ForegroundNormal": + palette["on_accent"] = colour + except OSError: + pass + + return palette diff --git a/packaging/debian/control.template b/packaging/debian/control.template index 26e73ca..306b322 100644 --- a/packaging/debian/control.template +++ b/packaging/debian/control.template @@ -4,7 +4,7 @@ Section: misc Priority: optional Architecture: amd64 Maintainer: Ekklesia -Depends: pkexec, polkit-kde-agent-1, plasma-desktop, plasma-workspace, kwin-wayland, plasma-nm, plasma-pa, plasma-widgets-addons, konsole, sddm, dbus-user-session, xwayland, fonts-dejavu, fonts-noto, network-manager, pipewire, pipewire-audio, wireplumber, pulseaudio-utils, cups, cups-client, cups-filters, foomatic-db-compressed-ppds, python3-gi, python3-gi-cairo, gir1.2-gtk-3.0, gir1.2-gtklayershell-0.1, libnotify-bin, curl, gnupg, ca-certificates, python3-paho-mqtt, python3-pyqt6.qtwebengine, python3-pyqt6 +Depends: pkexec, polkit-kde-agent-1, plasma-desktop, plasma-workspace, kwin-wayland, plasma-nm, plasma-pa, plasma-widgets-addons, konsole, sddm, dbus-user-session, xwayland, fonts-dejavu, fonts-noto, network-manager, pipewire, pipewire-audio, wireplumber, pulseaudio-utils, cups, cups-client, cups-filters, foomatic-db-compressed-ppds, python3-gi, python3-gi-cairo, gir1.2-gtk-3.0, gir1.2-gtklayershell-0.1, libnotify-bin, curl, gnupg, ca-certificates, python3-paho-mqtt, python3-pyqt6.qtwebengine, python3-pyqt6, libreoffice-impress, libreoffice-core, poppler-utils, fonts-liberation2, fonts-liberation-sans-narrow, fonts-croscore, fonts-crosextra-carlito, fonts-crosextra-caladea, fonts-urw-base35, fonts-roboto, fonts-open-sans, fonts-lato, fonts-montserrat, fonts-noto-extra Recommends: vlc Conflicts: plasma-welcome, plasma-discover, kdeconnect, kup-backup Description: Ekklesia managed classroom environment @@ -36,6 +36,28 @@ Description: Ekklesia managed classroom environment of this build. Chrome stays exactly where it was, for the ordinary browser. . + libreoffice-impress and poppler-utils are Presentations, and neither is + ever shown to a teacher. LibreOffice runs once per import, headless, + with no window on any screen, to turn a PPT or PPTX into a PDF; poppler + turns that PDF into one picture per slide; the classroom's own library + shows the pictures. Measured before it was chosen: `soffice --show` + does start a real slideshow and then leaves the Impress editor on + screen when it ends, and `okular --presentation` opens its own document + window and an information dialog behind the slides. Neither is + something a teacher may be left looking at, and converting once at + import costs 0.34s for a ten-slide deck and nothing at all afterwards. + libreoffice-gtk3 is deliberately NOT here: nothing interactive runs. + . + The fonts are what a Google Slides export asks for. The metric + compatible families cover the Microsoft names — Liberation for Arial, + Times New Roman and Courier New, Carlito for Calibri, Caladea for + Cambria, Croscore for the same three under their Chrome OS names — and + Roboto, Open Sans, Lato and Montserrat are the web fonts Google Slides + itself offers. Every one is in Debian main and installs without a + question. ttf-mscorefonts-installer is deliberately absent: it is in + contrib, it downloads from a third party at install time and it shows + an EULA prompt, and an unattended classroom upgrade cannot answer one. + . The Conflicts line is deliberate. A welcome tour, a software centre and a phone pairing daemon are all things plasma-desktop recommends and a room a teacher walks into should not have. diff --git a/packaging/debian/postinst b/packaging/debian/postinst index 4d322b3..49877dc 100755 --- a/packaging/debian/postinst +++ b/packaging/debian/postinst @@ -62,6 +62,13 @@ systemctl enable sddm.service >/dev/null 2>&1 || true systemctl --global enable ekklesia-classroom-audio.service >/dev/null 2>&1 || true systemctl --global enable ekklesia-classroom-desktop.service >/dev/null 2>&1 || true +# The presentation watcher. Enabled on every machine and started by every +# session, because whether it does anything is device.conf's answer, not +# the installer's: with PRESENTATIONS_ENABLED=false — which is the +# default, and therefore every existing classroom — it exits immediately +# and the room never runs an importer it has no use for. +systemctl --global enable ekklesia-classroom-presentations.service >/dev/null 2>&1 || true + # The panel's disc player is decided before the display manager starts, not # at the same time as it. Enabled rather than started: this install has # just run the same command directly, below. diff --git a/scripts/classroom-desktop-layout b/scripts/classroom-desktop-layout index 8a2afae..c4d330b 100755 --- a/scripts/classroom-desktop-layout +++ b/scripts/classroom-desktop-layout @@ -3,7 +3,7 @@ """Match the classroom's panel to the machine it is on. Which applications a device offers is decided here, once, and written into -the three feature lines of the installed layout. The panel is then built +the feature lines of the installed layout. The panel is then built from that layout at the next login. Each application is its own question, and the shape of the machine is @@ -15,6 +15,11 @@ never one of them: Parent Call PARENT_CALL_ENABLED. Same rule. + Presentations PRESENTATIONS_ENABLED. Same rule again, and it asks + the machine nothing at all: a presentation needs a + screen, which every device has. Alone among these it + defaults to OFF, because no existing room has it. + the disc DVD_ENABLED *and* a drive being present. The setting can player take the player away from a machine that has a drive; nothing can put it on a machine that has none, because a @@ -39,6 +44,7 @@ again at the next login. """ import glob +import json import os import re import sys @@ -61,10 +67,25 @@ FEATURE_LINES = ( ("WONDERINK", "WONDERINK_ENABLED"), ("DVD", "DVD_ENABLED"), ("PARENT_CALL", "PARENT_CALL_ENABLED"), + ("PRESENTATIONS", "PRESENTATIONS_ENABLED"), ) MARKER = "/* CLASSROOM-FEATURES-BEGIN */" +# WHAT THE MANUAL IS ALLOWED TO KNOW ABOUT THIS DEVICE. +# +# This command already decides what the device offers, so it is also the +# place to write that answer down where the classroom account can read +# it. A list of setting NAMES, and nothing else: no values, no broker +# password, no Wi-Fi, no update address, none of the rest of device.conf +# — which the manual has no use for and the room should not be handed. +# +# In /run rather than /etc because it is derived, not configured: it is +# rewritten from device.conf at every boot by the same service that +# builds the bar, so it cannot go stale behind a setting somebody +# changed. +MANIFEST = "/run/ekklesia-classroom/features.json" + # The kernel names optical drives sr0, sr1, ... regardless of bus. Both # views are checked: /dev is what anything opening the drive will use, and # /sys/block is the kernel's own list, which cannot be left behind by a @@ -121,6 +142,32 @@ def rewrite(text, variable, answer): ) +def publish(answers, path=MANIFEST): + """Leave the enabled features where classroom-manual can read them. + + Best effort on purpose. A room whose manual shows a page for + something it has not got is a small confusion; a panel that failed to + build because a directory was read-only is a room with no way of + getting anywhere. + """ + enabled = sorted( + setting for variable, setting in FEATURE_LINES if answers.get(variable) + ) + + try: + os.makedirs(os.path.dirname(path), exist_ok=True) + temporary = f"{path}.new" + + with open(temporary, "w", encoding="utf-8") as handle: + json.dump(enabled, handle) + + os.replace(temporary, path) + os.chmod(path, 0o644) + say(f"the manual will show {', '.join(enabled) or 'no optional pages'}") + except OSError as error: + say(f"could not write {path}: {error}") + + def main(): path = sys.argv[1] if len(sys.argv) > 1 else LAYOUT @@ -137,8 +184,11 @@ def main(): return 0 after = before + answers = wanted(read_device_config()) - for variable, answer in wanted(read_device_config()).items(): + publish(answers) + + for variable, answer in answers.items(): after = rewrite(after, variable, answer) if after == before: diff --git a/scripts/classroom-parent-call b/scripts/classroom-parent-call index 6e51516..10e47d5 100755 --- a/scripts/classroom-parent-call +++ b/scripts/classroom-parent-call @@ -105,95 +105,10 @@ OVERALL_TIMEOUT = 210.0 CLOSE_AFTER_SUCCESS = 4.0 -def load_colours(): - """The session's own palette, read from the colour scheme in use. - - There is one set of design tokens in this classroom, and they live in - a Plasma colour scheme. Reading them here rather than repeating them - means this card follows classroom-theme light and dark without - knowing that either exists. - """ - palette = { - "window": "#141c20", "view": "#0f171a", "text": "#e6edef", - "dim": "#93a5aa", "accent": "#4fb3a8", "on_accent": "#0e1518", - "negative": "#e36a6a", "neutral": "#e0b15c", "positive": "#6fcf97", - "line": "#25333a", - } - - scheme = "EkklesiaDark" - - for path in ( - os.path.expanduser("~/.config/kdeglobals"), - "/etc/ekklesia-classroom/xdg/kdeglobals", - "/etc/xdg/kdeglobals", - ): - try: - with open(path, "r", encoding="utf-8") as handle: - section = None - for line in handle: - line = line.strip() - if line.startswith("["): - section = line - elif section and section.startswith("[General]") and \ - line.startswith("ColorScheme="): - scheme = line.split("=", 1)[1].strip() - break - except OSError: - continue - else: - if scheme: - break - - def rgb(value): - parts = [part.strip() for part in value.split(",")] - if len(parts) != 3: - return None - try: - return "#%02x%02x%02x" % tuple(int(part) for part in parts) - except ValueError: - return None - - try: - with open(f"/usr/share/color-schemes/{scheme}.colors", "r", - encoding="utf-8") as handle: - group = None - for line in handle: - line = line.strip() - if line.startswith("["): - group = line - continue - if "=" not in line or group is None: - continue - key, value = (part.strip() for part in line.split("=", 1)) - colour = rgb(value) - if colour is None: - continue - if group == "[Colors:Window]": - if key == "BackgroundNormal": - palette["window"] = colour - elif key == "ForegroundNormal": - palette["text"] = colour - elif key == "ForegroundInactive": - palette["dim"] = colour - elif key == "ForegroundNegative": - palette["negative"] = colour - elif key == "ForegroundNeutral": - palette["neutral"] = colour - elif key == "ForegroundPositive": - palette["positive"] = colour - elif key == "BackgroundAlternate": - palette["line"] = colour - elif group == "[Colors:View]" and key == "BackgroundNormal": - palette["view"] = colour - elif group == "[Colors:Selection]": - if key == "BackgroundNormal": - palette["accent"] = colour - elif key == "ForegroundNormal": - palette["on_accent"] = colour - except OSError: - pass - - return palette +# The palette lives in classroom_style, so this card, the Presentations +# library and anything else the classroom draws cannot drift apart over +# what "the accent colour" means. +from classroom_style import load_colours # noqa: E402,F401 STYLE = """ diff --git a/scripts/classroom-presentation-import b/scripts/classroom-presentation-import new file mode 100755 index 0000000..41aebb1 --- /dev/null +++ b/scripts/classroom-presentation-import @@ -0,0 +1,339 @@ +#!/usr/bin/env python3 + +"""Watch the teacher's downloads, and keep the library tidy. + +A teacher downloads a session in ordinary Chrome and then looks for it in +Presentations. Nothing in between is their job: no file manager, no +import button, no "where did you save it". This is the in between. + + classroom-presentation-import run as a service, forever + classroom-presentation-import --once one pass, for a technician + classroom-presentation-import --status what the library holds + +WHAT IT WILL NOT DO. + + It never touches the teacher's download. The file Chrome wrote stays + where Chrome wrote it, with the name Chrome gave it, for as long as + the teacher leaves it there. Everything the library does is done to + its own copy. + + It never imports a Wonder Ink worksheet. Wonder Ink downloads into a + directory of its own inside Downloads and those are worksheets, not + sessions; the cleanup will not remove one either. + + It never imports a file that is still arriving. Chrome writes + `Session 7.pptx.crdownload` and renames it when the transfer is + done, so a finished name with that sibling beside it is a download in + progress, not a presentation. + + It never overwrites a presentation with a later one of the same + name. Two downloads called "Bible Study.pdf" are two presentations. +""" + +import argparse +import os +import shutil +import sys +import time +import uuid + +sys.path.insert(0, "/usr/local/lib/ekklesia-classroom") +sys.path.insert( + 0, + os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "lib"), +) + +import classroom_presentations as library # noqa: E402 +from classroom_config import feature, read_device_config # noqa: E402 + +# How often the downloads directory is looked at. +# +# Polling rather than inotify, deliberately. A teacher waits a few +# seconds either way, this cannot leak a watch descriptor or miss an +# event across a restart, and it is the kind of code somebody can still +# read in two years. +SCAN_SECONDS = 4 + +# How often expired presentations are cleared out. +CLEANUP_SECONDS = 3600 + + +def say(message): + print(f"classroom-presentation-import: {message}", flush=True) + + +def new_directory(root): + root.mkdir(parents=True, exist_ok=True) + directory = root / uuid.uuid4().hex + + directory.mkdir() + + return directory + + +def import_one(source, root=None): + """Take one finished download into the library. + + Ordered so that an interruption is always recoverable. The metadata + is written first, saying "importing"; the sweep at startup throws + away anything still saying that and lets it be imported again. A + presentation only becomes visible to a teacher once every file it + needs is on disk. + """ + root = root if root is not None else library.library_root() + mark = library.fingerprint(source) + + if mark is None: + return None + + directory = new_directory(root) + managed = directory / source.name + + data = { + "id": directory.name, + "state": "importing", + "title": library.readable_title(source.name), + "original_name": source.name, + "source_path": str(source), + "managed_copy": source.name, + "format": library.SUPPORTED.get(source.suffix.lower(), ""), + "imported_at": library.stamp(), + "last_presented_at": None, + "times_presented": 0, + "thumbnail_page": 1, + "pages": 0, + "error": None, + } + + presentation = library.Presentation(directory, data) + presentation.save() + + # Recorded before the work, so that a file which crashes the + # conversion every time cannot be retried in a loop forever. The + # startup sweep is what un-records an import interrupted part way. + library.remember(mark, directory.name, root) + + say(f"importing {source.name}") + + try: + # THE TEACHER'S OWN DOWNLOAD IS COPIED, NEVER MOVED. + shutil.copy2(source, managed) + + if data["format"] == "pdf": + # Already the thing everything else is converted into. A + # session exported from Google Slides as a PDF keeps exactly + # the appearance Google gave it, with no conversion at all. + shutil.copy2(managed, presentation.slides) + else: + converted, error = library.convert_to_pdf( + managed, presentation.slides) + + if not converted: + raise RuntimeError(error or "the file could not be converted") + + pages, error = library.render_pages( + presentation.slides, presentation.pages_directory) + + if not pages: + raise RuntimeError(error or "the slides could not be rendered") + + data["pages"] = pages + data["title"] = library.unique_title( + library.readable_title( + source.name, library.first_text(presentation.slides)), + library.titles_in_use(root, exclude=presentation.id), + ) + + library.render_thumbnail(presentation.page_image(1), + presentation.thumbnail) + + data["state"] = "ready" + presentation.save() + + say(f"imported {data['title']!r} ({pages} slides)") + + return presentation + except Exception as error: # noqa: BLE001 + # A card that says it could not be opened, rather than a card + # that opens onto nothing. The teacher's download is untouched + # either way, which is what the message says. + data["state"] = "failed" + data["error"] = str(error)[:300] + presentation.save() + + say(f"could not import {source.name}: {error}") + + return presentation + + +def sweep(root=None): + """Throw away imports that were interrupted, so they can happen again. + + A reboot in the middle of a conversion leaves a directory that says + "importing" and a ledger entry claiming the download is dealt with. + Both go, and the next scan imports it properly. + """ + root = root if root is not None else library.library_root() + + if not root.is_dir(): + return 0 + + ledger = library.ledger(root) + stale = 0 + + for presentation in library.library(root): + if presentation.state != "importing": + continue + + say(f"clearing an import that did not finish: {presentation.title!r}") + + for mark, value in list(ledger.items()): + if value == presentation.id: + ledger.pop(mark, None) + + shutil.rmtree(presentation.directory, ignore_errors=True) + stale += 1 + + if stale: + library.write_json(library.ledger_path(root), ledger) + + return stale + + +def scan(root=None, downloads=None): + """One look at the downloads directory.""" + root = root if root is not None else library.library_root() + known = library.ledger(root) + imported = 0 + + for candidate in library.candidates(downloads): + mark = library.fingerprint(candidate) + + if mark is None or mark in known: + continue + + if import_one(candidate, root) is not None: + imported += 1 + known = library.ledger(root) + + return imported + + +def cleanup(root=None, moment=None): + """Remove presentations whose time is up. + + Only ever the library's own directory, and never the presentation on + the screen. The teacher's download is not part of this and is not + looked at. + """ + root = root if root is not None else library.library_root() + lock = library.presenting_lock() + showing = "" + + try: + showing = lock.read_text().strip() + except OSError: + showing = "" + + removed = 0 + + for presentation in library.library(root): + if not presentation.expired(moment): + continue + + if presentation.id == showing: + # A retention timer must never interrupt a room. It will + # still be expired in an hour. + say(f"{presentation.title!r} is expired but is being presented") + continue + + if presentation.last_presented_at is None: + why = f"never presented, imported {presentation.data['imported_at']}" + else: + why = f"last presented {presentation.data['last_presented_at']}" + + say(f"removing {presentation.title!r} — {why}") + + shutil.rmtree(presentation.directory, ignore_errors=True) + removed += 1 + + return removed + + +def status(root=None): + presentations = library.library(root) + + if not presentations: + print("the library is empty") + return 0 + + for presentation in presentations: + expires = presentation.expires_at() + print(f"{presentation.title}") + print(f" state {presentation.state}" + f"{' — ' + presentation.error if presentation.error else ''}") + print(f" slides {presentation.pages}" + f" (card shows slide {presentation.thumbnail_page})") + print(f" imported {presentation.data.get('imported_at')}") + presented = presentation.data.get("last_presented_at") or "never" + print(f" presented {presented} " + f"({presentation.times_presented} times)") + print(f" expires {library.stamp(expires) if expires else 'unknown'}") + + return 0 + + +def main(): + parser = argparse.ArgumentParser( + description="Bring finished downloads into the Presentations library.") + parser.add_argument("--once", action="store_true", + help="one pass, then stop") + parser.add_argument("--status", action="store_true", + help="what the library holds; changes nothing") + parser.add_argument("--cleanup", action="store_true", + help="apply the retention rules now") + arguments = parser.parse_args() + + if arguments.status: + return status() + + # A device that does not offer Presentations does not run an importer + # for them. Said out loud for the technician who started it by hand. + if not feature(read_device_config(), "PRESENTATIONS_ENABLED"): + say("PRESENTATIONS_ENABLED is false on this device; not starting") + return 0 + + if arguments.cleanup: + removed = cleanup() + say(f"removed {removed} expired presentation(s)") + return 0 + + sweep() + + if arguments.once: + imported = scan() + cleanup() + say(f"imported {imported} presentation(s)") + return 0 + + say(f"watching {library.downloads_root()}") + + last_cleanup = 0.0 + + while True: + try: + scan() + + if time.monotonic() - last_cleanup > CLEANUP_SECONDS: + cleanup() + last_cleanup = time.monotonic() + except Exception as error: # noqa: BLE001 + # One bad file must not stop the watcher. A teacher whose + # next download never appears has no way to find out why. + say(f"scan failed: {error}") + + time.sleep(SCAN_SECONDS) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/scripts/classroom-presentations b/scripts/classroom-presentations new file mode 100755 index 0000000..cdf007a --- /dev/null +++ b/scripts/classroom-presentations @@ -0,0 +1,765 @@ +#!/usr/bin/env python3 + +"""The Presentations library, as a teacher sees it. + +Three buttons on a card — Present, Quick Look, Remove — and nothing else. +No storage locations, no file names, no import controls, no settings, no +retention. A teacher who has downloaded a session in Chrome opens this, +recognises tonight's by its picture, and presses Present. + +WHY THE PRESENTER IS IN THIS WINDOW AND NOT A SEPARATE PROGRAM. + +The disc player is a separate process, because a disc plays until +somebody stops it and the panel is how you get back to it. A +presentation is the opposite: it is a thing a teacher steps into and +must step out of, back to the library, reliably, with one key they +already know. + +Making the presenter a fullscreen window of this same application is the +whole of that guarantee. Escape is handled here, the fullscreen window is +taken down here, and the library is already on the screen underneath it. +There is no second process to fail to start, no window to be left behind, +and no path by which a teacher ends up looking at something that is not +the library. + +That is also why nothing here launches Impress, Okular or any other +document application. Every one of them that was measured leaves its own +editor or viewer on the screen when a slideshow ends — see +docs/presentations.md for what each one actually did. The slides are +pictures by the time they reach this window, rendered at import by +LibreOffice and poppler, and a picture cannot open a file dialog. +""" + +import os +import shutil +import sys + +import gi + +gi.require_version("Gtk", "3.0") +gi.require_version("Gdk", "3.0") +gi.require_version("GdkPixbuf", "2.0") + +from gi.repository import Gdk, GdkPixbuf, GLib, Gtk # noqa: E402 + +sys.path.insert(0, "/usr/local/lib/ekklesia-classroom") +sys.path.insert( + 0, + os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "lib"), +) + +import classroom_presentations as library # noqa: E402 +from classroom_config import feature, read_device_config # noqa: E402 +from classroom_style import load_colours # noqa: E402 + +APP_ID = "ekklesia-presentations" + +# How often the library notices a newly imported presentation. +# +# The importer is a separate service, so a session downloaded while this +# window is open appears without the teacher doing anything. Two seconds +# is well under the time it takes to walk back to the machine. +REFRESH_SECONDS = 2 + +CARD_WIDTH = 320 + + +STYLE = """ +window {{ background-color: {window}; }} +.heading {{ color: {text}; font-size: 30px; font-weight: 700; }} +.subtle {{ color: {dim}; font-size: 16px; }} +.card {{ + background-color: {view}; + border: 1px solid {line}; + border-radius: 18px; + padding: 14px; +}} +.card-title {{ color: {text}; font-size: 19px; font-weight: 600; }} +.card-note {{ color: {dim}; font-size: 14px; }} +.thumb {{ + background-color: {window}; + border: 1px solid {line}; + border-radius: 10px; +}} +button {{ + color: {text}; + background-image: none; + background-color: rgba(255,255,255,0.06); + border: 1px solid {line}; + border-radius: 12px; + padding: 10px 14px; + font-size: 16px; +}} +button:hover {{ background-color: rgba(255,255,255,0.12); }} +button.primary {{ + color: {on_accent}; + background-color: {accent}; + border-color: {accent}; + font-weight: 700; +}} +button.danger:hover {{ background-color: {negative}; color: {on_accent}; }} +.empty {{ color: {dim}; font-size: 20px; }} +.slide-counter {{ + color: {text}; + background-color: rgba(0,0,0,0.65); + border-radius: 10px; + padding: 6px 12px; + font-size: 16px; +}} +""" + + +def scaled_pixbuf(path, width): + try: + return GdkPixbuf.Pixbuf.new_from_file_at_scale( + str(path), width, -1, True) + except (GLib.Error, OSError): + return None + + +class Presenter(Gtk.Window): + """The slideshow. A fullscreen window showing one picture at a time. + + Everything a presentation remote and a keyboard can reasonably send + is accepted, because a teacher in front of a room does not get to + look up which key this one wants. The clicker in the cupboard sends + Page Up and Page Down; the keyboard sends arrows and space. + + Escape is the way out and it is the only way out, which is what makes + this safe to put in front of a teacher: there is nothing else to + press and nowhere else to end up. + """ + + def __init__(self, presentation, start_page=1, on_finish=None): + super().__init__(title=presentation.title) + + self.presentation = presentation + self.on_finish = on_finish + self.page = min(max(start_page, 1), presentation.pages or 1) + self.counted = False + self.finished = False + + self.set_app_paintable(True) + self.fullscreen() + # A slideshow is the only thing on the screen while it is running. + self.set_keep_above(True) + + black = Gdk.RGBA() + black.parse("#000000") + self.override_background_color(Gtk.StateFlags.NORMAL, black) + + self.image = Gtk.Image() + self.add(self.image) + + self.connect("key-press-event", self._key) + self.connect("delete-event", lambda *_: self.finish()) + self.connect("size-allocate", self._resized) + self.connect("window-state-event", self._state) + + self._drawn_at = (0, 0, 0) + + def _state(self, _widget, event): + """Put the slideshow back on the whole screen if it is taken off it. + + A compositor may unfullscreen a window without being asked: + measured in the lab, where focusing another window on the same + workspace dropped the slideshow to half the screen with the + library beside it, which is precisely the "teacher is left + looking at something that is not the presentation" this whole + design is built to prevent. KWin has its own occasions — + a notification, a second output appearing. + + So fullscreen is re-asserted rather than assumed, for as long as + the presentation is running. It stops the moment Escape is + pressed, so this can never fight the teacher's way out. + """ + if self.finished: + return False + + if not (event.new_window_state & Gdk.WindowState.FULLSCREEN): + self.fullscreen() + + return False + + # -- showing a slide ------------------------------------------ + + def _resized(self, _widget, _allocation): + self.show_page() + + def show_page(self): + path = self.presentation.page_image(self.page) + allocation = self.get_allocation() + want = (self.page, allocation.width, allocation.height) + + if want == self._drawn_at: + return + + if not path.exists(): + return + + pixbuf = self._fitted(path, allocation.width, allocation.height) + + if pixbuf is None: + return + + self.image.set_from_pixbuf(pixbuf) + self._drawn_at = want + + # A SLIDE IS ON THE SCREEN, SO THIS IS A PRESENTATION. + # + # Counted here and nowhere earlier. Pressing Present is an + # intention; a viewer that failed to start, a file that could not + # be read and a window that never drew are all not presentations, + # and none of them may buy another thirty days of retention. + if not self.counted: + self.counted = True + self.presentation.mark_presented() + + def _fitted(self, path, width, height): + if width < 2 or height < 2: + return None + + try: + original = GdkPixbuf.Pixbuf.new_from_file(str(path)) + except (GLib.Error, OSError): + return None + + # Letterboxed, never cropped and never stretched. A slide with a + # verse on it cannot lose its edges to fit a television. + ratio = min(width / original.get_width(), + height / original.get_height()) + + return original.scale_simple( + max(1, int(original.get_width() * ratio)), + max(1, int(original.get_height() * ratio)), + GdkPixbuf.InterpType.BILINEAR, + ) + + # -- moving about --------------------------------------------- + + def go(self, delta): + target = self.page + delta + + if target < 1: + return + + if target > self.presentation.pages: + # PAST THE LAST SLIDE IS THE END, AND THE END IS THE LIBRARY. + # + # Not a black "click to exit" slide, and certainly not an + # editor. A teacher who clicks once more than there are + # slides is finished, and being finished means being back + # where they started. + self.finish() + return + + self.page = target + self.show_page() + + def _key(self, _widget, event): + key = event.keyval + forward = ( + Gdk.KEY_Right, Gdk.KEY_Down, Gdk.KEY_space, Gdk.KEY_Page_Down, + Gdk.KEY_KP_Page_Down, Gdk.KEY_Return, Gdk.KEY_KP_Enter, + Gdk.KEY_KP_Right, Gdk.KEY_KP_Down, Gdk.KEY_n, + ) + backward = ( + Gdk.KEY_Left, Gdk.KEY_Up, Gdk.KEY_Page_Up, Gdk.KEY_KP_Page_Up, + Gdk.KEY_BackSpace, Gdk.KEY_KP_Left, Gdk.KEY_KP_Up, Gdk.KEY_p, + ) + + if key in forward: + self.go(1) + elif key in backward: + self.go(-1) + elif key in (Gdk.KEY_Home, Gdk.KEY_KP_Home): + self.page = 1 + self.show_page() + elif key in (Gdk.KEY_End, Gdk.KEY_KP_End): + self.page = self.presentation.pages + self.show_page() + elif key in (Gdk.KEY_Escape, Gdk.KEY_q, Gdk.KEY_F5): + self.finish() + + return True + + def finish(self): + if self.finished: + return True + + self.finished = True + + try: + library.presenting_lock().unlink() + except OSError: + pass + + if self.on_finish is not None: + self.on_finish() + + self.destroy() + + return True + + +class QuickLook(Gtk.Window): + """Look through the slides before showing them to a room. + + Three things a teacher can do here, and they are kept apart on + purpose because conflating any two of them would be wrong: + + browse which slide is on this screen right now; + Use this slide which slide the library card shows; + Present start the slideshow, from the beginning. + + Browsing is not presenting: coming in here, looking through every + slide and leaving again must not mark the session as presented or + move its retention timer by a second. Choosing the picture is not + presenting either, and it does not change where a presentation + starts. + """ + + def __init__(self, presentation, parent, on_close=None, on_present=None): + super().__init__(title=presentation.title) + + self.presentation = presentation + self.on_close = on_close + self.on_present = on_present + self.page = 1 + + self.set_transient_for(parent) + self.set_modal(True) + self.set_default_size(1000, 760) + + outer = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12) + outer.set_border_width(16) + self.add(outer) + + heading = Gtk.Label(label=presentation.title, xalign=0) + heading.get_style_context().add_class("heading") + heading.set_line_wrap(True) + outer.pack_start(heading, False, False, 0) + + self.slide = Gtk.Image() + frame = Gtk.EventBox() + frame.get_style_context().add_class("thumb") + frame.add(self.slide) + outer.pack_start(frame, True, True, 0) + + # Browsing. + browse = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) + browse.set_halign(Gtk.Align.CENTER) + + self.back = Gtk.Button(label="◀ Previous") + self.back.connect("clicked", lambda *_: self.go(-1)) + browse.pack_start(self.back, False, False, 0) + + self.counter = Gtk.Label() + self.counter.get_style_context().add_class("subtle") + browse.pack_start(self.counter, False, False, 12) + + self.forward = Gtk.Button(label="Next ▶") + self.forward.connect("clicked", lambda *_: self.go(1)) + browse.pack_start(self.forward, False, False, 0) + + outer.pack_start(browse, False, False, 0) + + # The three things this window is for. + actions = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) + + self.choose = Gtk.Button(label="Use this slide as the picture") + self.choose.connect("clicked", self._choose) + actions.pack_start(self.choose, False, False, 0) + + actions.pack_start(Gtk.Box(), True, True, 0) + + close = Gtk.Button(label="Back to Presentations") + close.connect("clicked", lambda *_: self.close_quietly()) + actions.pack_start(close, False, False, 0) + + present = Gtk.Button(label="Present") + present.get_style_context().add_class("primary") + present.connect("clicked", self._present) + actions.pack_start(present, False, False, 0) + + outer.pack_start(actions, False, False, 0) + + self.connect("key-press-event", self._key) + self.connect("delete-event", lambda *_: self.close_quietly()) + self.connect("size-allocate", lambda *_: self.show_page(False)) + + self._drawn_at = (0, 0, 0) + self.show_page() + + def show_page(self, force=True): + allocation = self.slide.get_allocation() + width = max(320, allocation.width or 900) + want = (self.page, width, 0) + + if want == self._drawn_at and not force: + return + + path = self.presentation.page_image(self.page) + pixbuf = scaled_pixbuf(path, width) if path.exists() else None + + if pixbuf is not None: + self.slide.set_from_pixbuf(pixbuf) + self._drawn_at = want + + total = self.presentation.pages + chosen = self.presentation.thumbnail_page + note = " · this is the library picture" if self.page == chosen else "" + self.counter.set_text(f"Slide {self.page} of {total}{note}") + + self.back.set_sensitive(self.page > 1) + self.forward.set_sensitive(self.page < total) + self.choose.set_sensitive(self.page != chosen) + + def go(self, delta): + target = self.page + delta + + if 1 <= target <= self.presentation.pages: + self.page = target + self.show_page() + + def _choose(self, *_): + # Writes the chosen slide and nothing else. Not a presentation, + # and not a change to where the slideshow starts. + self.presentation.set_thumbnail_page(self.page) + self.show_page() + + if self.on_close is not None: + self.on_close() + + def _present(self, *_): + self.destroy() + + if self.on_present is not None: + self.on_present(self.presentation) + + def close_quietly(self): + """Leave without having presented anything.""" + self.destroy() + + if self.on_close is not None: + self.on_close() + + return True + + def _key(self, _widget, event): + key = event.keyval + + if key in (Gdk.KEY_Right, Gdk.KEY_Down, Gdk.KEY_Page_Down, + Gdk.KEY_space): + self.go(1) + elif key in (Gdk.KEY_Left, Gdk.KEY_Up, Gdk.KEY_Page_Up): + self.go(-1) + elif key == Gdk.KEY_Escape: + self.close_quietly() + else: + return False + + return True + + +class Library(Gtk.Window): + """The window the panel button opens.""" + + def __init__(self): + super().__init__(title="Presentations") + + self.set_default_size(1180, 820) + self.presenter = None + self._signature = None + + self._apply_style() + + outer = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=8) + outer.set_border_width(20) + self.add(outer) + + heading = Gtk.Label(label="Presentations", xalign=0) + heading.get_style_context().add_class("heading") + outer.pack_start(heading, False, False, 0) + + self.note = Gtk.Label(xalign=0) + self.note.get_style_context().add_class("subtle") + outer.pack_start(self.note, False, False, 0) + + scroller = Gtk.ScrolledWindow() + scroller.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) + outer.pack_start(scroller, True, True, 8) + + self.grid = Gtk.FlowBox() + self.grid.set_valign(Gtk.Align.START) + self.grid.set_max_children_per_line(4) + self.grid.set_min_children_per_line(1) + self.grid.set_selection_mode(Gtk.SelectionMode.NONE) + self.grid.set_row_spacing(16) + self.grid.set_column_spacing(16) + self.grid.set_homogeneous(True) + scroller.add(self.grid) + + self.connect("key-press-event", self._key) + self.connect("destroy", lambda *_: Gtk.main_quit()) + + self.refresh() + GLib.timeout_add_seconds(REFRESH_SECONDS, self._tick) + + def _apply_style(self): + css = Gtk.CssProvider() + css.load_from_data(STYLE.format(**load_colours()).encode("utf-8")) + Gtk.StyleContext.add_provider_for_screen( + self.get_screen(), css, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) + + # -- the wall of cards ---------------------------------------- + + def _tick(self): + self.refresh() + return True + + def signature(self, presentations): + """What the library looks like, so it is only rebuilt when it changes. + + Rebuilding a FlowBox under a teacher's pointer every two seconds + would make the buttons unclickable. + """ + return tuple( + (p.id, p.state, p.pages, p.thumbnail_page, p.title) + for p in presentations + ) + + def refresh(self): + presentations = library.library() + signature = self.signature(presentations) + + if signature == self._signature: + return + + self._signature = signature + + for child in self.grid.get_children(): + self.grid.remove(child) + + if not presentations: + self.note.set_text( + "Download a presentation in Chrome and it will appear here.") + empty = Gtk.Label( + label="Nothing here yet.\n\n" + "Download a PowerPoint or PDF in Chrome, and it will " + "appear on this screen by itself.") + empty.get_style_context().add_class("empty") + empty.set_justify(Gtk.Justification.CENTER) + self.grid.add(empty) + else: + # Three states, and a file that could not be opened is not + # the same as one still being got ready. Telling a teacher + # something is "being prepared" when it never will be is how + # somebody ends up waiting through a Bible study for it. + ready = sum(1 for p in presentations if p.ready) + broken = sum(1 for p in presentations if p.failed) + working = len(presentations) - ready - broken + + parts = [f"{ready} ready to present"] + + if working: + parts.append(f"{working} still being prepared") + + if broken: + parts.append(f"{broken} could not be opened") + + self.note.set_text(", ".join(parts) + ".") + + for presentation in presentations: + self.grid.add(self.card(presentation)) + + self.grid.show_all() + + def card(self, presentation): + box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10) + box.get_style_context().add_class("card") + box.set_size_request(CARD_WIDTH, -1) + + picture = Gtk.Image() + picture.get_style_context().add_class("thumb") + pixbuf = None + + if presentation.thumbnail.exists(): + pixbuf = scaled_pixbuf(presentation.thumbnail, CARD_WIDTH - 28) + + if pixbuf is not None: + picture.set_from_pixbuf(pixbuf) + else: + picture.set_from_icon_name("view-presentation", Gtk.IconSize.DIALOG) + picture.set_pixel_size(96) + + box.pack_start(picture, False, False, 0) + + title = Gtk.Label(label=presentation.title, xalign=0) + title.get_style_context().add_class("card-title") + title.set_line_wrap(True) + title.set_max_width_chars(26) + box.pack_start(title, False, False, 0) + + note = Gtk.Label(xalign=0) + note.get_style_context().add_class("card-note") + box.pack_start(note, False, False, 0) + + buttons = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=8) + + if presentation.ready: + note.set_text(f"{presentation.pages} slides") + + present = Gtk.Button(label="Present") + present.get_style_context().add_class("primary") + present.connect("clicked", + lambda *_: self.start_presenting(presentation)) + buttons.pack_start(present, True, True, 0) + + look = Gtk.Button(label="Quick Look") + look.connect("clicked", lambda *_: self.quick_look(presentation)) + buttons.pack_start(look, True, True, 0) + elif presentation.failed: + # SHORT, AND IN WORDS A TEACHER CAN ACT ON. + # + # Never the converter's error text, never a path, never a + # terminal. The one useful fact is that their own download is + # still where they left it. + note.set_text("This file could not be opened.\n" + "Your download in Chrome is still there.") + note.set_line_wrap(True) + else: + note.set_text("Getting this ready…") + + remove = Gtk.Button(label="Remove") + remove.get_style_context().add_class("danger") + remove.connect("clicked", lambda *_: self.remove(presentation)) + buttons.pack_start(remove, True, True, 0) + + box.pack_start(buttons, False, False, 0) + + return box + + # -- what the buttons do -------------------------------------- + + def start_presenting(self, presentation, start_page=1): + if not presentation.ready: + return + + first = presentation.page_image(start_page) + + if not first.exists(): + self.trouble(presentation, + "This presentation is not ready yet.") + return + + try: + lock = library.presenting_lock() + lock.parent.mkdir(parents=True, exist_ok=True) + lock.write_text(presentation.id) + except OSError: + # A lock that could not be written only costs the cleanup its + # politeness. It must not stop a teacher presenting. + pass + + self.presenter = Presenter( + presentation, start_page, on_finish=self._presented) + self.presenter.show_all() + self.presenter.present() + + def _presented(self): + self.presenter = None + self._signature = None + self.refresh() + self.present_window() + + def present_window(self): + self.show_all() + self.present() + + def quick_look(self, presentation): + if not presentation.ready: + return + + window = QuickLook( + presentation, self, + on_close=self._looked, + on_present=lambda p: self.start_presenting(p), + ) + window.show_all() + + def _looked(self): + # Coming back from Quick Look is not a presentation. The only + # thing that may have changed is which slide the card shows. + self._signature = None + self.refresh() + + def remove(self, presentation): + dialog = Gtk.MessageDialog( + transient_for=self, + modal=True, + message_type=Gtk.MessageType.QUESTION, + buttons=Gtk.ButtonsType.NONE, + text=f"Remove “{presentation.title}”?", + ) + dialog.format_secondary_text( + "It will be taken off this screen.\n" + "Your download in Chrome is not affected.") + dialog.add_button("Keep it", Gtk.ResponseType.CANCEL) + dialog.add_button("Remove", Gtk.ResponseType.OK) + dialog.set_default_response(Gtk.ResponseType.CANCEL) + + answer = dialog.run() + dialog.destroy() + + if answer != Gtk.ResponseType.OK: + return + + shutil.rmtree(presentation.directory, ignore_errors=True) + self._signature = None + self.refresh() + + def trouble(self, presentation, message): + dialog = Gtk.MessageDialog( + transient_for=self, + modal=True, + message_type=Gtk.MessageType.INFORMATION, + buttons=Gtk.ButtonsType.OK, + text=presentation.title, + ) + dialog.format_secondary_text(message) + dialog.run() + dialog.destroy() + + def _key(self, _widget, event): + if event.keyval == Gdk.KEY_Escape: + # Escape in the library closes the library, which is the same + # thing it does everywhere else in this room. + self.destroy() + return True + + return False + + +def main(): + GLib.set_prgname(APP_ID) + GLib.set_application_name("Presentations") + + # A device that does not offer Presentations does not open them. The + # panel has no button, so nothing should reach here; saying it out + # loud is for the technician who ran the command by hand. + if not feature(read_device_config(), "PRESENTATIONS_ENABLED"): + print("classroom-presentations: PRESENTATIONS_ENABLED is false on " + "this device; not starting", flush=True) + return 0 + + window = Library() + window.show_all() + + Gtk.main() + + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/scripts/classroom-wonderink b/scripts/classroom-wonderink index a2d7dbb..e9d2378 100755 --- a/scripts/classroom-wonderink +++ b/scripts/classroom-wonderink @@ -62,7 +62,7 @@ sys.path.insert( os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "lib"), ) -from classroom_config import enabled, read_device_config # noqa: E402 +from classroom_config import feature, read_device_config # noqa: E402 HOME_PAGE = "https://app.wonderink.org/" @@ -682,7 +682,11 @@ def main(): # A device that has no Wonder Ink has no Wonder Ink. The panel does not # offer it, so nothing should reach here; saying it out loud is for the # technician who ran the command by hand and wants to know why. - if not enabled(config, "WONDERINK_ENABLED", default=True): + # feature(), not enabled(..., default=True). The default belongs in + # classroom_config.FEATURES with every other application's, so that + # the panel and the command can never disagree about whether a device + # offers this — which is the whole reason that table exists. + if not feature(config, "WONDERINK_ENABLED"): say("WONDERINK_ENABLED is false on this device; not starting") return 0 diff --git a/systemd/user/ekklesia-classroom-presentations.service b/systemd/user/ekklesia-classroom-presentations.service new file mode 100644 index 0000000..f1b10b6 --- /dev/null +++ b/systemd/user/ekklesia-classroom-presentations.service @@ -0,0 +1,28 @@ +[Unit] +Description=Ekklesia Classroom presentation import +Documentation=file:///usr/local/bin/classroom-presentation-import +# Nothing graphical: it copies, converts and renders files. It is a user +# service rather than a system one because the downloads it watches and +# the library it fills both belong to the classroom account, and a root +# service writing into a teacher's home would have to be told about every +# one of those permissions. +PartOf=graphical-session.target + +[Service] +ExecStart=/usr/local/bin/classroom-presentation-import +# It exits 0 immediately on a device with PRESENTATIONS_ENABLED=false, and +# on-failure means such a device is left alone rather than restarted in a +# loop forever. A device that does have Presentations gets the watcher +# back if it ever dies, because a teacher whose download never appears has +# no way at all to find out why. +Restart=on-failure +RestartSec=10 +Slice=session.slice +# LibreOffice converting a large deck must never be what a teacher notices +# about the machine. The room's own applications come first; this is the +# only thing here that is allowed to take a while. +Nice=10 +IOSchedulingClass=idle + +[Install] +WantedBy=plasma-workspace.target diff --git a/tests/test-classroom-desktop-layout.sh b/tests/test-classroom-desktop-layout.sh index 22365a0..3dc54e7 100755 --- a/tests/test-classroom-desktop-layout.sh +++ b/tests/test-classroom-desktop-layout.sh @@ -85,8 +85,16 @@ check("a desktop can have Wonder Ink taken away", check("and keeps everything else", desktop_no_ink["DVD"] is True and desktop_no_ink["PARENT_CALL"] is True) -check("an existing room that has never heard of these keeps them all", - all(module.wanted({}).values()), str(module.wanted({}))) +unset = module.wanted({}) +check("an existing room that has never heard of these keeps all three", + unset["WONDERINK"] and unset["DVD"] and unset["PARENT_CALL"], + str(unset)) +# The one that must NOT follow that rule. Every existing classroom has +# Wonder Ink, a drive and Parent Call, so an upgrade has to leave all +# three on. No existing classroom has Presentations, so an upgrade has to +# leave it off — a new button on a bar nobody asked for is a support call. +check("but Presentations is off until a device asks for it", + unset["PRESENTATIONS"] is False, str(unset)) print("3. a drive can only ever take the player away") @@ -126,13 +134,18 @@ check("and an unconfigured machine keeps every application", print("5. the bar that comes out, evaluated in node") STUB = r""" const fs = require("fs"); -const captured = {widgets: [], config: {}}; +const captured = {widgets: [], config: {}, launchers: []}; let current = null; function makeWidget(type) { const w = { type: type, currentConfigGroup: [], - writeConfig: function (k, v) { captured.config[type + "." + k] = String(v); }, + writeConfig: function (k, v) { + captured.config[type + "." + k] = String(v); + // Quick Launch widgets share a config key, so the last one + // written would otherwise be the only one anybody could see. + if (k === "launcherUrls") { captured.launchers.push(String(v)); } + }, reloadConfig: function () {} }; captured.widgets.push(type); @@ -172,8 +185,15 @@ else: check("a classroom gets Wonder Ink, the browser and the player, in order", every and every["config"].get(LAUNCH) == f"{INK},{WEB},{DISC}", (every or {}).get("config", {}).get(LAUNCH, why)) + CALL = "file:///usr/share/applications/ekklesia-parent-call.desktop" + HELP = "file:///usr/share/applications/ekklesia-manual.desktop" + check("and Parent Call in the corner", - every and "org.kde.plasma.quicklaunch" in every["widgets"]) + every and CALL in every["launchers"], + str((every or {}).get("launchers"))) + check("and Help beside it", + every and HELP in every["launchers"], + str((every or {}).get("launchers"))) no_ink, why = bar({"WONDERINK_ENABLED": "false"}) check("a Bible study desktop has the browser first and no gap", @@ -188,8 +208,50 @@ else: bible and bible["config"].get(LAUNCH) == WEB, (bible or {}).get("config", {}).get(LAUNCH, why)) check("with no Parent Call button on it", - bible and "org.kde.plasma.quicklaunch" not in bible["widgets"], - str((bible or {}).get("widgets"))) + bible and CALL not in bible["launchers"], + str((bible or {}).get("launchers"))) + # Help is not optional. A teacher who needs the manual is by + # definition one who does not know where to look, so every room has + # it — what differs is which pages it opens on. + check("but Help is still there, because every room has a manual", + bible and HELP in bible["launchers"], + str((bible or {}).get("launchers"))) + SLIDES = "applications:ekklesia-presentations.desktop" + + # THE DOCK ORDER IS THE THING NOT TO BREAK. + # + # Every existing room has Wonder Ink, the browser and the player in + # that order, and teachers have been pressing them in that order for + # months. Presentations is appended, so all three keep their place on + # every machine that upgrades into this release. + module.has_optical_drive = lambda: True + slides, why = bar({"PRESENTATIONS_ENABLED": "true"}) + check("Presentations goes on the END of the row, after the player", + slides and slides["config"].get(LAUNCH) + == f"{INK},{WEB},{DISC},{SLIDES}", + (slides or {}).get("config", {}).get(LAUNCH, why)) + + without, why = bar({"PRESENTATIONS_ENABLED": "false"}) + check("and is absent entirely when the device does not offer it", + without and SLIDES not in without["config"].get(LAUNCH, ""), + (without or {}).get("config", {}).get(LAUNCH, why)) + check("which leaves the other three exactly where they were", + without and without["config"].get(LAUNCH) == f"{INK},{WEB},{DISC}", + (without or {}).get("config", {}).get(LAUNCH, why)) + + # The prayer-room laptop: the browser and Presentations, nothing else. + module.has_optical_drive = lambda: False + study, why = bar({"PRESENTATIONS_ENABLED": "true", + "WONDERINK_ENABLED": "false", + "PARENT_CALL_ENABLED": "false", + "DEVICE_TYPE": "laptop"}) + check("the Bible study laptop gets the browser and Presentations", + study and study["config"].get(LAUNCH) == f"{WEB},{SLIDES}", + (study or {}).get("config", {}).get(LAUNCH, why)) + check("and still no Parent Call on it", + study and CALL not in study["launchers"], + str((study or {}).get("launchers"))) + check("and the status corner is untouched", bible and "org.kde.plasma.volume" in bible["widgets"] and "org.kde.plasma.digitalclock" in bible["widgets"] @@ -227,12 +289,28 @@ print("7. a disabled application does not start either") # talked into running it by a stale desktop entry or a technician's # muscle memory. for script, setting in (("classroom-wonderink", "WONDERINK_ENABLED"), - ("classroom-parent-call", "PARENT_CALL_ENABLED")): + ("classroom-parent-call", "PARENT_CALL_ENABLED"), + ("classroom-presentations", "PRESENTATIONS_ENABLED"), + ("classroom-presentation-import", + "PRESENTATIONS_ENABLED")): text = (root / "scripts" / script).read_text() check(f"{script} refuses when {setting} is false", setting in text and "not starting" in text) - check(f"{script} defaults to starting, so existing rooms are unaffected", - 'default=True' in text or 'feature(' in text) + check(f"{script} asks the shared helper rather than reading the file", + "feature(" in text and "read_device_config()" in text) + +# And each of them defaults the way its own room needs, which is not the +# same answer for all four. Asserting one rule for all of them would pass +# for the wrong reason on the one that differs. +from classroom_config import feature as _feature # noqa: E402 + +for setting, default, why in ( + ("WONDERINK_ENABLED", True, "every existing classroom has it"), + ("DVD_ENABLED", True, "every existing classroom has it"), + ("PARENT_CALL_ENABLED", True, "every existing classroom has it"), + ("PRESENTATIONS_ENABLED", False, "no existing classroom has it")): + check(f"{setting} defaults to {default} — {why}", + _feature({}, setting) is default) print() print(f"{passed} passed, {failed} failed") diff --git a/tests/test-classroom-presentations.sh b/tests/test-classroom-presentations.sh new file mode 100755 index 0000000..4bcda51 --- /dev/null +++ b/tests/test-classroom-presentations.sh @@ -0,0 +1,263 @@ +#!/bin/bash +# The Presentations library: what it imports, what it refuses, what it +# keeps and what it is never allowed to delete. +# +# No LibreOffice and no poppler here. Those are exercised by the lab and +# by the release validator against a real Debian; this is the part that +# has to be right whatever is installed — when a download counts as +# finished, whose files may be touched, what a teacher's choice of +# thumbnail does and does not change, and which of the two retention +# clocks is running. +set -uo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" + +PYTHONPATH="$ROOT/lib" python3 - "$ROOT" <<'PY' +import os +import shutil +import sys +import tempfile +import time +from datetime import timedelta +from pathlib import Path + +root = Path(sys.argv[1]) +sys.path.insert(0, str(root / "lib")) + +import classroom_presentations as library + +passed = failed = 0 + + +def check(label, condition, detail=""): + global passed, failed + if condition: + print(f" ok {label}") + passed += 1 + else: + print(f" FAIL {label}") + if detail: + print(f" {detail}") + failed += 1 + + +work = Path(tempfile.mkdtemp(prefix="classroom-presentations-")) +downloads = work / "Downloads" +wonderink = downloads / "Wonder Ink" +shelf = work / "library" +wonderink.mkdir(parents=True) +shelf.mkdir(parents=True) + + +def download(name, contents="x" * 400, age=60): + """A file sitting in Downloads, finished `age` seconds ago.""" + path = downloads / name + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(contents) + when = time.time() - age + os.utime(path, (when, when)) + return path + + +def entry(**data): + """A presentation in the library, without running an import.""" + directory = shelf / data.get("id", "one") + directory.mkdir(parents=True, exist_ok=True) + base = { + "id": directory.name, + "state": "ready", + "title": "A session", + "pages": 10, + "thumbnail_page": 1, + "imported_at": library.stamp(), + "last_presented_at": None, + "times_presented": 0, + } + base.update(data) + presentation = library.Presentation(directory, base) + presentation.save() + (directory / "slides.pdf").write_text("%PDF-1.4") + return presentation + + +print("1. a download that has finished, and ones that have not") +done = download("Session 7 - Romans.pptx") +check("a settled PowerPoint is importable", library.importable(done)) + +arriving = download("Still arriving.pptx") +partial = downloads / "Still arriving.pptx.crdownload" +partial.write_text("half") +check("one with a .crdownload beside it is not", + not library.importable(arriving), + "Chrome renames the .crdownload away when the transfer completes") + +check("and the .crdownload itself is never a candidate", + not library.importable(partial)) + +fresh = download("Just landed.pdf", age=0) +check("one still being written is not", + not library.importable(fresh), + "a file copied from a USB stick has no .crdownload to go by") + +check("something that is not a presentation is not", + not library.importable(download("notes.txt"))) + +empty = download("Nothing.pdf", contents="", age=60) +check("a nought-byte file is not", not library.importable(empty)) + +print("2. Wonder Ink's worksheets are not presentations") +worksheet = wonderink / "Colouring page.pdf" +worksheet.write_text("%PDF-1.4" + "x" * 400) +os.utime(worksheet, (time.time() - 60, time.time() - 60)) +check("a file in the Wonder Ink folder is recognised as Wonder Ink's", + library.within_wonderink(worksheet, downloads)) +check("and one beside it in Downloads is not", + not library.within_wonderink(done, downloads)) + +names = [p.name for p in library.candidates(downloads)] +check("so it is not offered for import", "Colouring page.pdf" not in names, + str(names)) +check("the finished session is", "Session 7 - Romans.pptx" in names, str(names)) +check("and nothing unfinished is", + "Still arriving.pptx" not in names and "Just landed.pdf" not in names, + str(names)) + +print("3. titles a teacher would recognise") +check("an ordinary name is kept", + library.readable_title("Session 7 - Romans.pptx") == "Session 7 - Romans", + library.readable_title("Session 7 - Romans.pptx")) +check("underscores become spaces", + library.readable_title("Session_7_Romans.pdf") == "Session 7 Romans", + library.readable_title("Session_7_Romans.pdf")) +check("a browser's duplicate counter goes", + library.readable_title("Bible Study (1).pdf") == "Bible Study", + library.readable_title("Bible Study (1).pdf")) +check("a percent-escaped space is decoded", + library.readable_title("Session%207.pdf") == "Session 7", + library.readable_title("Session%207.pdf")) +hashed = library.readable_title( + "a4f39c2e91bb4d7e.pdf", "Session 7 of the autumn study\nmore") +check("a hash falls back to the document's own first words", + hashed == "Session 7 of the autumn study", hashed) +check("and something with no name at all still gets one", + library.readable_title("...pdf", "") == "Presentation", + library.readable_title("...pdf", "")) + +print("4. two downloads of the same name are two presentations") +first = entry(id="first", title="Session 7") +second = entry(id="second", title="Session 7") +# The bug this replaces: excluding the import being named BY TITLE also +# removed the other presentation's identical title from the set, so a +# PDF and a PPTX of one session both came out called "Session 7". +taken = library.titles_in_use(shelf, exclude="second") +check("the other presentation's title is still in the way", + "Session 7" in taken, str(taken)) +check("so the second gets a title of its own", + library.unique_title("Session 7", taken) == "Session 7 (2)", + library.unique_title("Session 7", taken)) +check("and a name nothing else has is left alone", + library.unique_title("Session 8", taken) == "Session 8") +shutil.rmtree(shelf / "first") +shutil.rmtree(shelf / "second") + +print("5. the thumbnail is the teacher's choice, and only that") +# The first slide of a Bible study session is a generic opening shared by +# every session; the one that names the session is usually the second. +p = entry(id="thumb", pages=12) +before = dict(p.data) +p.set_thumbnail_page(2) +after = library.load(shelf / "thumb") +check("the chosen slide is remembered", after.thumbnail_page == 2, + str(after.thumbnail_page)) +check("it survives being read back from disk, so it survives a restart", + library.load(shelf / "thumb").thumbnail_page == 2) +check("choosing it did not mark the session as presented", + after.last_presented_at is None and after.times_presented == 0) +check("and did not move the retention clock", + after.data["imported_at"] == before["imported_at"] + and after.data.get("last_presented_at") is None) +check("a slide past the end is clamped rather than stored", + entry(id="thumb2", pages=5, thumbnail_page=99).thumbnail_page == 5) +check("and a nonsense one does not crash the card", + entry(id="thumb3", pages=5, thumbnail_page="banana").thumbnail_page == 1) + +print("6. the two retention clocks") +old = library.now() - timedelta(days=181) +recent = library.now() - timedelta(days=100) + +never = entry(id="never", imported_at=library.stamp(old)) +check("never presented, imported over 180 days ago, is expired", + never.expired(), str(never.expires_at())) + +young = entry(id="young", imported_at=library.stamp(recent)) +check("never presented but only 100 days old is not", + not young.expired(), str(young.expires_at())) + +shown = entry(id="shown", + imported_at=library.stamp(old), + last_presented_at=library.stamp(library.now() - timedelta(days=2)), + times_presented=3) +check("presented two days ago is kept, however old the import is", + not shown.expired(), + "presenting has to start the 30-day clock and stop the 180-day one") + +stale = entry(id="stale", + imported_at=library.stamp(old), + last_presented_at=library.stamp(library.now() - timedelta(days=31)), + times_presented=1) +check("presented 31 days ago is expired", stale.expired()) + +print("7. presenting is the only thing that resets the clock") +p = entry(id="counted", pages=4) +check("a fresh import has never been presented", + p.last_presented_at is None and p.times_presented == 0) +p.mark_presented() +reread = library.load(shelf / "counted") +check("presenting is recorded", reread.last_presented_at is not None) +check("and counted", reread.times_presented == 1) +first_due = reread.expires_at() +time.sleep(1.1) +reread.mark_presented() +again = library.load(shelf / "counted") +check("presenting again starts the thirty days over", + again.expires_at() > first_due, f"{first_due} -> {again.expires_at()}") +check("and counts again", again.times_presented == 2) + +print("8. an import that was interrupted is not shown to a teacher") +half = entry(id="half", state="importing") +check("it is in the library's own list", + any(x.id == "half" for x in library.library(shelf))) +check("but it is not ready, so no card offers Present", + not library.load(shelf / "half").ready) +broken = shelf / "broken" +broken.mkdir() +(broken / "presentation.json").write_text("{ this is not json") +check("a truncated metadata file is skipped rather than crashing the library", + all(x.id != "broken" for x in library.library(shelf)), + "a card a teacher cannot open is worse than no card") + +print("9. the presenting lock cannot outlive a reboot") +check("it lives in the runtime directory", + "/run" in str(library.presenting_lock()) + or str(library.presenting_lock()).startswith("/tmp"), + str(library.presenting_lock())) + +print("10. the ledger remembers a download after its presentation is gone") +mark = library.fingerprint(done) +library.remember(mark, "some-id", shelf) +check("a fingerprint is path, size and time", + mark is not None and str(done.resolve()) in mark, str(mark)) +check("it is written down", library.ledger(shelf).get(mark) == "some-id") +check("so Remove means removed, not removed until the next scan", + mark in library.ledger(shelf)) +touched = download("Session 7 - Romans.pptx", contents="y" * 900) +check("but re-downloading the same session is a new presentation", + library.fingerprint(touched) != mark, + "a different size or time is a different download") + +shutil.rmtree(work, ignore_errors=True) + +print() +print(f"{passed} passed, {failed} failed") +raise SystemExit(1 if failed else 0) +PY diff --git a/tools/lab/make-presentation b/tools/lab/make-presentation new file mode 100755 index 0000000..1bf2534 --- /dev/null +++ b/tools/lab/make-presentation @@ -0,0 +1,142 @@ +#!/usr/bin/env python3 + +"""Build a presentation to test the classroom's library with. + +Representative test material, NOT the pastor's own files. The shape is +copied from the real Bible study decks and nothing else about them is: + + slide 1 a generic opening, the same on every session + slide 2 the one that names the session + slide 3+ the session's content + +That first pair is the whole reason Quick Look lets a teacher choose +which slide becomes the library thumbnail. A library that assumed slide +one would show every session under the same picture. + +Writes a flat ODF presentation, which LibreOffice then converts to +whatever the test needs: + + tools/lab/make-presentation --slides 12 --session 7 out.fodp + soffice --headless --convert-to pptx out.fodp + soffice --headless --convert-to pdf out.fodp +""" + +import argparse +import html +import sys + +HEADER = """ + + + + + + + + + + + + + + +""" + +FOOTER = """ + + +""" + +PAGE = """ + + {title} + + + {body} + + +""" + +# Deliberately ordinary words. Nothing here is anybody's lesson. +POINTS = ( + "Read the passage aloud together", + "What does this tell us about God?", + "Where do you see this in your own week?", + "One thing to carry into Sunday", +) + + +def paragraphs(lines): + return "".join( + f"{html.escape(line)}" for line in lines + ) + + +def build(slides, session): + pages = [] + + # Slide 1 — the generic opening every session shares. + pages.append(PAGE.format( + name="page1", + title=paragraphs(["Wednesday Bible Study"]), + body=paragraphs(["River of Glory", "Welcome"]), + )) + + # Slide 2 — the one a teacher has to be able to pick as the thumbnail. + pages.append(PAGE.format( + name="page2", + title=paragraphs([f"Session {session}"]), + body=paragraphs([f"Session {session} of the autumn study", + "Tonight's passage and questions"]), + )) + + for number in range(3, slides + 1): + pages.append(PAGE.format( + name=f"page{number}", + title=paragraphs([f"Point {number - 2}"]), + body=paragraphs([ + POINTS[(number - 3) % len(POINTS)], + f"(slide {number} of {slides})", + ]), + )) + + return HEADER + "".join(pages) + FOOTER + + +def main(): + parser = argparse.ArgumentParser( + description="Build representative Bible study test material.") + parser.add_argument("output", help="where to write the .fodp") + parser.add_argument("--slides", type=int, default=10, + help="how many slides in total (minimum 2)") + parser.add_argument("--session", type=int, default=7, + help="the session number slide 2 announces") + arguments = parser.parse_args() + + if arguments.slides < 2: + print("a test deck needs at least the opening and the session slide", + file=sys.stderr) + return 2 + + with open(arguments.output, "w", encoding="utf-8") as handle: + handle.write(build(arguments.slides, arguments.session)) + + print(f"{arguments.output}: {arguments.slides} slides, session " + f"{arguments.session}") + return 0 + + +if __name__ == "__main__": + sys.exit(main())