Archivo

Archivo para diciembre, 2008

Borrando correos masivamente usando Javamail

Martes, 30 de diciembre de 2008

Este articulo es una mejora al código que escribí anteriormente. Jugando un poco con Gmail me di cuenta que los correos aún pueden ser recuperados usando POP3, pese a que fueron borrados con IMAP. Realmente bizarro. Así que modifiqué el programa para que manejara un poco mejor el caso de POP3 o IMAP según las propiedades.

Aquí está el código:

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
117
118
package com.kodegeek.blog.mail;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
 
import javax.mail.Session;
import javax.mail.Flags.Flag;
import javax.mail.internet.MimeMessage;
import javax.mail.Message;
 
import javax.mail.Folder;
import javax.mail.MessagingException;
import javax.mail.Store;
 
import com.sun.mail.imap.IMAPFolder;
 
import java.io.FileInputStream;
 
/**
 * I wrote this program to erase ALL the email on my GMAIL account. I have over 40,000 email so manually doing so was not an option :)
 * Please check the following resources:
 * <ul>
 * <li> http://java.sun.com/products/javamail/javadocs/index.html</li>
 * <li> http://java.sun.com/developer/onlineTraining/JavaMail/contents.html</li>
 * <li> http://java.sun.com/products/javamail/javadocs/com/sun/mail/imap/package-summary.html</li>
 * <li> http://java.sun.com/products/javamail/downloads/index.html</li>
 * </ul>
 * Also define a properties file with the following (adjust it to your configuration):
 * # As defined by the Javadoc
 * <ul>
 * <li> mail.user=name.lastname@gmail.com</li>
 * <li> mail.password=zzz</li>
 * <li> mail.store.host=pop.imap.gmail.com</li>
 * <li> mail.store.protocol=imap</li>
 * <li> mail.imap.port=993</li>
 * <li> mail.imap.socketFactory.port=993</li>
 * <li> mail.imap.socketFactory.class=javax.net.ssl.SSLSocketFactory</li>
 * </ul>
 * More examples:
 * <ul>
 * <li>POP3: -Dmail.user=name.lastname@gmail.com  -Dmail.password=XXXX -Dmail.store.host=pop.gmail.com -Dmail.store.protocol=pop3 -Dmail.store.folder=INBOX -Dmail.pop3.port=995 -Dmail.pop3.socketFactory.port=995 -Dmail.pop3.socketFactory.class=javax.net.ssl.SSLSocketFactory</li>
 * <li>IMAP: -Dmail.user=name.lastname@gmail.com  -Dmail.password=XXXX -Dmail.store.host=imap.gmail.com -Dmail.store.protocol=imap -Dmail.store.folder=INBOX -Dmail.imap.port=993 -Dmail.imap.socketFactory.port=993 -Dmail.imap.socketFactory.class=javax.net.ssl.SSLSocketFactory</li>
 * </ul>
 * License: GPL
 * http://kodegeek.com
 * @author Jose Vicente Nunez Zuleta
 * @version 12/28/2008
 */
public final class MailBulkEraser {
 
