Author: Oriol Rius

Cues del postfix i informacions relacionades

Reading time: 60 – 100 minutes

Per defecte les cues que té el postfix són:

  • hold: missatges que no s’intenten entregar mai
  • incoming: cua d’entrada de missatges
  • active: cua en la que es decideix amb quin delivery agent s’itenta entregar un missatge
  • defer/deferred: missatges que no s’han pogut entregar per un error temporal es posen en aquesta cua
  • bounce: on es generen els missatges d’error cap al remitent dels missatges que no s’han pogut entregar
  • corrupt: cua que conté missatges danyats amb els que no es pot fer res

Accions que podem fer amb els missatges d’una cua:

  • Listing messages
  • Deleting messages
  • Holding messages
  • Requeuing messages
  • Displaying messages
  • Flushing messages

Gestió de les cues:

mailq
  • Mostrar els 10 dominis amb més missatges pendents d’enviar, sovint va bé per controlar quan ens han usat per fer un email i hi ha molts correus enganxats per enviar.
qshape -s deferred|head -n 10
  • Borrar un missatge de les cues.
postsuper -d ID_MSG
  • Borrar tots els missatges de les cues.
postsuper -d ALL
  • Script per borrar missatges de les cues segons origen o destí:
#!/usr/bin/perl -w
#
# pfdel - deletes message containing specified address from
# Postfix queue. Matches either sender or recipient address.
#
# Usage: pfdel 
#                                                                                         

use strict;

# Change these paths if necessary.
my $LISTQ = "/usr/sbin/postqueue -p";
my $POSTSUPER = "/usr/sbin/postsuper";

my $email_addr = "";
my $qid = "";
my $euid =
 
gt;; if ( @ARGV != 1 ) { die "Usage: pfdel \n"; } else { $email_addr = $ARGV[0]; } if ( $euid != 0 ) { die "You must be root to delete queue files.\n"; } open(QUEUE, "$LISTQ |") || die "Can't get pipe to $LISTQ: $!\n"; my $entry = ; # skip single header line $/ = ""; # Rest of queue entries print on # multiple lines. while ( $entry = ) { if ( $entry =~ / $email_addr$/m ) { ($qid) = split(/\s+/, $entry, 2); $qid =~ s/[\*\!]//; next unless ($qid); # # Execute postsuper -d with the queue id. # postsuper provides feedback when it deletes # messages. Let its output go through. # if ( system($POSTSUPER, "-d", $qid) != 0 ) { # If postsuper has a problem, bail. die "Error executing $POSTSUPER: error " . "code " . ($?/256) . "\n"; } } } close(QUEUE); if (! $qid ) { die "No messages with the address <$email_addr> " . "found in queue.\n"; } exit 0;
  • Borrar missatges segons email origen o destí.
/root/bin/pfdel email
  • Hold a message / Retenir missatges, no intentar servir-los. Posar-los a una cua congelats.
postsuper -d ID_MSG
  • Hold all messages
postsuper -d ALL
  • Moure un missatge de la cua ‘hold’ a la cua ‘active’.
postsuper -H ID_MSG
  • Moure tots els missatges de la cua ‘hold’ a la cua ‘active’.
postsuper -H ALL
  • Re-encuar missatges, per exemple si el postfix tenia un erro de configuració després de corregir-los podem re-encuar els missatges perquè es corregeixin els possibles errors de classificació que hagin patit. Per exemple, canvi de ‘delivery agent’.
postsuper -r ID_MSG
o
postsuper -r ALL
  • Veure el contingut d’un missatge que esta a la cua:
postcat -q ID_MSG
  • Per forçar el re-enviament de missatges a la cua.
postqueue -s
o
postfix flush
  • Per forçar l’enviament de missatges a la cua per un domini.
postqueue -s domini.com

Python: afegir suport de plug-ins al nostre codi

Reading time: 82 – 136 minutes

A vegades quan estem fent un programa ens interessa que el nostre codi pugui ser extés sense haver de tocar la seva estructra, fins hi tot el que ens pot interessar és que aquest codi sigui extés en algunes ocasions i en d’altres no. Un altre requeriment que podem tenir també seria que qui l’extengui no siguem nosaltres. Sovint tot això i molt més s’acostuma a fer amb el que anomenem Plug-ins, per cert, sempre m’ha fet molta gràcia la traducció al català de la paraula: ‘afegitons’.

