<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1381165230718116833</id><updated>2024-12-19T00:32:01.207-03:00</updated><category term="windows"/><category term="genexus"/><category term="linux"/><category term="CODE128"/><category term="CODE39"/><category term="EAN13"/><category term="PDF417"/><category term="QR"/><category term="automation"/><category term="automatización"/><category term="barcode"/><category term="bash"/><category term="codigo de barra"/><category term="lazarus"/><category term="nodejs"/><category term="service"/><category term="COM"/><category term="base64"/><category term="cron"/><category term="cygwin"/><category term="download"/><category term="friendly name"/><category term="mime"/><category term="sed"/><category term="sort"/><category term="soundex"/><category term="tumblr"/><category term="uniq"/><category term="wget"/><title type='text'>Pato Díaz</title><subtitle type='html'>Blog sobre programación y tecnología informática</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://patotech.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://patotech.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Patricio Diaz</name><uri>http://www.blogger.com/profile/15817672756742645565</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>12</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1381165230718116833.post-3501368297407460747</id><published>2016-05-03T08:15:00.003-04:00</published><updated>2016-05-10T09:01:52.051-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="barcode"/><category scheme="http://www.blogger.com/atom/ns#" term="CODE128"/><category scheme="http://www.blogger.com/atom/ns#" term="CODE39"/><category scheme="http://www.blogger.com/atom/ns#" term="codigo de barra"/><category scheme="http://www.blogger.com/atom/ns#" term="EAN13"/><category scheme="http://www.blogger.com/atom/ns#" term="nodejs"/><category scheme="http://www.blogger.com/atom/ns#" term="PDF417"/><category scheme="http://www.blogger.com/atom/ns#" term="QR"/><category scheme="http://www.blogger.com/atom/ns#" term="service"/><title type='text'>Barcode and QR code as service</title><content type='html'>&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;en&quot;&gt;&lt;span title=&quot;En varios de mis desarrollos, en distintos leguajes, tuve la necesidad de generar algún tipo de codigo de barra y últimamente también necesité generar códigos QR.&quot;&gt;In
 several of my projects, in different leguajes, I had the need to 
generate some kind of bar code and lately also need to generate QR 
codes. &lt;/span&gt;&lt;span title=&quot;El problema siempre fue como conseguir integrar esa funcionalidad al desarrollo, ya sea como biblioteca nativa o consumiendo algún servicio externo.

&quot;&gt;The problem was always how to get that functionality integrated 
development, either as native library or using some external service.&lt;/span&gt;&lt;span title=&quot;En ambos casos he encontrado que las desventajas son varias y el riesgo de usarlas era importante.&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;en&quot;&gt;&lt;span title=&quot;En ambos casos he encontrado que las desventajas son varias y el riesgo de usarlas era importante.&quot;&gt;&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;en&quot;&gt;&lt;span title=&quot;En ambos casos he encontrado que las desventajas son varias y el riesgo de usarlas era importante.&quot;&gt;&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;en&quot;&gt;&lt;span title=&quot;En ambos casos he encontrado que las desventajas son varias y el riesgo de usarlas era importante.&quot;&gt;In both cases I have found that the disadvantages are many and the risk of use them is important. &lt;/span&gt;&lt;span title=&quot;En el caso de las bibliotecas nativas, no siempre existe una para el lenguaje que estamos usando, ya sea por que no exista, por la licencia, costo, etc.

&quot;&gt;For native libraries, not always there is one for the language we are using, because either does not exist, license cost, etc.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span title=&quot;En el caso de las bibliotecas nativas es que no siempre se encuentra una para el lenguaje que estamos usando, ya sea por que no exista, por la licencia, costo, etc.

&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span title=&quot;En el caso de las bibliotecas nativas es que no siempre se encuentra una para el lenguaje que estamos usando, ya sea por que no exista, por la licencia, costo, etc.

&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span title=&quot;En el caso de los servicios externos , aunque es muy cómodo simplemente llamar al servicio y recuperar una imágen, estos pueden dejar de existir, volverse muy lentos o simplemente el acceso a internet no es una opción.

&quot;&gt;In the case of external services, although it is very comfortable just
 call the service and retrieve an image, they can cease to exist, become very slow, &lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;en&quot;&gt;&lt;span title=&quot;En el caso de los servicios externos , aunque es muy cómodo simplemente llamar al servicio y recuperar una imágen, estos pueden dejar de existir, volverse muy lentos o simplemente el acceso a internet no es una opción.

&quot;&gt;&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;en&quot;&gt;&lt;span title=&quot;En el caso de los servicios externos , aunque es muy cómodo simplemente llamar al servicio y recuperar una imágen, estos pueden dejar de existir, volverse muy lentos o simplemente el acceso a internet no es una opción.

&quot;&gt;or just &lt;/span&gt;&lt;/span&gt; internet access is not an option.&lt;/span&gt;&lt;span title=&quot;Por este motivo me propuse crear un servidor sencillo que me permita exportar como servicios la generación de ciertos códigos de barra y QR (los que he necesitado) de forma local.

&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;en&quot;&gt;&lt;span title=&quot;Por este motivo me propuse crear un servidor sencillo que me permita exportar como servicios la generación de ciertos códigos de barra y QR (los que he necesitado) de forma local.

&quot;&gt;&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;en&quot;&gt;&lt;span title=&quot;Por este motivo me propuse crear un servidor sencillo que permita la generación de ciertos códigos de barra y QR (los que he necesitado hasta ahora) de forma local.

