Add manga extracting
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { catalog } from '$lib/catalog';
|
||||
import { P } from 'flowbite-svelte';
|
||||
|
||||
export let id: string;
|
||||
|
||||
|
||||
@@ -2,3 +2,4 @@ export * from './snackbar';
|
||||
export * from './upload';
|
||||
export * from './misc';
|
||||
export * from './modals';
|
||||
export * from './zip'
|
||||
56
src/lib/util/zip.ts
Normal file
56
src/lib/util/zip.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import type { Volume } from "$lib/types";
|
||||
import {
|
||||
BlobReader,
|
||||
BlobWriter,
|
||||
TextReader,
|
||||
ZipWriter,
|
||||
} from "@zip.js/zip.js";
|
||||
|
||||
async function zipVolumes(manga: Volume[]) {
|
||||
const volumeZips = []
|
||||
|
||||
for (const volume of manga) {
|
||||
const files = Object.values(volume.files);
|
||||
const zipWriter = new ZipWriter(new BlobWriter("application/zip"));
|
||||
|
||||
const promises = files.map((file) => {
|
||||
return zipWriter.add(file.name, new BlobReader(file))
|
||||
})
|
||||
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
|
||||
volumeZips.push({
|
||||
zipName: volume.volumeName,
|
||||
zipBlob: await zipWriter.close(),
|
||||
mokuroData: JSON.stringify(volume.mokuroData)
|
||||
});
|
||||
}
|
||||
|
||||
return volumeZips;
|
||||
}
|
||||
|
||||
export async function zipManga(manga: Volume[]) {
|
||||
const volumeZips = await zipVolumes(manga)
|
||||
const zipWriter = new ZipWriter(new BlobWriter("application/zip"));
|
||||
|
||||
|
||||
const promises = volumeZips.map((volumeZip) => {
|
||||
return [
|
||||
zipWriter.add(`${volumeZip.zipName}.mokuro`, new TextReader(volumeZip.mokuroData)),
|
||||
zipWriter.add(`${volumeZip.zipName}.zip`, new BlobReader(volumeZip.zipBlob))
|
||||
]
|
||||
})
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
const zipFileBlob = await zipWriter.close();
|
||||
|
||||
const link = document.createElement('a');
|
||||
link.href = URL.createObjectURL(zipFileBlob);
|
||||
link.download = `${manga[0].mokuroData.title}.zip`;
|
||||
link.click();
|
||||
|
||||
return false
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
import { catalog } from '$lib/catalog';
|
||||
import { goto } from '$app/navigation';
|
||||
import VolumeItem from '$lib/components/VolumeItem.svelte';
|
||||
import { Button, Listgroup } from 'flowbite-svelte';
|
||||
import { Button, Listgroup, Progressbar, Spinner } from 'flowbite-svelte';
|
||||
import { db } from '$lib/catalog/db';
|
||||
import { promptConfirmation } from '$lib/util';
|
||||
import { promptConfirmation, zipManga } from '$lib/util';
|
||||
import { page } from '$app/stores';
|
||||
import type { Volume } from '$lib/types';
|
||||
import { deleteVolume, volumes } from '$lib/settings';
|
||||
@@ -38,6 +38,8 @@
|
||||
{ timeReadInMinutes: 0, chars: 0, completed: 0 }
|
||||
);
|
||||
|
||||
$: loading = false;
|
||||
|
||||
async function confirmDelete() {
|
||||
const title = manga?.[0].mokuroData.title_uuid;
|
||||
manga?.forEach((vol) => {
|
||||
@@ -52,6 +54,13 @@
|
||||
function onDelete() {
|
||||
promptConfirmation('Are you sure you want to delete this manga?', confirmDelete);
|
||||
}
|
||||
|
||||
async function onExtract() {
|
||||
if (manga) {
|
||||
loading = true;
|
||||
loading = await zipManga(manga);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
@@ -70,6 +79,9 @@
|
||||
</div>
|
||||
<div>
|
||||
<Button color="alternative" on:click={onDelete}>Remove manga</Button>
|
||||
<Button color="light" on:click={onExtract} disabled={loading}>
|
||||
{loading ? 'Extracting...' : 'Extract manga'}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<Listgroup items={manga} let:item active class="flex-1 h-full w-full">
|
||||
|
||||
Reference in New Issue
Block a user