Skip to content

2023

Dynamic Markdown

Markdown è un sistema di markup che può essere utilizzato per aggiungere elementi di formattazione a dei normali file di testo. È molto apprezzato dagli sviluppatori, e non a caso è il sistema di riferimento per GitHub oppure per StackOverflow ma può essere utilizzato per qualsiasi tipo di documento, compresi report, libri, manuali, testi, etc.

Uno strumento indispensabile per lavorare, tra le altre cose, su documenti markdown è pandoc che viene definito come il coltellino svizzero per i documenti di testo. Può essere infatti utilizzato per convertire documenti markdown in documenti Word, Open Office, LaTeX, PDF, etc.

Ad esempio:

pandoc test.md -s -o test.odt

oppure:

pandoc test.md -s -o test.pdf

(necessario aver installato pdflatex, come ad es. portable MikTex, e configurato il PATH in maniera adeguata).

È possibile inoltre applicare dei template di alta qualità, come il template Eisvogel

pandoc test.md -s -o test.pdf --template eisvogel

Markdown Dinamico

Ho pensato che sarebbe estremamente comodo poter disporre di un documento markdown "dinamico". Ad esempio, per inserire delle tabelle in un documento Markdown posso utilizzare il plugin MarkDown per Adminer che ho scritto qualche tempo fa, in modo molto semplice e con i risultati spesso migliori di un copia-incolla da Excel su documento Word!

