@@ -32,9 +32,10 @@ export const ytdlpRouter = router({
3232 url : z . string ( ) . url ( ) . array ( )
3333 } )
3434 )
35- . mutation ( async ( { input : { url } , ctx } ) => {
35+ . mutation ( async ( { input : { url : urls } , ctx } ) => {
36+ const dbEntries = await addToDatabase ( urls )
3637 const files = await queuePromiseStack (
37- url . map ( ( u ) => ( ) => queueYtdlMetaCheck ( u ) . catch ( ( ) => null ) ) ,
38+ dbEntries . map ( ( u ) => ( ) => queueYtdlMetaCheck ( u ) . catch ( ( ) => null ) ) ,
3839 MAX_PARALLEL_DOWNLOADS
3940 ) . then ( ( files ) => files . filter ( ( s ) => ! ! s ) )
4041 const asyncResult = ytdlpDownloadQueue . addAll (
@@ -231,14 +232,42 @@ const deleteDownloadItem = (dbFile: SelectDownload) =>
231232 } )
232233 }
233234 } )
235+ const addToDatabase = async ( urls : string [ ] ) => {
236+ const [ items ] = await db . batch (
237+ urls
238+ . map ( ( url ) => {
239+ if ( typeof url !== 'string' || ! / ^ h t t p s / gi. test ( url ) ) return null
240+ return queries . downloads . createDownload ( {
241+ filepath : '' ,
242+ filesize : 0 ,
243+ meta : { } as any ,
244+ metaId : '' ,
245+ source : new URL ( url ) . hostname ,
246+ title : url ,
247+ url,
248+ state : 'queued' ,
249+ type : null ,
250+ error : null ,
251+ retryCount : 0
252+ } )
253+ } )
254+ . filter ( Boolean ) as any
255+ )
256+ ytdlpEvents . emit ( 'list' , items )
257+ log . debug ( 'addToDatabase' , { items } )
258+ return items as SelectDownload [ ]
259+ }
234260const queueYtdlMetaCheck = async (
235- url : string
261+ createdDbFile : SelectDownload
236262) : Promise < { dbFile : SelectDownload ; videoInfo : VideoInfo } > => {
237- if ( typeof url !== 'string' || ! / ^ h t t p s / gi. test ( url ) ) throw new Error ( 'Invalid url format' )
263+ const { url } = createdDbFile
264+ log . debug ( 'meta' , `added url` , url , createdDbFile )
265+ if ( ! createdDbFile . url ) throw new Error ( 'Invalid url format' )
238266 ytdlpEvents . emit ( 'status' , { action : 'getVideoInfo' , state : 'progressing' } )
239- log . debug ( 'meta' , `added url ${ url } ` )
240- const existingDbFile = await queries . downloads . findDownloadByExactUrl ( url )
241- let [ dbFile ] = await queries . downloads . createDownload ( {
267+ let dbFile = await queries . downloads . findDownloadById ( createdDbFile . id )
268+ if ( ! dbFile ) throw new Error ( 'Entry has been not found or has been removed' )
269+ const existingDbFile = await queries . downloads . findDownloadByExactUrl ( url , dbFile . id )
270+ Object . assign ( dbFile , {
242271 metaId : existingDbFile ?. metaId ?? '' ,
243272 meta : existingDbFile ?. meta ?? ( { } as any ) ,
244273 filepath : existingDbFile ?. filepath ?? '' ,
@@ -247,10 +276,10 @@ const queueYtdlMetaCheck = async (
247276 state : 'fetching_meta' ,
248277 title : existingDbFile ?. title ?? url ,
249278 type : null ,
250- url,
251279 error : null ,
252280 retryCount : 0
253281 } )
282+ await queries . downloads . updateDownload ( dbFile . id , dbFile )
254283 ytdlpEvents . emit ( 'list' , [ dbFile ] )
255284 if ( ! dbFile . meta ?. filename ) {
256285 const { value : videoInfo , error : videoInfoError } = await ytdl . getVideoInfo ( url )
@@ -372,8 +401,9 @@ const queueYtdlDownload = async (dbFile: SelectDownload, videoInfo: VideoInfo) =
372401 pushLogToClient ( `[${ dbFile . id } =${ dbFile . metaId } ] finished download: ${ dbFile . title } ` , 'success' )
373402 return await updateEntry ( )
374403}
375- function handleYtAddEvent ( url : string ) {
376- queueYtdlMetaCheck ( url ) . then ( ( { dbFile, videoInfo } ) => {
404+ async function handleYtAddEvent ( url : string ) {
405+ const [ newDbFile ] = await addToDatabase ( [ url ] )
406+ await queueYtdlMetaCheck ( newDbFile ) . then ( ( { dbFile, videoInfo } ) => {
377407 const asyncResult = ytdlpDownloadQueue . add ( ( ) => queueYtdlDownload ( dbFile , videoInfo ) )
378408 if ( ytdlpDownloadQueue . isPaused ) ytdlpDownloadQueue . start ( )
379409 return asyncResult
0 commit comments