クエリパラメータで設定できるペイントツール

黒背景で正方形のイラストをいっぱい描きたいことがあったんだけど、大抵のオンラインペイントツールは白背景で長方形のキャンバスで初期化されるので、毎回キャンバス設定の変更から始めないといけなくて面倒だった。

キャンバスの設定とかをクエリパラメータで指定できたら楽でいいのになと思ったけれど、需要がないのかそういうツールは探しても見つからなかったので、作ろうと思った。

dev.to

↑この記事で React + Canvas でのペイントアプリの作り方が解説されていたので、ほとんどこれを真似させてもらった。

f:id:YaaMaa:20210228232035p:plain

できた。

ここにあります。

?width=400&height=400&initial_pen_color=ffffff&background_color=000000

ってつけると初期状態が正方形・白ペン・黒背景になるので便利。

2020年に聞いた曲

Spotify が、「2020年にあなたがよく聞いた曲ランキング」を出してくれていた。

気に入った曲があったら、暗記するまでは頻繁に聞いて、そのあとはたまにしか聞かないプレイリストに移すという流れで消費している。だから、「よく聞いた曲ランキング」というのは「暗記に時間がかかった曲ランキング」と同じだった。ランキング1位の Want It All も、ラップ部分を覚えるために飽きるほどリピートしたのだった。

2019年末から GitHub Actions で Spotify のプレイリストへの変更を記録し続けていて、ちょうど1年分くらいデータが溜まっているのを思い出したので、それを BigQuery に送って集計した。

暗記にかかった時間(ヶ月)
1 TheFatRat - Rule the World 0.8
2 Ariana Grande - positions 1.0
3 Doja Cat - Say So 1.0
4 Papa Ya - Sunny 1.0
5 Velveteen - Part of the Game 1.0
90 UNIKID - Honey 7.1
91 Chris Coral - Lies (Killrude Remix) 7.1
92 Kadant - Out of My Mind 7.3
93 JPB - New Horizon 7.5
94 ANG - Wherever I Go 9.8

1ヶ月足らずで覚えたのもあれば、知らない単語あとで調べようと思い続けて半年ずっと聞いてた曲もある。

データポータルの community visualizations を使うとガントチャートも作れるので作った。

f:id:YaaMaa:20210125063847p:plain
曲ごとの、見つけてから覚えるまでの期間

規則正しく音楽を見つけてはせっせと聞いて覚えているのがわかる。社会人になったらこんなことする暇なくなりそうと思ってたけど、4月に就職してからも元気よくやっている。

2020年に聞いたお気に入りの曲

でもこんなに恋愛ソングばかり暗記してもしょうがないから、もうちょっと実用的な歌詞を覚えたい。curl コマンドのオプション一覧の歌とかないのかな(毎回忘れる)。

DMM英会話を高級知恵袋として使う

SpotifyのDiscover Weeklyに勧められるがままに音楽を聴いている。お気に入りのやつは歌詞も調べてプチリリで入力したりして楽しんでいる。

たまに、歌詞がネット上で見つからない曲がある。体感だと、popularity(0〜100)が30未満の曲は、あちこち探しても見つからないことが多い。そういう曲は、聴いてても「なんて言ってるかわからん…」とモヤモヤしてしまうし、そのせいで作業用BGMにも使えなくてもったいない。

英語わかる人に聞こうと思っていろいろ試してきたけど、どれもうまくいかなかった。

  • 知恵袋: 回答がつかないまま期限が来て、質問が削除されてしまった。
  • reddit: r/lyrichelpってsubredditを見つけて「まさにこれ!」と思ったけど、過疎っていた。稀にしか回答してもらえなさそう。
  • 英語ができる友達に聞く: HelloTalkで出会ったアメリカの人に2曲聞き取ってもらったけど、聞き取ってLINEに打ち込む作業すごくめんどくさいだろうなと思うと、罪悪感が激しい。

諦めかけていたとき、この記事が話題になってるのを見つけた。

togetter.com

DMM英会話のフリートークのレッスンでは、英語話者と自由に会話ができるらしい。じゃあ歌詞聞き取ってもらえませんかって頼んでもいいんかな…?

