@@ -6,6 +6,8 @@ import {Settings} from "../settings";
6
6
import { StringUtils } from "../stringUtils" ;
7
7
import { Utils } from "../utils" ;
8
8
9
+ import { SmartValue } from "../communicator/smartValue" ;
10
+
9
11
import { AugmentationModel } from "../contentCapture/augmentationHelper" ;
10
12
import { PdfScreenshotResult } from "../contentCapture/pdfScreenshotHelper" ;
11
13
@@ -37,7 +39,7 @@ export class SaveToOneNote {
37
39
// Used by PDF mode
38
40
private static maxImagesPerPatchRequest = 15 ;
39
41
private static timeBeforeFirstPatch = 1000 ;
40
- private static timeBetweenPatchRequests = 5000 ;
42
+ private static timeBetweenPatchRequests = 7000 ;
41
43
42
44
/**
43
45
* Checks for the 1) data result from creating a new page on clip, and 2) completion of the show ratings prompt calculation
@@ -287,13 +289,6 @@ export class SaveToOneNote {
287
289
}
288
290
}
289
291
290
- private static getAllPdfPageIndexesToBeSent ( ) : number [ ] {
291
- if ( this . clipperState . pdfPreviewInfo . allPages ) {
292
- return _ . range ( this . clipperState . pdfResult . data . get ( ) . viewportDimensions . length ) ;
293
- }
294
- return StringUtils . parsePageRange ( this . clipperState . pdfPreviewInfo . selectedPageRange ) . map ( ( indexFromOne ) => indexFromOne - 1 ) ;
295
- }
296
-
297
292
// Note this is called only after we finish waiting on the pdf request
298
293
private static logPdfOptions ( ) {
299
294
let clipPdfEvent = new Log . Event . BaseEvent ( Log . Event . Label . ClipPdfOptions ) ;
@@ -313,64 +308,44 @@ export class SaveToOneNote {
313
308
/**
314
309
* Executes the request(s) needed to save the clip to OneNote
315
310
*/
316
- private static executeApiRequest ( page : OneNoteApi . OneNotePage , clipMode : ClipMode ) : Promise < any > {
311
+ private static executeApiRequest ( page : OneNoteApi . OneNotePage , clipMode : ClipMode ) : Promise < OneNoteApi . ResponsePackage < any > > {
317
312
if ( clipMode === ClipMode . Pdf ) {
318
- return SaveToOneNote . patchPdfPages ( page ) ;
313
+ return SaveToOneNote . createAndPatchPdfPage ( page , SaveToOneNote . getAllPdfPageIndexesToBeSent ( ) ) ;
319
314
}
320
315
321
316
let saveLocation = SaveToOneNote . clipperState . saveLocation ;
322
317
return SaveToOneNote . getApiInstance ( ) . createPage ( page , saveLocation ) ;
323
318
}
324
319
325
- /**
326
- * Starting from the 31st PDF page, divides the remaining PDF pages as evenly as possible, where each
327
- * group has <= 30 pages, and then chains them all to be sent to OneNote as PATCH requests. Simply
328
- * resolves if there are no PDF pages to PATCH.
329
- */
330
- private static patchPdfPages ( page : OneNoteApi . OneNotePage ) : Promise < any > {
331
- let clipperState = SaveToOneNote . clipperState ;
332
- let previewOptions = clipperState . pdfPreviewInfo ;
333
- let pdfDocumentProxy = clipperState . pdfResult . data . get ( ) . pdf ;
334
-
335
- let indexesToBePatched = SaveToOneNote . getAllPdfPageIndexesToBeSent ( ) ;
336
- if ( indexesToBePatched . length === 0 ) {
337
- return new Promise < any > ( ( resolve ) => { resolve ( ) ; } ) ;
320
+ private static getAllPdfPageIndexesToBeSent ( ) : number [ ] {
321
+ if ( this . clipperState . pdfPreviewInfo . allPages ) {
322
+ return _ . range ( this . clipperState . pdfResult . data . get ( ) . viewportDimensions . length ) ;
338
323
}
324
+ return StringUtils . parsePageRange ( this . clipperState . pdfPreviewInfo . selectedPageRange ) . map ( ( indexFromOne ) => indexFromOne - 1 ) ;
325
+ }
339
326
340
- let indexesToBePatchedRanges = ArrayUtils . partition ( indexesToBePatched , SaveToOneNote . maxImagesPerPatchRequest ) ;
341
-
342
- return SaveToOneNote . checkIfUserHasPermissionToPatch ( ) . then ( ( ) => {
343
- return SaveToOneNote . pdfCreatePage ( page ) . then ( ( postPageResponse /* should also be a onenote response */ ) => {
344
- let pageId = postPageResponse . parsedResponse . id ;
345
-
346
- // As of 10/27/16, the page is not always ready when the 200 is returned, so we wait a bit, and then getPageContent with retries
347
- // When the getPageContent returns a 200, we start PATCHing the page.
348
- let timeBetweenPatchRequests = SaveToOneNote . timeBeforeFirstPatch ;
349
- return Promise . all ( [ postPageResponse ,
350
- indexesToBePatchedRanges . reduce ( ( chainedPromise , currentIndexesRange ) => {
351
- return chainedPromise = chainedPromise . then ( ( returnValueOfPreviousPromise /* should be a onenote response */ ) => {
352
- return new Promise ( ( resolve , reject ) => {
353
- // OneNote API returns 204 on a PATCH request when it receives it, but we have no way of telling when it actually
354
- // completes processing, so we add an artificial timeout before the next PATCH to try and ensure that they get
355
- // processed in the order that they were sent.
356
- setTimeout ( ( ) => {
357
- SaveToOneNote . createOneNotePagePatchRequest ( pageId , currentIndexesRange ) . then ( ( ) => {
358
- timeBetweenPatchRequests = SaveToOneNote . timeBetweenPatchRequests ;
359
- resolve ( ) ;
360
- } ) . catch ( ( error ) => {
361
- reject ( error ) ;
362
- } ) ;
363
- } , timeBetweenPatchRequests ) ;
364
- } ) ;
365
- } ) ;
366
- } , SaveToOneNote . getOneNotePageContentWithRetries ( pageId , 3 ) )
367
- ] ) ;
327
+ /**
328
+ * Creates a page for the PDF clipping, then sends PATCH requests to it. Resolves with the createPage
329
+ * response package when all operations are complete; rejects otherwise.
330
+ */
331
+ private static createAndPatchPdfPage ( page : OneNoteApi . OneNotePage , pageIndexes : number [ ] ) : Promise < OneNoteApi . ResponsePackage < any > > {
332
+ return new Promise < OneNoteApi . ResponsePackage < any > > ( ( resolve , reject ) => {
333
+ SaveToOneNote . checkIfUserHasPermissionToPatch ( ) . then ( ( ) => {
334
+ SaveToOneNote . pdfCreatePage ( page ) . then ( ( postPageResponse /* should also be a onenote response */ ) => {
335
+ let pageId = postPageResponse . parsedResponse . id ;
336
+ SaveToOneNote . sendPagesAsPatchRequests ( pageId , pageIndexes ) . then ( ( ) => {
337
+ resolve ( postPageResponse ) ;
338
+ } ) ;
339
+ } ) ;
340
+ } ) . catch ( ( error ) => {
341
+ return Promise . reject ( error ) ;
368
342
} ) ;
369
- } ) . catch ( ( error ) => {
370
- return Promise . reject ( error ) ;
371
343
} ) ;
372
344
}
373
345
346
+ /**
347
+ * Resolves if true; false otherwise
348
+ */
374
349
private static checkIfUserHasPermissionToPatch ( ) : Promise < void > {
375
350
return new Promise < any > ( ( resolve , reject ) => {
376
351
Clipper . getStoredValue ( ClipperStorageKeys . hasPatchPermissions , ( hasPermissions ) => {
@@ -397,7 +372,10 @@ export class SaveToOneNote {
397
372
} ) ;
398
373
}
399
374
400
- private static pdfCreatePage ( page : OneNoteApi . OneNotePage ) : Promise < any > {
375
+ /**
376
+ * Creates the initial page for the PDF clipping
377
+ */
378
+ private static pdfCreatePage ( page : OneNoteApi . OneNotePage ) : Promise < OneNoteApi . ResponsePackage < any > > {
401
379
let pdfCreatePageEvent = new Log . Event . PromiseEvent ( Log . Event . Label . PdfCreatePage ) ;
402
380
return new Promise < any > ( ( resolve , reject ) => {
403
381
SaveToOneNote . createNewPage ( page , ClipMode . Pdf ) . then ( ( postPageResponse ) => {
@@ -412,6 +390,10 @@ export class SaveToOneNote {
412
390
} ) ;
413
391
}
414
392
393
+ /**
394
+ * Checks to see if a given page exists with a certain number of retries. There is a delay
395
+ * between each retry.
396
+ */
415
397
private static getOneNotePageContentWithRetries ( pageId : string , numRetries : number ) : Promise < any > {
416
398
return SaveToOneNote . getPageContent ( pageId ) . catch ( ( error1 ) => {
417
399
// If the first call fails, we need to wait a couple of seconds before trying again
@@ -431,46 +413,99 @@ export class SaveToOneNote {
431
413
} ) ;
432
414
}
433
415
434
- private static sendOneNotePagePatchRequestWithRetries ( pageId : string , dataUrls : string [ ] , numRetries : number ) : Promise < any > {
435
- return SaveToOneNote . sendOneNotePagePatchRequest ( pageId , dataUrls ) . catch ( ( error ) => {
436
- if ( numRetries >= 1 ) {
437
- return SaveToOneNote . sendOneNotePagePatchRequestWithRetries ( pageId , dataUrls , numRetries - 1 ) ;
438
- } else {
439
- return Promise . reject ( error ) ;
440
- }
441
- } ) ;
416
+ /**
417
+ * Given a page and a list of page indexes, buckets them into PATCH request and sends them sequentially.
418
+ */
419
+ private static sendPagesAsPatchRequests ( pageId : string , indexesToBePatched : number [ ] ) : Promise < any > {
420
+ let indexesToBePatchedRanges : number [ ] [ ] = ArrayUtils . partition ( indexesToBePatched , SaveToOneNote . maxImagesPerPatchRequest ) ;
421
+
422
+ // As of 10/27/16, the page is not always ready when the 200 is returned, so we wait a bit, and then getPageContent with retries
423
+ // When the getPageContent returns a 200, we start PATCHing the page.
424
+ let timeBetweenPatchRequests = SaveToOneNote . timeBeforeFirstPatch ;
425
+ return Promise . all ( [
426
+ indexesToBePatchedRanges . reduce ( ( chainedPromise , currentIndexesRange ) => {
427
+ return chainedPromise = chainedPromise . then ( ( returnValueOfPreviousPromise /* should be a onenote response */ ) => {
428
+ return new Promise ( ( resolve , reject ) => {
429
+ // OneNote API returns 204 on a PATCH request when it receives it, but we have no way of telling when it actually
430
+ // completes processing, so we add an artificial timeout before the next PATCH to try and ensure that they get
431
+ // processed in the order that they were sent.
432
+ let dataUrlsSv = new SmartValue < string [ ] > ( ) ;
433
+ let createPatchRequestCb = ( ) => {
434
+ SaveToOneNote . createOneNotePagePatchRequest ( pageId , dataUrlsSv . get ( ) ) . then ( ( ) => {
435
+ timeBetweenPatchRequests = SaveToOneNote . timeBetweenPatchRequests ;
436
+ resolve ( ) ;
437
+ } ) . catch ( ( error ) => {
438
+ reject ( error ) ;
439
+ } ) ;
440
+ } ;
441
+
442
+ // Parallelize the PATCH request intervals with the fetching of the next set of dataUrls
443
+ setTimeout ( ( ) => {
444
+ if ( dataUrlsSv . get ( ) ) {
445
+ createPatchRequestCb ( ) ;
446
+ } else {
447
+ dataUrlsSv . subscribe ( ( value ) => {
448
+ createPatchRequestCb ( ) ;
449
+ } , { times : 1 , callOnSubscribe : false } ) ;
450
+ }
451
+ } , timeBetweenPatchRequests ) ;
452
+
453
+ SaveToOneNote . getDataUrls ( currentIndexesRange ) . then ( ( dataUrls ) => {
454
+ dataUrlsSv . set ( dataUrls ) ;
455
+ } ) ;
456
+ } ) ;
457
+ } ) ;
458
+ } , SaveToOneNote . getOneNotePageContentWithRetries ( pageId , 3 ) )
459
+ ] ) ;
442
460
}
443
461
444
462
/**
445
- * Given a list of page indexes, creates and sends the request to append the pages to the specified
446
- * page with the images
463
+ * Given a list of page indexes, queries the PDF file for a list of corresponding data urls representing
464
+ * images of the pages
447
465
*/
448
- private static createOneNotePagePatchRequest ( pageId : string , pageIndices : number [ ] ) : Promise < any > {
449
- let pdf = this . clipperState . pdfResult . data . get ( ) . pdf ;
450
-
466
+ private static getDataUrls ( pageIndices : number [ ] ) : Promise < string [ ] > {
451
467
let getPageListAsDataUrlsEvent = new Log . Event . PromiseEvent ( Log . Event . Label . ProcessPdfIntoDataUrls ) ;
452
468
getPageListAsDataUrlsEvent . setCustomProperty ( Log . PropertyName . Custom . NumPages , pageIndices . length ) ;
453
469
454
- return pdf . getPageListAsDataUrls ( pageIndices ) . then ( ( dataUrls ) => {
470
+ let pdf = this . clipperState . pdfResult . data . get ( ) . pdf ;
471
+ return pdf . getPageListAsDataUrls ( pageIndices ) . then ( ( dataUrls : string [ ] ) => {
455
472
getPageListAsDataUrlsEvent . stopTimer ( ) ;
456
473
getPageListAsDataUrlsEvent . setCustomProperty ( Log . PropertyName . Custom . AverageProcessingDurationPerPage , getPageListAsDataUrlsEvent . getDuration ( ) / pageIndices . length ) ;
457
474
Clipper . logger . logEvent ( getPageListAsDataUrlsEvent ) ;
458
475
459
- let patchRequestEvent = new Log . Event . PromiseEvent ( Log . Event . Label . PatchRequest ) ;
460
- return new Promise < any > ( ( resolve , reject ) => {
461
- SaveToOneNote . sendOneNotePagePatchRequestWithRetries ( pageId , dataUrls , Constants . Settings . numRetriesPerPatchRequest ) . then ( ( data ) => {
462
- resolve ( data ) ;
463
- } , ( err ) => {
464
- patchRequestEvent . setStatus ( Log . Status . Failed ) ;
465
- patchRequestEvent . setFailureInfo ( { error : err } ) ;
466
- reject ( err ) ;
467
- } ) . then ( ( ) => {
468
- Clipper . logger . logEvent ( patchRequestEvent ) ;
469
- } ) ;
476
+ return Promise . resolve ( dataUrls ) ;
477
+ } ) ;
478
+ }
479
+
480
+ /**
481
+ * Given a list of page indexes, creates and sends the request to append the pages to the specified
482
+ * page with the images
483
+ */
484
+ private static createOneNotePagePatchRequest ( pageId : string , dataUrls : string [ ] ) : Promise < any > {
485
+ let patchRequestEvent = new Log . Event . PromiseEvent ( Log . Event . Label . PatchRequest ) ;
486
+ return new Promise < any > ( ( resolve , reject ) => {
487
+ SaveToOneNote . sendOneNotePagePatchRequestWithRetries ( pageId , dataUrls , Constants . Settings . numRetriesPerPatchRequest ) . then ( ( data ) => {
488
+ resolve ( data ) ;
489
+ } , ( err ) => {
490
+ patchRequestEvent . setStatus ( Log . Status . Failed ) ;
491
+ patchRequestEvent . setFailureInfo ( { error : err } ) ;
492
+ reject ( err ) ;
493
+ } ) . then ( ( ) => {
494
+ Clipper . logger . logEvent ( patchRequestEvent ) ;
470
495
} ) ;
471
496
} ) ;
472
497
}
473
498
499
+ private static sendOneNotePagePatchRequestWithRetries ( pageId : string , dataUrls : string [ ] , numRetries : number ) : Promise < any > {
500
+ return SaveToOneNote . sendOneNotePagePatchRequest ( pageId , dataUrls ) . catch ( ( error ) => {
501
+ if ( numRetries >= 1 ) {
502
+ return SaveToOneNote . sendOneNotePagePatchRequestWithRetries ( pageId , dataUrls , numRetries - 1 ) ;
503
+ } else {
504
+ return Promise . reject ( error ) ;
505
+ }
506
+ } ) ;
507
+ }
508
+
474
509
/**
475
510
* Given a pageId and an array of dataUrls, sends a PATCH request with those dataUrls as image to update
476
511
* the page with pageId
0 commit comments