parser#

Самостоятельный парсер школьного расписания.

Содержит компоненты, свзяанные с получением расписания. Такие как получение расписание, его кеширование, отслеживание изменений, сборка индекс и поиск по расписанию.

Содержит:

  • Функция для сравнения двух расписаний.

  • Функция получения индекса.

  • Фнкцмя получения расписания.

  • Класс Schedule для работы с расписанием и его сохраненим.

Функции для работы с расписанием#

Некоторые отдельные функции, которые используются при работе с расписанием и могут быть использованы отдельно от экземпляра класса Scheule.

sp.parser.get_sc_updates(a: dict[str, list], b: dict[str, list]) list[dict[str, list]]#

Делает полное сравнение двух расписаний.

Делает полное построчное сравнение старого и нового расписания. Возвращает все найденные изменения в формате.

[
    // дни ...
    {
        // классы ...
        "9в" [
            // уроки ...
            null, // Ничего не изменилось
            ["старый:12", "новый:132"] // Предмет изменился
        ]
    }
]
Параметры:
  • a (dict[str, list]) – Исходное расписание для сравнения.

  • b (dict[str, list]) – Другое расписание для сравнения с исходным.

Результат:

Результаты поиска изменения в расписании.

Тип результата:

list[dict[str, list]]

sp.parser.get_index(sp_lessons: dict[str, list[str]], lessons_mode: bool | None = True) dict[str, list[dict]]#

Преобразует словарь расписания уроков в индекс.

В данном случае индексом называется словарь, где ключом вместо класса является название урока или кабинета.

Они так же часто используются, как и само расписание. Например при подсчёте количества элементов или при поиске в расписании определённого урока или кабинета.

Описание индексов:

  • Расписание: [Класс][День][Уроки]

  • l_mode True: [Урок][День][Кабинет][Класс][Номер урока]

  • l_mode False: [Кабинет][День][Урок][Класс][Номер урока]

Параметры:
  • sp_lessons (dict[str, list[str]]) – Словарь расписания уроков.

  • lessons_mode (Optional[bool]) – Режим получени индекса уроков. По умолчанию да.

Результат:

Индекс уроков или кабинетов.

Тип результата:

dict[str, list]

sp.parser.parse_lessons(csv_file: str) dict[str, list[list[str]]]#

Пересобирает CSV файл в словарь расписания.

Расписание в CSV файле представленно подобным образом.

+--+-------+---------+
|  | класс |         | <- Шапка с классами в расписание
+--+-------+---------+
| 1| урок  | кабинет | <- Первый урок понедельника.
| n| ...   | ...     |
+--+-------+---------+
| 1| урок  | кабинет | <- Первый урок вторника.
| n| ...   | ...     |
+--+-------+---------+

Задача этой функции преобразовать таблицу выше в словарь расписания уроков формата:

{
    // Классы
    "класс" {
        // Дни
        [
            // Уроки в днях
            "урок:кабинет"
        ]
    }
}
Параметры:

csv_file (bytes) – Данные CSV файла расписания.

Результат:

Словарь расписания уроков.

Тип результата:

dict[str, list[str]]

Класс расписания#

class sp.parser.ScheduleFile(content: bytes, hash: str)#

Описывает скачанный из сети файл расписания.

Зачастую это CSV файл расписания, представленный в бинанрном виде. Данный класс используется внутри методов обновления и загрузки расписания, для лучшей структуризации.

Параметры:
  • content (bytes) – Содержимое файла расписания.

  • hash (str) – Посчитанный хеш расписания.

Используется для прямой работы с самим расписанием уроков. Предоставляет так называемые «сырые» результаты. Которые вы после можете самостоятельно обработать.

Подсказка

Генератор сообщений.

Если же вас интересует готовый результат, обратитесь к классу представления или так называемому генератору сообщений sp.messages.SPMessages. В отличие от класса расписания, класс представления возвращает уже готовые текстовые сообщения, которые вы можете испльзовать например в sp.platform.Platform.

class sp.parser.Schedule(cl: str | None = None, sc_path: Path | str = PosixPath('sp_data/sc.json'), updates_path: Path | str = PosixPath('sp_data/updates.json'), index_path: Path | str = PosixPath('sp_data/index.json'))#

Предоставляет доступ к расписанию уроков.

В первую очередь занимается получение расписания из гугл таблиц. Отслеживает изменения в расписании и записывает их в файл. Вы можете получить расписание для конкретного класса, произвести полный поиск по урокам или кабинетам, использую фильтры, получить список изменений в расписании, также с возможностью отфильтровать результаты поиска. Тажке предосталвяет доступ к индексам расписания.

