Giter Club home page Giter Club logo

edupageapi's Introduction

EdupageAPI

This is an unofficial Node.js implementation of the Edupage API. This module is not maintained, authorized, or sponsored by Edupage. Edupage's internal API could change at any time, and break functionality of this module. If you find bugs, have any questions or suggestions for features, please let me know and submit an issue.

Table of Contents

Overview

EdupageAPI is a module to easily access and interact with your Edupage account. All the basic types like students, teachers, subjects, timetables, messages are stored into the groups with user-friendly API to get data and do basic actions (obtaining lessons, replying to messages...). You can also a send message marked as Important, which is not possible using the official Edupage application (unless you have an account with teacher privileges).

Requirements

  • Node.js v14.0.0+
  • Edupage account

Installation

npm i edupage-api

Usage

The only thing you need to set up the API is to log in, like so:

const {Edupage} = require("edupage-api");

// Create blank Edupage instance
const edupage = new Edupage();

// This will automatically create new User instance and
// fill in all arrays and properties inside `edupage`
edupage.login("username/email", "password").then(user => {
    // Currently logged user (`user`) can be also accessed by `edupage.user`

    // Here you can write your code...
}).catch(err => {
    // Catch errors
});

Most of the objects have _data property, which holds raw data fetched directly from Edupage servers so in case there are no parsed properties you are looking for, you can get raw data by accessing those _data properties and process it yourself.

Examples

Note: In production, you should be handling Promise rejections by promise.catch() or try ... catch.

Get lessons for a given date

This example shows how to obtain timetable (with lessons) for current date. Initially there are available 2 to 4 timetables only, but this method tries to automatically fetch and update given timetables.

const {Edupage} = require("edupage-api");

const edupage = new Edupage();

(async () => {
    await edupage.login("username", "password");

    //Get today's date for example
    const date = new Date();

    //Get timetable for `date`
    const timetable = await edupage.getTimetableForDate(date);

    //Get array with lessons for this timetable
    const lessons = timetable.lessons;

    console.log(lessons);

    edupage.exit(); //To exit the process
})();

Get homework assignments for the next day

This simple snippet returns each homework and test happening the next day (from today) as an array of the assignments.

const {Edupage} = require("edupage-api");

const edupage = new Edupage();

(async () => {
    await edupage.login("username", "password");

    //Get tomorrow's date
    const tomorrow = new Date();
    tomorrow.setDate(tomorrow.getDate() + 1);

    //Get lessons
    const timetable = await edupage.getTimetableForDate(tomorrow);
    const lessons = timetable.lessons;

    //Collect assignments
    const homeworks = lessons.reduce((arr, lesson) => (arr.push(...lesson.assignments), arr), []);

    console.log(homeworks);

    edupage.exit(); //To exit the process
})();

Get timetables for specific date range

If you need to access multiple timetables at once, you can use this method.

Note: You shouldn't be calling this method in loop for same date range, use getTimetableForDate method instead which reads from cache.

const {Edupage} = require("edupage-api");

const edupage = new Edupage();

(async () => {
    await edupage.login("username", "password");

    //Choose a date range
    const from = new Date("2021-05-10");
    const to = new Date("2021-05-15");

    //Fetch array of the timetables
    //Note: This will also update `edupage.timetables` array
    const timetables = await edupage.fetchTimetablesForDates(from, to);

    console.log(timetables);

    edupage.exit(); //To exit the process
})();

Sign into an online lesson

Using this simple snippet you can tell your teacher that you are present on the lesson.

const {Edupage} = require("edupage-api");

const edupage = new Edupage();

(async () => {
    await edupage.login("username", "password");

    //Get today's date for example
    const date = new Date();

    //Get timetable for today
    const timetable = await edupage.getTimetableForDate(date);

    //Get your lesson
    //Note: This will return second lesson in array, not second period.
    //      In case you want to access second period you may need:
    //      `timetable.lessons.find(e => e.period.id == "3")`
    const lesson = timetable.lessons[1];

    //You should check if the lesson is an online lesson
    if(lesson.isOnlineLesson) {
        //Sign it (this method may not be successful, in such case it will return `false`)
        const success = await lesson.signIntoLesson();

        console.log(success);
    }

    edupage.exit(); //To exit the process
})();

Send a message to the user

This example shows how to send a simple message to another user.

const {Edupage} = require("edupage-api");

const edupage = new Edupage();

(async () => {
    await edupage.login("username", "password");

    //Get the user
    const classmate = edupage.students.find(e => e.firstname == "John" && e.lastname == "Smith");

    //Configure the message
    const options = {
        text: "Hello there!",   //Message content
        important: true         //Make this message marked as important
    };

    //Send the message
    await classmate.sendMessage(options);

    edupage.exit(); //To exit the process
})();

Send a message with an attachment

This example shows how to send a message with an attachment(s) to another user.

const {Edupage} = require("edupage-api");

const edupage = new Edupage();

(async () => {
    await edupage.login("username", "password");

    //Get a user
    const teacher = edupage.teachers.find(e => e.firstname == "John" && e.lastname == "Smith");

    //Upload the attachment
    const attachment = await edupage.uploadAttachment("C:/Users/username/Documents/Homework.docx");

    //Configure the message
    const options = {
        text: "Sending my homework!",  //Message content
        attachments: [attachment]      //Array of attachments
    };

    //Send the message
    await teacher.sendMessage(options);

    edupage.exit(); //To exit the process
})();

Get the material data and results of an assignment

Using this snippet you can access material data and/or results of an assignment. This method is not implemented yet, so you have to process it yourself.

const {Edupage} = require("edupage-api");

const edupage = new Edupage();

(async () => {
    await edupage.login("username", "password");

    //Get an assignment (you can search by title, id...)
    const assignment = edupage.assignments.find(e => e.title.startsWith("Surface integral of vector field"));

    //Get the data
    //Note: This returns RawDataObject (it might get implemented in the future)
    const {materialData, resultsData} = await assignment.getData();

    console.log(materialData, resultsData);

    edupage.exit(); //To exit the process
})();

Post COVID-19 infectivity application

🚨 This example is experimental, you should avoid using it in production until stable version!

Are you annoyed sending each week a new infectivity application? You can make that programmatically now! The following snipped shows how to post Covid-19 infectivity application with current date.

