29 aprile, 2007

pygtk: un About Dialog con link cliccabile

Creare un about dialog con link di riferimento cliccabile è una di quelle cose che vediamo in molte applicazioni ma per la quale non è semplice trovare documentazione a riguardo.

Scoprire come fare per me non è stato semplicissimo e quindi ho pensato che una soluzione pronta potrebbe essere di aiuto a qualcuno.

Cosa stiamo per realizzare
Ciò che ci apprestiamo a realizzare è un dialogo di informazione come quello che potete vedere in figura:


Da notarsi che il link è cliccabile e cliccandoci sopra verrà aperto un browser che vi porterà guarda caso proprio a quell'indirizzo :) Le librerie gtk (e i rispettivi bindings per python) mettono a disposizione un apposito widget per creare i dialoghi di informazione. Il widget in questione permette di settare facilmente il nome dell'applicazione, la versione, gli autori, la licenza, i traduttori e altre cosette interessanti. Stranamente però non permette di impostare in modo altrettanto semplice un url che risponda al click del mouse. Per farlo è necessario utilizzare la funzione gtk.about_dialog_set_url_hook e indicare una callback da richiamare quando l'utente clicca sul link. La callback in questione dovrà poi occuparsi di creare un nuovo processo per lanciare il browser.


Il codice python



import gtk
import subprocess

def on_url(d, link, data):
subprocess.Popen(["firefox", "http://linubuntu.blogspot.com"])

gtk.about_dialog_set_url_hook(on_url, None)

def create_dialog():
dlg = gtk.AboutDialog()
dlg.set_version("0.1")
dlg.set_name("app")
dlg.set_license("Puoi fare di questo software quello che ti pare")
dlg.set_authors(["redgun"])
dlg.set_website("http://linubuntu.blogspot.com")
def close(w, res):
if res == gtk.RESPONSE_CANCEL:
w.hide()
dlg.connect("response", close)
return dlg

if __name__ == "__main__":
dlg = create_dialog()
dlg.run()


Ricordate che la finestra di dialogo di suo non risponde al click sul pulsante chiudi ma sarà necessario impostare una funzione di callback per il segnale response come nel codice.

27 aprile, 2007

Una chicca da Fedora 7

Era da tanto che non mi interessavo alla mia vecchia distribuzione (vedi qui). Oggi noto su ditsrowatch che è uscita la versione test 4 di Fedora 7. Dalle note di rilascio scopro che adesso anche fedora usa il sistema a live cd installabile, che non ha ancora abbandonato yum (credo che non esista un gestore di pacchetti peggiore), e che usa un nuovo tema di icone. Ok, mi dico, vediamo questo tema e cerco uno screenshot. Trovo questo:


Le icone sono carine ma un'altra cosa mi colpisce: la finestra delle preferenze si sviluppa su due livelli, un piccolo colpo di genio a mio parere.
Questa credo sia un ottima soluzione per il menù delle preferenze. L'altra opportunità sarebbe il centro di controllo gnome, ma la trovo poco funzionale. Il centro di controllo non è così immediato come i menù. Ecco come compare invece il menù delle preferenze sul mio desktop:

Decisamente meglio quello di fedora. Per una volta devo bastonare Ubuntu eh eh :)


P.S. Oggi blogger sembra avere qualche problema e a volte non compaiono gli articoli recenti e i commenti recenti del blog. Mi scuso per l'inconveniente.

23 aprile, 2007

Ubuntu Feisty: Impressioni d'uso

Ormai uso Feisty da circa un mesetto e a questo punto posso esprimere le mie valutazioni.

