Spiga

Christmas is Coming …

December 15, 11 by admin

Prestashop – Precios decrecientes – mostrar precios reales, sin diferencia

November 26, 11 by admin

Prestashop por defecto muestra la diferencia entre el precio unitario de un articulo con el precio de la compra de cantidades superiores, el cambio que he llevado a cabo es solo para mostrar el precio que tendría para las diferentes cantidades de artículos, no la diferencia.
Lo he llevado a cabo modificando la plantilla directamente, es un pequeño cambio que quizás ahorre tiempo a alguien en un futuro.

No he tenido en cuenta ninguna tasa adicional, puesto que yo no las uso.

fichero:themes/prestashop/product.tpl linea 396


{if $quantity_discount.price != 0 OR $quantity_discount.reduction_type == 'amount'}
Introducimos esta linea entre la sentencia if-> {convertPrice price = $product->specificPrice.price|floatval - $quantity_discount.real_value|floatval}
{else}

Regenerar miniaturas – Prestashop

November 14, 11 by admin

Prestashop cuenta con una funcionalidad para regenerar las miniaturas que genera por cada imagen automaticamente unas copias de ella misma en diferentes resoluciones, el problema es que si estas ya se encuentran creadas no las sobreescribe, pero esto tiene fácil solución si localizamos donde comprueba en el código si existe previamente.

Para la versión, 1.4.3, comentad las lineas 315, 316 y 317
File: admin/tabs/AdminImages.php

linea 315: //if (!file_exists($newDir))
linea 316: // continue;
linea 317: //if (!file_exists($newDir.substr($image, 0, -4).'-'.stripslashes($imageType['name']).'.jpg'))
linea 318: if (!imageResize($dir.$image, $newDir.substr($image, 0, -4).'-'.stripslashes($imageType['name']).'.jpg', (int)($imageType['width']), (int)($imageType['height'])))

Script bash – busca el archivo más nuevo por directorio

September 30, 11 by admin

Este script, lo he utilizado para revisar cada cuanto tiempo se llevaba a cabo las copias de seguridad de los usuarios del sistema. El funcionamiento es bien sencillo, en un directorio madre, busca en sus subdirectorios el archivo más nuevo y lo guarda en un fichero, de esta forma podemos saber hace cuanto que no ingresa ningún nuevo archivo a una carpeta determinada.

En mi caso, tengo un segundo script que lee este fichero y en función de un tiempo determinado alerta al usuario de que debería de realizar un Backup, pero es simplemente un uso que podemos darle.


#!/bin/bash
FILE=/home/datesBackup.txt
rm $FILE
#Borro el fichero antes de comenzar
for i in `ls -l /home | gawk '{print $8}'`
do
find /home/$i -type f | xargs ls -alt | head -n 1 | gawk '{print $3, $6}' >> $FILE | grep -v 'ls:' | grep -v 'xargs:'
done
#Listo todos los directorios de /home y almaceno en la variable i
#Por cada un o de ellos busco el más nuevo y lo empipo al Fichero que antes borramos, filtrando posibles errores

Las tendencias suicidas de aptitude

August 22, 11 by admin

Ya ha dejado de sorprenderme las temibles dependencias que puede llevar consigo el software más ‘mindudi’ de un sistema Ubuntu, pero querer hacerse un Harakiri al estilo Japonés me parece demasiado.

Los siguientes paquetes se ELIMINARÃN:
evolution-documentation-es g++-4.3 gimp-help-es imagemagick-doc language-support-translations-es libadns1 libboost-python1.34.1 libmagick++1 libphonon4 libqt4-opengl libqt4-qt3support libsilcclient-1.1-3 libstdc++6-4.3-dev libzephyr4
linux-headers-2.6.28-19 linux-headers-2.6.28-19-generic menu obexd-client openoffice.org-help-es openoffice.org-l10n-es phonon phonon-backend-gstreamer qt4-qtconfig thunderbird-locale-es-ar thunderbird-locale-es-es
0 actualizados, 0 se instalarán, 25 para eliminar y 4 no actualizados.
Se liberarán 180MB después de esta operación.
¿Desea continuar [S/n]? n
Abortado.
denis@denis-logco:~$ uname -a
Linux denis-logco 2.6.28-19-generic #66-Ubuntu SMP Sat Oct 16 17:39:04 UTC 2010 i686 GNU/Linux

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