Tuttavia sarebbe meglio ancora poter pescare i dati direttamente dal database di origine (così come da un CSV, XLSX, o quant'altro).

Un sistema che potrebbe funzionare è Jinga2 ovvero uno dei più utilizzati framework per template di Python. Questo sistema però, per precisa scelta architetturale, non prevede la possibilità di mescolare codice di programmazione con condice markup. Avendo vissuto in prima persona gli anni '90 dello scorso millennio, dove il codice HTML si mischiava al codice di programmazione senza capire bene il limiti di dove finiva uno ed iniziava l'altro, posso dire che tale scelta è perfettamente condivisibile. Tuttavia, pur essendo una opzione sempre valida, non è quello che stavo cercando!

Linguaggi di scripting?

Si potrebbe usare un Makefile con qualche script bash, magari integrato con dei sistemi che generano output in formato markdown come il mio perl-Sql-Textify.

Oppure PHP che, nel bene e nel male, permette di inserire del codice all'interno di un documento e può quindi essere utilizzato per rendere un documento Markdown dinamico.

Oppure ancora il buon vecchio HTML::Mason, che mi ha dato grandi soddisfazioni all'inizio del millennio permettendo di integrare codice HTML con il linguaggio perl. Purtoppo né HTML::Mason né Mason2 sono attivamente sviluppati da anni, anche se proprio nel momento in cui ho iniziato a scrivere questo post (ovvero il giorno 11 febbraio 2023 - scrivo molto lentamente!) è stato pubblicato HTML::Mason versione 1.60 che contiene un piccolo bugfix. Non ci sono poi aggiornamenti successivi.

Script Python?

Ho pensato di risolvere il problema con dei piccoli script Python. Un documento Markdown sarà composto come segue, con del codice Python inserito all'interno del documento:

---
title: "Report Dinamico"
author: [Federico Thiella]
date: 2023-09-11
subject: "Report Dinamico"
keywords: [codice, python, esempio]
lang: "it"
table-use-row-colors: True
book: True
...
^ import mktools as mk
^ c={'host':'myhost.mshome.net', 'database':'mydatabase', 'user':'myuser', 'password':'mypassword'}
# Report Dinamico creato con Markdown

^ q=mk.query_db("select * from sezioni", c)
^ for r in q['rows']:

## Titolo: <& r[2] &>

<& r[3] &>

Inserisci una tabella:

^   w=mk.query_db("""
^      select
^        col1,
^        col2,
^        col3
^      from
^        progetti
^      where
^        progetto_id={}
^      order by
^        col1, col2, col3
^      """.format(str(r[0])), c)
^   w['head'][1]['name']='Colonna 1'
^   w['head'][1]['align']='right'
^   w['head'][2]['name']='Colonna 2'
^   w['head'][2]['align']='right'
^   w['head'][3]['name']='Colonna 3'
^   w['head'][3]['align']='left'
^   mk.markdown_table(w['head'], w['rows'])
^^
\pagebreak
  1. questo codice Markdown dinamico verra compilato dallo script pp.py in uno script puro python, che può essere eseguito e che genererà in output il codice Markdown statico finale, pronto da poter essere utilizzato e/o convertito in altri formati;
  2. la libreria mktools.py contiene delle funzioni utili per eseguire velocemente delle operazioni su database:
  3. mk.query_db esegue una query e restituisce intestazione w['head'] e righe w['rows'];
  4. mk.markdown_table che converte la tabella descritta da intestazione e righe in formato markdown.

La compilazione del documento avviene in questo modo:

python pp.py -i documento.md | python | pandoc -o documento.pdf --template eisvogel.latex -s

(lo script dinamico e la libreria di utilities saranno pubblicate e descritte su GitHub quanto prima. Non si tratta di un sistema "professionale" ).

Mako Templates

Un'ultima opzione può essere il sistema Mako Templates, la cui filosofia "Don't reinvent the wheel...your templates can handle it!" contrasta con il mio paragrafo precedente. Lo approfondirò appena mi sara possibile!

Numeri di telefono riciclati: una falla di sicurezza?

Commento del febbraio 2023 su un blog, in risposta a un articolo che raccontava il caso di un utente che aveva ereditato per caso l'account WhatsApp di un'altra persona a causa del riutilizzo del numero di telefono.

Quando mi è stato assegnato il primo cellulare di lavoro, molti anni fa, ho cominciato a ricevere SMS e telefonate da amici che non sapevo di avere, che mi invitavano a feste ed eventi vari.

Una signora, che si spacciava per mia nonna, mi chiamava spesso piangendo per dirmi che, anche se mi rifiutavo di riconoscerla, per lo meno avevo ripreso a risponderle al telefono.

Infine un ragazzo mi accusava di avergli rubato cellulare e numero di telefono.

Gli operatori telefonici riutilizzano sempre i numeri di telefono, nel mio caso devono averlo fatto un po' troppo in fretta.

Il problema

Per quanto riguarda questa falla di sicurezza, mi sembra talmente scontata che mi stupisco che sia stata sottovalutata: nella maggior parte dei servizi di messaggistica il numero di telefono viene verificato solo in fase di attivazione (tramite chiamata o SMS) e poi l'applicazione viaggia su binari diversi rispetto alla SIM.

Puoi cambiare SIM, numero di telefono, puoi anche togliere la SIM, etc. ma a WhatsApp la cosa non interessa. Se un numero viene riassegnato, WhatsApp come fa a sapere se sei il vecchio utente di prima che ha cambiato telefono o un nuovo assegnatario del numero?

Le policy di cancellazione automatica per inattività (come i canonici 45 giorni previsti da alcune piattaforme) mitigano solo in parte il fenomeno, ma restano una toppa parziale.

Lo stesso problema con i domini

Ah, il problema succede anche con i domini internet. Se un dominio viene riassegnato, cosa che avviene per diverse ragioni non sempre volontarie, il nuovo proprietario può non solo leggere tutta la tua (nuova) corrispondenza, ma anche prendere accesso a tutti gli account esterni se registrati con una casella di posta legata al dominio "perduto".

Il pattern è sempre lo stesso: una risorsa viene riassegnata, ma i servizi che ci si appoggiano non lo sanno.

Windows Home Profile

Percorso Profilo Utente di Windows

La variabile %HOMEPROFILE% contiene il percorso del profilo corrente, tipicamente:

c:\Users\username

mentre la cartella dei documenti è di default la sua sottocartella Documents quindi:

c:\Users\username\Documents

tuttavia il nome della cartella Documents è configurabile e potrebbe essere stato impostato a piacere, per cui non si può dare per scontato che il percorso %HOMEPROFILE%\Documents sia sempre quello corretto.

Il percorso corretto è registrato nella seguente posizione del registro di Windows:

λ reg query "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" /v Personal

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
    Personal    REG_SZ    C:\Users\username\Documents

Alcuni linguaggi di programmazione mettono a disposizione librerie e funzioni apposite per interrogare il registro, mentre con la shell è necessario utilizzare uno script apposito.

Script di lettura Percorso

Il seguente script legge il percorso richiesto, e lo memorizza nella variabile %value%:

@echo OFF
setlocal ENABLEEXTENSIONS

set KEY_NAME="HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
set VALUE_NAME="Personal"

for /F "tokens=2*" %%A IN ('reg query %KEY_NAME% /v %VALUE_NAME%') do (
    set value=%%B
)
echo %value%

questo script sembra funzionare sia con le versioni più recenti di Windows che con le precedenti, e supporta percorsi con gli spazi.