Diary of a Perpetual Student

Perpetual Student: A person who remains at university far beyond the normal period

標準エラー出力が見れなくなるpreztoユーザはバージョンを確認しよう

結論

  • 昔のpreztoを使っている人は、最新のリポジトリの状態を反映しよう

本文

僕のターミナルがおかしい

僕のターミナル環境はなにかがおかしい。何がおかしいかというと、標準エラー出力に書き込まれているものが見えなくなることがありました。

コマンドの実行に失敗しても結果が見れず何も表示されないため、「あれ?一瞬でコマンド終了したけど成功はしてないな?ステータスコードも0じゃないし……」と困惑していました。

経験的にCtrl+cを押した後に確率的に動かなくなるという感覚を持っていました。また、新しいタブを開くとそのタブでは問題が解消することも知っていました。

この現象が、OSを問わず、僕の使っているあらゆるPCで発生していて、とても気持ち悪いなと思っていました。

preztoが悪いのだろう

そんな生活を2年ほど続けていたのですが、さすがに嫌になってきたので、原因調査と問題解消に取り組むことにしました。

実は原因はzshの設定にあるのだろうということは大方分かっていました。Macのデフォルトシェルがzshになって、preztoを導入した頃からこの事象が発生し続けているからです。

pretzoとはzshフレームワークのようなもので、様々なプロンプトのテーマを選んだり、補完や情報表示ができるプラグインをかんたんに導入できたりするものです。好きな僕はprezto本家のリポジトリをフォークして自前のcustomを施したものを各PCでcloneして使っています。

github.com

こんなデザインのターミナルに見覚えがありませんか?

ただ、「prezto 標準エラー出力 見れない」などと検索してもそれっぽい情報にたどり着くことができず、甘んじて受け入れていたのです。

issue発見

今日は本気で調べようと思ったので、英語で「pretzo stderr」と検索したら、あっさりと同様の不具合を訴えるissueが見つかりました。

github.com

依存していた zsh-async で、stderrを/dev/nullにマップしたままにしてしまうバグがあったようで、現在は改修されているとのことです。

そういえば、最初にforkしてから一回も本家リポジトリの最新版をpullしていないなあということに気づきました。

問題解決

2, 3年分の変更をpullして、自前のカスタムとのコンフリクトを解消しつつpreztoを最新版に置き換えることができました。

$ cd ~/.zpretzo
$ git stash
$ git pull git@github.com:sorin-ionescu/prezto.git master
$ ## コンフリクト解消
$ git commit
$ git push origin master
$ git stash pop
$ ## コンフリクト解消
$ git restore --staged
$ git stash destroy

*1

何度かコマンド実行中にCtrl-cを押して確認していますが、標準エラー出力が見えなくなる事象は発生していないような気がします。

まとめ

一度整備した開発環境を弄るのは、壊れてしまう可能性もあるので躊躇われますよね。ただ、ソフトウェアが意味もなくアップデートすることはそれほど多くありません。今回はシェルの設定に問題がありましたが、開発環境を構成する様々な要素の更新履歴を定期的に確認し、暇な時間にアップデートする習慣をつけていきます。

*1:余談ですが、git checkoutがgit switchとgit restoreに分かれていたことを最近知りました。たしかにcheckoutでできることが広すぎましたね

自宅にYAMAHAの業務用ルータを導入してみた

こんにちは、ネットワーク初心者のid:arthur-1です。今回は家のネットワーク環境整備の話をします。

学生時代には学園祭実行委員会の1ロールとしてITインフラ管理をやっていました。「ネット繋がらない!」「プリンター調子悪い!」という声に24時間体制で対応できるよう、学園祭期間中おもてなしせずに死んだ顔で部室にいたのも今は昔。それも、別に専門的な知識があってやっていたというわけではなく、マスタリングTCP/IPの入門編は一通り読んだなあという程度のものです。

今回のお話をまとめると、概ね以下の内容になります。

  • ASUSのルータもIPoEに対応したと思っていたけど完全ではなかった
  • 仕方ないので調子に乗ってYAMAHAのRTX830を買った
  • せっかくなのでVPN構築した

環境

  • ぷらら光 ホームタイプ
    • フレッツ 光ネクスト ファミリー・ギガラインタイプ 相当
    • ひかり電話未契約のため、ルータ機能がないONUを借りている

ASUSのルータが好きだった

