| @音楽

Spotify

音楽のサブスクリプションは 2018 年の春頃から Apple Music を使っている。ただ最近、 Spotify のレコメンデーションが良いという話を複数の友だちや Podcast 、仕事先で立て続けに耳にしたので久々に使ってみたら、確かに Daily Mix というやつが聞いたことないけど絶対に好きな感じの曲で埋め尽くされていてビックリした。 Spotify は 4 年くらい前にお試しで 2 ヶ月使っただけで、それ以後は使っていない。そのときに自分の iTunes ライブラリや聞く音楽の傾向を解析してレコメンデーションの土台としていたのだろう。すごい。

Apple Music にも For You というやつがあって「金曜日のプレイリスト」的なやつが表示されるが、半分くらいがライブラリにある曲、半分くらいが知らないけど全然好きじゃない曲が混じってたりする。 Apple Music のレコメンデーションでは まだ知らない新しい音楽(だけど好き) との出会いがない。どっちかというと Apple Music は個人に最適化されたプレイリストよりも「2010年代 ヒップホップ ベスト」みたいなプレイリストのようなキュレーションされたものの方がまともな感じがする。パーソナライズされたレコメンデーションはダメダメだ。

また、 Spotify にはあるけど Apple Music にない曲というのが結構多い。 Spotify のプレイリストで良かった曲を Apple Music で DL しようとすると曲がなかったりする。以前、ストリーミングサービスの一ストリーミング再生ごとのアーティストへの支払額みたいなやつの比較を見てて、確か Apple Music が一番高かった。どうせ聞くならアーティストに手厚くお金を払っているサービスを使いたいと思って Apple Music を選んだのだが、意外とインディー系のアーティストは Apple Music には楽曲提供しておらず、 Spotify の方に出しているようだった。

こうなってくると Spotify に乗り換えたいなと思うのだけど、 Apple Music はファミリープランに入っているので自分の一存で Spotify に移行することができない。ファミリープランは個人用プランからすると著しく安い価格設定になっているが、その理由はチャーンの抑制にあると思う。意思決定者を複数人にすることで他サービスへの乗り換えが困難となる。よく考えられた価格設定だ。

結果としていまは広告に耐えながら Mac の Spotify で好みの曲を探し、ちまちま Apple Music でライブラリに追加して iPhone で聞くという生活をしている。スマートフォン版の Spotify は無料状態だと完全シャッフルになるしめっちゃ広告入るので厳しい。 Apple Music と Spotify に二重支払いできるくらいの金持ち1になりたい。


  1. 元同僚でウルトラ富裕インフラエンジニアの @glidenote 先生は Apple Music と Spotify に二重加入しているとのこと 

| @ブログ

インデックスページをいじって各カテゴリーの最新記事 4 件を配置するようにしてみた。最近の個人サイト復興ブームでみなさんインデックスページを工夫されているのを見ていて真似したくなってやった。

カテゴリーごとに最新記事 4 件を表示

昔ながらのブログだとインデックスページというのは最新の記事 10 件くらいが表示されていて、「次へ」を押すと古い記事が出てくるという構成になっている。以前のこのブログもそうだった。

しかし自分自身が他人のブログで「次へ」を押して次々に記事を読んでいくということをやった記憶がほとんどない。自分のブログでだって何か目的があって特定のキーワードで検索したあとに引っかかった記事を読むという感じなので、時系列に本文とセットで記事が 10 件ずつ表示される UI というのは意味をなしていないと思った。そもそもインデックスという名称なのに最近の記事数件しか表示していないのはおかしい。インデックスというからにはすべての記事の目次になるべきだ。

このブログはカテゴリーがあるので、サイトマップを作るとするとこんな感じになると思う。

+----------+        +------------+        +-----------+
|          |        |            |        |           |
|   Blog   +---+--->+  Category  +------->+   Entry   |
|          |   |    |            |        |           |
+----------+   |    +------------+        +-----------+
               |
               |
               |    +------------+        +-----------+
               |    |            |        |           |
               +--->+  Category  +---+--->+   Entry   |
                    |            |   |    |           |
                    +------------+   |    +-----------+
                                     |
                                     |
                                     |    +-----------+
                                     |    |           |
                                     +--->+   Entry   |
                                     |    |           |
                                     |    +-----------+
                                     |
                                     |
                                     |    +-----------+
                                     |    |           |
                                     +--->+   Entry   |
                                          |           |
                                          +-----------+

