From 639f428f8f0994ccdf9dc46cf85ac44687c4e269 Mon Sep 17 00:00:00 2001 From: maddernd <87599686+maddernd@users.noreply.github.com> Date: Sun, 10 Sep 2023 12:21:51 +1000 Subject: [PATCH] feat: add new Numbas Feature Added new Numbas Service to the frontend as part of Integration Changed by: Daniel Maddern --- src/app/api/services/numbas.service.ts | 66 ++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 src/app/api/services/numbas.service.ts diff --git a/src/app/api/services/numbas.service.ts b/src/app/api/services/numbas.service.ts new file mode 100644 index 000000000..a0dc76564 --- /dev/null +++ b/src/app/api/services/numbas.service.ts @@ -0,0 +1,66 @@ +import { Injectable } from '@angular/core'; +import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http'; +import { Observable, throwError } from 'rxjs'; +import { catchError, map, retry } from 'rxjs/operators'; + +@Injectable({ + providedIn: 'root' +}) +export class NumbasService { + private readonly API_URL = 'http://localhost:3000/api/numbas_api'; + + constructor(private http: HttpClient) {} + + fetchResource(unitId: string, taskId: string, resourcePath: string): Observable { + const resourceUrl = `${this.API_URL}/${unitId}/${taskId}/${resourcePath}`; + const resourceMimeType = this.getMimeType(resourcePath); + + return this.http.get(resourceUrl, { responseType: 'blob' }).pipe( + retry(3), // Retrying up to 3 times before failing + map((blob) => new Blob([blob], { type: resourceMimeType })), + catchError((error: HttpErrorResponse) => { + console.error('Error fetching Numbas resource:', error); + return throwError('Error fetching Numbas resource.'); + }) + ); + } + + getMimeType(resourcePath: string): string { + const extension = resourcePath.split('.').pop()?.toLowerCase(); + const mimeTypeMap: { [key: string]: string } = { + 'html': 'text/html', + 'css': 'text/css', + 'js': 'application/javascript', + 'json': 'application/json', + 'png': 'image/png', + 'jpg': 'image/jpeg', + 'gif': 'image/gif', + 'svg': 'image/svg+xml' + }; + + return mimeTypeMap[extension || ''] || 'text/plain'; + } + uploadTest(unitId: string, taskId: string, file: File): Observable { + const uploadUrl = `${this.API_URL}/uploadNumbasTest`; + const formData = new FormData(); + + formData.append('file', file); + formData.append('unit_code', unitId); + formData.append('task_definition_id', taskId); + + const httpOptions = { + headers: new HttpHeaders({ + // You might need to set some headers here depending on your backend requirements + 'Accept': 'application/json' + }) + }; + + return this.http.post(uploadUrl, formData, httpOptions).pipe( + retry(3), + catchError((error: HttpErrorResponse) => { + console.error('Error uploading Numbas test:', error); + return throwError('Error uploading Numbas test.'); + }) + ); + } +}