Kaynağa Gözat

chore: 撤下武汉商学院 WBU_01 入口(功能已被 WBU_02/WBU_03 覆盖) (#747)

Foraes 15 saat önce
ebeveyn
işleme
53bac750f5
2 değiştirilmiş dosya ile 0 ekleme ve 362 silme
  1. 0 8
      resources/WBU/adapters.yaml
  2. 0 354
      resources/WBU/wbu_01.js

+ 0 - 8
resources/WBU/adapters.yaml

@@ -1,12 +1,4 @@
 adapters:
-  - adapter_id: "WBU_01"
-    adapter_name: "武汉商学院-超星教务系统"
-    category: "BACHELOR_AND_ASSOCIATE"
-    asset_js_path: "wbu_01.js"
-    import_url: "https://webvpn.wbu.edu.cn/"   # 这里放真实登录页
-    maintainer: "Foraes"
-    description: "武汉商学院教务系统课表导入适配"
-
   - adapter_id: "WBU_02"
     adapter_name: "武汉商学院-校园网访问"
     category: "BACHELOR_AND_ASSOCIATE"

+ 0 - 354
resources/WBU/wbu_01.js

@@ -1,354 +0,0 @@
-// 适配目标:武汉商学院-超星综合教学管理系统
-
-(function () {
-    function toast(message) {
-        if (window.shiguangBridge && typeof window.shiguangBridge.showToast === "function") {
-            window.shiguangBridge.showToast(message);
-        }
-    }
-
-    function sleep(ms) {
-        return new Promise((resolve) => setTimeout(resolve, ms));
-    }
-
-    async function getTargetDocument() {
-        if (location.href.includes("queryKbForXsd")) {
-            return document;
-        }
-
-        const iframe = document.querySelector("iframe[src*='queryKbForXsd']");
-        if (!iframe) return null;
-
-        for (let i = 0; i < 20; i += 1) {
-            try {
-                const doc = iframe.contentDocument || (iframe.contentWindow && iframe.contentWindow.document);
-                if (doc && doc.readyState && doc.readyState !== "loading") {
-                    return doc;
-                }
-            } catch (e) {
-                // ignore
-            }
-            await sleep(500);
-        }
-        return null;
-    }
-
-    async function waitForScheduleData(doc, timeoutMs = 15000) {
-        const start = Date.now();
-        while (Date.now() - start < timeoutMs) {
-            const cells = Array.from(doc.querySelectorAll("td.cell, td[id^='Cell']"));
-            const filled = cells.filter((cell) => {
-                const text = (cell.innerText || cell.textContent || "").trim();
-                return text.length > 0 && /周/.test(text);
-            });
-            if (filled.length > 0) {
-                return true;
-            }
-            await sleep(500);
-        }
-        return false;
-    }
-
-    function uniqueSortedNumbers(nums) {
-        const set = new Set(nums.filter((n) => Number.isFinite(n)));
-        return Array.from(set).sort((a, b) => a - b);
-    }
-
-    function parseWeekText(weekText) {
-        if (!weekText) return [];
-        let text = String(weekText).trim();
-        if (!text) return [];
-
-        let oddOnly = false;
-        let evenOnly = false;
-        if (text.includes("单")) oddOnly = true;
-        if (text.includes("双")) evenOnly = true;
-
-        text = text.replace(/周/g, "");
-        text = text.replace(/\s+/g, "");
-        text = text.replace(/\(.*?\)/g, "");
-        text = text.replace(/(.*?)/g, "");
-
-        const weeks = [];
-        const segments = text.split(",").map((s) => s.trim()).filter(Boolean);
-        segments.forEach((seg) => {
-            if (!seg) return;
-            const rangeMatch = seg.match(/^(\d+)-(\d+)$/);
-            if (rangeMatch) {
-                const start = parseInt(rangeMatch[1], 10);
-                const end = parseInt(rangeMatch[2], 10);
-                if (!Number.isFinite(start) || !Number.isFinite(end)) return;
-                for (let w = start; w <= end; w += 1) {
-                    weeks.push(w);
-                }
-                return;
-            }
-            const single = parseInt(seg, 10);
-            if (Number.isFinite(single)) weeks.push(single);
-        });
-
-        let filtered = weeks;
-        if (oddOnly && !evenOnly) {
-            filtered = weeks.filter((w) => w % 2 === 1);
-        } else if (evenOnly && !oddOnly) {
-            filtered = weeks.filter((w) => w % 2 === 0);
-        }
-
-        return uniqueSortedNumbers(filtered);
-    }
-
-    function splitCourseBlocks(cellText) {
-        const text = cellText.replace(/\r/g, "").trim();
-        if (!text) return [];
-        return text
-            .split(/\n{2,}/)
-            .map((block) => block.trim())
-            .filter(Boolean);
-    }
-
-    function extractWeeksTextFromLine(line) {
-        if (!line) return { weeksText: "", rest: line || "" };
-        const match = line.match(/(\d+(?:-\d+)?(?:,\d+(?:-\d+)?)*)\s*(?:\((单|双)\))?\s*周/);
-        if (!match) return { weeksText: "", rest: line };
-        const weeksCore = match[1];
-        const oddEven = match[2] ? `(${match[2]})` : "";
-        const weeksText = `${weeksCore}${oddEven}周`;
-        const rest = line.replace(match[0], "").trim();
-        return { weeksText, rest };
-    }
-
-    function parseCourseBlock(block) {
-        const lines = block
-            .split(/\n+/)
-            .map((l) => l.trim())
-            .filter(Boolean);
-        if (!lines.length) return null;
-
-        const name = lines[0] || "";
-        let teacher = "";
-        let weeksText = "";
-        let position = "";
-
-        const weekLineIndex = lines.findIndex((l) => /周/.test(l));
-        if (weekLineIndex >= 0) {
-            const { weeksText: extractedWeeks, rest } = extractWeeksTextFromLine(
-                lines[weekLineIndex]
-            );
-            weeksText = extractedWeeks;
-            if (weekLineIndex === 1) {
-                teacher = rest || lines[1];
-            }
-        }
-
-        if (!teacher && lines.length > 1) {
-            teacher = lines[1];
-            const { weeksText: extractedWeeks, rest } = extractWeeksTextFromLine(teacher);
-            if (extractedWeeks) {
-                weeksText = weeksText || extractedWeeks;
-                teacher = rest;
-            }
-        }
-
-        if (!weeksText) {
-            for (const line of lines) {
-                const { weeksText: extractedWeeks } = extractWeeksTextFromLine(line);
-                if (extractedWeeks) {
-                    weeksText = extractedWeeks;
-                    break;
-                }
-            }
-        }
-
-        if (weekLineIndex >= 0 && weekLineIndex + 1 < lines.length) {
-            position = lines[weekLineIndex + 1];
-        }
-        if (!position) {
-            position =
-                lines.find((l) => l !== name && l !== teacher && !/周/.test(l)) || "";
-        }
-
-        return {
-            name: name || "未知课程",
-            teacher: teacher || "",
-            weeksText,
-            position: position || "",
-        };
-    }
-
-    function padTime(value) {
-        const text = String(value || "").trim();
-        const match = text.match(/^(\d{1,2}):(\d{2})$/);
-        if (!match) return text;
-        const h = match[1].padStart(2, "0");
-        return `${h}:${match[2]}`;
-    }
-
-    function randomColor() {
-        return Math.floor(Math.random() * 12) + 1;
-    }
-
-    function createId() {
-        if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
-            return crypto.randomUUID();
-        }
-        return `id-${Date.now()}-${Math.random().toString(16).slice(2, 10)}`;
-    }
-
-    function mergeCourses(courses) {
-        const byKey = new Map();
-        courses.forEach((course) => {
-            const weeksKey = (course.weeks || []).join(",");
-            const key = [course.name, course.teacher, course.position, course.day, weeksKey].join("|");
-            if (!byKey.has(key)) byKey.set(key, []);
-            byKey.get(key).push({ ...course });
-        });
-
-        const merged = [];
-        byKey.forEach((items) => {
-            items.sort((a, b) => a.startSection - b.startSection);
-            let current = null;
-            items.forEach((item) => {
-                if (!current) {
-                    current = { ...item };
-                    return;
-                }
-                if (item.startSection === current.endSection + 1) {
-                    current.endSection = Math.max(current.endSection, item.endSection);
-                } else {
-                    merged.push(current);
-                    current = { ...item };
-                }
-            });
-            if (current) merged.push(current);
-        });
-
-        return merged;
-    }
-
-    function parseScheduleFromDocument(doc) {
-        const cells = Array.from(doc.querySelectorAll("td.cell"));
-        const fallbackCells = cells.length ? [] : Array.from(doc.querySelectorAll("td[id^='Cell']"));
-        const targetCells = cells.length ? cells : fallbackCells;
-        const courses = [];
-        const seen = new Set();
-
-        targetCells.forEach((cell) => {
-            const id = cell.getAttribute("id") || "";
-            const match = id.match(/^Cell(\d)(\d{1,2})$/);
-            if (!match) return;
-
-            const day = parseInt(match[1], 10);
-            const startSection = parseInt(match[2], 10);
-            const rowspan = parseInt(cell.getAttribute("rowspan") || "1", 10);
-            const endSection = startSection + Math.max(rowspan, 1) - 1;
-
-            const blocks = splitCourseBlocks(cell.innerText || "");
-            blocks.forEach((blockText) => {
-                const parsed = parseCourseBlock(blockText);
-                if (!parsed) return;
-                const weeks = parseWeekText(parsed.weeksText);
-                if (!weeks.length) return;
-
-                const key = [
-                    parsed.name,
-                    parsed.teacher,
-                    parsed.position,
-                    day,
-                    startSection,
-                    endSection,
-                    weeks.join(","),
-                ].join("|");
-                if (seen.has(key)) return;
-                seen.add(key);
-
-                courses.push({
-                    id: createId(),
-                    name: parsed.name,
-                    teacher: parsed.teacher,
-                    position: parsed.position,
-                    day,
-                    startSection,
-                    endSection,
-                    color: randomColor(),
-                    weeks,
-                });
-            });
-        });
-
-        return mergeCourses(courses);
-    }
-
-    function parseTimeSlots(doc) {
-        const slots = [];
-        const seenNumbers = new Set();
-        const timeRegex = /(\d{1,2}:\d{2})/g;
-
-        const timeCells = Array.from(
-            doc.querySelectorAll("td[data-jcindex], td[data-jcIndex]")
-        );
-
-        timeCells.forEach((cell) => {
-            const text = (cell.innerText || cell.textContent || "").trim();
-            if (!text) return;
-
-            const indexAttr = cell.getAttribute("data-jcindex") || cell.getAttribute("data-jcIndex");
-            const numberMatch = text.match(/^(\d{1,2})/);
-            const number = parseInt(indexAttr || (numberMatch && numberMatch[1]) || "", 10);
-            if (!Number.isFinite(number)) return;
-
-            const times = text.match(timeRegex) || [];
-            if (times.length < 2) return;
-
-            if (seenNumbers.has(number)) return;
-            seenNumbers.add(number);
-
-            slots.push({
-                number,
-                startTime: padTime(times[0]),
-                endTime: padTime(times[1]),
-            });
-        });
-
-        return slots.sort((a, b) => a.number - b.number);
-    }
-
-    async function run() {
-        toast("开始解析课表...");
-        const doc = await getTargetDocument();
-        if (!doc) {
-            toast("未找到课表页面 iframe");
-            return;
-        }
-
-        await waitForScheduleData(doc);
-
-        const courses = parseScheduleFromDocument(doc);
-        const timeSlots = parseTimeSlots(doc);
-
-        if (!courses.length) {
-            toast("未解析到课程,请确认课表已加载完成");
-            return;
-        }
-
-        try {
-            const result = await window.shiguangBridgePromise.saveImportedCourses(
-                JSON.stringify(courses)
-            );
-            if (result === true) {
-                if (timeSlots.length) {
-                    await window.shiguangBridgePromise.savePresetTimeSlots(
-                        JSON.stringify(timeSlots)
-                    );
-                }
-                toast("课表导出成功");
-                window.shiguangBridge.notifyTaskCompletion();
-            } else {
-                toast("课表导出失败,请查看控制台日志");
-            }
-        } catch (error) {
-            toast("导出失败: " + error.message);
-        }
-    }
-
-    run();
-})();