&quot;&gt;For those reasons I decided to create a simple server that allows the 
generation of certain barcodes and QR (I&#39;ve needed so far) locally. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;en&quot;&gt;&lt;span title=&quot;La dirección del proyecto es esta: https://github.com/padiazg/barcode-as-a-service

&quot;&gt;&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;en&quot;&gt;&lt;span title=&quot;El proyecto esta publicado en GitHub en esta dirección: https://github.com/padiazg/barcode-as-a-service

&quot;&gt;The project is posted on GitHub at: &lt;a href=&quot;https://github.com/padiazg/barcode-as-a-service&quot;&gt;https://github.com/padiazg/barcode-as-a-service&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;en&quot;&gt;&lt;span title=&quot;La dirección del proyecto es esta: https://github.com/padiazg/barcode-as-a-service

&quot;&gt;&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;en&quot;&gt;&lt;span title=&quot;El proyecto esta publicado en GitHub en esta dirección: https://github.com/padiazg/barcode-as-a-service

&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span title=&quot;Actualmente puede generar codigos EAN13, CODE39, CODE129, PDF417 y QR.&quot;&gt;Currently it can generate codes for EAN13, CODE39, CODE129, PDF417 and QR. &lt;/span&gt;&lt;span title=&quot;La lista puede extenderse a los demás tipos de código que soporta el paquete rescode en el que se basa este proyecto.

&quot;&gt;The list can be extended to other types that supports the Rescode package in which this project is based.&lt;/span&gt;&lt;span title=&quot;Para ponerlo a funcionar debemos seguir estos pasos:

    &quot;&gt;To put it to work we must follow these steps:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;en&quot;&gt;&lt;span title=&quot;Para ponerlo a funcionar debemos seguir estos pasos:

    &quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;en&quot;&gt;&lt;span title=&quot;Para ponerlo a funcionar debemos seguir estos pasos:

    &quot;&gt;&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;en&quot;&gt;&lt;span title=&quot;Tener instalado Node.js (se recomienda la versión mas actual)
    &quot;&gt;&lt;a href=&quot;http://node.js/&quot;&gt;Node.js&lt;/a&gt; must be &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span title=&quot;Tener instalado Node.js (se recomienda la versión mas actual)
    &quot;&gt;installed&amp;nbsp; (the last version is recommended)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;en&quot;&gt;&lt;span title=&quot;Tener instalado Node.js (se recomienda la versión mas actual)
    &quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span title=&quot;Descargar el proyecto en alguna carpeta
    &quot;&gt;Download the project in any folder&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;en&quot;&gt;&lt;span title=&quot;Descargar el proyecto en alguna carpeta
    &quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span title=&quot;Abrir una consola e ir a la carpeta donde acabamos de descargar el proyecto
    &quot;&gt;Open a console and go to the folder where you just downloaded the project&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;en&quot;&gt;&lt;span title=&quot;Abrir una consola e ir a la carpeta donde acabamos de descargar el proyecto
    &quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span title=&quot;Ejecutar npm install para descargar los paquetes requeridos
    &quot;&gt;Run &lt;b&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&lt;a href=&quot;https://www.npmjs.com/&quot;&gt;npm&lt;/a&gt; install&lt;/span&gt;&lt;/b&gt; to download the required packages&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;en&quot;&gt;&lt;span title=&quot;Ejecutar npm install para descargar los paquetes requeridos
    &quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span title=&quot;Ejecutar node barcode-service

&quot;&gt;Run &lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;en&quot;&gt;&lt;span title=&quot;Ejecutar node barcode-service

&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;en&quot;&gt;&lt;span title=&quot;Ejecutar node barcode-service

&quot;&gt;node &lt;/span&gt;&lt;/span&gt;barcode-service&lt;/span&gt;&lt;/b&gt; &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;en&quot;&gt;&lt;span title=&quot;Ejecutar node barcode-service

&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span title=&quot;Una vez corriendo el servicio, podemos apuntar un navegador al puerto 3000 de la máquina para tener un breve ejemplo del uso del servicio.

&quot;&gt;Once the service is&amp;nbsp; running, we can point a browser at port 3000 of the host for a brief example of using the service.&lt;/span&gt;&lt;span title=&quot;Se agradecerá los comentarios y algún feedback.&quot;&gt;Comments and any feedback would be appreciated.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
&lt;b&gt;Actualización:&lt;/b&gt;&lt;i&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/i&gt;&lt;/h3&gt;
V1.1 (&lt;i&gt;09/mayo/2016&lt;/i&gt;)&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Solved a problem with fonts, related to the scale of the output.&lt;/li&gt;
&lt;li&gt;Added paramater &quot;scale&quot;, to specify a desired scale for the gnerated image.&lt;/li&gt;
&lt;li&gt;Added parameter &quot;fmt&quot;, to choise the imege format. &lt;/li&gt;
&lt;li&gt;Implemented generation for &quot;DataMatrix&quot;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;The internal procedure is simplified.&lt;/li&gt;
&lt;/ul&gt;
In order to generate JPG output &lt;a href=&quot;http://www.graphicsmagick.org/&quot;&gt;GraphicsMagick&lt;/a&gt; is needed, it&#39;s just download and install the right version for your system, bejore run the server.&lt;br /&gt;
&lt;br /&gt;
Don&#39;t forget to update the requirements whit &lt;i&gt;&lt;b&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;npm install&lt;/span&gt;&lt;/b&gt;&lt;/i&gt; after upgrading to the new version.&lt;br /&gt;
&lt;span class=&quot;&quot; id=&quot;result_box&quot; lang=&quot;en&quot;&gt;&lt;span title=&quot;Se agradecerá los comentarios y algún feedback.&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://patotech.blogspot.com/feeds/3501368297407460747/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1381165230718116833/3501368297407460747' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default/3501368297407460747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default/3501368297407460747'/><link rel='alternate' type='text/html' href='http://patotech.blogspot.com/2016/05/barcode-and-qr-code-as-service.html' title='Barcode and QR code as service'/><author><name>Patricio Diaz</name><uri>http://www.blogger.com/profile/15817672756742645565</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1381165230718116833.post-1922141405795864361</id><published>2016-04-18T13:11:00.003-04:00</published><updated>2016-05-10T09:02:28.372-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="barcode"/><category scheme="http://www.blogger.com/atom/ns#" term="CODE128"/><category scheme="http://www.blogger.com/atom/ns#" term="CODE39"/><category scheme="http://www.blogger.com/atom/ns#" term="codigo de barra"/><category scheme="http://www.blogger.com/atom/ns#" term="EAN13"/><category scheme="http://www.blogger.com/atom/ns#" term="nodejs"/><category scheme="http://www.blogger.com/atom/ns#" term="PDF417"/><category scheme="http://www.blogger.com/atom/ns#" term="QR"/><category scheme="http://www.blogger.com/atom/ns#" term="service"/><title type='text'>Códigos de barra y QR como servicio </title><content type='html'>En varios de mis desarrollos, en distintos leguajes, tuve la necesidad de generar algún tipo de codigo de barra y últimamente también necesité generar códigos QR. El problema siempre fue como conseguir integrar esa funcionalidad al desarrollo, ya sea como biblioteca nativa o consumiendo algún servicio externo.&lt;br /&gt;
&lt;br /&gt;
En ambos casos he encontrado que las desventajas son varias y el riesgo usarlas era importante. En el caso de las bibliotecas nativas es que no siempre se encuentra una para el lenguaje que estamos usando, ya sea por que no exista, por la licencia, costo, etc.&lt;br /&gt;
&lt;br /&gt;
En el caso de los servicios externos , aunque es muy cómodo simplemente llamar al servicio y recuperar una imágen, estos pueden dejar de existir, volverse muy lentos o simplemente el acceso a internet no es una opción.&lt;br /&gt;
&lt;br /&gt;
Por este motivo me propuse crear un servidor sencillo que me permita exportar como servicios la generación de ciertos códigos de barra y QR (los que he necesitado) de forma local.&lt;br /&gt;
&lt;br /&gt;
La dirección del proyecto es esta:&amp;nbsp; &lt;a href=&quot;https://github.com/padiazg/barcode-as-a-service&quot;&gt;https://github.com/padiazg/barcode-as-a-service&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Actualmente puede generar codigos EAN13, CODE39, CODE129, PDF417 y QR. La lista puede extenderse a los demás tipos de código que soporta el paquete &lt;a href=&quot;https://www.npmjs.com/package/rescode&quot;&gt;rescode&lt;/a&gt; en el que se basa este proyecto.&lt;br /&gt;
&lt;br /&gt;
Para ponerlo a funcionar debemos seguir estos pasos:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Tener instalado &lt;a href=&quot;http://node.js/&quot;&gt;Node.js&lt;/a&gt; (se recomienda la versión mas actual)&lt;/li&gt;
&lt;li&gt;Descargar el proyecto en alguna carpeta&lt;/li&gt;
&lt;li&gt;Abrir una consola e ir a la carpeta donde acabamos de descargar el proyecto&lt;/li&gt;
&lt;li&gt;Ejecutar &lt;b&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&lt;a href=&quot;https://www.npmjs.com/&quot;&gt;npm&lt;/a&gt; install&lt;/span&gt;&lt;/b&gt; para descargar los paquetes requeridos&lt;/li&gt;
&lt;li&gt;Ejecutar &lt;b&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;node barcode-service&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
Una vez corriendo el servicio, podemos apuntar un navegador al puerto 3000 de la máquina para tener un breve ejemplo del uso del servicio. &lt;br /&gt;
&lt;br /&gt;
Se agradecerá los comentarios y algún feedback.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
&lt;b&gt;Actualización:&lt;/b&gt;&lt;i&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/i&gt;&lt;/h3&gt;
V1.1 (&lt;i&gt;09/mayo/2016&lt;/i&gt;)&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Se corrige un problema con las letras, relacionado a la escala del código generado.&lt;/li&gt;
&lt;li&gt;Se agrega el parámetro &quot;scale&quot;, con la que se puede especificar la escala de la imágen generada.&lt;/li&gt;
&lt;li&gt;Se agrega el parámetro &quot;fmt&quot; para seleccionar el formato de la imágen generada. &lt;/li&gt;
&lt;li&gt;Se implementa la generación de códigos &quot;DataMatrix&quot;&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Se&amp;nbsp; simplifica el procedimiento interno para la generación de los códigos.&lt;/li&gt;
&lt;/ul&gt;
Para la generación de salida en formato JPG se debe tener instalado &lt;a href=&quot;http://www.graphicsmagick.org/&quot;&gt;GraphicsMagick&lt;/a&gt;, es simplemente bajar e instalar la versión apropiada para su sistema, antes de ejecutar el servidor.&lt;br /&gt;
&lt;br /&gt;
No debemos olvidar de actualizar los requerimientos de paquetes con &lt;b&gt;&lt;i&gt;&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;npm install&lt;/span&gt;&lt;/i&gt;&lt;/b&gt; después de actualizar a la nueva versión.&lt;br /&gt;
&lt;ul&gt;
&lt;/ul&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://patotech.blogspot.com/feeds/1922141405795864361/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1381165230718116833/1922141405795864361' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default/1922141405795864361'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default/1922141405795864361'/><link rel='alternate' type='text/html' href='http://patotech.blogspot.com/2016/04/servicio-local-para-generar-codigos-de.html' title='Códigos de barra y QR como servicio '/><author><name>Patricio Diaz</name><uri>http://www.blogger.com/profile/15817672756742645565</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1381165230718116833.post-8858039141811569624</id><published>2016-04-13T17:19:00.001-04:00</published><updated>2016-04-14T09:42:28.034-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="genexus"/><category scheme="http://www.blogger.com/atom/ns#" term="soundex"/><title type='text'>Implementación algoritmo Soundex Español en Genexus</title><content type='html'>El algoritmo &lt;a href=&quot;https://es.wikipedia.org/wiki/Soundex&quot; target=&quot;_blank&quot;&gt;soundex&lt;/a&gt; es un algoritmo fonético, diseñado para indexar nombres por su pronunciación en Inglés. Es por esto que no es preciso cuando lo aplicamos a nombres o palabras en español, podría decirse incluso que no es usable en nuestro idioma.&lt;br /&gt;
&lt;br /&gt;
Investigando un poco hace algunos años había encontrado esta entrada &lt;a href=&quot;https://wiki.postgresql.org/wiki/SoundexESP&quot;&gt;https://wiki.postgresql.org/wiki/SoundexESP&lt;/a&gt;, en la que me basé para crear sus equivalentes en distintos lenguages (VBA, T-SQL para Oracle). Por supuesto cuando se dió la necesidad le tocó a Genexus.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Implementación&lt;/h3&gt;
La implementación la hice en un procedimiento llamado &lt;b&gt;soundex&lt;/b&gt;, pero ustedes pueden llamarlo como mas les convenga&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;soundex:&lt;/b&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:gx&quot;&gt;/*
 Implementación del algoritmo Soundex para el idioma español
 
 variables  tipo
 ----------------------- -----------
 caracter  C(1)
 caracteres_buscar C(20)
 caracteres_reemplazar C(20)
 i   N(2)
 primera_letra  C(1)
 reemplazo  C(1)
 resto   C(20)
 soundex   C(20)
 texto   C(32)
 tmp   C(32)

        parámetros
 -----------------------
 in:&amp;amp;texto
 out:&amp;amp;soundex

*/

&amp;amp;soundex.SetEmpty()
&amp;amp;tmp = &amp;amp;texto.Trim().ToUpper()

// Si no hay texto a procesar retornamos un texto vacío
if &amp;amp;tmp.IsEmpty()
&amp;nbsp;&amp;nbsp;&amp;nbsp; return
endif

// realizamos un preprocesado del texto
do &#39;limpieza&#39;

// aplicamos el algoritmo
do &#39;soundex&#39;

Sub &#39;limpieza&#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /*&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1) limpieza&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */
&amp;nbsp;&amp;nbsp;&amp;nbsp; // eliminamos la H inicial (incluso si hay mas de una)
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;tmp = &amp;amp;tmp.ReplaceRegEx(&#39;^(H+)(.*)&#39;, &#39;$2&#39;)

&amp;nbsp;&amp;nbsp;&amp;nbsp; // retornar vacío si no nos queda texto para analizar
&amp;nbsp;&amp;nbsp;&amp;nbsp; if &amp;amp;tmp.IsEmpty()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return
&amp;nbsp;&amp;nbsp;&amp;nbsp; endif

&amp;nbsp;&amp;nbsp;&amp;nbsp; // eliminamos los acentos y la Ñ
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;caracteres_buscar&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = &#39;ÑÁÉÍÓÚÀÈÌÒÙÜ&#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;caracteres_reemplazar = &#39;NAEIOUAEIOUU&#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp; for &amp;amp;i=1 to &amp;amp;caracteres_buscar.Length()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;caracter = &amp;amp;caracteres_buscar.Substring(&amp;amp;i,1)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if &amp;amp;caracteres_buscar.IndexOf(&amp;amp;caracter)&amp;gt;0
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;tmp = &amp;amp;tmp.Replace(&amp;amp;caracter, &amp;amp;caracteres_reemplazar.Substring(&amp;amp;i, 1))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; endif // &amp;amp;buscar.IndexOf(&amp;amp;caracter)&amp;gt;0
&amp;nbsp;&amp;nbsp;&amp;nbsp; endfor // &amp;amp;i=1 to &amp;amp;buscar.Length() ...

&amp;nbsp;&amp;nbsp;&amp;nbsp; // eliminamos caracteres no alfabéticos (números, signos, símbolos, etc)
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;tmp = &amp;amp;tmp.ReplaceRegEx(&#39;[^A-Z]&#39;, &#39;&#39;)

&amp;nbsp;&amp;nbsp;&amp;nbsp; /*&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2) ajustar primera letra&amp;nbsp;&amp;nbsp;&amp;nbsp; */&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; // fenómenos o casos especiales: GE y GI se convierten en JE y JI, CA en KA
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;primera_letra = &amp;amp;tmp.Substring(1,1)
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;resto = &amp;amp;tmp.Substring(2,&amp;amp;tmp.Length()-1) 

&amp;nbsp;&amp;nbsp;&amp;nbsp; do case
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case &amp;amp;primera_letra = &#39;V&#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;reemplazo = &#39;B&#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // VACA -&amp;gt; BACA, VALOR -&amp;gt; BALOR

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case &amp;amp;primera_letra = &#39;Z&#39; or &amp;amp;primera_letra = &#39;X&#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;reemplazo = &#39;S&#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // ZAPATO -&amp;gt; SAPATO, XILÓFONO -&amp;gt; SILÓFONO

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case &amp;amp;primera_letra = &#39;G&#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; and (&amp;amp;tmp.Substring(2,1)=&#39;E&#39; or &amp;amp;tmp.Substring(2,1)=&#39;I&#39;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;reemplazo = &#39;J&#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // GIMNASIO -&amp;gt; JIMNASIO, GERANIO -&amp;gt; JERANIO

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; case &amp;amp;primera_letra = &#39;C&#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; and &amp;amp;tmp.Substring(2,1)&amp;lt;&amp;gt;&#39;H&#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; and &amp;amp;tmp.Substring(2,1)&amp;lt;&amp;gt;&#39;E&#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; and &amp;amp;tmp.Substring(2,1)&amp;lt;&amp;gt;&#39;I&#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;reemplazo = &#39;K&#39;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // CASA -&amp;gt; KASA, COLOR -&amp;gt; KOLOR, CULPA -&amp;gt; KULPA

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; otherwise
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;reemplazo = &amp;amp;primera_letra

&amp;nbsp;&amp;nbsp;&amp;nbsp; endcase

&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;tmp = &amp;amp;reemplazo + &amp;amp;resto

&amp;nbsp;&amp;nbsp;&amp;nbsp; /*&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3) corregir letras compuestas, volverlas una sola&amp;nbsp;&amp;nbsp;&amp;nbsp; */
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;tmp = &amp;amp;tmp.ReplaceRegEx(&#39;CH&#39;, &#39;V&#39;)
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;tmp = &amp;amp;tmp.ReplaceRegEx(&#39;QU&#39;, &#39;K&#39;)
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;tmp = &amp;amp;tmp.ReplaceRegEx(&#39;LL&#39;, &#39;J&#39;)
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;tmp = &amp;amp;tmp.ReplaceRegEx(&#39;CE&#39;, &#39;S&#39;)
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;tmp = &amp;amp;tmp.ReplaceRegEx(&#39;CI&#39;, &#39;S&#39;)
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;tmp = &amp;amp;tmp.ReplaceRegEx(&#39;YA&#39;, &#39;J&#39;)
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;tmp = &amp;amp;tmp.ReplaceRegEx(&#39;YE&#39;, &#39;J&#39;)
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;tmp = &amp;amp;tmp.ReplaceRegEx(&#39;YI&#39;, &#39;J&#39;)
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;tmp = &amp;amp;tmp.ReplaceRegEx(&#39;YO&#39;, &#39;J&#39;)
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;tmp = &amp;amp;tmp.ReplaceRegEx(&#39;YU&#39;, &#39;J&#39;)
&amp;nbsp;&amp;nbsp; &amp;nbsp;//&amp;amp;tmp = &amp;amp;tmp.ReplaceRegEx(&#39;GE&#39;, &#39;J&#39;)
&amp;nbsp;&amp;nbsp; &amp;nbsp;//&amp;amp;tmp = &amp;amp;tmp.ReplaceRegEx(&#39;GI&#39;, &#39;J&#39;)
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;tmp = &amp;amp;tmp.ReplaceRegEx(&#39;NY&#39;, &#39;N&#39;)
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;tmp = &amp;amp;tmp.ReplaceRegEx(&#39;NH&#39;, &#39;N&#39;) // anho, banho, tamanho, inhalador
EndSub // &#39;limpieza&#39; ...

Sub &#39;soundex&#39;

&amp;nbsp;&amp;nbsp;&amp;nbsp; /* 4) obtener primera letra&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;primera_letra = &amp;amp;tmp.Substring(1, 1)
&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; /* 5) obtener el resto del texto&amp;nbsp;&amp;nbsp;&amp;nbsp; *
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;resto = &amp;amp;tmp.Substring(2, &amp;amp;tmp.Length()-1)
&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; /* 6) en el resto, eliminar vocales y consonantes fonéticas&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; */
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;resto = &amp;amp;resto.ReplaceRegEx(&#39;[AEIOUHWY]&#39;, &#39;&#39;)

&amp;nbsp;&amp;nbsp;&amp;nbsp; /* 7) convertir letras fonéticamente equivalentes a números. esto hace que B sea equivalente a V, C con S y Z, etc.&amp;nbsp;&amp;nbsp;&amp;nbsp; */
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;resto = &amp;amp;resto.ReplaceRegEx(&#39;[BPFV]&#39;,&amp;nbsp;&amp;nbsp; &#39;1&#39;)
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;resto = &amp;amp;resto.ReplaceRegEx(&#39;[CGKSXZ]&#39;, &#39;2&#39;)
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;resto = &amp;amp;resto.ReplaceRegEx(&#39;[DT]&#39;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;3&#39;)
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;resto = &amp;amp;resto.ReplaceRegEx(&#39;[L]&#39;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;4&#39;)
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;resto = &amp;amp;resto.ReplaceRegEx(&#39;[MN]&#39;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;5&#39;)
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;resto = &amp;amp;resto.ReplaceRegEx(&#39;[R]&#39;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;6&#39;)
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;resto = &amp;amp;resto.ReplaceRegEx(&#39;[QJ]&#39;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &#39;7&#39;)

&amp;nbsp;&amp;nbsp;&amp;nbsp; // eliminamos números iguales adyacentes
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;resto = &amp;amp;resto.ReplaceRegEx(&#39;(\d)\1+&#39;, &#39;$1&#39;) 
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;soundex = &amp;amp;primera_letra + &amp;amp;resto.Trim()
&amp;nbsp;&amp;nbsp;&amp;nbsp; if &amp;amp;soundex.Length() &amp;lt; 4
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;soundex = padr(&amp;amp;soundex, 4, &#39;0&#39;)
&amp;nbsp;&amp;nbsp;&amp;nbsp; else
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp;soundex = &amp;amp;soundex.Substring(1,4)
&amp;nbsp;&amp;nbsp;&amp;nbsp; endif
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
EndSub // &#39;soundex&#39; ...
&lt;/pre&gt;
&lt;br /&gt;
&lt;h3&gt;
Prueba &lt;/h3&gt;
A continuación podemos hacer unas pruebas para ver el algoritmo en funcionamiento, creamos otro procedimiento llamado &lt;b&gt;prueba_soundex&lt;/b&gt;:&lt;br /&gt;
&lt;br /&gt;
prueba_soundex:&lt;br /&gt;
&lt;pre class=&quot;brush:gx&quot;&gt;/*
 Colocar los siguientes valores en las propiedades del procedimiento
 -------------------------------------------------------------------
 Main program: true
 Call protocol: Command Line
*/

msg(&#39;hola =&amp;gt; &#39; + soundex.Udp(&#39;hola&#39;), status)
msg(&#39;ola =&amp;gt; &#39; + soundex.Udp(&#39;ola&#39;), status)

msg(&#39;zapato =&amp;gt; &#39; + soundex.Udp(&#39;zapato&#39;), status)
msg(&#39;sapato =&amp;gt; &#39; + soundex.Udp(&#39;sapato&#39;), status)

msg(&#39;Jimenez =&amp;gt; &#39; + soundex.Udp(&#39;Jimenez&#39;), status)
msg(&#39;Jiménez =&amp;gt; &#39; + soundex.Udp(&#39;Jiménez&#39;), status)
msg(&#39;Jimenes =&amp;gt; &#39; + soundex.Udp(&#39;Jimenes&#39;), status)
msg(&#39;Jiménes =&amp;gt; &#39; + soundex.Udp(&#39;Jiménes&#39;), status)
msg(&#39;Gimenez =&amp;gt; &#39; + soundex.Udp(&#39;Gimenez&#39;), status)
msg(&#39;Giménez =&amp;gt; &#39; + soundex.Udp(&#39;Giménez&#39;), status)
msg(&#39;Gimenes =&amp;gt; &#39; + soundex.Udp(&#39;Gimenes&#39;), status)
msg(&#39;Giménes =&amp;gt; &#39; + soundex.Udp(&#39;Giménes&#39;), status)

msg(&#39;Díaz =&amp;gt; &#39; + soundex.Udp(&#39;Díaz&#39;), status)
msg(&#39;días =&amp;gt; &#39; + soundex.Udp(&#39;días&#39;), status)
msg(&#39;dias =&amp;gt; &#39; + soundex.Udp(&#39;dias&#39;), status)

msg(&#39;mejico =&amp;gt; &#39; + soundex.Udp(&#39;mejico&#39;), status)
msg(&#39;mexico =&amp;gt; &#39; + soundex.Udp(&#39;mexico&#39;), status)
&lt;/pre&gt;
&lt;br /&gt;
Luego ejecutamos prueba_soundex y deberíamos de obtener la siguiente salida:
&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;&quot;C:\Program Files\Java\jdk1.8.0_25\bin\java.exe&quot;  atest_soundex
hola =&amp;gt; O400
ola =&amp;gt; O400
zapato =&amp;gt; S130
sapato =&amp;gt; S130
Jimenez =&amp;gt; J520
Jiménez =&amp;gt; J520
Jimenes =&amp;gt; J520
Jiménes =&amp;gt; J520
Gimenez =&amp;gt; J520
Giménez =&amp;gt; J520
Gimenes =&amp;gt; J520
Giménes =&amp;gt; J520
Díaz =&amp;gt; D200
días =&amp;gt; D200
dias =&amp;gt; D200
mejico =&amp;gt; M720
mexico =&amp;gt; M200
Execution Success
&lt;/pre&gt;
Como pueden ver el algoritmo es bastante preciso con palabras similares, aunque sigo trabajando en generalizar el caso de ji y xi.

&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
&lt;b&gt;Pensamientos finales&lt;/b&gt;&amp;nbsp;&lt;/h3&gt;
Los escenarios donde aplicar eso de forma práctica pueden variar mucho, de hecho no se si podría usarse efectivamente con nombres completos.&lt;br /&gt;
&lt;br /&gt;
En mi caso lo estuve utilizando para crear un diccionario de una tabla de nombres de calles. Primero se procesan las calles registradas (normalizadas), se separan en sus palabras componentes y se registran individualmente en un diccionario con su correspondiente código soundex. Se guarda la calle y su relación con sus palabras componentes.&lt;br /&gt;
&lt;br /&gt;
Al introducir un nombre de calle para buscar, esta también se separa en sus palabras componentes, se calcula el código soundex para cada una y son estos códigos los que se buscan en el diccionario, por supuesto que el proceso es mas complejo y tiene mas validaciones, pero básicamente es así como funciona.&lt;br /&gt;
&lt;br /&gt;
El código de ambos procedimientos pueden encontrarlos en &lt;a href=&quot;https://github.com/padiazg/soundex-genexus&quot;&gt;https://github.com/padiazg/soundex-genexus&lt;/a&gt;&lt;br /&gt;
&amp;nbsp; </content><link rel='replies' type='application/atom+xml' href='http://patotech.blogspot.com/feeds/8858039141811569624/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1381165230718116833/8858039141811569624' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default/8858039141811569624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default/8858039141811569624'/><link rel='alternate' type='text/html' href='http://patotech.blogspot.com/2016/04/implementacion-algoritmo-soundex-para.html' title='Implementación algoritmo Soundex Español en Genexus'/><author><name>Patricio Diaz</name><uri>http://www.blogger.com/profile/15817672756742645565</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1381165230718116833.post-3590497611799753645</id><published>2012-05-02T17:30:00.002-04:00</published><updated>2012-05-03T10:12:29.998-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="automation"/><category scheme="http://www.blogger.com/atom/ns#" term="bash"/><category scheme="http://www.blogger.com/atom/ns#" term="cygwin"/><category scheme="http://www.blogger.com/atom/ns#" term="download"/><category scheme="http://www.blogger.com/atom/ns#" term="sed"/><category scheme="http://www.blogger.com/atom/ns#" term="sort"/><category scheme="http://www.blogger.com/atom/ns#" term="tumblr"/><category scheme="http://www.blogger.com/atom/ns#" term="uniq"/><category scheme="http://www.blogger.com/atom/ns#" term="wget"/><title type='text'>Descargar todas las imágenes de un blog de Tumblr</title><content type='html'>&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;Advertencia:&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif; font-size: x-small;&quot;&gt;El contenido de este artículo está presentado solo con fines didácticos, como demostración de como utilizar herramientas GNU y expresiones regulares para procesar una gran cantidad de información de forma automática. &amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif; font-size: x-small;&quot;&gt;La propiedad intelectual de las imágenes en el sitio de Tumblr es de sus respectivos dueños.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Hace unos días se me ocurrió intentar bajar todas las imágenes de un blog de &lt;b&gt;Tumblr&lt;/b&gt;, pero hacerlo a mano tomaría demasiado tiempo, por lo que empecé a analizar la forma de automatizar la tarea.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Ya me había fijado en que todas las imágenes que estaba bajando estaban alojadas en dominios que empiezan con dos números seguidos de &lt;i&gt;.media.tumblr.com&lt;/i&gt; y los nombres empiezan con &lt;i&gt;tumblr_&lt;/i&gt;. Veamos un ejemplo: la imágen del post&amp;nbsp;&lt;a href=&quot;http://ilovephotographyclub.tumblr.com/post/22189996450/via-on-my-way-to-heaven-by-farhadvm-on&quot;&gt;http://ilovephotographyclub.tumblr.com/post/22189996450/via-on-my-way-to-heaven-by-farhadvm-on&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;es&amp;nbsp;&lt;a class=&quot;webkit-html-attribute-value webkit-html-resource-link&quot; href=&quot;http://27.media.tumblr.com/tumblr_m3chaqtcbC1roly7jo1_1280.jpg&quot; style=&quot;white-space: pre-wrap;&quot; target=&quot;_blank&quot;&gt;http://27.media.tumblr.com/tumblr_m3chaqtcbC1roly7jo1_1280.jpg&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Para este artículo voy a utilizar herramientas GNU, que pueden utilizarse tanto bajo las variantes *nix (Linux, FreeBSD, MacOS, etc.) como bajo Windows si instalamos &lt;a href=&quot;http://www.cygwin.com/&quot;&gt;cygwin&lt;/a&gt;&amp;nbsp;(lo cual recomiendo encarecidamente).&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Podemos utilizar &lt;b&gt;wge&lt;/b&gt;t para recuperar el contenido de la web y &lt;b&gt;sed&lt;/b&gt; para parsear el código html de la página para recuperar las direcciones de la imágenes. Con la siguiente&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;expresión regular&amp;nbsp;&lt;i&gt;&#39;/=&quot;http:\/\/.*media\.tumblr\.com\/tumblr_.*&quot;/ s/.*&quot;(http:\/\/.*\.[a-zA-Z]{3,4})&quot;.*/\1/p&#39;&lt;/i&gt; coincidimos las URL que nos interesan. &amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Ejecutando lo siguiente:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;$ wget -qO- http://ilovephotographyclub.tumblr.com/post/22189996450/via-on-my-way-to-heaven-by-farhadvm-on | sed -rn -e &#39;/=&quot;http:\/\/.*media\.tumblr\.com\/tumblr_.*&quot;/ s/.*&quot;(http:\/\/.*\.[a-zA-Z]{3,4})&quot;.*/\1/p&#39;
http://26.media.tumblr.com/tumblr_m3chaqtcbC1roly7jo1_250.jpg
http://27.media.tumblr.com/tumblr_m3chaqtcbC1roly7jo1_1280.jpg
&lt;/pre&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br class=&quot;Apple-interchange-newline&quot; /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;y terminamos con dos lineas que son los enlaces a las dos versiones de la imagen, una en baja resolución y la otra en una mayor resolución.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Ahora simplemente podemos bajar las imágenes con:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;$ wget&amp;nbsp;http://26.media.tumblr.com/tumblr_m3chaqtcbC1roly7jo1_250.jpg
$ wget&amp;nbsp;http://27.media.tumblr.com/tumblr_m3chaqtcbC1roly7jo1_1280.jpg
&lt;/pre&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Hasta acá solo probamos nuestra teoría de obtener los enlaces de los posts, ahora veamos como podemos aplicar esto a todos los posts del blog.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Vamos a trabajar con la página &lt;i&gt;principal&lt;/i&gt;&amp;nbsp;del blog para parsearla y recuperar de ahí los enlaces a cada post en particular. Personalmente no encontré una forma de hacer esto en pocos pasos, especialmente después de probarlo con varios blogs. La siguiente linea de comando nos retorna la lista de posts que solo pertenecen al blog que estamos procesando (muchas veces hay referencias a otros blogs de donde proviene la imágen).&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;$ wget -qO- http://ilovephotographyclub.tumblr.com | sed -rn -e &quot;/tumblr\.com\/post/ s/.*(\&quot;http:\/\/.*\.tumblr\.com\/post.*\&quot;).*/\1/p&quot; | sed -rn -e &#39;s/&quot;([^&quot;|^#]*)([&quot;#].*)/\1/p&#39; | sort | uniq

&lt;/pre&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;El comando recupera la página, filtra por los enlaces a posts y luego elimina el texto redundante que pasó por el primer filtro, también se aprovecha para eliminar referencias a la misma página (#), luego se ordena con &lt;b&gt;sort&lt;/b&gt; para que&amp;nbsp;&lt;b&gt;uniq&lt;/b&gt;&amp;nbsp;nos devuelva una lista única.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Ahora sería interesante aplicar esto a todos los posts del blog, si pudiéramos encontrar la forma de acceder a algún tipo de lista de los mismos.&amp;nbsp;La página&amp;nbsp;&lt;i&gt;archive&lt;/i&gt; del blog nos permite acceder al historial el blog, pero muestra solo los últimos posts en orden descendente, al ir bajando -mediante javascript- va agregando dinámicamente el resto de los posts mas antiguos que no aparecieron en la página al cargarse. Si intentamos recuperar esta página con &lt;b&gt;wget&lt;/b&gt; tenemos solo la página inicial y no todo el archivo por lo que no es práctico para nuestros intereses.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Otra forma de acceder al archivo de Tumblr es a través de páginas. Se pueden acceder ellas a través de la subcarpeta &lt;i&gt;page&lt;/i&gt; seguida del número de página a la que queremos acceder. Ej: http://blog.tumblr.com/page/3 para acceder a la página 3.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Con esto podemos recorrer todas las páginas con un contador y un bucle, hasta que lleguemos al final de las páginas. Si solicitamos una página posterior a la última que tenga contenido, el sitio nos devuelve una página sin enlaces a post alguno, con formato pero vacía, podría decirse.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Ya no podemos probar este concepto directamente desde la linea de comandos, tendremos que utilizar un script.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;#!/bin/bash

PAGE_NUM=1
SALIR=0
BASE_URL=&quot;http://$1.tumblr.com&quot;

while [ $SALIR -eq 0 ]; do
  SITE=&quot;$BASE_URL/page/$PAGE_NUM&quot;
  echo &quot;procesando la página $PAGE_NUM [$SITE]&quot;
  POST_LIST=`wget -qO- $SITE | sed -rn -e &quot;/$1\.tumblr\.com\/post/ s/.*(\&quot;http:\/\/.*\.tumblr\.com\/post.*\&quot;).*/\1/p&quot; | sed -rn -e &#39;s/&quot;([^&quot;|^#]*)([&quot;#].*)/\1/p&#39; | sort | uniq`
  if [ -z &quot;$POST_LIST&quot; ]; then
    SALIR=1
  else
    for POST in $POST_LIST; do
      echo $POST
    done
    let PAGE_NUM=$PAGE_NUM+1
  fi
done
&lt;/pre&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Este script entra en un loop en el que incrementaremos nuestro contador de páginas, recuperaremos los enlaces a posts de cada página, si no podemos recuperar ningún enlace mas significa que llegamos al final de las páginas, entonces salimos del loop. La única acción del script es recorrer la lista y mostrar los enlaces. Debemos de pasar el nombre del blog como parámetro. Ej:&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;$ sh dwn_tumblr_test.sh ilovephotographyclub
&lt;/pre&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Teniendo todo esto, es hora de programar un script que implemente todos los conceptos que probamos a lo largo del artículo.&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;#!/bin/bash

BLOG=$1
LOG=&quot;$1.log&quot;
URL=&quot;http://$1.tumblr.com&quot;
ARCHIVE=&quot;$URL/archive&quot;
DUMP_DIR=$1


echo -e &quot;Iniciando recuperacion del blog $1\n&quot; &amp;gt; $LOG
echo &quot;URL: $URL&quot; &amp;gt;&amp;gt; $LOG

echo -e &quot;Iniciando recuperacion del blog $1\n&quot; 
echo &quot;URL: $URL&quot;

# creamos la carpeta de salida
if [ -e $1 ] &amp;amp;&amp;amp; [ -d $1 ]; then
  echo &quot;usando directorio $PWD/$1&quot; &amp;gt;&amp;gt; $LOG
  echo &quot;usando directorio $PWD/$1&quot;
else
  echo &quot;directorio $PWD/$1 no existe, creando.&quot; &amp;gt;&amp;gt; $LOG
  echo &quot;directorio $PWD/$1 no existe, creando.&quot; 
  mkdir $1 &amp;gt;&amp;gt; $LOG
fi

echo &quot;&quot; &amp;gt;&amp;gt; $LOG

PAGE_NUM=1 # el número de página que vamos a procesar
SALIR=0    # el loop iteractuará mientras esta variable sea 0
while [ $SALIR -eq 0 ]; do
  PAGE_URL=&quot;$URL/page/$PAGE_NUM&quot;
  echo &quot;procesando la página $PAGE_NUM [$PAGE_URL]&quot;
  echo &quot;procesando la página $PAGE_NUM [$PAGE_URL]&quot; &amp;gt;&amp;gt; $LOG
  
  POST_LIST=`wget -qO- $PAGE_URL | sed -rn -e &quot;/$1\.tumblr\.com\/post/ s/.*(\&quot;http:\/\/.*\.tumblr\.com\/post.*\&quot;).*/\1/p&quot; | sed -rn -e &#39;s/&quot;([^&quot;|^#]*)([&quot;#].*)/\1/p&#39; | sort | uniq`
  if [ -z &quot;$POST_LIST&quot; ]; then
    SALIR=1
  else # if [ ! -z &quot;$POST_LIST&quot; ] ...
    for POST in $POST_LIST; do
   # recuperamos una lista de los enlaces de las imágenes del post. normalmente hay varias versiones
   # de la imágen posteada en varias resoluciones 
   IMG_URL_LIST=`wget -qO- $POST | sed -rn -e &#39;/=&quot;http:\/\/.*media\.tumblr\.com\/tumblr_.*&quot;/ s/.*(&quot;http:\/\/.*media\.tumblr\.com\/tumblr_.*&quot;).*/\1/p&#39; | sed -rn -e &#39;s/&quot;([^&quot;|^#]*)([&quot;#].*)/\1/p&#39; | sort | uniq`
  
   # recorremos la lista de imágenes
   for IMG_URL in $IMG_URL_LIST; do
  echo &quot;      url: $IMG_URL&quot;
    
  # recuperamos el nombre del archivo 
  FILE_NAME=`basename $IMG_URL`
  echo &quot;      filename: $FILE_NAME&quot;
    
  # para ahorrar tiempo solo bajamos el archivo si no existe en el directorio de salida 
  if [ -e &quot;$DUMP_DIR/$FILE_NAME&quot; ]; then
    echo &quot;url: $IMG_URL #filename: $FILE_NAME  post:$POST&quot; &amp;gt;&amp;gt; $LOG
    echo &quot;# ya existe&quot;
  else
    echo &quot;&amp;gt;&amp;gt; bajando&quot;
    echo &quot;url: $IMG_URL &amp;gt;filename: $FILE_NAME  post:$POST&quot; &amp;gt;&amp;gt; $LOG    
    wget -qO &quot;$DUMP_DIR/$FILE_NAME&quot; $IMG_URL &amp;gt;&amp;gt; $LOG
  fi
   done # for IMG_URL in $IMG_URL_LIST ...
    done # for POST in $POST_LIST ...
    let PAGE_NUM=$PAGE_NUM+1
  fi # if [ ! -z &quot;$POST_LIST&quot; ] ...
done # while [ $SALIR -eq 0 ] ...
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Guardamos el script en un archivo y lo ejecutamos, siempre pasando el nombre del blog como parámetro:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;$ sh dwn_tumblr.sh ilovephotographyclub
&lt;/pre&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;y al terminar tendremos un directorio con el nombre del blog con las imágenes y un archivo también con el mismo nombre pero con extensión .log con el detalle de todo lo descargado.

 &lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Todo el ejemplo aquí expuesto fue creado y probado con CygWin bajo Windows 7 x64.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Actualización 03/05/2012: En el último script, en la linea 42 se agregó &quot;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;| sort | uniq&quot;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt; &amp;nbsp;al código a fin de eliminar duplicados:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;IMG_URL_LIST=`wget -qO- $POST | sed -rn -e &#39;/=&quot;http:\/\/.*media\.tumblr\.com\/tumblr_.*&quot;/ s/.*(&quot;http:\/\/.*&quot;).*/\1/p&#39; | sed -rn -e &#39;s/&quot;([^&quot;|^#]*)([&quot;#].*)/\1/p&#39;`
&lt;/pre&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;por&lt;/span&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;IMG_URL_LIST=`wget -qO- $POST | sed -rn -e &#39;/=&quot;http:\/\/.*media\.tumblr\.com\/tumblr_.*&quot;/ s/.*(&quot;http:\/\/.*&quot;).*/\1/p&#39; | sed -rn -e &#39;s/&quot;([^&quot;|^#]*)([&quot;#].*)/\1/p&#39; | sort | uniq`&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;En las lineas 54 y 58 se agregó &quot;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;post: $POST&quot;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt; al texto del &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;echo&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;, a fin de registrar de cual entrada se recuperó la imágen.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://patotech.blogspot.com/feeds/3590497611799753645/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1381165230718116833/3590497611799753645' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default/3590497611799753645'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default/3590497611799753645'/><link rel='alternate' type='text/html' href='http://patotech.blogspot.com/2012/05/descargar-todas-las-imagenes-de-un-blog.html' title='Descargar todas las imágenes de un blog de Tumblr'/><author><name>Patricio Diaz</name><uri>http://www.blogger.com/profile/15817672756742645565</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1381165230718116833.post-6063968230797619492</id><published>2012-04-19T23:57:00.000-04:00</published><updated>2012-04-19T23:57:04.929-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="automatización"/><category scheme="http://www.blogger.com/atom/ns#" term="base64"/><category scheme="http://www.blogger.com/atom/ns#" term="bash"/><category scheme="http://www.blogger.com/atom/ns#" term="cron"/><category scheme="http://www.blogger.com/atom/ns#" term="genexus"/><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="mime"/><category scheme="http://www.blogger.com/atom/ns#" term="windows"/><title type='text'>Autómatas con Genexus Ev1 en Linux y Windows, y II</title><content type='html'>&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;En el &lt;a href=&quot;http://patotech.blogspot.com/2012/04/automatas-con-genexus-ev1-en-linux-y.html&quot;&gt;capítulo anterior&lt;/a&gt; creamos un programa de ejemplo con unos requerimientos específicos con la intención de ejecutarlo periódicamente de forma automática.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Ahora que tenemos nuestro programa funcionando, vamos a ponerlo a funcionar bajo linux.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: left;&quot;&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;La idea es crear un script del shell para llamar a nuestro programa, hacer algunas verificaciones y enviar el reporte resultante por correo.&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;h2&gt;
























&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Verificaciones previas&lt;/span&gt;&lt;/h2&gt;
&lt;/div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Antes que nada debemos asegurarnos que nuestra máquina linux puede enviar mensajes de correo y tenemos instalada alguna máquina virtual java.&lt;/span&gt;&lt;br /&gt;
&lt;h3&gt;
























&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Correo&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Para este proyecto utilizaremos Sendmail, que se instala con casi todas las distribución de linux mas conocidas.&amp;nbsp;Cómo configurar sendmail escapa del objetivo de este artículo, hay un montón de artículos al respecto en la red.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Podemos enviar un mensaje de prueba con el siguiente comando:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;echo -e &quot;Subject: ping \n\nthis goes on the body&quot;  | sendmail -f micuenta@dominio.com otracuenta@gmail.com&lt;/pre&gt;
&lt;br /&gt;
&lt;h3&gt;
























&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Verificamos si tenemos java instalado&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Para distribuciones basadas en Debian utilizamos el siguiente comando:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;dpkg --get-selections | grep openjdk
&lt;/pre&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJw69zUt4JJXSnuMfAi9HkJOfk28HI9g7eKltwmGiOsWlPcoJg5rEm1O8PdPSHzOvS3d6hBKSUpjb028Uw_Z1L2mNeQQgUfilRlo1Ws4YEs9EtX737xNcHrWN4eAg_svdpKz7kozHH2-rr/s1600/verificar_openjdk_turnkey.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;163&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJw69zUt4JJXSnuMfAi9HkJOfk28HI9g7eKltwmGiOsWlPcoJg5rEm1O8PdPSHzOvS3d6hBKSUpjb028Uw_Z1L2mNeQQgUfilRlo1Ws4YEs9EtX737xNcHrWN4eAg_svdpKz7kozHH2-rr/s400/verificar_openjdk_turnkey.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhL7lsGQri-p2UJuV_Nfb5QFpDEkjUN3U4sQL9WPqUx6LEZfl2ueDhPY3qskpP0OT_THFq1aXUR8OImYT323zm8EpOILDcaUpXjflrsY4ETE_Je5mfhcPZC7khnuL0Ga63aCn9n1k2ltNH5/s1600/verificar_openjdk_ubuntu.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;166&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhL7lsGQri-p2UJuV_Nfb5QFpDEkjUN3U4sQL9WPqUx6LEZfl2ueDhPY3qskpP0OT_THFq1aXUR8OImYT323zm8EpOILDcaUpXjflrsY4ETE_Je5mfhcPZC7khnuL0Ga63aCn9n1k2ltNH5/s400/verificar_openjdk_ubuntu.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Para distribuciones que utilizan RPM utilizamos esto:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;rpm -qa | grep openjdk
&lt;/pre&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5fgyW86iV2lYqId-SYPWrpwXAwEwX-t53uiviC7dOYcsPdlr8arnIN9RcKKpUTG97RrPRPoDtAJ2fVq6gQp7wHFY4xDnVE-3UFb98JzM0KaoB4Oa2wZGOps7jVh0J1Q_xbacsGjNz0I6-/s1600/verificar_openjdk_centos.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;165&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5fgyW86iV2lYqId-SYPWrpwXAwEwX-t53uiviC7dOYcsPdlr8arnIN9RcKKpUTG97RrPRPoDtAJ2fVq6gQp7wHFY4xDnVE-3UFb98JzM0KaoB4Oa2wZGOps7jVh0J1Q_xbacsGjNz0I6-/s400/verificar_openjdk_centos.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h3&gt;
























&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Copiar archivos al servidor&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;A los efectos de nuestro proyecto crearemos una carpeta &lt;i&gt;chequeodesatendido&lt;/i&gt; en &lt;b&gt;/opt&lt;/b&gt;, aunque no es obligatorio y podría ir en otro lugar, por ejemplo en &lt;b&gt;/usr/local&lt;/b&gt; o &lt;b&gt;/usr/lib&lt;/b&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Ahora debemos copiar nuestro programa a la caja linux,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;personalmente utilizo &lt;b&gt;WinSCP&lt;/b&gt;. En realidad no necesitamos copiar todos los archivos que nos creó el &lt;b&gt;Deployment Wizard&lt;/b&gt;, solo necesitamos las carperas &lt;i&gt;Shared&lt;/i&gt; y &lt;i&gt;chequeodesatendido&lt;/i&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAJ9BtlO_XknN4QpPe51rgHtCwdfcf32u_0NbKjtDlsJkHW3kvobR5ouNowUjLt-bltKQlnVJhxYrqJHDJkwzv7RTRQfD_YnJppUQKVztqJ0tBweDHjDjLnk3eV_V1T6X1X3g3IiDDYTwn/s1600/winscp_copiar.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;228&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAJ9BtlO_XknN4QpPe51rgHtCwdfcf32u_0NbKjtDlsJkHW3kvobR5ouNowUjLt-bltKQlnVJhxYrqJHDJkwzv7RTRQfD_YnJppUQKVztqJ0tBweDHjDjLnk3eV_V1T6X1X3g3IiDDYTwn/s400/winscp_copiar.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;h3&gt;





















&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Pruebas preliminares&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Ya tenemos todo lo necesario para empezar a probar nuestro programa. Creamos un archivo llamado test.sh y le agregamos el siguiente código:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;#!/bin/bash
# get current date with file name friendly format
FECHA=`date +&quot;%Y-%m-%d_%H-%M&quot;`

# output file
ARCHIVO_SALIDA=cr_$FECHA

# output folder
DIRECTORIO_SALIDA=&quot;$PWD/reportes&quot;

GXCLASSPATH=&quot;Shared/.:Shared/gxclassp.jar:Shared/iText.jar:chequeodesatendido/chequeodesatendido_GXWS.jar&quot;


HOY=`date +&quot;%d/%m/%y&quot;`
java -cp $GXCLASSPATH achequeodesatendido &quot;$HOY&quot; &quot;$HOY&quot; &quot;$DIRECTORIO_SALIDA/$ARCHIVO_SALIDA&quot; $&amp;gt; &quot;$DIRECTORIO_SALIDA/$ARCHIVO_SALIDA.log&quot;
&lt;/pre&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;En este script la variable FECHA captura la fecha y la hora del sistema, a diferencia del script que utilizamos bajo windows que solo capturaba la fecha.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Atender que la lista GXCLASSPATH&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;bajo linux&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;debe estar separada por &quot;:&quot; mientras que bajo windows va separada por &quot;;&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;La variable HOY es nueva en este script y es simplemente la fecha del sistema en el órden y formato que espera nuestro programa.&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Ejecutamos la prueba:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;sh test.sh&lt;/pre&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQglgA2enaa5qtEfBGhasufJ9wC4Poh1U2ItNkPk2gGaTTKY48NB6m5wOQOgEyAQd2RmqWBkGtwqOVEbKqXoqd3aJ1cFBiU2WEgMdPeu2D2RExvJ-014_JBj_WSDqYRGljCXCiE6yi63Wv/s1600/ejecucion_test.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;78&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQglgA2enaa5qtEfBGhasufJ9wC4Poh1U2ItNkPk2gGaTTKY48NB6m5wOQOgEyAQd2RmqWBkGtwqOVEbKqXoqd3aJ1cFBiU2WEgMdPeu2D2RExvJ-014_JBj_WSDqYRGljCXCiE6yi63Wv/s400/ejecucion_test.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Como en el capítulo anterior, deberíamos tener un PDF en la carpeta reportes.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;h3&gt;




















&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;El script definitivo&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Creamos un script llamado run.sh y le agregamos el siguiente código:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;#!/bin/bash

#cambiamos al directorio base
cd&amp;nbsp;/opt/chequeodesatendido

FECHA=`date +&quot;%Y-%m-%d_%H-%M&quot;`
ARCHIVO_SALIDA=&quot;cr_$FECHA&quot;
DIRECTORIO_SALIDA=&quot;$PWD/reportes&quot;
GXCLASSPATH=&quot;Shared/.:Shared/gxclassp.jar:Shared/iText.jar:chequeodesatendido/chequeodesatendido_GXWS.jar&quot;

# a quien notificar
LISTA_NOTIFICACION=&quot;destino1@dominio.com&quot;

# si tenemos mas de un destinatario, separar cada uno con un espacio
#LISTA_NOTIFICACION=&quot;destino1@dominio.com destino2@dominio.com&amp;nbsp;destino3@dominio.com&quot;
REMITENTE=&#39;verificador@dominio.com&#39;
SEPARADOR=&quot;$$-$$-$$-&quot;

# tamaño de la carpeta
TAMANHO_ACTUAL=`du -h $DIRECTORIO_SALIDA`

enviar_mail() {
    local DIRECCION_CORREO
    local REPORTE
    local ERRORES
    local FECHA_LINDA

    # codificamos el reporte en base64 y lo cargamos en una variable. esto va
    # a ir como un atado al mensaje.
    REPORTE=`base64 $DIRECTORIO_SALIDA/$ARCHIVO_SALIDA.pdf`

    # recuperamos las lineas del log en otra variable, estas no van a ir como
    # atado sino en el cuerpo del texto.
    ERRORES=`cat &quot;$DIRECTORIO_SALIDA/$ARCHIVO_SALIDA.log&quot;`

    # podemos filtrar las lineas, por ejemplo para ignorar advertencias o depuración.
    #ERRORES=`cat $DIRECTORIO_SALIDA/$ARCHIVO_SALIDA.log | grep &quot;Errores:&quot;`

    # fecha en formato mas amigable
    FECHA_LINDA=`date +&quot;%d/%m/%Y %H:%M&quot;`

    # enviamos un mensaje por cada dirección de la lista de notificación.
    # también se podría enviar un solo mensaje con las direcciones en CC.
    for DIRECCION_CORREO in $DIRECCION_NOTIFICACION; do
        /usr/sbin/sendmail -f $REMITENTE -t &amp;lt;&amp;lt;EOF
MIME-Version: 1.0
To: $DIRECCION_CORREO
From: $REMINTENTE
Subject: Verificación de consistencia - $FECHA_LINDA - $ERRORES
Content-Type: multipart/mixed; boundary=&quot;$SEPARADOR&quot;

--$SEPARADOR
Content-Type: text/plain; charset=UTF8; format=flowed
content-transfer-encoding: 8bit

$ERRORES

Reporte generado al $FECHA_LINDA
Archivo adjunto: $ARCHIVO_SALIDA.pdf

Tamaño actual del directorio: $ACTUAL_SIZE

--$SEPARADOR
Content-Type: application/pdf; name=&quot;$ARCHIVO_SALIDA.pdf&quot;
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=&quot;$ARCHIVO_SALIDA.pdf&quot;

$REPORTE

--$SEPARADOR
Content-Type: text/plain; name=&quot;$ARCHIVO_SALIDA.log&quot;
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=&quot;$ARCHIVO_SALIDA.log&quot;

`cat $DIRECTORIO_SALIDA/$ARCHIVO_SALIDA.log`

EOF
    done

}

# generar el reporte
HOY=`date +&quot;%d/%m/%y&quot;`
java -cp $GXCLASSPATH achequeodesatendido &quot;$HOY&quot; &quot;$HOY&quot; &quot;$DIRECTORIO_SALIDA/$ARCHIVO_SALIDA&quot; $&amp;gt; &quot;$DIRECTORIO_SALIDA/$ARCHIVO_SALIDA.log&quot;


# si se generó el archivo de salida, lo enviamos.
if [ -f $DIRECTORIO_SALIDA/$ARCHIVO_SALIDA.pdf ]; then
    echo &quot;Existe $ARCHIVO_SALIDA&quot;
    enviar_mail
fi
&lt;/pre&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Analicemos el script.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;#!/bin/bash

# cambiamos al directorio base
cd&amp;nbsp;/opt/chequeodesatendido

FECHA=`date +&quot;%Y-%m-%d_%H-%M&quot;`
ARCHIVO_SALIDA=&quot;cr_$FECHA&quot;
DIRECTORIO_SALIDA=&quot;$PWD/reportes&quot;
GXCLASSPATH=&quot;Shared/.:Shared/gxclassp.jar:Shared/iText.jar:chequeodesatendido/chequeodesatendido_GXWS.jar&quot;

# a quien notificar
LISTA_NOTIFICACION=&quot;destino1@dominio.com&quot;

# si tenemos mas de un destinatario, separar cada uno con un espacio
#LISTA_NOTIFICACION=&quot;destino1@dominio.com destino2@dominio.com&amp;nbsp;destino3@dominio.com&quot;
REMITENTE=&#39;verificador@dominio.com&#39;
SEPARADOR=&quot;$$-$$-$$-&quot;

# tamaño de la carpeta
TAMANHO_ACTUAL=`du -h $DIRECTORIO_SALIDA`
&lt;/pre&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;
&lt;br /&gt;
Hasta acá solo son definiciones de variables que utilizaremos mas tarde. SEPARADOR es un texto arbitrario que definiremos para separar las secciones del mensaje, explicaré eso mas adelante. Como siempre a modo de ejemplo en la variable TAMANHO_ACTUAL recuperamos el espacio en disco ocupado por los reportes y la incluiremos en el cuerpo del mensaje.&lt;br /&gt;
&lt;br /&gt;
A continuación tenemos la función que construye y envía el mensaje de correo.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;
&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush: bash; first-line: 22;&quot;&gt;enviar_mail() {
    local DIRECCION_CORREO
    local REPORTE
    local ERRORES
    local FECHA_LINDA

    # codificamos el reporte en base64 y lo cargamos en una variable. esto va
    # a ir como un atado al mensaje.
    REPORTE=`base64 $DIRECTORIO_SALIDA/$ARCHIVO_SALIDA.pdf`

    # recuperamos las lineas del log en otra variable, estas no van a ir como
    # atado sino en el cuerpo del texto.
    ERRORES=`cat &quot;$DIRECTORIO_SALIDA/$ARCHIVO_SALIDA.log&quot;`

    # podemos filtrar las lineas, por ejemplo para ignorar advertencias o depuración.
    #ERRORES=`cat $DIRECTORIO_SALIDA/$ARCHIVO_SALIDA.log | grep &quot;Errores:&quot;`

    # fecha en formato mas amigable
    FECHA_LINDA=`date +&quot;%d/%m/%Y %H:%M&quot;`

    # enviamos un mensaje por cada dirección de la lista de notificación.
    # también se podría enviar un solo mensaje con las direcciones en CC.
    for DIRECCION_CORREO in $DIRECCION_NOTIFICACION; do
        /usr/sbin/sendmail -f $REMITENTE -t &amp;lt;&amp;lt;EOF
MIME-Version: 1.0
To: $DIRECCION_CORREO
From: $REMINTENTE
Subject: Verificación de consistencia - $FECHA_LINDA - $ERRORES
Content-Type: multipart/mixed; boundary=&quot;$SEPARADOR&quot;

--$SEPARADOR
Content-Type: text/plain; charset=UTF8; format=flowed
content-transfer-encoding: 8bit

$ERRORES

Reporte generado al $FECHA_LINDA
Archivo adjunto: $ARCHIVO_SALIDA.pdf

Tamaño actual del directorio: $ACTUAL_SIZE

--$SEPARADOR
Content-Type: application/pdf; name=&quot;$ARCHIVO_SALIDA.pdf&quot;
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=&quot;$ARCHIVO_SALIDA.pdf&quot;

$REPORTE

--$SEPARADOR
Content-Type: text/plain; name=&quot;$ARCHIVO_SALIDA.log&quot;
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=&quot;$ARCHIVO_SALIDA.log&quot;

`cat $DIRECTORIO_SALIDA/$ARCHIVO_SALIDA.log`

EOF
    done

}
&lt;/pre&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Como nuestro archivo de salida es un archivo binario (PDF) no lo podemos incluirlo directamente, el mensaje de correo solo puede estar constituido por text ASCII. Para conseguir esto codificamos el archivo en base64 y separamos el mensaje en secciones, para eso nos servirá la variable SEPARADOR. En la primera sección pondremos el cuerpo del mensaje, en las siguientes colocamos los archivos &quot;atados&quot;.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Veamos esto con mas detalle:&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;
&lt;br /&gt;
En la linea 47 tenemos&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace; font-size: x-small;&quot;&gt;Content-Type: multipart/mixed; boundary=&quot;$SEPARADOR&quot;&lt;/span&gt;, que dice que el mensaje está formado por varias partes, de tipos mezclados y que el &#39;límite&#39; entre las secciones será el texto de SEPARADOR.&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;En la linea 49 definimos el límite de la primera sección, notese que todos los límites empiezan con dos signos menos seguidos: &quot;--&quot;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;En las siguientes lineas tenemos:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;brush: bash; first-line: 53;&quot;&gt;Content-Type: text/plain; charset=UTF8; format=flowed
content-transfer-encoding: 8bit&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Define la sección como texto plano, utilizando set de caracteres UTF8 y que la codificación de la transferencia será de 8bits (&lt;a href=&quot;http://www.freesoft.org/CIE/RFC/1521/5.htm&quot;&gt;http://www.freesoft.org/CIE/RFC/1521/5.htm&lt;/a&gt;).&lt;/span&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Agregamos al texto del cuerpo algunas de los datos que habíamos colectado, ERRORES y TAMANHO_ACTUAL.


En la linea 60 se define el límite de otra sección, esta vez el de nuestro archivo de salida binario. La cabecera de la sección está definida por:&lt;/span&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: bash; first-line: 64;&quot;&gt;Content-Type: application/pdf; name=&quot;$ARCHIVO_SALIDA.pdf&quot;
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=&quot;$ARCHIVO_SALIDA.pdf&quot;&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Definimos que el tipo de contenido va a ser &lt;i&gt;application/pdf&lt;/i&gt; y el nombre del atado, se especifica que la codificación de transferencia será &lt;i&gt;base64&lt;/i&gt;, que es un atado y el nombre de archivo sugerido al guardar. Y en la linea 65 colocamos el texto que goardamos en REPORTE.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Por último, en la linea 67 tenemos el límite de la última sección, seguido de la siguiente cabecera:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: bash; first-line: 71;&quot;&gt;Content-Type: text/plain; name=&quot;$ARCHIVO_SALIDA.log&quot;
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=&quot;$ARCHIVO_SALIDA.log&quot;&lt;/pre&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Como nuestro archivo de log está en formato texto, solo lo vamos a &quot;volcar&quot; a la sección con&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace; font-size: x-small;&quot;&gt;`cat $DIRECTORIO_SALIDA/$ARCHIVO_SALIDA.log`&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&amp;nbsp;y la cabecera especifica que es un atado.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Ahora nos encontramos con el código principal de nuestro script:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: bash first-line: 82;&quot;&gt;# generar el reporte
HOY=`date +&quot;%d/%m/%y&quot;`
java -cp $GXCLASSPATH achequeodesatendido &quot;$HOY&quot; &quot;$HOY&quot; &quot;$DIRECTORIO_SALIDA/$ARCHIVO_SALIDA&quot; $&amp;gt; &quot;$DIRECTORIO_SALIDA/$ARCHIVO_SALIDA.log&quot;


# si se generó el archivo de salida, lo enviamos.
if [ -f $DIRECTORIO_SALIDA/$ARCHIVO_SALIDA.pdf ]; then
    echo &quot;Existe $ARCHIVO_SALIDA&quot;
    enviar_mail
fi&lt;/pre&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;
&lt;/span&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;
&lt;/span&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;A pesar de ser el código principal, no hay mucho que explicar aquí, formateamos la fecha actual de la forma que espera nuestro programa como parámetro, llamamos a nuestro programa y redirigimos la salida estandar al archivo de log.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Finalmente verificamos si el programa generó alguna salida y la enviamos por mail con la función que explicamos mas arriba.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Probamos nuestro script:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;sh test.sh&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicaD8fGKrEHXxjvRke0YBo4vGWbAVY-EdRfb1HnzIkned1shREWpQQuh0_jSnsh_PU-HS7RUHLqNbjBsRLJwV5RZzqY-x6-ImPaeIgNPlBKc2nvM7-SmrrFtP8xtOzq8o7xB1iYwbFjzlK/s1600/ejecucion_recepcion_correo.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;117&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicaD8fGKrEHXxjvRke0YBo4vGWbAVY-EdRfb1HnzIkned1shREWpQQuh0_jSnsh_PU-HS7RUHLqNbjBsRLJwV5RZzqY-x6-ImPaeIgNPlBKc2nvM7-SmrrFtP8xtOzq8o7xB1iYwbFjzlK/s400/ejecucion_recepcion_correo.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: -webkit-auto;&quot;&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Si todo fue bien, debemos de estar recibiendo un mail con nuestros archivos como atados.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhB4IOxQuE8w5iiplWTvk8YPwWz5ndq8Y0HHaJifIh2oRiwcrDKzcw9XU5R-01MLq3kQvjP_nmnG7HbvE-cImcAO0ukQtTquNhJWRDJbcNGv0hRrF9DIEy5DR5ijVhmNq3BBG1dW46M22kh/s1600/email.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;296&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhB4IOxQuE8w5iiplWTvk8YPwWz5ndq8Y0HHaJifIh2oRiwcrDKzcw9XU5R-01MLq3kQvjP_nmnG7HbvE-cImcAO0ukQtTquNhJWRDJbcNGv0hRrF9DIEy5DR5ijVhmNq3BBG1dW46M22kh/s400/email.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;



&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Agendar para ejecución periódica&lt;/span&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Tan solo nos falta programar una tarea con CRON para que se ejecute periódicamente nuestro autómata.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Ejecutamos &lt;i&gt;crontab -e&lt;/i&gt; y agregamos la siguiente linea:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;*/5 * * * * sh /opt/chequeodesatendido/run.sh&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Guardamos la tarea (presionamos ESC, luego :w + ENTER, por último :q + ENTER para salir). A partir de ahora estaríamos recibiendo un correo electrónico cada 5 minutos con los resultados de nuestro programa como atado.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Bueno, hasta aquí esta segunda entrega de la serie.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;a class=&quot;GPCRQBSPB&quot; href=&quot;http://www.blogger.com/blogger.g?blogID=1381165230718116833&quot; kind=&quot;edit&quot; style=&quot;background-color: #fff9e7; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #1155cc; cursor: pointer; font-family: Arial, Helvetica, sans-serif; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 10px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: -webkit-left; vertical-align: baseline;&quot;&gt;Autómatas con Genexus Ev1 en Linux y Windows, y I&lt;/a&gt;
&lt;/div&gt;
&lt;br class=&quot;Apple-interchange-newline&quot; /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://patotech.blogspot.com/feeds/6063968230797619492/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1381165230718116833/6063968230797619492' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default/6063968230797619492'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default/6063968230797619492'/><link rel='alternate' type='text/html' href='http://patotech.blogspot.com/2012/04/automatas-con-genexus-ev1-en-linux-y_19.html' title='Autómatas con Genexus Ev1 en Linux y Windows, y II'/><author><name>Patricio Diaz</name><uri>http://www.blogger.com/profile/15817672756742645565</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJw69zUt4JJXSnuMfAi9HkJOfk28HI9g7eKltwmGiOsWlPcoJg5rEm1O8PdPSHzOvS3d6hBKSUpjb028Uw_Z1L2mNeQQgUfilRlo1Ws4YEs9EtX737xNcHrWN4eAg_svdpKz7kozHH2-rr/s72-c/verificar_openjdk_turnkey.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1381165230718116833.post-1404358061026423695</id><published>2012-04-18T19:26:00.001-04:00</published><updated>2016-04-13T16:40:26.882-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="automation"/><category scheme="http://www.blogger.com/atom/ns#" term="genexus"/><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="windows"/><title type='text'>Automata with GeneXus Ev1 on Linux and Windows, and I</title><content type='html'>&lt;div style=&quot;text-align: right;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;a href=&quot;http://patotech.blogspot.com/2012/04/automatas-con-genexus-ev1-en-linux-y.html&quot;&gt;Spanish version&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Today I will begin a series of four publications in which I will try to give a glimpse into how to program an automata in Genexus Ev1, periodically run it on Linux or Windows and send logs and/or resulting reports by mail.&lt;br /&gt;&lt;br /&gt;This technique we used in production at one company where I worked as a developer to implement a data integrity verification process.&lt;br /&gt;&lt;br /&gt;In this first issue will discuss the creation of the automaton with GeneXus Evolution 1 and the Java generator for Windows, but in fact could be programmed with any language that can throw a PDF with the name and directory you specify.&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;In the second issue we will deal with running it periodically under Linux using nothing but standard GNU applications that come with most distributions.&lt;br /&gt;&lt;br /&gt;In the third post will do the same but under Windows, using some third party applications to achieve the same effect as inLinux.&lt;br /&gt;&lt;br /&gt;In the fourth and final issue I will modify the script for Linux to use the same applications that we will use in Windows, as an exercise in adaptation from one platform to another.&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h2&gt;











&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Requirements of the automata&lt;/span&gt;&lt;/h2&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;We need to create a program without a user interface that receives parameters from the command line, create files in a directory passed as parameter, as its output goes to standard output text to the OS.&lt;br /&gt;&lt;br /&gt;Access to databases or other procedures will depend in each case we want to implement this technique, so they are optional as requirement.&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h2&gt;











&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Hands On&lt;/span&gt;&lt;/h2&gt;
&lt;div&gt;
&lt;h3&gt;











&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;The main procedure&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;As a first step we create a KB on GeneXus. For the purposes of this project we choose J&lt;i&gt;ava Environment&lt;/i&gt; in &lt;b&gt;Prototyping Environment &lt;/b&gt;and chose &lt;i&gt;Win &lt;/i&gt;as &lt;b&gt;target&lt;/b&gt;, the rest of the details aren&#39;t relevant but to follow the example would be advisable to name &lt;i&gt;chequeodesatendido&lt;/i&gt; to the KB.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7A1qdDgDg_lcG8Wp2kjTgLghC-dajWfek8pz9zJMe1IQg4yUgFvinmP7D_p8BvuPAbbPHLNRL8gEIIHKoLZqTBxYs0U4ciBX5pfN_HKKxGxCu8pma9oTmJgq5ZdgiyBBAyW6QVsr5DGtb/s1600/crear_kb.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;255&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7A1qdDgDg_lcG8Wp2kjTgLghC-dajWfek8pz9zJMe1IQg4yUgFvinmP7D_p8BvuPAbbPHLNRL8gEIIHKoLZqTBxYs0U4ciBX5pfN_HKKxGxCu8pma9oTmJgq5ZdgiyBBAyW6QVsr5DGtb/s400/crear_kb.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Now create a procedure called &lt;i&gt;chequeodesatendido&lt;/i&gt;, this will be the main procedure of our automata. Change in its properties&amp;nbsp;&lt;/span&gt;
&lt;b&gt;&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Main program&lt;/span&gt;&amp;nbsp;&lt;/b&gt;&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;to &lt;i&gt;True&lt;/i&gt; and &lt;b&gt;Call&lt;/b&gt;&lt;/span&gt;&lt;b&gt;&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;protocol&lt;/span&gt;&lt;/b&gt;&amp;nbsp;&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;to &lt;i&gt;Command line&lt;/i&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghoZVHhd3Jc87-pe4xFfgafPKyYLZ1elxqR0pQfvkK-sbju5quuTJC7fofaxEIKV9loZx58E_sLb2Sbo4IiP1NaZS3T-GpEQFzU9k-Y4wc7VYC-ZxOgs2ToKfl1fBqTdAKTOtZ7onga1Xe/s1600/procedimiento_prop.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghoZVHhd3Jc87-pe4xFfgafPKyYLZ1elxqR0pQfvkK-sbju5quuTJC7fofaxEIKV9loZx58E_sLb2Sbo4IiP1NaZS3T-GpEQFzU9k-Y4wc7VYC-ZxOgs2ToKfl1fBqTdAKTOtZ7onga1Xe/s400/procedimiento_prop.jpg&quot; width=&quot;268&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Add some code:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;b&gt;Rules&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;parm(in:&amp;amp;date_ini, in:&amp;amp;date_end, in:&amp;amp;filename);
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;b&gt;Source&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;if &amp;amp;date_ini.IsEmpty() or &amp;amp;date_end.IsEmpty() or &amp;amp;filename.IsEmpty() 
  msg(&quot;Faltan parametros.&quot;)
  msg(&quot;Se debe proveer fecha inicial, fecha final y nombre del archivo de salida&quot;)
endif

msg(&quot;date ini: &quot; + &amp;amp;date_ini.ToFormattedString() + 
  &quot; | date_end: &quot; + &amp;amp;date_end.ToFormattedString() + 
  &quot; | filename: &quot; + &amp;amp;filename
)

reporte.call(&amp;amp;date_ini, &amp;amp;date_end, &amp;amp;filename)
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;As can be seen the code is quite simple, just as an example.Msg is output to the console, which under Linux can be redirected to a file easily under Windows can not find yet how to do the same.&lt;br /&gt;&lt;br /&gt;This is where we run or call the code that performs some verification, correction, closing process, etc.. on our data. &lt;/span&gt;&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;h3&gt;









&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Report&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Create a procedure called report and modify its properties. By coincidence the properties matches the above procedure, change&amp;nbsp;
&lt;b&gt;Main program&lt;/b&gt;&amp;nbsp; to&amp;nbsp;&lt;i&gt;True&lt;/i&gt; and &lt;b&gt;Call&amp;nbsp;
protocol&lt;/b&gt;&amp;nbsp;&amp;nbsp;to &lt;i&gt;Command line&lt;/i&gt;. &lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;b&gt;Rules&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;parm(in:&amp;amp;date_ini, in:&amp;amp;date_end, in:&amp;amp;filename);
output_file(&amp;amp;filename, &#39;PDF&#39;);
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;b&gt;Source&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;print printBlock1
return
&lt;/pre&gt;
&lt;br /&gt;
&lt;h3&gt;






&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Layout&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;For our example create just a band called &lt;i&gt;printBlock1&lt;/i&gt; and add the variables that received as parameter. In production this is where the report to be sent as a result should be generated.&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeGZNJEsPJWzJaPVe_L2x-5y55IimFDYwDPcZQw6PFkXJmDsiQPeo-hJ9Q5L0FJ3Uu2n6H0wE8ttxsYQIqDFLWRFLsewzpZjSNNM0ERVAbVd6AelnEHvdXv_AxgIRNZMEJLMUnohuYBDYi/s1600/layout.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;200&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeGZNJEsPJWzJaPVe_L2x-5y55IimFDYwDPcZQw6PFkXJmDsiQPeo-hJ9Q5L0FJ3Uu2n6H0wE8ttxsYQIqDFLWRFLsewzpZjSNNM0ERVAbVd6AelnEHvdXv_AxgIRNZMEJLMUnohuYBDYi/s400/layout.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Now define &lt;i&gt;chequeodesatendido&lt;/i&gt; as the &lt;b&gt;Startup object&lt;/b&gt; and create the project.&lt;/span&gt;&lt;/div&gt;
&lt;h3&gt;






&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h3&gt;






&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Deploy it&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;The easiest way to package the files needed to run our project is doing a &quot;deploy&quot;, so you run the &lt;b&gt;Deployment Wizard&lt;/b&gt;.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSGGTswqxZ9tkxDlYqYGQgi-Q4g1gdXl1pqS3n1pYhDRp5iFIMDJqHYL9gme2468MyT66eH8kq_zP3LtVfy6G1f4pBfByQzU1oZley3JCY2aemr2WAfR5owNo9_ffygJGrDc7mIpaxceiC/s1600/deploymentwizard.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;335&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSGGTswqxZ9tkxDlYqYGQgi-Q4g1gdXl1pqS3n1pYhDRp5iFIMDJqHYL9gme2468MyT66eH8kq_zP3LtVfy6G1f4pBfByQzU1oZley3JCY2aemr2WAfR5owNo9_ffygJGrDc7mIpaxceiC/s400/deploymentwizard.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;
On the first screen our two procedures appears in the list of &lt;b&gt;Available mains&lt;/b&gt;, pass them to the right under&amp;nbsp;&lt;b&gt;Mains to deploy&lt;/b&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaVG0nC7H0Pnj7BUK9O-FayRC0QGiEUqyCq7McrmCqqY4m8BH9Z93XCWIYdjD6i1Onh4dElymQgGQL0Q5ZWJwxeiArp4w2IbqUG-uskapVilai63qVCUtMxQ8WT0Opqj2L0Ms8GbtlRTwi/s1600/dw1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;343&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaVG0nC7H0Pnj7BUK9O-FayRC0QGiEUqyCq7McrmCqqY4m8BH9Z93XCWIYdjD6i1Onh4dElymQgGQL0Q5ZWJwxeiArp4w2IbqUG-uskapVilai63qVCUtMxQ8WT0Opqj2L0Ms8GbtlRTwi/s400/dw1.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;br /&gt;We turn to the second screen and don&#39;t touch anything there, just hit &lt;b&gt;Next&lt;/b&gt; to reach the third screen. Once there we check the checkbox &lt;b&gt;Transfer&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;location&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;b&gt;files&lt;/b&gt; then we enter a directory where the wizard will place the files, finally click &lt;b&gt;Finish&lt;/b&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiN_xaAyeQEUxn4X-DyY0ErJ8E6q1d7s1k2CCePNIr2t0gaOemFzHz9ZdaFJlrl6JwWQPm07cjtg8itmOwKGiW4NFmnPMLXN7I4-NxcfZw62yZMDhmiG9V5hooqFN3QSkZzgKUr3MBooUKR/s1600/dw3.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;343&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiN_xaAyeQEUxn4X-DyY0ErJ8E6q1d7s1k2CCePNIr2t0gaOemFzHz9ZdaFJlrl6JwWQPm07cjtg8itmOwKGiW4NFmnPMLXN7I4-NxcfZw62yZMDhmiG9V5hooqFN3QSkZzgKUr3MBooUKR/s400/dw3.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Now opens the  Genexus Web Start Deployment window,  change &lt;b&gt;VM:&lt;/b&gt; to &lt;i&gt;Sun&lt;/i&gt;, specify a name in &lt;b&gt;Application name:&lt;/b&gt;, I used again &lt;i&gt;chequeodesatendido&lt;/i&gt;, now click on &lt;b&gt;Build Archives&lt;/b&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX2MJdmZRYICrwVpjVvFocNRegmzXNtWyhjwDAF5TxK4M-BqrMZRgu-aUjg1q52OsOG7pjd0-tgp9y4HO4Ty1FBcgVmau9MCRmgFEvh-XfZ3fZtcKg6wGCrrrfGlmu6tOpzpzm7QnQw_i-/s1600/gxwsd1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX2MJdmZRYICrwVpjVvFocNRegmzXNtWyhjwDAF5TxK4M-BqrMZRgu-aUjg1q52OsOG7pjd0-tgp9y4HO4Ty1FBcgVmau9MCRmgFEvh-XfZ3fZtcKg6wGCrrrfGlmu6tOpzpzm7QnQw_i-/s400/gxwsd1.png&quot; width=&quot;385&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Now, if all went well, we should have all the files needed to run our program in the directory you specified in the third window of the Genexus Deployment Wizard. We should have a &lt;i&gt;Shared&lt;/i&gt; folder and another with the name you specified in the &lt;b&gt;Application name:&lt;/b&gt; in the GeneXus Web Start Deployment. Create a folder named &lt;i&gt;reportes&lt;/i&gt;, which is where we&#39;ll ask our automata to send its reports.&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga8H7-5P1wwlM36ezaz8IWxo5_Qd3m-ckW1aRf095pW9Y2trqFBRroedikGVbJma4PH1HsjXw78rlWuQlRr5Ce3tIZMwsThyo8OJ41hCtv7VAvTxxVmg6E-A_Zz2VAgFi2NAFh56uYSbiC/s1600/carpeta.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;372&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga8H7-5P1wwlM36ezaz8IWxo5_Qd3m-ckW1aRf095pW9Y2trqFBRroedikGVbJma4PH1HsjXw78rlWuQlRr5Ce3tIZMwsThyo8OJ41hCtv7VAvTxxVmg6E-A_Zz2VAgFi2NAFh56uYSbiC/s400/carpeta.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;h3&gt;






&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Last actions&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;From here, in theory, we are able to test our automata, but there are still a couple of details that the wizard didn&#39;t cover, no idea why. For some reason the wizard doesn&#39;t copy the package &lt;b&gt;iText.jar&lt;/b&gt; that is necessary to generate the report, so we must copy it manually from our KB. Copy it from the folder&amp;nbsp;JavaModel on the KB&amp;nbsp;to Shared on our deployment.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;Under Windows 7, I gess it&#39;s should be the same under Vista, at the first run the progam attempts to copy&amp;nbsp;the file &lt;b&gt;winjutil.dll &lt;/b&gt;to the &lt;i&gt;bin&lt;/i&gt; folder of the &lt;b&gt;JRE&lt;/b&gt;, but will fail due to permissions. There are two ways to solve this problem, the first is run once our project as Administrator, the other is to copy the file from the KB &lt;i&gt;JavaModel&lt;/i&gt; our JRE&#39;s &lt;i&gt;bin&lt;/i&gt; folder.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKblpjqe1JM8iz3zriElWCT-WMQrR7TuhTKlAH4FCpMbFtfvHbZMYileZb6jpVH7MUYOpgC-27gvpZhljJQe1NwLV4ppijz6c2z1UZASF23KjHfdDyByH5YH4AR4IbzkpJjzvUJniEfFK1/s1600/errorpermiso.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;215&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKblpjqe1JM8iz3zriElWCT-WMQrR7TuhTKlAH4FCpMbFtfvHbZMYileZb6jpVH7MUYOpgC-27gvpZhljJQe1NwLV4ppijz6c2z1UZASF23KjHfdDyByH5YH4AR4IbzkpJjzvUJniEfFK1/s400/errorpermiso.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;h3&gt;






&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Testing the automata&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Create a file names &amp;nbsp;named &lt;b&gt;test.cmd&lt;/b&gt;&amp;nbsp;and add the following code:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;@echo off

rem reemplazamos los backslach &quot;/&quot; de la fecha por el signo menos &quot;-&quot;
for /f &quot;tokens=1-3 delims=/&quot; %%a in (&quot;%date%&quot;) do set FECHA=%%a-%%b-%%c
set ARCHIVO_SALIDA=cr_%FECHA%
set DIRECTORIO_SALIDA=%CD%\reportes
set GXCLASSPATH=&quot;shared/.;shared/gxclassp.jar;shared/iText.jar;chequeodesatendido/chequeodesatendido_GXWS.jar&quot;

java -cp %GXCLASSPATH% achequeodesatendido &quot;%FECHA%&quot; &quot;%FECHA%&quot; &quot;%DIRECTORIO_SALIDA%\%ARCHIVO_SALIDA%&quot;

&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Execute &lt;b&gt;test.cmd&lt;/b&gt;, after that whe should have a PDF file in the &lt;i&gt;reportes &lt;/i&gt;folder.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;That&#39;s all for the first issue, the second part in a couple of days.&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://patotech.blogspot.com/feeds/1404358061026423695/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1381165230718116833/1404358061026423695' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default/1404358061026423695'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default/1404358061026423695'/><link rel='alternate' type='text/html' href='http://patotech.blogspot.com/2012/04/automata-with-genexus-ev1-on-linux-and.html' title='Automata with GeneXus Ev1 on Linux and Windows, and I'/><author><name>Patricio Diaz</name><uri>http://www.blogger.com/profile/15817672756742645565</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7A1qdDgDg_lcG8Wp2kjTgLghC-dajWfek8pz9zJMe1IQg4yUgFvinmP7D_p8BvuPAbbPHLNRL8gEIIHKoLZqTBxYs0U4ciBX5pfN_HKKxGxCu8pma9oTmJgq5ZdgiyBBAyW6QVsr5DGtb/s72-c/crear_kb.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1381165230718116833.post-1732457076121970290</id><published>2012-04-16T23:06:00.001-04:00</published><updated>2016-04-13T16:42:47.344-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="automatización"/><category scheme="http://www.blogger.com/atom/ns#" term="genexus"/><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="windows"/><title type='text'>Autómatas con Genexus Ev1 en Linux y Windows, y I</title><content type='html'>&lt;div style=&quot;text-align: right;&quot;&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif; font-size: x-small;&quot;&gt;&lt;a href=&quot;http://patotech.blogspot.com/2012/04/automata-with-genexus-ev1-on-linux-and.html&quot;&gt;Versión en inglés&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Hoy empezaré una serie de cuatro publicaciones en las que trataré de dar un vistazo a como programar un autómata en Genexus Ev1, ejecutarlo periódicamente en Linux y Windows, enviar logs y/o reportes resultantes por mail.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Esta técnica la habíamos utilizado en producción en una de las empresas donde trabajé como desarrollador para ejecutar unos procesos de verificación de integridad de datos.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;En esta primera entrega abordaremos la creación del autómata con Genexus Evolution 1 y el generador Java para Windows, aunque en realidad se podría programar con cualquier lenguaje que pueda arrojarnos un PDF con el nombre y en el directorio que especifiquemos.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;En la segunda entrega nos ocuparemos de hacerlo correr periódicamente bajo Linux utilizando nada mas que las aplicaciones GNU estándar que vienen con las mayoría de las distribuciones.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;En la tercera entrega haremos lo mismo pero bajo Windows, utilizando algunas aplicaciones de terceros para lograr el mismo efecto que en Linux.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;En la cuarta y última entrega modificaremos el script para Linux para utilizar las mismas aplicaciones que utilizamos en Windows, como un ejercicio de adaptación de una plataforma a otra.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;h2&gt;



















&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif; font-size: x-large;&quot;&gt;Requerimientos del autómata&lt;/span&gt;&lt;/h2&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Necesitamos crear un programa sin interfaz de usuario, que reciba parámetros desde la linea de comandos, cree archivos en un directorio pasado por parámetro, su salida vaya como texto a la salida estándar del SO.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;El acceso a bases de datos u otros procedimientos dependerá en cada caso que queramos implementar esta técnica, por lo que son opcionales como requerimiento.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;h2&gt;




















&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif; font-size: x-large;&quot;&gt;Manos a la obra&lt;/span&gt;&lt;/h2&gt;
&lt;h3&gt;



















&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Procedimiento principal&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Como primer paso debemos crear una KB en Genexus. A los efectos de este proyecto debemos elegir&amp;nbsp;&lt;i&gt;Java Environment&lt;/i&gt; en&lt;b&gt; Prototyping Environment&lt;/b&gt; y en &lt;b&gt;target&lt;/b&gt; elegimos &lt;i&gt;Win&lt;/i&gt;, el resto de los detalles no son relevantes pero para seguir el ejemplo sería recomendable nombrar a la kb &lt;i&gt;chequeodesatendido&lt;/i&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7A1qdDgDg_lcG8Wp2kjTgLghC-dajWfek8pz9zJMe1IQg4yUgFvinmP7D_p8BvuPAbbPHLNRL8gEIIHKoLZqTBxYs0U4ciBX5pfN_HKKxGxCu8pma9oTmJgq5ZdgiyBBAyW6QVsr5DGtb/s1600/crear_kb.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;255&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7A1qdDgDg_lcG8Wp2kjTgLghC-dajWfek8pz9zJMe1IQg4yUgFvinmP7D_p8BvuPAbbPHLNRL8gEIIHKoLZqTBxYs0U4ciBX5pfN_HKKxGxCu8pma9oTmJgq5ZdgiyBBAyW6QVsr5DGtb/s400/crear_kb.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Ahora creamos un procedimiento llamado &lt;i&gt;chequeodesatendido&lt;/i&gt;, este será el procedimiento principal de nuestro autómata. En sus propiedades cambiamos &lt;b&gt;Main program&lt;/b&gt; a &lt;i&gt;True &lt;/i&gt;y &lt;b&gt;Call protocol &lt;/b&gt;a &lt;i&gt;Command line&lt;/i&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghoZVHhd3Jc87-pe4xFfgafPKyYLZ1elxqR0pQfvkK-sbju5quuTJC7fofaxEIKV9loZx58E_sLb2Sbo4IiP1NaZS3T-GpEQFzU9k-Y4wc7VYC-ZxOgs2ToKfl1fBqTdAKTOtZ7onga1Xe/s1600/procedimiento_prop.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghoZVHhd3Jc87-pe4xFfgafPKyYLZ1elxqR0pQfvkK-sbju5quuTJC7fofaxEIKV9loZx58E_sLb2Sbo4IiP1NaZS3T-GpEQFzU9k-Y4wc7VYC-ZxOgs2ToKfl1fBqTdAKTOtZ7onga1Xe/s400/procedimiento_prop.jpg&quot; width=&quot;269&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Agregamos algo de código:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;b&gt;Rules&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;parm(in:&amp;amp;date_ini, in:&amp;amp;date_end, in:&amp;amp;filename);
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;b&gt;Source&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;if &amp;amp;date_ini.IsEmpty() or &amp;amp;date_end.IsEmpty() or &amp;amp;filename.IsEmpty() 
  msg(&quot;Faltan parametros.&quot;)
  msg(&quot;Se debe proveer fecha inicial, fecha final y nombre del archivo de salida&quot;)
endif

msg(&quot;date ini: &quot; + &amp;amp;date_ini.ToFormattedString() + 
  &quot; | date_end: &quot; + &amp;amp;date_end.ToFormattedString() + 
  &quot; | filename: &quot; + &amp;amp;filename
)

reporte.call(&amp;amp;date_ini, &amp;amp;date_end, &amp;amp;filename)
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Como puede verse el código es bastante simple, solo a modo de ejemplo. La salida de msg va a la consola, la que bajo Linux puede redirigirse fácilmente hacia un archivo, bajo Windows no encuentro aún la forma de hacer lo mismo.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Aquí es donde debemos ejecutar o llamar al código que realice alguna verificación, corrección, cierre, etc. sobre nuestros datos.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;










&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif; font-size: large;&quot;&gt;Reporte&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Creamos un procedimiento llamado &lt;i&gt;reporte y modificamos sus propiedades&lt;/i&gt;. Por casualidad las propiedades coinciden con el procedimiento anterior,&amp;nbsp;&amp;nbsp;ponemos&lt;/span&gt;

&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;b&gt;Main program&lt;/b&gt;&amp;nbsp;a&amp;nbsp;&lt;i&gt;True&amp;nbsp;&lt;/i&gt;y&amp;nbsp;&lt;b&gt;Call protocol&amp;nbsp;&lt;/b&gt;a&amp;nbsp;&lt;i&gt;Command line.&amp;nbsp;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;b&gt;Rules&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;parm(in:&amp;amp;date_ini, in:&amp;amp;date_end, in:&amp;amp;filename);
output_file(&amp;amp;filename, &#39;PDF&#39;);
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;b&gt;Source&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush:text&quot;&gt;print printBlock1
return
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;b&gt;Layout&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Para nuestro ejemplo sencillamente creamos una banda llamada &lt;i&gt;printBlock1&lt;/i&gt; y agregamos las variables que recibimos como parámetro, pero es aquí donde debe generarse el reporte que va a enviar como resultado de la ejecución del autómata.&lt;/span&gt;

&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;
&lt;/span&gt;

&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeGZNJEsPJWzJaPVe_L2x-5y55IimFDYwDPcZQw6PFkXJmDsiQPeo-hJ9Q5L0FJ3Uu2n6H0wE8ttxsYQIqDFLWRFLsewzpZjSNNM0ERVAbVd6AelnEHvdXv_AxgIRNZMEJLMUnohuYBDYi/s1600/layout.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;200&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgeGZNJEsPJWzJaPVe_L2x-5y55IimFDYwDPcZQw6PFkXJmDsiQPeo-hJ9Q5L0FJ3Uu2n6H0wE8ttxsYQIqDFLWRFLsewzpZjSNNM0ERVAbVd6AelnEHvdXv_AxgIRNZMEJLMUnohuYBDYi/s400/layout.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;
&lt;/span&gt;

&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Ahora definimos a&amp;nbsp;&lt;i&gt;chequeodesatendido&lt;/i&gt;&amp;nbsp;como el &lt;b&gt;Startup object&lt;/b&gt; y&amp;nbsp;construimos el proyecto.&lt;/span&gt;

&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;
&lt;/span&gt;

&lt;br /&gt;
&lt;h3&gt;












&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Lo desplegamos&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;La forma mas fácil de empaquetar los archivos necesarios para ejecutar nuestro proyecto es haciendo un &quot;deploy&quot;, así que ejecutamos el &lt;b&gt;Deployment Wizard&lt;/b&gt;.&amp;nbsp;&lt;/span&gt;

&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;
&lt;/span&gt;

&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSGGTswqxZ9tkxDlYqYGQgi-Q4g1gdXl1pqS3n1pYhDRp5iFIMDJqHYL9gme2468MyT66eH8kq_zP3LtVfy6G1f4pBfByQzU1oZley3JCY2aemr2WAfR5owNo9_ffygJGrDc7mIpaxceiC/s1600/deploymentwizard.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;335&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSGGTswqxZ9tkxDlYqYGQgi-Q4g1gdXl1pqS3n1pYhDRp5iFIMDJqHYL9gme2468MyT66eH8kq_zP3LtVfy6G1f4pBfByQzU1oZley3JCY2aemr2WAfR5owNo9_ffygJGrDc7mIpaxceiC/s400/deploymentwizard.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;
&lt;/span&gt;

&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;En la primera pantalla nos apareceran nuestros dos procedimientos en la lista &lt;b&gt;Available mains&lt;/b&gt;, los pasamos a la derecha a &lt;b&gt;Mains to deploy.&lt;/b&gt;&amp;nbsp;&lt;/span&gt;

&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;
&lt;/span&gt;

&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaVG0nC7H0Pnj7BUK9O-FayRC0QGiEUqyCq7McrmCqqY4m8BH9Z93XCWIYdjD6i1Onh4dElymQgGQL0Q5ZWJwxeiArp4w2IbqUG-uskapVilai63qVCUtMxQ8WT0Opqj2L0Ms8GbtlRTwi/s1600/dw1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;343&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaVG0nC7H0Pnj7BUK9O-FayRC0QGiEUqyCq7McrmCqqY4m8BH9Z93XCWIYdjD6i1Onh4dElymQgGQL0Q5ZWJwxeiArp4w2IbqUG-uskapVilai63qVCUtMxQ8WT0Opqj2L0Ms8GbtlRTwi/s400/dw1.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;
&lt;/span&gt;

&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Pasamos a la segunda pantalla y no tocamos nada ahí, solo le damos siguiente (next) para llegar a la tercera pantalla. Una vez ahí chequeamos el cuadro &lt;b&gt;Transfer location files&lt;/b&gt;&amp;nbsp;luego ingresamos un directorio donde el wizard colocará los archivos, por último le damos &lt;b&gt;Finish&lt;/b&gt;.&lt;/span&gt;

&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;
&lt;/span&gt;

&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiN_xaAyeQEUxn4X-DyY0ErJ8E6q1d7s1k2CCePNIr2t0gaOemFzHz9ZdaFJlrl6JwWQPm07cjtg8itmOwKGiW4NFmnPMLXN7I4-NxcfZw62yZMDhmiG9V5hooqFN3QSkZzgKUr3MBooUKR/s1600/dw3.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;343&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiN_xaAyeQEUxn4X-DyY0ErJ8E6q1d7s1k2CCePNIr2t0gaOemFzHz9ZdaFJlrl6JwWQPm07cjtg8itmOwKGiW4NFmnPMLXN7I4-NxcfZw62yZMDhmiG9V5hooqFN3QSkZzgKUr3MBooUKR/s400/dw3.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;
&lt;/span&gt;

&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Ahora se abrirá la pantalla del Genexus Web Start Deployment, cambiamos &lt;b&gt;VM:&lt;/b&gt; a &lt;i&gt;Sun&lt;/i&gt;, especificamos un nombre en &lt;b&gt;Application name:&lt;/b&gt;, yo usé de vuelta &lt;i&gt;chequeodesatendido&lt;/i&gt;, y por último le damos a &lt;b&gt;Build Archives&lt;/b&gt;.&lt;/span&gt;

&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;
&lt;/span&gt;

&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX2MJdmZRYICrwVpjVvFocNRegmzXNtWyhjwDAF5TxK4M-BqrMZRgu-aUjg1q52OsOG7pjd0-tgp9y4HO4Ty1FBcgVmau9MCRmgFEvh-XfZ3fZtcKg6wGCrrrfGlmu6tOpzpzm7QnQw_i-/s1600/gxwsd1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX2MJdmZRYICrwVpjVvFocNRegmzXNtWyhjwDAF5TxK4M-BqrMZRgu-aUjg1q52OsOG7pjd0-tgp9y4HO4Ty1FBcgVmau9MCRmgFEvh-XfZ3fZtcKg6wGCrrrfGlmu6tOpzpzm7QnQw_i-/s400/gxwsd1.png&quot; width=&quot;385&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;
&lt;/span&gt;

&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Ahora, si todo fue bien, deberíamos de tener todos los archivos necesarios para correr nuestro programa en el directorio que especificamos en la tercera ventana del Genexus Deployment Wizard.&lt;/span&gt;

&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;
&lt;/span&gt;

&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Deberíamos de tener una carpeta &lt;i&gt;Shared &lt;/i&gt;y otra con el nombre que especificamos en&amp;nbsp;&lt;b&gt;Application name:&lt;/b&gt;&amp;nbsp;en el&amp;nbsp;Genexus Web Start Deployment. Creamos la carpeta &lt;i&gt;reportes&lt;/i&gt;, que es donde le pediremos a nuestro autómata que envíe sus reportes.&lt;/span&gt;

&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;
&lt;/span&gt;

&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga8H7-5P1wwlM36ezaz8IWxo5_Qd3m-ckW1aRf095pW9Y2trqFBRroedikGVbJma4PH1HsjXw78rlWuQlRr5Ce3tIZMwsThyo8OJ41hCtv7VAvTxxVmg6E-A_Zz2VAgFi2NAFh56uYSbiC/s1600/carpeta.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;373&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga8H7-5P1wwlM36ezaz8IWxo5_Qd3m-ckW1aRf095pW9Y2trqFBRroedikGVbJma4PH1HsjXw78rlWuQlRr5Ce3tIZMwsThyo8OJ41hCtv7VAvTxxVmg6E-A_Zz2VAgFi2NAFh56uYSbiC/s400/carpeta.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;
&lt;/span&gt;

&lt;br /&gt;
&lt;h3&gt;










&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Últimas acciones&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;A partir de aquí teóricamente estamos en condiciones de probar nuestro autómata, pero todavía quedan un par de detalles que el wizard no cubrió, ni idea del porqué.&lt;/span&gt;

&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;
&lt;/span&gt;

&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Por algún motivo el wizard no copia el paquete iText.jar que es necesario para el reporte, por lo que debemos copiarlo manualmente de nuestra KB, de la carpeta JavaModel a la carpeta Shared de nuestro deployment.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Bajo Windows 7, supongo que debería de ser lo mismo con Vista, al ejecutar el programa por primera vez intentará copiar el archivo&amp;nbsp;&lt;b&gt;winjutil.dll&lt;/b&gt; a la carpeta &lt;i&gt;bin&lt;/i&gt; del JRE, pero fallará por cuestión de permisos. Hay dos formas de solucionar este inconveniente, el primero es ejecutar una vez nuestro proyecto como Administrador, la otra es copiar el archivo desde la carpeta &lt;i&gt;JavaModel &lt;/i&gt;de nuestra KB a la carpeta&amp;nbsp;&lt;i&gt;bin&lt;/i&gt; del JRE.&lt;/span&gt;

&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKblpjqe1JM8iz3zriElWCT-WMQrR7TuhTKlAH4FCpMbFtfvHbZMYileZb6jpVH7MUYOpgC-27gvpZhljJQe1NwLV4ppijz6c2z1UZASF23KjHfdDyByH5YH4AR4IbzkpJjzvUJniEfFK1/s1600/errorpermiso.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;215&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKblpjqe1JM8iz3zriElWCT-WMQrR7TuhTKlAH4FCpMbFtfvHbZMYileZb6jpVH7MUYOpgC-27gvpZhljJQe1NwLV4ppijz6c2z1UZASF23KjHfdDyByH5YH4AR4IbzkpJjzvUJniEfFK1/s400/errorpermiso.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;h3&gt;



















&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Probando nuestro autómata&lt;/span&gt;&lt;/h3&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Creamos un archivo &lt;b&gt;test.cmd&lt;/b&gt; y le agregamos el siguiente código:&lt;/span&gt;



&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;pre class=&quot;brush:text&quot;&gt;@echo off

rem reemplazamos los backslach &quot;/&quot; de la fecha por el signo menos &quot;-&quot;
for /f &quot;tokens=1-3 delims=/&quot; %%a in (&quot;%date%&quot;) do set FECHA=%%a-%%b-%%c
set ARCHIVO_SALIDA=cr_%FECHA%
set DIRECTORIO_SALIDA=%CD%\reportes
set GXCLASSPATH=&quot;shared/.;shared/gxclassp.jar;shared/iText.jar;chequeodesatendido/chequeodesatendido_GXWS.jar&quot;

java -cp %GXCLASSPATH% achequeodesatendido &quot;%FECHA%&quot; &quot;%FECHA%&quot; &quot;%DIRECTORIO_SALIDA%\%ARCHIVO_SALIDA%&quot;

&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Ejecutamos el archivo &lt;b&gt;test.cmd&lt;/b&gt;, luego deberíamos tener un archivo PDF en la carpeta &lt;i&gt;reportes&lt;/i&gt;.&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;times new roman&amp;quot;;&quot;&gt;&lt;span style=&quot;white-space: normal;&quot;&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;Eso es todo para la primera entrega.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;times new roman&amp;quot;;&quot;&gt;&lt;span style=&quot;white-space: normal;&quot;&gt;&lt;span style=&quot;font-family: &amp;quot;trebuchet ms&amp;quot; , sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;a class=&quot;GPCRQBSPB&quot; href=&quot;http://www.blogger.com/blogger.g?blogID=1381165230718116833&quot; kind=&quot;edit&quot; style=&quot;border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #1155cc; font-family: Arial, Helvetica, sans-serif; font-size: 13px; margin-bottom: 0px; margin-left: 0px; margin-right: 10px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: -webkit-left; text-decoration: none; vertical-align: baseline;&quot;&gt;Autómatas con Genexus Ev1 en Linux y Windows, y II&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://patotech.blogspot.com/feeds/1732457076121970290/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1381165230718116833/1732457076121970290' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default/1732457076121970290'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default/1732457076121970290'/><link rel='alternate' type='text/html' href='http://patotech.blogspot.com/2012/04/automatas-con-genexus-ev1-en-linux-y.html' title='Autómatas con Genexus Ev1 en Linux y Windows, y I'/><author><name>Patricio Diaz</name><uri>http://www.blogger.com/profile/15817672756742645565</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7A1qdDgDg_lcG8Wp2kjTgLghC-dajWfek8pz9zJMe1IQg4yUgFvinmP7D_p8BvuPAbbPHLNRL8gEIIHKoLZqTBxYs0U4ciBX5pfN_HKKxGxCu8pma9oTmJgq5ZdgiyBBAyW6QVsr5DGtb/s72-c/crear_kb.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1381165230718116833.post-6567405834201986005</id><published>2012-04-13T09:56:00.001-04:00</published><updated>2012-05-06T18:55:23.428-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="COM"/><category scheme="http://www.blogger.com/atom/ns#" term="friendly name"/><category scheme="http://www.blogger.com/atom/ns#" term="lazarus"/><category scheme="http://www.blogger.com/atom/ns#" term="windows"/><title type='text'>Enumerate COM ports in Windows with Lazarus</title><content type='html'>&lt;div style=&quot;text-align: right;&quot;&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif; font-size: x-small;&quot;&gt;&lt;a href=&quot;http://patotech.blogspot.com/2012/04/enumerar-puertos-seriales-en-windows.html&quot;&gt;Spanish version&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;As I have only USB ports on my development machine, is quite common at connecting a serial device that I have to go to the device manager to see in which COM port it was installed.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;I am developing an application that needs to access a serial device, so I need to get aware of the COM ports installed, either to indicate which to use or to verify the existence of which was already configured.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Researching a bit to not reinvent the wheel, I found this page: &lt;a href=&quot;http://www.lazarus.freepascal.org/index.php?topic=14313.0&quot;&gt;http://www.lazarus.freepascal.org/index.php?topic=14313.0&lt;/a&gt; which publishes three interesting functions.&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;The first function
GetSerialPortNames&amp;nbsp;is extracted from the package &amp;nbsp;synaser (http://synapse.ararat.cz/doku.php/download), returns the COM ports installed on the operating system (in my case: COM3 &amp;amp; COM17). More or less what I need, but only the list without identifying them.&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: delphi&quot;&gt;function GetSerialPortNames: string;
var
  reg: TRegistry;
  l, v: TStringList;
  n: integer;
begin
  l := TStringList.Create;
  v := TStringList.Create;
  reg := TRegistry.Create;
  try
{$IFNDEF VER100}
    reg.Access := KEY_READ;
{$ENDIF}
    reg.RootKey := HKEY_LOCAL_MACHINE;
    reg.OpenKeyReadOnly(&#39;HARDWARE\DEVICEMAP\SERIALCOMM&#39;);//, false);
    reg.GetValueNames(l);
    for n := 0 to l.Count - 1 do
      v.Add(reg.ReadString(l[n]));
    Result := v.CommaText;
  finally
    reg.Free;
    l.Free;
    v.Free;
  end;
end;
&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;The second function GetSerialPortRegNames is a variant of the first in that shows the devices installed (in my case: \ Device \ ProlificSerial0 &amp;amp; \ Device \USBSER000), which is also not very clear.&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: delphi&quot;&gt;function GetSerialPortRegNames: string;
var
  reg: TRegistry;
  l  : TStringList;
  n: integer;
begin
  l := TStringList.Create;
//  v := TStringList.Create;
  reg := TRegistry.Create;
  try
{$IFNDEF VER100}
    reg.Access := KEY_READ;
{$ENDIF}
    reg.RootKey := HKEY_LOCAL_MACHINE;
    reg.OpenKeyReadOnly(&#39;HARDWARE\DEVICEMAP\SERIALCOMM&#39;);//, false);
    reg.GetValueNames(l);
//    for n := 0 to l.Count - 1 do
//      l[n]:= l[n]+&#39;=&#39;+ reg.ReadString(l[n]);
    Result := l.CommaText;
  finally
    reg.Free;
    l.Free;
//    v.Free;
  end;
end;
&lt;/pre&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;span class=&quot;hps&quot; style=&quot;background-color: whitesmoke;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;The last function GetComPortList seeks information from another part of the registry and gets the common name (FriendlyName) of the device installed, which is what I&#39;m wanting.&lt;/span&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre class=&quot;brush: delphi&quot;&gt;function GetComPortList(PortList: TStrings): integer;
var
  i,idx: integer;
  SerPortNum: integer;
  Reg: TRegistry;
  EnumList: TStrings;
begin
  result := -1;
 
  if not CheckMinOS(osWin2k) then
   exit;
 
  Reg := TRegistry.Create();
  EnumList := TStringList.Create;
  try
    // Anzahl der Schnittstellen ermitteln
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    if Reg.OpenKeyReadOnly(&#39;\System\CurrentControlSet\Services\SerEnum\Enum&#39;) then
    begin
      SerPortNum := Reg.ReadInteger(&#39;Count&#39;);
 
      // Registry-Schlüssel der Schnittstellen zwischenspeichern
      for i:=0 to SerPortNum-1 do
        EnumList.Add(Reg.ReadString(inttostr(i)));
      Reg.CloseKey;
 
      // Daten der Schnittstellen ermitteln
      for i:=0 to SerPortNum-1 do
      begin
        // Schnittstellenname ermitteln (z.B. &#39;COM2&#39;)
        if Reg.OpenKeyReadOnly(&#39;\System\CurrentControlSet\Enum\&#39;+EnumList.Strings[i]+&#39;\Device Parameters&#39;) then
          idx := PortList.Add(Reg.ReadString(&#39;PortName&#39;)+&#39;=&#39;);
        Reg.CloseKey;
        // Bezeichnung wie im Gerätemanager ermitteln (z.B. &#39;USB Serial Port (COM2)&#39; )
        if Reg.OpenKeyReadOnly(&#39;\System\CurrentControlSet\Enum\&#39;+EnumList.Strings[i]) then
          PortList.ValueFromIndex[idx] := Reg.ReadString(&#39;FriendlyName&#39;);
        Reg.CloseKey;
      end;
    end;
  finally
    EnumList.Free;
    Reg.Free;
  end;
  result := PortList.Count;
end;
&lt;/pre&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;span class=&quot;hps&quot; style=&quot;background-color: whitesmoke;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;But there is a problem with this last feature, it&#39;s looking for the information only in &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\SerEnum&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;. To test I plugged in two serial devices, a generic USB-to-RS232 adapter and a Blu Samba Q cellphone. One of them appears on the sheet &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;SerEnum&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt; but the other appears under &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;USBSER&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;, which makes me assume that depending on how it is programmed the device driver, service name is arbitrary and therefore its location in the tree &lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt; too.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;To solve my problem I took as example the first and the third function and made my own. &lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: delphi&quot;&gt;function GetSerialPortNamesExt: string;
var
  reg  : TRegistry;
  l,v  : TStringList;
  n    : integer;
  pn,fn: string;
 
  function findFriendlyName(key: string; port: string): string;
  var
    r : TRegistry;
    k : TStringList;
    i : Integer;
    ck: string;
    rs: string;
  begin
    r := TRegistry.Create;
    k := TStringList.Create;
 
    r.RootKey := HKEY_LOCAL_MACHINE;
    r.OpenKeyReadOnly(key);
    r.GetKeyNames(k);
    r.CloseKey;
 
    try
      for i := 0 to k.Count - 1 do
      begin
        ck := key + k[i] + &#39;\&#39;; // current key
        // looking for &quot;PortName&quot; stringvalue in &quot;Device Parameters&quot; subkey
        if r.OpenKeyReadOnly(ck + &#39;Device Parameters&#39;) then
        begin
          if r.ReadString(&#39;PortName&#39;) = port then
          begin
            //Memo1.Lines.Add(&#39;--&amp;gt; &#39; + ck);
            r.CloseKey;
            r.OpenKeyReadOnly(ck);
            rs := r.ReadString(&#39;FriendlyName&#39;);
            Break;
          end // if r.ReadString(&#39;PortName&#39;) = port ...
        end  // if r.OpenKeyReadOnly(ck + &#39;Device Parameters&#39;) ...
        // keep looking on subkeys for &quot;PortName&quot;
        else // if not r.OpenKeyReadOnly(ck + &#39;Device Parameters&#39;) ...
        begin
          if r.OpenKeyReadOnly(ck) and r.HasSubKeys then
          begin
            rs := findFriendlyName(ck, port);
            if rs &amp;lt;&amp;gt; &#39;&#39; then Break;
          end; // if not (r.OpenKeyReadOnly(ck) and r.HasSubKeys) ...
        end; // if not r.OpenKeyReadOnly(ck + &#39;Device Parameters&#39;) ...
      end; // for i := 0 to k.Count - 1 ...
      result := rs;
    finally
      r.Free;
      k.Free;
    end; // try ...
  end; // function findFriendlyName ...
 
begin
  v      := TStringList.Create;
  l      := TStringList.Create;
  reg    := TRegistry.Create;
  Result := &#39;&#39;;
 
  try
    reg.RootKey := HKEY_LOCAL_MACHINE;
    if reg.OpenKeyReadOnly(&#39;HARDWARE\DEVICEMAP\SERIALCOMM&#39;) then
    begin
      reg.GetValueNames(l);
 
      for n := 0 to l.Count - 1 do
      begin
        pn := reg.ReadString(l[n]);
        fn := findFriendlyName(&#39;\System\CurrentControlSet\Enum\&#39;, pn);
        v.Add(pn + &#39; = &#39;+ fn);
      end; // for n := 0 to l.Count - 1 ...
 
      Result := v.CommaText;
    end; // if reg.OpenKeyReadOnly(&#39;HARDWARE\DEVICEMAP\SERIALCOMM&#39;) ...
  finally
    reg.Free;
    v.Free;
  end; // try ...
end;
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://patotech.blogspot.com/feeds/6567405834201986005/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1381165230718116833/6567405834201986005' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default/6567405834201986005'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default/6567405834201986005'/><link rel='alternate' type='text/html' href='http://patotech.blogspot.com/2012/04/enumerate-com-ports-in-windows-with.html' title='Enumerate COM ports in Windows with Lazarus'/><author><name>Patricio Diaz</name><uri>http://www.blogger.com/profile/15817672756742645565</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1381165230718116833.post-120582991378918922</id><published>2012-04-12T15:03:00.000-04:00</published><updated>2012-04-19T09:17:44.356-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="lazarus"/><category scheme="http://www.blogger.com/atom/ns#" term="windows"/><title type='text'>Enumerar puertos seriales en Windows con Lazarus</title><content type='html'>&lt;div style=&quot;text-align: right;&quot;&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif; font-size: x-small;&quot;&gt;&lt;a href=&quot;http://patotech.blogspot.com/2012/04/enumerate-com-ports-in-windows-with.html&quot;&gt;Versión en ingles&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Como tengo solo puertos USB en mi máquina de desarrollo, es muy común que al conectar un dispositivo serial tengo que ir al administrador de dispositivos para ver en que puerto COM se instaló.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Estoy desarrollando una aplicación que necesita acceder a un dispositivo serial, por lo que necesito hacerlo consciente de los puertos COM instalados, ya sea para indicar cual usar o para verificar la existencia del que ya fue configurado.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;Investigando un poco para no reinventar la rueda, me encontré con esta página:&amp;nbsp;&lt;a href=&quot;http://www.lazarus.freepascal.org/index.php?topic=14313.0&quot;&gt;http://www.lazarus.freepascal.org/index.php?topic=14313.0&lt;/a&gt;&amp;nbsp;donde se publican tres funciones muy interesantes.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;La primera función &lt;b&gt;GetSerialPortNames&lt;/b&gt; es extraida del paquete &lt;b&gt;synaser&lt;/b&gt; (&lt;/span&gt;&lt;a href=&quot;http://synapse.ararat.cz/doku.php/download&quot;&gt;http://synapse.ararat.cz/doku.php/download&lt;/a&gt;),&amp;nbsp;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;devuelve los puertos COM instalados en el sistema operativo (en mi caso: COM3 y COM17). Mas o menos lo que necesito, pero solo los enumera sin identificarlos.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: delphi&quot;&gt;function GetSerialPortNames: string;
var
  reg: TRegistry;
  l, v: TStringList;
  n: integer;
begin
  l := TStringList.Create;
  v := TStringList.Create;
  reg := TRegistry.Create;
  try
{$IFNDEF VER100}
    reg.Access := KEY_READ;
{$ENDIF}
    reg.RootKey := HKEY_LOCAL_MACHINE;
    reg.OpenKeyReadOnly(&#39;HARDWARE\DEVICEMAP\SERIALCOMM&#39;);//, false);
    reg.GetValueNames(l);
    for n := 0 to l.Count - 1 do
      v.Add(reg.ReadString(l[n]));
    Result := v.CommaText;
  finally
    reg.Free;
    l.Free;
    v.Free;
  end;
end;
&lt;/pre&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;La segunda función &lt;b&gt;GetSerialPortRegNames&lt;/b&gt; es una variante de la primera en la que se muestra el dispositivo instalado en si (en mi caso:&amp;nbsp;\Device\ProlificSerial0 y&amp;nbsp;\Device\USBSER000), lo que&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;tampoco&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;es muy claro.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: delphi&quot;&gt;function GetSerialPortRegNames: string;
var
  reg: TRegistry;
  l  : TStringList;
  n: integer;
begin
  l := TStringList.Create;
//  v := TStringList.Create;
  reg := TRegistry.Create;
  try
{$IFNDEF VER100}
    reg.Access := KEY_READ;
{$ENDIF}
    reg.RootKey := HKEY_LOCAL_MACHINE;
    reg.OpenKeyReadOnly(&#39;HARDWARE\DEVICEMAP\SERIALCOMM&#39;);//, false);
    reg.GetValueNames(l);
//    for n := 0 to l.Count - 1 do
//      l[n]:= l[n]+&#39;=&#39;+ reg.ReadString(l[n]);
    Result := l.CommaText;
  finally
    reg.Free;
    l.Free;
//    v.Free;
  end;
end;
&lt;/pre&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;La última función&amp;nbsp;&lt;b&gt;GetComPortList&lt;/b&gt;&lt;/span&gt; &lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;busca la información en otra parte del registro y obtiene el nombre común (FriendlyName) del puerto instalado, que es&amp;nbsp;justamente&amp;nbsp;lo que estoy queriendo.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: delphi&quot;&gt;function GetComPortList(PortList: TStrings): integer;
var
  i,idx: integer;
  SerPortNum: integer;
  Reg: TRegistry;
  EnumList: TStrings;
begin
  result := -1;

  if not CheckMinOS(osWin2k) then
   exit;

  Reg := TRegistry.Create();
  EnumList := TStringList.Create;
  try
    // Anzahl der Schnittstellen ermitteln
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    if Reg.OpenKeyReadOnly(&#39;\System\CurrentControlSet\Services\SerEnum\Enum&#39;) then
    begin
      SerPortNum := Reg.ReadInteger(&#39;Count&#39;);

      // Registry-Schlüssel der Schnittstellen zwischenspeichern
      for i:=0 to SerPortNum-1 do
        EnumList.Add(Reg.ReadString(inttostr(i)));
      Reg.CloseKey;

      // Daten der Schnittstellen ermitteln
      for i:=0 to SerPortNum-1 do
      begin
        // Schnittstellenname ermitteln (z.B. &#39;COM2&#39;)
        if Reg.OpenKeyReadOnly(&#39;\System\CurrentControlSet\Enum\&#39;+EnumList.Strings[i]+&#39;\Device Parameters&#39;) then
          idx := PortList.Add(Reg.ReadString(&#39;PortName&#39;)+&#39;=&#39;);
        Reg.CloseKey;
        // Bezeichnung wie im Gerätemanager ermitteln (z.B. &#39;USB Serial Port (COM2)&#39; )
        if Reg.OpenKeyReadOnly(&#39;\System\CurrentControlSet\Enum\&#39;+EnumList.Strings[i]) then
          PortList.ValueFromIndex[idx] := Reg.ReadString(&#39;FriendlyName&#39;);
        Reg.CloseKey;
      end;
    end;
  finally
    EnumList.Free;
    Reg.Free;
  end;
  result := PortList.Count;
end;
&lt;/pre&gt;
&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;Pero hay un problema con esta última función, busca la información solo en&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\SerEnum&lt;/span&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;. Para probar conecté dos dispositivos seriales un adaptador USB-RS232 genérico y un celular Blu Samba Q, uno de ellos figura en la hoja SerEnum pero la otra aparece bajo UsbSer, lo que me hace suponer que dependiendo de cómo está programado el driver del dispositivo, el nombre del servicio que los controla es arbitrario por lo tanto su ubicación en el árbol&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services también.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;Para resolver mi problema tomé como ejemplo la primera y la tercera función e hice la mía propia.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: delphi&quot;&gt;function GetSerialPortNamesExt: string;
var
  reg  : TRegistry;
  l,v  : TStringList;
  n    : integer;
  pn,fn: string;

  function findFriendlyName(key: string; port: string): string;
  var
    r : TRegistry;
    k : TStringList;
    i : Integer;
    ck: string;
    rs: string;
  begin
    r := TRegistry.Create;
    k := TStringList.Create;

    r.RootKey := HKEY_LOCAL_MACHINE;
    r.OpenKeyReadOnly(key);
    r.GetKeyNames(k);
    r.CloseKey;

    try
      for i := 0 to k.Count - 1 do
      begin
        ck := key + k[i] + &#39;\&#39;; // current key
        // looking for &quot;PortName&quot; stringvalue in &quot;Device Parameters&quot; subkey
        if r.OpenKeyReadOnly(ck + &#39;Device Parameters&#39;) then
        begin
          if r.ReadString(&#39;PortName&#39;) = port then
          begin
            //Memo1.Lines.Add(&#39;--&amp;gt; &#39; + ck);
            r.CloseKey;
            r.OpenKeyReadOnly(ck);
            rs := r.ReadString(&#39;FriendlyName&#39;);
            Break;
          end // if r.ReadString(&#39;PortName&#39;) = port ...
        end  // if r.OpenKeyReadOnly(ck + &#39;Device Parameters&#39;) ...
        // keep looking on subkeys for &quot;PortName&quot;
        else // if not r.OpenKeyReadOnly(ck + &#39;Device Parameters&#39;) ...
        begin
          if r.OpenKeyReadOnly(ck) and r.HasSubKeys then
          begin
            rs := findFriendlyName(ck, port);
            if rs &amp;lt;&amp;gt; &#39;&#39; then Break;
          end; // if not (r.OpenKeyReadOnly(ck) and r.HasSubKeys) ...
        end; // if not r.OpenKeyReadOnly(ck + &#39;Device Parameters&#39;) ...
      end; // for i := 0 to k.Count - 1 ...
      result := rs;
    finally
      r.Free;
      k.Free;
    end; // try ...
  end; // function findFriendlyName ...

begin
  v      := TStringList.Create;
  l      := TStringList.Create;
  reg    := TRegistry.Create;
  Result := &#39;&#39;;

  try
    reg.RootKey := HKEY_LOCAL_MACHINE;
    if reg.OpenKeyReadOnly(&#39;HARDWARE\DEVICEMAP\SERIALCOMM&#39;) then
    begin
      reg.GetValueNames(l);

      for n := 0 to l.Count - 1 do
      begin
        pn := reg.ReadString(l[n]);
        fn := findFriendlyName(&#39;\System\CurrentControlSet\Enum\&#39;, pn);
        v.Add(pn + &#39; = &#39;+ fn);
      end; // for n := 0 to l.Count - 1 ...

      Result := v.CommaText;
    end; // if reg.OpenKeyReadOnly(&#39;HARDWARE\DEVICEMAP\SERIALCOMM&#39;) ...
  finally
    reg.Free;
    v.Free;
  end; // try ...
end;
&lt;/pre&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;La función busca los puertos COM enumerados en&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace; font-size: x-small;&quot;&gt;HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM&lt;/span&gt;, &lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;luego busca recursivamente &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;en&lt;/span&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace; font-size: x-small;&quot;&gt;HKEY_LOCAL_MACHINE\System\CurrentControlSet\Enum\&lt;/span&gt; &lt;span style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&gt;por el nombre común (FriendlyName) del dispositivo. Devuelve algo así:&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&quot;COM3 = Prolific USB-to-Serial Comm Port (COM3)&quot;,&quot;COM17 = MTK6225 USB Modem Driver (COM17)&quot;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://patotech.blogspot.com/feeds/120582991378918922/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1381165230718116833/120582991378918922' title='1 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default/120582991378918922'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default/120582991378918922'/><link rel='alternate' type='text/html' href='http://patotech.blogspot.com/2012/04/enumerar-puertos-seriales-en-windows.html' title='Enumerar puertos seriales en Windows con Lazarus'/><author><name>Patricio Diaz</name><uri>http://www.blogger.com/profile/15817672756742645565</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1381165230718116833.post-8024024850325880111</id><published>2011-06-05T19:01:00.000-04:00</published><updated>2011-06-05T19:01:32.787-04:00</updated><title type='text'>GPU baratos estan volviendo inútiles contraseñas seguras</title><content type='html'>Piensa que su contraseña de ocho caracteres consistente en caracteres en minúsculas, caracteres en mayúsculas y una rociada de números es suficientemente fuerte para protegerlo de un ataque de fuerza bruta.&lt;br /&gt;
Pienselo de nuevo!&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://twitter.com/#%21/jonhoneyball&quot; target=&quot;_blank&quot;&gt;Jon Honeyball&lt;/a&gt;, escribiendo para &lt;a href=&quot;http://www.pcpro.co.uk/&quot; target=&quot;_blank&quot;&gt;PC Pro&lt;/a&gt;, tiene una pieza sobria sobre &lt;a href=&quot;http://www.pcpro.co.uk/blogs/2011/06/01/how-a-cheap-graphics-card-could-crack-your-password-in-under-a-second/&quot;&gt;como GPU modernas pueden ser aprovechadas como una poderosa herramienta contra contraseñas&lt;/a&gt; que antes eran consideradas a salvo de ataques de fuerza bruta. &lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://www.golubev.com/files/ighashgpu/ighashgpu_q6600_5970.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;172&quot; src=&quot;http://www.golubev.com/files/ighashgpu/ighashgpu_q6600_5970.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Tome una GPU barata (como la Radeon HD 5770) y la herramienta  revienta contraseñas gratuita potenciada por GPU &#39;ighashgpu&#39;  (http://www.golubev.com/hashgpu.htm) y poseerá una magra y malvada  máquina de reventar contraseñas. Que tan magra y malvada? Bastante:&lt;br /&gt;
&lt;blockquote&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;Los  resultados son alarmantes. Trabajando contra contraseñas de login NTLM,  una contraseña &quot;fjR8n&quot; puede ser rota en la CPU en 24 segundos, a una  tasa de 9.7 millones de suposiciones de contraseña por segundo. En la  GPU, toma menos de un segundo a una tasa de 3.300 millones de  contraseñas por segundo.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: x-small;&quot;&gt;Incremente la contraseña a 6 caracteres  (pYDbL6), y la CPU se toma 1 hora y 30 minutos contra solo cuatro  segundos el la GPU. Continue a 7 caracteres (fh0GH5h), y la CPU  machacará por 4 días, contra unos francamente preocupantes 17 minutos y  30 segundos para la GPU.&lt;/span&gt;&lt;/blockquote&gt;Se pone peor. Tire una  contraseña de nueve caracteres, aleatoria mazclando entre  mayúsculas-minúsculas, y mientras una CPU tomaría unos abrumadores 43  años en romper esto, la GPU lo haría en 48 días.&lt;br /&gt;
&lt;br /&gt;
Sin  duda poniendo símbolos ahi dentro lo mantiene seguro, cierto? Equivocado!  Tome una contraseña consistente en siete caracteres, contraseñas  aleatorias mezclando entre mayúsculas-minúsculas/símbolos como &quot;F6&amp;amp;B is&quot; (note el espacio), eso debe ser dificil para un ataque de fuerza bruta, correcto? Una CPU tomará unos 75 días para recorrer a traves de las posibilidades, mientras una GPU se hace con ella en 7 horas.&lt;br /&gt;
&lt;br /&gt;
Cual es la solución?. Bueno, Honeyball no lo sabe, y tampoco yo para ser perfectamente honesto. Lo que si se es que esto es una advertencia, y una que debe tomerse en serio. A menis que estemos dispuestos a pasarnos a contraseñas de 15-16 caracteres aleatorios, entre mayúsculas, minúsculas y símbolos (las que terminaran en notas PostIt), las contraseñas pronto solo ofreceran protección contra gente honesta.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Esta es una traducción de este artículo: &lt;a href=&quot;http://www.zdnet.com/blog/hardware/cheap-gpus-are-rendering-strong-passwords-useless/13125&quot;&gt;Cheap GPUs are rendering strong passwords useless&lt;/a&gt;&lt;br /&gt;
Sugiero leer el artículo original por &lt;a href=&quot;https://twitter.com/#%21/jonhoneyball&quot; target=&quot;_blank&quot;&gt;Jon Honeyball&lt;/a&gt;, &lt;a href=&quot;http://www.pcpro.co.uk/blogs/2011/06/01/how-a-cheap-graphics-card-could-crack-your-password-in-under-a-second/&quot;&gt;How a cheap graphics card could crack your password in under a second&lt;/a&gt;.</content><link rel='replies' type='application/atom+xml' href='http://patotech.blogspot.com/feeds/8024024850325880111/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1381165230718116833/8024024850325880111' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default/8024024850325880111'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default/8024024850325880111'/><link rel='alternate' type='text/html' href='http://patotech.blogspot.com/2011/06/gpu-baratos-estan-volviendo-inutiles.html' title='GPU baratos estan volviendo inútiles contraseñas seguras'/><author><name>Patricio Diaz</name><uri>http://www.blogger.com/profile/15817672756742645565</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1381165230718116833.post-1906891485412019106</id><published>2008-10-07T16:19:00.010-04:00</published><updated>2008-10-08T09:32:06.949-04:00</updated><title type='text'>Cadenas, Tantras y Expresiones Regulares.</title><content type='html'>&lt;span style=&quot;font-family:arial;&quot;&gt;Es sabido que las famosas cadenas o tantras son uno de los tipos mas comunes de ataques basados en &lt;a style=&quot;font-family: arial;&quot; href=&quot;http://es.wikipedia.org/wiki/Ingenier%C3%ADa_social_%28seguridad_inform%C3%A1tica%29&quot;&gt;ingeniería social&lt;/a&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;, por cierto, quién no se pregunto alguna ves como es que los spamer consiguieron su dirección.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;En realidad no hece falta contar con programas sofisticados para procesar uno de estos emails, cargado con cientos de direcciones de correo, y hacer una list&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;a de ellas. Podríamos valernos de   &lt;span style=&quot;text-decoration: underline;font-family:arial;&quot; &gt; &lt;/span&gt;&lt;/span&gt;&lt;a style=&quot;font-family: arial;&quot; href=&quot;http://es.wikipedia.org/wiki/Expresi%C3%B3n_regular&quot;&gt;expresiones regulares&lt;/a&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;, que es una técnica para encontrar un patrones dentro de un texto dado, &lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;para extraerlas&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;.&lt;/span&gt;  &lt;span style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;&lt;br /&gt;Para demostrar el uso de expresiones regulares hice un programa que permite extraer coincidencias de un texto cualquiera. &lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;Puede bajarse de &lt;/span&gt;&lt;a style=&quot;font-family: arial;&quot; href=&quot;http://code.google.com/p/patotech/downloads/list&quot;&gt;aqui&lt;/a&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;&lt;br /&gt;El programa va a compañado de los códigos fuente, compila bien con Delphi 7. Necesita este &lt;a href=&quot;http://regexpstudio.com/TRegExpr/TRegExpr.html&quot;&gt;componente&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Podemos copiar y pegar contenido en el cuadro de entrada, o leerlo directamente de un archivo guardado, a tal efecto se puede hacer click derecho con el raton en cualquier parte de la ventana y aparecerá un menu con las opciones de leer desde o guardar a un archivo.&lt;br /&gt;&lt;br /&gt;No hay necesidad de preprocesar el cointenido a buscar, por ejemplo, podemos guardar una página web y leerla directamente a traves del menu.&lt;br /&gt;&lt;br /&gt;Las siguientes reglas permiten coincidir direcciones de correo, l&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;a explicación de la sintaxis de las mismas quedará para otro post&lt;/span&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;:&lt;span style=&quot;font-style: italic;font-family:courier new;&quot; &gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;br /&gt;&lt;ol style=&quot;font-style: italic; font-family: courier new;&quot;&gt;&lt;li&gt;[_a-zA-Z\d\-\.]+@[_a-zA-Z\d\-]+(\.[_a-zA-Z\d\-]+)+&lt;/li&gt;&lt;li&gt;\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}&lt;/li&gt;&lt;li&gt;([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)&lt;/li&gt;&lt;/ol&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt; &lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivZV0u7A1lI08Es0mOPqO02UZvj1ssleGfRJB0fxs9Lh2dPsqOTLYYBfnA2bQP6ltvsO_WBiL-ppyOcnWIc22ya6w0yFl0aWHUUwNJ4UJtF3IIRgywLZrJrjoNGY4xUx-YvuN7dL32hTzv/s1600-h/Principal.png&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivZV0u7A1lI08Es0mOPqO02UZvj1ssleGfRJB0fxs9Lh2dPsqOTLYYBfnA2bQP6ltvsO_WBiL-ppyOcnWIc22ya6w0yFl0aWHUUwNJ4UJtF3IIRgywLZrJrjoNGY4xUx-YvuN7dL32hTzv/s320/Principal.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5254529921300818898&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style=&quot;font-family:arial;&quot;&gt;En [1] colocamos la expresión regular, en [2] el contenido de algún email o texto que contenga direcciones de coreeo, luego presionamos Evaluar. Los resultados apareceran en [3].&lt;br /&gt;&lt;br /&gt;Debo aclarar que este programa en realidad puede extraer cualquier texto de acuerdo a la expresión regular que le introduzcamos, en este caso nos centramos en las direcciones de correo como demostración.&lt;br /&gt;&lt;br /&gt;Cada uno es libre de creer y hacer lo que mejor le parezca, mi sugerencia es que si vamos a enviar o reenviar uno de estos mails, nos tomemos el trabajo de eliminar las direcciones que acarrea el mail, o simplemente no caer en este tipo de juego.&lt;br /&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://patotech.blogspot.com/feeds/1906891485412019106/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1381165230718116833/1906891485412019106' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default/1906891485412019106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default/1906891485412019106'/><link rel='alternate' type='text/html' href='http://patotech.blogspot.com/2008/10/cadenas-tantras-y-expresiones-regulares.html' title='Cadenas, Tantras y Expresiones Regulares.'/><author><name>Patricio Diaz</name><uri>http://www.blogger.com/profile/15817672756742645565</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivZV0u7A1lI08Es0mOPqO02UZvj1ssleGfRJB0fxs9Lh2dPsqOTLYYBfnA2bQP6ltvsO_WBiL-ppyOcnWIc22ya6w0yFl0aWHUUwNJ4UJtF3IIRgywLZrJrjoNGY4xUx-YvuN7dL32hTzv/s72-c/Principal.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1381165230718116833.post-6841912095118850924</id><published>2008-09-22T22:28:00.002-04:00</published><updated>2008-09-22T22:41:22.812-04:00</updated><title type='text'>ETyC</title><content type='html'>&lt;span style=&quot;font-family: arial;&quot;&gt;Hoy inició la&lt;/span&gt;&lt;a style=&quot;font-family: arial;&quot; href=&quot;http://www.pol.una.py/etyc/&quot;&gt; Exposición de Tecnología y Ciencia&lt;/a&gt;&lt;span style=&quot;font-family: arial;&quot;&gt; (ETyC) edición 2008.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;La misma se lleva a cabo las instalaciones de la Facultad Politécnica en el Campus Universitario de San Lorenzo. El acceso es libre y gratuito.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;Cada día de la exposición tiene programadas &lt;/span&gt;&lt;a style=&quot;font-family: arial;&quot; href=&quot;http://www.pol.una.py/etyc/ConferenciasETyC.pdf&quot;&gt;conferencias&lt;/a&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;, charlas, cursos, encuentros, jornadas, talleres y concursos, para distintas áreas de interes, de las cuales solo algunas muy específicas tienen costo. No hay motivo para no ir dar una vuelta y participar de las actividades.  &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: arial;&quot;&gt;Para mas información y el cronograma de actividades, pueden visitar el sitio del evento.&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://patotech.blogspot.com/feeds/6841912095118850924/comments/default' title='Comentarios de la entrada'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/1381165230718116833/6841912095118850924' title='0 Comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default/6841912095118850924'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1381165230718116833/posts/default/6841912095118850924'/><link rel='alternate' type='text/html' href='http://patotech.blogspot.com/2008/09/etyc.html' title='ETyC'/><author><name>Patricio Diaz</name><uri>http://www.blogger.com/profile/15817672756742645565</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>