La mia storia con linux
Ho iniziato ad usare linux all'epoca della Mandrake 8 (poco prima avevo provato una SuSE [non ricordo quale versione]). Ho abbandonato Mandrake per una RedHat 9 sulla quale ho iniziato le "sperimentazioni serie", dalla ricompilazione del kernel, allo studio e modifica del processo di avvio, alla configurazione manuale di devices all'epoca del kernel 2.4 un po esotici come il bluetooth etc. Ho usato fedora fino alla versione 3 che ho abbandonato perché condividevo poco la sua politica, alla ricerca di una distribuzione che fosse semplice per l'uso quotidiano ma abbastanza aperta da regalarmi succulenti momenti di puro e gudurioso hacking, e mi sono fermato su ubuntu dapper.

Da allora non ho mai più installato un'altra distro. Ubuntu mi piace, amo persino il famoso marrone cacchina tanto contestato, il suo simbolo e tutto il resto.

Mai quanto con la Feisty però avevo avuto la sensazione di puro godimento nell'utilizzo del computer, il senso di quasi morboso piacere nel cliccare ed osservare come un bimbo le barre del progresso colorarsi, il pesce wanda nuotare nel pannello, le finestre fluttuanti danzare sulle loro trasparenze. Il tutto nella consapevolezza della libertà, della libera divulgazione delle conoscenze di un sistema aperto che cresce grazie a noi utenti verso la direzione che noi indichiamo e che nessun altro ci impone.

Ubuntu: la distro perfetta
Ubuntu è quasi perfetta. Mancano solo alcuni piccoli accorgimenti. Stupidaggini come qualche icona vecchiotta ed inconsistente qua e la (vedi menù giochi), qualche piccolo bug sporadico e altre piccolezze.

La prova di ciò è l'interessamento sempre crescente da parte degli utenti per questa distro. Ubuntu Feisty ha stupito anche i suoi stessi sviluppatori quando i mega server che ospitano ubuntu.com e canonical.com erano praticamente irraggiungibili nel giorno del rilascio. Forse avete notato che il sito di ubuntu è stato sostituito per qualche ora con una pagina statica per cercare di diminuire il carico sui servers. Insomma sarà per questo Vista che sembra non riscuotere molto successo, sarà per la consapevolezza di una alternativa che inizia a fare breccia nelle menti ma la comunità di Ubuntu inizia ad ottenere un peso consistente nel palcoscenico mondiale e io non posso che esserne felice!

Buon ubuntu a tutti!

19 aprile, 2007

Un modulo python per gestire le chiavi in gconf

Aggiornamento: ho aggiornato il modulo che è ora una classe ed include il metodo clean_section


L'ambiente desktop gnome mette a disposizione un ottimo sistema per memorizzare le impostazioni delle sue applicazioni: gconf.

Come funziona gconf?
Gconf è un sistema per la memorizzazione delle configurazioni basato su XML. La configurazione è contenuta in un albero ed ogni applicazione può costruire un suo sottoalbero nel quale memorizzare le proprie impostazioni. Gconf è composto da un demone (gconfd), che si occupa di notificare le applicazioni di eventuali modifiche alla loro configurazione (magari fatte da una applicazione esterna come gconf-editor) e di mantenere una cache dei valori in modo che le applicazioni non siano costrette a dover rifare il parsing del file XML ogni volta, e da un insieme di librerie che rendono semplice l'accesso all'albero gconf.


Come posso accedere/creare chiavi gconf con python?
Usare gconf da python è veramente semplice anche se un minimo di astrazione in più non fa certo male. Per questo vi voglio riportare un piccolo modulo python che permette di comprendere l'uso di gconf oltre che semplificare il processo di creazione/accesso/modifica delle chiavi.

Il codice python


import gtk
import gconf


class MyGconf:

def __init__(self, appname):
self.basedir = "/apps/" + appname
self.client = gconf.client_get_default()

def add_section(self, name, keys):
"""
Aggiunge una sottodirectory a self.basedir e la riempie
con le chiavi specificate nel dizionario keys
"""
dir = self.basedir + "/" + name + "/"
for key, value in keys.iteritems():
path = dir + key
self.client.set_string(path, value)

