| ... | ... |
@@ -6,6 +6,33 @@ Export [Firefox][] [session][]s to plain text. |
| 6 | 6 |
[Firefox]: https://en.wikipedia.org/wiki/Firefox |
| 7 | 7 |
[session]: https://support.mozilla.org/kb/how-restore-browsing-session-backup#w_restoring-from-a-backup-file |
| 8 | 8 |
|
| 9 |
+## Requirements |
|
| 10 |
+ |
|
| 11 |
+All of these are packaged in [Debian][]. |
|
| 12 |
+ |
|
| 13 |
+- [POSIX][]-compatible [shell][] |
|
| 14 |
+- [`lz4json`][] |
|
| 15 |
+- [`jq`][] |
|
| 16 |
+ |
|
| 17 |
+[Debian]: https://en.wikipedia.org/wiki/Debian |
|
| 18 |
+[POSIX]: https://en.wikipedia.org/wiki/POSIX |
|
| 19 |
+[shell]: https://en.wikipedia.org/wiki/Unix_shell |
|
| 20 |
+[`lz4json`]: https://github.com/andikleen/lz4json |
|
| 21 |
+[`jq`]: https://jqlang.org |
|
| 22 |
+ |
|
| 23 |
+## References |
|
| 24 |
+ |
|
| 25 |
+Relevant directories, files, and code in the [Firefox source][]: |
|
| 26 |
+ |
|
| 27 |
+- [`browser/components/sessionstore/`][] |
|
| 28 |
+ - [`session.schema.json`][]: JSON schema used by session stores. |
|
| 29 |
+ - [`SessionFile.sys.mjs` `SessionFileInternal.Paths`][]: JSON schema used by session stores. |
|
| 30 |
+ |
|
| 31 |
+[Firefox source]: https://github.com/mozilla-firefox/firefox |
|
| 32 |
+[`browser/components/sessionstore/`]: https://github.com/mozilla-firefox/firefox/blob/main/browser/components/sessionstore/ |
|
| 33 |
+[`session.schema.json`]: https://github.com/mozilla-firefox/firefox/blob/FIREFOX_141_0_RELEASE/browser/components/sessionstore/session.schema.json |
|
| 34 |
+[`SessionFile.sys.mjs` `SessionFileInternal.Paths`]: https://github.com/mozilla-firefox/firefox/blob/FIREFOX_141_0_RELEASE/browser/components/sessionstore/SessionFile.sys.mjs#L69 |
|
| 35 |
+ |
|
| 9 | 36 |
## License |
| 10 | 37 |
|
| 11 | 38 |
Licensed under the [ISC License][] unless otherwise noted, see the |
| 12 | 39 |
new file mode 100755 |
| ... | ... |
@@ -0,0 +1,75 @@ |
| 1 |
+#!/bin/sh |
|
| 2 |
+set -euC |
|
| 3 |
+ |
|
| 4 |
+# Usage: firefox-session-export [<file>] |
|
| 5 |
+ |
|
| 6 |
+file="${1:-}"
|
|
| 7 |
+if ! [ "$file" ] |
|
| 8 |
+then |
|
| 9 |
+ for file_ in \ |
|
| 10 |
+ "$HOME/.mozilla/firefox/"*default*'/sessionstore.jsonlz4' \ |
|
| 11 |
+ "$HOME/.mozilla/firefox/"*default*'/sessionstore-backups/recovery.jsonlz4' \ |
|
| 12 |
+ "$HOME/.mozilla/firefox/"*default*'/sessionstore-backups/previous.jsonlz4' \ |
|
| 13 |
+ "$HOME/.mozilla/firefox/"*default*'/sessionstore-backups/recovery.baklz4' |
|
| 14 |
+ do |
|
| 15 |
+ [ -r "$file_" ] || continue |
|
| 16 |
+ file="$file_" && break |
|
| 17 |
+ done |
|
| 18 |
+fi |
|
| 19 |
+if ! [ "$file" ] |
|
| 20 |
+then |
|
| 21 |
+ echo 'Could not find session.' >&2 |
|
| 22 |
+ exit 1 |
|
| 23 |
+fi |
|
| 24 |
+ |
|
| 25 |
+# session="$(basename "$file")" |
|
| 26 |
+session="${file#$HOME/.mozilla/firefox/}"
|
|
| 27 |
+lz4jsoncat "$file" | jq --arg session "$session" --raw-output ' |
|
| 28 |
+ def time: |
|
| 29 |
+ . / 1000 | strflocaltime("%Y-%m-%d %H:%M:%S");
|
|
| 30 |
+ |
|
| 31 |
+ def entry($isSelected; $lastAccessed): |
|
| 32 |
+ (($isSelected | select(.) | "**") // "") as $bold | |
|
| 33 |
+ ("\($lastAccessed | time): "? // "") as $time |
|
|
| 34 |
+ "\($bold)\($time)[\(.title | @html)](\(.url))\($bold)"; |
|
| 35 |
+ |
|
| 36 |
+ def tabs($selected): |
|
| 37 |
+ to_entries[] | (.key + 1) as $id | .value | |
|
| 38 |
+ ($id == $selected) as $isSlected | |
|
| 39 |
+ .lastAccessed as $lastAccessed | |
|
| 40 |
+ .entries | reverse | |
|
| 41 |
+ (.[0] | "- \(entry($isSlected; $lastAccessed))"), |
|
| 42 |
+ (.[1:][] | " - \(entry(false; null))"); |
|
| 43 |
+ |
|
| 44 |
+ def windows: |
|
| 45 |
+ to_entries[] | (.key + 1) as $id | .value | |
|
| 46 |
+ .selected as $selected | |
|
| 47 |
+ "### Window \($id)", |
|
| 48 |
+ "", |
|
| 49 |
+ "#### Open tabs", |
|
| 50 |
+ "", |
|
| 51 |
+ (.tabs | tabs($selected)), |
|
| 52 |
+ "", |
|
| 53 |
+ "#### Closed tabs", |
|
| 54 |
+ "", |
|
| 55 |
+ ([._closedTabs[].state] | tabs(0)), |
|
| 56 |
+ ""; |
|
| 57 |
+ |
|
| 58 |
+ def session($session): |
|
| 59 |
+ "# Session `\($session)`", |
|
| 60 |
+ "", |
|
| 61 |
+ "| | |", |
|
| 62 |
+ "| --- | --- |", |
|
| 63 |
+ "| Start | \(.session.startTime | time) |", |
|
| 64 |
+ "| Last update | \(.session.lastUpdate | time) |", |
|
| 65 |
+ "", |
|
| 66 |
+ "## Open windows", |
|
| 67 |
+ "", |
|
| 68 |
+ (.windows | windows), |
|
| 69 |
+ "", |
|
| 70 |
+ "## Closed windows", |
|
| 71 |
+ "", |
|
| 72 |
+ (._closedWindows | windows); |
|
| 73 |
+ |
|
| 74 |
+ session($session) |
|
| 75 |
+' |