Doncs bé, com que jo de programació no hi entenc gaire li vaig demanar al Pau que m’ajudés a entendre els models de plug-ins que implementaven alguns programes fets amb Python, ja que m’ineressava integrar aquesta funcionalitat en una serie de codis que estic desenvolupament. En aquest post intentaré explicar com funciona el paradigma dels plug-ins que usa Trac.

Primer de tot cal tenir en compte que Trac usa un patró de desplegament d’objectes anomenat Singleton, o sigui que totes les instàncies d’un objecte es refereixes a la mateixa instància. De fet, no sé dir fins a quin punt és necessari que el codi segueixi aquest patró per usar el sistema de plug-ins; tot i que jo diria que almenys les parts del codi que vulguin ser exteses pel model de plug-ins de Trac l’han de seguir.

Els plug-ins de Trac tenen les següents característiques:

  • Un Plug-in és un component que extent la funcionalitat d’un altre component
  • Un Plug-in pot extendre un altre Plug-in

Per tal d’incorporar la filosofia que té Trac per suportar Plug-ins al nostre codi cal importar el component ‘trac.core’, d’aquest component usarem el següent:

  • trac.core.Interface (classe) s’usa per definir quin és el contracte que hauran de seguir els plug-ins.
  • trac.core.ExtensionPoint (funció) quan volem que un component sigui extés usarà aquesta funció per recuperar les implementacions del contracte. Deifineix els punts de hook que té el nostre codi.
  • trac.core.implements (funció) quan un component usa aquesta funció és per implementar un contracte, o sigui, que els plug-ins que es construeixin l’han d’usar.

Abans de seguir explicaré que s’enten per contracte. Un contracte és en escència una classe de tipus interficie (python no té aquest model com a tal) que defineix quins mètodes (o altres classes) poden ser extesos dins el component original. O sigui, que cal no només definir quin és el contracte que s’ofereix sinó també documentar-lo el millor possible, explicant quines són les entrades i sortides que s’esperen de cada un dels mètodes/classes.

Perquè tot plegat s’entengui millor el Pau em va posar el següent exemple:

Imaginem que tenim una classe del tipus DNI que implementa una base de dades de DNIs, on té un metode que ens permet entrar DNIs a la base de dades:

class DNI(trac.core.Component):
  dni_checks = trac.core.ExtensionPoint(IDNIInput)
  def __init__(self):
     self._dnis = []
  def add(self, dni):
     assert not dni in self._dnis, "DNI ja existeix"for dni_check in self.dni_checks:
     if dni_check.check(dni) is False:
       print "El dni %s  sembla no ser correcte" % ( dni )
       return
    self._dnis.append(dni)
  def llista(self):
    print self._dnis

Cal fixar-se que la línia:

dni_checks = trac.core.ExtensionPoint(IDNIInput)

el que fa és carregar els plug-ins que extenen la funcionalitat del codi original. A més cal que ens fixem que el paràmetre que usa la funció és la classe que defineix el contracte sobre el que es fan els plug-ins:

class IDNIInput(trac.core.Interface):
  def check(dni):
    """ Es cridada cada cop que s'entra un nou dni, espera que es retorni un valor boleà"""

Com es pot veure el contracte només defineix un mètode: ‘check’ que ha de tenir un paràmetre d’entrada i espera un valor boleà de sortida.

Cal fixar-se en que la classe DNI cada vegada que afegeixi un element a la base de dades (en aquest cas una simple llista), cridarà a tots els plug-ins que compleixin el contracte per l’ordre en que s’han instanciat (s’han importat al codi original) mitjançant el següent codi.

for dni_check in self.dni_checks:
  if dni_check.check(dni) is False:
    print "El dni %s  sembla no ser correcte" % ( dni )
    return

Un exemple de plug-in sobre el codi anterior i que compleix el contracte especificat podria ser aquest:

import trac.core
import dni
class ValidDNI(trac.core.Component):
  trac.core.implements(dni.IDNIInput)
  def check(self, dni):
    if type(dni) is not type("str"):
      return False
    if len(dni) != 9:
      return False
    return True