実家にいたころは弟の希望でASUSの無線ルータを使っていたのですが、管理画面がモダンな感じでけっこう気に入っていました。

一人暮らししても同じようなインタフェースで触りたいと思い、以下の無線ルータを購入しました。

ASUSのルータはv6プラスに対応していたけど…

実家ではPPPoEしか使えない時代遅れのプロバイダを利用していたのですが、一人暮らしの家ではIPoE (IPv4 over IPv6)で繋いで爆速にしたいと考えていました。なぜIPoEにしたら嬉しいかという話は他のサイトに詳しいです。

www.ntt.com

一応自分の言葉でも説明してみます。

  • 従来のPPPoE接続よりIPoE接続のほうが高速
  • ただし、IPoE接続はIPv6前提で、これだけだとIPv6対応サイト(割りと少ない)しか見られなくなる
  • IPv4 over IPv6という技術を組み合わせると、IPv4の通信もIPv6経由で行うことができ、全てのサイトを高速に閲覧できる

先程紹介したASUSのルータも、ファームウェアアップデートにより「v6プラス」に対応したという情報を手に入れていたので購入したものになります。So-netのWebサイトにはv6プラスについての説明が以下の通り掲載されています。

「v6プラス」とは何ですか?

「IPoE接続方式によるIPv6インターネット接続」と「IPv6ネットワーク上で実現するIPv4インターネット接続 (IPv4 over IPv6) 」を指します。 IPv6通信だけでなく、IPv4通信もIPoE接続方式で利用できるため、さらに快適にインターネットをご利用いただけるようになります。

www.so-net.ne.jp

僕はこの説明を読んで、v6プラス対応のルータを買えば、IPoE経由でIPv4のサイトを閲覧できると思いました。ところが、実際にセットアップしてみると、なぜか繋がらないのです。

この理由は、IPoE×IPv4 over IPv6を実現する接続方式が1種類ではなく複数種類あり、「v6プラス」はそのうちの1種類だったからです。ブランディングのために名前を変えているというわけではなく、方式として異なるものということです。

  • v6プラス
  • IPv6オプション
  • transix (DS-Lite)
  • IPv6高速ハイブリッド IPv6 IPoE + IPv4
  • OCNバーチャルコネクト
  • クロスパス

そして、僕が利用しているぷららでは、v6プラスではなくOCNバーチャルコネクト方式を基本的に採用しているとのことでした。「ぷららv6エクスプレス」というサービス名だったので名前から採用方式まで知ることはできないのもあって、原因調査は困難を極めました。

ASUSルータはOCNバーチャルコネクトには対応していないので、この製品を大元のルータにしてしまうと、IPoEの恩恵に預かることができません。海外製品だから仕方ないですが、仕様乱立し過ぎだろ、とも思います。

業務用ルータに手を出す

仕方ないので(?)業務用ルータメーカとして名高いYAMAHAのRTX830を購入しました。正直NECAtermとか無難に国内メーカの家庭用ルータを買えば解決する話ではあったんですが、会社のネットワーク強そうな先輩方から勧められたので良い機会だと思って購入しました。

network.yamaha.com

もちろんこれだけだとWi-Fi接続ができないので、購入したASUSのRT-AX3000はアクセスポイントモードにして接続しました。二重ルータにするのは管理が面倒だし家庭用途で選択するメリットは薄いですね。もちろんホームゲートウェイ利用者などが何も知らずに自然と二重ルータにしてしまう例は数多くあるとは思いますが。

設定は大変かな~と思っていたのですが簡単でした。IPoEで繋げたいな~という顔をしてWebコンソールでポチポチしていると気づいたら設定が終わっています。もちろんOCNバーチャルコネクトにも対応しています。

VPN構築

これだけだと業務用ルータにしたうま味が少ないので、外出先から家のPCにリモートデスクトップ接続できるよう、VPNの設定をしてみました。

もちろん家庭用回線だし固定IPアドレスはもらっていません。しかし、DDNSというものを使うといつでも同じ名前で自分の家のネットワークにアクセスすることができます。グローバルIPアドレスが変わったときにルータがDNSサーバに通知してレコードを変えてくれるものです。YAMAHAのルータにはネットボランチDNSサービスというものが付随しています。

network.yamaha.com

(ちなみにDDNSサービスはASUSのルータにもついていました。)