const {Edupage} = require("edupage-api");

const edupage = new Edupage();

(async () => {
    await edupage.login("username", "password");

    //Get an application you want to post
    const application = edupage.applications.find(e => e.id == "teacher_infectivity_2_20210517");

    //Get today's date
    const today = new Date();

    //Post the application
    const success = await application.post({
        date: Edupage.dateToString(today)    //Processing for the values is not supported, so you have to make it yourself
    });

    //Console.log the result (🚨 This might not be precise!)
    console.log(success);

    edupage.exit(); //To exit the process
})();

API

Here you can find representations of all classes, interfaces and enums. In code, you shouldn't be creating any instances of the following classes except for Edupage class. All required classes are created internally. Most of the classes contain Edupage instance.

Note: following snippets are not actual valid code.

API Contents

Classes

class ASC

This class holds the basic information about a school and logged user.

class ASC extends RawData {
    edupage: Edupage;

    loggedUser: string;          // UserString of the currently logger user
    loggedUserRights: any[];

    lang: string;                // Language code
    timezone: string;            // Example: "Europe/Bratislava"
    firstDayOfWeek: number;      // 0 = sunday
    weekendDays: number[];       // 0 = sunday

    schoolName: string;          // Long name of the school
    schoolCountry: string;       // Country code
    schoolyearTurnover: string;  // Example: "08-01"

    server: string;
    gsecHash: string;
    gpids: string[];
    gpid?: string;
}

class Application

🚨 This is an experimental class, you should not be using this class in production

This class holds the information about an application (e.g. Covid-19 infectivity)

class Application extends RawData {
    edupage: Edupage;

    id: string;
    name: string;

    dateFrom: Date;
    dateTo: Date;

    parameters: string[];           // List of parameters to be passed to `Application.post(...)`
    
    availableFor: EntityType;       // Usually `ENTITY_TYPE.STUDENT` or `ENTITY_TYPE.TEACHER`

    isEnabled: boolean;             // Determines whether the application is enabled in your Edupage
    isTextOptional: boolean;		// Unknown property
    isAdvancedWorkflow: boolean;    // Unknown property
    isSimpleWorkflow: boolean;      // Unknown property

    // Creates draft for the application
    async createDraft(): Promise<string>;
    
    // Posts the application
    // 🚨 This method might not return accurate result
    static post(
        parameters: RawDataObject = {},     // Parameters from `Application.parameters`
        draftId?: string = null             // Draft ID (created internally if not provided)
    ): Promise<boolean>;
}

class Assignment

This class holds the information about an assignment such as homework, test, presentation...

class Assignment extends RawData {
    edupage: Edupage;

    id: string;
    superId: string;
    testId: string;
    hwkid: string;

    type: AssignmentType;
    owner: User | Teacher;   // Creator of the assignment
    subject: Subject;
    period: Period;
    grades: Grade[];

    creationDate: Date;      // Time when was the assignment created
    fromDate: Date;          // Time from when is the assignment available for students
    toDate: Date;            // Time until the assignment is available for students
    duration: number;        // Number of seconds for students to submit the assignment

    title: string;
    details: string;
    comment: string;
    result: string;

    state: string;
    stateUpdatedDate: Date;
    stateUpdatedBy: User | Teacher;

    cardsCount: number;
    answerCardsCount: number;

    isSeen: boolean;
    isFinished: boolean;

    async getData(): Promise<RawDataObject>;
    
    static from(
        data: RawDataObject,
        edupage: Edupage
    ): Assignment | Homework | Test;
}

class Attachment

This class holds the information about an attachment.

class Attachment extends RawData {
    edupage: Edupage;

    name: string;   // Name containing file extension
    src: string;    // Source url, absolute path
}

class Class

This class holds basic the information about a school class.

class Class extends RawData {
    edupage: Edupage;

    id: string;
    grade: number;  // e.g. first grade, second grade etc.
    name: string;
    short: string;

    classroom: Classroom;

    teacher?: Teacher;
    teacher2?: Teacher;
}

class Classroom

This class holds basic the information about a classroom.

class Classroom extends RawData {
    edupage: Edupage;

    id: string;
    name: string;
    short: string;

    cb_hidden: boolean;
}

class Edupage

This is the main EdupageAPI class, containing all resources fetched and parsed from the Edupage servers. You can access all properties and methods to obtain required data. The property _data contains original raw data. (As well as some data which are not supported yet)

class Edupage extends RawData {
    user: User | Teacher | Student;  // Gets assigned automatically after successful login() call

    students: Student[];
    teachers: Teacher[];
    parents: Parent[];

    plans: Plan[];
    classes: Class[];
    classrooms: Classroom[];
    
    seasons: Season[];
    periods: Period[];
    subjects: Subject[];
    timetables: Timetable[];

    timelineItems: Message[];       // Contains all timeline items (including confirmations)
    timeline: Message[];            // Contains only visible items (messages, assignments, grades...)
    assignments: Assignment[];      // Contains all assignments (homework assignments, tests and other)
    homeworks: Homework[];          // Contains assignments type of homework
    tests: Test[];                  // Contains assignments type of test

    ASC: ASC;

    year: number;
    baseUrl: string;                // Example: "https://example.edupage.org"

    getUserById(id: string): User | Teacher | Student | Parent | undefined;
    getUserByUserString(userString: string): User | Teacher | Student | Parent | undefined;
    getYearStart(time?: boolean = false): string; // Example: "2020-08-01" or "2020-08-01 00:00:00"

    async getTimetableForDate(date: Date): Promise<Timetable | undefined>;  // Note: Calls `fetchTimetablesForDates` method internally if the given timetable is missing
    
    async fetchTimetablesForDates(   // Fetches the timetables from Edupage (+caching and updating existing)
        fromDate: Date,
        toDate: Date
    ): Promise<Timetable[]>

    async login(
        username: string,
        password: string
    ): Promise<User | Teacher | Student>;
    
    async refresh(): void;                                        // Refreshes all values in current instance
    async refreshEdupage(_update?: boolean = true): void;         // Refreshes global Edupage data (such as teachers, classes, classrooms, subjects...)
    async refreshTimeline(_update?: boolean = true): void;        // Refreshes timeline data (messages, notifications...)
    async refreshCreatedItems(_update?: boolean = true): void;    // Refreshes timeline items data created by currently logged user
    async refreshGrades(_update?: boolean = true): void;          // Refreshes grades of currently logged  user