第一階層がインデックスページで、第二階層がカテゴリートップ、そして各記事がある。なのでインデックスページは二階層目の一覧ページになっているのが望ましいはずだ。しかし伝統的なブログはカテゴリーという記事をまとめる概念がありつつも、インデックスページから各記事ページへ直接遷移するのが主な導線だった。常に最新の記事が時系列順に並んでいるだけでは味気ないし、常連の読者ではないコンテキストを知らない訪問者には不親切だろう。

しかも SNS の隆盛で個人のブログのインデックスページが参照される機会というのはとんとなくなってしまった。個人が書いたブログ記事は SNS 経由で読まれ、個別記事だけが読まれる。インデックスページやトップページが読まれることはほとんどない。 SNS でシェアされている URL をクリックして個別記事を読んで、それ以上そのブログのほかの記事を読むことなく離脱してしまう。前後のコンテキストは無視して、一つのコンテンツだけがつまみ食いされてしまう。そんな流れにあらがいたいと思った。

これまで関連記事を記事下に表示するなどやってきたが、気に入っていくつか記事を読んで「ホーム」( = インデックスページ)を訪れたユーザーがもう少しブログを深掘りしてみたくなるようにインデックスページを各カテゴリーの最新記事一覧とするようにしてみた。このブログは現在カテゴリーが 13 個あるので、それぞれから 4 件ずつ記事を取得すると 52 記事になる。全カテゴリーからまんべんなく 4 記事ずつ取得して表示するのは簡単なようで結構難しい。普通の SQL ではできない。 OR マッパーではまず無理だろう。

いろいろ調べてみた結果、 MySQL では GROUP_CONCAT というのが使えそうだった。以下のような SQL を書いた。

select entries.id
from entries
inner join (
  select
    category_id,
    GROUP_CONCAT(id order by created_at desc) as entry_ids,
    max(created_at) as last_created_at
  from entries
  where entries.draft = false
  group by category_id
) as grouped_entries
on grouped_entries.category_id = entries.category_id
and FIND_IN_SET(id, entry_ids) between 1 and 4
order by last_created_at desc, entries.id desc;

GROUP_CONCATFIND_IN_SET という関数を組み合わせることで、各カテゴリーから作成日の降順に記事を 4 件ずつ取得できた。このクエリでは記事 id のみ取得して、もう一回 DB に記事を取得するクエリを ActiveRecord で投げる。 ActiveRecord でクエリを組み立てるときは N+1 が起こらないように関連テーブルを JOIN する。

query = <<~SQL
  select entries.id
  from entries
  inner join (
    select
      category_id,
      group_concat(id order by created_at desc) as entry_ids,
      max(created_at) as last_created_at
    from entries
    where entries.draft = false
    group by category_id
  ) as grouped_entries
    on grouped_entries.category_id = entries.category_id
    and find_in_set(id, entry_ids) between 1 and 4
  inner join categories on categories.id = entries.category_id
  order by last_created_at desc, entries.id desc;
SQL
entry_ids = ActiveRecord::Base.connection.select_all(query).rows.flatten
entries = Entry.includes(:category, :user, :tags, :comments).where(id: entry_ids)

PostgreSQL のときに最初に取得した entry_ids の並び順通りに結果が受け取れるかは怪しいが、 MySQL の場合は一回目のクエリで取得した id 順に各レコードが ActiveRecord のクエリ結果として取得できた。あとはこれをカテゴリーごとにグルーピングして View でよろしくやれば良い。

なお各カテゴリーはカテゴリー内の最新の記事の作成日で降順ソートするようにしている。例えば現在のインデックスページの最下部には音楽カテゴリーがあるが、これは音楽についての記事を最後に書いたのが一年以上前だからだ。もしいま音楽の記事を書けば音楽カテゴリーがトップに浮上するようになっている。

見た目に関しては各カテゴリーの記事最新一件は大きなサイズで表示している。最も最近書かれた記事なのでより多く人の目に付いた方がよいだろうという考えだ。またすべての記事にサムネイルというか、アイキャッチ画像を表示するようにした。画像がない記事に関してはデフォルトのサイトアイコン画像を表示するようにしている。やっぱり視覚的に情報を捉えられるのは重要だ。画像がごちゃごちゃ表示されるのを嫌う人もいるかもしれないが、テキストだけでは人間の認知というのはどうしても追いつかない。

