Minimal online import implementation
This commit is contained in:
@@ -24,7 +24,7 @@
|
||||
class="flex flex-row gap-5 items-center justify-between w-full"
|
||||
>
|
||||
<div>
|
||||
<p class="font-semibold" class:text-white={!isComplete}>{volumeName}</p>
|
||||
<p class="font-semibold" class:text-white={!isComplete}>{decodeURI(volumeName)}</p>
|
||||
<p>{progressDisplay}</p>
|
||||
</div>
|
||||
{#if isComplete}
|
||||
|
||||
@@ -4,6 +4,8 @@ import { showSnackbar } from '$lib/util/snackbar';
|
||||
import { requestPersistentStorage } from '$lib/util/upload';
|
||||
import { BlobReader, ZipReader, BlobWriter, getMimeType } from '@zip.js/zip.js';
|
||||
|
||||
export * from './web-import'
|
||||
|
||||
const zipTypes = ['zip', 'cbz', 'ZIP', 'CBZ'];
|
||||
const imageTypes = ['image/jpeg', 'image/png', 'image/webp'];
|
||||
|
||||
|
||||
7
src/lib/upload/web-import.ts
Normal file
7
src/lib/upload/web-import.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export function getItems(html: string) {
|
||||
const parser = new DOMParser();
|
||||
const htmlDoc = parser.parseFromString(html, 'text/html');
|
||||
|
||||
const items = htmlDoc.getElementsByTagName('a');
|
||||
return [...items]
|
||||
}
|
||||
@@ -1,19 +1,64 @@
|
||||
<script lang="ts">
|
||||
import Catalog from '$lib/components/Catalog.svelte';
|
||||
import FileUpload from '$lib/components/FileUpload.svelte';
|
||||
import { processFiles } from '$lib/upload';
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
import Loader from '$lib/components/Loader.svelte';
|
||||
import { getItems, processFiles } from '$lib/upload';
|
||||
import { Button } from 'flowbite-svelte';
|
||||
export const BASE_URL = 'https://www.mokuro.moe/manga';
|
||||
|
||||
let promise: Promise<void>;
|
||||
const manga = $page.url.searchParams.get('manga');
|
||||
const volume = $page.url.searchParams.get('volume');
|
||||
const url = `${BASE_URL}/${manga}/${volume}`;
|
||||
|
||||
async function onUpload(files: FileList) {
|
||||
promise = processFiles([...files]);
|
||||
let message = 'Loading...';
|
||||
let loading = false;
|
||||
|
||||
let files: File[] = [];
|
||||
|
||||
async function onImport() {
|
||||
loading = true;
|
||||
const mokuroRes = await fetch(url + '.mokuro');
|
||||
const mokuroBlob = await mokuroRes.blob();
|
||||
const mokuroFile = new File([mokuroBlob], volume + '.mokuro', { type: mokuroBlob.type });
|
||||
|
||||
Object.defineProperty(mokuroFile, 'webkitRelativePath', {
|
||||
value: '/' + volume + '.mokuro'
|
||||
});
|
||||
|
||||
const res = await fetch(url + '/');
|
||||
const html = await res.text();
|
||||
|
||||
const items = getItems(html);
|
||||
message = 'Downloading images...';
|
||||
|
||||
const imageTypes = ['.jpg', '.png', '.webp'];
|
||||
|
||||
for (const item of items) {
|
||||
if (imageTypes.includes('.' + item.pathname.split('.').at(-1) || '')) {
|
||||
const image = await fetch(url + item.pathname);
|
||||
const blob = await image.blob();
|
||||
const file = new File([blob], item.pathname.substring(1));
|
||||
Object.defineProperty(file, 'webkitRelativePath', {
|
||||
value: '/' + volume + item.pathname
|
||||
});
|
||||
|
||||
files.push(file);
|
||||
}
|
||||
}
|
||||
files.push(mokuroFile);
|
||||
files = files;
|
||||
message = 'Adding to catalog...';
|
||||
console.log(files);
|
||||
|
||||
processFiles(files).then(() => {
|
||||
goto('/');
|
||||
});
|
||||
loading = true;
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Note: webkitdirectory is not fully supported and does not work on mobile -->
|
||||
<FileUpload {onUpload} webkitdirectory>Upload directory</FileUpload>
|
||||
<FileUpload {onUpload} accept=".mokuro,.zip,.cbz" multiple>Upload files</FileUpload>
|
||||
|
||||
{#await promise}
|
||||
<h2>Loading...</h2>
|
||||
{/await}
|
||||
{#if loading}
|
||||
<Loader>{message}</Loader>
|
||||
{:else}
|
||||
<Button on:click={onImport}>Import {decodeURI(volume || '')} into catalog?</Button>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user