def clean_section(self, name):
"""
cosa potrebbe mai fare questo metodo :)
"""
dir = self.basedir + "/" + name
self.client.recursive_unset(dir, 0)

def get_sections(self):
"""
Ritorna una tupla contenente l'elenco delle sezioni
contenute in self.basedir
"""
return self.client.all_dirs(self.basedir)

def get_key(self, name):
"""
Ritorna il valore di una specifica chiave.
name deve essere un percorso relativo a self.basedir
"""
path = self.basedir + "/" + name
return self.client.get_string(path)

def set_key(self, name, value):
"""
Imposta il valore della chiave name a value
"""
path = self.basedir + "/" + name
self.client.set_string(path, value)




if __name__ == "__main__":
mg = MyGconf("myapp")
params = {
"test": "test value",
"test2" : "test2 value"
}
mg.add_section("mydir", params)
mg.add_section("mydir2", {"test": "value"})

print mg.get_key("mydir/test")
print mg.get_sections()
mg.set_key("mydir/test", "new value")
print mg.get_key("mydir/test")

mg.remove_section("mydir")


Il codice dovrebbe essere autoescplicativo ;)

18 aprile, 2007

Un processore di effetti di chitarra su Ubuntu

Oltre ad essere un utente ubuntu sono anche un discreto chitarrista. Una delle cose che di più mi manca su Ubuntu è un programma di emulazione di amplificatori in grado di permettermi di sfruttare la mia M-Audio Fast Track (lo so che c'è di meglio ma per divertirsi va più che bene) perfettamente riconsciuta da Ubuntu.

Stasera ho deciso di vedere che cosa è in grado di fare la mia linux box nell'ambito dell'effettistica realtime.

Installiamo il necessario
Prima di tutto ho installato il kernel a bassa latenza presente nei repository Ubuntu (linux-image-2.6.20-15-lowlatency). Quando si parla di audio su linux viene subito da pensare al server audio jackd. Questo server per poter avere buone prestazioni in realtime, ha bisogno di alcuni accorgimenti particolari. Infatti è necessario compilare un apposito modulo per il kernel: non lasciatevi intimidire, non è poi cosi difficile. Vediamo come fare. Prima di tutto vi consiglio di installare il pacchetto module-assitant che vi risparmierà un sacco di noie e alla fine produrrà un bel pacchetto deb con ciò di cui abbiamo bisogno.
Prima di procedere è consigliabile riavviare con il kernel lowlatency.

Quindi installiamo il pacchetto realtime-lsm.
A questo punto andiamo a compilare il nostro modulo (assicuratevi di essere ancora connessi ad internet):

$ sudo m-a a-i realtime-lsm
Questo comando scaricherà dalla rete tutto ciò di cui avrà bisogno per compilare il modulo e per costruire il pacchetto .deb. Alla fine dell'operazione installerà automaticamente il pacchetto con il modulo.
E' arrivato il momento di testare il modulo realtime:
$ sudo modprobe realtime any=1
Se il comando dovesse dare degli errori durante il caricamento provate a riavviare (a me è successo e riavviando ho risolto).

Se l'operazione è andata a buon fine possiamo procedere ad installare gli altri pacchetti: jackd, jack-rack, qjackctl, caps.

Siamo finalmente pronti a testare il nostro processore di effetti.
Lanciamo qjackctl ed impostiamo i parametri per il demone jackd (non dimentichiamoci di attivare l'opzione realtime naturalmente). Quindi lanciamo jack-rack e dopo aver fatto le opportune connessioni attraverso qjackctl possiamo caricare gli effetti. I simulatori di amplificatori, di cabinets, di preamplificatori etc si trovano dal pulsante Aggiungi->Uncategorised->C di jack-rack.

Impressioni d'uso
Giocando con le varie impostazioni si riescono ad ottenere alcuni suoni che non sono malaccio anche se non posso dire che siano pienamente soddisfacenti. Altra nota dolente è che sul mio centrino a 1.5 Ghz non riesco a caricare più di 3 o 4 moduli contemporaneamente in jack-rack. In ogni modo mi sento di consigliarvi di provarli anche solo per il gusto di vedere la vostra chitarra processata da software open source :)

17 aprile, 2007

Urban Terror: Ogni tanto meritiamo un piccolo svago:)

