summaryrefslogtreecommitdiff
path: root/public
diff options
context:
space:
mode:
Diffstat (limited to 'public')
-rw-r--r--public/index.php76
-rw-r--r--public/static/style.css12
-rw-r--r--public/upload.php113
3 files changed, 153 insertions, 48 deletions
diff --git a/public/index.php b/public/index.php
index 7d07c5b..e08a67a 100644
--- a/public/index.php
+++ b/public/index.php
@@ -26,9 +26,28 @@ include_once $_SERVER['DOCUMENT_ROOT'] . '/../lib/partials.php';
accept="<?= implode(', ', array_unique(array_values(FILE_ACCEPTED_MIME_TYPES))) ?>"
id="form-file">
- <button type="button" id="form-upload-wrapper" style="display: none">
- <h1>Click here to start upload</h1>
- </button>
+ <div class="column gap-8" id="form-upload-wrapper">
+ <button type="button">
+ <h1>Click here to start upload</h1>
+ </button>
+ <?php if (FILEEXT_ENABLED): ?>
+ <div class="row gap-8">
+ <p>URL:</p>
+ <div class="column grow">
+ <input type="url" name="url" id="form-url"
+ placeholder="Instagram, YouTube and other links">
+ <ul class="row gap-8 font-small" style="list-style:none">
+ <li>
+ <p>Max duration: <b><?= FILEEXT_MAX_DURATION / 60 ?> minutes</b></p>
+ </li>
+ <li><a href="https://github.com/yt-dlp/yt-dlp/blob/master/supportedsites.md"
+ target="_blank">Supported
+ platforms</a></li>
+ </ul>
+ </div>
+ </div>
+ <?php endif; ?>
+ </div>
<button type="submit">Upload</button>
</form>
@@ -49,15 +68,30 @@ include_once $_SERVER['DOCUMENT_ROOT'] . '/../lib/partials.php';
<script>
const uploadedFiles = document.getElementById('uploaded-files');
+ <?php if (FILEEXT_ENABLED): ?>
+ const fileURL = document.getElementById('form-url');
+ <?php endif; ?>
const formUpload = document.getElementById('form-upload');
formUpload.addEventListener('submit', (event) => {
event.preventDefault();
- fileUpload();
+ <?php if (FILEEXT_ENABLED): ?>
+ fileUpload(fileURL.value.length != 0);
+ <?php else: ?>
+ fileUpload(false);
+ <?php endif; ?>
});
- const formUploadWrapper = document.getElementById('form-upload-wrapper');
- formUploadWrapper.style.display = 'block';
+ const fileUploadWrapper = document.querySelector('#form-upload-wrapper>button');
+ fileUploadWrapper.style.display = 'block';
+
+ <?php if (FILEEXT_ENABLED): ?>
+ const fileURLWrapper = document.querySelector('#form-upload-wrapper>div');
+ fileURL.addEventListener('change', () => {
+ fileUploadWrapper.style.display = fileURL.value.length == 0 ? 'block' : 'none';
+ formSubmitButton.style.display = fileURL.value.length == 0 ? 'none' : 'block';
+ });
+ <?php endif; ?>
const formSubmitButton = document.querySelector('#form-upload button[type=submit]');
@@ -66,21 +100,31 @@ include_once $_SERVER['DOCUMENT_ROOT'] . '/../lib/partials.php';
formFile.addEventListener("change", (e) => {
const file = e.target.files[0];
if (file) {
- formUploadWrapper.innerHTML = `<h1>File: ${file.name}</h1>`;
+ fileUploadWrapper.innerHTML = `<h1>File: ${file.name}</h1>`;
formSubmitButton.style.display = 'block';
+ <?php if (FILEEXT_ENABLED): ?>
+ fileURLWrapper.style.display = 'none';
+ <?php endif; ?>
}
});
- formUploadWrapper.addEventListener("click", () => formFile.click());
+ fileUploadWrapper.addEventListener("click", () => formFile.click());
formSubmitButton.style.display = 'none';
- function fileUpload() {
- formUploadWrapper.innerHTML = `<h1>Uploading ${formFile.files[0].name}...</h1><p>This might take a while...</p>`;
+ function fileUpload(is_url) {
+ const form = new FormData(formUpload);
+
+ fileUploadWrapper.innerHTML = is_url ? `<h1>Uploading ${fileURL.value}</h1><p>This might take a while...</p>` : `<h1>Uploading ${formFile.files[0].name}...</h1><p>This might take a while...</p>`;
+ fileUploadWrapper.style.display = 'block';
+ <?php if (FILEEXT_ENABLED): ?>
+ fileURLWrapper.style.display = 'none';
+ fileURL.value = '';
+ <?php endif; ?>
formSubmitButton.style.display = 'none';
fetch(formUpload.getAttribute('action'), {
- 'body': new FormData(formUpload),
+ 'body': form,
'method': 'POST',
'headers': {
'Accept': 'application/json'
@@ -89,10 +133,18 @@ include_once $_SERVER['DOCUMENT_ROOT'] . '/../lib/partials.php';
.catch((err) => {
console.error(err);
alert('Failed to send a file. More info in the console...');
+ <?php if (FILEEXT_ENABLED): ?>
+ fileURLWrapper.style.display = 'flex';
+ <?php endif; ?>
+ fileUploadWrapper.style.display = 'block';
})
.then((r) => r.json())
.then((json) => {
- formUploadWrapper.innerHTML = '<h1>Click here to start upload</h1>';
+ fileUploadWrapper.innerHTML = '<h1>Click here to start upload</h1>';
+ <?php if (FILEEXT_ENABLED): ?>
+ fileURLWrapper.style.display = 'flex';
+ <?php endif; ?>
+ fileUploadWrapper.style.display = 'block';
if (json.status_code != 201) {
alert(`${json.message} (${json.status_code})`);
diff --git a/public/static/style.css b/public/static/style.css
index 69332ca..9762b38 100644
--- a/public/static/style.css
+++ b/public/static/style.css
@@ -52,14 +52,14 @@ button[type=submit]:hover {
cursor: pointer;
}
-#form-upload-wrapper {
+#form-upload-wrapper>button {
background: var(--background-2);
padding: 32px 0;
color: var(--foreground);
border: 4px dashed var(--box-border);
}
-#form-upload-wrapper:hover {
+#form-upload-wrapper>button:hover {
background: var(--background);
cursor: pointer;
}
@@ -116,10 +116,18 @@ button[type=submit]:hover {
padding: 4px;
}
+.gap-16 {
+ gap: 16px;
+}
+
.gap-8 {
gap: 8px;
}
.gap-4 {
gap: 4px;
+}
+
+.font-small {
+ font-size: 10px;
} \ No newline at end of file
diff --git a/public/upload.php b/public/upload.php
index 5c4e3cb..2fd7c67 100644
--- a/public/upload.php
+++ b/public/upload.php
@@ -7,57 +7,102 @@ if ($_SERVER['REQUEST_METHOD'] != 'POST') {
exit;
}
-if (!isset($_FILES['file'])) {
- json_response(null, "No 'file' specified!", 400);
- exit();
-}
-
if (!is_dir(FILE_DIRECTORY) && !mkdir(FILE_DIRECTORY, 0777, true)) {
json_response(null, 'Failed to create a directory for user files', 500);
exit();
}
try {
- $file = $_FILES['file'];
+ $url = $_POST['url'] ?? null;
+ $file = $_FILES['file'] ?? null;
+ $file_data = null;
- if (
- !isset($file['error']) ||
- is_array($file['error'])
- ) {
- throw new RuntimeException('Invalid parameters.');
- }
+ if (FILEEXT_ENABLED && isset($url) && !empty($url)) {
+ $output = [];
+ exec('yt-dlp --get-filename -o "%(filesize_approx)s %(ext)s %(duration)s" ' . escapeshellarg($url) . '', $output);
+ if (empty($output)) {
+ throw new RuntimeException('Bad URL');
+ }
+
+ $output = explode(' ', $output[0]);
+
+ // TODO: some videos don't have duration
+ $duration = intval($output[2]);
+ if ($duration > FILEEXT_MAX_DURATION) {
+ throw new RuntimeException(sprintf("File must be under %d minutes", FILEEXT_MAX_DURATION / 60));
+ }
- // checking file size
- switch ($file['error']) {
- case UPLOAD_ERR_OK:
- break;
- case UPLOAD_ERR_NO_FILE:
- throw new RuntimeException('No file sent.');
- case UPLOAD_ERR_INI_SIZE:
- case UPLOAD_ERR_FORM_SIZE:
- throw new RuntimeException('Exceeded filesize limit.');
- default:
- throw new RuntimeException('Unknown errors.');
+ if (!array_key_exists($output[1], FILE_ACCEPTED_MIME_TYPES)) {
+ throw new RuntimeException("Unsupported extension: {$output[1]}");
+ }
+
+ $file_data = [
+ 'size' => intval($output[0]),
+ 'mime' => FILE_ACCEPTED_MIME_TYPES[$output[1]],
+ 'extension' => $output[1]
+ ];
+ } else if (isset($file)) {
+ if (
+ !isset($file['error']) ||
+ is_array($file['error'])
+ ) {
+ throw new RuntimeException('Invalid parameters.');
+ }
+
+ // checking file error
+ switch ($file['error']) {
+ case UPLOAD_ERR_OK:
+ break;
+ case UPLOAD_ERR_NO_FILE:
+ throw new RuntimeException('No file sent.');
+ case UPLOAD_ERR_INI_SIZE:
+ case UPLOAD_ERR_FORM_SIZE:
+ throw new RuntimeException('Exceeded filesize limit.');
+ default:
+ throw new RuntimeException('Unknown errors.');
+ }
+
+ // checking file mimetype
+ $finfo = new finfo(FILEINFO_MIME_TYPE);
+ if (false === $file_ext = array_search($finfo->file($file['tmp_name']), FILE_ACCEPTED_MIME_TYPES, true)) {
+ throw new RuntimeException("Invalid file format.");
+ }
+
+ $file_data = [
+ 'size' => $file['size'],
+ 'mime' => FILE_ACCEPTED_MIME_TYPES[$file_ext],
+ 'extension' => $file_ext
+ ];
}
- // checking file mimetype
- $finfo = new finfo(FILEINFO_MIME_TYPE);
- if (false === $file_ext = array_search($finfo->file($file['tmp_name']), FILE_ACCEPTED_MIME_TYPES, true)) {
- throw new RuntimeException("Invalid file format.");
+ if (!$file_data) {
+ throw new RuntimeException('No URL or file specified');
}
$file_id = generate_random_char_sequence(FILE_ID_CHARACTERS, FILE_ID_LENGTH);
+ $file_data['id'] = $file_id;
+
+ if (isset($url)) {
+ $result = 0;
+ $output = [];
+
+ exec(sprintf(
+ 'yt-dlp -o "%s/%s.%s" %s 2>&1',
+ FILE_DIRECTORY,
+ $file_id,
+ $file_data['extension'],
+ escapeshellarg($url)
+ ), $output, $result);
- if (!move_uploaded_file($file['tmp_name'], FILE_DIRECTORY . sprintf('/%s.%s', $file_id, $file_ext))) {
+ if ($result != 0) {
+ 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 (!move_uploaded_file($file['tmp_name'], FILE_DIRECTORY . sprintf('/%s.%s', $file_id, $file_ext))) {
throw new RuntimeException("Failed to save the file. Try again later.");
}
- json_response([
- 'id' => $file_id,
- 'extension' => $file_ext,
- 'mime' => FILE_ACCEPTED_MIME_TYPES[$file_ext],
- 'size' => $file['size']
- ], null, 201);
+ json_response($file_data, null, 201);
} catch (RuntimeException $e) {
json_response(null, $e->getMessage(), 400);
} \ No newline at end of file