Quodlibet icon tray in KDE Neon

It could happen that in KDE Neon, the icon tray of Quodlibet, an excellent audio player, works quite wrong: same behavior with the right and the left mouse key.
I solved, with a no-flatpack release, installing indicator-application

sudo apt install indicator-application

and the reboot.

Librewriter for a pdf book

1. number pages

You can add number pages at the footer of your pages

  • in format -> page style -> footer -> Footer on
  • and then, in footer area (by clicking at the bottom) insert -> page number (select mirror to get different alignment for even and odd pages

2. titles in header

You can also create header, with, i.g., the book title (on the even pages) and the chapter title (on the odd ones):

  • in format -> page style -> header -> Header on (deselect same content for left and right pages)
  • and, as above for the footer, going in header area, insert, i.g. in a left page the field title, in a right page, insert -> fields -> Document -> (type: heading, format: heading content). Don’t forget to set the “up to level” (typically : 2, if you want tha names of headings of 2° level, as h2 in html), changing it from 1.

3. bibliografy

You can also add bibliography enter (i.g. in footnotes) and get an automatic bibliografi index at the the end of your file (book/article). These are the steps:

  • Set a “bibliografy entry” (or “citation”): insert -> table of content or index – > bibliografy entry (or “citation”) -> source: document content – new
  • there you have to set, if it is a book, at least the author, the title and the year, and a short name (in Italian, a sigla) to recall it afterwards quicky. (if Journal Article → Author, Title, Year, Journal).
  • Then you can create, typically at the end of your document, the bibliography index: insert -> table of content or index – > table of content or index or bibliography -> type: bibliography, and there you can edit the structure of the items (and their formatting)

Timeout of grub boot

You have to edit grub in /etc/default (i.g. with nano: sudo nano /etc/default/grub)

not only modifying this line: GRUB_TIMEOUT=3

but also adding (after that) this one: GRUB_RECORDFAIL_TIMEOUT=$GRUB_TIMEOUT

Of course after these changes you have to do a

sudo update-grub

as explained here.

Split columns in a pdf

It can happen that you have a pdf with two columns in a page

such as in this image pdf 2 colonne

and you want to split them (i.g. because the ocr is not correct, and you have a text as if was an only column).
A website very useful and easy to make this is online2pdf.

semantic tags

Html5 helps to use semantic tags, but only in some cases.

Dates

I.g. for a date you can use <time>

    <p>La conferenza si terrà il <time datetime="2025-11-14">14 novembre 2025</time>.</p>

Books

Far more complicated is the way for the books. There is not a tag such as <book>. Unfortunately, the Internet is not for the truth, but for commercial purposes, so you have to follow a very long and annoying way:

     <h1>List of Books</h1>

    <div itemscope itemtype="http://schema.org/Book">
        <h2 itemprop="name">The Great Gatsby</h2>
        <img src="cover-gatsby.jpg" alt="Cover of The Great Gatsby" itemprop="image">
        <p itemprop="author">F. Scott Fitzgerald</p>
        <p itemprop="description">The Great Gatsby is a novel written by F. Scott Fitzgerald and published in 1925. The story is set in 1922 during the Jazz Age and the economic prosperity of the United States.</p>
    </div>

    <div itemscope itemtype="http://schema.org/Book">
        <h2 itemprop="name">1984</h2>
        <img src="cover-1984.jpg" alt="Cover of 1984" itemprop="image">
        <p itemprop="author">George Orwell</p>
        <p itemprop="description">1984 is a dystopian novel written by George Orwell and published in 1949. The story is set in a future dystopia where the totalitarian government controls every aspect of citizens' lives.</p>
    </div>

    <div itemscope itemtype="http://schema.org/Book">
        <h2 itemprop="name">Moby Dick</h2>
        <img src="cover-moby-dick.jpg" alt="Cover of Moby Dick" itemprop="image">
        <p itemprop="author">Herman Melville</p>
        <p itemprop="description">Moby Dick is a novel written by Herman Melville and published in 1851. The story follows the obsessive quest of Captain Ahab to hunt down the white whale, Moby Dick.</p>
    </div>

another example:

<tr itemscope itemtype="http://schema.org/Book"><td><span itemprop="name">Traumdeutung</span></td>
<td><span itemprop="alternativeHeadline"> L'interpretazione dei sogni</span></td><td><span itemprop="datePublished" content="1900">1900</span></td></tr>
<tr itemscope itemtype="http://schema.org/Book"><td><span itemprop="name">Zur Psychopathlogie des Altagslebens</span></td>
<td><span itemprop="alternativeHeadline"> Psicopatologia della vita quotidiana</span></td><td><span itemprop="datePublished" content="1901">1901</span></td></tr>

other book’s tags

<span itemprop=”locationCreated”>

<span itemprop=”bookEdition”> (for Edition)

<span itemprop=”author”> (for Author)

Movies

You could use a code like the following:

<div itemscope itemtype="http://schema.org/Movie">
  <h1 itemprop="name">The Godfather</h1>
  <h2 itemprop="alternateName">Il Padrino</h2>
  <img itemprop="image" src="https://example.com/locandina_il_padrino.jpg" alt="Locandina del film Il Padrino">
  <p>Regista: <span itemprop="director">Francis Ford Coppola</span></p>
  <p>Data di rilascio: <span itemprop="releaseDate">15 marzo 1972</span></p>
</div>
more here.

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.

mysqli missing extension (in Linux)

Check if your php version is in apache mods-enabled (in /etc/apache2/mods-enabled).
Your current php should be in /etc/apache2/mods-available but not (if you have several php versions) in /etc/apache2/mods-enabled.

Tab session manager problem in Vivaldi

Recently I had a problem with Tab session manager in Vivaldi: impossible to see my sessions, and to add new ones.

I solved in Tab session manager settings in a very simple and easy way: disabling and re-enabling Tab session manager, with a simple mouse click in Vivaldi extensions.

Monetag? No, thanks!

Pro: automation of ads.
Cons: impossible to customize the type of ads. Therefore banal and vulgar advertising.