diff --git a/NodeApp/src/commander/assignment/subcommands/AssignmentExportCommand.ts b/NodeApp/src/commander/assignment/subcommands/AssignmentExportCommand.ts index 90c755e6ce65468a2c99e05701eb99b67331a6e2..48be25423f0a45f434acc7797b82ff2d52328213 100644 --- a/NodeApp/src/commander/assignment/subcommands/AssignmentExportCommand.ts +++ b/NodeApp/src/commander/assignment/subcommands/AssignmentExportCommand.ts @@ -1,13 +1,13 @@ -import CommanderCommand from '../../CommanderCommand.js'; -import DojoBackendManager from '../../../managers/DojoBackendManager.js'; -import AccessesHelper from '../../../helpers/AccessesHelper.js'; -import ora from 'ora'; -import GitlabManager from '../../../managers/GitlabManager.js'; -import TextStyle from '../../../types/TextStyle.js'; -import Assignment from '../../../sharedByClients/models/Assignment.js'; +import CommanderCommand from '../../CommanderCommand.js'; +import DojoBackendManager from '../../../managers/DojoBackendManager.js'; +import AccessesHelper from '../../../helpers/AccessesHelper.js'; +import ora from 'ora'; +import GitlabManager from '../../../managers/GitlabManager.js'; +import TextStyle from '../../../types/TextStyle.js'; +import Assignment from '../../../sharedByClients/models/Assignment.js'; // import User from '../../../sharedByClients/models/User.js'; -type CommandOptions = { name : string, clone? : string | boolean } +// type CommandOptions = { name : string, clone? : string | boolean } class AssignmentExportCommand extends CommanderCommand { protected commandName: string = 'export'; @@ -18,6 +18,7 @@ class AssignmentExportCommand extends CommanderCommand { this.command .description('export a repository in an archive') .argument('<userId>', 'name or url (http/s or ssh) of the assignment') + .argument('<folderName>', 'name of the zip') // .argument('<full>', 'export full') .action(this.commandAction.bind(this)); } @@ -29,9 +30,8 @@ class AssignmentExportCommand extends CommanderCommand { await GitlabManager.cloneRepository('./', this.assignment!.gitlabCreationInfo.http_url_to_repo, undefined, true, 0); } - protected async commandAction(userId : string): Promise<void> { + protected async commandAction(userId : string, folderName : string): Promise<void> { let user; - let tmp; if ( !await AccessesHelper.checkTeachingStaff() ) { throw new Error(); @@ -42,28 +42,32 @@ class AssignmentExportCommand extends CommanderCommand { }).start(); try { - // this.cloneRepository(idOrNamespace); user = await DojoBackendManager.getUserAssignments(userId); + + // user.assignments?.forEach((a, _) => { + // console.log(a.name); + // }); + if (user && user.assignments && user.assignments.length > 0) { const assignmentRequests = user.assignments.map(a => - DojoBackendManager.exportLightAssignment(String(a.name)) + DojoBackendManager.exportLightAssignment(String(a.name), folderName) ); // Attendre que toutes les promesses soient résolues const results = await Promise.all(assignmentRequests); - // Vérifier les résultats et traiter en conséquence results.forEach(result => { if (result) { - console.log(result); - } else { - console.error('Failed to archive some assignments\n'); - } + spinner.succeed(result); + } + // else { + // spinner.fail('Failed to archive some assignments' + result + '\n'); + // } }); + const link = await DojoBackendManager.zipFolder(folderName); + console.log('\n' + link); } - // DojoBackendManager.exportLightAssignment(userId); - spinner.succeed('Archiving successful\n'); } catch (error) { spinner.fail(`Failed to create an archive\n`); diff --git a/NodeApp/src/commander/exercise/ExerciseCommand.ts b/NodeApp/src/commander/exercise/ExerciseCommand.ts index 8089092754831b94bf8b9fba3e07e2fcd92a657e..a787a2c356aca4b9513d4b5577d8fd413f6dce51 100644 --- a/NodeApp/src/commander/exercise/ExerciseCommand.ts +++ b/NodeApp/src/commander/exercise/ExerciseCommand.ts @@ -2,6 +2,7 @@ import CommanderCommand from '../CommanderCommand.js'; import ExerciseCreateCommand from './subcommands/ExerciseCreateCommand.js'; import ExerciseRunCommand from './subcommands/ExerciseRunCommand.js'; import ExerciseCorrectionCommand from './subcommands/ExerciseCorrectionCommand.js'; +import ExerciseExportCommand from './subcommands/ExerciseExportCommand.js'; class ExerciseCommand extends CommanderCommand { @@ -16,6 +17,7 @@ class ExerciseCommand extends CommanderCommand { ExerciseCreateCommand.registerOnCommand(this.command); ExerciseRunCommand.registerOnCommand(this.command); ExerciseCorrectionCommand.registerOnCommand(this.command); + ExerciseExportCommand.registerOnCommand(this.command); } protected async commandAction(): Promise<void> { diff --git a/NodeApp/src/commander/exercise/subcommands/ExerciseExportCommand.ts b/NodeApp/src/commander/exercise/subcommands/ExerciseExportCommand.ts new file mode 100644 index 0000000000000000000000000000000000000000..1036f535e90873690d9cbfa21dcb2c8e80877fbc --- /dev/null +++ b/NodeApp/src/commander/exercise/subcommands/ExerciseExportCommand.ts @@ -0,0 +1,55 @@ +import CommanderCommand from '../../CommanderCommand.js'; +import AccessesHelper from '../../../helpers/AccessesHelper.js'; +import DojoBackendManager from '../../../managers/DojoBackendManager.js'; +import ora from 'ora'; + +class ExerciseExportCommand extends CommanderCommand { + protected commandName: string = 'export'; + + protected defineCommand() { + this.command + .description('export a repository in an archive') + .argument('<userId>', 'name or url (http/s or ssh) of the assignment') + .argument('<folderName>', 'name of the zip') + .action(this.commandAction.bind(this)); + } + + protected async commandAction(userId : string, folderName : string): Promise<void> { + let user; + + if ( !await AccessesHelper.checkTeachingStaff() ) { + throw new Error(); + } + const spinner: ora.Ora = ora({ + text : 'Archiving all assignments', + indent: 8 + }).start(); + + try { + user = await DojoBackendManager.getUserExercises(userId); + if (user && user.exercises && user.exercises.length > 0) { + + const exerciseRequests = user.exercises.map(a => + DojoBackendManager.exportLightExercise(String(a.id), folderName) + ); + + // Attendre que toutes les promesses soient finis + const results = await Promise.all(exerciseRequests); + // Verifier les résultats + results.forEach(result => { + if (result) { + spinner.succeed(result); + } + }); + // const link = await DojoBackendManager.zipFolder(folderName); + // console.log('\n' + link); + } + spinner.succeed('Archiving successful\n'); + } catch (error) { + spinner.fail(`Failed to create an archive\n`); + } + } +} + + +export default new ExerciseExportCommand(); \ No newline at end of file diff --git a/NodeApp/src/managers/DojoBackendManager.ts b/NodeApp/src/managers/DojoBackendManager.ts index d395fce7b19b011f199092ebe56f5ae4903651af..f6b2d62384b3bd2954a325494393a22652a862db 100644 --- a/NodeApp/src/managers/DojoBackendManager.ts +++ b/NodeApp/src/managers/DojoBackendManager.ts @@ -223,34 +223,67 @@ class DojoBackendManager { } } - public async exportLightAssignment(idOrNamespace: string) { + public async exportLightAssignment(idOrNamespace: string, folderName : string) { try { - return (await axios.get<DojoBackendResponse<null>>(DojoBackendHelper.getApiUrl(ApiRoute.ASSIGNMENT_ARCHIVE, { assignmentNameOrUrl: idOrNamespace}))).data.data; + return (await axios.get<DojoBackendResponse<null>>(DojoBackendHelper.getApiUrl(ApiRoute.ASSIGNMENT_ARCHIVE, { + assignmentNameOrUrl: idOrNamespace, + }).replace('{{folderName}}', folderName))).data.data; } catch ( error ) { - return undefined; + throw error; } } - + public async getUserAssignments(id : string, verbose: boolean = true) { // const spinner: ora.Ora = ora('Fetching user\'s assignments...'); // if ( verbose ) { // spinner.start(); // } - + try { - return ((await axios.get<DojoBackendResponse<User>>(DojoBackendHelper.getApiUrl(ApiRoute.USER_ASSIGNMENTS, - { - assignmentNameOrUrl : id - }).replace('{{userId}}', id))).data.data); + return ((await axios.get<DojoBackendResponse<User>>(DojoBackendHelper.getApiUrl(ApiRoute.USER_ASSIGNMENTS, { + userId : id + }))).data.data); } catch (error) { // this.handleApiError(error, spinner, verbose, `Fetching user's assignments error : ${ error }`); throw error; } - // return (await axios.get<DojoBackendResponse<User>>(this.getApiUrl(ApiRoute.USER_ASSIGNMENTS).replace('{{userId}}', id))).data.data; } + public async zipFolder(folderName: string): Promise<string> { + try { + const response = (await axios.get<DojoBackendResponse<string>>(DojoBackendHelper.getApiUrl(ApiRoute.ASSIGNMENT_ZIP).replace('{{folderName}}', folderName), { + responseType: 'blob', + })).data; + // Construire l'URL de téléchargement + const downloadUrl = URL.createObjectURL(new Blob([response.data], { type: 'application/zip' })); + return downloadUrl; + } catch (error) { + console.error('Error generating zip assignment:', error); + throw error; + } + } + + public async getUserExercises(id : string, verbose: boolean = true) { + try { + return ((await axios.get<DojoBackendResponse<User>>(DojoBackendHelper.getApiUrl(ApiRoute.USER_EXERCISE, { + userId : id + }))).data.data); + } catch (error) { + throw error; + } + } + + public async exportLightExercise(exerciseIdOrUrl: string, folderName : string) { + try { + return (await axios.get<DojoBackendResponse<null>>(DojoBackendHelper.getApiUrl(ApiRoute.EXERCISE_ARCHIVE, { + exerciseIdOrUrl: exerciseIdOrUrl, + }).replace('{{folderName}}', folderName))).data.data; + } catch ( error ) { + throw error; + } + } } diff --git a/NodeApp/src/sharedByClients b/NodeApp/src/sharedByClients index 1232b31c642007409232e9244a7173265cf1f0b8..0b209c36d0aad3a032c9bbe632207dc61a2a6cf8 160000 --- a/NodeApp/src/sharedByClients +++ b/NodeApp/src/sharedByClients @@ -1 +1 @@ -Subproject commit 1232b31c642007409232e9244a7173265cf1f0b8 +Subproject commit 0b209c36d0aad3a032c9bbe632207dc61a2a6cf8