@@ -12,7 +12,8 @@ import { QueryCacher } from "../utils/queryCacher";
12
12
import { getReputation } from "../utils/reputation" ;
13
13
import { getService } from "../utils/getService" ;
14
14
import { promiseOrTimeout } from "../utils/promise" ;
15
-
15
+ import { parseSkipSegments } from "../utils/parseSkipSegments" ;
16
+ import { getEtag } from "../middleware/etag" ;
16
17
17
18
async function prepareCategorySegments ( req : Request , videoID : VideoID , service : Service , segments : DBSegment [ ] , cache : SegmentCache = { shadowHiddenSegmentIPs : { } } , useCache : boolean ) : Promise < Segment [ ] > {
18
19
const shouldFilter : boolean [ ] = await Promise . all ( segments . map ( async ( segment ) => {
@@ -86,9 +87,6 @@ async function getSegmentsByVideoID(req: Request, videoID: VideoID, categories:
86
87
}
87
88
88
89
try {
89
- categories = categories . filter ( ( category ) => ! / [ ^ a - z | _ | - ] / . test ( category ) ) ;
90
- if ( categories . length === 0 ) return null ;
91
-
92
90
const segments : DBSegment [ ] = ( await getSegmentsFromDBByVideoID ( videoID , service ) )
93
91
. map ( ( segment : DBSegment ) => {
94
92
if ( filterRequiredSegments ( segment . UUID , requiredSegments ) ) segment . required = true ;
@@ -139,9 +137,6 @@ async function getSegmentsByHash(req: Request, hashedVideoIDPrefix: VideoIDHash,
139
137
try {
140
138
type SegmentPerVideoID = SBRecord < VideoID , { segments : DBSegment [ ] } > ;
141
139
142
- categories = categories . filter ( ( category ) => ! ( / [ ^ a - z | _ | - ] / . test ( category ) ) ) ;
143
- if ( categories . length === 0 ) return null ;
144
-
145
140
const segmentPerVideoID : SegmentPerVideoID = ( await getSegmentsFromDBByHash ( hashedVideoIDPrefix , service ) )
146
141
. reduce ( ( acc : SegmentPerVideoID , segment : DBSegment ) => {
147
142
acc [ segment . videoID ] = acc [ segment . videoID ] || {
@@ -396,75 +391,59 @@ function splitPercentOverlap(groups: OverlappingSegmentGroup[]): OverlappingSegm
396
391
} ) ;
397
392
}
398
393
399
- /**
400
- *
401
- * Returns what would be sent to the client.
402
- * Will respond with errors if required. Returns false if it errors.
403
- *
404
- * @param req
405
- * @param res
406
- *
407
- * @returns
408
- */
409
- async function handleGetSegments ( req : Request , res : Response ) : Promise < Segment [ ] | false > {
394
+ async function getSkipSegments ( req : Request , res : Response ) : Promise < Response > {
410
395
const videoID = req . query . videoID as VideoID ;
411
396
if ( ! videoID ) {
412
- res . status ( 400 ) . send ( "videoID not specified" ) ;
413
- return false ;
414
- }
415
- // Default to sponsor
416
- // If using params instead of JSON, only one category can be pulled
417
- const categories : Category [ ] = req . query . categories
418
- ? JSON . parse ( req . query . categories as string )
419
- : req . query . category
420
- ? Array . isArray ( req . query . category )
421
- ? req . query . category
422
- : [ req . query . category ]
423
- : [ "sponsor" ] ;
424
- if ( ! Array . isArray ( categories ) ) {
425
- res . status ( 400 ) . send ( "Categories parameter does not match format requirements." ) ;
426
- return false ;
397
+ return res . status ( 400 ) . send ( "videoID not specified" ) ;
427
398
}
428
399
429
- const actionTypes : ActionType [ ] = req . query . actionTypes
430
- ? JSON . parse ( req . query . actionTypes as string )
431
- : req . query . actionType
432
- ? Array . isArray ( req . query . actionType )
433
- ? req . query . actionType
434
- : [ req . query . actionType ]
435
- : [ ActionType . Skip ] ;
436
- if ( ! Array . isArray ( actionTypes ) ) {
437
- res . status ( 400 ) . send ( "actionTypes parameter does not match format requirements." ) ;
438
- return false ;
400
+ const parseResult = parseSkipSegments ( req ) ;
401
+ if ( parseResult . errors . length > 0 ) {
402
+ return res . status ( 400 ) . send ( parseResult . errors ) ;
439
403
}
440
404
441
- const requiredSegments : SegmentUUID [ ] = req . query . requiredSegments
442
- ? JSON . parse ( req . query . requiredSegments as string )
443
- : req . query . requiredSegment
444
- ? Array . isArray ( req . query . requiredSegment )
445
- ? req . query . requiredSegment
446
- : [ req . query . requiredSegment ]
447
- : [ ] ;
448
- if ( ! Array . isArray ( requiredSegments ) ) {
449
- res . status ( 400 ) . send ( "requiredSegments parameter does not match format requirements." ) ;
450
- return false ;
405
+ const { categories, actionTypes, requiredSegments, service } = parseResult ;
406
+ const segments = await getSegmentsByVideoID ( req , videoID , categories , actionTypes , requiredSegments , service ) ;
407
+
408
+ if ( segments === null || segments === undefined ) {
409
+ return res . sendStatus ( 500 ) ;
410
+ } else if ( segments . length === 0 ) {
411
+ return res . sendStatus ( 404 ) ;
451
412
}
452
413
453
- const service = getService ( req . query . service , req . body . service ) ;
414
+ await getEtag ( "skipSegments" , ( videoID as string ) , service )
415
+ . then ( etag => res . set ( "ETag" , etag ) )
416
+ . catch ( ( ) => null ) ;
417
+ return res . send ( segments ) ;
418
+ }
454
419
455
- const segments = await getSegmentsByVideoID ( req , videoID , categories , actionTypes , requiredSegments , service ) ;
420
+ async function oldGetVideoSponsorTimes ( req : Request , res : Response ) : Promise < Response > {
421
+ const videoID = req . query . videoID as VideoID ;
422
+ if ( ! videoID ) {
423
+ return res . status ( 400 ) . send ( "videoID not specified" ) ;
424
+ }
425
+
426
+ const segments = await getSegmentsByVideoID ( req , videoID , [ "sponsor" ] as Category [ ] , [ ActionType . Skip ] , [ ] , Service . YouTube ) ;
456
427
457
428
if ( segments === null || segments === undefined ) {
458
- res . sendStatus ( 500 ) ;
459
- return false ;
429
+ return res . sendStatus ( 500 ) ;
430
+ } else if ( segments . length === 0 ) {
431
+ return res . sendStatus ( 404 ) ;
460
432
}
461
433
462
- if ( segments . length === 0 ) {
463
- res . sendStatus ( 404 ) ;
464
- return false ;
434
+ // Convert to old outputs
435
+ const sponsorTimes = [ ] ;
436
+ const UUIDs = [ ] ;
437
+
438
+ for ( const segment of segments ) {
439
+ sponsorTimes . push ( segment . segment ) ;
440
+ UUIDs . push ( segment . UUID ) ;
465
441
}
466
442
467
- return segments ;
443
+ return res . send ( {
444
+ sponsorTimes,
445
+ UUIDs,
446
+ } ) ;
468
447
}
469
448
470
449
const filterRequiredSegments = ( UUID : SegmentUUID , requiredSegments : SegmentUUID [ ] ) : boolean => {
@@ -474,25 +453,9 @@ const filterRequiredSegments = (UUID: SegmentUUID, requiredSegments: SegmentUUID
474
453
return false ;
475
454
} ;
476
455
477
- async function endpoint ( req : Request , res : Response ) : Promise < Response > {
478
- try {
479
- const segments = await handleGetSegments ( req , res ) ;
480
-
481
- // If false, res.send has already been called
482
- if ( segments ) {
483
- //send result
484
- return res . send ( segments ) ;
485
- }
486
- } catch ( err ) /* istanbul ignore next */ {
487
- if ( err instanceof SyntaxError ) {
488
- return res . status ( 400 ) . send ( "Categories parameter does not match format requirements." ) ;
489
- } else return res . sendStatus ( 500 ) ;
490
- }
491
- }
492
-
493
456
export {
494
457
getSegmentsByVideoID ,
495
458
getSegmentsByHash ,
496
- endpoint ,
497
- handleGetSegments
459
+ getSkipSegments ,
460
+ oldGetVideoSponsorTimes
498
461
} ;
0 commit comments