Spiga

‘ Python ’ 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()

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")

getTorrent.py – script, para descarga de .torrent del RSS de Mininova y añadirlos a MLDONKEY

October 23, 08 by admin


Recientemente un amigo me paso un script para descargar Torrents de series españolas del MLDONKEY, el funcionamiento era que solicitaba el rss de series de mininova y lo parseaba para encontrar la url de dicho archivo, lo descargaba y guardaba en la carpeta que por defecto viene en el subdirectorio de mldonkey con nombre torrents/incoming. Mldonkey añade a su lista de descarga los torrent que se encuentre en esa carpeta.

Modificando su herramienta, la he convertido en un script para bajarme las series automáticamente sin necesidad de estar cada Lunes .. Martes etc… bajandome el torrent de la serie de turno y introduciendolo en MLDONKEY para subirle el torrent. El mecanismo es que seleciona del RSS el que más Seeds y Leechers tenga la formulá solo para mentes avanzadas Seeds*2+Leechers :P

El Script tiene dos modos básicos.

Manual:
[sourcecode language='Python']python getTorrent.py Dexter s03e04[/sourcecode]
Guardará en el directorio que le inquemos dentro del script como ML_PATH el torrent con mayor puntuación que de como resultado la busqueda de Dexter+s03e04, podriamos añadir todas las palabras de busqueda que queramos.

Automático:
[sourcecode language='Python']python getTorrent.py -c data.nui[/sourcecode]
contenido de data.nui:
[sourcecode language='Python']
Dexter+s03e01
Dexter+s03e02
Dexter+s03e03
Dexter+s03e04
[/sourcecode]
Ejecutamos esta orden mediante cron todos los Lunes. Primero descargará Dexter s03e01 al Lunes siguiente Dexter s03e02 y así sucesivamente hasta el final. Cierto es de que debemos de quitar el cron cuando se acabe la serie, aunque este no hará nada malo, ya que el archivo quedará vacio y no ejecutará nada.

Descargar: getTorrent.tar.gz