From bc1c54af820762464a9c995d6c0e5c64baf4fd17 Mon Sep 17 00:00:00 2001
From: "suzanne.soy" <suzanne.soy.gitlab@suzanne.soy>
Date: Fri, 9 Oct 2020 06:08:49 +0100
Subject: [PATCH] Export bookmarksbackup from firefox

---
 export-firefox-bookmarksbackup.sh | 23 +++++++++++++++++++++++
 export-firefox-tabs.sh            | 29 +++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+)
 create mode 100755 export-firefox-bookmarksbackup.sh
 create mode 100755 export-firefox-tabs.sh

diff --git a/export-firefox-bookmarksbackup.sh b/export-firefox-bookmarksbackup.sh
new file mode 100755
index 0000000..7e480c5
--- /dev/null
+++ b/export-firefox-bookmarksbackup.sh
@@ -0,0 +1,23 @@
+#!/usr/bin/env nix-shell
+#!nix-shell --pure -i bash -p dejsonlz4 jq bash -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/fea633695211167753ee732c9087808d0c57461c.tar.gz
+
+# Usage: ./export-firefox-bookmarks.sh [path/to/.mozilla/firefox/XXXXXXXX.profile]
+
+set -euET -o pipefail
+
+if test $# -ge 1; then
+  profile="$1"
+else
+  # use printf to avoid echo's ambiguity; sort for determinism; use null separator (only byte illegal in UNIX paths, save trailing whitespace with a dummy x (not needed here as the string ends with "default", but a good habit nonetheless)
+  profile="$(printf "%s"\\0 ~/.mozilla/firefox/*.default | sort -z | head -z -n 1 | tr -d \\0; printf "x")"
+  profile="${profile%x}"
+fi
+
+  # use printf to avoid echo's ambiguity; sort to get latest backup; use null separator (only byte illegal in UNIX paths, save trailing whitespace with a dummy x (not neede here as the string ends with ".jsonlz4" but a good habit nonetheless)
+js="$(printf "%s"\\0 "$profile"/bookmarkbackups/bookmarks-*.jsonlz4 | sort -z --general-numeric-sort | tail -z -n 1 | tr -d \\0; printf "x")"
+js="${js%x}"
+
+# TODO: filter out entries whose uri is null after checking that they're not important
+# TODO: add folder structure to give a path for each bookmark
+
+dejsonlz4 "$js" | jq 'recurse(.children?[]?) | "\( .title? ): \( .uri? )"'
diff --git a/export-firefox-tabs.sh b/export-firefox-tabs.sh
new file mode 100755
index 0000000..897ba97
--- /dev/null
+++ b/export-firefox-tabs.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env nix-shell
+#!nix-shell --pure -i bash -p dejsonlz4 jq bash -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/fea633695211167753ee732c9087808d0c57461c.tar.gz
+
+# Usage: ./export-firefox-bookmarks.sh [path/to/.mozilla/firefox/XXXXXXXX.profile]
+
+set -euET -o pipefail
+
+if test $# -ge 1; then
+  profile="$1"
+else
+  # use printf to avoid echo's ambiguity; sort for determinism; use null separator (only byte illegal in UNIX paths, save trailing whitespace with a dummy x (not needed here as the string ends with "default", but a good habit nevertheless)
+  profile="$(printf "%s"\\0 ~/.mozilla/firefox/*.default | sort -z | head -z -n 1 | tr -d \\0; printf "x")"
+  profile="${profile%x}"
+fi
+
+if test -e "$profile"/sessionstore-backups/recovery.jsonlz4; then
+  sessionstore="$profile"/sessionstore-backups/recovery.jsonlz4
+elif test -e "$profile"/sessionstore.jsonlz4; then
+  sessionstore="$profile"/sessionstore.jsonlz4
+elif test -e "$profile"/sessionstore.js; then
+  sessionstore="$profile"/sessionstore.js
+else
+  printf "Could not find session store at $profile/sessionstore-backups/recovery.jsonlz4 or $profile/sessionstore.jsonlz4 or $profile/sessionstore.js"
+  exit 1
+fi
+
+# TODO: when the name is sessionstore.js, it might not need a decompression with dejsonlz4 ?
+# Tabs from all windows are printed together, edit the jq expression to your needs. The input format is described at https://wiki.mozilla.org/Firefox/session_restore#For_developers
+dejsonlz4 "$sessionstore" | jq '.windows[].tabs[].entries[-1].url'