Класс по умолчанию используется как спокосб быстрого получения расписания для определённого класса. Однако в последствии класс по умолчанию будет удалён из класса. На его замену придут намерения пользователя по умолчнаию, которые будут передаваться извне.

Параметры:
  • cl (Optional[str]) – Ваш класс по умолчанию.

  • sc_path (Optional[Union[Path, str]]) – Ваш путь к файлу расписания.

  • updates_path (Optional[Union[Path, str]]) – Ваш путь к файлу списка изменений расписания.

  • index_path (Optional[Union[Path, str]]) – Ваш путь для сохранения индексов расписания.

schedule: dict[str, int | dict | str]#

Полное расписание, включая метаданные, прим. время полчения

lessons: dict[str, list[str]]#

Расписание уроков, он же индекс классов (часто используется)

Совет

Более подробно прочитать про значение schedule можно в методе get.

Более побробно почитать про значение lessons можно в функции parse_lessons.

Аттрибуты расписания#

property l_index: dict[str, list[dict]]#

Индекс уроков.

Загружает индекс урокво из файла. Индекс урока предоставляет изменённый словарь расписания, где вместо ключа используется название урока, а не класс.

Индексы удобно использовать при поиске данныех из разписания. К примеру если быстро нужно найти урок и посмотреть где, когда и для кого он проводится.

Пример структуры индекса:

{
    "матем": [
        { // Понедельник ...
            "204" { // Каибнет
                "8в" [ // класс
                    3 // Номер урока
                ]
            }
        },
        {}, // Вторник ...
        {}, // Среда ...
        {}, // ...
        {},
        {},
    ]
}
Результат:

Полный индекс уроков.

Тип результата:

dict[str, list[dict]]

property c_index: dict[str, list[dict]]#

Индекс кабинетов.

Загружает индекс кабинетов из файла. Индекс кабинетов предоставляет изменённый словарь расписания, где вместо ключа используется название кабинета, а не класс.

Удобно использовать для получения информации о кабинете. Какой урок, когда, для кого проходит в том или ином кабинете. Используется в функции поиска информации по кабинетам.

Пример структуры индекса:

{
    "204": [ // Каибинет
        { // Понедельник ...
            "матем" { // Какой урок проходит
                "8в" [ // класс для которого проходит
                    3 // Номер урока в расписании
                ]
            }
        },
        {}, // Вторник ...
        {}, // Среда ...
        {}, // ...
        {},
        {},
    ]
}
Результат:

Полный индекс уроков.

Тип результата:

dict[str, list[dict]]

property updates: list[dict[str, int | list[dict]]] | None#

Список изменений в расписании.

Загружает полный список изменений из файла. Список изменений предсталвляет собой перечень последних 30-ти зафиксированных изменений. Включая время начала и конца временного промежутка, когда эти изменения были зафиксированы.

Есди вы хотите получить не все обновления или хотите отфильтровать результаты намерения при помощи Намерения, то воспользуйтесь методом get_updates.

Пример одной из записей:

{
    "start_time": 1703479133.752195,
    "end_time": 1703486843.468643,
    "updates": [ // Дни недели
        {
            "5а": [ // Классы ...
                [ // Изменение в расписании
                    "тфк:110", // Старый урок:класс
                    "None:110" // Новый урок:класс
                ],
                null, // Если уроки не изменились
                null,
                null,
                null,
                null,
                null,
                null
            ],
        },
        {}, // Вторик ...
        {}, // Среда ...
        {}, // ...
        {},
        {}
    ]
}
Результат:

Полный список изменений в расписании.

Тип результата:

list[list[dict[str, Union[int, list[dict]]]]]

Методы для получения расписания#

get() dict[str, int | dict | str]#

Получает расписание уроков.

Если расписание уроков пустое или таймёр истёк, запускает процесс обновления.

Процесс обновления:

  • Загрузка файла расписания.
    • Если не удалосью, передвигаем метку обновления.

  • Сравниваем хеши расписаний.

  • Если различаются:
    • Парсим расписание из файла.

    • Обновляем индексы расписания.

    • Сравниваем и записывает изменения в расписании.

  • Сдвигаем временнцую метку следующего обновления.

Расписание уроков представляет собой словарь:

  • hash: Хеш сумма рсписания уроков.

  • last_parse: Unixtime посленей проверки расписания.

  • next_parse: Ubixtume следующей проверки расписания.

  • lessons: Сам словарь расписаний уроков по классам.

Результат:

Словарь данных расписания уроков.

Тип результата:

dict[str, Union[int, dict, str]]

Методы для работы с расписанием#

get_class(cl: str) str#

Получает класс из расписания.

Устарело, начиная с версии 5.7: Этот метод будет вскоре удалён

Лучшще используйте вместо этого:

if cl in sp.lessons: ...
get_lessons(cl: str | None = None) list[list[str]]#

