Recopilatori d'Abril


Escrit per Aaloy a 28 de April , 2013 a les 6:53 p.m.

A més de llegir el llibre de Gabriel Ginebra als vespres, aquests darrers dies han estat prou interessant. Tant que m'agradaria compartir amb la gent que llegeix aquest blog un parell d'històries i reflexions que m'han passat aquests darrers dies. El títol del l'apunt potser no és del tot exacte, però no sé com anomenar aquest calaix de sastre. És en aquests casos on es veu perfectament el concepte de blog personal :)

Feina comercial

La primera història entronca en el que és el funcionament diari de l'empresa. Un client de Madrid ens demana un pressupost per a una aplicació web. És un empresa gran i vol que hi anem a presentar-nos. Té bones referències nostres però ens vol conèixer personalment.

No hi tenc cap problema amb que un client ens vulgui conèixer, la nostra oficina està sempre oberta i la cafetera engegada. Però vol que anem a Madrid en pocs dies de marge. Es pot arreglar, li dic, però ens haurà d'enviar els bitllets.

Això deixà el client descol·locat. Diu que això no ho fan, que són els possibles proveïdors que es paguen el viatge per anar a veure'ls. Li explicam que nosaltres no funcionam així i al final la reunió es fa per videoconferència.

Sé que això és una pràctica habitual, però el que em sorprèn és que alguna gent no sia conscient de que al final el que estarà pagant en el seu projecte no serà sols el cost de desenvolupament i direcció de projecte, sinó també el cost dels comercials engominats que l'aniran a veure. I el que és pitjor, estarà pagant el cos no seu, sinó el cost proporcional de totes aquestes visites comercials que s'han fet, s'han pagat i que no han resultat en una feina. En poques paraules, estaran pagant molt més doblers per a un desenvolupament sols per fet que a algú li agradi sentir-se afalagat o important.

Sé que la feina comercial és important, però la nostra màxima ha estat sempre mantenir un nivell de despesa supèrflua mínima i per tant no carregar els pressuposts amb la despesa extra que suposa tenir una munió de comercials l'objectiu del qual no és més que fer la pilota als possibles clientes i que moltes vegades no saben el que venen.

Curiosament pareix que el potencial client, que normalment no pagarà la feina amb els seus propis doblers, necessita d'aquesta cerimònia, no essent conscient de que tot això ha de sortir forçosament dels projectes que farà l'empresa que està avaluant.

Potser també som atípics amb aquest aspecte, però em resisteixo a aquestes coses i trob que si la relació comercial ha de ser duradora aquesta no es pot basar en "te faig la pilota i així em compraràs". Si jo he de perdre tot un dia per anar a veure't al manco hem de compartir despeses, ja que per mi no és just haver de carregar aquests costs damunt els projectes d'un altre client.

De la mateix manera quan un pressupost veig que ha de dur dies de feina i a vegades setmanes o mesos, no ens podem deixar enlluernar pel possible guany futur. Si un vol un pressupost anàlisi d'aquesta mena l'ha de pagar, de la mateixa manera que paga els plànols d'un arquitecte. En cas contrari estaríem novament carregant molts costs contra els projectes que sí es fan.

Òbviament a l'hora de calcular el cost per hora que s'ha de carregar per la feina s'ha de tenir en compte que sempre hi haurà un cost comercial, com hi ha un cost per la gestió de l'empresa o el cost associat per la direcció. Però per ser justs crec que tot allò que ultrapassi el que és raonable s'ho hauria de pagar el que ho demana.

Segur amb aquesta mentalitat no arribarem mai a tenir un Ferrari a la porta, però segur què hi farem...!

Festa d'Habitissimo

El divendres vaig anar a la festa d'Habitissimo. M'agrada veure com un equip de gent com aquest creix i li van bé les coses. Ja fan quatre anys i han pogut créixer a un ritme fantàstic, i a la mateixa vegada mantenir l'esperit viu, inquiet i innovador no és fàcil i aquesta gent ho està aconseguint. Estic molt content per ells i sempre és un plaer poder converçar amb Jordi i Martin. A més la festa va servir per poder saludar a amics com Hugo o Suki. Amb Suki un poc més i feim les tantes cotorrejant.

