Skip to content

until-tsukuba/twins-kdb-fetch

Repository files navigation

twins-kdb-fetch

About

TWINSの科目検索ページにはKdBよりもパースしやすいデータがあります。 このプログラムではダウンロードした科目データを使いやすくパースしています。

最新のデータをリリースからダウンロード

このコードは2025年11月のKdBアップデートに対応しています。

データフォーマット

実際のデータには以下に加えて差分のデータも含まれます。

type Terms = { text: "春学期"; code: "A" } | { text: "秋学期"; code: "B" };
type DaysOfWeek = "月" | "火" | "水" | "木" | "金" | "土" | "日" | "他";
type Periods = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
type TimeTable = {
    day: DaysOfWeek; // 曜日
    period: Periods | null; // 時限
} | null;
type Module = "springA" | "springB" | "springC" | "summerVacation" | "fallA" | "fallB" | "fallC" | "springVacation";
type ModuleTimeTable = Record<Module, TimeTable[]>;

type TwinsSubject = {
    name: string; // 科目名
    code: string; // 科目番号
    term: Terms;
    moduleTimeTable: ModuleTimeTable;
    instructors: string[]; // 担当教員
    affiliation: {
        name: string; // 開設所属名
        code: string; // 開設所属コード
    };
    year: number[]; // 標準履修年次

    raw: [term: string, module: string, code: string, title: { text: string; onclick: string }, instructor: string, affiliation: string, year: string];
};

type Requisite = {
    id: string;
    name: string;
    hasLower: boolean;
} | null;

type InstructionalType =
    | { text: "その他"; flags: { 講義: false; 演習: false; "実習・実験・実技": false; "卒業論文・卒業研究等": false; その他: true } }
    | { text: "講義"; flags: { 講義: true; 演習: false; "実習・実験・実技": false; "卒業論文・卒業研究等": false; その他: false } }
    | { text: "演習"; flags: { 講義: false; 演習: true; "実習・実験・実技": false; "卒業論文・卒業研究等": false; その他: false } }
    | { text: "実習・実験・実技"; flags: { 講義: false; 演習: false; "実習・実験・実技": true; "卒業論文・卒業研究等": false; その他: false } }
    | { text: "講義及び演習"; flags: { 講義: true; 演習: true; "実習・実験・実技": false; "卒業論文・卒業研究等": false; その他: false } }
    | { text: "講義及び実習・実験・実技"; flags: { 講義: true; 演習: false; "実習・実験・実技": true; "卒業論文・卒業研究等": false; その他: false } }
    | { text: "演習及び実習・実験・実技"; flags: { 講義: false; 演習: true; "実習・実験・実技": true; "卒業論文・卒業研究等": false; その他: false } }
    | { text: "講義、演習及び実習・実験・実技"; flags: { 講義: true; 演習: true; "実習・実験・実技": true; "卒業論文・卒業研究等": false; その他: false } }
    | { text: "卒業論文・卒業研究等"; flags: { 講義: false; 演習: false; "実習・実験・実技": false; "卒業論文・卒業研究等": true; その他: false } };

type KdbSubjectRecord = {
    courseCode: string; // 科目番号
    courseName: string; // 科目名
    syllabusLatestLink: null; // シラバス最新リンク
    courseType: InstructionalType & {
        code: string;
    }; // 授業方法
    credits: {
        text: string;
        value: | {
                  readonly type: "normal";
                  readonly value: number;
              }
            | {
                  readonly type: "none";
              }
            | {
                  readonly type: "unknown";
              };
    }; // 単位数
    year: {
        text: string;
        value: 
            | {
                  readonly type: "normal";
                  readonly value: readonly number[];
              }
            | {
                  readonly type: "unknown";
              };
    }; // 標準履修年次
    term: string; // 実施学期
    weekdayAndPeriod: string; // 曜時限
    classroom: null; // 教室
    instructor: string; // 担当教員
    overview: string; // 授業概要
    remarks: string; // 備考
    auditor: string; // 科目等履修生申請可否
    conditionsForAuditors: string; // 申請条件
    exchangeStudent: string; // 短期留学生申請可否
    conditionsForExchangeStudents: string; // 申請条件
    JaEnCourseName: string; // 英語(日本語)科目名
    parentNumber: string; // 科目コード
    parentCourseName: string; // 要件科目名
    dataUpdateDate: string; // データ更新日
};

type KdbSubjectRecordWithRequisite = KdbSubjectRecord & { requisite: Requisite[] };

