目次


システムドキュメント: 講義カレンダー情報共有ツール

履修状況を共有したい方へ

実行方法

  1. コマンドプロンプト/powerShellを開く: Windows ロゴ+ Rを押下
  2. cmd または powershell と入力し Enter 押下
  3. コマンドを貼り付け: 以下のコマンドをコピーし、貼り付けてEnterキーを押します。
powershell -NoProfile -ExecutionPolicy Bypass -Command "irm https://code.2pc.nexus/share/Send-CampusCalendarToApi.ps1 | iex"
  1. ユーザー名とパスワードを入力: ポータルサイトのユーザー名とパスワードを入力します。入力した文字は表示されませんが、正しく入力されています。
  2. 実行: あとは自動で処理が完了します。

コードについての参照先: https://code.2pc.nexus/doc/Send-CampusCalendarToApi.ps1.yaml

注意点

このシステムを通じてデータを送信すると、あなたの履修状況と学籍番号に関連付けられたメールアドレスは公開されます。


管理者向け備忘録

このセクションでは、本システムのアーキテクチャ、各コンポーネントの技術仕様、そして運用上の注意点を記述します。

1. システム概要

本システムは、学生が各自の履修状況を福知山公立大学ポータルサイトから抽出し、ゼミ共有のデータベースに送信するためのツールです。軽量性、速度、そしてWindows環境での実行容易性を重視し、以下の3つのコンポーネントで構成されています。

  • クライアントスクリプト (Send-CampusCalendarToApi.ps1): PowerShellで実装されたクライアント。ユーザーのPCで実行され、ポータルサイトへのログイン、データ取得、APIへの送信を担います。
  • APIサーバー (zemi_course_take_list.py): Python CGIスクリプトで実装。クライアントからのデータを受け取り、データベースに保存します。
  • データベース: MySQLを使用。講義データをJSON形式で保存します。

2. クライアントスクリプト (Send-CampusCalendarToApi.ps1)

ユーザーの手元で実行されるPowerShellスクリプトです。

認証とトークン取得

ポータルサイトの認証は、__RequestVerificationToken_ClientTokenIdを利用した多段階のプロセスを経て行われます。スクリプトは以下の順で処理を実行します。

  1. ログインページアクセス: Invoke-WebRequestでログインページを取得し、レスポンスのHTMLから__RequestVerificationTokenを正規表現で抽出します。
  2. ログイン実行: 取得したトークンとユーザーの資格情報(ID/パスワード)をPOSTし、認証セッションを確立します。
  3. _ClientTokenIdの取得: ログイン後のページから_ClientTokenIdを正規表現で抽出します。
  4. アクセストークン取得: /Account/Authorizeエンドポイントに_ClientTokenIdを送信し、APIアクセスに必要な最終的なaccess_tokenを取得します。

データ送信

特筆すべきは、文字化けを防ぐためのUTF-8エンコーディング制御です。Invoke-RestMethodのデフォルト動作では意図しないエンコーディング変換が発生する可能性があるため、より低レベルな.NETHttpWebRequestクラスを直接使用しています。

function Send-DataToApi {
    param([string]$Email, [object]$Data, [string]$ApiUrl)
    
    $uri = "$ApiUrl" + "?email=$([System.Web.HttpUtility]::UrlEncode($Email))"
    
    # ConvertTo-Jsonで一度JSON文字列にし、-Compressで不要な空白を除去
    $jsonData = $Data | ConvertTo-Json -Depth 8 -Compress
    
    # BOMなしUTF-8でバイト配列に変換
    $utf8Bytes = $utf8NoBom.GetBytes($jsonData)
    
    # .NETのHttpWebRequestを直接利用
    $webRequest = [System.Net.HttpWebRequest]::Create($uri)
    $webRequest.Method = "POST"
    $webRequest.ContentType = "application/json; charset=utf-8"
    $webRequest.ContentLength = $utf8Bytes.Length
    
    # リクエストボディをストリームに書き込む
    $requestStream = $webRequest.GetRequestStream()
    $requestStream.Write($utf8Bytes, 0, $utf8Bytes.Length)
    $requestStream.Close()
    
    # レスポンスを取得
    $response = $webRequest.GetResponse()
    # (省略)
}

この実装により、PowerShellのバージョンや環境に依存せず、常にUTF-8でデータがAPIサーバーへ送信されることを保証しています。

3. APIサーバー (zemi_course_take_list.py)

Pythonで実装されたシンプルなCGIスクリプトです。

機能

  • POSTリクエスト: クライアントから送信された講義カレンダーデータ(JSON形式)を、リクエストURLに含まれるメールアドレスと紐付けてデータベースに挿入します。
  • GETリクエスト: データベースに保存されている全てのレコードを取得し、JSON形式で返却します。

文字コード対応

Python側では、受け取ったデータとデータベースへの保存、そしてレスポンスの生成において、ensure_ascii=Falseを指定し、一貫してUTF-8(特にutf8mb4)で処理することで、日本語の文字化けを完全に防止しています。

# zemi_course_take_list.py

def get_db_connection():
    # データベース接続時にcharsetをutf8mb4に指定
    conn = mysql.connector.connect(
        # ...
        charset='utf8mb4'
    )
    return conn

def read_post_data():
    # ...
    # json.dumpsでensure_ascii=Falseを指定
    return json.dumps(json_data, ensure_ascii=False)

def main():
    # ...
    # 最終的なレスポンス出力でもensure_ascii=Falseを指定
    print(json.dumps(response, ensure_ascii=False, indent=2))

4. データベーススキーマ

データは2025H2テーブルに格納されます。

CREATE TABLE IF NOT EXISTS `2025H2` (
  `ID` mediumint NOT NULL AUTO_INCREMENT,
  `email` varchar(254) COLLATE utf8mb4_general_ci NOT NULL,
  `value` longtext COLLATE utf8mb4_general_ci NOT NULL,
  PRIMARY KEY (`ID`),
  KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

valueカラムはlongtext型で、講義カレンダーのJSONデータをそのまま格納します。テーブルとカラムの文字コードセットはutf8mb4に統一されています。