mizdra's poem

雑なこと (日記/技術ポエム/メモ/…) を書くブログです.

2018-07-06

今日の電車

  • 行き: 勝った気持ち
  • 帰り: 負け

休講情報表示システム

弊サークルの部室には, 弊学の休講情報を掲載するWebページを表示するディスプレイが配置されており, 部員が休講情報に高速にアクセスする手段を提供している. 果たしてディスプレイ1枚を常時可動させ, 手元のスマートフォンからも数タップでアクセス可能なページを表示させる意味があるのか, という点については議論の余地があるだろう. が, 弊学の教務課がWebページを更新する度にそれを紙に印刷し, 掲示板に張り出しているという処置が取られていることに対する対抗運動であると考えるならば, 妥当と言えるかもしれない *1.

さて, この休講情報表示システムだが, 最近システムに利用されている端末が壊れたまま放置されていたため, 他の部員と協力して復活させることにした. 僕が担当したのはブラウザを開き, 休講情報を画面に表示する部分. 端末にはマウスは接続されていないため, どうにかしてブラウザをCLIから操作する必要がある. こういう時に GoogleChrome/puppeteer が便利.

const puppeteer = require('puppeteer')

const RELOAD_INTERVAL = 10 * 60 * 1000 // 10 minutes

async function setup() {
  const browser = await puppeteer.launch({ headless: false, args: ['--disable-infobars'] })
  const page = await browser.newPage()
  await page.goto('http://kyoumu.office.uec.ac.jp/kyuukou/kyuukou.html')

  return { browser, page }
}

async function main() {
  const { browser, page } = await setup()

  // 最新の休講情報を表示するため定期的にWebページをリロードする
  while (true) {
    await page.reload()
    // viewport size を window inner size に合わせる
    // ref: https://github.com/GoogleChrome/puppeteer/issues/1183#issuecomment-383722137
    await page._client.send('Emulation.clearDeviceMetricsOverride')

    // 表をフルスクリーンで表示
    await page.$eval('table', (el) => {
      el.webkitRequestFullscreen()
      el.style.backgroundColor = 'white' // そのままだと全画面表示したときに黒になるので, 背景色を変更
    })
    await page.waitFor(RELOAD_INTERVAL)
  }
}

main()

puppeteerは本来Chromiumをヘッドレスブラウザとして操作するためのライブラリで, デバッグのために puppeteer.launch({ headless: false }) という実際のウインドウを表示するオプションが付いている. これを利用することで, ユーザはブラウザが実際にどのような挙動を示すのかを目で確認しながらpuppeteerを使ったコードをデバッグできる. 今回はこの機能を流用し, puppeteerをモダンなJavaScript APIでブラウザを操作できるライブラリとして利用している.

実際に動かすと以下のような感じになる. ついでにFullscreen APIでちゃんと表を全画面表示してくれて最高ですね.

f:id:mizdra:20180707012100g:plain

*1:実際どのような理由で設置されているのかは僕は把握しておらず, 適当なことを書いています.