    _updateInternalValues(): void;                                // Updates all fields of the current instance (called internally after
                                                                  // any of the "refresh" methods, if `_update` is set to `true`)

    async uploadAttachment(filepath: string): Promise<Attachment>;
    async api(options: APIOptions, _count: number = 0): Promise<RawDataObject | string, Error | {retry: true, count: number}>;

    scheduleSessionPing(): void;
    async pingSession(): Promise<boolean>;

    exit(): void;                   // Stops internal timers to prevent process from hanging infinitely.

    static compareDay(
        date1: Date | number | string,
        date2: Date | number | string
    ): boolean;

    static dateToString(            // Converts Date into string (Example: "2020-05-17")
        date: Date
    ): string;
}

class Grade

This class holds the information about a student's grade.

Note: properties points, maxPoints and percentage are only available if type == "3".

class Grade extends RawData {
    edupage: Edupage;

    id: string;
    eventId: string;
    superId: string;

    type: string;
    state: string;
    provider: string;       // Usually "edupage"

    student: Student;
    teacher: Teacher;

    creationDate: Date;
    signedDate: Date;
    signedByParentDate: Date;

    plan: Plan;
    class: Class;
    classes: Class[];

    season: Season;
    subject: Subject;
    assignment: Assignment;

    title: string;
    short: string;
    date: string;

    value: string;          // Actual grade
    weight: number;         // Weight of the grade as decimal number (Example: 0.25)
    points?: number;        // Points gained
    maxPoints?: number;     // Max possible points
    percentage?: number;    // Ratio between gained points and maxPoints in percents
    average: string;        // Average gained points / grade in class

    isSigned: boolean;
    isClassified: boolean;
}

class Homework

This is a wrapper class for the Assignment class

class Homework extends Assignment {

}

class Lesson

This class holds the information about a lesson.

class Lesson extends RawData {
    edupage: Edupage;

    id: string;
    lid: string;

    students: Student[];
    teachers: Teacher[];

    classes: Class[];
    classrooms: Classroom[];

    date: Date;            // Starting time of the lesson
    period: Period;
    subject: Subject;
    
    assignments: Assignment[];
    onlineLessonURL: string;

    homeworkNote: string;
    absentNote: string;
    curriculum: string;

    isOnlineLesson: boolean;

    async signIntoLesson(): Promise<boolean>;
}

class Message

This class holds the information about a message. You can also do some basic actions like replying, liking the message, starring the message...

class Message extends RawData {
    edupage: Edupage;

    id: string;
    otherId: string;
    type: TimelineItemType;

    owner: User | Teacher | Student | Parent;   // Sender or Author
    recipient: User | Teacher | Student | Parent | Plan | Class;
    recipientUserString: string;                // In some cases, the recipient cannot be parsed, so this property holds it's raw UserString
    participants: (User | Teacher | Student | Parent)[];
    participantsCount: number;

    creationDate: Date;          // Time when the message was created
    timelineDate: Date;          // Time on the timeline (when someone reacts to the message, it will get pushed at the top of the timeline)
    lastReplyDate: Date;         // Time of the last reply
    seenDate: Date;              // Time when the message has been seen (this will be always same as `creationDate` if the message is not important)
    likedDate: Date;
    doneDate: Date;

    likedBy: ({
        user: User | Teacher | Student | Parent,
        date: Date
    })[];
    
    seenBy: ({
        user: User | Teacher | Student | Parent,
        date: Date
    })[];

    text: string;
    title: string;
    likes: number;
    
    replyOf: Message;
    replies: Message[];
    repliesCount: number;

    attachments: Attachment[];
    assignment: Assignment;

    isRemoved: boolean;
    isReply: boolean;
    isImportant: boolean;
    isSeen: boolean;                  // This will be always true if the message is not important
    isLiked: boolean;
    isDone: boolean;
    isStarred: boolean;
    isWildcardRecipient: boolean;     // Determines whether exact recipient is known (you should be using `recipientUserString` if this is true)

    async markAsSeen(): Promise<void>;
    async markAsLiked(state?: boolean = true): Promise<boolean>;
    async markAsDone(state?: boolean = true): Promise<boolean>;
    async markAsStarred(state?: boolean = true): Promise<boolean>;

    async reply(options: MessageReplyOptions): void;
    async refresh(data?: RawDataObject = null): void;	// To refresh message content (e.g. replies) call this method (ignoring `data` paramenter)
}

class Parent

This class holds the basic information about a parent.

class Parent extends User {
    edupage: Edupage;

    id: string;
    userString: string;

    firstname: string;
    lastname: string;

    gender: GENDER;
}

class Period

This class holds the information about a school period.

class Period extends RawData {
    id: string;    // Starts from 1

    name: string;
    short: string;

    startTime: string;
    endTime: string;

    getInvalid(data?: {    //Creates new invalid Period
        id?: string?,
        name?: string,
        short?: string,
        startTime?: string,
        endTime?: string
    } = null): Period;
}

class Plan

This class holds the information about a school Plan. It's like a group of specific students for some subject.

class Plan extends RawData {
    edupage: Edupage;

    id: string;
    otherId: string;
    customClassId: string;

    teacher: Teacher;
    teachers: Teacher[];
    students: Student[];

    changedDate: Date;
    approvedDate: Date;
    
    name: string;
    customName: string;
    classOrdering: number;

    year: number;
    season: Season;
    subject: Subject;
    classes: Class[];
    
    state: string;
    timetableGroup: string;
    settings: Object<string, any>;

    topicsCount: number;
    taughtCount: number;
    standardsCount: number;

    isEntireClass: boolean;
    isApproved: boolean;
    isPublic: boolean;
    isValid: boolean;
}

class RawData

This is the base class for storing raw data fetched from Edupage servers. It contains a single property - _data, this property is non-enumerable

class RawData {
    _data: RawDataObject;
}

class Season

This class holds the information about a school season. It could be month, semester...

class Season extends RawData {
    edupage: Edupage;

    id: string;
    index: number;      // Starting from 1 (e.g. first month of the school year)
    types: string[];    // ? Unknown property

