random_done e Obsidian: o come crearsi uno script in Python da eseguire da riga di comando e aggiungerlo al proprio sistema operativo.
Obisidan è bello, ma vuoi mettere prendere e usarlo anche come modo per tracciare cosa fare? Ultimamente sto usando il terminale e ci è voluto poco a pensare:
- posso fare uno strumento che eseguo da linea di comando in cui posso aggiungere task o farmi passare dei task da fare a caso?
- a volte basta iniziare e una cosa del genere dovrebbe aiutarmi. Ci sono 20 minuti prima di preparar da mangiare... c'è qualcosa di facile che posso togliermi di torno? Posso scrivere qualcosa che mi aiuti con questa pigrizia?
Mi risolvo un problema da terminale
Aprire un terminale su Mac è abbastanza comodo. Uno si cerca Terminale dalle applicazioni o magari ha una scorciatoia dedicata. (Sì, lo so, vorrei vedere che ha fatto Wes con Ghosthub , non tanto per gli agenti quanto per le sessioni ssh. Ho aggiunto un task con l'applicazione che andremo a sviluppare per venirne a capo: rdone --add "test_ghosthub_and_post".)
Lavorando, facendo cose, etc capita di aver voglia di segnarsi qualcosa da fare. Magari anche piccola. Cerca questo libro, prova a fare questo, vedi com'è questo servizio. Cose che magari si fanno in un quarto d'ora, però poi spesso uno le perde per strada.
Fare un tool da riga di comando in Python è abbastanza semplice, anche se non l'ho mai fatto sul serio.
Quindi, a parte trovare qualcosa che ci fa interagire con il nostro programma usando la tastiera o il terminale, il resto del codice è abbastanza semplice. Abbiamo dei task con un titolo e quando vengono completate. E sappiamo che dobbiamo pescare dei task a caso e proporli all'utente. Sta a noi poi accettarli, rifiutarli o completarli.
Ecco randomdone o, per gli amici, rdone. Perché, ecco, da un lato ci risparmiamo di qualche carattere per invocarlo e, dall'altro, qualcosa che ti spara addosso task a caso è un po' un (me)rdone.
Cosa si impara
Visto che è un post un po' tecnico, vediamo che cosa bolle in pentola per noi. L'idea è di vedere come:
- creare uno strumento da terminale in Python
- vedere due o più opzioni per fare la stessa cosa, che non sono poi le stesse nel nostro contesto
- capire come integrarsi con Obsidian (i suoi Vault son come Fallout)
- scoprire come trasformare un robino in Python in qualcosa di eseguibile
Python e riga di comando
Ci sono sostanzialmente due modi per scrivere cose in Python da usare da terminale:
– usi argparse per definire i comandi che vuoi mandare e gli dici cosa fare. A me serve aggiungere task (--add) e poi completarle (--done). E poi mi serve gestire l'elenco delle task quando sono dentro il programma: accettare un task, skipparlo, completarlo e chiudere il programma.
– in alternativa si può usare qualcosa di più moderno tipo typer, dal creatore di FastAPI. Sostanzialmente facciamo le stesse codice, però usando meno codice.
Visto che vogliamo usare la cosa da terminale senza troppe seccature, andiamo sul semplice. Per eseguire il nostro programma ci bastano Python e la libreria standard. Ci accolliamo un po' di codice in più da scrivere, però evitiamo di dover gestire l'aggiunta di pacchetti extra.
I task sono file che gestiamo in Obsidian
Le task da fare sono in realtà dei file. In particolare file da gestire in Obsidian. Magari dentro al file mi segno l'url del servizio da testare o un po' di note sulle cose da fare.
Quello che mi aspetto è questo: – dico a Rdone di aggiungere un task. Mi crea il file in markdown (il formato di Obsidian) e me lo mette in una cartella dedicata – accetto di fare un task del (me)Rdone. Mi apre il file in questione in Obsidian. Questo è comodissimo se uno deve prendere e si becca un task che riguarda lo scrivere qualcosa.
Lato applicativo, il fatto che i task siano file ci semplifica parecchio le cose: non ci sono grandi query da fare, si tratta di prendere e contare i file che sono in una determinata cartella – quello delle task da fare. Quando un task è completato, lo spostiamo in un'altra cartella. Questo si porta dietro due cose di cui essere consapevoli: da una parte ci toccherà interagire con Obsidian per aprire i file; dall'altra se vogliamo associate dei metadati alle task tipo quando sono state create o completate dobbiamo scendere a compromessi col fatto che le task non sono nostri oggetti sul database, ma – appunto – file.
Obsidian delle mie brame
Capire come usare Obsidian per aprire un file è stata la parte più complicate. Ho creato una funzione di Python che aprisse un file test.md usando Obsidian.
Qui ci sono un po' di considerazioni da fare.
Partiamo da una cosa più facile. Apriamo e basta un file di testo. Ovviamente ogni sistema operativo fa come gli pare: macOS ha un comando, Windows un altro, Linux ancora un altro. E, sviluppando dentro un devcontainer da macOS, ci si ritrova in una situazione in cui sviluppi in un mondo (Linux) ma userai il programma in un altro.
In fondo metto uno schema per queste differenze, soprattutto per me che presto mi dimenticherò di averlo fatto.
Obsidian aggiunge un livello di complessità. Al netto del fatto che ogni sistema operativo apre i file a modo suo, adesso tocca aprire usando Obsidian.
A quanto pare dobbiamo risolvere questo
subprocess.run([opener, uri],
L'apertura di Obsidian è un sottoprocesso rispetto alla nostra app che gira da linea di comando. Per eseguirlo ci serve un comando di apertura – e qui ci risolviamo la questione del sistema operativo – e una risorsa da aprire. Questa risorsa è obsidian. Qui la documentazione di Obsidian ci dice come usare open. E, volendo, qui c'è un plugin per fare ancora più cose con l'apertura dei file in obsdian.
Qui si apre un problemino extra. Obsidian si apre alle sue condizioni. Obisdian ragiona in Vault, la cassaforte dove tenere i file. In pratica: Obsidian apre solo una cassaforte, non possiamo aprire obsidian “into the wild” se vogliamo aprire dei file. Quindi
Da scriptino in Python a “hey, vive nel mio sistema”
Abbiamo uno script, lo abbiamo messo nella cartella giusta di Obsidian. Praticamente funziona e ci siamo. Però come facciamo ad eseguire tutto da terminale? Questo è l'ultimo passo che ci tocca fare.
In pratica dobbiamo fare due cose:
1. assicurarci che lo script sia eseguibile
2. fare in modo che il terminale sappia che quando scriviamo qualcosa (nel mio caso rdone) vogliamo utilizzare quello script, e renderlo disponibile ovunque.
Si fa abbastanza presto. Lato Mac con questa riga all'inizio del file
#!/usr/bin/env python3
Lo rendiamo eseguibile. Poi dobbiamo assicurarci che chi interagisce col file abbia i permessi per farlo, quindi chmod +x script.py (script.py è il nostro file, la x sono i permessi di esecuzione) per poter eseguire direttamente ./script.py
Per renderlo eseguibile, dobbiamo aggiungere qualcosa nel nostro terminale. Un'operazione simile a quando definite una scorciatoia – tipo up per aprire tutto quello che vi serve per lavorare. O magari tipo alcune personalizzazioni in git.
In pratica creiamo una cartella dove mettere il nostro programma (bin, un altro modo convenzionale per parlare di scatoloni). Colleghiamo il nostro file dentro obsidian con questo scatolone con un link simbolico (symlink) Il link simbolico è quello con cui evocheremo il comando. Aggiungiamo il nome fittizio del link simbolico al terminale.
Tutto insieme è questo (macOS / Linux):
mkdir -p ~/bin # creiamo una cartella di comodo
chmod +x ~/Documents/vault_obsidian/randomdone_tasks/random_done.py # diamo i permessi per eseguire il file
ln -sf ~/Documents/vault_obsidian/randomdone_tasks/random_done.py ~/bin/rdone # link simbolico. Se non vi piace 'rdone aggiustatelo
echo 'export PATH="$HOME/bin:$PATH"' >> ~/.zshrc # il terminale sa che il nostro file è disponibile, aggiungiamo il nostro ~/bin al PATH del terminale
source ~/.zshrc # refresh del terminale
E su Windows?
C'è da passare dai bat, ma ancora non ho provato. Qualcosa del tipo
- si crea un file
rdone.batcosì:bat @echo off set RANDOM_DONE_VAULT_DIR=%USERPROFILE%\Documents\vault py "%USERPROFILE%\Documents\vault\randomdone_tasks\random_done.py" %*
A proposito di differenze
Recap e schemini
- Apertura URL verso app: macOS usa
open, Linux usaxdg-openogio, Windows usaos.startfile(uri). - Shebang e
chmod +xsu macOS/Linux. In Windows uscite gratis di prigione se.pyè associato a un programma come estensione. - link simbolico e bin vs. file
.bat.
#obsidian #taskmanager #randomdone #python #coding
Ci si vede nel Fediverso?
In attesa di capire come funzionano i commenti in Writefreely, e se val la pena aggiungerli, mi trovate qui nel fediverso.