設定手順は以下の通りです。

  • OCNバーチャルコネクトだけではなく、サブとしてPPPoEによる接続設定も追加
  • PPのインタフェースに対してDDNSを設定
  • VPNの通信はPPPoE側に流すようフィルタを設定

これらを全部説明してもよいのですが、長くなってしまうので各自他のWebサイトの情報をあたってください。業務用ルータはコマンドで設定しなきゃいけないというハードルを感じる人もいるかもしれませんが心配いりません。今回の設定はすべてWebコンソールから行えました

まとめ

  • IPoE × IPv4 over IPv6 を使うとネットが速くなりがち
  • でも、接続方式が複数あるのでプロバイダ採用の方式を調べてからルータを選ぼう
  • DDNSサービス使うと固定IPなくてもVPN運用やりやすい

以上で爆速インターネットとVPNを手に入れたのでした。(完)

(これでも大学の専用回線には遠く及ばないので光クロス対応エリアになってほしい。)

202203引っ越しログ 5. 物件編

いよいよ引っ越しの振り返りも最後です。友人も引っ越しをそろそろしたいようで、このエントリ群を参考にしてもらっています。

  1. 家電編
  2. 家具編
  3. PC周辺機器編
  4. IoT機器編
  5. 物件編 ←本エントリ

物件編

要件定義

まず、物件に求める要件を書き出して、それらを重要度ごと分類しました。テレワークメインで働くというワークスタイルを想定していたのと、友人を呼んでボードゲームを遊びたいと思っていたので、それらを想像しながら具体的な要件に分解していきました。自分の場合は概ね以下の通りになりました。

  • Must
    • [立地] 片道2時間以内にオフィスに到着できること
    • [設備] 光配線方式でインターネットが利用可能
    • [設備] 専有トイレがある
  • Should
    • [立地] 駅から徒歩10分以内
    • [建物] 防音性を持った建物 (木造や壁薄はNG)
    • [建物] 専有面積40m2前後
    • [契約] 共益費込みで家賃8万円前後
    • [設備] エアコンあり
  • May
    • [立地] オフィスまで乗り換え1回以内 (優等列車への乗り換えも含む)
    • [立地] 東海道新幹線に乗りやすい
    • [建物] 2DKは部屋が分かれすぎ、それよりは1LDKを希望
    • [設備] 屋内に洗濯機が置ける
    • [設備] 都市ガス
    • [設備] PCデスクを置く予定の位置でアースが取れる
    • [設備] 駐車場あり
    • [契約] 普通賃貸借契約

前回の一人暮らしの反省もここに反映しています。1つは駅近立地にしたことです。昔は駅から徒歩20分弱かかっていたせいで、大学に行きたくなくなる・大学から帰りたくなくなるという致命的な問題を抱えていました。今でこそオンライン授業が盛んですが、昔は対面が当たり前だったのです。

また、都市ガスを希望したのもそうです。やはりプロパンガスは少々高かったように感じました。寒がりを極めていて熱めのシャワーを15分ぐらい浴びていたいのでガス代が馬鹿になりません。

物件を探す

自分はsuumoで条件を絞り込んで、見つかった良さげな物件を満たす条件とともにスプレッドシートに記入していきました。広くて駅チカで安めという厳しい条件を課したのもあって、そもそも選択肢があまりない状態でした。

さらに、良い物件というのは一瞬で無くなっていくものです。初期費用の不安からためらっていると、欲しい物件を先に取られてしまいます。就職活動の後は新生活のための貯金をしておくことを強く推奨します。

物件探しは11月ぐらいから始めましたが、最終的にこれだ決めたのは1月下旬ぐらいです。その物件は個人的には条件にマッチしていてとても良いなと思ったのですが、物件情報サイトで長期間残っていたので内見はドキドキでした。

契約スケジュール

スケジュール感の参考にしてください。

1/22
物件の状況問い合わせ
1/31
内見(オフライン)・申込み
2/4
審査通過通知
2/13
契約書見本受領
2/18
契約手続き(オフライン)
2/22
初期費用振り込み
3/5
契約開始・鍵の受け取り(オフライン)

内見

仲介担当者の心象が後の審査に影響すると聞いていたので、内見は丁寧な姿勢で臨みました。遅刻しないよう30分前に最寄り駅につき、ひとしきり散策して周囲の環境をチェックしました。