あわせて今回、インデックスページの冒頭部にこのサイトについての説明文を載せることにした。ながしまきょうさんr7kamura さんがやっているののパクりだ。伝統的なブログのインデックスページは初めて訪れた人のことを無視しすぎていたと思う。そのブログ自体について説明するページがあるブログは少ない。最初の記事でブログを始めた経緯みたいなことが書かれたきり、そのブログは何なのか、誰が書いているのかが書かれることは希だ。きちんとブログについての説明ページと著者についての説明ページがあっても、左右のサイドバーやトップのナビゲーションの端っこに押し込まれて見られることはない。これではいけないだろう。というわけでインデックスページの一番目立つ位置にブログと自分自身の簡単な紹介を入れた。

インデックスページトップに紹介文を表示

ブログはなぜ衰退したかを考えてみると、 Facebook や Twitter の隆盛はあるにせよ、ブログ自体に初めて訪れた人に読まれるための工夫が欠けていたのだと思う。誰も自分のブログの継続率を計測したりコホート分析したりはしない。読者が前後の記事を読んでいることを前提に書かれた記事やサイト構成では初めて訪れた人はどうやっても離脱してしまう。特に書き手が芸能人でもない一般人の場合はなおさらだ。誰も RSS フィードを購読していないし、ほとんどの読者は初めて訪れる人なのだから、そういう人たちが読んでブログのテーマや著者の人となりが分かる構成にしていかなければならないのだと思う。でないと SNS でたまにバズったときだけ読んでもらえる、ソーシャルメディアの肥やしにしかならない。

この新しいインデックスページが正解なのかどうかは分からないが、ブログ衰退の流れにあらがっていきたい。

| @散財

ウキグモ Light & ウンカイ Light & Hammock Trekking Tarp

一つ前に「キャンプもんなんてするもんじゃない」という趣旨の記事を書いたが、その記事を書いた日の午後に佐賀のキャンプ場までキャンプをしに行った。

池と月

家族はテントの中で寝たが、自分はハンモックで寝てみたいと思っていたので外で寝ることにした。 9 月の連休に久住のキャンプ場に行ったときはキャンプサイトが原っぱでちょうどいい感じの木が生えておらずハンモックを張れなかったので初めて実際のフィールドでハンモックを使うことになる。

ハンモックの中からの景色

ちなみに以前書いた記事ではウキグモ Light (ダウンハンモック)を買ったということは書いていたが、その後ヤフオクを物色していてトップキルト(ハンモック用掛け布団)のウンカイ Light が安く出品されているのを発見したのでサクッと落札した。これによりウキグモ Light とウンカイ Light 、 Exped Hammock Trekking Tarp (軽量タープ)のハンモック泊三種の神器がそろい、温かい低山であればいつでも野営できるようになった。

ハンモック泊三種の神器: ウンカイ Light 、ウキグモ Light 、 Exped Hammock Trekking Tarp

ウンカイ Light に関しては以下のブログが参考になる。

メーカーのアクシーズクインのページと GRiPS のブログも。

実際に張っている様子は以下。

三種の神器

キャンプ場の標高は 550m くらいで、ふもとの気温と標高差からこの日のキャンプ場の最低気温は 15 度前後だったと想像される。ウキグモ Light の快適使用温度は 15 度以上となっていて、またウンカイ Light とも組み合わせていたので条件的には問題ないはずだが、明け方に風が吹くと寒さで目が覚めてしまった。

9 月下旬の久住のキャンプで寒さ対策の必要性を痛感していたので今回は寝るとき用にスウェットパンツと厚手のセーターを着込んでいた。それでも風が吹くと背面が冷えた。 XERO SHOES のサンダルを履いていた都合上、足は裸足で靴下ははいていなかった。ウンカイ Light には足を突っ込めるフットボックスがあるが、それでも足下からも冷気が入り込んで足が冷えた。またウンカイ Light からはみ出している頭にも寒気を感じたので、一度ハンモックから這い出して薄手のウィンドシェルをセーターの上から着てフードを被ってハンモックに入り直した。そうすると随分寒さは軽減されたが、 5 時頃からキャンプ場に合宿に来ていた少年野球クラブの子ども達がわーわーと騒ぎ始め、またあたりが明るくなってきたことにより寝付けなくなってしまった。結局 3 時間しか寝られなかった。以下の学びを得た。

  • ハンモックは寒い。寝るときは厚着が必要。
  • トップキルトからはみ出る頭の部分や足が冷えるのでフードのある服かニットキャップが必要。靴下もはいておく。
  • ハンモック&タープでは外の影響をもろに受ける。周囲の音や日の出で目が覚めるので早寝早起きが快適。