    fromDate: Date;
    toDate: Date;

    name: string;
    halfYear: number;   // First or second semester
    supSeason: Season;  // Upper season (e.g. if `this` is the first month, this property will be first a half year)
    classificationSeason?: Season;

    isClassification: boolean;
}

class Student

This class holds the information about a student.

class Student extends User {
    edupage: Edupage;

    class: Class;
    number: number;           // ? Unknown property
    numberInClass: number;    // This is actual number in class

    parent1Id: string;
    parent2Id: string;
    parent3Id: string;

    parent1?: Parent;
    parent2?: Parent;
    parent3?: Parent;

    userString: string;

    getUserString(parents?: boolean = false): string;
}

class Subject

This class holds the information about a subject.

class Subject extends RawData {
    id: string;

    name: string;
    short: string;
}

class Teacher

This class holds the information about a teacher.

class Teacher extends User {
    edupage: Edupage;

    classroom: Classroom;
    short: string;
    
    userString: string;
    cb_hidden: number;     // ? Unknown property
}

class Test

This is a wrapper class for the Assignment class.

class Test extends Assignment {

}

class Timetable

This class holds the information about a timetable. Timetable for only single day, not entire week.

class Timetable extends RawData {
    edupage: Edupage;

    date: Date;
    week: number;         // ? Unknown property (Maybe odd/even week?)
    lessons: Lesson[];
}

class User

This class holds the information about a user. Use sendMessage method to send message to the user.

class User extends RawData {
    edupage: Edupage;

    id: string;
    origin: string;
    userString: string;

    dateFrom: Date;
    dateTo: Date;
    
    firstname: string;
    lastname: string;
    gender: Gender;
    email?: string;
    cookies?: CookieJar;
    credentials?: {
        username: string,
        password: string
    };

    isLoggedIn: boolean;
    isOut: boolean;

    getUserString(): string;

    async sendMessage(options: MessageOptions): Message;
    
    async login(
        username: string,
        password: string
    ): Promise<User>;

    static from(
        userString: string,
        data?: RawDataObject = {},
        edupage?: Edupage = null
    ): User | Teacher | Student | Parent;
}

Interfaces

interface APIOptions

Using this interface you can specify the API options.

interface APIOptions {
    url: string | APIEndpoint;          // APIEndpoint is automatically resolved
    data?: (Object<string, any> | stream.Readable | Buffer | string) = {};
    headers?: Object<string, any> = {};
    method?: string = "POST";
    encodeBody?: boolean = true;        // Encode body as `form-urlencoded` using Edupage "special" encryption
    type?: "json" | "text" = "json";    // Response type
    autoLogin?: boolean = true;         // Log in the user automatically if they're logged out (e.g. expired session)
}

interface MessageOptions

Using this interface you can specify the message options.

interface MessageOptions {
    text: string;                       // Content of the message
    important?: boolean = false;        // Mark message as important
    parents?: boolean = false;          // Include parents
    attachments?: Attachment[] = [];
}

interface MessageReplyOptions

Using this interface you can specify the message options for reply.

interface MessageReplyOptions {
    text: string;                       //  Content of the reply
    recipient?: (User | Teacher | Student | Parent) = null;	// Send only to the exact user
    parents?: boolean = false;          // Include parents
    attachments?: Attachment[] = []
}

interface RawDataObject

This interface is used to represent raw data fetched from the Edupage servers.

interface RawDataObject {
  [property: string]: any;
}

Enums

enum APIEndpoint

This enum contains records about the API endpoints.

enum APIEndpoint {
    DASHBOARD_GET_USER,
    DASHBOARD_SIGN_ONLINE_LESSON,
    TIMELINE_GET_DATA,
    TIMELINE_GET_REPLIES,        
    TIMELINE_GET_CREATED_ITEMS,  
    TIMELINE_CREATE_ITEM,        
    TIMELINE_CREATE_CONFIRMATION,
    TIMELINE_CREATE_REPLY,       
    TIMELINE_FLAG_HOMEWORK,      
    TIMELINE_UPLOAD_ATTACHMENT,
    ELEARNING_TEST_DATA,        
    ELEARNING_TEST_RESULTS,     
    ELEARNING_CARDS_DATA,       
    GRADES_DATA
}

enum APIStatus

This enum contains records about the API response statuses.

enum APIStatus {
    OK = "ok",
    FAIL = "fail"
}

enum AssignmentType

This enum contains records about the assignment types.

enum AssignmentType {
    HOMEWORK = "hw",
    ETEST_HOMEWORK = "etesthw",
    BIG_EXAM = "bexam",
    EXAM = "exam",
    SMALL_EXAM = "sexam",
    ORAL_EXAM = "oexam",
    REPORT_EXAM = "rexam",
    TESTING = "testing",
    TEST = "test",
    PROJECT_EXAM = "pexam",
    ETEST = "etest",
    ETEST_PRINT = "etestprint",
    ETEST_LESSON = "etestlesson",
    LESSON = "lekcia",
    PROJECT = "projekt",
    RESULT = "result",
    CURRICULUM = "ucivo",
    TIMELINE = "timeline"
}

enum AssignmentGroup

This enum contains records about the assignments groups.

enum AssignmentGroup {
    HOMEWORK = ["hw", "etesthw"],
    EXAM = ["bexam", "sexam", "oexam", "rexam", "testing"],
    TEST = ["test", "etest", "etestprint"],
    PROJECT = ["pexam", "projekt"],
    PRESENTATION = ["etestlesson", "lekcia"],
    OTHER = ["result", "ucivo", "timeline"]
}

enum EntityType

This enum contains records about the entity types.

enum EntityType {
    STUD_PLAN = "StudPlan",
    STUDENT = "Student",
    CUST_PLAN = "CustPlan",
    STUDENT_ONLY = "StudentOnly",
    STUD_CLASS = "StudTrieda",
    TEACHER = "Ucitel",
    ALL = "*",
    CLASS = "Trieda",
    STUDENT_ALL = "Student*",
    STUDENTONLY_ALL = "StudentOnly*",
    TEACHER_ALL = "Ucitel*",
    ADMIN = "Admin",
    PARENT = "Parent"
}

enum Gender

This enum contains records about the genders.