内見のときの反省点は、カーテンサイズの参考のためにと窓枠の大きさを測ってしまったことです。窓ではなくカーテンレールの幅や高さを測る必要があります。そうしないと、サイズの合わないカーテンを買ってしまう可能性があります。自分はこれをしそびれていて契約開始後に改めて計測したのですが、既製品のサイズが合わないことがわかりました。その後オーダーメイドで作ってもらったので時間がかかり、しばらくカーテンなし生活を強いられてしまいました。内見の時点で適切なサイズがわかっていればあらかじめ発注しておけます。

初期費用

項目 金額
敷金 80,000
礼金 80,000
初回賃料(2か月分) 149,860
鍵交換費用 27,500
仲介手数料 88,000
初回保証料 40,000
火災保険料*1 15,440
合計 444,620

敷礼1か月ずつに仲介手数料丸々自分持ちだったので、かなり掛かってしまったなあという印象です。それでも、月額でサポート会員料とかいうみかじめ料を取られる物件も数多くある中、この物件はなかったので初期費用としてはこんなものかなと思います。あれって、仲介手数料なしの代わりに取りますよというシステムですよね。仲介手数料は法律で上限が定まっていますが、サポート会員費用となるとその縛りから逃れられるので、トータル費用が同じだったとしても心象がよくないです。

まとめ

項目 金額
1. 家電編 92,859
2. 家具編 167,218
3. PC周辺機器編 104,397
4. IoT機器編 71,571
5. 物件編 444,620
合計 880,665

ここに載せていない雑費もそれなりにあると思いますが、トータルとしては大台にいかないぐらいになりました。引っ越しは実家に手伝ってやってもらって無料だったのが大きいですね。引っ越しシーズンに大量の本とボードゲームとPCを遠方から運んでもらっていたら、一体いくらになっていたのだろうと思います。

振り返りとして費用対効果の話をすると、これだけの金額を掛ける価値があったと思っています。僕はメンタルが露骨にパフォーマンスの差に現れる人間なので、家の快適さというのは本当に大事なポイントでした。社会人を始めて3か月目になりますが、持続的に仕事できているのは間違いなく家の環境が良いおかげです。(もちろん、職場の環境も心理的安全性の面でとても良いのですが。)SDGsとかいう大きな看板を掲げる前に、自分の生活が持続的であるかという身近な問題をクリアしたいです。

最後に、今快適に新生活を送れているのは、僕に仕事を与えてくれたみなさん、就職祝いをくれた親族の方々のおかげです。本当にありがとうございました。

*1:これだけ契約開始翌月末〆

input[type="datetime-local"]の値をPlay Frameworkで受け取るには

結論

  • input[type="datetime-local"] をPlay Frameworkで受け取る時のValidationルールは localDateTime("yyyy-MM-dd'T'HH:mm")

本文

背景と問題

Play Frameworkのチュートリアルとして、スケジュール管理ツールのようなものを作ろうとしていました。予定のタイトルと開始日時・終了日時をDBに蓄積していくようなWebアプリケーションです。

日時の入力を自分で実装するのは大変なので、input[type="datetime-local"] 要素を利用しました。この要素を利用すると、ブラウザが良い感じに日時を選択するUIを表示してくれます。

developer.mozilla.org

この値をPlay Frameworkで受け取ろうとして、以下のようなControllerを作りました。

package controllers

import java.time.LocalDateTime
import 
import javax.inject._
import play.api.i18n._
import play.api.mvc._
import play.api.data.Form
import play.api.data.Forms._

case class CreateScheduleRequest(title: String, startsAt: LocalDateTime, endsAt: LocalDateTime)

@Singleton
class CalendarController @Inject() (mcc: MessagesControllerComponents) extends MessagesAbstractController(mcc) {
  private val form = Form(
    mapping(
      "title" -> nonEmptyText(maxLength = 30),
      "startsAt" -> localDateTime,
      "endsAt" -> localDateTime
    )(CreateScheduleRequest.apply)(CreateScheduleRequest.unapply)
  )


  def postAdd = Action { implicit request =>
    form
      .bindFromRequest()
      .fold(
        error => {
          // エラー表示
        },
        postRequest => {
          // Scheduleの追加処理
        }
      )
  }
}

ところが、input[type="datetime-local"] で日時を選んで送信しても、localDateTimeじゃないよというバリデーションエラーが表示されてしまいます。