Es pot veure com la classe és una instància de ‘trac.core.Component’ (model Singleton) i implementa la interfice ‘dni.IDNIInput’. A nivell funcional el que es fa és ben simple, comprovem que sigui una cadena de texte i que tingui una mida de 9 caràcters, si això es dona retorna un ‘True’ o sinó un ‘False’.

Un exemple de com quedaria el codi principal seria:

import trac.core                                                           

class IDNIInput(trac.core.Interface):
  def check(nom):
    """ Es cridada cada cop que s'entra un nou dni"""
class DNI(trac.core.Component):
  dni_checks = trac.core.ExtensionPoint(IDNIInput)
  def __init__(self):
    self._dnis = []
  def add(self, dni):
    assert not dni in self._dnis, "DNI ja existeix"
    for dni_check in self.dni_checks:
      if dni_check.check(dni) is False:
        print "El dni %s  sembla no ser correcte" % ( dni )
        return
    self._dnis.append(dni)
  def llista(self):
    print self._dnis

Exemples d’ús:

>>> import trac.core
>>> from dni import DNI
>>>
>>> dni_bd = DNI(comp_mgr)
>>> dni_bd.add("38135009C")
>>> dni_bd.add("38135009")
>>> dni_bd.llista()
['38135009C', '38135009']

# importem el plug-in check_dni
>>> import check_dni
>>> dni_bd.add("11111111")
El dni 11111111  sembla no ser correcte
>>> dni_bd.add("11111111A")
>>> dni_bd.llista()
['38135009C', '38135009', '11111111A']

Definim el codi ‘log_dni’ que serà un altre plug-in:

import trac.core
import dni
class LogDNI(trac.core.Component):
  trac.core.implements(dni.IDNIInput)
  def check(self, dni):
    print "Nou dni entrat %s" % (dni)

Seguim amb l’exemple anterior:

# importem ara el plug-in 'log_dni'
>>> import log_dni
>>> dni_bd.add("22222222B")
Nou dni entrat 22222222B

A aquestes altures ja s’han carregat dos plug-ins que treballen un després de l’altre i s’ha pogut apreciar la simplicitat i potència del model. Obviament es poden trobar coses a faltar com per exemple algún element que defineixi el llistat de plug-ins disponibles i que permeti alterar l’ordre en que aquests s’executen però això ja s’hauria de desenvolupar a part.

Espero haver-ho descrit de forma entenedora i sent el més fidel possible a les explicacions del Pau, al que he d’agrair-li l’esforç i dedicació per explicar-me aquest model de Plug-ins de Python.

llibre d’XMPP – notes a peu de pàgina

Reading time: 1 – 2 minutes

Després de llegir-me el llibre:

He pres les següents notes al moleskine que guardo aquí per poder consultar en el futur:

  • pg.39: IQ or Message
  • RFC 3920: stanza errors list
  • SleekXMPP llibreria python interessant
    • Apendix F: llistat de llibreries XMPP
  • pg.50: Subscription
  • Presence priority: -127 +128
  • XEP 0191: bloquejar JID o dominis
    • Podria ser interessant per bloquejar clients que no paguen
  • XEP 0079: ideal delivery a pantalles, reliable delivery
    • oblidar-nos de problemes si les pantalles estan offline
    • expiration time dels missatges
    • control delivering
  • XEP 0009: JabberRPC
  • XEP 0072: SOAP over XMPP
  • XEP 0060: PubSub
  • XEP 0163: permet que JID sigui un ‘collection node’ que agrupi serveis PubSub això es pot publicar junt amb les capabilities
  • Pg. 132/150: ICE, molt bona explicació
  • Pg. 145/163: VNC over XMPP es pot fer usant socks5 com a proxy segons XEP
  • XEP 0050: remote commands
  • BOSH: 180/198
  • Pg. 189/207: Serverless Messaging
  • Pg. 267/285: DNS SRV

Nagios external commands

Reading time: 12 – 19 minutes

