Firefox History in der Kommandozeile

Firefox ist so bekannt geworden, weil man alles mögliche an ihm einstellen kann. Warum ist es dann so schwer, ihn von der Kommandozeile zu steuern?
Ich würde wirklich gerne ein paar Skripte schreiben, welche die aktuell geöffneten Seiten von Firefox auswerten (zum Beispiel um die aktuelle Seite in eine Liste einzutragen, einen Eintrag in meinen Passwortmanager zu machen oder ähnliches).
Leider ist das scheinbar sehr schwierig, denn dieser riesige Kloß von einem Browser kann scheinbar nicht nach außen kommunizieren (Ich arbeite gerade mit Mozilla Firefox 46). Folgenden Notbehelf habe ich gefunden:
Die neuste Seite ist aktuell
Ich nehme vereinfachend an, dass ich mich nur für die Seite interessiere, die als letztes aufgerufen wurde. Dann muss man nur in der Firefox History nachschauen, welche Seite die letzte war und sie ausgeben.
Warum ist das leichter? Firefox speichert seine History, Bookmarks und noch ein paar andere Dinge in einer sqlite Datenbank: $HOME/.mozilla/iwfal82r.default/places.sqlite
. (Der Teil vor “default” sieht jedes mal ein bisschen anders aus, aber das findet man schon. Im Folgenden benutze ich ein Regexsternchen, so dass die Befehle bei jedem funktionieren sollten.) Da ich ja neulich schon etwas Erfahrung mit Datenbanken gesammelt habe, wage ich mich da mal rein.
In der Datenbank
sqlite3 $HOME/.mozilla/firefox/*.default/places.sqlite
SQLite version 3.13.0 2016-05-18 10:57:30
Enter ".help" for usage hints.
sqlite>
Wir sind jetzt in der Datenbank (raus kommen wir mit Ctrl-D). Erstmal schauen wir was es hier für tables gibt:
sqlite> .tables
moz_anno_attributes moz_favicons moz_items_annos
moz_annos moz_historyvisits moz_keywords
moz_bookmarks moz_hosts moz_places
moz_bookmarks_roots moz_inputhistory
Die Tabelle die wir brauchen ist die moz_places
. Hier ist unsere gesamte Browserhistory drin (habe ich hier rausgefunden). Wir schauen uns die Spalten der Tabelle an:
sqlite> pragma table_info(moz_places);
0|id|INTEGER|0||1
1|url|LONGVARCHAR|0||0
2|title|LONGVARCHAR|0||0
3|rev_host|LONGVARCHAR|0||0
4|visit_count|INTEGER|0|0|0
5|hidden|INTEGER|1|0|0
6|typed|INTEGER|1|0|0
7|favicon_id|INTEGER|0||0
8|frecency|INTEGER|1|-1|0
9|last_visit_date|INTEGER|0||0
10|guid|TEXT|0||0
11|foreign_count|INTEGER|1|0|0
Für uns sind url
und last_visit_date
wichtig (denn wir wollen ja die URL, die zuletzt aufgerufen wurde). Wir tasten uns mal langsam ran:
Alle URLS, die ich je aufgerufen habe
Alphabetisch sortiert.
sqlite> select url from moz_places;
...
Alle URLS, die ich je aufgerufen habe
Nach Datum sortiert.
sqlite> select url from moz_places order by last_visit_date;
...
Wann die letzte URL aufgerufen wurde
sqlite> select max(last_visit_date) from moz_places;
1464029535578940
Hmm, eigentlich sollte hier ein Datum stehen. Laut table_info ist dieses als Integer kodiert. Das Internet hilft weiter.
sqlite> select max(last_visit_date) as raw_visit_date,datetime(last_visit_date/1000000,'unixepoch') from moz_places;
1464029535578940|2016-05-23 18:52:15
Sieht doch gleich viel besser aus, die ISO 8601 lebe hoch. Aber irgendwie ist das um zwei Stunden falsch? Ach ja, Zeitzonen.
sqlite> select max(last_visit_date) as raw_visit_date,datetime(last_visit_date/1000000,'unixepoch','localtime') from moz_places;
1464029535578940|2016-05-23 20:52:15
Geht doch.
Eigentlich brauchen wir diese schick formatierten Strings aber gar nicht, wir wollen ja nur nach Zeit sortieren. Deswegen orientieren wir uns am ersten Versuch.
Die URL, die ich als letztes besucht habe
Genau genommen fragen wir eher nach allen urls, die zu dem Zeitpunkt aufgerufen wurden, an dem wir zuletzt eine url aufgerufen haben.
sqlite> select url from moz_places where last_visit_date=(select max(last_visit_date) from moz_places);
https://www.schauderbasis.de/
Hurra, es funktioniert!
Für Skripte
Damit wir uns nicht ständig in sqlite einloggen müssen, kann man das auch von außen tun.
$ sqlite3 $HOME/.mozilla/firefox/*.default/places.sqlite "select url from moz_places where last_visit_date=(select max(last_visit_date) from moz_places)"
https://www.schauderbasis.de/
So, da ist sie. Die letzte besuchte Url. Das funktioniert, auch sofort nach dem Aufrufen der Url oder wenn der Firefox aus ist.