この要素を使ってフォームを送信すると、値としては 2018-06-12T19:30 のような形になります。これはJavaでいうと ISO_LOCAL_DATE_TIME と呼ばれるフォーマットになります。

解決法の模索

まず最初に、内部的に LocalDateTime.parse() を呼んでいて、これに失敗しているのではないかと考え、REPLで実験してみました。

scala> java.time.LocalDateTime.parse("2022-04-20T18:21")
val res0: java.time.LocalDateTime = 2022-04-20T18:21

これはうまくいくようです。

次に、localDateTime には nonEmptyText(maxLength = 30) と同じように引数が渡せるのではないかと睨みました。実際、 def localDateTime(pattern) という定義がありました。コメントには

@param pattern the date pattern, as defined in java.time.format.DateTimeFormatter

と書かれています。ならばと以下のように書いてみましたがType Errorになります。

import java.time.format.DateTimeFormatter.ISO_LOCAL_DATE_TIME
...
      "startsAt" -> localDateTime(ISO_LOCAL_DATE_TIME),

なんと、patternはstringのみしか許容しないようです。定数として定義済みのフォーマッタも使えないのかあという気持ちになりました。

解決法

-       "startsAt" -> localDateTime,
+       "startsAt" -> localDateTime("yyyy-MM-dd'T'HH:mm"),
-       "endsAt" -> localDateTime
+       "endsAt" -> localDateTime("yyyy-MM-dd'T'HH:mm")

上記のように文字列でフォーマットを教えてあげることで解決しました。Tという固定の文字列をpatternとしてどう表現するか分からず、地味に苦戦しました。(シングルクォートすれば良いようです。)

感想

WebのフォームからlocalDateTimeを送信する時に、input[type="datetime-local"] を使うのは自然なムーブだと思うので、こちらのフォーマットをデフォルトにして欲しいなと思いました。

202203引っ越しログ 4. IoT機器編

もう5月も終わりそうなのに未だに3月の話をしている。

  1. 家電編
  2. 家具編
  3. PC周辺機器編
  4. IoT機器編 ←本エントリ
  5. 物件編

IoT機器編

持ち込んだもの

Nature Remo Mini

スマートリモコンと呼ばれるものです。赤外線のリモコンで制御できる製品なら、こう行った製品を使うことで簡単にスマート家電化できます。リモコンの代わりにこいつが赤外線信号を発信してくれるんですね。いくつか種類があるのですが、僕は1回目の一人暮らしの頃からずっとNature Remo Miniを使っていました。今は世代が変わったものが販売されているそうです。

昔はこのRemoを使って、エアコンとシーリングライトを制御していました。ただ、シーリングライトの制御には不満がありました。

Google Home経由でRemoにつながっている製品を制御することができるのですが、Google Homeでは、シーリングライトの状態を取れる前提でインタフェースが設計されています。メインの操作がtoggleボタン(ついている時は消す・消えている時はつける)になっているんですね。ところが、Remoはただのリモコンなので、ライトがついているかどうか知ることはできないです。よって、toggleボタンがバグって思うように操作できなくなってしまいます。

Remoのアプリから操作すればこの問題は解決できますが、他のスマートデバイスGoogle Homeに紐づけていたので、これだけやらないという選択肢は取りたくありませんでした。よって、今回の引っ越しを機に、シーリングライトそのものをスマートデバイスに変えることにしました。Remoはエアコン専用として今後も使っていきます。外出先から帰宅する時に遠隔で予めエアコンをつけられるだけで価値があります。

Google Nest Mini

スマートスピーカーです。旧型のGoogle Homeを持っている人にGoogleが無償でプレゼントしてくれました。

store.google.com

このスピーカーを通して、音声によりシーリングライトやエアコンを操作していました。病気で身体が動かせなくなったときに、音声入力や音声操作のありがたみをとても感じたのがきっかけで、こういったスマートデバイスを愛用しています。また、目覚まし時計の代わりにもなっています。

買ったもの

スマートシーリングライト

¥13,980- (6,990x2)

ニトリのスマートシーリングライト「ネクト」を2台購入しました。リモコンも付いていて便利。

www.nitori-net.jp *1

6畳用を購入したのですが最大輝度でも若干暗い気がしました。部屋は明るければ明るいほど良いと思っているので、8畳用にすればよかったです。