	/**
	 * Command line processing
	 * @param args [0] Location of the properties configuration file, If not provided then will use system defaults (defined with -D)
	 * @throws Exception
	 * @since 0.1
	 */
	public static void main(String [] args) throws Exception {
 
		Logger logger = Logger.getLogger(MailBulkEraser.class.getName());
 
		Properties props = System.getProperties();
		if (args.length == 1) {
			props.load(new FileInputStream(args[0]));
		}
		Session session = Session.getInstance(props, null);
		session.setDebug(Boolean.parseBoolean(props.getProperty("debug")));
		Store store = session.getStore(props.getProperty("mail.store.protocol"));
		logger.info(String.format("Connecting to: %s@%s", props.getProperty("mail.user"), props.getProperty("mail.store.host")));
		store.connect(props.getProperty("mail.store.host"), props.getProperty("mail.user"), props.getProperty("mail.password"));
		Folder folder = store.getDefaultFolder();
		logger.info("Got default folder. Erasing emails from ALL the folders");
		Folder [] folders = folder.list();
		long messgCnt = 0;
		for(Folder currFolder: folders) {
 
			try {
 
				if ((currFolder.getType() & Folder.HOLDS_MESSAGES) == 0) {
					continue; // Skip this folder type
				}
				logger.info(String.format("Opening folder: %s, num messages; %d", currFolder.getFullName(), currFolder.getMessageCount()));
				currFolder.open(Folder.READ_WRITE);
				Message [] messages = currFolder.getMessages();
 
				// Mark all the messages for delete
				for (Message message: messages) {
					try {
						if (! currFolder.isOpen()) {
							logger.warning(String.format("Folder %s is closed. Moving to next folder", currFolder.getFullName()));
							break;
						}
						message.setFlag(Flag.DELETED, true);
						MimeMessage currMessage = (MimeMessage) message;
						logger.info(String.format("Deleting mail subject: '%s', folder: '%s', date: '%s'", currMessage.getSubject(), currMessage.getFolder().getFullName(), currMessage.getSentDate()));
						if (currFolder instanceof IMAPFolder) {
							messages = currFolder.expunge(); // Confirm delete for all the messages on the current folder
						}
						messgCnt += 1;
					}  catch (Throwable thrbl) {
						logger.log(Level.WARNING, "There was a problem erasing the message, ignoring", thrbl);
						continue;
					}
				}
 
				logger.info(String.format("Messages erased on folder %s: %d", currFolder.getFullName(), messages.length));
				currFolder.close(true);
 
			} catch (MessagingException messgExp) {
				logger.log(Level.WARNING, "There was a problem, ignoring", messgExp);
			}
 
		}
		logger.info(String.format("Total number of erased messsages: %d", messgCnt));
		store.close();
		System.exit(0);
	}
 
}

Nota de los cambios:

Que lo disfruten :) .

java, kodegeek, opensource , , , , , ,

¿Como borrar 40000 correos en Gmail? Fácil, usando Javamail e IMAP

Domingo, 28 de diciembre de 2008

Este fin de semana me decidí a poner un poco de orden en mis cuentas de correo; Una de las cosas que me obligó a ello es que mi cuenta paga de Yahoo expiró y aún ando debatiendo si debo pagar $20 por una cuenta de correo que no ofrece nada por encima de Gmail. Al momento de revizar mi cuenta de Gmail me encuentro con que estoy usando por encima de 1 GB en correo con más de 40000 correos.

Si, es increíble la cantidad de basura que se acumula en dos años :)

Definitivamente no estaba dispuesto a perder mi tiempo borrando tal cantidad de correos a mano, en vez de eso me decicí a automatizar la tarea usando Java y el hecho de que Gmail soporta POP / IMAP (Javamail cuenta con accesso a IMAP comp arte de su API). Una vez leido un poco abrí mi Eclipse y el resultado es el código que viene a continuación:

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
package com.kodegeek.blog.mail;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
 
import javax.mail.Session;
import javax.mail.Flags.Flag;
import javax.mail.internet.MimeMessage;
import javax.mail.Message;
 
import javax.mail.Folder;
import javax.mail.MessagingException;
import javax.mail.Store;
 
import java.io.FileInputStream;
 
/**
 * I wrote this program to erase ALL the email on my GMAIL account. I have over 40,000 email so manually doing so was not an option :)
 * Please check the following resources:
 * <ul>
 * <li> http://java.sun.com/products/javamail/javadocs/index.html</li>
 * <li> http://java.sun.com/developer/onlineTraining/JavaMail/contents.html</li>
 * <li> http://java.sun.com/products/javamail/javadocs/com/sun/mail/imap/package-summary.html</li>
 * <li> http://java.sun.com/products/javamail/downloads/index.html</li>
 * </ul>
 * Also define a properties file with the following (adjust it to your configuration):
 * # As defined by the Javadoc
 * <ul>
 * <li> mail.user=name.lastname@gmail.com</li>
 * <li> mail.password=zzz</li>
 * <li> mail.store.host=pop.imap.gmail.com</li>
 * <li> mail.store.protocol=imap</li>
 * <li> mail.imap.port=993</li>
 * <li> mail.imap.socketFactory.port=993</li>
 * <li> mail.imap.socketFactory.class=javax.net.ssl.SSLSocketFactory</li>
 * </ul>
 * License: GPL
 * http://kodegeek.com
 * @author Jose Vicente Nunez Zuleta
 * @version 12/28/2008
 */