調べてみると、これこそ私がほしかったサービスだということがわかってきた。

  • 1日25分間、英語の先生に質問し続けられる
  • お金を払っているので多少面倒なことをお願いするのにも罪悪感が少ない
  • 毎回別の先生を選択することができる(毎回同じ先生にこんなこと頼んだら絶対嫌われると思う)

幸運なことに、初月半額のキャンペーン中だった。それでも3000円かかるけど、1年以上溜め込んでいたモヤモヤを晴らすためならまぁいっかと思ってやってみた。

準備

受講前の準備としては、

  • 歌詞を聞き取ってほしい曲を選ぶ
  • それらのYouTube動画へのリンクをメモ
  • 自分でできるだけ聞き取ったやつを、他人に見せられる程度に整える

の3つをした。

歌詞が不明な曲はこの時点で12曲あって、簡単なものから始めたいので難易度順に並べた。一番簡単そうな Oli Harper の It’s Not You を最初に持っていくことにして、逆に Prefekt の Figure It Out みたいに何言ってるかわからんやつは後回しにした。

受講開始

無料体験を2回できるので、まずはそれを試す。1回目は無難に日本人の先生のレッスンを申し込んだ。

この曲の歌詞が知りたいんですと説明すると、「こういうのは検索語句の問題なんだよね〜」と言いながらググって、それで見つからないことがわかると、次はスマホを取り出して先生がサブスクライブしてるApple Musicで探してくれた。そしたら何とApple Musicには歌詞登録されているのを見つけた。スマホ画面をこっちに向けてスクロールしてもらいながら、英語の先生に妙なことさせてしまって申し訳ない気持ちになった。

目的を達成できたので、あとは音楽とか映画とか普通の雑談をして終わった。「英語の話し方が変だったら教えてください」とも言ったけど、それより持ち込んだトピックが変だと笑われた。でもおもしろかったよと言ってもらえて助かった。

レッスン終了後、自分でもその曲をiTunesで購入してみたけど、歌詞は表示されなかった。アカウントの地域設定のせいかな…。

反省

今回のレッスンではいきなり「歌詞を知りたいんです、聞き取ってもらえませんか」と頼んでしまったが、それだと唐突すぎてびっくりされる。

「私はリスニングスキルを向上させるために、英語の曲の歌詞を聞き取って書く練習をしています。けど答えがネットにない曲があって困っています。なので、私の回答が合っているかどうか見てもらえませんか?」

というふうに英文添削っぽくお願いすれば、そんなに変な話題と思われることもないのではないか。

2回目

無料体験2回目は日本人を指名できないので、ブルガリアの先生を選んだ。

この人もとてもいい人で、経緯を説明すると快諾してくれた。私が Miss Ghyss の Drop the Mic を聞き取ったのを添削用の欄に貼り付けて、そこから正しい歌詞に書き直していってもらった。「ここは自信ない」って言ってたところも一つだけあったけど、全体的に納得感のある答えを出してもらえて、すごくすっきりした。さらに、歌詞にイディオムが出てくるたびに「これの意味わかる?」と確認を入れてくれた。

けど曲のフルバージョンは先生の地域では視聴できないようで、途中までとなった(諦めるまでにもいろいろ試してくれてありがたかった)。

反省

こういう頼みごとがあるなら、レッスン予約するときのメッセージ欄に書いておいた方がいいよと言われた。次からそうする。

3回目

今回から有料プラン開始。セルビアの先生のレッスンを予約した。

ZOLA の No Words という曲をお願いすると、そんなにテンション高くはないけど普通に「いいよ」という感じで始めてくれた。今回も私のを添削する形式でやってもらった。先生にも聞き取れないところもあったけど、繰り返し聞いたり0.5倍速再生したりして、めっちゃ粘ってくれてありがたかった。「うーんこの部分は無理やわ」って言ってちょっと雑談始めて、思い出したように「やっぱもうちょっと聞けばいける気がする」って動画に戻って行ったりしていた。私がわからないところは8箇所あったけど、先生はそのうち6箇所を埋めてくれた。


まだ3回目だけど、疑問がどんどん解消していってて感動的。無料で使える知恵袋やredditに比べるともちろん高いけど、英語堪能かつ親切な人に時間を割いてもらえるし、何らかの答えを返してくれる保証もあるので、お金をかけてよかった。月3000円は初月だけなので、それが終わったらやめるけど。

