Автор скрипта @OlegROA
Дисклеймер публикации
Не забывайте читать комментарии внутри скрипта!
Сам скрипт: Браузерный скрипт пропущенных ДЗ с журналами
Список уроков без ДЗ в указанном интервале дат
Список уроков без ДЗ в указанном интервале дат для указанных учителей или для всех учителей.
В данный список будут включены уроки, на которые не задано ДЗ явно или не поставлена метка «Без ДЗ».
1. ОБЯЗАТЕЛЬНО заходите в старую админку, на любую страницу.
2. Открываете в браузере панель инструментов разработчика.
3. Переходите на закладку Консоль.
4. Открываете файл со скриптом и копируете все его содержимое в окно консоли (в ФайрФоксе возможно придется подтвердить вставку кода ручным вводом указанной фразы).
5. Проверяете начальные параметры — код учебного года, интервал дат, список учителей.
6. Жмете Enter. В зависимости от браузера или будет предложено сохранить csv-файл или он автоматически будет сохранен в папку «Загрузки».
Наименование файла — «Без ДЗ (ГГГГ-ММ-ДД — ГГГГ-ММ-ДД).csv».
Сортировка по ФИО учителя, дате, номеру урока.
Кодировка текста в файле «Windows-1251», так что его сразу можно открывать в Excel и сортировать/фильтровать по нужным критериям.
Как просто узнать ИД нужных учителей:
1. Заходите в справочник кадров и открываете карточку нужного учителя.
2. Кликаете мышкой в адресную строку браузера и видите число в конце адреса — это и есть ИД учителя.
var year_id = 13; // Идентификатор учебного года (2025-2026)
// Основные параметры
// Список (через запятую) ИД проверяемых учителей.
// Если список пустой - проверка по всем учителям.
var th_ids = [];
var date_start = "2025-09-16"; // Начало интервала дат (обязательно с ведущим нулём!)
var date_end = "2025-09-16"; // Конец интервала дат (обязательно с ведущим нулём!)
// Если date_start не указана (date_start = ""), то будет принята текущая дата
// а для date_end будет принята завтрашняя дата.
// Если date_start указана, но не указана date_end (date_end = ""), то для date_end
// будет принята дата date_start + 1 день.
// Глобальные переменные
var no_dz = [];
(async () => {
// Функция преобразования текста из кодировки UTF-8
// в кодовый массив Windows-1251
async function toWin(s){
let code = [];
for(let i = 0; i < s.length; i++){
let c = s.charCodeAt(i);
if (c == 0x401){
code.push(0xA8);
} else if (c == 0x451){
code.push(0xB8);
} else if (c < 0x410){
code.push(c);
} else {
code.push(c - 848);
};
};
return (new Uint8Array(code));
};
// Функция чтения одной страницы данных в формате JSON
async function fetchOne(url) {
const res = await fetch(url);
const json = await res.json();
return(json);
};
// Функция чтения всех страниц данных в формате JSON
async function fetchAll(url, pagesProp="x-pagination-total-pages") {
if (url.indexOf("?") == -1){
url += "?per_page=1000";
} else {
url += "&per_page=1000";
}
let recs = [];
let page = 0, pages = 0;
while (true){
page += 1;
const res = await fetch(url +"&page="+ page);
const hdr = await res.headers;
recs.push(...(await res.json()));
pages = hdr.get(pagesProp);
if (!pages || (page >= pages)){break};
};
return(recs);
};
if (!th_ids || !th_ids.length){
// Если список учителей пустой - формируем словарь всех учителей
let th = await fetchAll("core/api/teacher_profiles");
for(let i = 0; i < th.length; i++){
th_ids.push(th[i].id);
};
};
if (!date_start){
date_start = (new Date()).toISOString().slice(0, 10);
date_end = "";
};
if (!date_end){
date_end = (new Date((new Date(date_start))
.getTime() + 24*60*60*1000)).toISOString().slice(0, 10);
};
// Основной цикл - обход учителей
let sch_dates = "&from="+ date_start +"&to="+ date_end;
let hw_dates = "&begin_date="+ date_start.split("-").reverse().join(".") +
"&end_date="+ date_end.split("-").reverse().join(".");
for (let th of th_ids){
// Словарь меток "Без ДЗ" учителя
let dz_mark = new Map();
// Читаем расписание учителя
let sch = await fetchAll("jersey/api/schedule_items?academic_year_id="+ year_id +
"&teacher_id="+ th + sch_dates +
"&with_lesson_info=true&with_group_class_subject_info=true");
if (!sch || !sch.length){continue};
console.log(sch[0].teacher_name || "???");
for (let ls of sch){
if ((ls.homeworks_to_verify || []).length){continue};
// Явного ДЗ на данный урок нет, проверяем наличие метки "Без ДЗ"
marks = dz_mark.get(ls.group_id)
if (marks === undefined){
// Для данной группы еще не запрашивали метки "Без ДЗ"
marks = [];
let hw_abs = await fetchAll("core/api/homework_absences?group_id="+ ls.group_id + hw_dates);
for (let mark of hw_abs){
marks.push(mark.date.split(".").reverse().map(Number).join("-"));
};
dz_mark.set(ls.group_id, marks);
};
if (!marks.includes(ls.date.join("-"))){
no_dz.push((ls.teacher_name || "???") +";"+
ls.date[0] +"-"+ ("0"+ls.date[1]).substr(-2) +"-"+ ("0"+ls.date[2]).substr(-2) +";"+
ls.study_ordinal +";"+ ls.class_unit_name +";"+ ls.subject_name +";"+ ls.group_name + ";" + "https://school.mos.ru/teacher/study-process/journal/grade/" + ls.group_id +"?scheduleItemId="+ ls.id);
};
};
};
if (!no_dz.length){
console.log("Нет уроков без ДЗ!");
} else {
no_dz.sort();
let csv = "ФИО учителя;Дата урока;Урок;Класс;Предмет;Группа;Журнал\n"+ no_dz.join("\n");
// Создание файла формата CSV в кодировке Windows-1251
// и сохранение его браузером
const link = document.createElement("a");
const file = new Blob([await toWin(csv)], {type:'text/csv'});
link.href = URL.createObjectURL(file);
link.download = "Без ДЗ ("+ date_start +" - "+ date_end +").csv";
link.click();
URL.revokeObjectURL(link.href);
console.log("Всего уроков без ДЗ: "+ no_dz.length);
};
})()