Empreses com Habitissimo per mi sí que representen el que hauria de ser una empresa en el Parc Bit. Supòs que no és tan cool com fer-se una foto davant el logo de Microsoft pels polítics, però sí que us puc assegurar que estan fent molt més pel teixit empresarial de la nostra illa que els altres. Potser si algun dia ens n'adonam tots d'això es podrà invertir realment en el que dona feina i és una alternativa real al monocultiu turístic.

Antibes

La gent d'ACREW va organitzar un event a Antibes d'allò més sonat, i ja sabeu com va això. S'han de crear noves planes per l'ocasió, mirar de tenir noves característiques llests, i fins i tot un canvi d'imatge i de tot el procés de registre.

Van ser dies intensos de programació, però el resultat s'ho paga. Molt bona acollida de l'aplicació, molts usuaris nous i una startup que creix. No sé si arribarà als nivells d'Habitissimo, però la veritat és que per l'esforç que hi està posant la gent d'ACREW s'ho mereixen.

La resta és més o manco el dia a dia. Pareix que ens estam especialitzant en donar suport a emprenedors, tant gent que vol montar el seu negoci per primera vegada com empreses que volen donar el pas cap a Internet, i això m'agrada molt. És un tipus de client fantàstic i s'estableix una relació de complicitat molt bona.

No ho sé, a vegades tenc la sensació que podríem guanyar més organitzant-nos com a una empresa clàssica de desenvolupament, amb comercials engominats especialitzats en vendre vehicles de dues rodes, però segur que no ens ho passaríem tant bé.

Un dels lemes que més m'agraden de Python, el llenguatge que hem triat per al desenvolupament es "Life is short, use Python", per què no aplicar-ho també a la feina diària?


Traducciones/Translations by apertium

0 comentaris, 0 trackbacks (URL) , Tags: Informàtica Gestió de projectes APSL


El japonés que estrelló el tren para ganar tiempo


Escrit per Aaloy a 28 de April , 2013 a les 12:16 p.m.

Ahir vaig acabar de llegir "El japonés que estrelló el tren para ganar tiempo" de Gabriel Ginebra. Segons el subtítol intenta explicar el perquè ens tornam incompentents i com evitar-ho.

Ho vaig comprar en la seva edició Kindle, per poc més de 5 Eur. L'edició en sí es un poc descuidada, sovint no veus on comença un subcapítol i sembla que hi ha una línia desconnexa de la resta, la qual cosa resulta un tant molesta a l'hora de llegir.

Ginebra ens va mostrant les causes de la incompetència i els primers capítols són un resum del principi de Peter, lleis de Murphy i Dilbert, potser per posar-nos ja en guàrdia del que ens espera. Bàsicament ens ve a dir que tothom som incompetents, sia en un aspecte o altre i que el primer que hem de fer per millorar és ser conscient d'aquesta incompetència, abraçar-la i gestionar-la.

Fa molt èmfasi en com la sobrecompetència genera la incompetència. Voler arribar a la perfecció sense tenir en compte que vivim en un món imperfecte, a base de normes, procediments i sancions el que fa es generar renou i aconseguir l'efecte contrari del que volíem.

L'autor ens diu s'han d'eliminar capes de procediments, que la direcció de les empreses s'ha de concentrar amb gestionar les persones amb les persones, i no viure en una torre d'ivori practicant una mena de despotisme il·lustrat. És el que anomena el management amb minúscules.

Realment el que exposa Ginebra és del tot lògic i raonable, però no per això deixa de ser necessari exposar-ho i repetir-ho fins que la idea s'assenti. La meva pròpia experiència en les empreses en que he treballat m'ha permès veure molts tics que assenyala l'autor, així que hi hagi veus autoritzades que tracten el tema trob que sempre és bo.