プログラミングをすると変な夢を見る

しばらくプログラミングをした後に勢いよく寝ると、現実でやってたことや考えてたことの続きみたいな不思議な夢を見ることがある。変数が食べ物になったり自分がDBのレコードだったりしておもしろい。

いくらの寿司

isLoading というbooleanの変数を作っていた。(ここまで現実)その言語のboolean型はいくらの寿司で、いくらをシャリのどちらの端に固めるかによって、スイッチのようにtrue/falseを表現するようになっていた。いくらの場所が中途半端だったら、trueなのかfalseなのかわかりにくくて困るだろうなと思った。

f:id:YaaMaa:20201222205843p:plain

Señorita

Shawn MendesのSeñoritaを脳内で再生していた。(ここまで現実)サビの「You keep me coming for ya」というところで、二人称が2回出てくるのは冗長だから、コードレビューで指摘される前に直しておこうと思った。2回目の二人称を $_ みたいな特殊変数に置き換えられないだろうかと考えた。

イライラ棒

イライラ棒のようなゲームをやっていた。ゲームのフィールドはCloudFormationのテンプレートで、一つ一つの障害物がAWSのリソースだった。障害物にぶつかるとリソース定義同士がくっついてmalformed JSONとなり、本番で稼働しているアプリケーションが壊れてしまうので、緊張感があった。

ギャル

updated_at という変数があった。(ここまで現実)語と語の間にこのような伸ばし棒を入れるのはギャルの特徴的な話し方なので、うちの会社にもギャルのエンジニアがいたんだな、と新鮮な気持ちになった。

元気でね

友人との別れ際に、友人が「元気でね!」と声をかけてくれたのだが、それと同時に私のDBレコードのJSON型カラムに{ "status": "元気" }みたいなプロパティを押し込んできた。気持ちはありがたいけど、自分の状態は自分で決めたいので、勝手に状態を定義されて少し困惑した。


プログラマーとして働いているとこういう夢を見るのが普通なのかな。職場の人も家がHTMLになって苦しむ夢を見たという記事を書いていた。

AWS認定試験の受験失敗とAWSしりとり

本記事は、はてなエンジニア Advent Calendar 2020 の17日目の記事です。昨日は id:papix さんでした。

papix.hatenablog.com


AWSの資格試験を受けようとして失敗した話と、その副産物であるAWSしりとりについて書きます。

AWS認定資格試験の、Solutions Architect Associateを受験しようとしていました。受験には試験会場まで行く方法と自宅でオンラインで受ける方法があり、出かけるのが面倒だった私はピアソンVUEのオンライン受験を予約しました。

PCの要件は満たしていてシステムチェックも通ったけど、実際受けたら失敗したので、その体験談です。

1回目

監督者の方とチャットが繋がり、「それでは試験を送ります」と連絡をもらったところまでは順調でした。

試験案内のページに移り、チャットで「ページは切り替わりましたか?」と確認されましたが、文字を入力しようとすると虹色がくるくる回り出し、一文字入力するのに5秒くらいかかるようになってしまいました。それに気づかぬまま十数文字ほどタイプしてしまっていたため、その入力がゆっくりと処理されていくのをひたすら見守ることしかできません。

返答がないことで異常に気づいたのか、監督者が2人に増え、様子を尋ねてくれました。私は質問に少しでも早く返事をするために、タイプ数を節約して「hai」「no」などと返答していましたが、それでも監督者が次の質問を被せてくる方が早くて、会話が全く成り立ちませんでした。もはや紙にメッセージを書いてカメラに見せた方が早いと思ったけど、試験中は机の上に物を置けないので無理でした。

結局、質問を全部無視して「trouble」と送ったところ、「パソコンを再起動してみてください」と案内してもらえたので、再起動しました。

2回目

再起動してもう一度チェックインをやり直すと、無事チャットが繋がり、「さっきはすみません、再度チェックインできました」「よかったです」などとやりとりをすることができました。直後にチャット欄が消え、「試験が開始されるまでお待ちください」という案内だけが残されました。

