File size: 3,554 Bytes
5161c7a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import re
import aiohttp
import pandas as pd
from io import StringIO

from constants.constants import (
    vtop_process_attendance_url,
    vtop_process_attendance_detail_url,
)
from utils.payloads import (
    get_attendance_payload,
    get_attendance_detail_payload,
)


async def _get_attendance_page(

    sess: aiohttp.ClientSession, username: str, semID: str, csrf: str

):
    async with sess.post(
        vtop_process_attendance_url, data=get_attendance_payload(username, semID, csrf)
    ) as req:
        return await req.text()


async def _get_attendance_detail_page(

    sess: aiohttp.ClientSession, csrf, semID, username, courseID, courseType

):
    async with sess.post(
        vtop_process_attendance_detail_url,
        data=get_attendance_detail_payload(csrf, semID, username, courseID, courseType),
    ) as req:
        return await req.text()


def _get_class_type(classType: str):
    if classType == "Embedded Theory":
        return "ETH"
    elif classType == "Embedded Lab":
        return "ELA"
    elif classType == "Theory Only":
        return "TH"
    elif classType == "Lab Only":
        return "LO"


def _parse_attendance_detail(attendance_detail_page: str):
    attendance_detail_table = pd.read_html(StringIO(attendance_detail_page))
    if len(attendance_detail_table) < 2:
        return {}
    attendance_detail_table = attendance_detail_table[1]
    attendance_detail = {}

    for index, row in attendance_detail_table.iterrows():
        attendance_detail[str(row["Sl.No."])] = {
            "status": row["Status"],
            "date": row["Date"],
            "time": row["Day / Time"],
        }

    return attendance_detail


async def _parse_attendance(

    attendance_page: str,

    sess: aiohttp.ClientSession,

    username: str,

    csrf: str,

    semID: str,

):
    table_df = pd.read_html(StringIO(attendance_page))[0]

    attendance = []

    for index, row in table_df.iterrows():
        code = row["Course Detail"].split("-")[0].strip()
        slot = row["Class Detail"].split("-")[1].strip()
        if "Total Number Of Credits" in code:
            if "0" in code:
                raise Exception
            continue

        attendance.append(
            {
                "classID": row["Class Detail"].split("-")[0].strip(),
                "name": row["Course Detail"].split("-")[1].strip(),
                "courseType": row["Course Detail"].split("-")[2].strip(),
                "slot": slot,
                "totalClasses": str(row["Total Classes"]),
                "attendedClasses": str(row["Attended Classes"]),
                "attendancePercentage": row["Attendance Percentage"][:-1],
                "attendanceDetail": _parse_attendance_detail(
                    await _get_attendance_detail_page(
                        sess,
                        csrf,
                        semID,
                        username,
                        re.search(f";(\w*_{code}_\d*)&", attendance_page).group(1),
                        _get_class_type(row["Course Detail"].split("-")[2].strip()),
                    )
                ),
            }
        )

    return attendance


async def get_attendance_data(

    sess: aiohttp.ClientSession, username: str, semID: str, csrf: str

):
    return await _parse_attendance(
        await _get_attendance_page(sess, username, semID, csrf),
        sess,
        username,
        csrf,
        semID,
    )