Updates on download

This commit is contained in:
0d0 2025-01-30 03:10:04 +01:00
parent c6629b387f
commit 6ca85079fa
6 changed files with 375 additions and 344 deletions

View file

@ -1,6 +1,20 @@
<script lang="ts">
import '../app.css';
let { children } = $props();
</script>
{@render children()}
<footer
class="absolute bottom-0 w-[100dvw] mt-10 bg-black text-green-500 text-center py-4 border-t-4 border-green-500"
>
Made with ❤️ by Emersa <span>©</span>
</footer>
<style>
span {
transform: rotate(180deg);
display: inline-block;
}
</style>

View file

@ -1,42 +1,80 @@
import { DOWNLOAD_PATH } from "$env/static/private";
import { redirect } from "@sveltejs/kit";
import youtubedl from "youtube-dl-exec";
import { DOWNLOAD_PATH } from '$env/static/private';
import { redirect } from '@sveltejs/kit';
import youtubedl from 'youtube-dl-exec';
const isAudioFormat = (format: string) => {
let isAudio = false;
switch (format) {
case 'mp3':
isAudio = true;
break;
default:
isAudio = false;
break;
}
return isAudio;
};
const isVideoFormat = (format: string) => {
let isVideo = false;
switch (format) {
case 'mp4':
isVideo = true;
break;
default:
isVideo = false;
break;
}
return isVideo;
}
export const actions = {
download: async ({ request, cookies }) => {
const data = await request.formData();
download: async ({ request, cookies }) => {
const data = await request.formData();
const obj = {};
for (const element of data) {
obj[element[0]] = element[1];
}
const obj = {};
for (const element of data) {
obj[element[0]] = element[1];
}
const { format, source, link } = obj;
const { format, source, link } = obj;
if (!(format && source && link)) {
throw redirect(307, "/");
}
if (!(format && source && link)) {
throw redirect(307, '/');
}
console.info(`Asked ${source} download of ${link}`);
console.info(`Asked ${source} download of ${link}`);
switch (source) {
case "youtube":
const output = await youtubedl(link, {
output: `${DOWNLOAD_PATH}/%(artist)s-%(title)s.%(ext)s`,
embedThumbnail: true,
audioFormat: format
});
case 'youtube':
const options = {
output: `${DOWNLOAD_PATH}/%(artist)s-%(title)s.%(ext)s`,
embedThumbnail: true
}
console.log(output);
console.info(`Downloaded ${link} to ${output}`);
if (isAudioFormat(format)) {
options.extractAudio = true;
options.audioFormat = format;
}
break;
case "spotify":
break;
default:
console.error("ops");
}
isVideoFormat(format) ? options.format = format : ''
return { success: true };
},
const output = await youtubedl(link);
console.log(output);
console.info(`Downloaded ${link} to ${output}`);
break;
case 'spotify':
break;
default:
console.error('ops');
}
return { success: true };
}
};

View file