Encara que el llibre en el seu conjunt és clar, si bé en alguns casos cau massa en l'anècdota, hi ha un capítol que ha quedat entre confús i contradictori. És el capítol 8 titulat "Trabajar lo peor posible". És un títol i una argumentació poc afortunada tal com s'expressa. Personalment la resumiria en aquella frase que diu que no hi ha res pitjor que fer de manera eficient allò que mai s'hauria d'haver fet. Això no vol dir fer feina el pitjor possible, sinó ser a la vegada intel·ligents i peresosos, saber treure el màxim rendiment de l'esforç i no crec que tengui res a veure amb treballar el pitjor possible. El fons del capítol està en aquesta línia, però trob que "The lazy project manager" tracta molt millor el tema i de manera més argumentada i menys contradictòria. En descàrrec de Ginebra val a dir que ell dedica un capítol a l'argumentació i l'altra és un llibre complet. El que sap greu és que és un capítol que no està realment a l'alçada de la resta.

M'han agradat especialment els capítols destinats a l'empresa barroca, el com una empresa va sobrecarregant-se, com els seus treballadors i directius van creant-se tasques del tot innecessàries per tal d'autojustificar-se. L'anomena el "Síndrome del demasiado tiempo libre". També són prou clarificadors els darreres capítols, destinats a les relacions humanes, a com gestionar persones i equips, el tracte humà, el parlar amb la gent, el poder-nos gestionar l'agenda de manera que s'ha de fer lloc per estar per la gent.

En resum, un llibre interessant, clarificador i bo de llegir, Potser massa llarg i tot pels pocs, però importants, conceptes que tracta. Força recomanable.


Traducciones/Translations by apertium

1 comentari, 0 trackbacks (URL) , Tags: Gestió de projectes


Raspberry pi


Escrit per Aaloy a 25 de April , 2013 a les 8:20 p.m.

Abans de festes en Xisco (a.k.a Zigazaga) em va dur la Raspberry, la idea era provar-la per mirar de substituir els ordenadors Pentium IV dels nins, però sobretot veure de primera mà aquest petit dispositiu del qual se n'estava parlant tant a la xarxa. Tanmateix el cost d'un dispositiu així si fa no fa és el d'un sopar sense postres, així que l'experiment si sortia malament tampoc no era excessivament complicat.

Xisco va dur la Rasberry i una capseta, tot queda molt compacte, la veritat. Una visita al magatzem xinès del costat de l'oficina va proporcionar el cable per connectar el monitor i vaig reciclar una tarja SD de 32 Gb que tenia sense utilitzar i que ara torna a ser al caixò dels cables.

La instal·lació va ser cosa de baixar-se la Rasbian, crear el disc d'instal·lació i seguir les instruccions, en poc menys d'una hora el sistema complet i funcionant, amb l'entorn gràfic i tot.

Es pot fer feina, però va molt justet de velocitat. Els nins estan acostumats a jugar online, a l'OpenOffice i ja vaig veure que no aniria gairebé la cosa. Tot i això per fer feina ofimàtica i programar va prou bé.

Així que pla B, a veure com es comportava com a servidor. Vaig desinstal·lar la part gràfica i fer un parell d'optimitzacions que vaig trobar per la web. Després a matxacar el sistema:

  • Postgresql 9.1
  • Django
  • Supervidor
  • Servidor ssh
  • ngnix
  • vim configurat
  • htop
  • tmux amb byobu
  • gunicorn
  • virtualenv i virtualenvwrapper

Tot això amb el Raspberry ja sense monitor i que està a la part inferior de la taula a l'altra punta del despatx de casa.

Vaig instal·lar la primera aplicació Django completa amb Gunicorn i connexió a Postgresql. Sense cachés ni res i desde l'ordinador principal un apache benchmark va amollar 3 req/s fent 100 peticions i 5 concurrents. La CPU del dispositiu al 100% però allà el veus tirant de base de dades i servint contingut. Potser 3 peticions per segon no pareixen moltes, però comencem a pensar en hores i dies i la cosa ja canvia.

Així doncs ja tinc un servidor prou bo per trastejar, que pot fer distints usos canviant la tarja SD i que torba uns 20-30 segons en posar-se en producció. Prou divertit.

Ara sols em quedava veure quins més usos es podrien donar al un servidor de despatx. A ca'n APSL vam montar un proxy de PyPi per evitar tenir que descarregar-nos els paquets cada vegada i agilitar la instal·lació dels entorns de les aplicacions. Vaig pensar que seria una bona idea, i vaig instal·lar el PyPiCache, ho vaig configurar a 3 workers (per mi amb un bastaria) i el vaig posar dins l'atenta gestió del supervisor i vaig configurar l'ordinador de feina per a que els paquets les demanàs a la Raspberry.