Tan de temps usant nagios i mai havia tingut la necessita de recorrer als Nagios External Commands. Escencialment es tracta d’una named-pipe que usa Nagios per rebre comandes via shell.

  • Sintaxis per injectar les comandes. Per suportar aquesta funcionalitat previament cal haver-la habilitat al fitxer de configuració de nagios, això també ho trobareu a l’anterior enllaç.
  • Comandes suportades, la llista és força gran i hi podem trobar coses com ara forçar un check per host o fins hi tot deshabilitar els checks sobre un servei o un host.

A continuació adjunto la comanda que podeu llençar desdel prompt per llençar una ordre al nagios al cap de deu segons. En aquest cas forcem que es verifiquin tots els serveis d’un host.

# des del directori on hi ha la 'named-pipe' sovint anomenada 'nagios.cmd'
now=$(date +%s); next=$(expr $now + 10); echo "[$now] SCHEDULE_FORCED_HOST_SVC_CHECKS;nom_host;$next" > nagios.cmd

Per veure el resultat de la comanda i si aquesta ha estat rebuda pel nagios només cal que mirem el fitxer nagios.log. La sortida del log serà algo així:

data host_server nagios: EXTERNAL COMMAND: SCHEDULE_FORCED_HOST_SVC_CHECKS;nom_host;unix_ts

Què vol dir Creative Commons?

Reading time: < 1 minute Fa molt temps que tinc aquesta animació en flash donant tombs pel disc dur i avui m'he decidit a penjar-ho per aquí abans de que no li perdi la pista:

Fitxers kmz/kml i htc footprints

Reading time: 3 – 5 minutes

footprintAquestes últimes vacances a madeira he aprofitat per utitlizar una eina que fins ara incorporaven els mòbils que tenia però que fins ara que m’he passat a Android no m’he decidit a expremer, estic parlant d’htc footprints. És una eina que a partir d’un simple formulari permet registrar llocs emblemàtics, bonics, interessants, curiosos o que simplement volem recordar. Aquest formulari guarda coses com una fotografia del lloc, un títol, la posició del GPS, la direcció, pots afegir-hi comentaris de text i fins hi tot de veu; potser hem deixo algún detallet del que pots afegir-hi per cada entrada a footprints però escencialment això és tot el que fa. Obviament el bo del tema és que gràcies a les tecnologies que incorpora el telèfon omplir el formulari és ben senzill, ja que la foto, posició del GPS o gravació de veu es fan amb simples clics, com sempre el més molest és escriure text.

L’interessant del tema és que després això es pot exportar a un fitxer .kmz (tot el contingut del footprints) o un fitxer .kml (només una entrada del footprints). El .kmz conté en escència un paquet amb un fitxer kml i els arxius externs del footprints, per exemple, les fotografies o l’audio. Pel que fa al format del fitxer .kml es tracta d’un fitxer XML amb el contingut del formulari que he comentat anteriorment. Aquests fitxers són directament importables al Google Earth i a moltes altres eines de la saga de Google. Però el que a mi m’interessa comentar en aquest article és la llibereria libkml, també de google, la que vaig usar per parsejar el fitxer kmz de les vacances a Madeira.

schema fitxer kml

A través d’un simple codi amb python vaig generar el codi en format dokuwiki necessari per montar-me l’esquelet de la web de les vacances a Madeira. De fet, el codi no esta gens polit i esta extret d’snippets d’exemple que he trobat per la web, però pel que jo volia era més que suficient. Al final del post hi teniu un enllaç.

Fa dies que en aquesta línia dono voltes a la idea de montar-me un servei que després de fer una entrada al footprints amb el mòbil enviï automàticament el fitxer .kmz/.kml per email a una direcció reservada que parsegi el correu i que automàticament doni d’alta aquest contingut a alguna de les seccions d’oriolrius.cat, de fet, encara no tinc clar si la millor idea és injectar-ho com a post o com a entrada del wiki, el que si que tinc clar és que això després s’haurà de referenciar al meu lifestream perquè així quedi constància de llocs interessants que coneixo i que sempre que vols recordar ja has oblidat. Si algú té idees de com millorar aquesta idea, ja ho sap, que m’avisi.

Referències:

NOTA: el codi del dokuwiki usa el plugin de google maps.

Salt amb paracaigudes

Reading time: < 1 minute Avui he marcat un 'fet' en una de les coses que tinc que fer a la vida abans de morir:

Nous gadgets que corren per casa

Reading time: 7 – 12 minutes

