Exemple #1
0
    def get_cal(self, course_info):
        chinese_to_numbers = {
            "一": 0,
            "二": 1,
            "三": 2,
            "四": 3,
            "五": 4,
            "六": 5,
            "日": 6
        }

        coursenum_to_time = {
            "1": (timedelta(hours=8, minutes=30), timedelta(hours=9,
                                                            minutes=15)),
            "2": (timedelta(hours=9,
                            minutes=25), timedelta(hours=10, minutes=10)),
            "3": (timedelta(hours=10,
                            minutes=30), timedelta(hours=11, minutes=15)),
            "4": (timedelta(hours=11,
                            minutes=25), timedelta(hours=12, minutes=10)),
            "5": (timedelta(hours=13,
                            minutes=30), timedelta(hours=14, minutes=15)),
            "6": (timedelta(hours=14,
                            minutes=25), timedelta(hours=15, minutes=10)),
            "7": (timedelta(hours=15,
                            minutes=20), timedelta(hours=16, minutes=5)),
            "8": (timedelta(hours=16,
                            minutes=25), timedelta(hours=17, minutes=10)),
            "9": (timedelta(hours=17,
                            minutes=20), timedelta(hours=18, minutes=5)),
            "10": (timedelta(hours=19,
                             minutes=0), timedelta(hours=19, minutes=45)),
            "11": (timedelta(hours=19,
                             minutes=55), timedelta(hours=20, minutes=40)),
            "12": (timedelta(hours=20,
                             minutes=50), timedelta(hours=21, minutes=35)),
            "13": (timedelta(hours=21,
                             minutes=45), timedelta(hours=22, minutes=30)),
        }

        term_start_time = datetime(
            year=int(config["term_start_time"]["year"]),
            month=int(config["term_start_time"]["month"]),
            day=int(config["term_start_time"]["day"]),
            tzinfo=pytz.timezone("Asia/Shanghai"),
        )

        events = []

        for course in course_info:
            week_nums = []
            week_segs = course["weeks"].split(",")
            for seg in week_segs:
                delimiter = [int(i) for i in seg.split("-")]
                start = delimiter[0]
                end = delimiter[1] if len(delimiter) == 2 else start
                for i in range(start, end + 1):
                    week_nums.append(i)
            if not course["time"].split("[")[0].isdigit():
                day = chinese_to_numbers[course["time"].split("[")[0]]
            else:
                day = int(course["time"].split("[")[0])
            seg = course["time"].split("[")[1].split("-")
            if len(seg) == 2:
                inweek_delta_start = timedelta(
                    days=day) + coursenum_to_time[seg[0]][0]
                inweek_delta_end = timedelta(
                    days=day) + coursenum_to_time[seg[1]][1]
                for week_num in week_nums:
                    event_start_datetime = (
                        term_start_time + (week_num - 1) * timedelta(days=7) +
                        inweek_delta_start)
                    event_end_datetime = (term_start_time +
                                          (week_num - 1) * timedelta(days=7) +
                                          inweek_delta_end)
                    event = Event()
                    event.add(
                        "summary",
                        "[{}]{}".format(course["teacher"],
                                        course["course_name"]),
                    )
                    event.add("location", course["location"])
                    self._add_datetime(event, "dtstart", event_start_datetime)
                    self._add_datetime(event, "dtend", event_end_datetime)
                    # Fix #2: 添加 dtstamp 与 uid 属性
                    event.add("dtstamp", datetime.utcnow())
                    namespace = uuid.UUID(
                        bytes=int(event_start_datetime.timestamp()).to_bytes(
                            length=8, byteorder="big") +
                        int(event_end_datetime.timestamp()).to_bytes(
                            length=8, byteorder="big"))
                    event.add(
                        "uid",
                        uuid.uuid3(
                            namespace,
                            f"{course['course_name']}-{course['teacher']}"),
                    )

                    events.append(event)

        cal = Calendar()
        cal.add(
            "prodid",
            f'-//重庆大学课表//{config["user_info"]["username"]}//Powered By cqu-kb//',
        )
        cal.add("version", "2.0")
        cal.add_component(
            Timezone.from_ical("BEGIN:VTIMEZONE\n"
                               "TZID:Asia/Shanghai\n"
                               "X-LIC-LOCATION:Asia/Shanghai\n"
                               "BEGIN:STANDARD\n"
                               "TZNAME:CST\n"
                               "DTSTART:16010101T000000\n"
                               "TZOFFSETFROM:+0800\n"
                               "TZOFFSETTO:+0800\n"
                               "END:STANDARD\n"
                               "END:VTIMEZONE\n"))
        for event in events:
            cal.add_component(event)
        return cal
Exemple #2
0
import configparser
import datetime
import uuid
import json
from io import BytesIO
from openpyxl import load_workbook
from icalendar import Calendar, Event, Timezone, vDDDTypes

__all__ = ('mkical', 'load_from_xlsx', 'loadIO_from_xlsx', 'load_from_json',
           'loadIO_from_json')

