LoginSignup
3
1

More than 5 years have passed since last update.

AtCoder Color Markという円を表示する拡張機能を作った話

Last updated at Posted at 2018-12-17

はじめに

これは、AtCoder関連サービス Advent Calendar 2018の18日目の記事です。今年作ったAtCoder向けのChrome拡張について書きます。

この拡張へのリンクはこちら。何かあったらフィードバックをもらえるとありがたいです。
※ 追記: この記事を公開した日にAtCoderのURLに変更が行われ、一時的にこの拡張が動かなくなってました。

機能

概要

  • コンテストの順位表のそれぞれの名前の右にレーティングの円を表示
    • こんなかんじ
  • プロフィールの過去の参加コンテストのページにレーティングの円を表示(beta版のみ)
    • こんなかんじ

どうして作ったのか

  • 自分の前後のレーティングを見たい
  • 過去のパフォーマンスがどの色のどのレベルなのか分かりやすくしたい

どうやって実現しているか

Chrome拡張部分

Chrome拡張とは

Chrome拡張は個人で書いて公開1することができ、それをインストールすることでChromeに機能を追加することができます。この拡張機能の様なDOMの操作だけでは無く、クライアントJSではできないようなChromeの用意しているAPIを利用した機能も実装できます。逆に、拡張機能のメニューが必要な場合は自作が必要になります。そして、Chromeで動けば良いため、ES6なども問題なく使用することができます。
公開方法としては、Tampermonkeyという拡張機能のスクリプトとして公開することもできます。こちらはユーザ登録派不要です。

manifest.json

"https://*.contest.atcoder.jp/*", 
"http://*.contest.atcoder.jp/*",       
"https://beta.atcoder.jp/contests/*",     
"https://beta.atcoder.jp/users/*/history"

上記の4つのドメインを対象にしてます。betaの方がドメインが統一されていてloclstorageとか共有できて嬉しいです。
上記のページに対してCSS,JSを一個ずつ挿入してます。

表示部分

レーティングの円の表示はcanvas要素の挿入によって実現してます(canvasなのでinnerTextには無影響なはずなので、他の拡張に影響はおそらく無いはず)。表示内容はおそらくTopCoderと同じようになるようにレーティングの色2とその色の最大値と最小値を100%、0%にしたときにどの位置になるかを円で表しています。
要素
完成図
canvasの円は上の3つの要素を組み合わせて描写しています。上の例は40%の場合の例で、まず左の円と真ん中の長方形の共通部分のみ描写します(source-in)。そうすると円の中身の部分だけ作れるので、それに右の円の輪郭を足し合わせるとTopCoderみたいな円が完成します。

取得部分

順位表にはユーザのレーティングは載っていないため、円を表示するにはそれを取得する必要があります。そのため、localstorageを確認して最新のデータが無かった場合に自前のサーバにレーティングのJSONを取得しに行っています。取得したJSONはlocalstorage3に取得時刻とともに記録し、無駄にデータを取ってこないようにしています(Chromeはサーバ側のキャッシュ用ヘッダを無視して取得しているように見える)。具体的には15分キャッシュします。
beta版を使用していない場合、コンテストごとにドメインが異なるのでlocalstorageにJSONがそれぞれ溜まってしまうという弊害はあります。
ユーザのコンテスト成績のページについてはレーティング値がページ内にあるのでそれを取得して表示しているだけでデータの取得・保存はしていません。

バックエンド部分

クライアント側でAtCoderのユーザページのJSONをたたくのも可能ですが、AtCoderとクライアント両方の負荷の負荷軽減のため自前のサーバでJSONを配布してます。
JSONは30分に一回AtCoderのランキングページをスクレイピングしてJSONを生成しています。ライブラリはjsdomを利用してます。
手順は以下のとおり、
1. ランキングページにアクセス
2. ページャの右端からページ数を取得
3. 各ページのテーブルの特定列からユーザとレーティングの関係を取得
4. JSONにして保存

TODO

  • beta版以外での無効化(JSONがかなり溜まるため)
  • JSON取得・保存をサーバレス化する

  1. Chrome拡張はChromeウェブストアから公開できますが、5ドルが最初に必要になります 

  2. レーティングの色の分布はここを参考にしました。 

  3. cookieは容量が小さすぎて入らないため 

3
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
3
1