public final class ImapBulkEraser {
 
	/**
	 * Command line processing
	 * @param args [0] Location of the properties configuration file, If not provided then will use system defaults (defined with -D)
	 * @throws Exception
	 * @since 0.1
	 */
	public static void main(String [] args) throws Exception {
 
		Logger logger = Logger.getLogger(ImapBulkEraser.class.getName());
 
		Properties props = System.getProperties();
		if (args.length == 1) {
			props.load(new FileInputStream(args[0]));
		}
		Session session = Session.getInstance(props, null);
		session.setDebug(Boolean.parseBoolean(props.getProperty("debug")));
		Store store = session.getStore(props.getProperty("mail.store.protocol"));
		logger.info(String.format("Connecting to: %s@%s:%s", props.getProperty("mail.user"), props.getProperty("mail.store.host"), props.getProperty("mail.imap.port")));
		store.connect(props.getProperty("mail.store.host"), props.getProperty("mail.user"), props.getProperty("mail.password"));
		Folder folder = store.getDefaultFolder();
		logger.info("Got default folder. Erasing emails from ALL the folders");
		Folder [] folders = folder.list();
		long messgCnt = 0;
		for(Folder currFolder: folders) {
 
			try {
 
				if ((currFolder.getType() & Folder.HOLDS_MESSAGES) == 0) {
					continue; // Skip this folder type
				}
				logger.info(String.format("Opening folder: %s, num messages; %d", currFolder.getFullName(), currFolder.getMessageCount()));
				currFolder.open(Folder.READ_WRITE);
				Message [] messages = currFolder.getMessages();
 
				// Mark all the messages for delete
				for (Message message: messages) {
					try {
						message.setFlag(Flag.DELETED, true);
						MimeMessage currMessage = (MimeMessage) message;
						logger.info(String.format("Set delete flag for mail subject: '%s', folder: '%s'", currMessage.getSubject(), currMessage.getFolder().getFullName()));
						messages = currFolder.expunge(); // Confirm delete for all the messages on the current folder
						messgCnt += messages.length;
					}  catch (MessagingException messgExp) {
						logger.log(Level.WARNING, "There was a problem erasing the message, ignoring", messgExp);
					}
				}
 
				logger.info(String.format("Messages erased on folder %s: %d", currFolder.getFullName(), messages.length));
				currFolder.close(true);
 
			} catch (MessagingException messgExp) {
				logger.log(Level.WARNING, "There was a problem, ignoring", messgExp);
			}
 
		}
		logger.info(String.format("Total number of erased messsages: %d", messgCnt));
		store.close();
	}
 
}

Correr el código es trivial, asegurese de tener el JAR de Javamail en el $CLASSPATH y haga algo como esto:


java com.kodegeek.blog.mail.ImapBulkEraser -Dmail.user=name.lastname@gmail.com -Dmail.password=XXXX -Dmail.store.host=imap.gmail.com -Dmail.store.protocol=imap -Dmail.store.folder=INBOX -Dmail.imap.port=993 -Dmail.imap.socketFactory.port=993 -Dmail.imap.socketFactory.class=javax.net.ssl.SSLSocketFactory

El programa no es perfecto, ya que de vez en cuando me conseguí con la siguiente error:


NFO: Set delete flag for mail subject: 'Deploying webapps in embedded environment', folder: 'tomcat-user'
Dec 28, 2008 5:40:18 PM com.kodegeek.blog.mail.ImapBulkEraser main
WARNING: There was a problem erasing the message, ignoring
javax.mail.MessagingException: Failed to load IMAP envelope
at com.sun.mail.imap.IMAPMessage.loadEnvelope(IMAPMessage.java:1069)
at com.sun.mail.imap.IMAPMessage.getSubject(IMAPMessage.java:256)
at com.kodegeek.blog.mail.ImapBulkEraser.main(ImapBulkEraser.java:83)
Dec 28, 2008 5:40:18 PM com.kodegeek.blog.mail.ImapBulkEraser main