enum Gender {
    MALE = "M",
    FEMALE = "F"
}

enum TimelineItemType

This enum contains records about the timeline item types.

enum TimelineItemType {
    MESSAGE = "sprava",
    MESSAGE_TO_SUBTITUTER = "spravasuplujucemu",
    NOTICEBOARD = "nastenka",
    GRADE_ANNOUNCEMENT = "nastenka",
    GRADE = "znamka",
    NOTE = "vcelicka",
    HOMEWORK = "homework",
    HOMEWORK_STUDENT_STATE = "homework",
    ABSENCE_NOTE = "ospravedlnenka",
    ABSENCE_NOTE_REMINDER = "ospravedlnenka_reminder",
    PROCESS = "process",
    PROCESS_ADMIN = "processadmin",
    STUDENT_ABSENT = "student_absent",
    ACCIDENT = "accident",
    EVENT = "event",
    TIMETABLE = "timetable",
    SUBSTITUTION = "substitution",
    CANTEEN_MENU = "stravamenu",
    CANTEEN_CREDIT = "strava_kredit",
    CANTEEN_SUSPEND_REINSTATE_ORDERS = "strava_prerusObnovObj",
    CANTEEN_OPENING = "strava_vydaj",
    SURVEY = "anketa",
    PLAN = "plan",
    SETTINGS = "settings",
    ALBUM = "album",
    NEWS = "news",
    TEST_ASSIGNMENT = "testpridelenie",
    TEST_RESULT = "testvysledok",
    CHAT = "chat",
    CHECK_IN = "pipnutie",
    CONSULTATION_MESSAGE = "konzultaciemsg",
    CONSULTATION = "konzultacie",
    PAYMENTS = "payments",
    SIGN_IN = "signin",
    CURRICULUM = "ucivo",
    CURRICULUM_REMINDER = "ucivo_reminder",
    BLACKBOARD = "bb",
    STUDENT_PICKUP = "odchadzka",
    TIMETABLE_CLOUD_GENERATE = "ttcloudgen",
    CONFIRMATION = "confirmation",
    CONTEST = "contest"
}

edupageapi's People

Contributors

ivanhrabcak avatar loumadev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

edupageapi's Issues

failed to parse redirect url.

hello. i am currently just trying to grab a timetable. but my school has got a custom subdomain here.

and cant seem to find out to use "Edupage.Login". Thanks In Advance

Edupage logging out after some time

#
# A fatal error has occurred!
#
# This is probably not your fault!
# If this happens often, please consider reporting a bug.
#
# Error thrown:
#  ParseError: Failed to parse timetable data from html
#      at Function.parse (/media/cfp/Volume/Projects/edupageCLI/node_modules/edupage-api/src/Timetable.js:70:51)
#      at Edupage.fetchTimetablesForDates (/media/cfp/Volume/Projects/edupageCLI/node_modules/edupage-api/src/Edupage.js:466:27)
#      at processTicksAndRejections (node:internal/process/task_queues:96:5)
#      at async Edupage.getTimetableForDate (/media/cfp/Volume/Projects/edupageCLI/node_modules/edupage-api/src/Edupage.js:426:11)
#      at async timetable (/media/cfp/Volume/Projects/edupageCLI/main.js:36:30)
#      at async /media/cfp/Volume/Projects/edupageCLI/main.js:178:7
#
# Summary:
#  Time: Fri Jan 21 2022 17:21:57 GMT+0100 (Central European Standard Time)
#  EdupageAPI version: v0.7.14
#  Node.js version: v16.13.0
#  Error log: /media/cfp/Volume/Projects/edupageCLI/node_modules/edupage-api/logs/fatal_error_2022-01-21T16-21-57Z.json
#
# If you would like to submit an issue, please visit:
#  > https://github.com/loumadev/EdupageAPI/issues
#  (Please, include this error message + error log)
#

✖ Error!!

TypeError: Cannot read properties of undefined (reading 'dates')
    at Edupage.fetchTimetablesForDates (/media/cfp/Volume/Projects/edupageCLI/node_modules/edupage-api/src/Edupage.js:467:36)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async Edupage.getTimetableForDate (/media/cfp/Volume/Projects/edupageCLI/node_modules/edupage-api/src/Edupage.js:426:11)
    at async timetable (/media/cfp/Volume/Projects/edupageCLI/main.js:36:30)
    at async /media/cfp/Volume/Projects/edupageCLI/main.js:178:7

Error log:

{
	"error": {
		"stack": "ParseError: Failed to parse timetable data from html\n    at Function.parse (/media/cfp/Volume/Projects/edupageCLI/node_modules/edupage-api/src/Timetable.js:70:51)\n    at Edupage.fetchTimetablesForDates (/media/cfp/Volume/Projects/edupageCLI/node_modules/edupage-api/src/Edupage.js:466:27)\n    at processTicksAndRejections (node:internal/process/task_queues:96:5)\n    at async Edupage.getTimetableForDate (/media/cfp/Volume/Projects/edupageCLI/node_modules/edupage-api/src/Edupage.js:426:11)\n    at async timetable (/media/cfp/Volume/Projects/edupageCLI/main.js:36:30)\n    at async /media/cfp/Volume/Projects/edupageCLI/main.js:178:7",
		"message": "Failed to parse timetable data from html",
		"name": "ParseError"
	},
	"data": {
		"html": "JS: /* Error6511024354099 */ ASC.reloadPage();",
		"match": null
	}
}

Stuff that may be causing the problem:
I left the program running for a very long time, maybe it logged out after some time and thats why?

`const d = this.period.startTime.split(":");` can't read `startTime` of `undefined`

Hi! sorry me again,
got a roadblock today when listing lessons, idk what Edupage outputs there

/CON/edupage-ical/node_modules/edupage-api/src/Lesson.js:130
                const d = this.period.startTime.split(":");
                                      ^

