背景
AtCoderでは、ログイン時にキャプチャ認証が要求されるようになったためかCLIツールでのログイン提出ができなっているようだが、ブラウザのクッキー情報を以下のjsonlに与えればコンテスト中は提出ができるようだ。
- Linux: ~/.local/share/cargo-compete/cookies.jsonl
- macOS: ~/Library/Application Support/cargo-compete/cookies.jsonl
- Windows: %APPDATA%\cargo-compete\cookies.jsonl
作ったもの
#!/path/to/yt-dlp/bin/python
# accc.py
import sys
from yt_dlp.cookies import extract_cookies_from_browser,YDLLogger
from datetime import datetime,timezone
import json
import os
import pathlib
def get_cookie(browser):
jar =extract_cookies_from_browser(browser,logger=YDLLogger())
for c in jar:
if ("atcoder.jp"==c.domain)&("REVEL_SESSION"==c.name):
line={
"raw_cookie":f"{c.name}={c.value}; HttpOnly; Secure",
"path":[c.path,bool(c.path_specified)],
"domain":{"HostOnly":c.domain},
}
if c.expires is not None:
line["expires"]={"AtUtc":datetime.fromtimestamp(c.expires,tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")}
return json.dumps(line)
raise RuntimeError(f"No cookie in {browser}")
def cargo_compete_cookie_path():
if sys.platform.startswith("linux"):
base = os.environ.get("XDG_DATA_HOME", pathlib.Path.home() / ".local" / "share")
return pathlib.Path(base) / "cargo-compete" / "cookies.jsonl"
if sys.platform == "darwin":
return pathlib.Path.home() / "Library" / "Application Support" / "cargo-compete" /"cookies.jsonl"
if os.name == "nt":
appdata = os.environ.get("APPDATA", pathlib.Path.home() / "AppData" / "Roaming")
return pathlib.Path(appdata) / "cargo-compete" / "cookies.jsonl"
raise RuntimeError(f"Unsupported platform: {sys.platform}")
def main():
if len(sys.argv)<2:
raise SystemExit("Usage: accc.py <browser-name>\nSupported browsers: brave, chrome, chromium, edge, firefox, opera, safari, vivaldi, whale")
browser=sys.argv[1]
cargo_path=cargo_compete_cookie_path()
cargo_path.parent.mkdir(parents=True,exist_ok=True)
cargo_path.write_text(get_cookie(browser)+"\n",encoding="utf-8")
main()
使い方
- シェバンはyt-dlpの入ってるpythonにかえる。
- ブラウザでAtcoderにログインする。
- 以下を実行
./accc.py firefox
これでブラウザのクッキーがCLIに与えられてコンテスト中だけであるが提出が可能になる。
yt-dlp的には以下のブラウザに対応してると思われる。
- brave
- chrome
- chromium
- edge
- firefox
- opera
- safari
- vivaldi
- whale
蛇足
firefox ならクッキー暗号化されてないのでcookies.sqliteをどこかにコピーして以下を実行すればsqliteだけでREVEL_SESSIONを取得可能である。
sqlite3 cookies.sqlite "SELECT value FROM moz_cookies WHERE host='atcoder.jp' AND name='REVEL_SESSION' ORDER BY lastAccessed DESC LIMIT 1;"
列名
sqlite3 cookies.sqlite "PRAGMA table_info(moz_cookies)"
0|id|INTEGER|0||1
1|originAttributes|TEXT|1|''|0
2|name|TEXT|0||0
3|value|TEXT|0||0
4|host|TEXT|0||0
5|path|TEXT|0||0
6|expiry|INTEGER|0||0
7|lastAccessed|INTEGER|0||0
8|creationTime|INTEGER|0||0
9|isSecure|INTEGER|0||0
10|isHttpOnly|INTEGER|0||0
11|inBrowserElement|INTEGER|0|0|0
12|sameSite|INTEGER|0|0|0
13|schemeMap|INTEGER|0|0|0
14|isPartitionedAttributeSet|INTEGER|0|0|0
15|updateTime|INTEGER|0||0