Tra uno studio, un lavoro e tutto il resto noi linuxiani amiamo anche passare un po ti tempo a giocare. Visto che purtroppo sulla ubuntu feisty nexuiz sembra avere qualche problemino (almeno sul mio pc crasha non appena inizio una partita) ho cercato delle alternative in rete e ho trovato Urban Terror un gioco davvero ben fatto e divertente da giocare online.



Installazione
Per installare Urban Terror è necessario scaricare questi files dal sito http://www.urbanterror.net/:

  1. UrbanTerror40_full.zip
  2. ioUrbanTerrorInstaller_1.0.zip
  3. http://urt.battleye.com/BEClient_i386.so
  4. http://urt.battleye.com/BEServer_i386.so
A questo punto creiamo una cartella UrbanTerror dove meglio ci pare (ad esempio nella nostra home). Unzippiamo il file ioUrbanTerrorInstaller_1.0.zip in una cartella temporanea e copiamo il contenuto della cartella Linux-i386 nella cartella UrbanTerror che avevamo creato in precedenza.
Ora unzippiamo il file UrbanTerror40_full.zip nella cartella UrbanTerror ed infine copiamo i files BEClient_i386.so e BEServer_i386.so nella cartella UrbanTerror/BattlEye.

Siamo quasi pronti a giocare. Rimane solo da dare i permessi di esecuzione al file UrbanTerror/ioUrbanTerror.i386 ed eseguirlo.

Il gioco
Si tratta di una arena a squadre da giocare online. Si muore molto facilmente (è realistico) ma è molto divertente. Lo consiglio a tutti quelli che dopo una intensa giornata di lavoro sentono l'esigenza di "uccidere qualcuno" (metaforicamente naturalmente :)

Happy gaming!

14 aprile, 2007

Una classe per le notifiche con python e dbus: parte seconda

Qulche tempo fa in questo post avevo spiegato come è possibile generare una notifica utilizzando python e dbus. Il commento di AS in quel post mi ha dato l'ispirazione per approfondire le conoscenze su dbus e per creare questo nuovo post con una versione più evoluta della classe python per le notifiche (vi suggerisco la lettura del post precedente prima).

La nuova bestiola mostra un esempio di come sia possibile aggiungere funzionalità alle notifiche con l'inclusione di pulsanti.

L'esempio chiarisce inoltre come sia possibile posizionare la notifica in un punto arbitrario del desktop.

Il codice python


import dbus
from dbus.mainloop.glib import DBusGMainLoop

ICON = "file:///home/redgun/python/planimo/data/icons/planimo48.png"

class Notifier:
def __init__(self):
dbus_loop = DBusGMainLoop()
self.session_bus = dbus.SessionBus(mainloop = dbus_loop)
obj = self.session_bus.get_object("org.freedesktop.Notifications",
"/org/freedesktop/Notifications")
self.notif = dbus.Interface(obj, "org.freedesktop.Notifications")

self.notif.connect_to_signal("ActionInvoked", self.action_cb)

def action_cb(self, id, act):
print act

def notify(self, title, message, iconfile = ICON, time = 3000):
hints = {}
hints['x'] = 1200
hints['y'] = 50
actions = ["a1", "Azione1", "a2", "Azione2"]
try:
self.notif.Notify("Notification",
dbus.UInt32(0), iconfile, title, message,
actions, hints, dbus.Int32(time), dbus.UInt32(0))
except:
try:
self.notif.Notify("Notification",
dbus.UInt32(0), iconfile, title, message,
actions, hints, dbus.Int32(time))
except Exception, detail:
print detail