なぜスマートライトにしたかったかというと、18畳の部屋の片隅にスイッチがあり、わざわざ押しにいってON/OFFを切り替えるのが大変だからです。部屋のどこにいても、OK Googleと呼びかけることでシーリングライトをつけ消しできます。

スマートスポットライト

¥28,664- (10,780x2+ダクトレール7,104)

スマートスポットライトを4つ(2つセットを2組)購入しました。ダクトレールにつけるタイプの製品です。部屋に3箇所ローゼットがあったのですが、全部普通のライトだと面白くないので、1箇所はスポットライトにすることにしました。引掛ローゼットに取り付けられるタイプのダクトレールも合わせて購入しました。

ON/OFFはもちろん、明るさや色温度まで制御できます。ただ、最小の明るさでもそれなりに明るくなるので、就寝時の照明としては使えなさそうでした。

半分は寝室エリア照明、半分はリビングエリア照明

ネットが繋がるまでの繋ぎとしてリモコンも買ったんですが対応機種を確認し忘れていました。こちらは上位機種のみの対応のようです。

Google Nest Hub

¥11,000-

前述の通りNest miniを持っているのですが、スマートデバイスを手で操作したいこともあるため、画面付きのNest Hub (第2世代)を購入しました。

store.google.com

買ったちょっと後に、GWのセールで1台買うともう1台もらえるというキャンペーンが開催されました。ちょっと損した気分になっています。

スマートキー

¥12,580- (7,377+アダプタ600+WiFiモジュール4,603)

僕は物理の鍵をよく失くすので、スマートフォンなどで鍵の開け閉めができるスマートキーは必須でした。いくつか種類がある中選んだのはSesame 4です。その理由は、他の製品に比べて安いことと、そのままでは非対応な鍵にも3Dプリンタでアダプタを作ってくれることです。実際、僕の家のサムターンには変な土台がついていてうまく取り付けられませんでした。採寸してメールしたら、1週間ぐらいでアダプタを送ってくれました。

今のところ問題なく使えています。GPSで自動解閉錠などの機能もあるようですが、うまく動作するか疑問なのでまだ利用していません。

まとめ

項目 単価 個数 小計
スマートシーリングライト 6,990 2 13,980
スマートスポットライト2個セット 10,780 2set 21,560
ダクトレール 7,104 1 7,104
Google Nest Hub 11,000 1 11,000
スマートキー 12,580 1式 17,927
合計 71,571

IoT大好き人間なので一通り揃えて快適空間になりました。スマートスポットライトは若干高価でしたが、部屋の雰囲気を良い感じにしてくれて、買ってよかったなと思います。

本シリーズも次でいよいよ最終回です。軽く物件を紹介しつつ、トータル費用を計算しようと思います。

*1:余談ですが、ニトリのサイトへのリンク、うまく動かないことがありますよね。製品ページではなくトップページに飛んでしまう場合、もう一度リンクを押すと製品ページに飛べると思います。

SlackのチャンネルURLに関する実験

Slackのチャンネルにリンクを貼りたいと思ったことはありませんか?僕はあります。

以下のようにチャンネルメニューを開いて「リンクをコピー」を選択することで、チャンネルのURLを取得することができるんですね。

チャンネルURLは https://{your_workspace_name}.slack.com/archives/{channel_id} のような形で得られます。例えば、 https://example.slack.com/archives/C03CFUDH2MU のような感じですね。IDの部分はランダムな英数字が入っているので、URLだけ見てもどのチャンネルへのリンクか分かりません。

実は、これ以外のURLでもチャンネルへのリンクを実現することができます。 https://{your_workspace_name}.slack.com/archives/{channel_name} のように、IDが入っていた部分にそのままチャンネル名を入れてあげればOKです。#random チャンネルなら https://example.slack.com/archives/random といった具合ですね。チャンネル名を変えてしまったときにリンク切れになってしまいますが、IDのものよりは分かりやすいURLが得られました。

ここまでの話を読んで、気になることはありませんか?

そうです。channel IDと同名のチャンネルが存在する場合どうなるんでしょうか。channel idが入る場合もチャンネル名が入る場合もURLの構造がまるっきり同じなんですよね。

実際にやってみた

結論を言うと、Slackのチャンネル名には大文字の英字は利用できませんでした。大文字を入力しようとしても無理やり小文字に直されます。この制約によって、URLのパスに含まれる文字列がchannel IDなのかそれともチャンネル名なのか区別できるという訳ですね。