TypeError: Cannot read properties of undefined (reading 'startTime')
    at Lesson.init (/CON/edupage-ical/node_modules/edupage-api/src/Lesson.js:130:25)
    at new Lesson (/CON/edupage-ical/node_modules/edupage-api/src/Lesson.js:108:42)
    at /CON/edupage-ical/node_modules/edupage-api/src/Timetable.js:57:78
    at Array.map (<anonymous>)
    at Timetable.init (/CON/edupage-ical/node_modules/edupage-api/src/Timetable.js:57:66)
    at /CON/edupage-ical/node_modules/edupage-api/src/Edupage.js:359:34
    at Array.forEach (<anonymous>)
    at Edupage._updateInternalValues (/CON/edupage-ical/node_modules/edupage-api/src/Edupage.js:359:19)
    at Edupage.refresh (/CON/edupage-ical/node_modules/edupage-api/src/Edupage.js:194:8)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    

I'm using snippet of your code in https://github.com/loumadev/EdupageAPI#get-lessons-for-a-given-date

I hope I didn't disturb you.

Incorrect username

Hi, I'm trying to login to Edupage using edupage API, and it works, on my machine.

        var user = await edupage.login(process.env.USER, decryptedpass, {edupage: process.env.SCHOOL}).catch((err) => {
            console.log('-----EDUPAGE LOGIN FAILED-----');
            console.log(err)
         });

        if (typeof user == 'object') {
            sentembed3.delete();
            console.log('-----EDUPAGE LOGIN OK-----');
            await origmsg.channel.send({
                embeds: [embed4]
            });
            isInitialized = true;


            return edupage;
        } else { 
            sentembed3.delete();
            emergency.emergency(origmsg, bot);
            await origmsg.channel.send({
                embeds: [embed6]
            });
            return false;
        }

It logs in just fine on my PC, but on my server running Linux, it is unable to, and it says:
Failed to login: Incorrect username. (If you are sure that the username is correct, try providing the 'edupage' option)

Any ideas?
Thanks.

Listening for the substitution notifications

Zdravím, doufám že nevadí že budu psát česky.
Chtěl jsem se zeptat zda by bylo možné díky EdupageAPI napsat do konzole vždy když se nahraje na web suplování pro mojí třídu, zkoušel jsem to ale nepodařilo se mi to.

Je to možné?
Díky,
Megami.

EDIT: translated

Greetings, I hope it doesn't matter that I will write in Czech.
I'd like to ask, if it is be possible, thanks to EdupageAPI, to print into the console when there's a new substitution uploaded to the web for my class, I've tried it myself, but it I failed.

Is it possible?
Thanks,
Megami.

`debug` is not here

Error ⬇️

node:internal/modules/cjs/loader:936
  throw err;
  ^

Error: Cannot find module 'debug'
Require stack:
- /Volumes/2TB/edupag/node_modules/edupage-api/src/Edupage.js
- /Volumes/2TB/edupag/node_modules/edupage-api/index.js
- /Volumes/2TB/edupag/index.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (/Volumes/2TB/edupag/node_modules/edupage-api/src/Edupage.js:1:15)
    at Module._compile (node:internal/modules/cjs/loader:1101:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:1005:19) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/Volumes/2TB/edupag/node_modules/edupage-api/src/Edupage.js',
    '/Volumes/2TB/edupag/node_modules/edupage-api/index.js',
    '/Volumes/2TB/edupag/index.js'
  ]
}

Fixes - npm i debug with edupage-api module

Getting timetables for classes, students and teachers not just "My Timetable"

Yeah would be pretty cool to have, especially for my edupage discord bot as it currently shows my timetable to all students in my class who might have slightly different timetables.
Also i think this might be very easy to implement.
There should be some kind of InsufficientPermission exception for when you do not have permission to see a timetable.

Failed to parse timetable data from html

hey, me again

am sorry to bother you this


#
# A fatal error has occurred!
#
# This is probably not your fault!
# If this happens often, please consider reporting a bug.
#
# Error thrown:
#  ParseError: Failed to parse timetable data from html
#      at Function.parse (/home/runner/edupejc/node_modules/edupage-api/src/Timetable.js:70:51)
#      at Edupage.fetchTimetablesForDates (/home/runner/edupejc/node_modules/edupage-api/src/Edupage.js:466:27)
#      at processTicksAndRejections (node:internal/process/task_queues:96:5)
#      at async educal (/home/runner/edupejc/index.js:43:24)
#
# Summary:
#  Time: Sun Jan 09 2022 19:23:55 GMT+0000 (Coordinated Universal Time)
#  EdupageAPI version: v0.7.14
#  Node.js version: v16.7.0
#  Error log: /home/runner/edupejc/node_modules/edupage-api/logs/fatal_error_2022-01-09T19-23-55Z.json
#
# If you would like to submit an issue, please visit:
#  > https://github.com/loumadev/EdupageAPI/issues
#  (Please, include this error message + error log)
#

/home/runner/edupejc/node_modules/edupage-api/src/Edupage.js:467
        const timetables = iterate(_json.dates).map(([i, date, data]) => new Timetable(data, date, this));
                                         ^

TypeError: Cannot read property 'dates' of undefined
    at Edupage.fetchTimetablesForDates (/home/runner/edupejc/node_modules/edupage-api/src/Edupage.js:467:36)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async educal (/home/runner/edupejc/index.js:43:24)
    

Can't login