if __name__ == "__main__":
n = Notifier()
n.notify("Title", "message <b>bold style</b>", time=10000)

import gobject
loop = gobject.MainLoop()
loop.run()


Il risultato sarà il seguente:



Da notarsi che i pulsanti sono cliccabili e le azioni possono essere gestite all'interno del metodo action_cb. La variabile hints, invece ci permette di impostare le coordinate della notifica sul desktop. Le azioni vengono specificate in una lista dove gli elementi pari rappresentano i nomi delle azioni che andranno a comparire sui pulsanti, mentre quelli dispari rappresentano il valore che verrà passato alla funzione di callback. In questo caso quindi, quando premiamo il pulsante Azione1 la funzione action_cb riceverà nella variabile act il valore a1.

13 aprile, 2007

Ubuntu 7.10: nome in codice Gutsy Gibbon

Ancora prima del rilascio ufficiale di Ubuntu Feisty Fawn, Mark Shuttleworth annuncia il nome della prossima Ubuntu: Gutsy Gibbon. Mark ci riprova e assicura che in Ubuntu 7.10 gli effetti grafici saranno abilitati di default (intanto qui una guida su come abilitarli su Feisty Fawn con una ati 9600/9700).

Gusty Gibbon non sarà una LTS release (Long Term Support) e una delle novità importanti che introdurrà sarà il fatto che uscirà in due edizioni distinte: una versione normale ed una priva di ogni software per il quale non è disponibile il codice sorgente, dai firmware ai drivers proprietari e tutti gli altri materiali come suoni e immagini per i quali non si hanno pieni diritti per la modifica.

Per il resto non ci resta che aspettare ansiosi di vedere quale saranno le altre novità introdotte.

12 aprile, 2007

Modem Alice Adsl Wireless

Se state pensando di fare un abbonamento ad alice adsl e richiedere il modem in comodato d'uso per connettervi via wireless con la vostra amata Ubuntu ve lo sconsiglio per svariati motivi.

1) Non lasciatevi ingannare dal fatto che appare come un router (4 porte ethernet e interfaccia wireless), non lo è. Con l'apparecchio ci si può collegare da un solo computer per volta. (incredibile ma vero. Probabilmente un blocco via firmware)

2) La connessione ad internet deve essere lanciata direttamente dal computer (non è l'aggeggio che lo fa per voi)

3) Non ha praticamente interfaccia di configurazione se non una per lo stato e per l'attivazione della chiave wep o wpa, tra l'altro predefinita e non modificabile, memorizzata in una sorta di scheda tipo sim card.

4) Il segnale wireless fa a dir poco pena. Da una stanza all'altra con un centrino la rete va e viene.

5) Scordatevi qualsiasi tipo di funzionalità avanzata.

6) L'assistenza telecom lascia a dir poco a desiderare

Vi suggerisco quindi, se proprio non potete fare a meno dell'adsl di telecom di quantomeno acquistare un router per conto vostro!

10 aprile, 2007

Pid di un processo a cui appartiene un socket

Come si fa a conoscere il pid di un processo sapendo che è in ascolto su un determinato numero di porta?

Si usa il comando fuser!

Ad esempio supponiamo che sul nostro sistema sia in esecuzione un processo che apre un socket sulla porta 80 (apache ad esempio): per conoscere il pid del processo si può procedere con il comando fuser come segue:

$ fuser -n tcp 80

Questo comando stamperà qualcosa di simile a:

80/tcp: 15136 15140 15141 15142 15143 15144

I numeri che si trovano a destra dei due punti sono tutti pid dei processi facenti uso della porta 80. (in questo caso ne abbiamo più di uno perché apache duplica se stesso quando viene avviato)

Se si tratta di un socket udp è necessario specificarlo al posto di tcp.