Maravilloso

December 06, 10 by admin

mysql> drop database otrs2
-> ;
ERROR 1008 (HY000): Can't drop database 'otrs2'; database doesn't exist
mysql> create database otrs2
-> ;
ERROR 1007 (HY000): Can't create database 'otrs2'; database exists
mysql>

Directorio de componentes Joomla

November 07, 10 by admin

Comparto con vosotros un diccionario que he ido alimentando de manera automática en su inicio y artesanal después, de componentes de Joomla, principalmente componentes vulnerables, puede que se haya colado alguno que no tenga fallo conocido, pero principalmente los componentes incluidos tiene algún tipo de fallo de seguridad.

Personalmente lo pongo en práctica con la herramienta pipper, que según veo ya no se encuentra en la página del autor Mandingo. Así que os lo adjuntaré abajo junto al diccionario.

Ejemplo de uso de pipper:
perl pipper.pl http://www.web.com/components/[file]/ -v file=/ruta/components.txt -hc 404

[+] Diccionatio: components.txt
[+] Pipper: pipper.tar.gz

Vacaciones inminentes!

July 31, 10 by admin

Hoy mismo empiezo las vacaciones, todo el mes de agosto, para comprar pilas nuevas y recargar las viejas. Estas vacaciones parecen que van a ser intensas, mañana salgo para Galicia una semana, después una semanita a la Herradura, un poquito de feria y a terminar el mes y descansar en Portugal.

Os dejo con esta canción que me ha acompañado mucho este año, y que cada vez que la escucho se me ponen los bellos de punta:

“que grande sería estar en un concierto de Daft Punk”, mae mia



Configurar Nagios para que te avise por Twitter

February 16, 10 by admin

Una poyadita que se me ocurrió, muy fácil de llevar a cabo, y que puede lanzarte a convertirte en el más guay de la oficina.

1.- Te sacas una cuenta twitter, le pones una foto de una tia buenorra, para que te de menos corage cuando algún servicio tenga problemas.. twitter te dá la posibilidad de proteger tus tweets, para que solo el que tu quieras pueda seguirte.

2.- Configuras blt en tu máquina, esta aplicación en linea de comandos te permite twitear.

3.- Modificas el archivo /etc/nagios3/commands.cfg

#Twitter
define command{
command_name notify-host-by-twitter
command_line /usr/bin/printf "%b" "***** Nagios *****\n\nNotification Type: $NOTIFICATIONTYPE$\nHost: $HOSTNAME$\nState: $HOSTSTATE$\nAddress: $HOSTADDRESS$\nInfo: $HOSTOUTPUT$\n\nDate/Time: $LONGDATETIME$\n" | /usr/local/bin/blt ** $NOTIFICATIONTYPE$ Host Alert: $HOSTNAME$ is $HOSTSTATE$ **
}

define command{
command_name notify-service-by-twitter
command_line /usr/bin/printf "%b" "***** Nagios *****\n\nNotification Type: $NOTIFICATIONTYPE$\n\nService: $SERVICEDESC$\nHost: $HOSTALIAS$\nAddress: $HOSTADDRESS$\nState: $SERVICESTATE$\n\nDate/Time: $LONGDATETIME$\n\nAdditional Info:\n\n$SERVICEOUTPUT$" | /usr/local/bin/blt "** $NOTIFICATIONTYPE$ Service Alert: $HOSTALIAS$/$SERVICEDESC$ is $SERVICESTATE$ **"
}

4.- Configuras el usuario que vaya a ser notificado por twitter, por defecto en: /etc/nagios3/contacts_nagios2.cfg


service_notification_commands notify-service-by-twitter
host_notification_commands notify-host-by-twitter

5.- Reiniciar el servicio y listo. /etc/init.d/nagios3 restart