diff --git a/package-lock.json b/package-lock.json
index 3d9dab56..be1ec2cd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -29,6 +29,7 @@
"@ngx-translate/core": "15.0.0",
"@ngx-translate/http-loader": "^8.0.0",
"@popperjs/core": "2.11.8",
+ "@supercharge/promise-pool": "^3.1.0",
"@svgdotjs/svg.js": "3.2.0",
"@tensorflow/tfjs": "^4.13.0",
"@tensorflow/tfjs-backend-wasm": "^4.13.0",
@@ -5088,6 +5089,14 @@
"integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==",
"dev": true
},
+ "node_modules/@supercharge/promise-pool": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@supercharge/promise-pool/-/promise-pool-3.1.0.tgz",
+ "integrity": "sha512-gB3NukbIcYzRtPoE6dx9svQYPodxvnfQlaaQd8N/z87E6WaMfRE7o5HwB+LZ+KeM0nsNAq1n4TmBtfz1VCUR+Q==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/@svgdotjs/svg.js": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@svgdotjs/svg.js/-/svg.js-3.2.0.tgz",
diff --git a/package.json b/package.json
index 4a5d5755..6bc58601 100644
--- a/package.json
+++ b/package.json
@@ -66,6 +66,7 @@
"@ngx-translate/core": "15.0.0",
"@ngx-translate/http-loader": "^8.0.0",
"@popperjs/core": "2.11.8",
+ "@supercharge/promise-pool": "^3.1.0",
"@svgdotjs/svg.js": "3.2.0",
"@tensorflow/tfjs": "^4.13.0",
"@tensorflow/tfjs-backend-wasm": "^4.13.0",
diff --git a/src/main/webapp/app/scanexam/alignscan/alignscan.component.html b/src/main/webapp/app/scanexam/alignscan/alignscan.component.html
index 51fc2fa0..2ca2029d 100644
--- a/src/main/webapp/app/scanexam/alignscan/alignscan.component.html
+++ b/src/main/webapp/app/scanexam/alignscan/alignscan.component.html
@@ -52,6 +52,20 @@
Layout options
+
+
+
+
+
+
Téléchargement pdfs
template.pdf
diff --git a/src/main/webapp/app/scanexam/alignscan/alignscan.component.ts b/src/main/webapp/app/scanexam/alignscan/alignscan.component.ts
index 4c76aa37..9104c6e1 100644
--- a/src/main/webapp/app/scanexam/alignscan/alignscan.component.ts
+++ b/src/main/webapp/app/scanexam/alignscan/alignscan.component.ts
@@ -30,6 +30,7 @@ import { QuestionService } from '../../entities/question/service/question.servic
import { ZoneService } from '../../entities/zone/service/zone.service';
import { TemplateService } from 'app/entities/template/service/template.service';
import { ScanService } from 'app/entities/scan/service/scan.service';
+import PromisePool from '@supercharge/promise-pool';
export interface IPage {
image?: ArrayBuffer;
@@ -80,8 +81,6 @@ export class AlignScanComponent implements OnInit, CacheUploadNotification {
blocked = false;
observable: Observable
| undefined;
observer: Subscriber | undefined;
- observablePage: Observable | undefined;
- observerPage: Subscriber | undefined;
allowPartialAlign = false;
message = '';
@@ -90,6 +89,7 @@ export class AlignScanComponent implements OnInit, CacheUploadNotification {
scale = 2;
nbPageAlignInCache = 0;
activeIndex = 1;
+ stepPage = 50;
responsiveOptions2: any[] = [
{
breakpoint: '1500px',
@@ -114,9 +114,9 @@ export class AlignScanComponent implements OnInit, CacheUploadNotification {
showMapping = false;
layoutsidebarVisible = false;
- nbreCore = navigator.hardwareConcurrency - 2;
+ nbreCore = (navigator.hardwareConcurrency - 2) / 2 > 0 ? (navigator.hardwareConcurrency - 2) / 2 : 1;
nbreCoreMax = navigator.hardwareConcurrency - 2;
-
+ resolves: Map = new Map();
constructor(
public examService: ExamService,
protected activatedRoute: ActivatedRoute,
@@ -175,6 +175,7 @@ export class AlignScanComponent implements OnInit, CacheUploadNotification {
this.allowPartialAlign = p > 0; // && p1 > 0 && p === p1;
}
+ processpage: number[] = [];
initPool(): void {
this.observable = new Observable(observer => {
this.observer = observer;
@@ -184,9 +185,13 @@ export class AlignScanComponent implements OnInit, CacheUploadNotification {
selectTransferables: input => [input.imageA],
workerCount: this.nbreCore,
fallbackWorkerCount: 3,
- }).subscribe(
- (e: IImageAlignement) => {
+ }).subscribe({
+ next: (e: IImageAlignement) => {
const im = new ImageData(new Uint8ClampedArray(e.imageAligned!), e.imageAlignedWidth!, e.imageAlignedHeight);
+
+ // this.submessage = '' + this.avancement + this.avancementunit;
+ this.processpage.push(e.pageNumber!);
+
e.imageAligned = undefined;
if (e.imagesDebugTracesWidth !== undefined) {
const dim = new ImageData(new Uint8ClampedArray(e.imagesDebugTraces!), e.imagesDebugTracesWidth!, e.imagesDebugTracesHeight);
@@ -198,28 +203,27 @@ export class AlignScanComponent implements OnInit, CacheUploadNotification {
title: 'Exam',
});
}
+ /* this.resolves.get(e.pageNumber!)()
+ this.resolves.delete(e.pageNumber!)
+ this.avancement = this.currentPageAlignOver;
+ this.currentPageAlignOver = this.currentPageAlignOver + 1;
+ im.data.set([]);*/
this.saveEligneImage(e.pageNumber!, im).then(() => {
im.data.set([]);
- if (this.currentPageAlign < this.numberPagesInScan + 1) {
- this.observerPage?.next(this.currentPageAlign);
- this.currentPageAlign = this.currentPageAlign + 1;
- }
- if (this.currentPageAlignOver < this.numberPagesInScan) {
- this.avancement = this.currentPageAlignOver;
- this.currentPageAlignOver = this.currentPageAlignOver + 1;
- } else {
- this.avancement = this.currentPageAlignOver;
- this.currentPageAlignOver = this.currentPageAlignOver + 1;
- this.observerPage?.complete();
- this.observer?.complete();
- }
+ this.resolves.get(e.pageNumber!)();
+ this.resolves.delete(e.pageNumber!);
+ this.avancement = this.currentPageAlignOver;
+ this.currentPageAlignOver = this.currentPageAlignOver + 1;
+
+ // this.progress = ;
});
},
- err => {
+ // eslint-disable-next-line object-shorthand
+ error: err => {
console.log(err);
},
- );
+ });
}
async removeElement(examId: number): Promise {
@@ -265,9 +269,8 @@ export class AlignScanComponent implements OnInit, CacheUploadNotification {
}
await this.load();
await this.loadTemplatePage();
- this.initPool();
- this.exportAsImage();
+ await this.exportAsImage();
}
async loadTemplatePage(): Promise {
return new Promise(resolve => {
@@ -312,6 +315,7 @@ export class AlignScanComponent implements OnInit, CacheUploadNotification {
this.partialAlign = false;
this.showMapping = false;
this.startPage = 1;
+ this.processpage = [];
this.currentPageAlign = 1;
this.endPage = value;
this.numberPagesInScan = value;
@@ -338,38 +342,96 @@ export class AlignScanComponent implements OnInit, CacheUploadNotification {
this.router.navigateByUrl('/exam/' + this.examId);
}
- public exportAsImage(): void {
- this.observablePage = new Observable(observer => {
- this.observerPage = observer;
- });
+ public async exportAsImage(): Promise {
+ const stepPage = this.stepPage;
+ let nbrePageToProcess = this.numberPagesInScan;
+ if (this.partialAlign) {
+ nbrePageToProcess = this.numberPagesInScan - this.startPage + 1;
+ }
- this.observablePage.subscribe(
- e => {
- this.alignPage(e);
- },
- err => console.log(err),
- () => {
- this.saveData();
- },
- );
+ console.error(nbrePageToProcess);
- if (this.partialAlign) {
- this.currentPageAlign = this.startPage;
- } else {
- this.startPage = 1;
- this.currentPageAlign = 1;
+ let count = Math.floor(nbrePageToProcess / stepPage);
+ for (let k = 0; k < count; k++) {
+ const pagesnumber: number[] = [];
+ if (this.alignement !== 'off') {
+ this.initPool();
+ }
+ if (this.partialAlign) {
+ this.currentPageAlignOver = this.startPage;
+ this.avancement = this.startPage;
+ for (let i = 1 + k * stepPage; i <= (k + 1) * stepPage; i++) {
+ if (i >= this.startPage) {
+ pagesnumber.push(i);
+ }
+ }
+ } else {
+ this.currentPageAlignOver = 1 + k * stepPage;
+ this.avancement = 1 + k * stepPage;
+ for (let i = 1 + k * stepPage; i <= (k + 1) * stepPage; i++) {
+ pagesnumber.push(i);
+ }
+ }
+ await PromisePool.for(pagesnumber)
+ .withConcurrency(this.nbreCore)
+ /* .onTaskFinished((page) => {
+ console.error('end send page to process ', page);
+ })*/
+ .process(
+ async page =>
+ new Promise(resolve => {
+ this.alignPage(page);
+ this.resolves.set(page, resolve);
+ }),
+ );
+ if (this.alignement !== 'off') {
+ this.observer?.complete();
+ }
+ }
+ if (this.alignement !== 'off') {
+ this.initPool();
}
+ const count2 = nbrePageToProcess % stepPage;
+ console.error(count2);
+ let count1 = Math.floor(nbrePageToProcess / stepPage);
+ console.error(count1);
+ if (count2 > 0) {
+ const pagesnumber: number[] = [];
- while (
- this.currentPageAlign < this.startPage + Math.floor(this.nbreCore * 1.5) /* (navigator.hardwareConcurrency - 1) /* * 2 */ &&
- this.currentPageAlign < this.numberPagesInScan + 1
- ) {
- this.observerPage!.next(this.currentPageAlign);
- this.currentPageAlign = this.currentPageAlign + 1;
+ if (this.partialAlign) {
+ this.currentPageAlignOver = this.startPage;
+ this.avancement = this.startPage;
+ for (let i = 1 + count1 * stepPage; i <= count1 * stepPage + count2; i++) {
+ if (i >= this.startPage) {
+ pagesnumber.push(i);
+ }
+ }
+ } else {
+ this.currentPageAlignOver = 1 + count1 * stepPage;
+ this.avancement = 1 + count1 * stepPage;
+ for (let i = 1 + count1 * stepPage; i <= count1 * stepPage + count2; i++) {
+ pagesnumber.push(i);
+ }
+ }
+ console.error(pagesnumber);
+ await PromisePool.for(pagesnumber)
+ .withConcurrency(this.nbreCore)
+ .process(
+ async page =>
+ new Promise(resolve => {
+ this.alignPage(page);
+ this.resolves.set(page, resolve);
+ }),
+ );
+ if (this.alignement !== 'off') {
+ this.observer?.complete();
+ }
}
+
+ this.saveData();
}
- public async alignPage(page: number): Promise {
+ public async alignPage(page: number): Promise {
if (this.alignement === 'off') {
const dataURL = await this.db.getFirstNonAlignImage(+this.examId, page);
if (dataURL !== undefined) {
@@ -378,31 +440,23 @@ export class AlignScanComponent implements OnInit, CacheUploadNotification {
pageNumber: page,
value: dataURL!.value,
});
- if (this.currentPageAlign < this.numberPagesInScan + 1) {
- this.observerPage?.next(this.currentPageAlign);
- this.currentPageAlign = this.currentPageAlign + 1;
- }
- if (this.currentPageAlignOver < this.numberPagesInScan) {
- this.avancement = this.currentPageAlignOver;
- this.currentPageAlignOver = this.currentPageAlignOver + 1;
- } else {
- this.avancement = this.currentPageAlignOver;
- this.currentPageAlignOver = this.currentPageAlignOver + 1;
- this.observerPage?.complete();
- this.observer?.complete();
- }
- return page;
+ this.avancement = this.currentPageAlignOver;
+ this.currentPageAlignOver = this.currentPageAlignOver + 1;
+ this.resolves.get(page)();
+ this.resolves.delete(page);
+
+ return;
} else {
this.messageService.add({
severity: 'error',
summary: this.translateService.instant('scanexam.npagealign'),
detail: this.translateService.instant('scanexam.npagealigndetails') + page,
});
- return page;
+ return;
}
} else {
- const p = this.aligneImages(page);
- return p! + 1;
+ this.aligneImages(page);
+ return;
}
}
@@ -429,7 +483,7 @@ export class AlignScanComponent implements OnInit, CacheUploadNotification {
i.src = file;
}
- aligneImages(pagen: number): number {
+ aligneImages(pagen: number): void {
let paget = pagen % this.nbreFeuilleParCopie;
if (paget === 0) {
paget = this.nbreFeuilleParCopie;
@@ -449,7 +503,7 @@ export class AlignScanComponent implements OnInit, CacheUploadNotification {
indexDb: this.preferenceService.getPreference().cacheDb === 'indexdb',
});
}
- return pagen;
+ return;
}
private imageDataToDataURL(img: ImageData): string {
diff --git a/src/main/webapp/app/scanexam/associer-copies-etudiants/allbindings/allbindings.component.ts b/src/main/webapp/app/scanexam/associer-copies-etudiants/allbindings/allbindings.component.ts
index 035677dd..e33ae832 100644
--- a/src/main/webapp/app/scanexam/associer-copies-etudiants/allbindings/allbindings.component.ts
+++ b/src/main/webapp/app/scanexam/associer-copies-etudiants/allbindings/allbindings.component.ts
@@ -6,7 +6,6 @@ import { DynamicDialogConfig, DynamicDialogRef } from 'primeng/dynamicdialog';
import { ExamSheetService } from '../../../entities/exam-sheet/service/exam-sheet.service';
import { firstValueFrom } from 'rxjs';
import { StudentService } from 'app/entities/student/service/student.service';
-import { v4 as uuid } from 'uuid';
@Component({
selector: 'jhi-allbindings',
@@ -83,52 +82,37 @@ export class AllbindingsComponent implements OnInit {
}
async bindStudentInternal(student: IStudent, currentStudent: number, element: any): Promise {
- let examSheet4CurrentStudentId: (number | undefined)[] = [];
- if (student.examSheets) {
- examSheet4CurrentStudentId = student.examSheets.filter((ex: any) => ex?.scanId === this.exam.scanfileId).map(ex1 => ex1.id);
+ console.error(this.students);
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
+ const examSheet4CurrentStudent1: IExamSheet[] = [...new Set(this.students.flatMap(s => s.recognizedStudent.examSheets!))].filter(
+ sh =>
+ sh.pagemin === currentStudent * this.nbreFeuilleParCopie &&
+ sh.pagemax === (currentStudent + 1) * this.nbreFeuilleParCopie - 1 &&
+ sh.scanId === this.exam.scanfileId,
+ );
+ // ExamSheetExist
+ if (examSheet4CurrentStudent1.length === 1) {
+ const sheet = examSheet4CurrentStudent1[0];
+ sheet.students = [student];
+ await firstValueFrom(this.sheetService.updateStudents(sheet.id!, [student.id!]));
+ element.bound = true;
}
- // Récupère la sheet courante.
- const examSheet4CurrentPage: IExamSheet[] = (
- this.students
- .filter(
- s =>
- s.examSheets?.some(
- (ex: any) => ex?.scanId === this.exam.scanfileId && ex.pagemin === currentStudent * this.nbreFeuilleParCopie,
- ),
+ // ExamSheetNotExist
+ else {
+ const sheets: IExamSheet[] | null = (
+ await firstValueFrom(
+ this.sheetService.query({
+ scanId: this.exam.scanfileId,
+ pagemin: currentStudent * this.nbreFeuilleParCopie,
+ pagemax: (currentStudent + 1) * this.nbreFeuilleParCopie - 1,
+ }),
)
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return
- .map(s => s.examSheets) as any
- ).flat();
- // Passe cette sheet à -1 -1. sémantique plus associé
-
- for (const ex of examSheet4CurrentPage.filter(ex2 => !examSheet4CurrentStudentId.includes(ex2.id))) {
- ex.pagemin = -1;
- ex.pagemax = -1;
- await firstValueFrom(this.sheetService.update(ex));
- }
-
- // Pour l'étudiant sélectionné. récupère la sheet. Si elle exite, on met à jour les bonnes pages sinon on crée la page.
-
- const examS4Student = student.examSheets?.filter((ex: IExamSheet) => ex.scanId === this.exam.scanfileId);
- if (examS4Student !== undefined && examS4Student.length > 0) {
- for (const ex of examS4Student) {
- ex.pagemin = currentStudent * this.nbreFeuilleParCopie;
- ex.pagemax = (currentStudent + 1) * this.nbreFeuilleParCopie - 1;
- await firstValueFrom(this.sheetService.update(ex));
+ ).body;
+ if (sheets !== null && sheets.length === 1) {
+ await firstValueFrom(this.sheetService.updateStudents(sheets[0].id!, [student.id!]));
+ element.bound = true;
}
- } else {
- const sheet: IExamSheet = {
- name: uuid(),
- pagemin: currentStudent * this.nbreFeuilleParCopie,
- pagemax: (currentStudent + 1) * this.nbreFeuilleParCopie - 1,
- scanId: this.exam.scanfileId,
- students: [student],
- };
- const e = await firstValueFrom(this.sheetService.create(sheet));
- student.examSheets?.push(e.body!);
- await firstValueFrom(this.studentService.update(student));
}
- element.bound = true;
}
async bindAllStudent(element: any): Promise {
@@ -141,6 +125,7 @@ export class AllbindingsComponent implements OnInit {
await this.bindStudentInternal(s.recognizedStudent, s.currentStudent, s);
}
} catch (e) {
+ console.error(e);
console.error('could not bind ', s.recognizedStudent);
}
}
diff --git a/src/main/webapp/app/scanexam/chargerscan/chargerscan.component.html b/src/main/webapp/app/scanexam/chargerscan/chargerscan.component.html
index 26938b61..13d5ad96 100644
--- a/src/main/webapp/app/scanexam/chargerscan/chargerscan.component.html
+++ b/src/main/webapp/app/scanexam/chargerscan/chargerscan.component.html
@@ -68,7 +68,7 @@
-
+
@@ -107,7 +107,7 @@
0 && pageInScan > 0"
+ *ngIf="showVignette && !reloadScan && examid && pageInTemplate > 0 && pageAlreadyScan > 0"
[examId]="+examid!"
>
diff --git a/src/main/webapp/app/scanexam/chargerscan/chargerscan.component.ts b/src/main/webapp/app/scanexam/chargerscan/chargerscan.component.ts
index 0c777bc7..30309c78 100644
--- a/src/main/webapp/app/scanexam/chargerscan/chargerscan.component.ts
+++ b/src/main/webapp/app/scanexam/chargerscan/chargerscan.component.ts
@@ -16,7 +16,7 @@ import { ExamService } from 'app/entities/exam/service/exam.service';
import { IScan, Scan } from 'app/entities/scan/scan.model';
// import { AlertError } from 'app/shared/alert/alert-error.model';
import { MessageService, ConfirmationService } from 'primeng/api';
-import { finalize, firstValueFrom, Observable, scan, Subscriber } from 'rxjs';
+import { finalize, firstValueFrom, Observable, scan } from 'rxjs';
import { ScanService } from '../../entities/scan/service/scan.service';
import { IExam } from '../../entities/exam/exam.model';
import { CacheServiceImpl } from '../db/CacheServiceImpl';
@@ -27,6 +27,7 @@ import { QuestionService } from 'app/entities/question/service/question.service'
import { ZoneService } from 'app/entities/zone/service/zone.service';
import { PreferenceService } from '../preference-page/preference.service';
import { ViewandreorderpagesComponent } from '../viewandreorderpages/viewandreorderpages.component';
+import { PromisePool } from '@supercharge/promise-pool';
interface Upload {
progress: number;
@@ -75,13 +76,14 @@ export class ChargerscanComponent implements OnInit {
editForm: UntypedFormGroup;
progress = 0;
pageInTemplate = 0;
- pageInScan = 0;
+ pageAlreadyScan = 0;
message = '';
reloadScan = false;
merge = true;
saveTemplate = true;
- observablePage: Observable
| undefined;
- observerPage: Subscriber | undefined;
+ loaded = false;
+ // observablePage: Observable | undefined;
+ // observerPage: Subscriber | undefined;
@ViewChild('viewpage')
viewcomponent!: ViewandreorderpagesComponent;
@@ -110,7 +112,6 @@ export class ChargerscanComponent implements OnInit {
// private editedImage: HTMLCanvasElement | undefined;
templatePages: Map = new Map();
phase1 = false;
- loaded = false;
alignement = 'marker';
alignementOptions = [
{ label: 'Off', value: 'off' },
@@ -187,7 +188,7 @@ export class ChargerscanComponent implements OnInit {
}
async init(): Promise {
const p = await this.db.countNonAlignImage(+this.examid!);
- this.pageInScan = p;
+ this.pageAlreadyScan = p;
const templatePage = await this.db.countPageTemplate(+this.examid!);
this.pageInTemplate = templatePage;
}
@@ -288,7 +289,11 @@ export class ChargerscanComponent implements OnInit {
}
protected onSaveSuccess(): void {
- this.initCacheProcessing(false);
+ if (this.merge) {
+ this.initCacheProcessing(false);
+ } else {
+ this.initCacheProcessing(true);
+ }
this.reloadScan = false;
// this.gotoUE();
}
@@ -369,22 +374,25 @@ export class ChargerscanComponent implements OnInit {
}
const e1 = await firstValueFrom(this.templateService.getPdf(this.exam.templateId));
this.blob1 = e1;
+ this.loaded = true;
}
}
-
+ i = 1;
public async pdfloaded(): Promise {
- if (!this.phase1) {
- this.nbreFeuilleParCopie = this.pdfService.numberOfPages();
- }
- this.loaded = true;
- if (this.phase1) {
- if (this.pdfService.numberOfPages() !== 0) {
- // Change if partial update
- this.numberPagesInScan = this.pdfService.numberOfPages();
- this.avancementunit = ' / ' + this.numberPagesInScan;
+ if (this.loaded && this.pdfService.numberOfPages() !== 0) {
+ if (!this.phase1) {
+ this.nbreFeuilleParCopie = this.pdfService.numberOfPages();
+ await this.process();
+ } else {
+ if (this.pdfService.numberOfPages() !== 0 && this.i < 20) {
+ // Change if partial update
+ this.numberPagesInScan = this.pdfService.numberOfPages();
+ this.avancementunit = ' / ' + this.numberPagesInScan;
+ await this.process();
+ this.i = this.i + 1;
+ }
}
}
- await this.process();
}
blob: any;
@@ -405,59 +413,68 @@ export class ChargerscanComponent implements OnInit {
if (this.blob !== undefined) {
this.blob1 = this.blob;
} else {
- const e1 = await firstValueFrom(this.scanService.getPdf(this.exam.scanfileId));
- this.blob1 = e1;
+ this.blob1 = await firstValueFrom(this.scanService.getPdf(this.exam.scanfileId));
}
}
}
}
} else {
- this.observablePage = new Observable(observer => {
- this.observerPage = observer;
- });
-
- this.observablePage.subscribe(
- e => {
- this.processPage(e, false);
- // this.alignPage(e);
- },
- err => console.log(err),
- () => {
- this.phase1 = false;
- this.blob = undefined;
- this.blob1 = undefined;
- this.blocked = false;
- this.firstPageToLoad = 0;
- if (this.viewcomponent !== undefined) {
- this.viewcomponent.update();
- } else {
- this.db.countNonAlignImage(+this.examid!).then(p => {
- this.db.countPageTemplate(+this.examid!).then(p1 => {
- this.pageInScan = p;
- this.pageInTemplate = p1;
- this.showVignette = true;
- });
- });
- }
-
- this.progress = 0;
- this.submessage = '';
- this.message = '';
- // this.saveData();
- },
- );
-
this.startPage = 1;
this.currentPageAlign = 1;
- while (
- this.currentPageAlign < this.startPage + ((navigator.hardwareConcurrency - 1) * 3) / 2 &&
- this.currentPageAlign < this.numberPagesInScan + 1
- ) {
- this.observerPage!.next(this.currentPageAlign);
- this.currentPageAlign = this.currentPageAlign + 1;
+ const pagesnumber: number[] = [];
+ for (let i = 1; i <= this.numberPagesInScan; i++) {
+ pagesnumber.push(i);
}
+ await PromisePool.for(pagesnumber)
+ .withConcurrency(30)
+ /* .onTaskStarted((page, pool) => {
+ console.log(`Progress: ${pool.processedPercentage()}%`);
+ console.log(`Active tasks: ${pool.processedItems().length}`);
+ console.log(`Active tasks: ${pool.activeTasksCount()}`);
+ console.log(`Finished tasks: ${pool.processedItems().length}`);
+ console.log(`Finished tasks: ${pool.processedCount()}`);
+ })*/
+ .onTaskFinished((page, pool) => {
+ this.progress = pool.processedPercentage();
+ this.avancement = this.currentPageAlignOver;
+ this.currentPageAlignOver = this.currentPageAlignOver + 1;
+ this.submessage = '' + this.avancement + this.avancementunit;
+ })
+ .process(async page => {
+ console.error('send process', page);
+ await this.processPage(page, false);
+ });
+ // await Promise.all(this.imagesP);
+ console.error('end of processing');
+ /* if (this.images1.length>20){
+ await this.db.addNonAligneImages(this.images1);
+ this.images1 = [];
+ }*/
+
+ this.loaded = false;
+ // this.blob = undefined;
+ // this.blob1 = undefined;
+ // this.phase1 = false;
+ this.blocked = false;
+ this.firstPageToLoad = 0;
+ if (this.viewcomponent !== undefined) {
+ this.viewcomponent.update();
+ } else {
+ this.db.countNonAlignImage(+this.examid!).then(p => {
+ this.db.countPageTemplate(+this.examid!).then(p1 => {
+ this.pageAlreadyScan = p;
+ this.pageInTemplate = p1;
+ this.showVignette = true;
+ });
+ });
+ }
+
+ this.progress = 0;
+ this.submessage = '';
+ this.message = '';
}
+ this.blocked = false;
}
async saveTemplateImage(pageN: number, imageD: any): Promise {
@@ -475,8 +492,10 @@ export class ChargerscanComponent implements OnInit {
}
}
+ images1: any[] = [];
+
async saveNonAligneImage(pageN: number, imageD: any): Promise {
- await this.db.addNonAligneImage({
+ const im1 = {
examId: +this.examid!,
pageNumber: pageN + this.firstPageToLoad,
value: JSON.stringify(
@@ -485,51 +504,45 @@ export class ChargerscanComponent implements OnInit {
},
this.replacer,
),
- });
- if (this.currentPageAlign < this.numberPagesInScan + 1) {
- this.observerPage?.next(this.currentPageAlign);
- this.currentPageAlign = this.currentPageAlign + 1;
- }
- if (this.currentPageAlignOver < this.numberPagesInScan) {
- this.avancement = this.currentPageAlignOver;
- this.currentPageAlignOver = this.currentPageAlignOver + 1;
- this.progress = Math.floor((this.avancement * 100) / this.numberPagesInScan);
- this.submessage = '' + this.avancement + this.avancementunit;
- } else {
- this.avancement = this.currentPageAlignOver;
- this.currentPageAlignOver = this.currentPageAlignOver + 1;
- this.observerPage?.complete();
- console.timeEnd('processPage');
- }
+ };
+ await this.db.addNonAligneImage(im1);
+ /* this.images1.push(im1)
+ if (this.images1.length>20){
+ await this.db.addNonAligneImages(this.images1);
+ this.images1 = [];
+ }*/
}
gotoUE(): any {
this.router.navigateByUrl('/exam/' + this.examid!);
}
- public async processPage(page: number, template: boolean): Promise {
+ // imagesP: Promise[] = [];
+ public async processPage(page: number, template: boolean): Promise {
+ console.error('process page');
const scale = { scale: this.scale };
- if (page === 1 && !template) console.time('processPage');
- if (page === 1 && !template) console.timeLog('processPage', 'before getDataURL ', page);
+ if (page < 10 && !template) console.time('processPage' + page);
+ if (page < 10 && !template) console.timeLog('processPage' + page, 'before getDataURL ', page);
const dataURL = await this.pdfService.getPageAsImage(page, scale);
- if (page === 1 && !template) console.timeLog('processPage', 'getDataURL ', page);
- const p = await this.saveImageScan(dataURL, page, template);
- if (page === 1 && !template) console.timeLog('processPage', 'saveImageScan ', page);
-
- return p + 1;
+ // this.pdfService.getP
+ if (page < 10 && !template) console.timeLog('processPage' + page, 'getDataURL ', page);
+ await this.saveImageScan(dataURL, page, template);
+ if (page < 10 && !template) console.timeLog('processPage' + page, 'saveImageScan ', page);
}
- async saveImageScan(file: any, pagen: number, template: boolean): Promise {
- // await this.saveNonAligneImage(pagen, file);
+ saveImageScan(file: any, pagen: number, template: boolean): Promise {
return new Promise(resolve => {
if (pagen === 1 && !template) console.timeLog('processPage', 'start', pagen);
const i = new Image();
i.onload = async () => {
if (pagen === 1 && !template) console.timeLog('processPage', 'image Loaded ', pagen);
- const editedImage = document.createElement('canvas');
- editedImage.width = i.width;
- editedImage.height = i.height;
+ const editedImage = new OffscreenCanvas(i.width, i.height);
+
+ // document.createElement('canvas');
+ // document.createOff
+ // editedImage.width = i.width;
+ // editedImage.height = i.height;
const ctx = editedImage.getContext('2d');
ctx!.drawImage(i, 0, 0);
if (pagen === 1 && !template) console.timeLog('processPage', 'draw first canvas ', pagen);
@@ -560,15 +573,22 @@ export class ChargerscanComponent implements OnInit {
exportImageType = this.preferenceService.getPreference().imageTypeExport;
}
- const webPImageURL = editedImage.toDataURL(exportImageType, compression);
+ const webPImageBlob = await editedImage.convertToBlob({
+ type: exportImageType,
+ quality: compression,
+ });
+ const webPImageURL = await blobToDataURL(webPImageBlob);
if (template) {
await this.saveTemplateImage(pagen, webPImageURL);
+ console.error('save template ' + pagen);
+ resolve();
} else {
if (pagen === 1 && !template) console.timeLog('processPage', 'before save ', pagen);
await this.saveNonAligneImage(pagen, webPImageURL);
+ resolve();
+
if (pagen === 1 && !template) console.timeLog('processPage', 'after save ', pagen);
}
- resolve(pagen);
};
i.src = file;
});
@@ -585,3 +605,17 @@ export class ChargerscanComponent implements OnInit {
}
}
}
+
+function blobToDataURL(blob: Blob): Promise {
+ return new Promise((resolve, reject) => {
+ const a = new FileReader();
+ a.onload = e => {
+ if (e.target !== null) {
+ resolve(e.target.result);
+ } else {
+ reject();
+ }
+ };
+ a.readAsDataURL(blob);
+ });
+}
diff --git a/src/main/webapp/app/scanexam/corrigequestion/corrigequestion.component.ts b/src/main/webapp/app/scanexam/corrigequestion/corrigequestion.component.ts
index 6917fc88..6231149b 100644
--- a/src/main/webapp/app/scanexam/corrigequestion/corrigequestion.component.ts
+++ b/src/main/webapp/app/scanexam/corrigequestion/corrigequestion.component.ts
@@ -269,7 +269,7 @@ export class CorrigequestionComponent implements OnInit, AfterViewInit {
// await this.refreshStudentList(forceRefreshStudent);
}
if (this.studentid !== studentid_prev) {
- this.getSelectedStudent(this.currentStudent);
+ await this.getSelectedStudent(this.currentStudent);
}
// must be done here as the change of the nbreQuestions triggers the event of change question with page = 0
@@ -397,7 +397,7 @@ export class CorrigequestionComponent implements OnInit, AfterViewInit {
this.questions = undefined;
setTimeout(() => {
this.questions = questions;
- }, 0);
+ }, 20);
}, 1);
}
diff --git a/src/main/webapp/app/scanexam/db/CacheServiceImpl.ts b/src/main/webapp/app/scanexam/db/CacheServiceImpl.ts
index 16908d93..be8c830a 100644
--- a/src/main/webapp/app/scanexam/db/CacheServiceImpl.ts
+++ b/src/main/webapp/app/scanexam/db/CacheServiceImpl.ts
@@ -63,6 +63,9 @@ export class CacheServiceImpl implements CacheService {
addNonAligneImage(elt: AlignImage): Promise {
return this.service.addNonAligneImage(elt);
}
+ addNonAligneImages(elts: AlignImage[]): Promise {
+ return this.service.addNonAligneImages(elts);
+ }
export(examId: number, options?: ExportOptions | undefined): Promise {
return this.service.export(examId, options);
}
diff --git a/src/main/webapp/app/scanexam/db/db.ts b/src/main/webapp/app/scanexam/db/db.ts
index 2d81142b..4a5a8791 100644
--- a/src/main/webapp/app/scanexam/db/db.ts
+++ b/src/main/webapp/app/scanexam/db/db.ts
@@ -199,6 +199,9 @@ export class ExamIndexDB extends Dexie {
async addNonAligneImage(elt: AlignImage) {
await this.nonAlignImages.put(elt);
}
+ async addNonAligneImages(elts: AlignImage[]) {
+ await this.nonAlignImages.bulkAdd(elts);
+ }
export(options?: ExportOptions): Promise {
return super.export(options);
@@ -464,6 +467,19 @@ export class AppDB implements CacheService {
return db1.addNonAligneImage(elt);
}
+ async addNonAligneImages(elts: AlignImage[]): Promise {
+ if (elts.length > 0) {
+ let db1 = this.dbs.get(elts[0].examId);
+ if (db1 === undefined) {
+ db1 = new ExamIndexDB(elts[0].examId);
+ this.dbs.set(elts[0].examId, db1);
+ }
+ return db1.addNonAligneImages(elts);
+ } else {
+ return;
+ }
+ }
+
export(examId: number, options?: ExportOptions): Promise {
let db1 = this.dbs.get(examId);
if (db1 === undefined) {
@@ -652,6 +668,7 @@ export interface CacheService {
removePageNonAlignForExamForPages(examId: number, pageStart: number, pageEnd: number): Promise;
addAligneImage(elt: AlignImage): Promise;
addNonAligneImage(elt: AlignImage): Promise;
+ addNonAligneImages(elts: AlignImage[]): Promise;
export(examId: number, options?: ExportOptions): Promise;
import(examId: number, blob: Blob, options?: ImportOptions): Promise;
countPageTemplate(examId: number): Promise;
diff --git a/src/main/webapp/app/scanexam/db/dbsqlite.ts b/src/main/webapp/app/scanexam/db/dbsqlite.ts
index de9bbffe..3f0345d1 100644
--- a/src/main/webapp/app/scanexam/db/dbsqlite.ts
+++ b/src/main/webapp/app/scanexam/db/dbsqlite.ts
@@ -209,6 +209,26 @@ export class SqliteCacheService implements CacheService {
return this._dispatch('addNonAligneImage', el1, [el1.value]).toPromise();
}
+ async addNonAligneImages(elts: ImageDB[]) {
+ const enc = new TextEncoder(); // always utf-8
+ if (elts.length > 0) {
+ const els: any[] = [];
+ const els1: ArrayBufferLike[] = [];
+ elts.forEach(elt => {
+ const el1 = {
+ examId: elt.examId,
+ pageNumber: elt.pageNumber,
+ value: enc.encode(elt.value).buffer,
+ };
+ els.push(el1);
+ els1.push(el1.value);
+ });
+
+ return this._dispatch('addNonAligneImages', els, els1).toPromise();
+ }
+ return;
+ }
+
export(examId: number, options?: ExportOptions | undefined): Promise {
return this._dispatch('export', {
examId: examId,
diff --git a/src/main/webapp/i18n/en/scanexammodule.json b/src/main/webapp/i18n/en/scanexammodule.json
index fbf7bcca..13ebd972 100644
--- a/src/main/webapp/i18n/en/scanexammodule.json
+++ b/src/main/webapp/i18n/en/scanexammodule.json
@@ -443,6 +443,8 @@
"hybridcommentStep": "Number of slice(s)",
"hybridcommentStepTooltip": "Used to indicate whether the marker can divide the value of this comment into a number of slices. For example, if the mark for this comment is 80% of the overall mark and the number of brackets is 2, the marker may not apply this comment, apply this comment with one slice (40% of the overall mark) or apply this comment with two slices (80% of the overall mark).",
"hybridcommentGrade": "Grade",
- "downloadpdf": "Download pdfs"
+ "downloadpdf": "Download pdfs",
+ "stepPage": "Number of images processed in batch",
+ "stepPageTooltip": "Used to configure the number of images processed in batch before memory is released"
}
}
diff --git a/src/main/webapp/i18n/fr/scanexammodule.json b/src/main/webapp/i18n/fr/scanexammodule.json
index 6765266a..8f5df6ee 100644
--- a/src/main/webapp/i18n/fr/scanexammodule.json
+++ b/src/main/webapp/i18n/fr/scanexammodule.json
@@ -447,6 +447,8 @@
"hybridcommentStep": "Nombre de tranche(s)",
"hybridcommentStepTooltip": "Permet d'exprimer si le correcteur pourra diviser la valeur de ce commentaire en un nombre de tranche(s). Ainsi, si la note de ce commentaire vaut 80% de la note globale et que le nombre de tranche est 2, le correcteur pourra ne pas appliquer ce commentaire, appliquer ce commentaire avec une tranche (40% de la note globale), appliquer ce commentaire avec deux tranches 80% de la note globale",
"hybridcommentGrade": "Note",
- "downloadpdf": "Téléchargement pdfs"
+ "downloadpdf": "Téléchargement pdfs",
+ "stepPage": "Nombre d'images traitées en batch",
+ "stepPageTooltip": "Permet de configurer le nombre d'images traitées en batch avant libération de la mémoire"
}
}