N.B. Se il processo appartiene all'utente root è necessario invocare il comando fuser con i privilegi di amministratore e quindi preponendo sudo

05 aprile, 2007

feisty compiz e ati mobility radeon 9600/9700

In questi giorni mi sono finalmente deciso a passare alla beta di ubuntu (feisty). Tutto è filato liscio con un semplice sudo update-manager -d anche se ci ha impiagato circa 4 ore con tutti i pacchetti che avevo installati.

Avendo fesity con il supporto a compiz integrato come non provare il fatidico cubo? Forse ero rimasto uno dei pochi a non averlo ancora visto dal vivo e non mi ero mai impegnato ad installare tutto il necessario.

Scopro però che i drivers proprietari della mia scheda Ati mobility radeon 9700 non supportano l'estensione AIGLX necessaria a compiz. Io ho sempre usato questi drivers perché con quelli open non riuscivo ad abilitare il supporto all'accelerazione 3d.

Con un po di impegno in più, questa volta ci sono riuscito e finalmente ho anch'io i cubi rotanti e le finestre fluttuanti :D

Come procedere?

Prima di tutto se si hanno i drivers proprietari ati è necessario rimuoverli completamente.
Quindi bisogna editare il file xorg.conf con:

sudo gedit /etc/X11/xorg.conf

e fare in modo che le varie sezioni contengano quanto segue:


Section "Module"
........
........
Load "dri"
Load "glx"
........
........
EndSection

Section "Device"
Identifier "ATI Technologies, Inc. RV350 NP [Mobility Radeon 9600/9700 M10/M11]"
Driver "radeon"
...........
Option "AGPMode" "8"
Option "AGPFastWrite" "true"
Option "RenderAccel" "true"
Option "backingstore" "true"
EndSection

Section "DRI"
Mode 0666
EndSection

Section "Extensions"
Option "Composite" "True"
Option "RENDER" "Enable"
Option "DAMAGE" "true"
EndSection

A questo punto non rimane che riavviare X (se non funziona riavviate completamente il sistema operativo)

Assicuratevi che l'accelerazione 3d sia attiva con:

glxinfo | grep direct


deve comparire:

direct rendering: Yes

Se compare "no" allora siete sfortunati o avete sbagliato qualcosa.

Se compare "yes" è possibile finalmente abilitare gli effetti grafici: dal menù gnome Sistema->Preferenze->Effetti Desktop abilitare il cubo e le finestre fluttuanti.

Per una gestione più fine delle opzioni compiz, suggerisco di installare il pacchetto gnome-compiz-manager

03 aprile, 2007

Catturiamo il SIGTERM con python

Scrivendo una applicazione a volte è necessario compiere delle operazioni di "pulizia" prima che questa venga chiusa. A volte è necessario compierle anche se l'applicazione viene uccisa con kill.

Il comando kill

Il comando Kill serve per inviare dei segnali ad un processo. Utilizzato senza opzioni e con parametro un pid di un processo (che possiamo trovare utilizzando il comando ps), kill invia a tale processo il segnale SIGTERM che in genere indica al processo di terminare le sue operazioni. Esistono molti altri segnali ma in questo post ci occuperemo solo del SIGTERM.

Il modulo signal

Per la gestione dei segnali python mette a disposizione il modulo signal. Una delle funzioni più importanti presenti in questo modulo è la signal(). Questa funzione permette di registrare un handler per un particolare segnale.

Esempio


import signal
import sys
import time

def sigterm_handler(signum, frame):
print "SIGTERM catturato"
sys.exit(0)

signal.signal(signal.SIGTERM, sigterm_handler)

while (1):
sys.stdout.write(".")
sys.stdout.flush()
time.sleep(1)

Questo esempio continua a stampare "." fin quando non cattura il segnale SIGTERM inviato con una kill pid. A questo punto stampa il messaggio che indica che il segnale è stato catturato ed esce