Last Modified:
ブラウザのブックマークを同期したい #Firefox #Safari #macOS
色々あったので箇条書き
- iPhoneでiOS Safariをメインで使っている
- ✅macOS SafariはiCloudで同期済み
- ✅Windows ChromeはiCloudブックマーク - Chrome ウェブストアで同期可能
- ✅Windows FirefoxはiCloud ブックマークで同期可能
- ❌macOS Firefoxにも同期したい…がなぜか見つからない
- 💡iCloud ブックマークはどちらもApple Inc.純正でどちらもWindows版しかない。どうやらmacOS上ではSafari以外は使うなということらしい。
- ❌(以前Firefoxがメインのとき使っていた)Eversyncは、Windows/macOS両対応だがFirefoxとChromeのみ
- オンラインブックマークも検討した。⭕Raindrop.io — All-in-one bookmark managerこれはこれでアリだけどそうじゃない。
macOS Safari(以下Safari)からmacOS Firefox(以下Firefox)へブックマークを同期する方法を考える。
Safariからブックマークをエクスポート→Firefoxへインポート
- Safariで[ファイル]→[書き出す]→[ブックマーク...]、
- Firefoxで[ブックマーク]→[ブックマークを管理]→[HTML から読み込む...]
この手作業を自動化したい。
- ❌スクリプトエディタ このスクリプト難しいです…。[記録]も動かないし…。それにいちいちウィンドウが上がってくるのも煩わしい。
❌ショートカット うーん…
~/Library/Safari/Bookmarks.plist を直接読む
- ⚠️Terminalからだとセキュリティの関係で読めない。 "System Preferences" -> "Security & Privacy" -> "Privacy" -> "Full Disk Access", check "Terminal".
- ❌healthypackrat/safari_bookmarks_parser: Dump ~/Library/Safari/Bookmarks.plist as JSON/YAML (RubyGems)階層無視やん…
- ❌anoved/ReadingListReader: Python library to read contents of Safari Reading List. Includes scripts to output as CSV or "bookmarks" file format and to upload to Instapaper.いや、ブックマークも欲しいねん…
- ❌Mac::Tie::PList - Parse Apple NSDictionary objects (e.g. Preference Lists) - metacpan.orgFoundation.pmに依存していて、システムPerlにしか入ってないのでパス
- ⭕Mac::PropertyList - work with Mac plists at a low level - metacpan.org
- ℹ️javascript - bookmarks.html の仕様書 - スタック・オーバーフロー
- ✅読むのはすぐできた。フォルダー階層構造もBookmarks.plistでそのまま表現されてるので良さそう。bookmarks.htmlっぽい出力もできた(ADD_DATE,LAST_MODIFIEDは無い)。
~/.firefox/places.sqlite(以下~/.firefox => ~/Library/Application Support/Firefox/Profiles/xxxxxxxx.default)に直接書き込む
- ❌sqlite使ってmoz_bookmarksに入れたら良さそうだけど、moz_placesも考慮しないといけなくて、スキーマ眺めてたらめんどくさくなった…。Bookmarks.plistには日時データもないのでFirefox Sync辺りで影響が出そうな予感もして早々と撤退。
- ℹ️Comcast add bookmarks Ruby scriptこういうのもあった。良さそうだけど試してない。
❌そもそも[HTML から読み込む...]は、Firefoxの"ブックマークメニュー"に入ってしまう。
- ブックマークツールバー - ブクマ1 - ブクマ2 - ブックマークメニュー - ブクマ3 ↑これが↓こうなってしまう - ブックマークツールバー - ブックマークメニュー - ブックマークツールバー - ブクマ1 - ブクマ2 - ブックマークメニュー - ブクマ3
実は、Firefoxで書き出したbookmarks.htmlをそのまま読み込んだとしてもこうなってしまう。復元できてないやん。 バックアップのJSONと同じ形式で作って、[復元]をすればこの問題は起きない。でもJSON作るのがめんどくさそう。 (後半でわかったけどこれ、インポート先が"PlacesUtils.bookmarks.menuGuid"となっているからだと思う。BookmarkHTMLUtils.sys.mjs - mozsearch)
Firefoxで[他のブラウザーから読み込む...]
Firefoxで[ファイル]→[他のブラウザーから読み込む...]を使うとSafariのブックマークなどが読み込める。 でも何回もクリックが必要なので、スクリプトエディタで自動化するにしても減らしたほうが良いと思い設定から減らしてみる。
// ~/.firefox/user.js
// これでブラウザ選択候補がSafariだけになる
user_prefs("browser.migrate.brave.enabled", false);
user_prefs("browser.migrate.canary.enabled", false);
user_prefs("browser.migrate.chrome-beta.enabled", false);
user_prefs("browser.migrate.chrome-dev.enabled", false);
user_prefs("browser.migrate.chrome.enabled", false);
user_prefs("browser.migrate.chromium-360se.enabled", false);
user_prefs("browser.migrate.chromium-edge-beta.enabled", false);
user_prefs("browser.migrate.chromium-edge.enabled", false);
user_prefs("browser.migrate.chromium.enabled", false);
user_prefs("browser.migrate.edge.enabled", false);
user_prefs("browser.migrate.firefox.enabled", false);
user_prefs("browser.migrate.ie.enabled", false);
user_prefs("browser.migrate.opera-gx.enabled", false);
user_prefs("browser.migrate.opera.enabled", false);
user_prefs("browser.migrate.safari.enabled", true); // Safariだけtrue
user_prefs("browser.migrate.vivaldi.enabled", false);
// こうすると読み込むデータ選択に履歴の項目が出てこない
user_prefs("browser.migrate.history.maxAgeInDays", 0);
// これは新しいタイプのマイグレーションモーダルを使う設定
user_prefs("browser.migrate.content-modal.enabled", true);
// 読み込むデータ選択の[+]を押す手間が省ける
user_prefs("browser.migrate.content-modal.import-all.enabled", false);
ここまでやっといてアレだけど、やっぱりスクリプトエディタでメニューをクリックさせる方法が良く分からない。
コマンドラインで自動化する
MozReplとかあったなと思い出し、chrome://browser/content/bookmarks/bookmarksManager.xulを開いてメニュークリックさせたりできるのでは?と思って試してみる。
- ❌が、ブックマークマネージャーが開かない。なんでだ?
と思ったら、どうやらFirefoxはいつの間にかXULを使わないようになり、WebComponentsの仕様に従ってるらしい。
- chrome://browser/content/bookmarks/bookmarksManager.xul → chrome://browser/content/places/places.xhtml
- chrome://browser/content/browser.xul → chrome://browser/content/browser.xhtml
- ⭕CPANでMozReplを探していたらFirefox::Marionette - Automate the Firefox browser with the Marionette protocol - metacpan.orgを見つけた。これ行けそう!
Firefox::Marionette
とりあえず試しにブックマーク一覧を出してみる。
use v5.30;
use Firefox::Marionette;
my $firefox = Firefox::Marionette->new();
foreach my $bookmark ($firefox->bookmarks()) {
say $bookmark->guid(), ": ", $bookmark->url();
}
- ❌出ない。あー、ウィンドウが出ないということはSeleniumみたいなテスト目的であって、違うプロファイルで実行してるのかな?
- ⭕ドキュメント見て
Firefox::Marionette->new(profile_name => 'default')
に変えてみたらうまくいった。 - ❌
$firefox->import_bookmarks();
'Unrecognised format for bookmark import'とか言われて動かない。ちょっとだけソース見たけど、[他のブラウザーから読み込む...]とは違うなぁ…。 - 追加する前に一旦クリアしないといけないので
$firefox->delete_bookmark($bookmark);
を試す。けどなんか全部消すのが妙に遅い…。 - 💡Marionette.pmソース見たら
script
で何やらJavaScriptを流してる模様・・・ってXPCOMやんけ! - ということは、ちまちまブックマークの処理をしなくても、[他のブラウザーから読み込む...]の処理を追っていけばXPCOM呼び出しでできるのでは?と思い、ソースを漁る。
- /Applications/Firefox.app/Contents/Resources/omni.ja がzipだったので展開して探してみたり。
- / - mozsearchで探してみたり。
- ℹ️migration « components « browser - firefox - debian-backports: firefox各ブラウザのMigrator
- ⭕Silently Import Bookmarks from IE to Firefox | Firefox for Enterprise Support Forum | Mozilla brukerstøtteこ…これは素晴らしい!
- ⭕あとどこかで
eraseEverything
というのを見かけたのでそれも使える。
⭕というわけで、自動的にSafariからFirefoxへブックマークを同期するスクリプトが完成。
#! /usr/bin/env perl
use v5.30;
use Firefox::Marionette qw();
Firefox::Marionette->new(profile_name => 'default', debug => 1)
->chrome()
->script(<<'END_OF_SCRIPT');
return (async function () {
await PlacesUtils.bookmarks.eraseEverything();
const migrator = await MigrationUtils.getMigrator("safari");
await migrator.migrate(MigrationUtils.resourceTypes.BOOKMARKS);
})();
END_OF_SCRIPT