Skip to content

Commit

Permalink
chore: merge pull request #72 from Gabriel29306/generate-grade-book
Browse files Browse the repository at this point in the history
Generate grade book
  • Loading branch information
Vexcited authored Jan 17, 2025
2 parents 2573d27 + 9f57f2b commit 401f5be
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 0 deletions.
56 changes: 56 additions & 0 deletions examples/gradebook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import * as pronote from "../src";
import { credentials } from "./_credentials";
import { GradeBook } from "~/models/gradebook";

void async function main() {
const session = pronote.createSessionHandle();
await pronote.loginCredentials(session, {
url: credentials.pronoteURL,
kind: pronote.AccountKind.STUDENT,
username: credentials.username,
password: credentials.password,
deviceUUID: credentials.deviceUUID
});
const tab = session.userResource.tabs.get(pronote.TabLocation.Gradebook);
if (!tab) throw new Error("Cannot retrieve periods for the grades tab, you maybe don't have access to it.");
const selectedPeriod = tab.defaultPeriod!;

console.log("Available periods for this tab ->", tab.periods.map((period) => period.name).join(", "));
console.log("We selected the default period,", selectedPeriod.name, "!\n");

let gradebook: GradeBook;
try {
gradebook = await pronote.gradebook(session, selectedPeriod);
}
catch (error) {
console.error("The period is not accesibles");
throw error;
}

console.group("--- Subjects ---");

gradebook.subjects.forEach(
(subject) => {
console.group(subject.subject.name, ":", subject.teachers.join(", "));
console.log("Coef:", subject.coef);
console.group("Averages:");
console.log("Student:", subject.averages.student);
console.log("Class overall:", subject.averages.classOverall);
console.log("Max:", subject.averages.max);
console.log("Min:", subject.averages.min);
console.groupEnd(); // Averages
console.group("Assessment" + (subject.assessments.length > 1 ? "s: " : ": "));
subject.assessments.forEach((a) => console.log(a));
console.groupEnd(); // Assessments
console.groupEnd(); // Subject
}
);
console.groupEnd(); // Subjects
console.log(); // Make space between categories

console.group("--- Overall ---");
console.group("Assessment" + (gradebook.overallAssessments.length > 1 ? "s :" : " :"));
gradebook.overallAssessments.forEach((a) => console.log(a.name, ":", a.value));
console.groupEnd(); // Assessments
console.groupEnd(); // Overall
}();
25 changes: 25 additions & 0 deletions src/api/gradebook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { RequestFN } from "~/core/request-function";
import { encodePeriod } from "~/encoders/period";
import { type Period, type SessionHandle, TabLocation } from "~/models";
import { apiProperties } from "./private/api-properties";

import { decodeGradeBook } from "~/decoders/gradebook";
import { GradeBook } from "~/models/gradebook";

export const gradebook = async (session: SessionHandle, period: Period): Promise<GradeBook> => {
const properties = apiProperties(session);

period = {...period, kind: 2};

const request = new RequestFN(session, "PageBulletins", {
[properties.data]: {
classe: {},
eleve: {},
periode: encodePeriod(period)
},
[properties.signature]: { onglet: TabLocation.Gradebook }
});

const response = await request.send();
return await decodeGradeBook(session, period, response.data[properties.data]);
};
1 change: 1 addition & 0 deletions src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export * from "./discussions";
export * from "./evaluations";
export * from "./geolocation";
export * from "./gradebook-pdf";
export * from "./gradebook";
export * from "./grades-overview";
export * from "./homepage";
export * from "./instance";
Expand Down
47 changes: 47 additions & 0 deletions src/decoders/gradebook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { GradeBook, GradeBookSubject } from "~/models/gradebook";
import { decodeSubject } from "./subject";
import { gradebookPDF } from "~/api";
import { PageUnavailableError, Period, SessionHandle } from "~/models";

/**
* @param gradeBookData response from PageBulletins
*/
export const decodeGradeBook = async (session: SessionHandle, period: Period, gradeBookData: any): Promise<GradeBook> => {
// When bad period is used, the return is `{ data: {}, nom: 'PageBulletins' }` but the session don't expire.
if (Object.keys(gradeBookData).length == 0 || gradeBookData.message)
throw new PageUnavailableError();

let overallAssessments: { name: string; value: string; }[] = gradeBookData.ObjetListeAppreciations.V.ListeAppreciations.V.map(
(assessment: any) => {
return { name: assessment.Intitule, value: assessment.L };
}
);
const subjects = (gradeBookData.ListeServices.V as Array<any>).map(
(subjectData) => {
return {
subject: decodeSubject(subjectData.Matiere?.V),
subjectGroup: subjectData.SurMatiere.V,
coef: parseInt(subjectData.Coefficient.V),

averages: {
student: parseFloat(subjectData.MoyenneEleve.V.replace(",", ".")),
classOverall: parseFloat(subjectData.MoyenneClasse.V.replace(",", ".")),
max: parseFloat(subjectData.MoyenneSup.V.replace(",", ".")),
min: parseFloat(subjectData.MoyenneInf.V.replace(",", "."))
},

assessments: (subjectData.ListeAppreciations.V as Array<any>).map((a) => a.L),
teachers: subjectData.ListeElements?.V.map((elem: any) => elem.ListeProfesseurs?.V.map((v: any) => v.L))
?? subjectData.ListeProfesseurs?.V.map((a: any) => a.L)
?? []
} as GradeBookSubject;
}
);

return {
overallAssessments,
graph: gradeBookData?.graphe?.replace("\\n", ""),
subjects,
url: await gradebookPDF(session, period)
};
};
32 changes: 32 additions & 0 deletions src/models/gradebook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Subject } from "./subject";

export type GradeBook = Readonly<{
message?: string;
/**
* The differents assessments like the mentions or the overall rating
*/
overallAssessments: {
name: string;
value: string;
}[];
/**
* graph image as base64 png (with white backgound)
*/
graph?: string;
subjects: GradeBookSubject[];
url: string;
}>;

export type GradeBookSubject = {
subject: Subject;
subjectGroup: string;
coef: number;
averages: {
student: number;
classOverall: number;
max: number;
min: number;
};
assessments: string[];
teachers: string[];
};

0 comments on commit 401f5be

Please sign in to comment.