Hi @loumadev , I'm trying to use your API but I get an error:
edupage.login(process.env.USERNAME, decryptedpass).then(user => {
that the password is incorrect. It is, however correct, the issue is that I cannot login via portal.edupage.org, I need to login via subdomain.edupage.org, however this API unlike the python edupage api does not support the subdomain option for logging in. How can I proceed otherwise?
Thanks.

Cannot read property 'year' of undefined

My tries doing something with dates in the API (ex. get Homework)
Just gives the error "Cannot read property 'year' of undefined"
at Edupage.refresh(node_modules\edupage_api\src\Edupage.js:153:5

SyntaxError: Unexpected token '.' at /node_modules/edupage-api/src/Edupage.js:191

Hi,
I'm trying to run the sample code in readme for getting timetable. The only thing I changed is the username and password arguments.
I get the following error.

/node_modules/edupage-api/src/Edupage.js:191
iterate(_grades.data?.vsetkyUdalosti || {})

SyntaxError: Unexpected token '.'

Its the '.' after iterate(_grades.data?
in front of vsetkyUdalosti || {})

Cannot login

Hello, I've encountered a problem which I think was unavoidable (I've mentioned previously that it is a problem, but it was dismissed).

I cannot login with my credentials. They are correct, but in my school, I can't login with portal.edupage.org, only with subdomain.edupage.org where subdomain is the subdomain of my school. That is why your login method does not work with my credentials.

Error:

#
# A fatal error has occurred!
#
# This is probably not your fault!
# If this happens often, please consider reporting a bug.
#
# Error thrown:
#  EdupageError: Edupage server did not redirect login request to proper origin
#      at /home/ivanhrabcak/PythonProjects/edupog-backend/node_modules/edupage-api/src/User.js:221:52
#      at processTicksAndRejections (node:internal/process/task_queues:96:5)
#
# Summary:
#  Time: Fri Jan 28 2022 15:44:52 GMT+0100 (Central European Standard Time)
#  EdupageAPI version: v0.8.1
#  Node.js version: v17.4.0
#  Error log: /home/ivanhrabcak/PythonProjects/edupog-backend/node_modules/edupage-api/logs/fatal_error_2022-01-28T14-44-52Z.json
#
# If you would like to submit an issue, please visit:
#  > https://github.com/loumadev/EdupageAPI/issues
#  (Please, include this error message + error log)
#

Error Log:

	"error": {
		"stack": "EdupageError: Edupage server did not redirect login request to proper origin\n    at /home/ivanhrabcak/PythonProjects/edupog-backend/node_modules/edupage-api/src/User.js:221:52\n    at processTicksAndRejections (node:internal/process/task_queues:96:5)",
		"message": "Edupage server did not redirect login request to proper origin",
		"name": "EdupageError"
	},
	"data": {
		"html": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\"><html><HEAD><META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=utf-8\"><title> EduPage </title><style>html, body {margin: 0px;padding: 0px;height: 100%;}body,td,input,select { font-family: Verdana; \tfont-size: 10pt;\tcolor: #1f497d;}th {font-family: Verdana; font-size: 10pt; color: #FFFFFF; background-color: #4B6BAC}tr.sedeth th {\tbackground-color: #333333;}tr.zeleneth th {\tbackground-color: #1c611c;}tr.table_row1 {\tbackground-color: #E9F7FF; }tr.table_row2 {\tbackground-color: #D3E8FC; }tr.table_row1_sede {background-color: #dddddd; }tr.table_row2_sede {background-color: #ededed;}tr.table_row1_sede td {color:#222222}tr.table_row2_sede td {color:#222222}tr.table_row1_zelene {background-color: #e3f7b8; }tr.table_row2_zelene {background-color: #d7efa5;}tr.table_row1_zelene td {color:#164c16}tr.table_row2_zelene td {color:#164c16}td.td_border { border: solid 1px #D3E8FC; }img {\tborder:none;}a {\ttext-decoration: none;\t\tcolor: #1f497d;}a:hover{\ttext-decoration: underline;}a.th{\tcolor: #FFFFFF;}@media print {\thtml, body {\t\tmargin: 0px;\t\tpadding: 0px;\t\theight: 100%;\t}\tbody,td,input,select { font-family: Verdana; \t\tfont-size: 12pt;\t\tcolor: #000000;\t}\tth {\t\tfont-family: Verdana; font-size: 12pt; color: #000000; font-weight:bold;\t}\t\ttr.sedeth th {\t\tbackground-color: #333333;\t}\ttr.zeleneth th {\t\tbackground-color: #1c611c;\t}\ttr.table_row1 { }\ttr.table_row2 { }\ttr.table_row1_sede { }\ttr.table_row2_sede {}\ttr.table_row1_sede td {}\ttr.table_row2_sede td {}\t\ttr.table_row1_zelene {}\ttr.table_row2_zelene {}\ttr.table_row1_zelene td {}\ttr.table_row2_zelene td {}\t\ttable.printBorder td {border: 1px solid #000000;}\ttable.printBorder th {border: 1px solid #000000;}\ttable.printBorder {border-collapse: collapse;border:1px solid #000000;}\t\timg {\t\tborder:none;\t}\ta {\t\ttext-decoration: none;\t\t\t\tcolor: #000000;\t}\t\ta:hover{\t\ttext-decoration: underline;\t}\t\t\ta.th{\t\tcolor: #000000;\t}</style><link rel=\"stylesheet\" type=\"text/css\" href=\"/global/pics/css/jquery-ui-1.10.2.css\" />\t\t\t\t\t\t\t<link rel=\"stylesheet\" type=\"text/css\" href=\"/global/pics/css/edubar.css?v=20140415\" />\t\t\t\t\t\t\t\t\t\t<script type=\"text/javascript\" src=\"/global/pics/js/jquery/jquery-1.9.1.min.js?v=20130325\"></script>\t\t\t\t\t\t\t\t\t\t<script type=\"text/javascript\" src=\"/global/pics/js/jquery/jquery-ui-1.10.2.min.js\"></script>\t\t\t\t\t\t\t\t\t\t<script type=\"text/javascript\" src=\"/langs/pics/js/lang_sk.js\"></script>\t\t\t\t\t<script src=\"/global/pics/js/edubarUtils.js?v=20140415\" type=\"text/javascript\"></script>\t\t\t\t\t</HEAD><body style=\"margin:0px;overflow:visible;\">Stránka sa načítava...<script language=\"javascript\">window.open(\"https://portal.edupage.org/?login&PSID=REDACTED\", \"_top\");</script></body></html>",
		"url": "https://portal.edupage.org/?login&PSID=REDACTED",
		"origin": "portal",
		"ESID": "REDACTED"
	}

I encounter the same problem when using the login_auto function in the develop branch of edupage-api with my credentials - login_auto uses the same login method as you.

from edupage_api import Edupage
edupage = Edupage()
edupage.login_auto(username, password)
"""
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/ivanhrabcak/PythonProjects/edupog-backend/edupog/edupage_api/__init__.py", line 31, in login_auto
    Login(self).login_auto(username, password)
  File "/home/ivanhrabcak/PythonProjects/edupog-backend/edupog/edupage_api/login.py", line 34, in login_auto
    self.__parse_login_data(data)
  File "/home/ivanhrabcak/PythonProjects/edupog-backend/edupog/edupage_api/login.py", line 7, in __parse_login_data
    json_string = data.split("$j(document).ready(function() {")[1] \
IndexError: list index out of range
"""

But when using login (you also have to provide your school's subdomain), everythings runs ok.
image

This issue is related to #6 in eduage-api, #5 and the fix is described here

Cannot read property 'loggedUser' of undefined

I tried logging in but it prints this stacktrace:
TypeError: Cannot read property 'loggedUser' of undefined at new ASC (node_modules\edupage-api\src\ASC.js:31:36) at Edupage.refreshEdupage (node_modules\edupage-api\src\Edupage.js:220:14) at processTicksAndRejections (node:internal/process/task_queues:96:5) at async Edupage.refresh (node_modules\edupage-api\src\Edupage.js:182:3) at async node_modules\edupage-api\src\Edupage.js:169:5

Affected line:
this.loggedUser = data.req_props.loggedUser;

Causes:
data is {}

Failed to init the Grade object warning (from #4)

This is the crash log (#4):

An error has occurred!

This is probably not your fault!
It should not cause the program to crash, but some functionality can be limited.
If this happens often, please consider reporting a bug.
You can disable the warnings by including "--edu-disable-warnings=true" as a CLI argument.

Error thrown:
  EdupageError: Failed to init the Grade object: Cannot find provider
      at Grade.init (C:\Users\dajzr\OneDrive\Počítač\node_modules\edupage-api\src\Grade.js:199:48)
      at new Grade (C:\Users\dajzr\OneDrive\Počítač\node_modules\edupage-api\src\Grade.js:177:41)
      at C:\Users\dajzr\OneDrive\Počítač\node_modules\edupage-api\src\Edupage.js:334:89
      at Array.map (<anonymous>)
      at Edupage._updateInternalValues (C:\Users\dajzr\OneDrive\Počítač\node_modules\edupage-api\src\Edupage.js:334:77)
      at Edupage.refresh (C:\Users\dajzr\OneDrive\Počítač\node_modules\edupage-api\src\Edupage.js:194:8)
      at processTicksAndRejections (node:internal/process/task_queues:96:5)
      at async C:\Users\dajzr\OneDrive\Počítač\node_modules\edupage-api\src\Edupage.js:169:5

Summary:
  Time: Fri Sep 17 2021 15:46:54 GMT+0200 (Central European Summer Time)
  EdupageAPI version: v0.7.9
  Node.js version: v16.9.1
  Error log: C:\Users\dajzr\OneDrive\Počítač\node_modules\edupage-api\logs\warning_2021-09-17T13-46-54Z.json

If you would like to submit an issue, please visit:
  > https://github.com/loumadev/EdupageAPI/issues
  (Please, include this error message + error log)
{
	"error": {
		"stack": "EdupageError: Failed to init the Grade object: Cannot find provider\n    at Grade.init (C:\\Users\\dajzr\\OneDrive\\Počítač\\node_modules\\edupage-api\\src\\Grade.js:199:48)\n    at new Grade (C:\\Users\\dajzr\\OneDrive\\Počítač\\node_modules\\edupage-api\\src\\Grade.js:177:41)\n    at C:\\Users\\dajzr\\OneDrive\\Počítač\\node_modules\\edupage-api\\src\\Edupage.js:334:89\n    at Array.map (<anonymous>)\n    at Edupage._updateInternalValues (C:\\Users\\dajzr\\OneDrive\\Počítač\\node_modules\\edupage-api\\src\\Edupage.js:334:77)\n    at Edupage.refreshTimeline (C:\\Users\\dajzr\\OneDrive\\Počítač\\node_modules\\edupage-api\\src\\Edupage.js:246:20)\n    at processTicksAndRejections (node:internal/process/task_queues:96:5)\n    at async Timeout._onTimeout (C:\\Users\\dajzr\\OneDrive\\Počítač\\edupage jeblina\\index.js:23:9)",
		"message": "Failed to init the Grade object: Cannot find provider",
		"name": "EdupageError"
	},
	"data": {
		"_data": {
			"provider": "agenda",
			"znamkaid": "-2",
			"studentid": "39735",
			"predmetid": "37765",
			"udalostid": "0",
			"mesiac": "V1",
			"data": "o",
			"datum": "0000-00-00 00:00:00",
			"ucitelid": "0",
			"podpisane": null,
			"podpisane_rodic": null,
			"timestamp": "2021-09-14 12:23:44",
			"stav": "o"
		}
	}
}

Documentation?

Is there some kind of documentation so I can know how this API works?

School clubs Periods not found

hey, sorry me again. This is probably error on Edupage's side. Got this error.

#
# An error has occurred!
#
# This is probably not your fault!
# It should not cause the program to crash, but some functionality can be limited.
# If this happens often, please consider reporting a bug.
# You can disable the warnings by including "--edu-disable-warnings=true" as a CLI argument.
#
# Error thrown:
#  ReferenceError: Failed to find period for lesson
#      at Lesson.init (/home/runner/edupejc/node_modules/edupage-api/src/Lesson.js:132:27)
#      at new Lesson (/home/runner/edupejc/node_modules/edupage-api/src/Lesson.js:109:42)
#      at /home/runner/edupejc/node_modules/edupage-api/src/Timetable.js:57:78
#      at Array.map (<anonymous>)
#      at Timetable.init (/home/runner/edupejc/node_modules/edupage-api/src/Timetable.js:57:66)
#      at new Timetable (/home/runner/edupejc/node_modules/edupage-api/src/Timetable.js:47:45)
#      at /home/runner/edupejc/node_modules/edupage-api/src/Edupage.js:467:68
#      at Array.map (<anonymous>)
#      at Edupage.fetchTimetablesForDates (/home/runner/edupejc/node_modules/edupage-api/src/Edupage.js:467:43)
#
# Summary:
#  Time: Mon Dec 13 2021 20:45:49 GMT+0000 (Coordinated Universal Time)
#  EdupageAPI version: v0.7.13
#  Node.js version: v16.7.0
#  Error log: /home/runner/edupejc/node_modules/edupage-api/logs/warning_2021-12-13T20-45-49Z.json
#
# If you would like to submit an issue, please visit:
#  > https://github.com/loumadev/EdupageAPI/issues
#  (Please, include this error message + error log)
#

im ignoring it now im just letting you know. there is an error with school clubs
warning_2021-12-13T20-34-01Z.json (log file)

some things are redacted for sake of my own privacy

have a nice day!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.