El que faré en aquesta entrada és un petit recull de comentaris sobre els últims dispositius que hi ha per casa.

Consola Wii + Wii Fit + Wii Motion Plus

Wii

Mai m’havia imaginat que em compraria una consola, de fet, tècnicament tampoc ho he fet ja que va ser un regal que li vaig fer a Estefania pel seu aniversari a finals de maig. Però com ja era la idea és un regal que disfrutem tots dos. Realment és un concepte totalment diferent del que jo havia entès sempre com a consola. Sota el meu punt de vista és una eina d’entreteniment que dona un punt d’interactivitat tan innovador que potser fins hi tot li caldria un nom diferent, enlloc de ser una consola més.

Wii Fit

Si ens fixem en l’ús que jo li dono, fins hi tot podriem anomenar-ho màquina de fer esport. Per sort no només faig esport amb la Wii, però he de dir que entre els 30min de footing que faig dia si dia no, més el control del meu IMC que hem permet portar la Wii Fit i la experiència brutal que em dona el Wii Motion Plus quan jugo al Virtua Tennis 2009 és una màquina de fer esport molt entretinguda i a sobre m’ajuda a mantenir-me en forma.

Wii Motion Plus

A més no cal oblidar la component social, crec que és una consola ideal per disfrutar amb els amics i deixar de banda els sovint aborrits jocs de taula. Segur que hi ha molta gent que no es cansa mai de jugar al parxís o a la oca; però jo de ben petit sempre he tingut repelús a aquest jocs, fins hi tot quan no sabia ni el que era un ordinador.

Archos 5 + DVR Station Generation 6

De fet l’Archos5 ja fa molts dies que corre per casa, fins hi tot hauria de dir pel món. Ja que com a dispositiu portàtil per això va ser pensat per emportarte’l pel món. Com passa sovint amb aquests gadgets Estefania els disfruta sobretot quan anem de viatge, però jo en el meu dia a dia l’uso per ambietar les meves jornades de treball o per animar els viatges que faig a Barcelona.

Els seus 120Gb de disc dur trobo que són ideals, mai els he trobat excessius com a molt algún cop n’hagués volgut més. Ja que sempre es pot usar com a disc dur portàtil. Potser una cosa que no m’agradam massa és que no puc usar la funció de dispositiu mass storage (disc dur extern) mentre reprodueixo música. Trobo que seria ideal tenir-lo connectat al portàtil mentre treballo i escolto musica, de forma que quan tingués alguna cosa que copiar-me per emportar: PDFs, més música, podcasts, etc. ho fes directament. Però no es pot tenir tot.

He de dir que les funcions que més uso quan viatjo són les de veure videos, escoltar música i llegir PDFs. Aquesta última funció és un pel lenta pel meu gust però sovint l’utilitzo ja que sempre porto una bona col·lecció de llibres tècnics que no puc evitar fullejar o fins hi tot llegir. Això si, no ús recomano fer-ho més d’1h seguida ja que és força dur per la vista les 5″ de la pantalla tampoc donen per tan.

Archos5 DVR Station

Pel que fa a la DVR station només fa unes setmanes que la vaig comprar, obviament la tenim al menjador i gràcies al seu comandament a distància més que complert l’usem per veure pel·lícules o per posar música usant la TV del menjador. L’usabilitat del comandament a distància és bona en general, potser el problema més greu és que el ratolí (per dir-li d’alguna forma) que incorpora el comandament és força inusable però això només cal usar-ho si volem navegar per internet.

Archos5 DVR Station Generation 6 - Remote Control

Pel que fa a l’accés del contingut que tinc a la xarxa es fa via UPnP i el servidor UPnP que tinc instal·lat al meu NAS (Openfiler) és el Mediatomb, cosa que de moment m’està donant una serie d’inconvenients que no he resolt. Per un costat, a l’hora de buscar contingut em mostra tot el media en una sola carpeta, cosa força inusable degut a la quantitat. Malgrat això és culpa de que el servidor UPnP exporta el contingut de forma poc òptima per defecte, hauré de mirar de configurar-lo millor. L’altre inconvenient és que si reps un contingut via UPnP no pots usar les funcions de ‘fast-forward’ i ‘rewind’ cosa realment molesta en moltes ocasions.