Sin embargo esos no son todos los correos :)

Como siempre el código fuente de este programa es GPL y se puede bajar desde CVS.

java , , , ,

El Ingeniero de sistemas: ¿Un profesional con crisis de identidad?

Miércoles, 24 de diciembre de 2008

Todo comenzó cuando una amiga publicó una invitación en Facebook para el grupo “SALGAN DE LA IGNORANCIA! El ingeniero de sistemas NO es un técnico!!!

La invitación del grupo comienza así:

Este grupo fue creado para protestar pacíficamente por la misión y visión del Ingeniero de Sistemas, sin ánimo de ofender a los técnicos y tecnólogos en sistemas.

La idea es que el mundo sepa que los objetivos entre las tres ramas anteriormente nombradas son distintos y cada profesión desempeña diferentes funciones. Así como un Ingeniero no tiene el deber de saber como se arregla un electrodoméstico, un tecnólogo no tiene porque saber que es el algoritmo de Edsger Dijkstra.

Como todo grupo de Facebook este es un arroz con mango; Una de la primera cosa que hacen sus miembros es publicar opiniones acerca de, sorpresa, problemas relacionados con computación (y de las más baja dificultad técnica. No creo que hacer páginas WWW figure entre los problemas más complejos que se pueden resolver con una computadora). Pero sin irme aún más por la tangente creo que es necesario comentar acerca de lo que no es un Ingeniero de sistemas empezando por lo que no es.

  1. No es un ingeniero eléctrico: Sabe sobre sistemas de control, puede determinar si un sistema es observable y controlable, puede diseñar y programar un sistema SCADA, y definitivamente sabe que Grafcet no es una palabra bonita en Francés. Sin embargo no es un ingeniero eléctrico ya que no diseña circuitos, aunque seguro sabe como leer el diagrama de uno de ellos.
  2. No es un ingeniero de computación: Pero sabe de base de datos, TCP / IP, Inteligencia artificial y redes neuronales. Al menos programa en C++ y seguro en Java
  3. No es un sistemologo: Pero sabe sobre probabilidades, modelos discretos y continuos y seguro sabe resolver problemas usando técnicas de investigación de operaciones (se siente bien hablando del método simplex)

Los ingenieros de sistemas al final terminan especializándose en una de estas áreas. El hecho de que la carrera tenga tantas posibilidades le da una versatilidad increíble en el mercado ya que el Ingeniero de sistemas ha sido expuesto a todo, como un caballito de batalla. Sin embargo tiene la desventaja ante sus compañeros especializados de que es un “generalista” al cual le falta profundidad, al menos inicialmente.

¿Entonces porqué el desprecio por los computistas? Yo creo que es exagerado e inútil, especialmente en Venezuela. Una de las razones es que el mercado laboral es muy estrecho y que los sitios en donde el Ingeniero de sistemas puede dedicarse a control o sistemología interpretativa es más reducido si se le compara con computación; Esa flexibilidad de poder saltar de empleador a empleador (mejorando el sueldo anterior) es definitivamente un punto a favor para quienes se dedican a la computación como un todo.

¿Es un error dedicarse a computación, viniendo de control o investigación de operaciones? Para nada, de hecho una de las cosas que las universidades no enseñan es que muchas veces terminamos trabajando en áreas completamente distintas a las cuales nos graduamos. Una de las industrias en donde he visto mucho eso es en el área de finanzas; Yo trabajó con corredores de bolsa (algunos de los cuales hacen hasta 4 millones de dolares al año) los cuales vienen de lugares tan diversos como agentes encubiertos de la DEA, ingenieros quimicos, ingenieros mecanicos entre otros (y que decir de gochito que escribe este artículo el cual llegó a un banco de inversiones y trabaja hoy en día en un sistema que hace algoritmic trading :) )