El proxy el que fa es mirar si té el paquet amb la versió que li demanam, si la té la serveix i si no la demana a PyPi. 42M d'arxius ja hi tenc guardats: Django, PIL, Pillow, Sort, reportlab, ...

El sistema encara no ha tirat de swap, els 512 MB de RAM aguanten la poca càrrega que li estic donant però amb prou utilitat per poder dir que en un tres i no res hauré amortitzat la compra (bé quan Xisco passi la factura clar! :) )

Raspberry te torna el gust a trastejar amb màquines, veure que una cosa tant petita i barata pot fer tanta cosa fa encara més ganes de fer servir més la imaginació i veure fins on es pot arribar.


Traducciones/Translations by apertium

1 comentari, 0 trackbacks (URL) , Tags: Python Django Codi lliure Linux


Mails amb Django - IV


Escrit per Aaloy a 29 de March , 2013 a les 11:21 a.m.

Amb tot el que hem vist fins ara podem organitzar els nostres enviaments de correus i mantenir al seu manteniment organitzat encara que el nombre d'opcions sigui gran.

Hi ha encara un grapat d'escenaris que és interessant tractar, ja que ens els trobarem sovint. Pensem en aquests possibles escenaris:

  • Ens hem de connectar a un servidor SMTP extern i el temps de connexió és gran, la qual cosa fa que la nostra aplicació web no respongui.

  • Tenim un entorn de preproducció on els correus no s'enviïn però on volem mantenir registre del que s'hauria enviat.

  • Volem mantenir un registre dels correus que s'envien dins la nostra aplicació.

El primer escenari es pot resoldre amb un servidor de correu local y fent realy cap al servidor final, però això a vegades no és possible ja que no tenim la gestió del servidor de correu.

També ho podem resoldre amb un sistema de coes, és a dir, l'enviament de correu es posa com a tasca i és un altre programa (un worker) el que se n'encarrega de fer l'enviament. La combinació de Celery+Redis ens pot anar bé, però també estam afegint un factor gran de complexitat: hem de tenir Redis instal·lat, configurar adequadament Celery i mantenir els workers actius amb supervisor.

Encara que el sistema de coes possiblement sigui l'opció millor per sistemes amb molta càrrega, s'ha d'avaluar bé si per la nostra aplicació convé complicar-nos tant la vida. Quan més peces posem més complexitat, més punts a gestionar, i la simplicitat importa. Si la nostra aplicació creix Django té prou flexibilitat per permetre'ns anar separant capes, afegir les coes, ...

Una solució a tots aquests problemes i escenaris, que a més és prou simple és la de guardar els correus que s'han d'enviar dins una taula de la base de dades i executar un procés cron per fer els enviaments. Això allibera ràpidament a la nostra aplicació web i no té la complexitat de manteniment d'un sistema de coes dedicat.

Com que el cron ho gestionam nosaltres, en preproducció podem dir que no s'executi, i els correus queden dins la base de dades i els podem veure sense cap problema sense fer un enviament real. Si hem de mantenir registre del que s'han enviat doncs també ho tenim.

Això no vol dir que aquest sistema no tengui mancances: si generam molts correus per segon el nostre coll d'ampolla serà la base de dades, però també és veritat que si enviam tal quantitat de correus, llavors sí que potser convé complicar-nos un poc més amb l'arquitectura de l'aplicació.

Dit això uns present django-mailer2. Al link he posat el fork que fem servir a APSL ja que ens hem trobat amb alguns problemes relacionats amb l'unicode que hem resolt i també amb la necessitat de poder visualitzar els e-mails amb adjunts. Així que es va fer un fork del fork i el fem servir a l'espera que l'autor del fork original ens admeti el codi nou, i ja posats vam generar la documentació per posar-la online a readthedocs.

django-mailer2 actua com a backend de Django, per la qualcosa una vegada instal·lada l'aplicació i posada als nostres settings.py hem de configurar el backend per a que quedi com

