summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorilotterytea <iltsu@alright.party>2025-06-01 00:01:49 +0400
committerilotterytea <iltsu@alright.party>2025-06-01 00:01:49 +0400
commit0ac128d6a2df3a84f49a4d86cfbf501bbbb52a43 (patch)
tree6e9727270a8adfc7c1a0ab1fee2870264875840f
parent4da453ba7cd09849d7c3c1229188e1ee3b3866be (diff)
feat: file thumbnails
-rw-r--r--lib/partials.php2
-rw-r--r--lib/thumbnails.php41
-rw-r--r--public/index.php4
-rw-r--r--public/upload.php39
4 files changed, 80 insertions, 6 deletions
diff --git a/lib/partials.php b/lib/partials.php
index 13ea156..8a7824e 100644
--- a/lib/partials.php
+++ b/lib/partials.php
@@ -20,7 +20,7 @@ function html_big_navbar()
function html_footer()
{
- $files = glob(FILE_DIRECTORY . "/*.*");
+ $files = glob(FILE_UPLOAD_DIRECTORY . "/*.*");
$file_size = 0;
foreach ($files as $file) {
diff --git a/lib/thumbnails.php b/lib/thumbnails.php
new file mode 100644
index 0000000..5afc775
--- /dev/null
+++ b/lib/thumbnails.php
@@ -0,0 +1,41 @@
+<?php
+function generate_image_thumbnail(string $src_path, string $dst_path, int $width, int $height)
+{
+ if ($src_path == "") {
+ return -2;
+ }
+
+ $input_path = escapeshellarg($src_path);
+ $output_path = escapeshellarg($dst_path);
+
+ $result_code = null;
+
+ exec(command: "magick $input_path -resize {$width}x{$height} -loop 0 $output_path", result_code: $result_code);
+
+ return $result_code;
+}
+
+function generate_video_thumbnail(string $src_path, string $folder_path, string $dst_path, int $width, int $height)
+{
+ if ($src_path == "") {
+ return -2;
+ }
+
+ if (!is_dir($folder_path) && !mkdir($folder_path, 0777, true)) {
+ return -3;
+ }
+
+ $input_path = escapeshellarg($src_path);
+ $output_path = escapeshellarg($dst_path);
+
+ $ffmpeg_command = "ffmpeg -i $input_path -vf \"fps=4,scale=320:-1:flags=lanczos\" -t 10 $folder_path/frames_%04d.png 2>&1";
+ $magick_command = "magick $folder_path/frames_*.png -loop 0 -delay 60 -resize {$width}x{$height} $output_path 2>&1";
+
+ exec($ffmpeg_command, $ffmpeg_output, $ffmpeg_result_code);
+ exec($magick_command, $magick_output, $magick_result_code);
+
+ array_map('unlink', array_filter((array) glob("$folder_path/*.*")));
+ rmdir($folder_path);
+
+ return $ffmpeg_result_code === 0 && $magick_result_code === 0 ? 0 : -1;
+} \ No newline at end of file
diff --git a/public/index.php b/public/index.php
index 5e2f77a..b85dadf 100644
--- a/public/index.php
+++ b/public/index.php
@@ -263,11 +263,13 @@ include_once $_SERVER['DOCUMENT_ROOT'] . '/../lib/partials.php';
function addUploadedFile(file) {
return `
<div class="box item column gap-4 pad-4">
+ <?php if (FILE_THUMBNAILS): ?>
<div class="column align-center justify-center grow">
<div style="max-width: 128px; max-height:128px;">
- <img src="/userdata/${file.id}.${file.extension}" alt="${file.id}.${file.extension}" style="max-width:100%; max-height: 100%;">
+ <p><i><img src="<?= FILE_THUMBNAIL_DIRECTORY_PREFIX ?>/${file.id}.webp" alt="No thumbnail." style="max-width:100%; max-height: 100%;"></i></p>
</div>
</div>
+ <?php endif; ?>
<h2>${file.id}.${file.extension}</h2>
<div>
<p>${file.mime}</p>
diff --git a/public/upload.php b/public/upload.php
index 3ef0a0c..ae550c9 100644
--- a/public/upload.php
+++ b/public/upload.php
@@ -1,13 +1,14 @@
<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/../config.php';
include_once $_SERVER['DOCUMENT_ROOT'] . '/../lib/utils.php';
+include_once $_SERVER['DOCUMENT_ROOT'] . '/../lib/thumbnails.php';
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
json_response(null, 'Method not allowed', 405);
exit;
}
-if (!is_dir(FILE_DIRECTORY) && !mkdir(FILE_DIRECTORY, 0777, true)) {
+if (!is_dir(FILE_UPLOAD_DIRECTORY) && !mkdir(FILE_UPLOAD_DIRECTORY, 0777, true)) {
json_response(null, 'Failed to create a directory for user files', 500);
exit();
}
@@ -102,7 +103,7 @@ try {
exec(sprintf(
'yt-dlp -f "worst" -o "%s/%s.%s" %s 2>&1',
- FILE_DIRECTORY,
+ FILE_UPLOAD_DIRECTORY,
$file_id,
$file_data['extension'],
escapeshellarg($url)
@@ -112,12 +113,42 @@ try {
error_log(sprintf("Failed to download a file (URL: %s): %s", $url, implode('\n', $output)));
throw new RuntimeException('Failed to download a file! Try again later.');
}
- } else if (isset($paste) && !file_put_contents(FILE_DIRECTORY . sprintf('/%s.%s', $file_id, $file_data['extension']), $paste)) {
+ } else if (isset($paste) && !file_put_contents(FILE_UPLOAD_DIRECTORY . sprintf('/%s.%s', $file_id, $file_data['extension']), $paste)) {
throw new RuntimeException('Failed to paste a text! Try again later.');
- } else if (isset($file) && !move_uploaded_file($file['tmp_name'], FILE_DIRECTORY . sprintf('/%s.%s', $file_id, $file_data['extension']))) {
+ } else if (isset($file) && !move_uploaded_file($file['tmp_name'], FILE_UPLOAD_DIRECTORY . sprintf('/%s.%s', $file_id, $file_data['extension']))) {
throw new RuntimeException("Failed to save the file. Try again later.");
}
+ if (FILE_THUMBNAILS && !is_dir(FILE_THUMBNAIL_DIRECTORY) && !mkdir(FILE_THUMBNAIL_DIRECTORY, 0777, true)) {
+ throw new RuntimeException('Failed to create a directory for thumbnails');
+ }
+
+ if (
+ FILE_THUMBNAILS && (
+ (
+ str_starts_with($file_data['mime'], 'image/') &&
+ $thumbnail_error = generate_image_thumbnail(
+ FILE_UPLOAD_DIRECTORY . "/{$file_id}.{$file_data['extension']}",
+ FILE_THUMBNAIL_DIRECTORY . "/{$file_id}.webp",
+ FILE_THUMBNAIL_SIZE[0],
+ FILE_THUMBNAIL_SIZE[1]
+ )
+ ) ||
+ (
+ str_starts_with($file_data['mime'], 'video/') &&
+ $thumbnail_error = generate_video_thumbnail(
+ FILE_UPLOAD_DIRECTORY . "/{$file_id}.{$file_data['extension']}",
+ FILE_THUMBNAIL_DIRECTORY . "/{$file_id}",
+ FILE_THUMBNAIL_DIRECTORY . "/{$file_id}.webp",
+ FILE_THUMBNAIL_SIZE[0],
+ FILE_THUMBNAIL_SIZE[1]
+ )
+ )
+ )
+ ) {
+ throw new RuntimeException("Failed to create a thumbnail (Error code {$thumbnail_error})");
+ }
+
if ($_SERVER['HTTP_ACCEPT'] == 'application/json') {
json_response($file_data, null, 201);
} else {