Skip to content

feat(hpi): HPI を入れて ActivityWatch モジュールを自作する - #397

Merged
gapul merged 1 commit into
mainfrom
feat/hpi
Aug 21, 2026
Merged

feat(hpi): HPI を入れて ActivityWatch モジュールを自作する#397
gapul merged 1 commit into
mainfrom
feat/hpi

Conversation

@gapul

@gapul gapul commented Aug 21, 2026

Copy link
Copy Markdown
Owner

個人データを1つのクエリ面にまとめる枠組みとして HPI を入れます。あわせて、上流に無い ActivityWatch モジュールを自作しました。

HPI の位置づけを訂正

最初に「今バラバラにあるものを統合する道具」と説明しましたが、モジュール一覧を確認したら ActivityWatch は対象外でした。近いのは arbtt.pyrescuetime.py だけです。この環境で一番量のあるローカルデータ(実測 115 万イベント)が入らないので、説明として不正確でした。

一方で本来の使いどころが分かりました。my/google/takeout/parser.py が Takeout の "My Activity" を扱っていて、そこには検索履歴と YouTube の視聴履歴が両方入っています。つまり HPI は「SaaS を離れるときにエクスポートを引き出して、以後ずっとローカルで引けるようにしておく」ための道具です。前に話題に出た2つの、自前化する前の過去ぶんがそのまま入ります。

自作した my/activitywatch.py

REST API ではなく SQLite を直接読みます。API 経由だと aw-server が起動している必要があり、「過去のデータを後から集計する」という HPI の使い方に合わないためです。稼働中の WAL を取りこぼさないよう my.core.sqlite.sqlite_copy_and_open を使っています(my.zotero と同じ手口)。

ホスト名を読むときに正規化して、MacBook-Mini.localMacBook-Mini を同じ端末として扱います。この分裂は 2026-08-09 に window と afk が .local 無しへ切り替わり、ブラウザ拡張だけ .local に残ったことで起きていました。

DB を書き換えて統合する案もありましたが、採りませんでした。8ヶ月ぶんの再取得不可能なデータに破壊的な操作をする理由がなく、読むときに寄せれば同じ結果になるからです。実際そうなりました(下の検証)。

API は events() / window() / afk() / browser() と、stats()

検証(実機)

$ hpi doctor my.activitywatch
✅ config check: success!
✅ OK  : my.activitywatch
ホスト名(正規化後): {'MacBook-Mini': 1152279}      ← 分裂が消えている
  MacBook-Mini   afkstatus          23510          ← 22,163 + 1,347 が合流
  MacBook-Mini   currentwindow      946994
  MacBook-Mini   web.tab.current    181775
YouTube 視聴: 5328

期間は 2025-12-13 → 2026-08-21。

パッケージング

本体は nix ではなく uv tool install HPI で入れます。HPI はモジュールを自分で書き換えて使う前提の設計(editable install を推奨)なので、store に固めると噛み合いません。~/.local/bincommon.nix で既に PATH に入っていて、コメントにも「uv tool binaries」と書いてあるので、そのまま通ります。

設定と自作モジュールだけ dotfiles に置いて home-manager が ~/.config/my/my/ に配置します。implicit namespace package なので __init__.py は不要です(PEP 420)。

ライブラリとして使うときは import my.core.init を先に呼ぶ必要があります。これが sys.path への差し込みを実行します(hpi CLI 経由なら不要)。ハマったのでコメントに残しました。

この先

config.py に Google Takeout / GitHub / browserexport の設定をコメントアウトで用意してあります。対応するエクスポートを取ってきたら外すだけです。Takeout の申請とダウンロードは手作業なので、そこは残タスクです。

HPI は「SaaS から引き出したエクスポートを、ローカルで横断的に引ける形にして
おく」ための枠組み。Google Takeout の "My Activity" には検索履歴と YouTube の
視聴履歴が入っているので、離れるときに取っておけば過去ぶんが手元に残る。

ただし HPI 本体に ActivityWatch のモジュールは無い。近いのは arbtt と
rescuetime だけで、この環境で一番量のあるローカルデータ (実測 115 万イベント、
2025-12-13 以降) が対象外だった。なので自分で書いて my 名前空間に足す。

REST API ではなく SQLite を直接読む。API だと aw-server の起動が必要で、
過去のデータを後から集計するという使い方に合わない。稼働中の WAL を
取りこぼさないよう my.core.sqlite.sqlite_copy_and_open を使う。

読むときにホスト名を正規化して MacBook-Mini.local と MacBook-Mini を同じ端末
として扱う。この分裂は 2026-08-09 に window と afk が .local 無しへ切り替わり、
ブラウザ拡張だけ .local に残ったことで起きていた。DB を書き換えて統合する手も
あるが、8ヶ月ぶんの再取得不可能なデータに破壊的な操作をする理由がない。

本体は uv tool install で入れる。HPI はモジュールを自分で書き換える前提の
設計なので store に固めない。~/.local/bin は既に PATH にある。

実機で確認済み:
- hpi doctor my.activitywatch が通る
- events 1,152,279 / window 946,994 / browser 181,775 / afk 23,510
- 正規化後のホスト名が MacBook-Mini の1つだけになる (afk は 22,163 + 1,347 が
  合流して 23,510)
- browser から YouTube の視聴イベントが 5,328 件抽出できる
@gapul
gapul merged commit 73bd37a into main Aug 21, 2026
5 checks passed
@gapul
gapul deleted the feat/hpi branch August 21, 2026 03:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant