esport and show FF bookmarks in a webpage

With the help of IA I managed to get Firefox bookmarks

import os
import json
import sqlite3
import shutil
import tempfile

profile_name = "your-profile"  # <-- cambia con il tuo
profile_path = os.path.expanduser(f"~/.mozilla/firefox/{profile_name}")
db_path = os.path.join(profile_path, "places.sqlite")

if not os.path.isfile(db_path):
    print(f"Il file places.sqlite non esiste: {db_path}")
    exit(1)

# Copia temporanea per evitare blocchi
tmp_dir = tempfile.gettempdir()
temp_db_path = os.path.join(tmp_dir, "places_copy.sqlite")
shutil.copy2(db_path, temp_db_path)

conn = sqlite3.connect(temp_db_path)
conn.row_factory = sqlite3.Row
cursor = conn.cursor()

# Preleva tutte le informazioni rilevanti
query = """
SELECT
    b.id,
    b.title,
    b.parent,
    b.type,
    b.fk,
    b.dateAdded,
    p.url,
    ia.content AS description
FROM moz_bookmarks b
LEFT JOIN moz_places p ON b.fk = p.id
LEFT JOIN moz_items_annos ia ON b.id = ia.item_id
LEFT JOIN moz_anno_attributes a_attr ON ia.anno_attribute_id = a_attr.id
WHERE (b.type = 1 OR b.type = 2)
  AND (a_attr.name IS NULL OR a_attr.name = 'bookmarkProperties/description')
ORDER BY b.parent, b.position
"""

cursor.execute(query)
rows = cursor.fetchall()

# Costruisci dizionario gerarchico
items = {row["id"]: {
    "id": row["id"],
    "title": row["title"] if row["title"] else "(senza titolo)",
    "type": "folder" if row["type"] == 2 else "bookmark",
    "url": row["url"] if row["type"] == 1 else None,
    "description": row["description"],
    "children": []
} for row in rows}

# Organizza gerarchia
root = []
for row in rows:
    item = items[row["id"]]
    parent_id = row["parent"]
    if parent_id in items:
        items[parent_id]["children"].append(item)
    else:
        root.append(item)

# Salva in JSON
with open("bookmarks_full.json", "w", encoding="utf-8") as f:
    json.dump(root, f, ensure_ascii=False, indent=2)

print(f"Esportazione completata: {len(root)} cartelle o elementi di primo livello.")
conn.close()
os.remove(temp_db_path)

also selecting a specific bookmark folder

import os
import sqlite3
import shutil
import tempfile
import sys

profile_name = "your-FF-profile"
folder_name_to_export = "[the folder name]"  # Nome della cartella da esportare
output_path = "bookmarks-FF-[a name].php"

# Percorso del profilo
profile_path = os.path.expanduser(f"~/.mozilla/firefox/{profile_name}")
db_path = os.path.join(profile_path, "places.sqlite")

if not os.path.isfile(db_path):
    print(f"Il file places.sqlite non esiste: {db_path}")
    sys.exit(1)

# Copia temporanea del DB
tmp_dir = tempfile.gettempdir()
temp_db_path = os.path.join(tmp_dir, "places_copy.sqlite")
shutil.copy2(db_path, temp_db_path)

conn = sqlite3.connect(temp_db_path)
conn.row_factory = sqlite3.Row
cursor = conn.cursor()

# 1. Query per cartelle e segnalibri (senza tag)
query = """
SELECT
  b.id,
  b.title,
  b.parent,
  b.type,
  b.fk,
  p.url
FROM moz_bookmarks b
LEFT JOIN moz_places p ON b.fk = p.id
WHERE b.type IN (1, 2)
ORDER BY b.parent, b.position
"""

cursor.execute(query)
rows = cursor.fetchall()

# Costruzione struttura
items = {row["id"]: {
    "id": row["id"],
    "title": row["title"] or "(senza titolo)",
    "type": "folder" if row["type"] == 2 else "bookmark",
    "url": row["url"] if row["type"] == 1 else None,
    "description": None,
    "children": []
} for row in rows}

