Spiga

‘ programacion ’ category archive

Script para hacer Mailing en Python

July 30, 11 by admin

Mucho tiempo después vuelvo a compartir algo a través de este triste Blog, justo el día antes de irme de vacaciones, y con la intención de una vez que vuelva de las mismas dedicarle un poco más de tiempo, ya que me voy haciendo mayor y los escasos 140 caracteres de twitter se me empiezan a quedar cortos.

El tema es que hace unos días me puse manos a la obra a instalar una herramienta para hacer mailing y mientras buscaba pensaba en lo fácil que sería programarlo con Python, así que después de no encontrar nada que mereciera la pena, me puse a tirar lineas y en apenas un par de horas ya lo tenía, Python es maravilloso :D , así que con una sonrisa que aún dura, os dejo el código por si sirviera a alguien de ayuda en un futuro, y una buena manera de tenerlo yo siempre a mano.

Decir que el envío lo hago a través de Gmail de una cuenta legítima para evitar que sea catalogado como SPAM y el envío se hace cada 5 segundos para evitar que Gmail nos bloquee. Así que no está preparado para enviar grandes volúmenes.

init.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#!/usr/bin/python
#Script for Mailing
 
import sqlite3
import urllib
import smtplib
import sys
import time
from GmailMail import GmailMail
 
def initDb():
	conn = sqlite3.connect('db.sqlite')
	c = conn.cursor()
 
	# Drop and Create table
	try:
		c.execute('''DROP table user''')
	except:
		print "No existe tabla user previamente"
	c.execute('''create table user
	(id integer, name text, surname text,
	 email text, send integer)''')
 
	# Insert a row of data
	fd = open("datos.txt")
 
	i=0
	for line in fd:
	   	datos = line.split("\t")
		c.execute("insert into user values ("+str(i)+", '" + datos[0]+ "' , '" + datos[1] + "', '" + datos[2] +"',0)")
		conn.commit()
 
	   	print str(i) + ":  " + datos[0] + "  " + datos[2]
		i = i+1
	fd.close()
	conn.close()
def connDB():
	return sqlite3.connect('db.sqlite')
 
def closeDB(conn):
	conn.close()
 
def getAllDB(conn):
	c = conn.cursor()
	c.execute('''select * from user WHERE send=0''')
	arr = c
	return arr
 
def updateRegister(id,conn):
	c = conn.cursor()
	c.execute("UPDATE user SET send=1 WHERE id="+str(id))
	conn.commit()
 
def composeContent():
	f = open("email.txt")	
	content=f.read().decode("utf8")
	f.close()
        return content
 
def sendDB(subject, content, search):
	conn = connDB()
	try:
		m = GmailMail("usuario@gmail.com", "password")
	except:
		print "Error SMTP", sys.exc_info()
		raise
 
	c=getAllDB(conn)
	for row in c:
		print "Durmiendo cinco segundo para no saturar Gmail"
		time.sleep(5)
		try:
                        content=composeContent()
			email=row[3]	
			content = content.replace(search, row[1])
			m.send(email, subject, content)
			updateRegister(row[0], conn)
			print str(row[0]) + "  Enviado email a " + row[1] + " email : " + email
		except:
			print "Error id: " + str(row[0]), sys.exc_info()
	closeDB(conn)		
 
 
if __name__ == '__main__':
 
 
	if sys.argv[1]=="initDb":
		initDb()
	if sys.argv[1]=="run":
 
		subject=u"Asunto del email"
		search="$nombre"
 
		sendDB(subject, "", search)
	else:
		print """
			[+] initDb: Vuelca el contenido del fichero datos.txt a db.sqlite
			[+] run: Empieza el envio de mailing
		"""

datos.txt

nombre1 ape1 email
nombre2 ape2 email

email.txt

Estimado $nombre:

bla bla bla
bla bla bla
bla bla blas

GmailMail.py, por no complicarme con la codificación al final opté por esta clase que robé de internet.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/env python
 
# requires Python >= 2.5
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.mime.audio import MIMEAudio
from email.mime.image import MIMEImage
from email.encoders import encode_base64
from mimetypes import guess_type
from os.path import basename
 