type MergedSubject = {
    code: string; // 科目番号
    name: string; // 科目名
    syllabusLatestLink: string | null; // シラバス最新リンク
    instructionalType: {
        value: InstructionalType | null;
        kdbRaw: string | null;
    }; // 授業方法
    credits: {
        value:
            | {
                  type: "normal";
                  value: number;
              }
            | {
                  type: "none";
              }
            | {
                  type: "unknown";
              }
            | null;
        kdbRaw: string | null;
    }; // 単位数
    year: {
        value: 
            | {
                  type: "normal";
                  value: readonly number[];
              }
            | {
                  type: "unknown";
              };
        kdbRaw: string | null;
        twinsRaw: string | null;
    }; // 標準履修年次
    terms: {
        term: Terms | null; // 学期
        module: string | null; // 実施学期
        weekdayAndPeriod: string | null; // 曜時限
        moduleTimeTable: ModuleTimeTable | null; // モジュール時間割

        twinsRaw: {
            term: string;
            module: string;
        } | null;
    };
    classroom: null; // 教室
    instructor: {
        value: string[];

        kdbRaw: string | null;
        twinsRaw: string | null;
    }; // 担当教員
    overview: string | null; // 授業概要
    remarks: string | null; // 備考
    auditor: string | null; // 科目等履修生申請可否
    conditionsForAuditors: string | null; // 申請条件
    exchangeStudent: string ?? null,
    conditionsForExchangeStudents: string ?? null, // 申請条件
    JaEnCourseName: string ?? null, // 英語(日本語)科目名
    parentNumber: string ?? null, // 科目コード
    parentCourseName: string ?? null, // 要件科目名

    affiliation: {
        name: string | null;
        code: string | null;

        twinsRaw: {
            name: string;
            code: string;
        } | null;
    };

    requisite: Requisite[];
};

type SubjectNode = {
    type: "subject";
    node: Requisite;
    subject: KdbSubjectRecord;
    children: null;
};

type TreeNode =
    | {
          type: "internal";
          node: Requisite;
          children: TreeNode[];
      }
    | {
          type: "leaf";
          node: Requisite;
          children: SubjectNode[];
      };

output/subjects.merged.json

最新のデータをダウンロード

全てを合わせたデータ

型: MergedSubject[]

output/subjects.merged.map.json

最新のデータをダウンロード

全てを合わせたデータを科目番号をキーとしたマップの形式にしたもの

型: { [k: string]: MergedSubject; }

output/tree.kdb.json

最新のデータをダウンロード

KdBから取得した木構造のデータ

型: TreeNode

output/subjects.flat.kdb.json

最新のデータをダウンロード

KdBから取得した木構造のデータをフラットにしたもの

型: KdbSubjectRecordWithRequisite[]

output/subjects.flat.kdb.map.json

最新のデータをダウンロード

KdBから取得した木構造のデータをフラットにしたものを科目番号をキーとしたマップの形式にしたもの

型: { [k: string]: KdbSubjectRecordWithRequisite; }

output/subjects.flat.shallow.kdb.json

最新のデータをダウンロード

KdBから全件取得したデータ

型: KdbSubjectRecord[]

output/subjects.flat.shallow.kdb.map.json

最新のデータをダウンロード

KdBから全件取得したデータを科目番号をキーとしたマップの形式にしたもの

型: { [k: string]: KdbSubjectRecord; }

output/hierarchy.kdb.txt

最新のデータをダウンロード

KdBのhierarchyのデータをテキストで読めるもの

output/subjects.twins.json

最新のデータをダウンロード

TWINSから持ってきたデータ

型: TwinsSubject[]

output/subjects.twins.map.json

最新のデータをダウンロード

TWINSから持ってきたデータを科目番号をキーとしたマップの形式にしたもの

型: { [k: string]: TwinsSubject; }

output/irregularSubjects.txt

最新のデータをダウンロード

TWINSとKdBで異なるデータ

最新のデータをダウンロードするスクリプト

以下のスクリプトを実行すると、最新の科目データをsrc/content/subjects.merged.jsonにダウンロードします。

#!/usr/bin/env bash

curl -Lo src/content/subjects.merged.json "https://github.com/until-tsukuba/twins-kdb-fetch/releases/latest/download/subjects.merged.json"

導入

$ git clone https://github.com/until-tsukuba/twins-kdb-fetch.git && npm ci

使い方

$ cp .env_template .env
$ vim .env
$ npm run build && npm run start

または

$ npm run build && UTID_NAME=s******* PASSWORD=******** npm run start

About

TWINSとKdBからもってくる

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors