mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 16:19:19 +02:00
feat: PeerTube integration — alternate audio/video labels, FilePond pools, shared SMTP credentials, channel by name, test button, resumable upload, embed improvements, fix alt labels/curl_close/deprecation
This commit is contained in:
40
app/public/admin/actions/peertube-test.php
Normal file
40
app/public/admin/actions/peertube-test.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* peertube-test.php
|
||||
*
|
||||
* HTMX endpoint: tests PeerTube connectivity using the form's current values.
|
||||
* Reads POST fields, performs a temporary settings update, tests, then returns
|
||||
* an HTMX fragment with the result.
|
||||
*/
|
||||
require_once __DIR__ . '/../../../bootstrap.php';
|
||||
require_once __DIR__ . '/../../../src/AdminAuth.php';
|
||||
AdminAuth::requireLogin();
|
||||
|
||||
require_once APP_ROOT . '/src/Database.php';
|
||||
require_once APP_ROOT . '/src/SmtpRelay.php';
|
||||
require_once APP_ROOT . '/src/PeerTubeService.php';
|
||||
|
||||
if (!isset($_POST['csrf_token'], $_SESSION['csrf_token'])
|
||||
|| !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) {
|
||||
http_response_code(403);
|
||||
echo '<span style="color:var(--color-error);">Token CSRF invalide.</span>';
|
||||
exit;
|
||||
}
|
||||
|
||||
$db = new Database();
|
||||
|
||||
// Save current settings so we can test with the form values
|
||||
$data = [
|
||||
'instance_url' => $_POST['peertube_instance_url'] ?? '',
|
||||
'channel_name' => $_POST['peertube_channel_name'] ?? '',
|
||||
'privacy' => $_POST['peertube_privacy'] ?? 1,
|
||||
];
|
||||
PeerTubeService::updateSettings($db, $data);
|
||||
|
||||
$test = PeerTubeService::test($db);
|
||||
|
||||
if ($test['ok']) {
|
||||
echo '<span style="color:var(--color-success);">✓ Connexion réussie — authentification et résolution de la chaîne OK.</span>';
|
||||
} else {
|
||||
echo '<span style="color:var(--color-error);">✗ ' . htmlspecialchars($test['error']) . '</span>';
|
||||
}
|
||||
@@ -138,17 +138,12 @@ if ($section === 'formulaire_restrictions') {
|
||||
$enabled = isset($_POST['peertube_upload_enabled']) ? '1' : '0';
|
||||
$db->setSetting('peertube_upload_enabled', $enabled);
|
||||
|
||||
// Credentials — only overwrite password when user typed something
|
||||
// PeerTube-specific settings (auth uses SMTP credentials)
|
||||
$data = [
|
||||
'instance_url' => $_POST['peertube_instance_url'] ?? '',
|
||||
'username' => $_POST['peertube_username'] ?? '',
|
||||
'channel_id' => $_POST['peertube_channel_id'] ?? 1,
|
||||
'channel_name' => $_POST['peertube_channel_name'] ?? '',
|
||||
'privacy' => $_POST['peertube_privacy'] ?? 1,
|
||||
];
|
||||
$pwd = $_POST['peertube_password'] ?? '';
|
||||
if ($pwd !== '') {
|
||||
$data['password'] = $pwd;
|
||||
}
|
||||
PeerTubeService::updateSettings($db, $data);
|
||||
$logger->logPeerTubeUpdate($enabled === '1');
|
||||
App::flash('success', 'Paramètres PeerTube mis à jour.');
|
||||
|
||||
@@ -33,8 +33,16 @@
|
||||
"text/vtt",
|
||||
"application/zip", "application/x-tar", "application/gzip"
|
||||
],
|
||||
// When PeerTube is active, exclude video/audio from TFE pool
|
||||
acceptedFileTypesPeerTube: [
|
||||
"image/jpeg", "image/png", "image/gif", "image/webp",
|
||||
"application/pdf",
|
||||
"text/vtt",
|
||||
"application/zip", "application/x-tar", "application/gzip"
|
||||
],
|
||||
labelFileTypeNotAllowed: "Format non accepté",
|
||||
fileValidateTypeLabelExpectedTypes: "PDF, Images, Vidéos, Audio, VTT, Archives",
|
||||
fileValidateTypeLabelExpectedTypesPeerTube: "PDF, Images, VTT, Archives",
|
||||
maxFileSize: "500MB",
|
||||
labelMaxFileSizeExceeded: "Fichier trop volumineux",
|
||||
labelMaxFileSize: "Taille max: {filesize}",
|
||||
@@ -91,17 +99,37 @@
|
||||
labelMaxFileSize: "Taille max: {filesize}",
|
||||
allowMultiple: false
|
||||
},
|
||||
peertube_video: {
|
||||
acceptedFileTypes: ["video/mp4", "video/webm", "video/ogg", "video/quicktime"],
|
||||
labelFileTypeNotAllowed: "Format non accepté",
|
||||
fileValidateTypeLabelExpectedTypes: "MP4, WebM, OGV, MOV",
|
||||
maxFileSize: "500MB",
|
||||
labelMaxFileSizeExceeded: "Fichier trop volumineux",
|
||||
labelMaxFileSize: "Taille max: {filesize}",
|
||||
allowMultiple: true
|
||||
},
|
||||
peertube_audio: {
|
||||
acceptedFileTypes: ["audio/mpeg", "audio/ogg", "audio/flac", "audio/x-wav", "audio/aac", "audio/mp4"],
|
||||
labelFileTypeNotAllowed: "Format non accepté",
|
||||
fileValidateTypeLabelExpectedTypes: "MP3, OGG, FLAC, WAV, AAC, M4A",
|
||||
maxFileSize: "500MB",
|
||||
labelMaxFileSizeExceeded: "Fichier trop volumineux",
|
||||
labelMaxFileSize: "Taille max: {filesize}",
|
||||
allowMultiple: true
|
||||
},
|
||||
};
|
||||
|
||||
// Map input id → queue type
|
||||
var INPUT_ID_TO_TYPE = {
|
||||
"tfe-files-input": "tfe",
|
||||
"tfe-files-input-2": "tfe",
|
||||
"video-files-input": "video",
|
||||
"audio-files-input": "audio",
|
||||
"annexe-files-input": "annexe",
|
||||
"couverture": "cover",
|
||||
"note_intention": "note_intention",
|
||||
"tfe-files-input": "tfe",
|
||||
"tfe-files-input-2": "tfe",
|
||||
"video-files-input": "video",
|
||||
"audio-files-input": "audio",
|
||||
"annexe-files-input": "annexe",
|
||||
"couverture": "cover",
|
||||
"note_intention": "note_intention",
|
||||
"peertube-video-input": "peertube_video",
|
||||
"peertube-audio-input": "peertube_audio",
|
||||
};
|
||||
|
||||
// ── Helpers ───────────────────────────────────────────────────────────
|
||||
@@ -167,6 +195,15 @@
|
||||
// Per-type max size overrides (for TFE: PDF=100MB, video/audio=2GB)
|
||||
var perExtMax = cfg.perExtensionMaxSize || {};
|
||||
|
||||
// When PeerTube is active, restrict TFE pool to PDF/text only
|
||||
var peerTubeActive = queueType === "tfe" && input.dataset.peertubeActive === "1";
|
||||
var acceptedFileTypes = peerTubeActive && cfg.acceptedFileTypesPeerTube
|
||||
? cfg.acceptedFileTypesPeerTube
|
||||
: cfg.acceptedFileTypes;
|
||||
var expectedTypesLabel = peerTubeActive && cfg.fileValidateTypeLabelExpectedTypesPeerTube
|
||||
? cfg.fileValidateTypeLabelExpectedTypesPeerTube
|
||||
: cfg.fileValidateTypeLabelExpectedTypes;
|
||||
|
||||
return {
|
||||
allowMultiple: cfg.allowMultiple,
|
||||
allowReorder: true,
|
||||
@@ -174,9 +211,9 @@
|
||||
storeAsFile: true,
|
||||
|
||||
// ── Native FilePond validation ──
|
||||
acceptedFileTypes: cfg.acceptedFileTypes,
|
||||
acceptedFileTypes: acceptedFileTypes,
|
||||
labelFileTypeNotAllowed: cfg.labelFileTypeNotAllowed,
|
||||
fileValidateTypeLabelExpectedTypes: cfg.fileValidateTypeLabelExpectedTypes,
|
||||
fileValidateTypeLabelExpectedTypes: expectedTypesLabel,
|
||||
maxFileSize: cfg.maxFileSize,
|
||||
labelMaxFileSizeExceeded: cfg.labelMaxFileSizeExceeded,
|
||||
labelMaxFileSize: cfg.labelMaxFileSize,
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
require_once APP_ROOT . '/src/PeerTubeService.php';
|
||||
$_ptDb = Database::getInstance();
|
||||
$peerTubeEnabled = PeerTubeService::isEnabled($_ptDb);
|
||||
$peerTubeSettings = PeerTubeService::getSettings($_ptDb);
|
||||
|
||||
$db = $_ptDb->getConnection();
|
||||
|
||||
@@ -98,6 +99,20 @@ $hasAnnexesChecked = !empty($_POST['has_annexes']);
|
||||
hx-trigger="change"
|
||||
hx-include="[name='formats[]'], [name='website_url'], [name='admin_mode'], [name='edit_mode'], [name='_cover']"
|
||||
hx-swap="outerHTML"
|
||||
<?php elseif ((int)$opt['id'] === ($videoId ?? 0)): ?>
|
||||
hx-post="<?= htmlspecialchars($hxPost) ?>"
|
||||
hx-target="#slot-video"
|
||||
hx-select="#slot-video"
|
||||
hx-trigger="change"
|
||||
hx-include="[name='formats[]'], [name='admin_mode'], [name='edit_mode'], [name='_cover']"
|
||||
hx-swap="outerHTML"
|
||||
<?php elseif ((int)$opt['id'] === ($audioId ?? 0)): ?>
|
||||
hx-post="<?= htmlspecialchars($hxPost) ?>"
|
||||
hx-target="#slot-audio"
|
||||
hx-select="#slot-audio"
|
||||
hx-trigger="change"
|
||||
hx-include="[name='formats[]'], [name='admin_mode'], [name='edit_mode'], [name='_cover']"
|
||||
hx-swap="outerHTML"
|
||||
<?php endif; ?>
|
||||
>
|
||||
<?= htmlspecialchars($opt['name']) ?>
|
||||
@@ -142,9 +157,13 @@ $hasAnnexesChecked = !empty($_POST['has_annexes']);
|
||||
// ── Existing files ──
|
||||
$_thesisFilesList = array_values(array_filter($_efiles, fn($f) => $f["file_type"] !== "cover"));
|
||||
foreach ($_thesisFilesList as $_f):
|
||||
$_fExt = strtolower(pathinfo($_f["file_path"] ?? "", PATHINFO_EXTENSION));
|
||||
$_fPath = $_f["file_path"] ?? "";
|
||||
$_fIsPeerTube = str_starts_with($_fPath, "peertube_ids:");
|
||||
$_fExt = strtolower(pathinfo($_fPath, PATHINFO_EXTENSION));
|
||||
$_fType = $_f["file_type"] ?? "other";
|
||||
$_fIcon = match (true) {
|
||||
$_fIsPeerTube && $_fType === "video" => "🎬",
|
||||
$_fIsPeerTube && $_fType === "audio" => "🔊",
|
||||
$_fType === "main" || $_fExt === "pdf" => "📄",
|
||||
in_array($_fExt, ["jpg","jpeg","png","gif","webp"]) => "🖼️",
|
||||
$_fType === "video" || in_array($_fExt, ["mp4","webm","mov","ogv"]) => "🎬",
|
||||
@@ -153,8 +172,8 @@ $hasAnnexesChecked = !empty($_POST['has_annexes']);
|
||||
$_fType === "website" => "🌐",
|
||||
default => "📎",
|
||||
};
|
||||
$_fIsExternal = str_starts_with($_f["file_path"] ?? "", "http://") || str_starts_with($_f["file_path"] ?? "", "https://");
|
||||
$_fLinkHref = $_fIsExternal ? htmlspecialchars($_f["file_path"]) : "/media?path=" . urlencode($_f["file_path"]);
|
||||
$_fIsExternal = str_starts_with($_fPath, "http://") || str_starts_with($_fPath, "https://");
|
||||
$_fLinkHref = $_fIsPeerTube ? "#" : ($_fIsExternal ? htmlspecialchars($_fPath) : "/media?path=" . urlencode($_fPath));
|
||||
?>
|
||||
<li class="admin-file-list-item" data-file-id="<?= (int)$_f["id"] ?>">
|
||||
<input type="hidden" name="file_sort_order[]" value="<?= (int)$_f["id"] ?>">
|
||||
@@ -222,9 +241,15 @@ $hasAnnexesChecked = !empty($_POST['has_annexes']);
|
||||
name="queue_file[tfe][]"
|
||||
multiple
|
||||
class="tfe-file-picker"
|
||||
<?= !$adminMode ? 'required' : '' ?>>
|
||||
<?= !$adminMode ? 'required' : '' ?>
|
||||
data-peertube-active="<?= $peerTubeEnabled ? '1' : '0' ?>">
|
||||
<small class="admin-file-hint">
|
||||
<?php if ($peerTubeEnabled): ?>
|
||||
PDF (max 100 MB) · Images (max 500 MB) · VTT · Archives (max 500 MB).
|
||||
Vidéo & Audio → utilisez les emplacements dédiés ci-dessous.
|
||||
<?php else: ?>
|
||||
PDF (max 100 MB) · Images (max 500 MB) · Vidéo & Audio (max 2 GB) · VTT · Archives (max 500 MB).
|
||||
<?php endif; ?>
|
||||
Glissez pour réordonner.
|
||||
PDFs trop lourds ? <a href="https://www.bentopdf.com" target="_blank" rel="noopener">https://bentopdf.com/</a>
|
||||
</small>
|
||||
@@ -265,20 +290,21 @@ $hasAnnexesChecked = !empty($_POST['has_annexes']);
|
||||
<div id="slot-siteweb" hidden></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Slot: Video (disabled — video files are now uploaded via the TFE input) -->
|
||||
<!--
|
||||
<?php if ($hasVideo): ?>
|
||||
<!-- Slot: Video (always visible when PeerTube enabled) -->
|
||||
<?php if ($peerTubeEnabled): ?>
|
||||
<div id="slot-video" class="admin-form-group">
|
||||
<label for="peertube_video">Vidéo PeerTube<?= !$adminMode ? ' <span class="asterisk">*</span>' : '' ?></label>
|
||||
<div id="slot-video" class="admin-form-group admin-files-fieldgroup">
|
||||
<label for="peertube-video-input">Vidéo<?= !$adminMode ? ' <span class="asterisk">*</span>' : '' ?></label>
|
||||
<div class="admin-file-input">
|
||||
<input type="file" id="peertube_video" name="peertube_video"
|
||||
<input type="file" id="peertube-video-input"
|
||||
name="queue_file[peertube_video][]"
|
||||
multiple
|
||||
accept="video/mp4,video/webm,video/ogg,video/quicktime,.mp4,.webm,.ogv,.mov"
|
||||
class="tfe-file-picker"
|
||||
<?= !$adminMode ? 'required' : '' ?>>
|
||||
<small>MP4, WebM ou MOV. La vidéo sera hébergée sur PeerTube. Max 500 MB.</small>
|
||||
<small class="admin-file-hint">MP4, WebM ou MOV. Max 500 MB. Glissez pour réordonner. Hébergé sur <a href="<?= htmlspecialchars($peerTubeSettings['instance_url']) ?>" target="_blank" rel="noopener">PeerTube</a>.</small>
|
||||
</div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<?php elseif ($hasVideo): ?>
|
||||
<div id="slot-video" class="admin-form-group admin-files-fieldgroup">
|
||||
<label for="video-files-input">Vidéo<?= !$adminMode ? ' <span class="asterisk">*</span>' : '' ?></label>
|
||||
<div class="admin-file-input">
|
||||
@@ -291,27 +317,25 @@ $hasAnnexesChecked = !empty($_POST['has_annexes']);
|
||||
<small class="admin-file-hint">MP4, WebM ou MOV. Max 500 MB. Glissez pour réordonner.</small>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php else: ?>
|
||||
<div id="slot-video" hidden></div>
|
||||
<?php endif; ?>
|
||||
-->
|
||||
<div id="slot-video" hidden></div>
|
||||
|
||||
<!-- Slot: Audio (disabled — audio files are now uploaded via the TFE input) -->
|
||||
<!--
|
||||
<?php if ($hasAudio): ?>
|
||||
<!-- Slot: Audio (always visible when PeerTube enabled) -->
|
||||
<?php if ($peerTubeEnabled): ?>
|
||||
<div id="slot-audio" class="admin-form-group">
|
||||
<label for="peertube_audio">Audio PeerTube<?= !$adminMode ? ' <span class="asterisk">*</span>' : '' ?></label>
|
||||
<div id="slot-audio" class="admin-form-group admin-files-fieldgroup">
|
||||
<label for="peertube-audio-input">Audio<?= !$adminMode ? ' <span class="asterisk">*</span>' : '' ?></label>
|
||||
<div class="admin-file-input">
|
||||
<input type="file" id="peertube_audio" name="peertube_audio"
|
||||
<input type="file" id="peertube-audio-input"
|
||||
name="queue_file[peertube_audio][]"
|
||||
multiple
|
||||
accept="audio/mpeg,audio/ogg,audio/wav,audio/flac,audio/aac,audio/mp4,.mp3,.ogg,.oga,.wav,.flac,.aac,.m4a"
|
||||
class="tfe-file-picker"
|
||||
<?= !$adminMode ? 'required' : '' ?>>
|
||||
<small>MP3, OGG, WAV, FLAC ou AAC. Le fichier sera hébergé sur PeerTube. Max 500 MB.</small>
|
||||
<small class="admin-file-hint">MP3, OGG, WAV, FLAC ou AAC. Max 500 MB. Glissez pour réordonner. Hébergé sur <a href="<?= htmlspecialchars($peerTubeSettings['instance_url']) ?>" target="_blank" rel="noopener">PeerTube</a>.</small>
|
||||
</div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<?php elseif ($hasAudio): ?>
|
||||
<div id="slot-audio" class="admin-form-group admin-files-fieldgroup">
|
||||
<label for="audio-files-input">Audio<?= !$adminMode ? ' <span class="asterisk">*</span>' : '' ?></label>
|
||||
<div class="admin-file-input">
|
||||
@@ -324,12 +348,9 @@ $hasAnnexesChecked = !empty($_POST['has_annexes']);
|
||||
<small class="admin-file-hint">MP3, OGG, WAV, FLAC ou AAC. Max 500 MB. Glissez pour réordonner.</small>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php else: ?>
|
||||
<div id="slot-audio" hidden></div>
|
||||
<?php endif; ?>
|
||||
-->
|
||||
<div id="slot-audio" hidden></div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user