何か試験開始の条件を満たしていないのだろうかと思って確認すると、OnVUE(受験のためのアプリケーション)以外の全てのアプリケーションを閉じないといけないところがChromeだけ残っていました。しかも応答なし状態になっていて、強制終了しても終了する気配がありません。今回はチャット欄がないためトラブルを伝えることもできず、独断でパソコンを再起動しました。

3回目

今回も一瞬チャットが繋がりましたが、すぐに消えてしまい、「試験が開始されるまでお待ちください」のまま進まない状態となりました。それでも1時間は粘ろうと思ってじっと待っていましたが、カメラから離れると失格とされる可能性があるし、他のアプリケーションも開けず、机の上にはなにもなくて、ただただ虚無の時間でした。頭の中でAWSしりとりをするなどして時間をつぶしました。

1時間経っても変化がなかったので、OnVUEを強制終了し、諦めることとしました。

その後サポートの方とメールでやりとりして、今回の試験結果の取り消しなど対応していただけました。

原因

後から調べてみると、Karabiner-Elementsが原因でOnVUEを使った受験に失敗することがあるそうです。私もKarabiner-Elementsを使っているので、これが原因だったのかもしれません。

dev.classmethod.jp


この体験談を社内で共有したところ、私が待ち時間にやっていたという「AWSしりとり」とは?という話になりました。

AWSしりとりとは、AWSに関連する用語(主にサービス名)を使ったしりとりです。

f:id:YaaMaa:20201209084154p:plain
一歩も前に進まないしりとりの様子

サービス名に使われるアルファベットは偏っていることもあり、なかなかうまく続けられませんでした。せっかくなのでもっと長いしりとりを作りたいと思い、「最長しりとりを組合せ最適で解く」のコメント欄の方法を試してみました*1

手順を以下に書きます。

1. 文字をノード、単語をエッジとするグラフを作る

使える単語を全部使って、文字をノード、単語をエッジとするグラフを作ります。例を挙げると、

f:id:YaaMaa:20201216013305p:plain

こういう感じです。

実際にAWSのサービス名(AWSのプロダクト一覧glossaryから取った)でやってみると、こうなります。

f:id:YaaMaa:20201212231711p:plain
サービス名も表示すると見づらくなったので省略

このグラフからは、「Cで始まるサービス名が多い」「Rで終わるサービス名が多い」などの特徴が読み取れます。

f:id:YaaMaa:20201212231759p:plainf:id:YaaMaa:20201212231817p:plain
Cからは出ていく矢印が多く(Cloud○○とか)、Rには入っていく矢印が多い(○○erとか)

さらに、startノードとendノードを作ります。AWSしりとりは「AWS」の「S」から始めたいので、startノードは「S」ノードにのみ繋ぎます。どこでしりとりが終わってもいいように、endノードは他の全ての文字ノードと繋ぎます。

2. 解きたい問題を定義する

しりとりの長さを最大化するということは、以下の問題を解くのと同義です。

  • 上のグラフで、startノードからendノードまでを辿る
  • エッジはそれぞれ最大1回ずつ通れる
  • なるべく多くのエッジを通りたい

上記の条件をコードで定義しやすいように、以下のようなテーブルを作ります。

f:id:YaaMaa:20201218213521p:plain

すると、解きたい問題は

  • それぞれのエッジを通るかどうかを 0 か 1 で表す
  • startから出るエッジ、endに入るエッジはそれぞれ1本ずつ通る
  • 通ることになったエッジの中では、fromノードとtoノードの文字の種類と数が一致しなければならない(startとend以外)
    • 例えば、「A」から出るエッジを2回通るなら、「A」に入るエッジも2回通らなければならない
  • エッジを通るかどうかの値の合計(テーブルの水色の部分の合計)をなるべく大きくする

という条件の下でそれぞれのエッジを通るかどうかを決める(テーブルの水色の部分の値を決める)ということになります*2

3. 最適化問題として解いてもらう

いろいろ制約がある中で、ある値を最大・最小にするにはどうすればいいかというのを考えるのは、最適化問題と呼ばれています。その中でも線形計画問題は、PuLPというPythonライブラリで扱うのが定番のようです。PuLPを使って上記の問題を定義し、ソルバーに解いてもらうことで、どのエッジを通ると経路を長くできるのかを求めることができました。