ダウン入りハンモックなので九州の低山であれば真冬でも使えるのではと期待していたが、やはり山は寒い。この感じだとやはりウキグモ Light & ウンカイ Light は晩春から早秋にかけてしか使えない、夏用の寝具と捉えるしかない。どうしても冬場も使いたいなら、ブランケットで体をぐるぐる巻きにするか、ハンモックをまるごと覆ってしまうモグを検討するしかないだろう。

テントと寝袋を買いそろえると高い(テントが 5 万円、寝袋が 3 万円、マットが 1 万円くらいする)し重い(テント 1kg 、寝袋とマットで 1kg くらい)から、ハンモックなら軽いし安く宿泊装備がそろうはず、と思って揃えたハンモックシステムなので、これ以上何か買って本末転倒にならないように気をつけたい。

| @ブログ

blog.8-p.info の過去記事ページの真似をして、 Archive ページにタグを表示するようにしてみた。

Archive ページにタグを表示

タグはあまり使っていなかったのだけど、一覧で記事タイトルだけ並んだときその記事にどんな内容が書いてあるのかを把握するためにはタグが便利だなと思い直し、タグを表示させてみることにした。いくつか過去のタグが付いていない記事にタグを振ってもみた。

このブログは技術情報からポエム、日々の日記まで何でもありのごった煮ブログなので、カテゴリーによる情報分類には限界がある。現在 13 個のカテゴリーがあるが、記事数にバラツキがあり、情報分類としてあまり機能していない。カテゴリーの粒度をもっと荒くして緩い分類に変更し、そこから先はタグによって超細かくラベリングすると情報の分類としてはまともになるのではないかと思った。

いま、カテゴリーの内訳がこんな感じ。

- "雑談":303
- "技術/プログラミング":272
- "映画/ドラマ/テレビ":150
- "Mac/iPhone":134
- "WWW":113
- "散財":95
- "旅行/ハイキング":70
- "ブログ":69
- "音楽":63
- "読書":34
- "写真":32
- "料理/食事":31
- "労働":27

もっと緩い分類にして以下みたいな感じにするとよさそう。

- 雑記
- パソコン・インターネット
- 見た・読んだ・聞いた
- 出かけた・撮った・食べた

カテゴリーとタグの使い分けは 10 年以上前から悩んでいる気がする。

情報分類の手法でありつつコンテンツの内容そのものを指し示すものでもあるからだろう。インスタグラムで #ラーメン #からの #うどん とかやってる投稿を見るととても嫌な気持ちになるのだけど、そういうことがされるくらいにタグというものは不安定なもので、正しく使おうとか気負わず、もっと緩く使えばいいのかもしれない。

もう廃れてしまったが、フォークソノミーが勢いを取り戻して、情報の発信者ではなく受け取り側がコンテンツにタグ付けできるような世の中になるとおもしろいのかもしれない。

| @Mac/iPhone

Touch Bar

リモートワーク中心の世の中なので Slack の Status で離席していることやミーティング中であることが分かると便利なはず。というわけで自分はなるべく Slack の Status を更新するようにしているが、 Slack アプリ内での Status の更新は面倒くさい。メニューを押して絵文字選んでひと言アップデートを入力とか毎度やってられない。ボタン一発で Status を更新したい。

MacBook Pro の Touch Bar は評判が悪い。自分もあまり便利だと思わないのだけど、一つだけ便利な使い方があって、それがこの Slack の Status アップデートボタンを配置するというもの。 Touch Bar に配置されたボタンを押すだけで食事中であることや退勤済であることを Slack の Status として表示できるようになる。めっちゃ便利。

なお、オリジナルのアイディアとソースコードは 9m さんのものです。

必要なもの

準備

1. Slack の API Token を発行する

2. 9m さんの gist を clone し、手元で動かせるようにする

$ ghq clone https://gist.github.com/af5894ced5cc1ac38bfd2687cad7c780.git slack_status
$ cd clack_status
$ bundle install
$ echo "SLACK_TOKEN=XXXX" > .env
$ bundle exec app.rb "🍺" "退勤しました"

ちゃんと設定できてれば以下のようになる。

コマンドラインから Slack Status をアップデートしている様子

3. Automator を開き、クイックアクションを設定

新規作成で「クイックアクション」を選ぶ。

Automator を開き「クイックアクション」を新規作成

