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.

So sieht eine Datenbank von innen aus

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);  
http://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)"
http://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.

Bilder von hier und hier

Impressum