4. 解答からルートを組み立てる

最適化問題を解いて、それぞれのエッジを通るか否かは決まりましたが、通る順番までは決まっていません。

どのように経路を求めるかというと、使うことに決まったエッジのみを使ってグラフを作り、startノードとendノードも繋いでから、startノードを起点とするオイラー閉路を求めます*3networkxのeulerian_circuit()などが使えます。

こうして、73個のサービス名を使ったAWSしりとりを作ることができました。


AWS → SESSNSSQSStep FunctionsSWFFreeRTOSShieldDirect ConnectTimestreamMQQuickSightTextractTrusted AdvisorRoboMakerRAMManaged BlockchainNetwork FirewallLightsailLambdaAppFlowWAMMacieECRRekognitionNeptuneEBSSnowmobileEKSSnowconeECSSnowballLumberyardDataSyncConfigGovCloudDeepLensSumerianNLBBraketTranscribeElastic BeanstalkKinesis Video StreamsSecrets ManagerRDSSystems ManagerRedshiftTranslateElastic InferenceElastiCacheEventBridgeElasticsearch ServiceELBBatchHoneycodeEFSSecurity HubBackupPrivateLinkKendraA2CCloud MapPanoramaA2IInferentiaAuroraAthenaAppSyncCognitoOrganizationsSSOOutpostsSageMakerRoute 53


意外とまともなしりとりができてしまった。

EBS → Snowmobile → EKS → Snowcone → ECS → Snowball

このあたり、リズム感があって好きです。

話が逸れてしまいましたが、Solutions Architect Associateの試験を受けたかったのでした。近いうちに再挑戦しようと思います。

アドベントカレンダーの明日の担当は id:onk さんです。

onk.hatenablog.jp

*1:調べてみて初めて知ったけど、最長しりとり問題はかなり昔からある話題で、最長しりとりを作ってくれるwebサイトもあります。この記事で自分で実装することにしたのは、始める文字縛りやグラフの可視化など、追加でやりたいことがあったからです。

*2:厳密には、この条件だけではstartからendまで一筆で辿れる保証はありません。下の非連結グラフについての注釈参照。

*3:非連結グラフになってしまった場合(飛び地ができてしまった場合)はそのままではオイラー閉路を求められませんが、そのときの対処法も参考記事のコメント欄に書いてくれてあります。その解よりも長いしりとりを探しに行きたい場合はこの記事のような工夫をする必要があるようです。

アイコン変えた

旧アイコンはこれだった↓

f:id:YaaMaa:20191014021508p:plainf:id:YaaMaa:20191122021647p:plain

服部平次が好きなので*1、服部の肌の色をアニメや映画から6色取って並べたアイコン。

でも以下の点が気に入ってなかった。

  • 色のチョイス

    特に明確な基準もなく、手元にあった服部の色から6色を「なんとなく」で選んだ。

  • 描き方

    GIMPでラスター画像として作ったので、拡大/縮小でぼやけてしまう。おまけに、角度とかは目分量で描いたので、歪んでるように見えてもやもやする。

もともとはTwitterの閲覧用アカウントのためのアイコンとして作ったので、めっちゃ適当だったけど、今のバイト先でも流れでこのアイコン使ってるし、来年の4月からの就職先でもずっと使い続けそうなので、もうちょっと整えようと思った。何らかの基準をもって色を選びたいし、ちゃんと座標を計算してパスを描きたい。

配色

服部の肌の色の豊富さに感動して作ったアイコンなので、今回もいろんな色をまんべんなく選びたい。

どうやったら偏りなく色を選べるのかな、と調べてたら、カラーパレットを生成するI Want Hueとかこの記事ではk-meansクラスタリングが使われていた。

候補の色を全部CIE L*a*b*に変換して、そこからk-meansクラスタリングをすることで、人間の視覚的に「近い」色同士を集めてk個のグループに分けることができる。それぞれのグループから一色ずつ選ぶことで、選ばれた色同士は互いにある程度離れていることが保証できるから、バランスの良い配色が作れる、ということらしい。