自由研究のために乗換案内をスクレイピングしようとしたら法律の勉強をすることになった話

PR & Introduction

こんにちは。id:arthur-1です。GWいかがお過ごしでしょうか。まずはPRから。

hatenacorp.jp

株式会社はてなが2022年5月1日付でフレキシブルワークスタイル制度をアップデートしました。その1要素として、居住地に関する制限が全国に拡大します。

社員・契約社員の居住地条件を「日本全国」(※)

出社時に飛行機や新幹線を含む公共交通機関を利用した際の交通費は毎月5万円を上限に実費支給

※ 居住地は「要請があった場合、所属オフィス(京都・東京)にAM11時に出社できることを目安とする」などの条件あり

と言われて、では実際どこに住めるのか、気になりませんか?気になりますよね?

住みたい場所が決まっている人は良いのですが、この条件を満たす良い住処はないかなあと思っている人の選択肢を提示できるサービスがあったら素敵だなと思いました。今回のエントリは、GWの自由研究として「11時までに出社できる到達圏マップ」を作ろうとして挫折したという話になります。

先行研究の調査

Twitterで「●●大学1限マップ」なる画像ツイートを見たことはありませんか?各大学の地理に詳しい方々がこのように地図を公開して、大きな反響を呼んでいます。イメージとしてはこれをプログラミングによって機械的に作りたいんですよね。

しかし、僕は残念ながら地理オタクではないので、これを行うのに必要な情報をどうやって得るかという知見がありません。当然時刻表の分厚い冊子を買ったこともありません。日本全国の鉄道・空路全てを網羅して自分で調査するのは困難で、手作業で情報を集めると考慮抜けが発生してしまうことが想定されます。そこで、各社が提供しているオープンAPIにアクセスして、必要な情報(11時にオフィスに到着できる出発駅のリスト)を機械的に集めようという方針を立てました。

Open API

地図アプリの代表と言えばGoogle Mapだと思いますが、最近のGoogle Mapはアプリ内で公共交通機関を含んだ経路検索ができて便利ですよね。つまり、Googleは情報を持っていて、それをAPIとして提供しているのではないかと考えました。調査したところ、Google Maps PlatformのDirection APIによって、情報を取得できそうでした。

ところが、FAQにこんなことが書いてありました。

Directions API と Distance Matrix API は、日本を除くすべての国の Google 乗換案内パートナーをサポートしています。

ということで残念ながら振り出しに。

他社が提供している個人で使えそうな乗換案内系のOpen APIも調査しましたが、いずれも日時まで指定しての時刻表のデータを考慮した経路検索はできないようでした。

ちなみに、NAVITIME APIのReachableというサービスを利用すると、到達圏検索ができるので今回やりたいようなことに近いことができます。ただし、時刻表180分より長い時間を設定できない上に、出発時間/到着時間も設定できないので見送りました。これはこれでおもしろそう。

rapidapi.com

qiita.com

乗換案内サービスの利用規約

仕方ないので、各種乗り換え案内サービスにpuppeteerでスクレイピングして全駅分情報を取得するか、という気持ちになりました。とてもnaiveですが、日本中の各駅・バス停などを出発地、オフィスを到着地として、到着時刻を11:00に設定して経路検索をすれば、出発日時を見ることで出社可能か否かが分かりますよね。

あれ、でもこれって利用規約的にOKなんだっけ?と頭をよぎりました。先程のOpen APIがちゃんとした経路検索の機能を提供していないことも踏まえると、ダメそうな予感がします。

Yahoo! 路線情報

Yahoo!路線情報ヘルプ

路線に掲載されている情報は、情報提供元との契約により配信されているものです。そのため、情報や画面の二次利用は基本的に不可となります。

無理そう。

NAVITIME

利用規約 | NAVITIME

お客様は、本サービス及び本サービスで使用されているソフトウェア、ドキュメント、データ、画像、キャラクター、ロゴ等につき、次に定めることを行ってはなりません。

(3) 複製、頒布、公衆送信、改変、翻訳、翻案又は二次的著作物の作成をすること

翻案ってなんだろう?あと二次的著作物には該当するのだろうか。

駅すぱあと for web

利用規約 | 駅すぱあと for web

お客様は本サービスの利用に関して、次の各号に定める行為を行わないものとします。