Archos5 DVR Station Generation 6 - Connections

Comentar també que la radio per internet que té instal·lada l’Archos5 és un programa que es diu vTuner i que malgrat té molt contingut i molt ben ordenat, entre el qual he trobat emisores que m’agraden molt també trobo molt a faltar el no poder usar eines d’internet com Spotify o LastFM. Cosa que a priori semblaria suportada perquè l’Archos5 suporta Flash tan en pàgines web com en aplicaciones standalone però no és capaç de reproduir cap de les coses que he comentat.

HTC Hero

htc hero

Finalment l’últim gadget a comentar és el mòbil que he adquirit: HTC Hero en lloc del HTC Touch Cruise que he tingut fins ara. De fet, no ha estat un canvi per gust sinó obligat ja que en un sopar a la fresca d’aquest estiu el mòbil va desapareixer i per tant vaig haver de buscar-me la vida. Així doncs, després d’una bona oferta per part d’Orange vaig adquirir aquest terminal.

Comentar que per fi sóc lliure! ja no depenc del coi de Windows Mobile que això més que un sistema operatiu era un mal son. Android no és la perfecció però em dona moltes alegries i bones experiències cada dia. Cosa que no es pot dir del anterior sistema.

Sobre el terminal comentar que aquesta petita curva que fa en la part inferior i que tanta por em feia que es convertís en una incomoditat, almenys per mi, s’ha acabat convertint en una comoditat ja que quan porto el terminal a la butxaca aquest s’adapta millor a la forma del cos.

Com a inconvenient comentar que la pantalla tàctil és una mica difícil d’usar quan tens les mans suades o humides de la calor o algún altre motiu. Sort del trackball que sovint ens facilita la vida. Això si, quan tens les mans ben seques la usabilitat tàctil del terminal és genial i el teclat virtual quan girem el terminal és realment còmode d’usar.

Per buscar-li coses negatives comentar que la cobertura GSM a vegades va i ve, sense massa explicacions i malgrat et diu que tens cobertura sembla que a qui et truca li diu que no estas disponible. Encara he d’acabar de validar si aquest problema és degut a la cobertura que hi ha a casa meva o bé, és realment un problema del terminal. Aquesta propera setmana tindré un altre teminal d’Orange per temes de feina i així ho podré contrastar.

Ubuntu Hardy (8.04) i monit 4.10.1

Reading time: 15 – 25 minutes

El paquet .deb de la versió 4.10.1 del monit no esta disponible per Ubuntu Hardy (v.8.04) el paquet més nou disponible és el 4.8 el problema més greu que suposa això és que no podem usar com servidor de notificacions servidors SMTP sense SSL, per exemple, no es pot usar smtp.gmail.com (gmail.com).

Si voleu instal·lar el paquet 8.10.1 el que s’ha de fer és:

cd /var/tmp
wget http://es.archive.ubuntu.com/ubuntu/pool/universe/m/monit/monit_4.10.1-3_i386.deb
sudo dpkg -i monit_4.10.1-3_i386.deb
monit -V

i veurem l’esperat:

This is monit version 4.10.1
Copyright (C) 2000-2007 by the monit project group. All Rights Reserved.

En cas de voler enviar els correus a gmail la configuració seria algo així:

set mailserver smtp.gmail.com port 587
    username [user]@gmail.com password [pass]
    using TLSV1
    with TIMEOUT 20 seconds

Viatge a Madeira d’aquest agost

Reading time: 1 – 2 minutes

Aquest agost Estefania i jo ens hem escapat 7 dies a l’illa de Madeira per descansar i fer una mica el turista. Fa dies que estem remanant per mostar-vos un petit resum del que varem estar fent per l’illa en format web i finalment tenim una versió presentable del que hem escrit.

Per cert, pels més geeks comentar que les fotografies i la informació del GPS les he tret del programa footprints que vaig estrenar durant el viatge amb el nou mòbil: htc hero. Mòbil del qual encara ús dec una review, de fet, per casa hi tot un seguit de nous aparells que hem anat comprant els últims 2 o 3 mesos i que encara no he comentat al blog. Així doncs, segurament aquesta setmana en faré una review conjunta.

Scroll to Top