mirror of
https://github.com/ThaUnknown/miru.git
synced 2026-01-12 00:03:44 +00:00
feat: NNTP streaming
This commit is contained in:
parent
de3da8acf8
commit
f2b6f12fcb
8 changed files with 75 additions and 19 deletions
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "ui",
|
||||
"version": "6.4.150",
|
||||
"version": "6.4.151",
|
||||
"license": "BUSL-1.1",
|
||||
"private": true,
|
||||
"packageManager": "pnpm@9.15.5",
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ importers:
|
|||
version: 1.8.13(@gql.tada/svelte-support@1.0.1(svelte@4.2.19)(typescript@5.9.2))(graphql@16.10.0)(typescript@5.9.2)
|
||||
hayase-extensions:
|
||||
specifier: github:hayase-app/extensions
|
||||
version: https://codeload.github.com/hayase-app/extensions/tar.gz/0fad214a4a0aacd826c0801255ced65bd1d49a13
|
||||
version: https://codeload.github.com/hayase-app/extensions/tar.gz/2c43ec0bf157733901be1ad9188b64933aac2e15
|
||||
jassub:
|
||||
specifier: ^1.8.6
|
||||
version: 1.8.6
|
||||
|
|
@ -197,7 +197,7 @@ importers:
|
|||
version: 2.1.3
|
||||
native:
|
||||
specifier: github:hayase-app/native
|
||||
version: https://codeload.github.com/hayase-app/native/tar.gz/b77747898ca7e4991fac752559ea159c8c0f5083
|
||||
version: https://codeload.github.com/hayase-app/native/tar.gz/e8045ec8878086117a9c3b52dcff069f4b9b48e8
|
||||
rollup-plugin-license:
|
||||
specifier: ^3.6.0
|
||||
version: 3.6.0(picomatch@4.0.3)(rollup@4.40.2)
|
||||
|
|
@ -1711,8 +1711,8 @@ packages:
|
|||
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
hayase-extensions@https://codeload.github.com/hayase-app/extensions/tar.gz/0fad214a4a0aacd826c0801255ced65bd1d49a13:
|
||||
resolution: {tarball: https://codeload.github.com/hayase-app/extensions/tar.gz/0fad214a4a0aacd826c0801255ced65bd1d49a13}
|
||||
hayase-extensions@https://codeload.github.com/hayase-app/extensions/tar.gz/2c43ec0bf157733901be1ad9188b64933aac2e15:
|
||||
resolution: {tarball: https://codeload.github.com/hayase-app/extensions/tar.gz/2c43ec0bf157733901be1ad9188b64933aac2e15}
|
||||
version: 1.0.6
|
||||
|
||||
idb-keyval@6.2.2:
|
||||
|
|
@ -2051,8 +2051,8 @@ packages:
|
|||
engines: {node: ^18 || >=20}
|
||||
hasBin: true
|
||||
|
||||
native@https://codeload.github.com/hayase-app/native/tar.gz/b77747898ca7e4991fac752559ea159c8c0f5083:
|
||||
resolution: {tarball: https://codeload.github.com/hayase-app/native/tar.gz/b77747898ca7e4991fac752559ea159c8c0f5083}
|
||||
native@https://codeload.github.com/hayase-app/native/tar.gz/e8045ec8878086117a9c3b52dcff069f4b9b48e8:
|
||||
resolution: {tarball: https://codeload.github.com/hayase-app/native/tar.gz/e8045ec8878086117a9c3b52dcff069f4b9b48e8}
|
||||
version: 1.0.0
|
||||
|
||||
natural-compare@1.4.0:
|
||||
|
|
@ -4560,7 +4560,7 @@ snapshots:
|
|||
dependencies:
|
||||
function-bind: 1.1.2
|
||||
|
||||
hayase-extensions@https://codeload.github.com/hayase-app/extensions/tar.gz/0fad214a4a0aacd826c0801255ced65bd1d49a13: {}
|
||||
hayase-extensions@https://codeload.github.com/hayase-app/extensions/tar.gz/2c43ec0bf157733901be1ad9188b64933aac2e15: {}
|
||||
|
||||
idb-keyval@6.2.2: {}
|
||||
|
||||
|
|
@ -4865,7 +4865,7 @@ snapshots:
|
|||
|
||||
nanoid@5.1.5: {}
|
||||
|
||||
native@https://codeload.github.com/hayase-app/native/tar.gz/b77747898ca7e4991fac752559ea159c8c0f5083: {}
|
||||
native@https://codeload.github.com/hayase-app/native/tar.gz/e8045ec8878086117a9c3b52dcff069f4b9b48e8: {}
|
||||
|
||||
natural-compare@1.4.0: {}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Hayase</title>
|
||||
<link rel="preconnect" href="https://graphql.anilist.co/">
|
||||
<link rel="preconnect" href="https://www.youtube-nocookie.com">
|
||||
<link rel="icon" href="%sveltekit.assets%/logo_white_fit.svg" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -13,5 +13,6 @@
|
|||
<div class='text-muted-foreground'>
|
||||
{location.country}
|
||||
</div>
|
||||
{:catch}
|
||||
{/await}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import anitomyscript, { type AnitomyResult } from 'anitomyscript'
|
||||
import Debug from 'debug'
|
||||
import { get } from 'svelte/store'
|
||||
import { toast } from 'svelte-sonner'
|
||||
|
||||
import { dedupeAiring, episodes, isMovie, type Media, getParentForSpecial, isSingleEpisode } from '../anilist'
|
||||
import { episodes as _episodes } from '../anizip'
|
||||
|
|
@ -203,13 +204,14 @@ export const extensions = new class Extensions {
|
|||
debug(`Checking ${Object.keys(workers).length} extensions for ${media.id}:${media.title?.userPreferred} ${episode} ${resolution} ${checkMovie ? 'movie' : ''} ${checkBatch ? 'batch' : ''}`)
|
||||
|
||||
for (const [id, worker] of Object.entries(workers)) {
|
||||
if (!extopts[id]!.enabled) continue
|
||||
const thisExtOpts = extopts[id]!
|
||||
if (!thisExtOpts.enabled) continue
|
||||
if (configs[id]!.type !== 'torrent') continue
|
||||
try {
|
||||
const promises: Array<Promise<TorrentResult[]>> = []
|
||||
promises.push(worker.single(options))
|
||||
if (checkMovie) promises.push(worker.movie(options))
|
||||
if (checkBatch) promises.push(worker.batch(options))
|
||||
promises.push(worker.single(options, thisExtOpts.options))
|
||||
if (checkMovie) promises.push(worker.movie(options, thisExtOpts.options))
|
||||
if (checkBatch) promises.push(worker.batch(options, thisExtOpts.options))
|
||||
|
||||
for (const result of await Promise.allSettled(promises)) {
|
||||
if (result.status === 'fulfilled') {
|
||||
|
|
@ -246,6 +248,37 @@ export const extensions = new class Extensions {
|
|||
return { results: navigator.onLine ? await this.updatePeerCounts(deduped) : deduped, errors }
|
||||
}
|
||||
|
||||
async getNZBResultsFromExtensions (hash: string) {
|
||||
await storage.modules
|
||||
const workers = storage.workers
|
||||
const results: Array<{ nzb: string, options: Record<string, string> }> = []
|
||||
const errors: Array<{ error: Error, extension: string }> = []
|
||||
|
||||
const extopts = get(extensionOptions)
|
||||
const configs = get(saved)
|
||||
|
||||
for (const [id, worker] of Object.entries(workers)) {
|
||||
const thisExtOpts = extopts[id]!
|
||||
if (!thisExtOpts.enabled) continue
|
||||
if (configs[id]!.type !== 'nzb') continue
|
||||
try {
|
||||
const nzb = await worker.query(hash, thisExtOpts.options)
|
||||
if (!nzb) continue
|
||||
results.push({ nzb, options: thisExtOpts.options })
|
||||
} catch (error) {
|
||||
errors.push({ error: error as Error, extension: id })
|
||||
}
|
||||
}
|
||||
|
||||
if (errors.length) {
|
||||
for (const { error, extension } of errors) {
|
||||
toast.error(`Error fetching NZB from ${configs[extension]?.name ?? extension}`, { description: error.message })
|
||||
}
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
async updatePeerCounts <T extends TorrentResult[]> (entries: T): Promise<T> {
|
||||
debug(`Updating peer counts for ${entries.length} entries`)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
import { finalizer } from 'abslink'
|
||||
import { expose } from 'abslink/w3c'
|
||||
|
||||
import type { SearchFunction, TorrentSource } from 'hayase-extensions'
|
||||
import type { SearchFunction, TorrentSource, NZBorURLSource } from 'hayase-extensions'
|
||||
|
||||
export default expose({
|
||||
mod: null as unknown as Promise<TorrentSource>,
|
||||
mod: null as unknown as Promise<TorrentSource | NZBorURLSource>,
|
||||
construct (code: string) {
|
||||
this.mod = this.load(code)
|
||||
},
|
||||
|
||||
async load (code: string): Promise<TorrentSource> {
|
||||
async load (code: string): Promise<TorrentSource | NZBorURLSource> {
|
||||
// WARN: unsafe eval
|
||||
const url = URL.createObjectURL(new Blob([code], { type: 'application/javascript' }))
|
||||
const module = await import(/* @vite-ignore */url)
|
||||
|
|
@ -22,15 +22,19 @@ export default expose({
|
|||
},
|
||||
|
||||
async single (...args: Parameters<SearchFunction>): ReturnType<SearchFunction> {
|
||||
return await ((await this.mod)).single(...args)
|
||||
return await ((await this.mod) as TorrentSource).single(...args)
|
||||
},
|
||||
|
||||
async batch (...args: Parameters<SearchFunction>): ReturnType<SearchFunction> {
|
||||
return await ((await this.mod)).batch(...args)
|
||||
return await ((await this.mod) as TorrentSource).batch(...args)
|
||||
},
|
||||
|
||||
async movie (...args: Parameters<SearchFunction>): ReturnType<SearchFunction> {
|
||||
return await ((await this.mod)).movie(...args)
|
||||
return await ((await this.mod) as TorrentSource).movie(...args)
|
||||
},
|
||||
|
||||
async query (...args: Parameters<NZBorURLSource['query']>) {
|
||||
return await ((await this.mod) as NZBorURLSource).query(...args)
|
||||
},
|
||||
|
||||
async test () {
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ export default Object.assign<Native, Partial<Native>>({
|
|||
navigate: async () => undefined,
|
||||
downloadProgress: async () => undefined,
|
||||
updateProgress: async () => undefined,
|
||||
createNZB: async () => undefined,
|
||||
torrentInfo: async (): Promise<TorrentInfo> => ({
|
||||
name: '',
|
||||
progress: 0,
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@ import Debug from 'debug'
|
|||
import { writable } from 'simple-store-svelte'
|
||||
import { get } from 'svelte/store'
|
||||
import { persisted } from 'svelte-persisted-store'
|
||||
import { toast } from 'svelte-sonner'
|
||||
|
||||
import client from '../auth/client'
|
||||
import { extensions } from '../extensions'
|
||||
import native from '../native'
|
||||
import { SUPPORTS } from '../settings'
|
||||
import { w2globby } from '../w2g/lobby'
|
||||
|
|
@ -97,8 +99,21 @@ export const server = new class ServerClient {
|
|||
const result = { id, media, episode, files: await native.playTorrent(id, media.id, episode) }
|
||||
debug('torrent play result', result)
|
||||
this.downloaded.value = this.cachedSet()
|
||||
this._addNZBs(result.files[0]!.hash)
|
||||
return result
|
||||
}
|
||||
|
||||
async _addNZBs (hash: string) {
|
||||
const nzbs = await extensions.getNZBResultsFromExtensions(hash)
|
||||
|
||||
for (const { nzb, options } of nzbs) {
|
||||
try {
|
||||
await native.createNZB(hash, nzb, options.domain!, Number(options.port!), options.username!, options.password!, Number(options.poolSize!))
|
||||
} catch (e) {
|
||||
toast.error('Failed to add NZB', { description: (e as Error).message })
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
requestIdleCallback(() => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue