diff --git a/TODO.md b/TODO.md index 260513d..c94a47b 100644 --- a/TODO.md +++ b/TODO.md @@ -1,11 +1,6 @@ # TODO -- [x] Standardise all links (including header) to be heavy (font-weight: 600) and add violet accent color on hover -- [x] Remove border-radius from aria-current nav links, drop a:focus-visible ring in header, consolidate border-bottom/padding in shared header.css -- [x] Admin nav-logo: use grid layout with SVG + text horizontally aligned and vertically centered -- [x] repertoire.css: .rep-entry → step-1, years col → step-3, col h2 → step-1 -- [x] Rework tfe.php layout: row1 author above title, row2 meta+synopsis 2-col grid, row3 flex files -- [x] Contacts: allow empty name OR empty role (not both) when saving a contact -- [x] Sidebar links: make "site de l'erg" and "code source" editable via admin panel -- [x] Admin contact blocks: grid layout (3 columns: Nom, Email, Lien) -- [x] Admin contacts: bouton supprimer un contact avec réindexation automatique +- [x] Ajouter `PeerTubeService::deleteVideo()` pour supprimer une vidéo via l'API PeerTube +- [x] Modifier `deleteThesisFileToTrash()` pour appeler `deleteVideo()` quand `file_path` commence par `peertube_ids:` +- [x] Modifier `hardDeleteThesis()` pour supprimer les vidéos PeerTube associées +- [ ] Commit + jj new diff --git a/app/src/Controllers/ThesisFileHandler.php b/app/src/Controllers/ThesisFileHandler.php index ad52221..8cc6851 100644 --- a/app/src/Controllers/ThesisFileHandler.php +++ b/app/src/Controllers/ThesisFileHandler.php @@ -1244,6 +1244,9 @@ trait ThesisFileHandler return; } if (str_starts_with($filePath, 'peertube_ids:')) { + $uuid = substr($filePath, strlen('peertube_ids:')); + require_once __DIR__ . '/../PeerTubeService.php'; + PeerTubeService::deleteVideo($this->db, $uuid); return; } diff --git a/app/src/Database.php b/app/src/Database.php index 033307c..638fea1 100644 --- a/app/src/Database.php +++ b/app/src/Database.php @@ -2351,7 +2351,16 @@ class Database $storageRoot = defined('STORAGE_ROOT') ? STORAGE_ROOT : '/var/www/xamxam/storage'; foreach ($files as $file) { $fp = $file['file_path'] ?? ''; - if ($fp === '' || str_starts_with($fp, 'http://') || str_starts_with($fp, 'https://') || str_starts_with($fp, 'peertube_ids:')) { + if ($fp === '') { + continue; + } + if (str_starts_with($fp, 'http://') || str_starts_with($fp, 'https://')) { + continue; + } + if (str_starts_with($fp, 'peertube_ids:')) { + $uuid = substr($fp, strlen('peertube_ids:')); + require_once __DIR__ . '/PeerTubeService.php'; + PeerTubeService::deleteVideo($this, $uuid); continue; } $abs = $storageRoot . '/' . $fp; diff --git a/app/src/PeerTubeService.php b/app/src/PeerTubeService.php index bb3024b..c0e008b 100644 --- a/app/src/PeerTubeService.php +++ b/app/src/PeerTubeService.php @@ -265,6 +265,43 @@ class PeerTubeService return rtrim($s['instance_url'], '/') . '/videos/watch/' . $uuid; } + // ------------------------------------------------------------------------- + // Delete + // ------------------------------------------------------------------------- + + /** + * Delete a video from PeerTube by UUID or shortUUID. + * + * DELETE /api/v1/videos/{uuid} + * + * @return bool true on success, false on failure + */ + public static function deleteVideo(Database $db, string $uuid): bool + { + $s = self::getSettings($db); + if ($s['instance_url'] === '') { + error_log('PeerTubeService::deleteVideo: instance not configured'); + return false; + } + try { + $token = self::obtainToken($s); + $url = rtrim($s['instance_url'], '/') . '/api/v1/videos/' . urlencode($uuid); + $resp = self::httpRequest($url, 'DELETE', [ + 'headers' => ['Authorization' => 'Bearer ' . $token], + 'timeout' => 30, + ]); + if ($resp['status'] === 204 || $resp['status'] === 200) { + error_log('PeerTubeService: deleted video ' . $uuid); + return true; + } + error_log('PeerTubeService::deleteVideo: unexpected status ' . $resp['status'] . ' for ' . $uuid . ' | body=' . substr($resp['body'], 0, 300)); + return false; + } catch (\Throwable $e) { + error_log('PeerTubeService::deleteVideo failed: ' . $e->getMessage()); + return false; + } + } + // ------------------------------------------------------------------------- // Channel resolution // -------------------------------------------------------------------------