学校の文化祭で進行状況を表示したかった話


# はじめに

この記事は、Qiita Advent Calendar 1日目の記事です。
以下の記事より、すべての記事をご覧になれます。

https://qiita.com/0_terarin_0/items/2b60d47a2d0e64a273c3

# 筆者について

現在高校3年生
（元）水泳部マネージャー
（元）生徒会長
（元）とある団体の代表

# 本編

題名の通りです。離れ離れの場所で開催されているそれぞれの催しごとの進行状況を一つのサイネージで表示させるだけのプログラムです。

## バッググラウンドのシステム

うちの学校はGoogle Workspaceを利用していますのでGoogle Apps Scriptをバックグラウンドに利用しました。データの管理をGoogle Spredsheetですることによって誰でも進行中のプログラムの表示をインターネットにさえ繋がっていれば編集できるようにしました。参考までに下にシートを表示させておきます

![Screenshot 2024-11-30 at 14.23.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583428/a5a6d411-6359-1c55-f3df-1fab5d238431.png)

続いて、Google Apps Scriptのコードですが、こちらは単純で表示されているデータを読み込んでGETのリクエストをしているだけです。

```js:code.gs
function doGet(e) {
    const SHEET = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
    const cell_place1 = SHEET.getRange('A1');
    const cell_place2 = SHEET.getRange('A2');
    let status;
    if (place == "place1") {
        status = cell_arena.getValue();
    }else if (place == "place2") {
        status = cell_restaurant.getValue();
    } else {
        tatus = "faild"
    }
    let status_json = JSON.stringify({ "status": status });
    const res = ContentService.createTextOutput(status_json);
    return res.setMimeType(ContentService.MimeType.JSON);
}
```

## フロントエンドの表示

こちらは至ってシンプルでHTMLで表示させているだけです。

```html:index.html
<!DOCTYPE html>
<html style="height: 100vh; width: 100wh">
  <head>
    <meta charset="utf-8" />
    <link
      rel="stylesheet"
      href="./assets/bootstrap/css/bootstrap.css"
      type="text/css"
    />
    <link rel="stylesheet" href="./assets/bootstrap-icons/font/bootstrap-icons.css" />
    <link rel="stylesheet" href="./main.css" />
    <script src="./assets/grid/grid.js"></script>
    <script src="./show_s.js"></script>
  </head>
  <body id="body" class="px-5 bg-black py-2">
    <div style="width: 100%; display: flex; flex-direction: row-reverse">
      <div style="height: 250px; width: 250px">
        <img src="./assets/logo.png" height="100%" />
      </div>
    </div>
    <div class="w-100 h-100 d-flex flex-column justify-content-center">
      <p class="text-start" style="font-size: 42px">現在進行中の演目（場所１）</p>

      <p id="test" class="text-center" style="font-size: 160px">Loading</p>

      <p class="text-center blinking text-danger" style="font-size: 48px; visibility: hidden;" id="enterCheck">
        <mark class="text-danger"
          ><i class="bi bi-exclamation-triangle"></i>
          保護者の方はご入場いただけません。</mark
        >
      </p>
      <p class="text-center" style="font-size: 36px;">左のQRコードよりプログラムをご覧いただけます。</p>
    </div>
    <script>
      function reload(){
        window.location.reload()
      }
      window.addEventListener('load', function () {
        setTimeout(reload, 10000)
      });
    </script>
  </body>
</html>
```

```javascript:show.js
var url =
  "https://script.googleusercontent.com/a/macros/orgs/echo?user_content_key=g2fBKmOQo09sGyF5oTpt0V6E0pInkSUR0ayX-ZKMVL7Asmxpu1n-u90zgpETWO4Fw4u0jhMgA9hBhoTwm6tjOjn8timCr2_aOJmA1Yb3SEsKFZqtv3DaNYcMrmhZHmUMi80zadyHLKB_hBJV5WlOhfA94WaGlHKSA9aQ5h6yNrXV2OKoRIslidk-qB0GWTDUpa_aSooZBEu5Bu0E8u5yTqQXf38TPM5si3rWNRlAG7W6n3IKuz0N_vx6N_gjwHpg3diNI9_hD9HeBuIZzq-uuZPF0hqxPb_b7iWQ0oMh3Wo&lib=MWalQ9ejAjj_0YHST5Cw9h1kL2vNjz42l";
fetch(url)
  .then((res) => res.json())
  .then((cont) => (document.getElementById("test").textContent = cont.status))
  .then((show) => {
    if(show =="OP"){document.getElementById("enterCheck").style.visibility = "visible";}});
```

```css:main.css
p {
    color: #fff;
  }

  .blinking {
    -webkit-animation: blink 1.6s ease-in-out infinite alternate;
    -moz-animation: blink 1.6s ease-in-out infinite alternate;
    animation: blink s ease-in-out infinite alternate;
  }
  @-webkit-keyframes blink {
    0% {
      opacity: 0;
    }
    100% {
      opacity: 1;
    }
  }
  @-moz-keyframes blink {
    0% {
      opacity: 0;
    }
    100% {
      opacity: 1;
    }
  }
  @keyframes blink {
    0% {
      opacity: 0;
    }
    100% {
      opacity: 1;
    }
  }


.grid-td{
    color: white ;
    text-align: center ;
    border: 1px solid #fff;

}

.grid-table{
    color: white;
    text-align: center;
    border: 1px solid #fff;
    font-size:24px;
    margin-top:12px;
}

.grid-th{
    color: white;
    text-align: center;
    border: 1px solid #fff;
}

.gridjs-wrapper{
    overflow: scroll;
}
```

で、問題はこれをどうやって表示するかです。この状況を打破するのに幾つかの問題がありました。例えば、僕の使っているMacはM1のMacですが、学校のMacはIntelのものです。PythonやNginxのシングルバイナリにするにはエミュレート環境でビルドしたら解決と思っていたのですが、フロントエンドのコードが変わるたびにビルドし直すのはとてもめんどくさいです。

そこでネットを漁っていると次のようなバイナリを発見しました。

https://redbean.dev/

これを利用したらどうやらうまいことできそう。ということで、ここに書いてある通りにしてWebサーバー建てました。（詳細聞きたい方はコメント欄で質問してください）

## 結局うまくいかなかった理由

結局うまくいかなかったのは次の理由があると考えられます。

- そもそもネットワークが安定していなかった
- Macのバッテリーが弱りすぎている
- 自動スリープの設定変更に管理者権限が必要になる

これらの理由から、失敗したと思っていますが、結局は事前のリサーチ不足ですね。やっぱり片手間でやることやなか（）

# 最後に

こんな経験をするのはおそらくこの先ないかあってもしばらくないと考えています。今回の経験を次回以降に活かしていきたいと考えています。