以前に服部の色データベースを作ってあったので、そこに保存されている色を使う。色一覧をCIE L*a*b*空間にプロットしたらこうなった:

f:id:YaaMaa:20191013063734p:plain

それをクラスタリングして6つに分けたところ↓

f:id:YaaMaa:20191013061649p:plain

(彩度が低すぎる色は除外した)

服部の色を取るときはなるべく特徴的な色になってるシーンを選ぶようにしてたけど、やっぱり並べてみると無難な茶色が多い。最近の服部は、RGB (182, 134, 99)くらいに落ち着きがちなイメージがある。

グループから一色を選ぶには、グループ内の要素の平均値を取るって方法もあるけど、今回は複数の服部を平均した色が欲しいわけではないので、それぞれのグループの中心から一番近い要素を選ぶことにした。

少年サンデー2017年1号 表紙
甲子園の奇跡! 見えない悪魔に負けず嫌い
第479話 服部平次との3日間 2
第523話 本当に聞きたいコト
第291話 孤島の姫と龍宮城 事件編
第326話 炎の中に赤い馬 捜査編

こんな配色になった。

SVGで描く

色が決まったので、SVGで形を描いていく。上でクラスタリングとかするのにPython使ったので、SVG書くのもPythonでやることにした。

svgwriteっていうSVG作成に特化したPythonライブラリもあるけど、既にdeprecatedになってるattributeを入れてきたりするので、今回のようにシンプルなことをするだけなら標準ライブラリのElementTreeでXMLとして作った方が簡単そう。

左上の部分だけarcとlineで<path>を書いて、それを<defs>で定義しておけば、他の部分は<use>+transform:rotateをするだけで使える。

f:id:YaaMaa:20191207042300p:plain

SVGマークアップにコメント入れられるので便利。以前のPNGアイコンでは、どの部分がどの服部に対応するかを別ファイルにメモっておかなければいけなかったけど、SVGなら個々のパスの上に「これはあそこの服部だよ」ってコメントしておける。こんな感じで↓

<svg ...>
  <defs>
    <path id="seg" d="..." />
  </defs>

  <!-- 第479話 服部平次との3日間 2 -->
  <use xlink:href="#seg" transform="rotate(0 50 50)" fill="#b8835e" />

  <!-- 少年サンデー2017年1号 表紙 -->
  <use xlink:href="#seg" transform="rotate(60 50 50)" fill="#fbc15c" />

  <!-- 第523話 本当に聞きたいコト -->
  <use xlink:href="#seg" transform="rotate(120 50 50)" fill="#937053" />

  <!-- 第291話 孤島の姫と龍宮城 事件編 -->
  <use xlink:href="#seg" transform="rotate(180 50 50)" fill="#a55e3a" />

  <!-- 甲子園の奇跡! 見えない悪魔に負けず嫌い -->
  <use xlink:href="#seg" transform="rotate(240 50 50)" fill="#e9b886" />

  <!-- 第326話 炎の中に赤い馬 捜査編 -->
  <use xlink:href="#seg" transform="rotate(300 50 50)" fill="#6a5038" />
</svg>

比較(旧→新)

f:id:YaaMaa:20191014021508p:plainf:id:YaaMaa:20191122012126p:plain
f:id:YaaMaa:20191122021647p:plainf:id:YaaMaa:20191122015614p:plain

寒色系服部が増えた。

ファイルサイズ

元々のPNG15,297 bytes
今回のSVG997 bytes

93%くらい削減できてすっきり。

*1:最新話は追わなくなってしまったけど、今も服部平次の概念自体は好き

Spotifyプレイリストの変更履歴を記録する

Spotifyのプレイリストを定期バックアップして、変更履歴をGitHubでコミット履歴として見れるようにしたかった。Spotifyプレイリストをエクスポートするスクリプトを既に公開してる人もいるけど、大抵認証時にポップアップが出てくるタイプで自動実行できなさそうだったので、自分で作った。

f:id:YaaMaa:20191005014052p:plain
追加したり移動したりしてる