アクションの中からシェルスクリプトを選ぶ。

シェルスクリプトを選ぶ

実行したい処理をシェルスクリプトで書く。

実行したい処理をシェルスクリプトとして記載

自分は以下のようにしている。

export PATH="~/.rbenv/shims:$PATH"
export LC_ALL=ja_JP.UTF-8
export LANG=ja_JP.UTF-8
cd /Users/morygonzalez/src/gist.github.com/slack_status
bundle exec ruby app.rb "🚽" "放尿 or 脱糞中です"

なお、赤枠で囲った「ワークフローが受け取る項目」は「入力なし」にしておかないとちゃんと動かないので注意。

入力なしを選択

設定完了したら名前を付けて保存する。自分の場合は Slack トイレ などのような名前にしている。この作業を追加したいコマンドの数だけ繰り返す。

4. キーボードショートカットの割り当て

システム環境設定 -> キーボード -> ショートカット -> サービス の順に進む。正しく Automator でアクションを設定できていれば「サービス」の一覧に表示されるので、割り当てたいショートカットキーを割り当てる。

ショートカットの設定

5. BetterTouchTool で Touch Bar をカスタマイズする

タッチバーに表示されるボタンのアイコンとラベル文字を選び、タップしたときにショートカットキーが実行されるようにする。

BetterTouchTool で Touch Bar をカスタマイズ

こうすることで Touch Bar から Automator のクイックアクションが実行され、めでたく Slack の Status がアップデートされるようになる。

ちなみに自分の Touch Bar はこんな感じ。

Touch Bar の様子

ほこりをかぶってる Touch Bar を是非有効活用してあげてください。

Touch Bar がないパソコンを使っている人向けの情報

Touch Bar のない Mac を使っている人はこのやり方を使えないので Slack の Google Calendar 連携機能を使うと良いと思う。設定に Status Sync という項目があるのでこいつを On にすると、 Google Calendar で予定が入っている時間になると Slack の Status を自動で更新してくれる。

Google Calender の Status Sync

会議中であることくらいしか共有できないので Touch Bar にいろんなボタンを配置するのに比べたら不便だけど、カレンダーに予定を入れておくだけで Slack の Status を更新できるようになるのは便利。

今後の課題

良くありがちなのが「仕事中」の Status のまま退勤してしまうというやつ。夜中や週末も仕事している異常な人になってしまう。スマートフォンからも同様にめっちゃ手軽に Slack の Status をアップデートしたいけどまだソリューションを見つけられていない。情報お持ちの方いたら教えてください。

| @ブログ

キャプションの表示

画像にキャプションを表示させるようにした。 img 要素には alt 属性を細かく入れていたので alt の内容を抜き出して figcaption として表示させるようにした。やり方はまるっきり r7kamura さんの手法 を真似した。

昔の記事はレイアウトが壊れているかもしれないけど気にしないことにする。

| @散財

Pebble Time Round

4 年前の誕生日に嫁さんに買ってもらった Pebble Time Round をずっと使ってる。

純正革ベルトは購入後割とすぐに異臭を放つようになってしまった。革ベルト自体がくさいのではなく自分の手首の垢がベルトに染み付いて異臭を放ってるみたいだった。

おまけに充電部が皮膚と触れるせいで端子がさびてしまい購入半年で充電しづらくなってしまった。

その後ベルトをナイロン製の NATO のやつに変えて臭いも端子のサビも(肌が直接充電端子に触れなくなったので)幾分かましになったが、最近また調子が悪い。

Pebble は自分が Pebble Time Round を購入した年の年末に FitBit に買収されて終了した。

その FitBit も Google に買収されてしまった。

結構きついのがソフトウェアの更新が止まってることだ。有志がメンテナンスしてくれているが、いつ iOS のアップデートに追従できなくなるかがわからない。

なんだか書いていて暗澹たる気分になってきたが、二日はバッテリーが持つし、小さくて軽いし、 E-Ink なので常時時間を確認できるしで良いところもたくさんある。厚みが薄くて見た目がいかにもスマートウォッチ然していないのも良かった。それでいて万歩計、睡眠トラッキング、スマートフォンへの通知の受け取りにも対応しているので神デバイスだったと思う。腕時計へプッシュ通知が届くことの便利さに慣れたらなくては困ると感じるだろうから壊れたら観念して Apple Watch を買おうと思うけど、 Pebble Time Round のような感覚では使えないのだろうなと思う。