class GmailMail():
    def __init__(self, gmail_user, gmail_pwd):
        """
        Prepares an instance with basic authentication
 
        """
        self.gmail_user = gmail_user
        self.gmail_pwd = gmail_pwd
 
    def getAttachment(self, path, charset='ASCII'):
        contentType, encoding = guess_type(path)
 
        if contentType is None or encoding is not None:
            contentType = 'application/octet-stream'
 
        mainType, subType = contentType.split('/', 1)
        _file = open(path, 'rb')
 
        if mainType == 'text':
            attachment = MIMEText(_file.read(), subType, charset)
        elif mainType == 'message':
            attachment = email.message_from_file(_file)
        elif mainType == 'image':
            attachment = MIMEImage(_file.read(), _subType=subType)
        elif mainType == 'audio':
            attachment = MIMEAudio(_file.read(), _subType=subType)
        else:
            attachment = MIMEBase(mainType, subType)
            attachment.set_payload(_file.read())
            encode_base64(attachment)
 
        _file.close()
 
        attachment.add_header('Content-Disposition', 'attachment',
            filename=basename(path))
 
        return attachment
 
    def send(self, to, subject, text=u"", html=None, attachments=None, charset="iso-8859-15"):
        """
        Sends an email through Gmail using the authentication
        given to this instance.
 
        If given, attachments must be a list of paths pointing
        to the files we want to include.
 
        This script does not embed inline content (multipart/related)
 
        """
        if charset in ['utf8','utf-8']: #bug?
            from email.charset import add_charset, SHORTEST
            add_charset('utf-8', SHORTEST, None, None)
 
        if isinstance(text, unicode):
            text = text.encode(charset, 'replace')
 
        if isinstance(html, unicode):
            html = html.encode(charset, 'replace')
        if attachments is None:
            attachments = []
 
        if text: plain_part = MIMEText(text, 'plain', charset)
        if html: html_part = MIMEText(html, 'html', charset)
 
        is_alternative = html and text
        layers = []
        if attachments or is_alternative:
            msg = MIMEMultipart() #mixed
            msg.set_charset(charset)
            msg.preamble = 'This is a multi-part message in MIME format.'
            msg.epilogue = ''
            layers.append(msg)
 
            if is_alternative:
                msgAlternative = MIMEMultipart('alternative')
                msg.attach(msgAlternative)
                layers.append(msgAlternative)
 
            if text:
                layers[-1].attach(plain_part)
            if html:
                layers[-1].attach(html_part)
 
        elif text:
            msg = plain_part
        else: #html only
            msg = html_part
 
        for path in attachments:
            msg.attach(self.getAttachment(path, charset))
 
        msg['From'] = self.gmail_user
        msg['To'] = to
        msg['Subject'] = subject
 
        mailServer = smtplib.SMTP("smtp.gmail.com", 587)
        mailServer.ehlo()
        mailServer.starttls()
        mailServer.ehlo()
        mailServer.login(self.gmail_user, self.gmail_pwd)
        mailServer.sendmail(self.gmail_user, to, msg.as_string())
        # Should be mailServer.quit(), but that crashes...
        mailServer.close()

Manual gSoap, por Manuel Castillo Cagigal

April 22, 09 by admin

Mi amigo Manuel Castillo Cagigal ha escrito un excelente manual sobre gSoap, lo comparte con todos vosotros con el fín de que a alguien le pueda facilitar un poco la comprensión de esta herramienta.

gSoap:
La herramienta gSoap realiza una conexión de lenguaje entre el protocolo SOAP/XML y el lengua je de programación C/C++ facilitando considerablemente el desarrollo de servicios web y aplicaciones cliente/servidor en estos lenguajes.

Descargar Manual.

getTorrent.py – nueva versión.

April 10, 09 by admin

¿Que es?

He subido una nueva versión debido a cambios en el RSS de mininova que no me parseaba correctamente los seechs y leechs.

Podeís descargarla desde aquí.

Script para hacer Backups

April 06, 09 by admin

Me he hecho un pequeño script en Python que llamo todos los dias en en el cron para que me haga un backup.
Utiliza scp y lo tengo configurado con certificado de la máquina ‘backup’ hacía la que va a copiar.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#!/usr/bin/env python
import os, time, smtplib, sys, subprocess, StringIO
from email.mime.image import MIMEImage
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
 
email = "email@dominio" #email al que vas a enviar
email_from = "email@dominio" #Desde el que vas a enviar
path = "/path/donde/guardar/el/backup"
path_l = path + "files/"
path_h = "/path/de/la/maquina/remota/a/copiar"
host = "ip_o_dominio"
user = "cacaue"
 
def writelog(content):
log=open(path+'log.txt', 'a')
log.write(time.strftime("%d %m %Y %H:%M")+"  "+content+"\r\n")
log.close()
 
def sendemail(content, asunto):
msg = MIMEMultipart()
msg['To'] = email
msg['Cc'] = ""
msg['From'] = email_from
msg['Subject'] = asunto
text = MIMEText(content)
text.add_header("Content-Disposition", "inline")
msg.attach(text)
 
try:
server=smtplib.SMTP("localhost")
server.sendmail(msg['From'], msg['To'], msg.as_string())
server.quit()
writelog("Email enviado a "+msg['To']+" con el contenido: "+content)
except:
writelog("Error al enviar email")
 
if __name__ == "__main__":
path_backup = path_l+time.strftime("%d%m%y")
try:
os.mkdir(path_backup)
except:
writelog("Ya existe --> "+path_backup)
 
cmd = "scp -r "+user+"@"+host+":"+path_h+" "+path_backup
try:
f=open(path+"temp.txt", "w")
retcode = subprocess.call(cmd, shell=True, stdin=f, stderr=f)
f.close()
if retcode < 0:
writelog("Child was terminated by signal")
else:
f=open(path+"temp.txt", "r")
salida = f.read()
f.close()
if os.path.getsize(path+"temp.txt")>0:
writelog("Error en "+host)
else:
sendemail(salida, "Backup "+time.strftime("%d/%m/%y")+" realizado con exito")
writelog("Realizado con exito")
 
except OSError, e:
writelog("Execution failed")