新しく知った曲は「New」っていうプレイリストに入れておいて、しばらく聴き続けてだいたい歌詞を覚えたら、覚えた曲用プレイリストに移動するという運用をしている。もともとは、留学中にカラオケ行くことになったときに、やばい洋楽なんか何も知らんって焦って、とりあえず流行ってそうな曲を頭に詰め込むために始めた方法だったけど、それが妙に習慣化して今も続いている。こういう管理方法なので、それぞれの曲をいつ頃知って、どれくらいの時間をかけて覚えたのかを記録するためにプレイリストのバックアップが必要になった。

Spotifyには「プレイリストに変更があればwebhookで通知」みたいな機能はなさそう*1なので、1日1回のcronジョブで現在のプレイリスト一覧を取ってきて、前のデータとの差分を1個ずつコミットしている。

Spotify API

認証

Spotify APIにアクセスするには、クライアント登録をしてから認証が必要。認証にはauthorization code, client credentials, implicit grantの3つの方法があるけど、client credentialsはユーザー情報にアクセスできないし、implicit grantではaccess keyを更新するためのrefresh tokenをもらえないので、authorization codeを使う。

  1. /authorizeってエンドポイントにclient IDをクエリパラメータとしてくっつけたURLにアクセスする
  2. アクセスを許可しますか?みたいな画面になるので、自分のSpotifyアカウントでログインした状態でOK押す
  3. 設定しておいたリダイレクト先のURLにauthorization codeをクエリパラメータとしてつけた状態でリダイレクトされる
  4. そのauthorization codeをclient IDとかと共に/api/tokenにPOSTしたら、access tokenとrefresh tokenがもらえる
  5. Refreshするときは、/api/tokenにrefresh tokenをPOSTすると、新しいaccess tokenがもらえる

という手順でできた。

5の説明に"A new refresh token might be returned too."って書いてあるけど、それはrefresh tokenも定期的にexpireしちゃうって意味なのか、別に新しいやつを使わなくてもいいのかについては、情報が見つからなかった。今はrefresh tokenをsecretsに登録しといてaccess tokenは都度取得して使うようにしてるけど、refresh tokenも更新しないといけない場合もあるんかな...。

GitHub Actions

GitHubで全部完結したらありがたいので、初めてGitHub Actionsを使った。

トリガー

開発中はpushしたら即実行してくれた方が動作確認が楽なので、ワークフローの実行タイミングをon [push]にしていた。けどそのワークフローから更にpushする処理があるので、無限ループになるのでは?ってちょっと心配だった。意外とそんなことはなくて、わざと止めてくれているらしい

Git

actions/checkoutっていうアクションが$GITHUB_WORKSPACEリポジトリの中身を持ってきてくれる。このアクションがgit checkout $GITHUB_SHAを実行するためdetached HEAD状態になるので、現ブランチに行きたければ自分でcheckoutする必要がある。私の場合はmasterって決まってるからいいけど、そうじゃない人はブランチ名を$GITHUB_REFから頑張って取ってて大変そうだった。

pushするのは、$GITHUB_ACTORsecrets.GITHUB_TOKEN(自分でsecretsに入れなくても勝手に登録してくれるやつ)を使えばできた。

run: git push "https://${GITHUB_ACTOR}:${{ secrets.GITHUB_TOKEN }}@github.com/${GITHUB_REPOSITORY}" master

曲の表記

曲情報を書くとき、今までは「曲名 / アーティスト名」とか「アーティスト名 - 曲名」とか全く統一性なく適当に書いてたけど、この機会にどれが一番無難か調べてみようと思った。有名どころのサイトに行って、曲ページの<title>を確認してみたら、タイトルとアーティスト名の順番や区切り文字について意外とバリエーションがあった。

サイト 表記
Spotify Title · Artist (再生中のタイミングだけ)
Genius Lyrics ArtistTitle (ちょっと長いハイフン)
Musixmatch Artist - Title
AZLyrics Artist - Title
Shazam Title - Artist
Last.fm TitleArtist (かなり長いハイフン)
プチリリ Title / Artist

Artist - Titleが一番多そうなので、コミットメッセージに曲情報載せるときもそれに従った。


f:id:YaaMaa:20191005031019p:plain

これで、間違えて曲を削除しちゃって「今何消したっけ!!」ってなることもないので安心。

*1:Zapierにintegrationはあるけど、トラックの削除はたぶん検出できなさそうだった