El ingeniero de sistemas tiene la responsabilidad de profundizar sus conocimientos una vez graduado, buscando especializarse en alguna de sus ramas. Su gran rango de conocimientos en diversas disciplinas le permiten atacar problemas desde diferentes angulos, dándole una ventaja sobre computistas puros. Pero inicialmente la ventaja la tienen los ingenieros eléctricos, computistas puros, etc.

Así que si usted es un ingeniero de sistemas y alguien lo confunde con un ingeniero de computación, en vez de sentirse ofendido más bien estudie bien que es lo que le están ofreciendo. Lo que le espera detrás de esa puerta puede cambiarle la vida.

Buscar en otros sitios:

Blogalaxia:, , ,
Technorati:, , ,
To2blogs:, , ,
Del.icio.us:, , ,

kodegeek , ,

JAVAFX es lanzado hoy

Jueves, 4 de diciembre de 2008

Después de mucha espera hoy lanzan JAVAFX. Yo ya les había hablado sobre JAVA FX en mis visita al JavaOne de este año y hoy finalmente sacan su versión 1.0 para varios sistemas operativos, entre ellos Linux y OS X.

¿Son buenas noticias para SUN? Yo en particular creo que sí, aunque vamos a ver como se ve la adopción de le herramienta. En las últimas horas de trading antes de escribir este articulo el precio de las acciones de SUN subio casi un dolar, quizas un indicador de que el mercado cree que esta es una buena noticia (el precio hoy antes de que abra el mercado a las 9:30 AM son $3.81)

Por los momentos no queda otra sino esperar para bajarse el kit de desarollo y ponerse a echar código. Aunque si quiere especular sobre el futuro de Java, lo invito a ver el indice de TIOBE (Java tiene %20, C# %10 y Ruby está por debajo de Python con % 2.87 y % 5.1 respectivamente.

Buscar en otros sitios:

Blogalaxia:, , , ,
Technorati:, , , ,
To2blogs:, , , ,
Del.icio.us:, , , ,

java, kodegeek, opensource , , , ,

De como Facebook mató a mi blog (y como estoy feliz por eso)

Lunes, 1 de diciembre de 2008

Vamos a ver: Levanten la mano ¿quienes han escrito cosas que no tienen nada que ver con el tema central del su blog, pero en cambió escribieron algo en Facebook o Twitter?

Facebook, Flickr o el mismo Twitter han convertido a los blogs en medios obsoletos para mantener informados a los amigos, familia y otros acerca de nuestras andanzas. Para redes de trabajo nada mejor que Linked In, con sus recomendaciones.

Si, el blog tiene más flexibilidad pero ¿puede garantizar que sus amigos verán los cambios de inmediato?

Yo pienso que esto es bueno. Los blogs se han convertido en un todero, donde los “profesionales” (entiendase compañias que pueden pagar a más de un escritor para que hable sobre un tema) smplemente acorralan y aplastan a quienes escriben por placer propio y cuando el tiempo se los permite (tienen un trabajo que paga las cuentas).

¿Y que hay del puro ocio? Simplemente estas aplicaciones orientadas a las llamadas redes sociales son mucho más flexibles y fáciles de usar. Yo lo quiero ver a usted repitiendo las mismas morisquetas usando WordPress o Blogger :)

Así que el blog se hace algo más personalizado. Un sitio en donde el contenido debe ser profundo y no sólo “pings”. Yo ya me rendí a la nueva tendencia hace rato (como los Borg de Star Trek, he sido asimilado), y pienso dejar todo lo que no es tecnología fuera de este blog.

En otro orden de ideas, Diciembre es un mes importante para el Blog. Piensen en KodeGeek 2.0. Viene una buena limpieza y cambio de imagen, la idea es hacer este blog un sitio mucho más útil para quienes lo leen.

¿Y usted, ya actualizó su estado en Facebook? Yo ya exporté el RSS de mi blog :D

Buscar en otros sitios:

Blogalaxia:, , ,
Technorati:, , ,
To2blogs:, , ,
Del.icio.us:, , ,

kodegeek , , ,