EMAIL_BACKEND = ‘django_mailer.smtp_queue.EmailBackend’

i farem un syncdb per crear les taules que necessitam a la base de dades.

A partir d'aquest moment els correus que enviem quedaran a la base de dades de django-mailer i no sortiran fins que executem la comanda

python manage.py send_mail

que és el que normalment posarem al cron.

Podem interactuar amb la prioritat d'enviament amb la capçalera

{‘X-Mail-Queue-Priority’: ‘<value>’}

on <value> pot prender els valor:

  • now per no posar-ho a la coa i enviar-lo immediatament.
  • normal prioritat per defecte
  • low prioritat baixa. Sortiran els darrers.

Si fem servir django-mailviews fixau-vos que seria prou senzill fer una classe base que abans d'enviar el correu li posàs la prioritat desitjada, afagint aquest paràmetre als headers.

Per mi aquesta aplicació ha estat un dels factors de productivitat més grans dels darrers mesos. Potser perquè les nostres aplicacions han d'enviar avisos amb adjunts i correus formatejats en HTML, és veritat, però poder mantenir el registre del que s'ha enviat i a l'entorn de preproducció despreoucupar-nos de maldecaps de si s'enviarà el correu sense voler o no és una meravella.

Epíleg

Amb això acab aquesta sèrie d'apunts sobre l'enviament de correus electrònics i Django. Esper que us hagi agradat llegir-los tant com a mi m'ha agradat escriure'ls.

La idea, com sempre, és compartir un poc les troballes que un va fent al llarg del temps. Pensau però que no hi ha veritats absolutes, potser per la vostra aplicació el que he contat per aquí no s'aplicarà, o demà sortirà una manera millor de fer les coses. Si això passa no deixeu d'avisar!


Traducciones/Translations by apertium

0 comentaris, 0 trackbacks (URL) , Tags: Django


Mails amb Django - III


Escrit per Aaloy a 28 de March , 2013 a les 1:18 p.m.

Fins ara hem vist com podem enviar correus electrònics amb format text, amb format HTML en el dos formats. També hem vist que podem generar el nostres correus a partir de plantilles Django.

A poc que l'aplicació es vaig fent més gran veurem que és molt interessant poder tenir tots els correus que enviam centralitzats, de manera que no hagem d'anar a cercar per codi i per les diferents aplicacions els correus que enviam.

Sovint a més els correus que enviam són semblants: van dirigits a la mateixa gent, o tenen informació que canvia molt poc d'uns als altres, com el peu del missatges o la salutació.

Una situació ideal per utilitzar dues coses: les plantilles de Django per a la generació de correus i aprofitar com Django va a cercar les plantilles per tenir tots els correus centralitzats a un mateix lloc, i per una altra banda l'herència pròpia de Python que ens permetrà guanyar temps a l'hora de generar els correus i farà que siguem menys propensos a error a l'hora de generar-los.

Ara és quan a un se li encén la bombeta i es posa com a un boig a generar classes de Python per a la generació de correus amb Django. No faceu tanta via! La primera regla del bricolatge: "si està fet compra-ho". Així que el primer que hem de fer és cercar si ja hi ha alguna cosa feta. I com no, hi és. De fet hi ha vàries llibreries per a la generació de correus fent servir plantilles Django. Una de les més interessants és la que ha fet Ted Kaemming anomenada django-mailviews que a més d'encapsular tot això en classes Python, ho ha posat dins un paquet Django que ens facilita la vida de visualitzar els correus.

La documentació no és tot el completa/acurada que hauria de ser i és focalitza més en la visualització que en el que jo trob més interessant que és aquesta possibilitat d'encapsulació. Així que fork al canto per a millorar la documentació!

En aquest article faré servir aquesta llibreria per mostrar com fer les tasques més habituals i que ja hem vist abans. Ja que hi som aprofitaré també per mostrar com podem enviar un fitxer adjunt.

Enviar un correu sols de text

Volem enviar un correu a un usuari.

Definirem les dues plantilles que utilitzarem, la primera per l'assumpte (subject) y l'altra per al contingut.