VTIMEZONE = Timezone.from_ical("""BEGIN:VTIMEZONE
TZID:Asia/Shanghai
X-LIC-LOCATION:Asia/Shanghai
BEGIN:STANDARD
TZNAME:CST
TZOFFSETFROM:+0800
TZOFFSETTO:+0800
DTSTART:19700101T000000
END:STANDARD
END:VTIMEZONE""")
TIMEZONE = VTIMEZONE.to_tz()
time_dict = {
    1: [(8, 30), (9, 15)],
    2: [(9, 25), (10, 10)],
    3: [(10, 30), (11, 15)],
    4: [(11, 25), (12, 10)],
    5: [(13, 30), (14, 15)],
    6: [(14, 25), (15, 10)],
    7: [(15, 20), (16, 0o5)],
    8: [(16, 25), (17, 10)],
    9: [(17, 20), (18, 0o5)],
Exemple #3
0
def get_cal(page_content):
    soup = BS(page_content, features="html.parser")
    tables = soup.find_all(class_="page_table")

    courses_info = []
    for i in range(len(tables) // 2):
        table = tables[i * 2 + 1]
        rows = table.find('tbody').find_all('tr')
        cols_num = len(rows[0].find_all('td'))
        for row in rows:
            course_info = {}
            cols = row.find_all('td')
            course_info.update({
                'course_name':
                cols[1].text.split(']')[-1] +
                ("" if cols_num == 13 else "(实验)")
            })
            course_info.update(
                {'teacher': cols[-4 if cols_num == 13 else -5].text})
            course_info.update({'weeks': cols[-3].text})
            course_info.update({'time': cols[-2].text.replace('节]', '')})
            course_info.update({'location': cols[-1].text})
            courses_info.append(course_info)
    for i in range(len(courses_info)):
        if courses_info[i]['course_name'] == '' or courses_info[i][
                'course_name'] == '(实验)':
            courses_info[i]['course_name'] = courses_info[i - 1]['course_name']

    chinese_to_numbers = {
        '一': 0,
        '二': 1,
        '三': 2,
        '四': 3,
        '五': 4,
        '六': 5,
        '日': 6
    }

    coursenum_to_time = {
        '1': (timedelta(hours=8, minutes=30), timedelta(hours=9, minutes=15)),
        '2': (timedelta(hours=9, minutes=25), timedelta(hours=10, minutes=10)),
        '3': (timedelta(hours=10, minutes=30), timedelta(hours=11,
                                                         minutes=15)),
        '4': (timedelta(hours=11, minutes=25), timedelta(hours=12,
                                                         minutes=10)),
        '5': (timedelta(hours=13, minutes=30), timedelta(hours=14,
                                                         minutes=15)),
        '6': (timedelta(hours=14, minutes=25), timedelta(hours=15,
                                                         minutes=10)),
        '7': (timedelta(hours=15, minutes=20), timedelta(hours=16, minutes=5)),
        '8': (timedelta(hours=16, minutes=25), timedelta(hours=17,
                                                         minutes=10)),
        '9': (timedelta(hours=17, minutes=20), timedelta(hours=18, minutes=5)),
        '10': (timedelta(hours=19, minutes=0), timedelta(hours=19,
                                                         minutes=45)),
        '11': (timedelta(hours=19, minutes=55), timedelta(hours=20,
                                                          minutes=40)),
        '12': (timedelta(hours=20, minutes=50), timedelta(hours=21,
                                                          minutes=35)),
        '13': (timedelta(hours=21, minutes=45), timedelta(hours=22,
                                                          minutes=30)),
    }

    term_start_time = datetime(year=int(config["term_start_time"]["year"]),
                               month=int(config["term_start_time"]["month"]),
                               day=int(config["term_start_time"]["day"]),
                               tzinfo=pytz.timezone('Asia/Shanghai'))

    events = []

    for course in courses_info:
        week_nums = []
        week_segs = course['weeks'].split(',')
        for seg in week_segs:
            delimiter = [int(i) for i in seg.split('-')]
            start = delimiter[0]
            end = delimiter[1] if len(delimiter) == 2 else start
            for i in range(start, end + 1):
                week_nums.append(i)
        day = chinese_to_numbers[course['time'].split('[')[0]]
        seg = course['time'].split('[')[1].split('-')
        if len(seg) == 2:
            inweek_delta_start = timedelta(
                days=day) + coursenum_to_time[seg[0]][0]
            inweek_delta_end = timedelta(
                days=day) + coursenum_to_time[seg[1]][1]
            for week_num in week_nums:
                event_start_datetime = term_start_time + (
                    week_num - 1) * timedelta(days=7) + inweek_delta_start
                event_end_datetime = term_start_time + (
                    week_num - 1) * timedelta(days=7) + inweek_delta_end
                event = Event()
                event.add(
                    'summary', '[{}]{}'.format(course['teacher'],
                                               course['course_name']))
                event.add('location', course['location'])
                event.add('dtstart', event_start_datetime)
                event.add('dtend', event_end_datetime)
                # Fix #2: 添加 dtstamp 与 uid 属性
                event.add('dtstamp', datetime.utcnow())
                namespace = uuid.UUID(
                    bytes=int(event_start_datetime.timestamp()).to_bytes(
                        length=8, byteorder='big') +
                    int(event_end_datetime.timestamp()).to_bytes(
                        length=8, byteorder='big'))
                event.add(
                    'uid',
                    uuid.uuid3(namespace,
                               f"{course['course_name']}-{course['teacher']}"))

                events.append(event)

    cal = Calendar()
    cal.add(
        'prodid',
        f'-//重庆大学课表//{config["user_info"]["username"]}//Powered By cqu-kb//')
    cal.add('version', '2.0')
    cal.add_component(
        Timezone.from_ical("BEGIN:VTIMEZONE\n"
                           "TZID:Asia/Shanghai\n"
                           "X-LIC-LOCATION:Asia/Shanghai\n"
                           "BEGIN:STANDARD\n"
                           "TZNAME:CST\n"
                           "DTSTART:16010101T000000\n"
                           "TZOFFSETFROM:+0800\n"
                           "TZOFFSETTO:+0800\n"
                           "END:STANDARD\n"
                           "END:VTIMEZONE\n"))
    for event in events:
        cal.add_component(event)
    return cal