Получает полное расписание уроков для указанного класса.

Устарело, начиная с версии 5.8: Данный метод может быть переработан

  • Поскольку он завист от внутреннего аттрибута класса.

  • Не поддерживает намерения для фильтрации результата.

Возарвщает полное расписнаие уроков для укзаанного класса. Если не укзатаь класс, берёт класс из аттрибута расписания. Если такого класса в расписании нету, то верён пустое расписание на неделю. Обратите внимание, что даже при неправильном классе результат вернётся корректный. Внимательно следите в каком регистре вы передаёте класс. Или это может сыграть с вами злую шутку.

Параметры:

cl (Optional[str]) – Для какого класса получить расписание.

Результат:

расписание уроков на неделю для класса.

Тип результата:

list[list[str]]

get_updates(intent: Intent, offset: int | None = None) list[list[dict[str, int | list[dict]]]]#

Получает список изменений расписания.

Это более продвинутый метод полчения записей об изменениях в расписании. Проходится по всему списку изменений, возвращая необходимые вам результаты. Для уточнения результатов вы можеет использовать Намерения. К примеру чтобы получить все изменения для одного класса. Или посмотреть как изменялост расписание в определённый день.

Помимо этого вы можете передвать временную метку обновления, начиная с коророй будет производиться поиск изменений. Это используется при отправке именно новых обновлений в расписании пользователей.

Если же ваша цель - просто получить список всех изменений в расписании, то воскользуйтесь аттрибутом updates.

Параметры:
  • intent (Intent) – Намерения для уточнения поиска изменений.

  • offset (int) – С какой временной метки обновления начать.

Результат:

Список обновлений расписания.

Тип результата:

list[list[dict[str, Union[int, list[dict]]]]]

search(target: str, intent: Intent, cabinets: bool | None = False) list[list[list[str]]]#

Производит поиск в расписании.

Для поиска цели в индексах расписания. Сама же цель - название кабинета/урока. Для уточнения результатов поиска используются намерения. Например чтобы получить результаты на опрелдённый день. Ну или к примеру в определённых кабинетах, если речь об уроке.

Поиск немного изменяется в зависимости от режима.

cabinets

obj

another

false

lesson

cabinet

true

cabinet

lesson

Результат поиска возаращем подобный расписанию формат.

[ // Дни
    [ // Уроки (по умолчанию 8)
        [ // Найдённые результаты
            "{cl}",
            "{obj}",
            "{cl}:{obj}",
            "..."
        ],
        [], // Если список пустой - ничего не найдено
        [],
        [],
        [],
        [],
        [],
        []
    ],
    [], // Вторник ...
    [], // Среда ...
    [], // ...
    [],
    []
]

Как вы могли заметить, результат поиска - строка. Формат строки зависит от некоторых условий:

  • {cl} - Если в намерении 1 кабинет и указаны уроки.

  • {obj} - Если в намерении 1 класс (опускаем описание класса).

  • {cl}:{obj} - Для всех прочих случаев.

Параметры:
  • target (str) – Цель для поиска, урок или кабинет.

  • intent (Intent) – Намерения для уточнения результатов поиска.

  • cabinets (bool) – Что ищём, урок или кабинет. Обычно урок.

Результат:

Результаты поиска в расписании

Тип результата:

list[list[list[str]]]

Методы для работы с намерениями#

construct_intent(cl: Iterable[str] | str = (), days: Iterable[int] | int = (), lessons: Iterable[str] | str = (), cabinets: Iterable[str] | str = ()) Intent#

Создаёт новое намерение для текущего расписания.

Является сокращением для Intent.construct(sc, …)

sc = Schedule()

# Можно использовать любой вариант
i = Intent.construct(sc, ...)
i = sc.construct_intent(...)
Параметры:
  • cl (Union[Iterable[str], str]) – Какие классы расписания добавить в намерение

  • days (Union[Iterable[int], int]) – Какие дни добавить в намерение (0-5)

  • lessons (Union[Iterable[str], str]) – Какие уроки добавить в намерение (из l_index).

  • cabinets (Union[Iterable[str], str]) – Какие кабинеты добавить в намерение (c_index).

Результат:

Проверенное намерение из переданных аргументов

Тип результата:

Intent

parse_intent(args: Iterable[str]) Intent#

Парсит намерение из строковых аргументов.

Парсит для текущего расписания. Является сокращением для Intent.parse(sc, args)

sc = Schedule()
args = "матем 204".split()

# Можно использовать любой вариант
i = Intent.parse(sc, args)
i = sc.parse_intent(args)
Параметры:

args (Iterable[str]) – Арнументы парсинга намерений.

Результат:

Готовое намерение из строковых аргументов.

Тип результата:

Intent