@ -1,209 +1,185 @@
<script>
let source = $state("youtube");
let link = $state("");
let format = "mp3";
let showModal = false;
import { enhance } from '$app/forms';
const toggleModal = () => {
showModal = !showModal;
};
let { form } = $props();
let source = $state('youtube');
let link = $state('');
let format = $state('mp3');
let loading = $state(true);
let showModal = $state(false);
let error = $state(false);
const handleSubmit = (e) => {
e.preventDefault();
console.log({
source,
link,
format,
});
};
const toggleModal = () => {
showModal = !showModal;
};
$effect(() => {
// Auto selected the radio button based on url regex
if (link.includes('spotify')) {
source = 'spotify'
} else if (link.includes('youtube')) {
source = 'youtube'
}
})
const handleSubmit = (e) => {
e.preventDefault();
console.log({
source,
link,
format
});
};
const onFormSubmit = ({ formElement, formData, action, cancel, submitter }) => {
loading = true;
// `formElement` is this `<form>` element
// `formData` is its `FormData` object that's about to be submitted
// `action` is the URL to which the form is posted
// calling `cancel()` will prevent the submission
// `submitter` is the `HTMLElement` that caused the form to be submitted
return async ({ result, update }) => {
loading = false;
error = result.type !== 'success';
// `result` is an `ActionResult` object
// `update` is a function which triggers the default logic that would be triggered if this callback wasn't set
};
};
$effect(() => {
// Auto selected the radio button based on url regex
if (link.includes('spotify')) {
source = 'spotify';
} else if (link.includes('youtube')) {
source = 'youtube';
}
});
</script>
<div
class="relative sm:max-w-sm md:max-w-md lg:max-w-lg 2xl:max-w-2xl mx-auto mt-10 p-6 bg-black text-green-500 rounded-lg shadow-lg border-4 border-green-500"
id="wrapper"
class="relative mx-auto rounded-lg bg-black p-6 text-green-500 shadow-lg sm:max-w-sm sm:border-4 sm:border-green-500 md:mt-10 md:max-w-md lg:max-w-lg 2xl:max-w-2xl"
>
<!-- Info Icon -->
<button
onclick={toggleModal}
class="absolute top-3 right-3 text-pink-500 hover:text-pink-300 transition"
aria-label="Open Info Modal"
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
class="w-6 h-6"
viewBox="0 0 24 24"
>
<path
d="M12 0C5.373 0 0 5.373 0 12c0 6.627 5.373 12 12 12s12-5.373 12-12C24 5.373 18.627 0 12 0zm.75 18h-1.5v-6h1.5v6zm0-8h-1.5V8h1.5v2z"
/>
</svg>
</button>
<!-- Info Icon -->
<button
onclick={toggleModal}
class="absolute right-3 top-3 text-pink-500 transition hover:text-pink-300"
aria-label="Open Info Modal"
>
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" class="h-6 w-6" viewBox="0 0 24 24">
<path
d="M12 0C5.373 0 0 5.373 0 12c0 6.627 5.373 12 12 12s12-5.373 12-12C24 5.373 18.627 0 12 0zm.75 18h-1.5v-6h1.5v6zm0-8h-1.5V8h1.5v2z"
/>
</svg>
</button>
<h1 class="text-xl text-center mb-6">🐙 Scaricatore 🐙</h1>
<form method="POST" action="?/download" class="space-y-6">
<!-- Source Selection -->
<fieldset class="space-y-4">
<legend class="text-green-400 text-sm">Choose Source:</legend>
<label class="flex items-center space-x-3">
<input
type="radio"
name="source"
value="youtube"
bind:group={source}
class="retro-radio"
/>
<span>YouTube</span>
</label>
<h1 class="mb-6 text-center text-xl">🐙 Scaricatore 🐙</h1>
<form method="POST" action="?/download" class="space-y-6" use:enhance={onFormSubmit}>
<!-- Source Selection -->
<fieldset class="space-y-4">
<legend class="text-green-400">Choose Source:</legend>
<label class="flex items-center space-x-3">
<input
type="radio"
name="source"
value="spotify"
bind:group={source}
class="retro-radio"
/>
<span>Spotify</span>
</label>
<label class="flex items-center space-x-3">
<input type="radio" name="source" value="youtube" bind:group={source} class="retro-radio" />
<span>YouTube</span>
</label>
<label class="flex items-center space-x-3">
<input
type="radio"
name="source"
value="other"
bind:group={source}
class="retro-radio"
/>
<span>
Other (<a
href="https://github.com/yt-dlp/yt-dlp/blob/master/supportedsites.md"
target="_blank"
rel="noopener noreferrer"
class="text-pink-500 hover:underline"
>supported sites
</a>)
</span>
</label>
</fieldset>
<label class="flex items-center space-x-3">
<input type="radio" name="source" value="spotify" bind:group={source} class="retro-radio" />
<span>Spotify</span>
</label>
<!-- Link Input -->
<div>
<label for="link" class="block text-green-400 text-sm mb-2">
Enter Playlist or Video Link:
</label>
<input
name="link"
type="url"
id="link"
bind:value={link}
required
placeholder="Paste your link here"
class="w-full px-4 py-3 text-black bg-green-200 border-4 border-green-500 rounded-lg focus:outline-none focus:border-pink-500"
/>
</div>
<label class="flex items-center space-x-3">
<input type="radio" name="source" value="other" bind:group={source} class="retro-radio" />
<span>
Other (<a
href="https://github.com/yt-dlp/yt-dlp/blob/master/supportedsites.md"
target="_blank"
rel="noopener noreferrer"
class="text-pink-500 hover:underline"
>supported sites
</a>)
</span>
</label>
</fieldset>
<!-- Format Selection -->
<div>
<label for="format" class="block text-green-400 text-sm mb-2">
Choose Format:
</label>
<select
id="format"
name="format"
bind:value={format}
class="w-full px-4 py-3 text-black bg-green-200 border-4 border-green-500 rounded-lg focus:outline-none focus:border-pink-500"
>
<option value="mp3">MP3</option>
<option value="ogg">OGG</option>
<option value="mp4">MP4</option>
</select>
</div>
<!-- Link Input -->
<div>
<label for="link" class="mb-2 block text-green-400"> Enter Playlist or Video Link: </label>
<input
name="link"
type="url"
id="link"
bind:value={link}
required
placeholder="Paste your link here"
class="w-full rounded-lg border-4 border-green-500 bg-green-200 px-4 py-3 text-black focus:border-pink-500 focus:outline-none"
/>
</div>
<!-- Submit Button -->
<button
type="submit"
class="w-full px-4 py-3 text-black bg-pink-500 border-4 border-pink-700 rounded-lg hover:bg-pink-600 active:border-yellow-500 transition"
>
Start Download!
</button>
</form>
<!-- Format Selection -->
<div>
<label for="format" class="mb-2 block text-green-400"> Choose Format: </label>
<select
id="format"
name="format"
bind:value={format}
class="w-full rounded-lg border-4 border-green-500 bg-green-200 px-4 py-3 text-black focus:border-pink-500 focus:outline-none"
>
<option value="mp3">MP3</option>
<option value="vorbis">OGG</option>
<option value="mp4">MP4</option>
</select>
</div>
<!-- Submit Button -->
<button
type="submit"
class="w-full rounded-lg border-4 border-pink-700 bg-pink-500 px-4 py-3 text-black transition hover:bg-pink-600 active:border-yellow-500"
>
Start Download!
</button>
</form>
</div>
<!-- Modal -->
{#if showModal}
<div
class="fixed inset-0 flex items-center justify-center bg-black bg-opacity-80 z-50"
>
<div
class="w-4/5 max-w-lg bg-green-900 text-green-100 p-6 rounded-lg border-4 border-green-500 text-center"
>
<h2 class="text-lg mb-4"> Retro Media Downloader Info</h2>
<p class="text-sm">
This app allows you to download Spotify playlists and YouTube videos
directly. Choose your source, paste the link, and select a format to
start downloading!
</p>
<button
onclick={toggleModal}
class="mt-6 px-4 py-2 bg-pink-500 text-black border-4 border-pink-700 rounded-lg hover:bg-pink-600"
>
Close
</button>
</div>
</div>
<div class="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-80">
<div
class="w-4/5 max-w-lg rounded-lg border-4 border-green-500 bg-green-900 p-6 text-center text-green-100"
>
<h2 class="mb-4 text-lg"> Retro Media Downloader Info</h2>
<p>
This app allows you to download Spotify playlists and YouTube videos directly. Choose your
source, paste the link, and select a format to start downloading!
</p>
<button
onclick={toggleModal}
class="mt-6 rounded-lg border-4 border-pink-700 bg-pink-500 px-4 py-2 text-black hover:bg-pink-600"
>
Close
</button>
</div>
</div>
{/if}
<!-- Footer -->
<footer
class="absolute bottom-0 w-[100dvw] mt-10 bg-black text-green-500 text-center py-4 border-t-4 border-green-500"
>
Copyleft © 2024 - Made with ❤️ by Emersa
</footer>
<style>
@import url("https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap");
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
* {
font-family: "Press Start 2P", sans-serif;
}
.retro-radio {
appearance: none;
background-color: #000;
border: 2px solid #39ff14;
width: 20px;
height: 20px;
cursor: pointer;
}
* {
font-size: 12px;
font-family: 'Press Start 2P', sans-serif;
}
.retro-radio {
appearance: none;
background-color: #000;
border: 2px solid #39ff14;
width: 20px;
height: 20px;
cursor: pointer;
}
.retro-radio:checked {
background-color: #39ff14;
box-shadow:
0 0 4px #39ff14,
0 0 10px #39ff14;
}
.retro-radio:checked {
background-color: #39ff14;
box-shadow:
0 0 4px #39ff14,
0 0 10px #39ff14;
}
input[type="url"],
select {
font-family: inherit;
}
.retro-container {
max-width: 800px;
margin: auto;
padding: 20px;
background: rgba(0, 0, 0, 0.8); /* Semi-transparent black */
border: 4px solid #39ff14;
border-radius: 8px;
box-shadow: 0 0 20px #39ff14;
}
input[type='url'],
select {
font-family: inherit;
}
</style>