1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

AtCoderのバチャカレンダーを作った話

Posted at

※ バチャ、というより非AtCoderの日本語コン、というほうが正いかもしれません。とりあえず、この記事では「バチャ」で進めます。

できたもの

このページを開いて、右下の「+」ボタンを押せば自分のカレンダーに表示されるようになります。

何これ

AtCoder ProblemsおよびMojacoderで開かれているバチャを自動で取得し、カレンダーに追加してくれます。

AtCoderコンテストカレンダーyukicoderコンテストカレンダーあたりと併用したらいいんじゃないかと思います。

注意点

なんとなく察しがついているかもしれませんが、これを入れるとカレンダーがコンテストで埋まります。非表示設定とかを頑張るか諦めるかしてください。

あと、情報の正確性などは全く保証しません。一部非表示にしているコンテストもあります。(後述)

製作記

発想

今までぼーっと競プロしてきたけど、そろそろ精進もするべきだし、バチャにでも出ようかな〜、でもTwitterの告知見る時には終わってるしな〜、ということで、Googleカレンダーに表示することにしました。

ちょうどTwitterでRustを見かけて、なんか難しそうだけど面白そう、ってことでRustを使いたかったってのもあります。手段の為ならば目的を選ばない、ってやつですね。

製作

まずはコンテストサイトの選定です。とりあえずよくお世話になっているProblemsにバチャ機能があるらしいので、これは表示したいですね。あと、Twitterでよく流れてくるサイトでMojacoderってのがあったので、これもせっかくなので入れておきます。他にも何か良さそうなサイトがあれば教えてください。やる気があったら追加します。

Rustの勉強

なんで全く知らない言語でプロダクト作るんだ、という話は聞きません。ロマンですロマン。

とりあえず、なんか所有権とかいうのがあって、GCを使ってなくて、なぜかメモリ安全なコードが書けるらしい、くらいの認識だったので、公式のチュートリアル(の和訳)を読みました。

途中まで読んで†完全に理解†状態になったので、即プロジェクト作成です。

処理の実装

対象サイトをスクレイピングして、Google CalenderにAPIアクセスを送りつけるCLIになるだろうな、と思ってたので、とりあえずreqwestを使ってProblemsにアクセスを送るコードを書きました。Chromeの開発者ツールを使ってそれっぽいJSONをGETしに行くコードを書きました。で、なんかアクセス拒否されます。

Postmanでアクセスしたら普通に帰ってくるので、ヘッダーかな? と思い、hyperに乗り換えてAccept-Encoding: gzipを追加して送信。とりあえずリクエストは帰ってきました。

でもなんか文字化けするので困ってたんですが、そういえばgzip圧縮ってことよな? と思い、flate2GzDecoderを使って復号してみるとJSONになりました。やったー

Mojacoderは、https://mojacoder.app/_next/data/gFS1O7T42djs1wRKmTHvP/ja/contests.json(もうアクセスできません)という、いかにも更新時にパスが変わりそうなURLのものがあったので、どうしようかな...手動更新は嫌だな...と思ったのですが、コンテストページのHTMLの下の方に、<script id="__NEXT_DATA__" ... >という場所があって、その中身がコンテスト情報だったので、少し汚いやり方ですがここを正規表現で取ってくる事にしました。

次にGoogle APIです。どうやら、

  1. Google Cloud?でアプリ作成
  2. Calender APIを使えるよう登録
  3. API Key的な情報がJSONファイルでもらえるので、それを使ってhttpリクエスト(JWT)
  4. するとOAuthトークンが降りてくるので、実リクエスト時はこれをヘッダーに入れて使う

という感じっぽかったので、色々サイトを調べながら作ってみました。
こことかここがわかりやすかったです。

最後に重複など確認して、まだカレンダーにないコンテストだけ追加して完成です。
ただ、そのまま追加すると、Problemsなどにある超長期コン(2ヶ月くらいのやつとかありますよね)が入ってしまって溢れてしまうので、24時間を超える長さのものや、もう終了したコンテストのことは無視するようにしました。

実行

cronで回すのも面倒だったので、適当にloop {}の中に1時間sleepをかましています。(あまりにひどい...)
あとはこれを持ってるレンタルサーバーの無料枠(クソスペック)に放り込んで実行して完了です。
バックグラウンドで実行してもらうために、screenコマンドで実行しています。

終わりに

一応作ってみたはいいんですが、忙しくて全然参加できる気がしないんですよね...

ていうわけで供養です。誰かの役に立ってくれると嬉しいですね...

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?