Aggiungere GeoGebra alle applicazioni.

GeoGebra è un software open‑source per la didattica della matematica e della geometria dinamica.

Quello che intendiamo qui con “geometria dinamica” è un approccio all’insegnamento e alla sperimentazione della geometria in cui le costruzioni non sono “fisse” su carta, ma “vive”: ogni elemento può essere spostato e il disegno si aggiorna in tempo reale rispettando i vincoli geometrici impostati.

Caratteristiche principali

  • Interattività: punti, segmenti, rette, cerchi… possono essere trascinati con il mouse, e tutte le parti collegate si ridisegnano automaticamente.
  • Vincoli parametrizzati: si definiscono relazioni (perpendicolarità, parallelismo, congruenza, misura fissa di lunghezze o angoli…), e lo strumento mantiene queste condizioni anche quando modifichi le figure.
  • Esplorazione e scoperta: anziché leggere un teorema su un libro e poi disegnarlo staticamente, puoi sperimentare direttamente come cambiano gli angoli, le misure e le posizioni, cogliendo al volo pattern e proprietà.
  • Validazione immediata: se costruisci, per esempio, un quadrilatero sempre con angoli opposti supplementari, vedrai subito – spostando un vertice – che la somma dei due angoli rimane 180°.

Vantaggi didattici

  • Rende più intuitivi i concetti astratti: vedere una parabola “muoversi” quando cambi un punto di costruzione aiuta a capire perché la definizione funziona.
  • Sviluppa un approccio sperimentale e competente nella dimostrazione: l’allievo non si limita ad accettare un enunciato, ma può verificarne la validità in mille casi diversi e poi ragionare sul “perché”.
  • Favorisce la creatività: si possono esplorare con facilità configurazioni inedite, provare con poligoni regolari, esplorare locus geometrici…

Esempi di software

  • GeoGebra: probabilmente il più diffuso, combina geometria dinamica, algebra e calcolo; supporta anche la creazione di applet per il web.
  • Cabri Géomètre (storico), Cinderella, The Geometer’s Sketchpad, GeoMedia, ecc.

Geogebra per Gnome/Linux

Su molte distribuzioni Linux Geogebra lo si trova comodamente nel Software Center, ma scaricare il pacchetto portatile in formato tar.gz permette di avere sempre a disposizione l’ultima versione senza dipendenze aggiuntive. In questo articolo vedremo come scaricare GeoGebra, estrarre l’archivio e configurarne manualmente il lanciatore in GNOME Shell.

Per scaricare la mia versione Linux ho visitato il sito e sono andato alla sezione GeoGebra Classic 5 for Desktop,, dopodiché si procede qui: Linux Portable: Portable Linux bundle for 64-bit Linux systems (unsupported)

Siatemiamo la versione di GeoGebra scaricata nella cartella “Scaricati”, pronta per partire…

Un veloce

$ cd GeoGebra-Linux-Portable-5-2-893-2
chmod +x geogebra-portale

Il file risulta quindi eseeguibile: quando finalmente lanci l’app da terminale, la tanto desiderata icona personalizzata non compare né nella barra delle applicazioni (ne compare una generica, la rotellina dentata), né nell’elenco dei preferiti di GNOME Shell.

Eppure il file di configurazione c’era già, e sembrava perfetto:

$ cat ~/.local/share/applications/geogebra.desktop

[Desktop Entry]
Version=1.0
Type=Application
Name=GeoGebra 5 Portable
Exec=/home/marcob/Scaricati/geoGebra/.../geogebra-portable
Icon=/home/marcob/Scaricati/geoGebra/geogebra.big.png
Terminal=false

Alla fine il trucco stava tutto in due dettagli:

  • Il tema icone di GNOME non ama i percorsi assoluti, preferisce pescare le immagini dalle sue cartelle standard.
  • GNOME Shell deve poter “riconoscere” la finestra in esecuzione come figlia del tuo .desktop, altrimenti usa l’icona generica e disabilita pure il clic destro → “Aggiungi ai preferiti”, che infatti non compariva nel menu di scelta del tasto destro..

Ecco come abbiamo risolto, in due mosse ben precise:

1. Installare l’icona nel tema Hicolor
Abbiamo creato la cartella utente

~/.local/share/icons/hicolor/256x256/apps

e ci abbiamo piazzato dentro la PNG rinominata in “geogebra.png”.
L’icona l’ho cercata col sistema di ricerca di immagini di DuckDuckGo, ho scaricato una PNG e ho prodotto le varie icone:

$ convert logo.png \
  -define icon:auto-resize=256,128,64,48,32,16 \
  geogebra-icon.ico

Un rapido

update-icon-caches ~/.local/share/icons/hicolor

ha fatto il resto, rendendo disponibile l’icona a tutto il sistema.

2. Allineare il launcher al WM_CLASS dell’app
Con xprop WM_CLASS abbiamo scoperto che GeoGebra identifica le sue finestre come, ad esempio, Geogebra5. A questo punto, basta aggiungere al file ~/.local/share/applications/geogebra.desktop le due righe magiche all’inizio del file:

StartupNotify=true
StartupWMClass=Geogebra5
Icon=geogebra

E trasformare il .desktop in eseguibile (chmod +x …). Un rapido Alt+F2 → r (reload della shell) ed ecco l’icona nel Dash, pronta per essere aggiunta ai Preferiti con un click destro e – finalmente! – fissa nella barra delle applicazioni.

geogebra Icon gome applications
geogebra Icon gome applications