(2)当社若しくは第三者の商標権、著作権等の知的財産権その他一切の権利を侵害する行為、又は侵害するおそれのある行為

直接的にNGであるとする表現はなかったけれど、ここに引っかかる可能性があるのかな?

ジョルダン

サイトのご利用にあたって|乗換案内ヘルプ|ジョルダン

当サイトに関する著作権を含む一切の知的財産権等の権利は、当社又は当社に対して使用許諾を行っている情報提供者に帰属します。 当サイトの内容を無断転載・複写・修正・改変し、または第三者に譲渡することを禁じます。

直接的にNGであるとする表現はなかったけれど、ここに引っかかる可能性があるのかな?

ekitan

利用規約 - 駅探

(1) 本サービスに関する一切の権利は、当社および知的財産権を有する当社へのライセンサに帰属します。本サービスの内容を無断で転載・複写・修正・改変・蓄積・転送し、または第三者に譲渡することを禁じます。

(2) 当社は、JR各社、電鉄各社およびその指定機関等から直接、時刻表ダイヤグラムを含むデータを購入し、その利用許諾を得て本サービスを提供しております。お客様は、有償無償・利用形態の如何に拘わらず、当社の許可なく当該データを加工・再利用・再配布・販売することはできません。

無理そう。

スクレイピングと法律と利用規約

実はこれまで個人的にいろんなデータをスクレイピングして解析して遊んできていましたが、不安ではあったんですよね。そこで、法的根拠についてちゃんと調べてみることにしました。

以下のページが丁寧な説明で参考になりました。

sugiaki1989.gitbook.io

topcourt-law.com

また、以下のページでは総務省スクレイピングを可能としている根拠を紹介していました。*1

self-development.info

調べてわかったことをまとめると、

  • データ分析目的なら法的には大丈夫 (知らなかった)
  • robots.txtを確認しよう (知ってた)
  • 利用規約を確認しよう (知ってた)
    • でも、使う前に同意を求められなければ大丈夫かも (知らなかった)
  • たくさんアクセスをしてサーバ落としたりすると偽計業務妨害罪になるかも (知ってた)

といったところです。ただ「ダメそう」という雰囲気ではなく、法的にアウトか(刑事訴訟されるかも)、サービスの利用規約としてアウトか(BANされる・民事訴訟されるかも)という切り分けも大事かもしれません。もっとも、僕は後者なら破っても良いかと思う人間ではないですが。

ここまで調べているうちに、僕がしたかったのは法律の勉強じゃない!と思い、調査に時間がかかったのもあって熱が冷めてしまいました。

思ったこと

まずは1クリエイターとして、いろいろな情報が一定の秩序が守られた上で自由に使える世界にもっとなって欲しいと思いました。多量のデータから機械学習を行うdeep learningが様々な領域に応用されて久しいですね。自分が提供するサービスではきちんとルールを定め、個人情報保護などを考慮しつついろんな情報を利用しやすい形で提供できるよう心がけたいです。

もちろん、連絡をすればOKをもらえるかも、という考えもありますよね。(実際、これまで個人で提供してきたサービスも、関係者と直接連絡を取って許可をいただいたものがいくつかあります。)でも、僕はチキンなので、そこまでの労力をかけて提供しようと思えない限りは諦めてしまいます。他にもやりたいことはいくらでもあるので。

この件に限らず、例えばUGC(User Generated Contents)においては、ユーザが投稿した内容が法律に触れていないかという問題もありますね。このように、ものづくりの技術だけでは作ったものを合法的に提供することができません。企業は法務部や顧問弁護士を抱えていますが、個人のクリエイターが同じことをするのは難しいですよね。自分が全知全能になるか、外注するしかないと思いました。全知全能を目指す方向性はスケールしないことが明らかで厳しいですね。やはり同じ志を持つ仲間を見つけてカバーする専門領域を拡大していくのが大事かもしれないです。

という感想を書き綴ったところでGWの自由研究発表を終わります。他にも自由研究ネタはいくつかあるけどpublicにはしないと思います。

*1:以下のページでは全く触れられていませんが、総務省は各サービス提供者から事前承諾を得ています。諸外国の事例も載っていて参考になるので元の資料(https://www.soumu.go.jp/main_sosiki/kenkyu/big_data/02toukatsu01_04000328.html の資料1)を参照推奨です。