# Costruzione gerarchia
for row in rows:
    item = items[row["id"]]
    parent_id = row["parent"]
    if parent_id in items:
        items[parent_id]["children"].append(item)

# 2. Query per associare tag reali ai segnalibri
tag_query = """
SELECT
  b.id AS bookmark_id,
  GROUP_CONCAT(tg.title, ', ') AS tags
FROM moz_bookmarks b
LEFT JOIN moz_bookmarks bt ON bt.fk = b.fk
LEFT JOIN moz_bookmarks tg ON tg.id = bt.parent AND tg.parent = -3
WHERE b.type = 1
GROUP BY b.id
"""

cursor.execute(tag_query)
tag_rows = cursor.fetchall()

# Assegna i tag ai segnalibri nella struttura
for row in tag_rows:
    bookmark_id = row["bookmark_id"]
    tags = row["tags"]
    if bookmark_id in items:
        items[bookmark_id]["description"] = tags if tags else "(senza tag)"

# Cerca la cartella da esportare
matching_folders = [item for item in items.values()
                    if item["type"] == "folder" and item["title"] == folder_name_to_export]

if not matching_folders:
    print(f"Nessuna cartella trovata con nome '{folder_name_to_export}'.")
    conn.close()
    os.remove(temp_db_path)
    sys.exit(1)

# Funzione per scrivere array PHP
def to_php_array(item, indent=2):
    space = ' ' * indent
    lines = [f"{space}["]
    lines.append(f"{space}  'title' => '{item['title'].replace('\'', '\\\'')}',")
    if item.get("url"):
        lines.append(f"{space}  'url' => '{item['url'].replace('\'', '\\\'')}',")
    if item.get("description"):
        lines.append(f"{space}  'description' => '{item['description'].replace('\'', '\\\'')}',")
    if item.get("children"):
        lines.append(f"{space}  'children' => [")
        for child in item["children"]:
            lines.append(to_php_array(child, indent + 4) + ",")
        lines.append(f"{space}  ],")
    lines.append(f"{space}]")
    return "\n".join(lines)

# Scrittura file PHP
with open(output_path, "w", encoding="utf-8") as f:
    f.write("<?php\nreturn [\n")
    for folder in matching_folders:
        f.write(to_php_array(folder, indent=2))
        f.write(",\n")
    f.write("];\n")

print(f"Esportazione completata in {output_path}")

conn.close()
os.remove(temp_db_path)

and output them in a php webpage

<?php
$segnalibri = include 'bookmarks-FF-[a name].php';

function stampaSegnalibri($items) {
    foreach ($items as $item) {
        echo "<div style='margin-bottom:8px'>";

        if (isset($item['url'])) {
            // titolo come link
            $title_html = htmlspecialchars($item['title'], ENT_QUOTES);
            $url_html = htmlspecialchars($item['url'], ENT_QUOTES);
            echo "<a href=\"$url_html\" target=\"_blank\">$title_html</a>";
        } else {
            // solo titolo testo normale
            echo "<strong>" . htmlspecialchars($item['title'], ENT_QUOTES) . "</strong>";
        }

        // descrizione (se presente)
        if (!empty($item['description'])) {
            $desc_html = htmlspecialchars($item['description'], ENT_QUOTES);
            echo "<br><small style='color: #555;'>$desc_html</small>";
        }

        // figli (ricorsivo)
        if (isset($item['children']) && count($item['children']) > 0) {
            echo "<div style='margin-left:20px; margin-top:4px;'>";
            stampaSegnalibri($item['children']);
            echo "</div>";
        }

        echo "</div>";
    }
}

stampaSegnalibri($segnalibri);
?>

The problem is that FF doesn’t have a description field, and I didn’t manage tgo get it from another filed, such as ‘tags’ one.

Lascia un commento

Il tuo indirizzo email non sarĂ  pubblicato. I campi obbligatori sono contrassegnati *