Adesso, ogni volta che avvieremo GeoGebra dalle “Attività” (il segmentino orizzontale in alto a sinistra, oppure premendo il tasto Windows), vedremo il logo corretto, che potremo fissare alla barra delle applicazioni in un lampo, senza perderci più in percorsi assoluti o icone sbagliate.

Un piccolo esercizio da vero “power user” di GNOME, e una bella lezione sulla gestione delle risorse grafiche in Linux.

Buon lavoro con GeoGebra, e buon divertimento nella personalizzazione del desktop!

Come creare uno slideshow di sfondi personalizzati in Ubuntu (GNOME)


Gnome open source free spftware linux desktop environment
Gnome open source free spftware linux desktop environment

Negli ambienti desktop basati su GNOME, come Ubuntu, è possibile impostare uno sfondo che cambia automaticamente nel tempo, come una presentazione. Quello che molti non sanno è che GNOME supporta nativamente gli slideshow tramite file XML, e che lo slideshow con il “cronometrino” visibile nella sezione Aspetto delle impostazioni è un esempio di questo meccanismo.

In questa guida vedremo come creare un nostro slideshow personalizzato con immagini a piacere, farlo comparire nella GUI di GNOME e attivarlo come sfondo dinamico.

Preparazione delle immagini

GNOME accetta solo percorsi di sistema per gli slideshow, per cui le immagini vanno copiate in una directory accessibile globalmente, come /usr/share/backgrounds/.

Per esempio, possiamo creare una nuova cartella e copiarci dentro le nostre immagini:

sudo mkdir -p /usr/share/backgrounds/apod
sudo cp ~/Immagini/Sfondi_APOD/* /usr/share/backgrounds/apod/

Creazione dello slideshow

Lo slideshow viene definito da un file XML con una struttura precisa. Possiamo generarlo automaticamente con uno script bash. Ecco uno script che crea il file /usr/share/backgrounds/apod_slideshow.xml con durata di 30 minuti per ogni immagine e transizioni di 5 secondi:

#!/bin/bash

IMAGES_DIR="/usr/share/backgrounds/apod"
OUTPUT="/usr/share/backgrounds/apod_slideshow.xml"
DURATION=1800.0
TRANSITION=5.0

sudo bash -c "cat > '$OUTPUT' <<EOF
<?xml version=\"1.0\"?>
<background>
  <starttime>
    <year>2025</year>
    <month>07</month>
    <day>04</day>
    <hour>00</hour>
    <minute>00</minute>
    <second>00</second>
  </starttime>
EOF"

IMAGES=(\$(find \"\$IMAGES_DIR\" -type f \( -iname '*.jpg' -o -iname '*.png' \) | sort))
NUM_IMAGES=\${#IMAGES[@]}

for ((i=0; i<NUM_IMAGES; i++)); do
    FROM=\${IMAGES[\$i]}
    TO=\${IMAGES[\$(( (i+1)%NUM_IMAGES ))]}

    sudo bash -c "cat >> '$OUTPUT' <<EOF
  <static>
    <duration>\$DURATION</duration>
    <file>\$FROM</file>
  </static>
  <transition>
    <duration>\$TRANSITION</duration>
    <from>\$FROM</from>
    <to>\$TO</to>
  </transition>
EOF"
done

sudo bash -c "echo '</background>' >> '$OUTPUT'"

Salva questo script in un file .sh, rendilo eseguibile con chmod +x e lancialo. Il file XML verrà generato correttamente nella directory di sistema.

Registrazione dello slideshow nella GUI

Per far apparire lo slideshow tra gli sfondi selezionabili nella sezione Aspetto, è necessario creare un file descrittore in /usr/share/gnome-background-properties/. Ecco un esempio:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE wallpapers SYSTEM "gnome-wp-list.dtd">
<wallpapers>
  <wallpaper deleted="false">
    <name>NASA APOD Slideshow</name>
    <filename>/usr/share/backgrounds/apod_slideshow.xml</filename>
    <options>scaled</options>
    <pcolor>#000000</pcolor>
    <scolor>#ffffff</scolor>
    <shade_type>solid</shade_type>
  </wallpaper>
</wallpapers>

Nell’opzione options è possibile impostare scaled se si vuole che l’immagine venga riscalata (come ho preferito in questo caso). I possibili valori sono riassunti in uqesta tabella

ValoreComportamento
centeredImmagine centrata, nessun ridimensionamento
scaledScala per entrare nello schermo
stretchedDeforma per riempire lo schermo
zoomRiempie mantenendo proporzioni (può sgranare)
spannedSu più monitor, come un unico sfondo

Salva questo file come /usr/share/gnome-background-properties/apod-slideshow.xml. Dopo averlo fatto, apri di nuovo le impostazioni di GNOME: nella sezione Aspetto vedrai una nuova voce con il nome indicato nel campo <name>, accompagnata dal simbolo del cronometro. Selezionandola, attiverai lo slideshow appena creato.

Questo metodo sfrutta direttamente le funzionalità native di GNOME, senza bisogno di strumenti esterni come Variety. È ideale se vuoi uno sfondo dinamico elegante, discreto e completamente personalizzabile, che rispetti le logiche del sistema e venga integrato perfettamente nella GUI.

Puoi aggiornare le immagini quando vuoi: ti basta sostituirle nella cartella /usr/share/backgrounds/apod/ e rigenerare il file XML con lo script.


Scaricare immagini dalla NASA

Le immagini pubblicate quotidianamente dalla NASA attraverso il servizio Astronomy Picture of the Day (APOD) sono un’ottima fonte di sfondi spettacolari. Sono liberamente utilizzabili perché rilasciate nel pubblico dominio. Per scaricarle in modo automatizzato si può utilizzare l’API ufficiale messa a disposizione dalla NASA, accessibile gratuitamente previa registrazione su api.nasa.gov. Una volta ottenuta la chiave di accesso (API key), è possibile scrivere uno script che interroga l’API per ottenere l’immagine del giorno, ne estrae il collegamento ad alta risoluzione e la salva in una cartella locale.

Un esempio di script bash potrebbe interrogare l’API per un certo numero di giorni passati, scaricare le immagini disponibili e salvarle in una directory temporanea. Da lì è poi possibile copiarle in /usr/share/backgrounds/apod/, come descritto in precedenza, ed eventualmente rigenerare lo slideshow. Va tenuto presente che l’API non consente di filtrare le immagini in base alla risoluzione o all’orientamento, quindi potrebbe essere necessario un controllo manuale o automatico a posteriori, ad esempio per escludere immagini verticali o troppo piccole.

In questo modo è possibile costruire uno slideshow di sfondi aggiornato con immagini astronomiche sempre nuove, sincronizzate con la pubblicazione quotidiana della NASA.

Valutare la qualità e la velocità dei modelli Whisper: un esperimento pratico

Riconoscimento vocale con Whisper
Riconoscimento vocale con Whisper

Negli ultimi giorni ho condotto una piccola sperimentazione con Whisper, il modello di riconoscimento vocale automatico (ASR) open source sviluppato da OpenAI. L’obiettivo era duplice:

  1. Registrare l’audio del sistema in modo pulito (senza passare dal microfono)
  2. Valutare le prestazioni e l’accuratezza dei modelli tiny, base e small di Whisper, cercando una misura sintetica della loro “efficienza complessiva”

Cos’è Whisper

Whisper consente di trascrivere il parlato contenuto in un file audio producendo un file di testo.

E’ un sistema di riconoscimento vocale automatico (Automatic Speech Recognition, ASR) rilasciato da OpenAI nel 2022. È basato su una rete neurale di tipo transformer e addestrato su un enorme corpus di dati multilingue e multitask. Whisper è capace di:

  • Trascrivere audio parlato in testo
  • Tradurre automaticamente parlato in inglese
  • Riconoscere e segmentare parlato in presenza di rumore di fondo

Uno degli aspetti più interessanti è che Whisper è open source e facilmente utilizzabile da linea di comando o come libreria Python. Supporta vari modelli di dimensioni crescenti, dal più piccolo (tiny) al più grande (large), con diversi trade-off tra velocità e accuratezza.

Registrazione pulita con PulseAudio e Audacity

Utilizzando pavucontrol su Ubuntu, è possibile registrare direttamente ciò che il sistema riproduce, senza microfoni.

Infatti in prima battuta facevo funzionare il browser che riproduceva il video e registravo l’audio con il microfono del PC: un setup abastanza ingenuo e primitivo.

La chiave è selezionare come sorgente di registrazione:

Monitor of Built-in Audio Analog Stereo

In Audacity basta:

  • Premere “Record”
  • Selezionare la sorgente giusta da pavucontrol (scheda “Registrazione”)

Il risultato è una traccia audio digitale e pulita, ideale per testare Whisper.

Trascrizione automatica con Whisper

Whisper supporta modelli di diverse dimensioni, con un compromesso tra:

  • Velocità di esecuzione (più piccolo è il modello, più è veloce)
  • Qualità della trascrizione (i modelli più grandi sono più accurati)

I comandi utilizzati:

whisper test.wav --language Italian --model small --output_dir small --output_format all

Ripetuto per tiny, base e small, salvando i risultati in sottodirectory dedicate.

Una tabella riassuntiva sui modelli ci mostra le caratteristiche di ognuno:

ModelloParametriDimensione fileNote
tiny≈ 39 milioni~75 MBVelocissimo, ma meno preciso
base≈ 74 milioni~142 MBBuon compromesso leggero
small≈ 244 milioni~462 MBPiù lento, ma molto più accurato

La metrica che unisce qualità e prestazioni

Durante il confronto, ho voluto trovare una figura di merito (FdM) che combinasse:

  • WER (Word Error Rate): misura quanto il testo trascritto è fedele
  • RTF (Real-Time Factor): tempo impiegato per trascrivere diviso la durata dell’audio

La formula che ho adottato è:

\textit{FdM} = \frac{1-\textit{WER}}{1+RTF}

Più è alta, migliore è il modello.


Risultati su un frammento audio “sporco”

Test su una frase:

Il sistema SRFC si rivolge a persone con esperienza maturata in contesti di istru…

Risultati:

Modello    | Durata audio | Tempo impiegato | RTF   | WER       | FdM
-----------------------------------------------------------------------
tiny       |        8.00s |           0.65s | 0.08  | 28.57%    | 0.66
base       |        8.00s |           0.91s | 0.11  | 35.71%    | 0.58
small      |        7.00s |           2.37s | 0.34  | 7.14%     | 0.69

Osservazioni:

  • small è il più accurato, nonostante sia più lento
  • tiny sorprende: pur essendo meno preciso, ha una FdM superiore a base
  • base in questo caso è il peggiore compromesso

Specifiche del sistema di test

Tutti i benchmark sono stati eseguiti su una macchina con le seguenti caratteristiche:

  • CPU: Intel® Core™ i5-1235U (12th Gen)
  • Architettura: x86_64, 10 core (2 performance + 8 efficient), 12 thread
  • Frequenza massima: 4.4 GHz
  • RAM: [aggiungere se si vuole, es. 16 GB DDR4]
  • Sistema operativo: Ubuntu con Whisper in ambiente venv (Python 3.12)
  • Note: elaborazione solo su CPU, senza accelerazione GPU

Considerazioni finali

Questa esperienza mostra innanzitutto che una registrazione pulita è fondamentale per la qualità della trascrizione; l’accuratezza e la velocità possono essere combinate in una metrica utile. Infine la dimensione small del modello è un ottimo compromesso su CPU se si accetta un RTF più alto

Il pensiero di combinare RTF e WER in un indice sintetico è nato spontaneamente durante il lavoro: un piccolo segnale che la mente umana ha ancora margine per affiancare (e talvolta superare) l’intelligenza artificiale.

Note bibliografiche

  • RTF (Real-Time Factor) è definito come il rapporto tra il tempo di elaborazione e la durata del file audio. Se un sistema ha un RTF = 1, significa che lavora in tempo reale. Vedi anche:
  • WER (Word Error Rate) è la metrica classica per valutare i sistemi ASR, calcolata come:
    • = sostituzioni= cancellazioni= inserzioni= numero di parole nella trascrizione di riferimento

Riferimenti

  • Wikipedia – Word Error Rate
  • “Automatic Evaluation of Machine Translation Quality Using Longest Common Subsequence and Skip-Bigram Statistics” — Lin and Och (2004)

Scritto con l’aiuto di Whisper, Python e un po’ di caffeina.

Sicnronizzare due directory su due computer con rsync

sync come strumento di sincroizzazione tra archivi

Utilizzo intercambiabilmente due PC e preferisco mantenere in locale (non su cloud) i contentuti di due directory, per maggior sicurezza.

Nell’ambito di una qualsiasi rete locale in cui collego i due pc voglio che una volta al giorna queste irectory vengano sincronizzate.

Solitamente utilizzo Samba per collegare la directory di PC1 montandola in PC2. L’uso di GVFS però non consente a rsync di lavorare bene perché non riesce la gestione dei diritti di accesso dei file.

Ho superato questo problema smontando la direcory remota e rimontandola a mano con mount.

Quindi le tre operazioni da fare sono:

  • montare in PC2 la directory /home/marcob/clienti/#PC1
  • lanciare rsync
  • creare un cron job per eseguire questo allineamento una volta al giorno mentre sono in pausa.

rsync versione 1

#!/bin/bash
sudo mount -t cifs //10.1.23.245/sambashare /mnt/sambashare -o username=marcob,password=XXXXX,uid=$(id -u),gid=$(id -g),file_mode=0777,dir_mode=0777
rsync -av --progress /home/marco/Documenti/clienti/ /mnt/sambashare/clienti/

Ora però non voglio specificare l’indirizzo IP, preferendo affidarmi piuttosto al DNS (o al file /etc/hosts), in modo tale che lo script funzioni indipendentemente dalla rete in cui mi trovo.

Una seconda tecnica che voglio utilizzare è quella dei secrets in mofdo tale che le informazioni riservate come le credensiali di accesso non siano scritte nello script ma vengano lette da un file locale di configurazione accessibile solo al processo.

La terza cosa che desidero è che tutti i parametri non sensibii siano scitti un un secondo file di configurazione.

rsync ersione finale

La versione finale avrà dunque tre file principali:

  1. Lo script di sincronizzazione (sync_samba.sh)
  2. Il file di configurazione (samba_sync.conf)
  3. Il file dei secrets (/etc/samba/sync_credentials)

Creazione del file di configurazione

Crea un file chiamato samba_sync.conf per definire i parametri di montaggio e sincronizzazione:

# File di configurazione: samba_sync.conf

# Nome host o IP della condivisione Samba
SERVER="js"

# Nome della condivisione Samba
SHARE="sambashare"

# Directory di mount
MOUNT_POINT="/mnt/sambashare"

# Percorso locale dei file da sincronizzare
LOCAL_PATH="/home/marco/Documenti/clienti/"

# Percorso remoto nella condivisione Samba
REMOTE_PATH="clienti/"

# Versione del protocollo SMB (modificabile se necessario)
SMB_VERSION="3.0"

# Percorso del file dei secrets (non deve essere leggibile da altri utenti!)
CREDENTIALS_FILE="/etc/samba/sync_credentials"

Salvo questo file nella directory /etc/samba/ così posso condividerlo tra più script.


Creazione del file dei secrets (per sicurezza)

Creiamo il file /etc/samba/sync_credentials per contenere le credenziali:

username=marcob
password=XXXXX

Salvo con permessi restrittivi per evitare che altri utenti possano leggerlo:

sudo chmod 600 /etc/samba/sync_credentials

Script di sincronizzazione (sync_samba.sh)

Ora creiamo lo script sync_samba.sh per montare, sincronizzare e smontare la condivisione.

#!/bin/bash

# Carica il file di configurazione
CONFIG_FILE="$(dirname "$0")/samba_sync.conf"
if [ ! -f "$CONFIG_FILE" ]; then
    echo "Errore: File di configurazione '$CONFIG_FILE' non trovato!"
    exit 1
fi
source "$CONFIG_FILE"

# Controlla che il file delle credenziali esista
if [ ! -f "$CREDENTIALS_FILE" ]; then
    echo "Errore: File delle credenziali '$CREDENTIALS_FILE' non trovato!"
    exit 1
fi

# Controlla se la condivisione è già montata
if mountpoint -q "$MOUNT_POINT"; then
    echo "La condivisione è già montata su $MOUNT_POINT"
else
    echo "Montando la condivisione Samba..."
    sudo mount -t cifs "//$SERVER/$SHARE" "$MOUNT_POINT" -o credentials="$CREDENTIALS_FILE",uid=$(id -u),gid=$(id -g),file_mode=0777,dir_mode=0777,vers=$SMB_VERSION
    if [ $? -ne 0 ]; then
        echo "Errore: Impossibile montare la condivisione Samba."
        exit 1
    fi
fi

# Esegue la sincronizzazione con rsync
echo "Avvio della sincronizzazione..."
rsync -av --progress "$LOCAL_PATH" "$MOUNT_POINT/$REMOTE_PATH"
if [ $? -eq 0 ]; then
    echo "Sincronizzazione completata con successo."
else
    echo "Errore durante la sincronizzazione!"
    exit 1
fi

# Smonta la condivisione
echo "Smontando la condivisione..."
sudo umount "$MOUNT_POINT"
if [ $? -eq 0 ]; then
    echo "Condivisione smontata correttamente."
else
    echo "Attenzione: impossibile smontare la condivisione!"
    exit 1
fi

Rendiamolo eseguibile:

chmod +x sync_samba.sh

Utilizzo dello script

Ora possiamo eseguire il tuo script in qualsiasi rete, senza bisogno di specificare l’IP:

./sync_samba.sh
...
vpn/fortinet/settings.png
         77.301 100%  208,53kB/s    0:00:00 (xfr#5522, to-chk=9/13473)
vpn/fortinet/test.ods
         15.581 100%   41,92kB/s    0:00:00 (xfr#5523, to-chk=8/13473)
vpn/fortinet/unlicensed.png
         56.307 100%  151,48kB/s    0:00:00 (xfr#5524, to-chk=7/13473)
vpn/fortinet/update_firefox_chrome.txt
            804 100%    2,16kB/s    0:00:00 (xfr#5525, to-chk=6/13473)
vpn/fortinet/version.png
         60.212 100%  132,14kB/s    0:00:00 (xfr#5526, to-chk=5/13473)
vpn/fortinet/vulnus.png
         58.945 100%  100,28kB/s    0:00:00 (xfr#5527, to-chk=4/13473)
vpn/ftp/
vpn/ftp/FileZilla.xml
         13.691 100%   19,46kB/s    0:00:00 (xfr#5528, to-chk=3/13473)
vpn/ftp/connection_refused.png
         15.255 100%   21,62kB/s    0:00:00 (xfr#5529, to-chk=2/13473)
vpn/ftp/connection_refused_da_prometeo.png
        259.856 100%  283,85kB/s    0:00:00 (xfr#5530, to-chk=1/13473)
vpn/girondi/
vpn/girondi/Default.txt
            455 100%    0,50kB/s    0:00:00 (xfr#5531, to-chk=0/13473)
vpn/prova/

sent 3.880.680.485 bytes  received 133.663 bytes  7.166.785,13 bytes/sec
total size is 8.226.028.213  speedup is 2,12
Sincronizzazione completata con successo.
Smontando la condivisione...
Condivisione smontata correttamente.

Voglio ora schedulare l’operazione periodicamente con cron, apriamo crontab:

crontab -e

e aggiungo una riga per eseguire lo script ogni giorno alle 13:

0 13 * * * /usr/local/bin/sync_samba.sh >> /var/log/samba_sync.log 2>&1

Vantaggi di questa soluzione

Sicurezza: Le credenziali sono protette e non visibili nello script.
Flessibilità: Il file di configurazione permette di cambiare i parametri senza modificare lo script.
Automazione: Puoi schedulare l’esecuzione con cron.
Adattabilità: Funziona su diverse reti senza bisogno di cambiare IP.


Copiare utilizzare i data source in un report BIRT

Sto progettando un report con BIRT (Business Intellgence and Report Tool), un tool di Eclipse.

Avevo questo problema: non volendo cablare nel template design i parametri della sorgente dati, ma piuttosto acquisirli da un file di configurazione esterno, ho visto che è possibile creare delle source library da posizionare nella stessa cartella del report.

Così in ambiente di sviluppo punto alla library che si connette al database di sviluppo e in produzione, posizionando nella cartella corrispondente del report lo stesso file con le coordinate della produzione, troverò la connessione alla produzione.

In questo modo il report è indipendente dal database.

L’inghippo era questo: creavo la library a non riuscivo a importarla nel data source.

Se tentavo di crearne una potevo solo ricrearla da zero perdendo il vantaggio del disaccoppiamento, ma non ptevo in nessun mod importarla dalla library. Non ho trovato alcun aiuto da nessuna parte. Anzi Chat GPT è stato piuttosto confusionario facendomi agire su punti della GUI inessenziali allo scopo.

Alla fine il metodo buono è questo:

  1. Creare la source library posizionando il file rptdesign nella direcotry del report
  2. Quando si apre il report con BIRT, la library comparirà sotto Outline > Libraries
  3. Nella parte destra dello schermo c’è una tab Resource Explorer: selezionarla
  4. Appare la library con il data source: cliccare sul data source e con tasto destro selzionare “Add to report”

Fine.

Risorsa Samba non più raggiungibile

Mi prendo un appunto su questo problema e la soluzione che ho trovato con GPT.

Problema

Improvvisamente (in realtà ieri ho fatto un aggiornamento di Windows) dalla mia macchina Windows non riesco più ad accedere alla risorsa ssamba montata sul mio “muletto” Ubuntu Linux jsbach. Quando tento di montare la risorsa Samba mi compare la maschera di autenticazione ma anche fornendo le credenziali corrette mi viene rifiutato l’accesso.

Soluzione

Sono necessarie modifiche da entrambe le parti (Linux/Windows)

Ubuntu

Questa è la sezione SambaShare (/etc/samba/smb.conf):

[SambaShare]
   comment = Directory Condivisa Samba
   path = /home/marcob/sambashare
   browseable = yes
   writable = yes
   guest ok = no
   read only = no
   force user = marcob
   user = marcob
   ;valid user = Marco
   public = yes

Considerando che il file smb.conf funzionava correttamente fino a poco tempo fa e il problema si è verificato solo ora, è importante distinguere tra eventuali aggiornamenti di Samba o cambiamenti nelle policy di rete Windows. Procediamo con un’analisi più approfondita


1. Direttiva non valida: user

La direttiva user in Samba non è più valida. Potrebbe essere ignorata fino a un certo punto, ma con aggiornamenti recenti di Samba (o altre librerie correlate), l’opzione non riconosciuta ora potrebbe causare errori. Per sicurezza, rimuovo e aggiorno la configurazione della condivisione come segue:

[SambaShare]
   comment = Directory Condivisa Samba
   path = /home/marcob/sambashare
   browseable = yes
   writable = yes
   guest ok = no
   read only = no
   force user = marcob
   valid users = marcob
   public = no

Modifiche principali:

  1. Rimossa user (non valida).
  2. Corretto valid users, abilitando l’utente corretto.
  3. Impostato public = no, coerente con guest ok = no (public è legato agli accessi guest).

2. Aggiorna Samba dopo la modifica

Dopo aver aggiornato il file, verifico e applico le modifiche:

  1. Verifica il file di configurazione: testparm Controlla eventuali errori o avvisi.
  2. Riavvia Samba: sudo systemctl restart smbd nmbd

3. Controlla l’utente Samba

Verifica che l’utente marcob esista nel database di Samba e che abbia una password correttamente configurata. Aggiungi o aggiorna l’utente con:

sudo smbpasswd -a marcob

Se hai già configurato l’utente, conferma semplicemente la password. Tutto OK.


Windows

Controlla le policy di sicurezza di Windows

Il messaggio di errore “i criteri di sicurezza dell’organizzazione bloccano l’accesso guest non autenticato” è spesso legato a modifiche nelle impostazioni di Windows per SMB. Recentemente, Microsoft ha rinforzato le regole per SMB1, disabilitando l’accesso guest per motivi di sicurezza.

Ecco come risolvere:

  1. Abilita l’accesso autenticato (NTLMv2):
  • Premi Win+R, digita secpol.msc e premi Invio.
  • Vai su Criteri locali -> Opzioni di sicurezza.
  • Cerca Criteri di rete: livello di autenticazione LAN Manager e impostalo su: Invia risposta NTLMv2 se negoziato
  • Riavvia il PC Windows dopo la modifica.

Testa nuovamente la connessione

Dopo aver completato i passi sopra:

  • Verifica se Windows richiede di nuovo l’autenticazione.
  • Controlla i log di Samba in /var/log/samba/ per tracciare i tentativi.

A questo punto tutto riprende a funzionare

Porting di una app Oracle a MySQL

Durante un porting ho incontrato queste differenze che ho dovuto gestire.

Function

Non può contenere istruzioni DDL (es. CREATE TABLE).

Non può nemmeno chiamare una procedura che contene istruzioni DDL.

Se si vogliono lanciare istruzioni DDL, utilizzare le procedure, non le function.

Procedure

Può contenere DDL però mi da’ un fastidioso errore alla dichiarazione di una variabile locale:

DECLARE p_count BIGINT DEFAULT 0;

Viene sollevato un errore che sembra legato alla sintassi:

Errore SQL [1064] [42000]: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 3

ma la sintassi è corretta.

Il problema qui è il client DBeaver: risulta che il driver deve avere una configurazione particolare:

Verifica configurazione della connessione DBeaver

Vai nelle impostazioni della connessione DBeaver:

Modifica la connessione:

Vai su Database > Connessioni > Modifica connessione.

Driver Properties:

Verifica che il driver MySQL utilizzi allowMultiQueries=true:

Se è false, cambia a true (è questo il mio caso)

Aggiungi questa proprietà se non esiste.

Fatta la modifica mi sconnetto e mi riconnetto allo schema e la definizione della procedura con DDL funziona (funziona anche la procedura).

Trigger

I trigger non possono contenere variabili locali, non è ammessa una sezione DECLARE. E’ ammessa solo in procedure e function.

Nei trigger però possono venire usate variabili di sessione, dichiarate con il prefisso @ davanti al nome:

SET @p_username = 'myuser';

Eventualmente spostare il codice che usa variabili locali non di sessione in una procedura e invocare la procedura dal triger.

Ancora Procedure

Nelle procedure però non è consentito l’uso di variabili di sessione, ma solo di variabili locali.

Se ad esempio dichiariamo:

DELIMITER //

CREATE PROCEDURE my_set(p_username VARCHAR(255))
BEGIN
    set @login = p_username;
    -- Restituisce il valore tramite SELECT
    SELECT @login AS result;
END//

DELIMITER ;

incontro un errore che sembra legato alla sintassi:

Errore SQL [1064] [42000]: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 4

Nelle procedure utilizzare solo variabili locali.

In realtà ho trattato in altro modo una variabile di sessione gestendola all’interno di una tabella temporanea, che viene creata dalla procedura alla sua invocazione.

La tabella TEMPORARY così creata non viene listata né da comando

show tables;

né dall’information schema:

SELECT *
FROM information_schema.tables
WHERE table_schema = 'mydb';

per ragioni di consistenza (user diversi vedono cose diverse, e anche lo stesso utente in sessioni diverse).

Però posso interrogarla:

slect count(1)
from app_session;

-- return 1

Mirth: compilazione del Message template

Mi è capitata una anomalia che non avevo mai notato. In realtà non è un’anomalia ma è così che va Mirth: avevo scritto una query di select in un database reader ma non mi veniva compilato il message template nel transformer.

Il comportamento di Mirth dipende dal contesto tabellare della query:

  • Se il risultato è scalare (SELECT 1 AS n;), Mirth non genera automaticamente il template.
  • Se il risultato ha un contesto tabellare (SELECT 1 AS n FROM tabella;), Mirth genera correttamente il template.

Usa una clausola FROM per sfruttare il popolamento automatico della Message Template. Questo approccio garantisce compatibilità con il funzionamento di Mirth e previene problemi futuri.

Fine della pillola.

Driver Java/MySQL per Mirth Connect: dove posizionare le librerie?

MySQL 8.0
MySQL 8.0
Java
Java
Mirth Connect
Mirth Connect

Ci sono due directory in cui è possibile depositare archivi JAR (Java Archive) per estendere le funzionalità di Mirth Connect, nel mio caso la libreria che consente di connettersi a MySQL:

custom-lib/ e server-lib/database/.

Le due directory hanno scopi leggermente differenti e vengono utilizzate per gestire librerie personalizzate o di sistema in maniera modulare:

1. custom-lib/:

  • Scopo: Questa directory è destinata a contenere librerie personalizzate che potresti voler aggiungere a Mirth Connect. Ad esempio, se stai utilizzando un driver JDBC o altre librerie esterne specifiche per il tuo progetto o personalizzazioni, puoi inserirle qui.
  • Utilizzo: È particolarmente utile quando hai bisogno di integrare librerie che non sono incluse di default in Mirth Connect, come connettori o altre dipendenze che il sistema non gestisce autonomamente.

2. server-lib/database/:

  • Scopo: Questa directory è destinata alle librerie di database utilizzate da Mirth Connect per la connessione a varie tipologie di database, come MySQL, PostgreSQL, Oracle, ecc. Mirth Connect cerca automaticamente qui i driver di database necessari per i connettori Database Reader o Database Writer.
  • Utilizzo: È il percorso preferito per i driver JDBC. Se stai lavorando principalmente con database e hai bisogno di specificare i driver JDBC, questa è la directory in cui vanno posizionati.

Differenze chiave:

  • custom-lib/: Per librerie personalizzate o aggiuntive non incluse di default.
  • server-lib/database/: Per driver di database JDBC, generalmente gestiti dal sistema.

Quando usarle:

  • Se hai bisogno di aggiungere librerie specifiche per il tuo progetto o personalizzazioni (non solo JDBC), usa custom-lib/.
  • Per i driver JDBC destinati ai connettori Database Reader/Writer, il posto più appropriato è server-lib/database/.

Perché la libreria deve stare in una sola delle due directory:

Mantenere una singola versione della libreria in una sola directory evita conflitti di classpath e sovraccarico nella gestione delle classi. Se una libreria è presente in entrambe le directory, Mirth potrebbe non sapere quale utilizzare, provocando errori come il NoClassDefFoundError che ho riscontrato. Un problema silente al deploy del canale che però si verificava a runtime.

Tra i tentativi che ho fatto ci sono stati quelli di trovare una liberia compatibile con la VM ma non era qui il problema.

Scrivendo un breve programma Java, la connessione si stabiliva e si riusciva a anche a tirare le query: il problema non era la libreria in sé, né la VM

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSet;

public class MySQLConnectionTest {

    public static void main(String[] args) {
        String jdbcUrl = "jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=Europe/Rome";
        String username = "myuser";
        String password = "mypassword"; 

        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;

        try {
            // Carica il driver MySQL
            Class.forName("com.mysql.cj.jdbc.Driver");
            System.out.println("Driver MySQL caricato correttamente.");

            // Effettua la connessione
            connection = DriverManager.getConnection(jdbcUrl, username, password);
            System.out.println("Connessione al database riuscita.");

            // Crea uno statement e esegui la query "SELECT 1"
            statement = connection.createStatement();
            resultSet = statement.executeQuery("SELECT 1");

            // Mostra i risultati
            while (resultSet.next()) {
                int result = resultSet.getInt(1);
                System.out.println("Risultato della query SELECT 1: " + result);
            }

        } catch (ClassNotFoundException e) {
            System.out.println("Errore: il driver MySQL non è stato trovato.");
            e.printStackTrace();
        } catch (SQLException e) {
            System.out.println("Errore: impossibile connettersi al database.");
            e.printStackTrace();
        } finally {
            // Chiudi il ResultSet, Statement e Connection
            try {
                if (resultSet != null) resultSet.close();
                if (statement != null) statement.close();
                if (connection != null) connection.close();
                System.out.println("Connessione chiusa.");
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

L’output è pulito:

$ java -cp .:/opt/mirthconnect4.2/custom-lib/mysql-connector-java-8.2.0.jar MySQLConnectionTest
Driver MySQL caricato correttamente.
Connessione al database riuscita.
Risultato della query SELECT 1: 1
Connessione chiusa.

Conclusione:

Le due directory sono utilizzate per scopi diversi e possono coesistere, ma è importante non duplicare le librerie tra di esse. Per i driver di database JDBC, come nel mio caso, server-lib/database/ è il posto più adatto!

Riferimenti

Mirth: cosa sono le Code Libraries

Il tutto parte da un avviso che mi compariva ogniqualvolta importavo un canale Mirth costruito in precedenza: un avviso che, con il codice, veniva importata anche una libreria, una fantomatica Library1.


Cosa sono le Code Libraries in Mirth Connect?

Le Code Libraries in Mirth Connect sono collezioni di funzioni, template e blocchi di codice che possono essere riutilizzati in più canali. Introdotte in versioni più recenti (come Mirth 3.3.0), le code libraries permettono agli utenti di centralizzare il codice utilizzato in vari canali, facilitando la manutenzione e la gestione del codice riutilizzabile.

A cosa servono le Code Libraries?

  1. Riutilizzo del codice:
    Le code libraries consentono agli sviluppatori di definire funzioni e blocchi di codice una sola volta e riutilizzarli su più canali e trasformatori. Invece di scrivere lo stesso codice ripetutamente in diversi canali, puoi semplicemente creare un template di codice in una libreria e richiamarlo dove necessario.
  2. Manutenzione centralizzata:
    Quando hai codice distribuito in più canali, apportare modifiche può essere complesso e dispendioso in termini di tempo. Con le code libraries, puoi aggiornare una funzione o un template centralizzato, e la modifica verrà automaticamente applicata a tutti i canali che utilizzano quella libreria.
  3. Organizzazione modulare del codice:
    Le code libraries permettono di organizzare il codice in moduli o componenti, migliorando la leggibilità e la gestione. Puoi creare librerie separate per gestire funzioni diverse, come operazioni su stringhe, trasformazioni di dati, o gestione degli errori, e associarle solo ai canali che ne hanno bisogno.
  4. Facilità di condivisione:
    Le code libraries possono essere facilmente esportate e importate, facilitando la condivisione di template e codice riutilizzabile tra diversi ambienti o team. Questo migliora l’interoperabilità e riduce la duplicazione del lavoro tra sviluppatori.
  5. Controllo sull’inclusione di librerie nei canali:
    In Mirth Connect, puoi decidere a quali canali associare specifiche code libraries. Questo ti permette di avere un controllo preciso su quali canali hanno accesso a determinate funzioni o template, evitando che tutto il codice sia incluso in ogni canale senza necessità.

Il problema della libreria vuota (Library1):

In alcuni casi, come dopo la migrazione a versioni più recenti di Mirth (ad esempio 3.3.0), potrebbe venire creata una libreria di default chiamata Library1. Questa libreria viene creata per includere eventuali code templates pre-esistenti, ma a volte potrebbe risultare vuota. Questo succede per una delle seguenti ragioni:

  • Non ci sono code templates esistenti nelle versioni precedenti.
  • I code templates non sono stati trasferiti correttamente durante la migrazione.
  • La libreria è semplicemente un placeholder creato dal sistema per gestire eventuali future aggiunte di code templates.

Dove compare l’avviso

Quando si importa un canale sviluppato altrove può accadere di vedere un avviso simile, che viene mostrato perché il canale da importare si porta dietro delle librerie oltre al codice scritto nella Source, nelle Destination e nei Transformers/Filters:

Importazione della Library 1 tra i Code Templates
Importazione della Library 1 tra i Code Templates

Nella fattispecie vedevo spesso comparire questa misteriosa Library 1 ma non sapevo cosa contenesse, al che ho pensato che fosse il caso di approfondire.

Le librerie custom di solito si possono includere in un file JAR dentro alla directory /opt/mirthconnect/cutom-library che però nel mio caso (nel Mirth di partenza) non aveva alcuna Library 1 al suo interno, anzi era addirittura vuota.

Un altro modo è gestirle da Mirtch Connect Administratore secondo il percorso:

Channels > Code Templates

Vediamo i passi da compiere per eliminare definitivamente l’avviso.

Come gestire la libreria vuota:

  • Se la libreria è vuota o non serve: Puoi ignorarla o rimuoverla, poiché non avrà alcun impatto sui canali attuali.
  • Se intendi usarla: Puoi aggiungere nuovi code templates alla libreria e associarli ai canali che necessitano di quel codice.
  • Importare nuovi template: Invece di usare Library1, potresti voler creare nuove librerie per separare meglio i tuoi code templates in base alle funzionalità (ad esempio, una libreria per operazioni su stringhe, una per trasformazioni JSON, ecc.).

Nel mio caso l’ho proprio eliminata utilizzando la GUI Mirth Connect Administrator e dai canali che la richiedevano.

Conclusione:

Le Code Libraries in Mirth Connect sono uno strumento potente per migliorare la gestione del codice, facilitando il riutilizzo e la manutenzione centralizzata. Tuttavia, in alcuni casi, come durante le migrazioni di versione, potrebbero essere create librerie vuote che possono essere rimosse o ignorate se non necessarie.