Cream un directori anomenat mail (sóc així d'original) dins templates de la nostra aplicació principal. A partir d'aquí podríem anar creant diferents subdirectoris segons els correus per a enviar, però supòs que ja es veu la idea...

La plantilla per l'assumpte queda com:

 {# plantilla 'mail/subject.html'
 Greetings {{user.get_full_name}}

i seguidament definim el cos del missatge

{# plantilla 'mail/body_text.html' #}
Dear {{user.get_full_name}}, 
You are the best.

Please give us your money!

El codi per enviar aquest missatge podria ser alguna cosa semblant a:

    from mailviews.messages import TemplatedEmailMessageView
    from django.contrib.auth.models import User

    class SimpleSpamView(TemplatedEmailMessageView):
        """
        Classe per spamejar l'usuari demo i dir-li que ens doni els doblers
        """

        subject_template_name = 'mail/subject.html'
        body_template_name = 'mail/body_text.html'

        def get_context_data(self, **kwargs):
            context = super(SimpleSpamView, self).get_context_data(**kwargs)
            context['user'] = self.user
            return context

        def render_to_message(self, *args, **kwargs):
            self.user = User.objects.get(username='demo')
            kwargs['to'] = (self.user.email, )
            return super(SimpleSpamView, self).render_to_message(*args, **kwargs)

i per enviar-lo bastaria cridar:

SimpleSpamView().send()

Pareix molta feina comparat amb el que teníem, veritat? Doncs sí, però com passa amb els class based views de Django aquesta feina extra inicial es veu compensada de sobres per la claretat del codi, que d'aquesta manera queda molt documentat, separant el text de generació, i sobretot possibilitant la reutilització.

Per cert la sortida d'aquest correu és:

Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: Greetings Demy Ostracion
From: webmaster@localhost
To: demo@example.com
Date: Thu, 28 Mar 2013 11:40:53 -0000
Message-ID: <20130328114053.6625.94194@T1600>

Dear Demy Ostracion,

You are the best.

Please give us your money!

Com podem veure es tracta d'un missatge codificat com a text, que és precisament el que cercàvem.

Correu amb text i HTML

Sabem que Demy, el nostre usuari de proves, fa servir un lector de correu que permet el format HTML, així que per reforçar més el missatge el que farem serà enfatitzar el missatge generant una plantilla HTML

{# mail/body_html.html #}
Dear {{user.get_fullname}},

<h1>You are the best!</h1>

<strong>Please give us your money!</strong>

Ara el que farem és que enlloc de fer herència de TemplatedEmailMessageView la farem de la classe TemplatedHTMLEmailMessageView que té un atribut nou html_body_template_name

    from mailviews.messages import TemplatedHTMLEmailMessageView
    from django.contrib.auth.models import User

    class SimpleSpamView(TemplatedHTMLEmailMessageView):
        """
        Classe per spamejar l'usuari demo i dir-li que ens doni els doblers
        """

        subject_template_name = 'mail/subject.html'
        body_template_name = 'mail/body_text.html'
        html_body_template_name = 'mail/body_html.html'

        def get_context_data(self, **kwargs):
            context = super(SimpleSpamView, self).get_context_data(**kwargs)
            context['user'] = self.user
            return context

        def render_to_message(self, *args, **kwargs):
            self.user = User.objects.get(username='demo')
            kwargs['to'] = (self.user.email, )
            return super(SimpleSpamView, self).render_to_message(*args, **kwargs)

i l'enviam com abans

    SimpleSpamView().send()

que té per sortida:

Content-Type: multipart/alternative;
boundary="===============6944209950729072063=="
MIME-Version: 1.0
Subject: Greetings Demy Ostracion
From: webmaster@localhost
To: demo@example.com
Date: Thu, 28 Mar 2013 11:56:34 -0000
Message-ID: <20130328115634.6625.91235@T1600>

--===============6944209950729072063==
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit

Dear Demy Ostracion,

You are the best.

Please give us your money!

--===============6944209950729072063==
Content-Type: text/html; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit

Dear Demy Ostracion,

<h1>You are the best!</h1>

<strong>Please give us your money!</strong>

Adjuntant arxius a un correu

Des de marketing ens diuen que ara el que convé és adjuntar fitxers en pdf per reforçar encara més el missatge i tenir el nostre usuari entretingut, així que ens passen un pdf amb informació corporativa que hem d'adjuntar a cada e-mail que li enviam a Demy.

Nosaltres el desarem al nostre directori pdf, però tenim un problema, la classe que estam fent servir no diu res d'adjuntar pdf. Però nins, això és codi obert i li podem fer una ullada al codi. Com podem veure el que fa render_to_message és tornar-nos una instància de la classe EmailMessage de Django i aqueta té dos mètodes per adjuntar imatges attach i attach_file. La primera la farem servir principalment quan tenim un fluxe de dades (per exemple hem generat nosaltres el pdf i està en memòria) i la segona quan tenim el fitxer dins el sistema d'arxius.

    from mailviews.messages import TemplatedHTMLEmailMessageView
    from django.contrib.auth.models import User

    class SimpleSpamView(TemplatedHTMLEmailMessageView):
        """
        Classe per spamejar l'usuari demo i dir-li que ens doni els doblers
        """

        subject_template_name = 'mail/subject.html'
        body_template_name = 'mail/body_text.html'
        html_body_template_name = 'mail/body_html.html'

        def get_context_data(self, **kwargs):
            context = super(SimpleSpamView, self).get_context_data(**kwargs)
            context['user'] = self.user
            return context

        def render_to_message(self, *args, **kwargs):
            self.user = User.objects.get(username='demo')
            kwargs['to'] = (self.user.email, )
            msg = super(SimpleSpamView, self).render_to_message(*args, **kwargs)
            msg.attach_file('./pdfs/test.pdf')
            return msg

    SimpleSpamView().send()

Que torna:

    Content-Type: multipart/mixed; boundary="===============5276732835281812163=="
    MIME-Version: 1.0
    Subject: Greetings Demy Ostracion
    From: webmaster@localhost
    To: demo@example.com
    Date: Thu, 28 Mar 2013 12:11:51 -0000
    Message-ID: <20130328121151.6625.85753@T1600>

    --===============5276732835281812163==
    Content-Type: multipart/alternative;
     boundary="===============7874338344503940985=="
    MIME-Version: 1.0

    --===============7874338344503940985==
    Content-Type: text/plain; charset="utf-8"
    MIME-Version: 1.0
    Content-Transfer-Encoding: 7bit

    Dear Demy Ostracion,

    You are the best.

    Please give us your money!

    --===============7874338344503940985==
    Content-Type: text/html; charset="utf-8"
    MIME-Version: 1.0
    Content-Transfer-Encoding: 7bit

    Dear Demy Ostracion,

    <h1>You are the best!</h1>

    <strong>Please give us your money!</strong>

    --===============7874338344503940985==--
    --===============5276732835281812163==
    Content-Type: application/pdf
    MIME-Version: 1.0
    Content-Transfer-Encoding: base64
    Content-Disposition: attachment; filename="test.pdf"

    JVBERi0xLjQKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0ZpbHRlci9GbGF0ZURl
    Y29kZT4+CnN0cmVhbQp4nDPQM1Qo5ypUMFAwALJMLU31jBQsTAz1LBSKUrnCtRTyIHJAWJTO5RTC
    ZWoGlDI3NwEqDklR0HczVDA0UghJi7YxMLQzs7AxMLIztDEwttM1sjEwsYsN8eJyDeEK5ApUAAB7
    ....
    ....
    --===============5276732835281812163==--

Com podeu veure s'ha enviat tant el text pla, l'html i el nostre adjunt.

En una aplicació real el path cap a l'arxiu seria una variable i/o estaria codificat de manera absoluta, però per l'exemple ja em perdonareu.

A partir d'aquí ja podeu veure que les possibilitats de personalització són infinites. Pensau que en una aplicació real amb molts correus a enviar, poder organitzar el codi en classes ens permetrà reaprofitar molta feina, i sobretot ens llevarà feina de depuració a l'hora d'anar canviant el texte del correu o les condicions en que s'ha d'enviar un correu.

I al proper article parlarem d'enviaments, coes, registre i depuració. Tot en un mateix paquet django-mailer2.


Traducciones/Translations by apertium

1 comentari, 0 trackbacks (URL) , Tags: Django