Mostrando las entradas con la etiqueta webdev. Mostrar todas las entradas
Mostrando las entradas con la etiqueta webdev. Mostrar todas las entradas

25.7.11

Corregir "warning" del timezone en PHP 5.3

Si actualizaron PHP en su servidor y ven millones de errores del timezone como este:

PHP Warning: mktime(): It is not safe to rely on the system's timezone settings. You 
are *required* to use the date.timezone setting or the date_default_timezone_set() function.
In case you used any of those methods and you are still getting this warning, you most likely
misspelled the timezone identifier. We selected 'America/Buenos_Aires' for 'EDT/-3.0/DST'
instead in page.php on line 1

Van a tener que configurar el parametro date.timezone en el archivo php.ini que este usando su servidor web (en mi caso esta en /etc/php.ini) y agregarle la zona correspondiente.

;;;;;;;;;;;;;;;;;;;
; Module Settings ;
;;;;;;;;;;;;;;;;;;;

[Date]
; Defines the default timezone used by the date functions
; http://www.php.net/manual/en/datetime.configuration.php#ini.date.timezone
date.timezone = America/Buenos_Aires

Si no saben en donde esta el archivo php.ini que tienen que modificar, pueden crear un archivo PHP con este codigo:

<?php phpinfo(); ?>

Y acceder a dicho archivo desde el navegador. Ahi van a encontrar la ruta al archivo php.ini del cual necesitan modificar el timezone.

24.5.11

Como cambiar/resetear el password de administrador en Django

Otra vez me olvide la contraseña del administrador de un sitio que hace meses no trabajo y necesito cambiarla por una nueva. Parados en el directorio en donde tenemos nuestra aplicacion vamos a iniciar una 'shell' y hacer uso del modelo de usuarios:


caco@particula:~/dev/subs$ ./manage.py shell
Python 2.6.6 (r266:84292, Sep 15 2010, 15:52:39)
Type "copyright", "credits" or "license" for more information.

>>> from django.contrib.auth.models import User
>>> usuarios = User.objects.all()
>>> usuarios
[<User: caco>]
>>> usuarios[0].set_password('nuev0passwowd')
>>> usuarios[0].save()


Resumiendo: instanciamos el modelo User, traemos todos los usuarios, seteamos un nuevo password para el primer usuario ([0]) y guardamos en la base de datos la informacion sobre este usuario.

23.5.11

Seguimiento del servicio gratuito de SMS Online y la Aplicacion SMS Online de Personal

Un poquito cansado de que no funcione el servicio de Personal para enviar SMS gratuitos por internet decidi investigar un poco y escribir al respecto notificando a Personal via Twitter cuando el servicio no funcionaba, por que y como detectar cuando esto pasaba.

El problema esta de tu lado

De todas las respuestas de Personal (de 9 personas diferentes que manejan su cuenta de Twitter) ninguna se hacia cargo del problema. Las soluciones que me brindaban tenian que ver con mi navegador, cosas como borrar el historial o las cookies. La mas graciosa fue "Intenta actualizar la pagina reiteradas veces": obvio, si tienen un problema de disponibilidad en algun momento que no este saturado el servicio me va a tocar pero la idea es no tener que pasar por eso (sobre todo como cliente de una compañia de comunicaciones).

Ante este tipo de respuestas, empeze a enviar la entrada en mi blog sobre el analisis del problema y comenzaron a responderme que iban a revisar el problema y al parecer lo hicieron.

Aqui no paso nada

En estos momentos, la pagina de personal para enviar mensajes por internet dejo de mostrar el error de SQL que mostraba cuando no funcionaba PERO el sitio sigue sin ser capaz de generar el CAPTCHA para enviar los mensajes desde la web.



Quiza un error no visible haga creer al usuario promedio que es su culpa, o culpa "del internet", que el sitio no funcione pero a mi me gusta investigar y estos dias tengo mucho tiempo libre!

La aplicacion online

En una de las respuestas de Personal me recomiendan utilizar la "Aplicacion SMS Online", asi que la descargue e instale en una de mis maquinas virtuales. Lamentablemnete la aplicacion no funciono y la solucion que me dio Personal fue reinstalar, el mambo de las cookies y demas.

Nuevamente, me pongo a ver en detalle que es lo que no funciona. Haciendo pasar la aplicacion de Personal por un proxy veo que la aplicacion pide la siguiente URL:

http://www.personal.com.ar/smsonline/aplicacion/config/PersonalSMSOnline.txt

Que desde la aplicacion respondia con un error pero desde el navegador respondia:

Personal SMS Online
1.1.1
1.1.2
\nHay una nueva versión de\nAplicación Personal SMS Online


Haciendo un par de pruebas, pude hacer arrancar la aplicacion eliminando el User-agent de la peticion a esa URL. Una vez pasado este paso, la aplicacion funcionaba de manera "normal". Me alegre mucho, pero la alegria me duro poco y fue muy desmoralizante ver que la aplicacion de escritorio que te bajas de personal no es nada mas ni nada menos que un parser de la web de donde se envian los mensajes (para los no-tecnicos, usa la misma web sacando los datos que necesita para funcionar). Osea que si la web no anda, tampoco anda la aplicacion online.

Estamos en la misma, es casi imposible usar el servicio de las 21.00hs a 24.00hs y en las soluciones que plantean no se reconoce el problema real. Tampoco creo que los tecnicos de una empresa como Personal no sepan lo que pasa, pero como me comento otro usuario del servicio: "no van a arreglar algo que no les representa ganancias" y pareceria que tiene toda la razon.

Quiza alguien lea esto y piense que estoy "atacando" a Personal, pero la verdad es que estoy laburandoles gratis a ver si de alguna vez por todas este servicio (que un monton de gente usa y hasta escuche casos que fue crucial para elegir una compania de celular) funcione perfecto.

6.5.11

Pesima disponibilidad del servicio SMS Online de Personal para enviar mensajes por la web

Me gusta que en Personal se pueden mandar mensajes gratis desde la web a otro Personal; pero casi siempre tengo problemas para utilizar este servicio por errores en la carga completa de esta pagina.

El error visible


El error en concreto es de conexion con una base de datos MySQL:

Can't connect to local MySQL server through socket '/tmp/mysql.sock' (11)

Cada vez que aparece este error en la pagina, no se muestra el CAPTCHA y hace imposible completar el formulario correctamente para enviar un SMS desde la web. Probablemente el CAPTCHA se guarde en una base de datos MySQL y se verifique al suscribirse el formulario.



Interaccion con Personal

Cuando comente en Twitter un vez el problema y respondieron "Hubo tareas de mantenimiento, pero ya esta solucionado. Actualiza la pagina presionando F5 que se corrige!", pero el problema persiste. En otra ocasion, me recomendaron "dsd tu explorador ingresá a Herram/opc d internet tildar eliminar el historial de exploracion al salir, aplicar, aceptar, salir y actualizar la página." pero tampoco no funciono ya que claramente es un error del servidor.

UPDATE (mas "soluciones" que ofrece personal, obviamente no entienden el problema):

- 06/06/2011: Ni bien publique este articulos, negaron nuevamente el problema y me recomendaron hacer "Borrado de cache" [@PersonalAr].
- 15/05/2011: Hola! No tenemos reportado novedades.Probaste borrar el historial d navegación? Intentá actualizar la pag reiteradas veces. LM [@PersonalAr]
- 19/05/2011: Hola! Intentá eliminar el historial de navegación. Saludos! NM @PersonalAr

Analisis del servicio

Analizando un poco como funciona el sevicio, pude ver que hay dos servidores que tienen estos formularios para enviar los mensajes: sms1.personal.com.ar y sms2.personal.com.ar; ambos servidores tiran el mismo error en los mismos periodos de tiempo. Decidi hacer un script muy basico que se compruebe cada un minuto si cada uno de estos dos servidores da error o carga el formulario completo para enviar un mensaje y generar unos graficos para que se puedan ver los problemas de disponibilidad de este servicio.

Aca vemos, por ejemplo, un grafico de sms1.personal.com.ar del 03/05/2011 desde las 20hs hasta el final del dia. Los cuadrados indican si en ese minuto hubo un error o si el formulario se cargaba correctamente. Lo ideal seria que este TODO VERDE.


El script intenta acceder a la pagina "http://sms1.personal.com.ar/Mensajes/sms.php" y buscar en su contenido indicios del error de MySQL que se encuentra al principio de la pagina. Si el error existe no se muestra el CAPTCHA, por lo tanto no es posible completar el formulario para enviar el SMS y mi grafico lo muestra en rojo. Cuando no encuentra el error, asume que vamos a poder enviar un SMS y lo marca en verde.

Otro ejemplo del mismo servidor durante todo el dia 04/05/2011:




Que nos dicen los grafiquitos chulos?

Podemos ver que desde las 00hs hasta las 12hs el servicio es usable y estable. A partir de las 12hs comienza a tener problemas menores de disponibiliad y desde las 20hs hasta las 00hs es practicamente inusable.

Se podra implementar el mismo sistema sin utilizar una base de datos (solo datos en la sesion de usuario)? Agregando un servidor mas a los dos que tienen, alcanzara para resolver los problemas de disponibilidad de la noche?


Algunos usuarios afectados

Cuando empeze a buscar en Twitter y Google encontre un monton, algunos como para tener de referencia:

* https://twitter.com/aldulovato/status/66325916665655296
* https://twitter.com/lucianita88/status/66310154454433792
* https://twitter.com/dreamcoders/status/65945527312850944
* http://twitoaster.com/ea00d009/el-cant-connect-to-local-mysql-server-through-socket-tmpmysqlsock-11-de-la-web-de-personal-me-tiene-podrido-personal-fail/
* http://www.taringa.net/posts/ebooks-tutoriales/5539478/No-anda-la-pagina-de-sms-personal-_Solucion_.html

3.9.09

Redireccionar direccion sin www a direccion con www

Algunas personas se sienten incompletas sin las tres doble-v adelante de cualquier dominio a la hora de ver una pagina (no es mi caso) y para suplir esa irracional necesidad tenemos unas reglas de apache.

Supongamos que tenemos el dominio "direccion.com.ar" y queremos que cuando se ingresa la direccion "direccion.com.ar" o "www.direccion.com.ar" ambas apunten a "www.direccion.com.ar". La regla que necesitamos es:

RewriteEngine on
RewriteCond %{http_host} ^direccion.com.ar [NC]
RewriteRule ^(.*)$ http://www.direccion.com.ar/$1 [R=301,NC]

La podemos poner en el .htaccess o sobre la configuracion de apache para este dominio en particular. Ademas de cuestiones esteticas (con www, sin www), cuestiones de costumbre (esos bichos raros: "sin las www? creo que esta mal!") podemos usar esta regla para centralizar/unificar y evitar que un mismo contenido este en dos direcciones distintas. Entre otras cosas (que me da pereza comentar).

22.7.09

Colores en el diff de Subversion

Hay varias maneras de tener colores cuando hacemos 'svn diff', una de las mas simples y que no requiere instalar software adicional (como colordiff) es utilizando 'vim' de la siguiente forma:

svn diff | vim -R -

El resultado de este comando deberia resultar en algo parecido a esto:

30.1.09

Los "Tags" en lanacion.com estan de adorno

No se que hacen! Creo que no hacen nada y son para agregarle un par de palabras a la nota. Deberian comportarse de otra manera. No entiendo. Quiero tocarlos y que me lleven a notas con los mismos tags!

16.9.08

Escuchar Online

En la ultima semana estuve aprendiendo a usar Django, un framework web para Python. El sitio tiene unos scripts en Python que buscan referencias a archivos de audio, revisan los tags ID3 y siguiendo ciertos criterios los almacenan en la base de datos. La interface del usuario permite buscar temas de musica para escuchar y, en algunos casos, escuchar un CD entero de una banda (la funcionalidad que estaba buscando en un sitio que me habia gustado y le faltaba!). El desarrollo de la interface al usuario fue muy rapido (muy facil de integrar templates), el administrador que genera es util y la documentacion me fue llevando bien (pegue unos saltos en algunas partes que luego lamente!).

Ya hay una demo usable en http://escucharonline.homelinux.org/, de a poco estoy subiendole mas datos y correcciones. Y la eterna duda con el disenio.

Este fin de semana me voy de vacaciones asi que no voy a poder seguirlo mucho, seguro cuando vuelva voy a estar sediento de programar y kab00M: zombismo electronico.

1.9.08

Horror ancestral javascriptoso microsoftero

Estoy modificando un site para un laburo y en el codigo me encuentro con esto:

<script language="JavaScript1.2" fptype="dynamicanimation" src="file:///C:/Archivos%20de%20programa/Microsoft%20Office/Office10/fpclass/animate.js">
</script>

JASHKAJFHVSDQWDPOCXZXMVCNALuhGHTTT!!!

Cabe aclarar que el site es muy viejo y hecho "a la antigua" con FrontPage (que debe ser el causante de esa linea que se ve tan mal).

2.6.08

Generando ID unicos (UUID) en MySQL

La funcion UUID() de MySQL nos devuelve un Identificador Unico Universal que podemos utilizar como ID unico en nuestras aplicaciones.

Podemos probarlo ejecutando la siguiente consulta:

select uuid() as uid;

El resultado esta compuesto por 5 grupos de caracteres hexadecimales separados por un guion:


+--------------------------------------+
| uid |
+--------------------------------------+
| 107782ca-8250-102b-bae9-001a92ba7031 |
+--------------------------------------+


Si estan usando PHP pueden validar el UUID con la funcion ValidateMySqlUid();

Validando UUID de MySQL en PHP

Funcion de PHP para validar (regexp de fede) los IDs unicos generados por MySQL:
function ValidateMySqlUid($string) {
if (strlen($string) == 36) {
if (preg_match('/[0-9a-f]{8,8}-([0-9a-f]{4,4}-){3}[0-9a-f]{12,12}/', $string)) {
return true;
}
}
return false;
}

27.5.08

Eliminar directorios (y sus contenidos) en PHP

La funcion rmdir() de PHP solo elimina directorios que se encuentren vacios, lo cual hace un poco denso eliminar estructuras de directorios grandes y complejas. En el manual de PHP hay un comentario que contiene una funcion para eliminar directorios y sus contenidos de forma recursiva:

function rm_recursive($filepath) {
if (is_dir($filepath) && !is_link($filepath)) {
if ($dh = opendir($filepath)) {
while (($sf = readdir($dh)) !== false) {
if ($sf == '.' || $sf == '..') {
continue;
}
if (!rm_recursive($filepath.'/'.$sf)) {
throw new Exception($filepath.'/'.$sf.' could not be deleted.');
}
}
closedir($dh);
}
return rmdir($filepath);
}
return unlink($filepath);
}

La entrada de rmdir() en el manual de PHP tiene otras recetas similares a la que use anteriormente. Otros ejemplos usan glob() pero, al parecer, tarda mucho en soltar los archivos y esto puede generar problemas aleatorios con los permisos de los archivos. El comentario correspondiente a la funcion tambien expone que utilizar opendir() es mas rapido que glob().

19.3.08

Firebug en Firefox 3

Al fin, el Firebug era lo que me impedia moverme de Firefox2 al Firefox3. La version del Firebug 1.2.0a, todavia en estado alfa, se encuentra disponible en la seccion releases de la pagina de Firebug.

Para los que no conocen esta extension, les permite hacer Debug intensivo de paginas web monitoreando requests, modificando HTML y valores de CSS sobre la marcha (del lado del navegador), hacer debug de JavaScript y ejecutar JavaScript en una consola. Una vez que se lo comienza a usar se vuelve indispensable al punto que uno llega a decir que no puede trabajar sin el.

23.11.07

Cartelotes e Imagenes en Blogs

Me parece de muy mal gusto llenar las side-bars de los Blogs (en donde esta la info y el blogroll/links) con tiras y tiras de imagenes, aplicaciones inutiles y... mas imagenes! Quizas se deba a mi formacion web o al frecuenteo (???) en entornos geek-minimalisticos, haciendo que tenga una tendencia a apreciar las interfaces claras, limpias y que dicen lo que hacen. Menos marketing y mas realidad.

Eso si, no me producen tanta repulsion como los collages hechos con paint/photoshop usando colores fluo, dibujando flechas o tapando caras de personas. Eso excede el mal gusto y pasa a catalogarse como digital-grasa.

Right now, solo apruebo chirimbolos como Twitter. Hasta que algo me haga cambiar de opinion.

8.11.07

Como cambiar la página de Error 404 del Apache

Si queremos levantar un poco los ánimos de nuestros compañeros de la oficina cuando el error 404 acecha, nada mejor que armar una pagina personalizada de error:



Para hacerlo tenemos que editar el archivo de configuración httpd.conf del apache (en mi distribución se encuentra en /etc/apache/httpd.conf) y buscar siguiente linea:

ErrorDocument 404 /404.html

Seguramente este comentada (con un # adelante), hay que descomentarla. Una vez hecho esto, crear una página a gusto para mostrar el error 404. La llamamos "404.html" (como dice la línea anterior del archivo de configuración) y deberá estar ubicada en el DocumentRoot (/) del servidor apache. Si queremos saber en que ruta del disco se encuentra el DocumentRoot, alcanza con buscar esta linea en el archivo de configuración:

DocumentRoot "/var/www/localhost/htdocs"

Si quieren mantener un poco de la info que tira la página original 404 del servidor, tomen como ejemplo el archivo que viene originalmente con el server.

24.9.07

Eligiendo mal (bien) nombres de tablas y campos en MySQL

Durante el último desarrollo "grande" que estuve haciendo (un CMS) tuve un problema que me dieron ganas de golpearme cuando lo pude resolver. Elegí mal nombres de tablas y, luego, de campos, utilizando algunas de las palabras reservadas de MySQL. Con el posterior error de no renombrarlas ni bien me di cuenta de esto teniendo que escapar en las consultas algunas tablas y campos con "`".

Entre los nombres de tabla, use "schema" en donde la consulta:

SELECT * FROM schema;

Tiraba un error y, luego de insultar a medio mundo (un cuarto existente o otro cuarto no), me di cuenta que tenia que escapar la palabra reservada asi:

SELECT * FROM `schema`;

Aunque no afecta al funcionamiento de la aplicación que estamos desarrollando, si somos distraidos aveces podemos estar un rato hasta darnos cuenta que nos paso otra vez (si, aveces caigo en los mismos loops). Otro caso fue elegir como nombres de campo para definir el orden de elementos, el nombre "order".

A continuación, la lista de palabras reservadas para MySQL 5.0:




















































































ADD ALL ALTER
ANALYZE AND AS
ASC ASENSITIVE BEFORE
BETWEEN BIGINT BINARY
BLOB BOTH BY
CALL CASCADE CASE
CHANGE CHAR CHARACTER
CHECK COLLATE COLUMN
CONDITION CONSTRAINT CONTINUE
CONVERT CREATE CROSS
CURRENT_DATE CURRENT_TIME
CURRENT_TIMESTAMP
CURRENT_USER CURSOR DATABASE
DATABASES DAY_HOUR DAY_MICROSECOND
DAY_MINUTE DAY_SECOND DEC
DECIMAL DECLARE DEFAULT
DELAYED DELETE DESC
DESCRIBE DETERMINISTIC DISTINCT
DISTINCTROW DIV DOUBLE
DROP DUAL EACH
ELSE ELSEIF ENCLOSED
ESCAPED EXISTS EXIT
EXPLAIN FALSE FETCH
FLOAT FLOAT4 FLOAT8
FOR FORCE FOREIGN
FROM FULLTEXT GRANT
GROUP HAVING HIGH_PRIORITY
HOUR_MICROSECOND HOUR_MINUTE
HOUR_SECOND
IF IGNORE IN
INDEX INFILE INNER
INOUT INSENSITIVE INSERT
INT INT1 INT2
INT3 INT4 INT8
INTEGER INTERVAL INTO
IS ITERATE JOIN
KEY KEYS KILL
LEADING LEAVE LEFT
LIKE LIMIT LINES
LOAD LOCALTIME LOCALTIMESTAMP
LOCK LONG LONGBLOB
LONGTEXT LOOP LOW_PRIORITY
MATCH MEDIUMBLOB MEDIUMINT
MEDIUMTEXT MIDDLEINT MINUTE_MICROSECOND
MINUTE_SECOND MOD MODIFIES
NATURAL NOT NO_WRITE_TO_BINLOG
NULL NUMERIC ON
OPTIMIZE OPTION OPTIONALLY
OR ORDER OUT
OUTER OUTFILE PRECISION
PRIMARY PROCEDURE PURGE
READ READS REAL
REFERENCES REGEXP RELEASE
RENAME REPEAT REPLACE
REQUIRE RESTRICT RETURN
REVOKE RIGHT RLIKE
SCHEMA SCHEMAS SECOND_MICROSECOND
SELECT SENSITIVE SEPARATOR
SET SHOW SMALLINT
SONAME SPATIAL SPECIFIC
SQL SQLEXCEPTION SQLSTATE
SQLWARNING SQL_BIG_RESULT
SQL_CALC_FOUND_ROWS
SQL_SMALL_RESULT SSL STARTING
STRAIGHT_JOIN TABLE TERMINATED
THEN TINYBLOB TINYINT
TINYTEXT TO TRAILING
TRIGGER TRUE UNDO
UNION UNIQUE UNLOCK
UNSIGNED UPDATE USAGE
USE USING UTC_DATE
UTC_TIME UTC_TIMESTAMP VALUES
VARBINARY VARCHAR VARCHARACTER
VARYING WHEN WHERE
WHILE WITH WRITE
XOR YEAR_MONTH ZEROFILL
ASENSITIVE CALL CONDITION
CONTINUE CURSOR DECLARE
DETERMINISTIC EACH ELSEIF
EXIT FETCH INOUT
INSENSITIVE ITERATE LEAVE
LOOP MODIFIES OUT
READS RELEASE REPEAT
RETURN SCHEMA SCHEMAS
SENSITIVE SPECIFIC SQL
SQLEXCEPTION SQLSTATE SQLWARNING
TRIGGER UNDO WHILE

24.6.07

MAC OUI Vendor Search

Unas semanas atras, entusiasmado con implementar SimpleJS en algo y se me dio por hacer dos aplicaciones web. La primera que empece, quedo en repoco y esta fue agraciada con un desarollo mas activo (lease, termine con la funcionalidad que me propuse).

Dada una direccion MAC de un dispositivo de red busca en una base de datos quien es el fabricante.





Para incluirla en Blogger lo que hice en este caso fue un iframe cavernicola:

<iframe src="http://caco.homelinux.org:7080/caco/mac-oui-search/" style="width: 369px; border: 0px;
padding: 0px; margin: 0px; height: 193px">

No es gran cosa, pero me parecio algo como para hacer de esa forma. A "esa forma" me refiero a la tendencia de desarrollar cosas en "cajitas" para ser incluidas en otros sitios.

23.6.07

Imagenes Rotativas (al azar) en JavaScript

Un amigo necesitaba para su Blog que el banner con su logotipo muestre una imagen al azar cada vez que se cargue la pagina. Al estar alojado en Blogger, no tenia la posibilidad de hacerlo en PHP y por eso la eleccion fue JavaScript.

El script tiene dos partes, en la primera definimos la una funcion con la lista de las posibles imagenes a mostar, y la segunda parte es la llamada al script en el lugar en donde querramos mostrar la imagen.

Dentro de las etiquetas <head> y <head> de la pagina debemos agregar las siguientes lineas:


<script type="text/javascript">
function MostrarImagenes() {
var Imagenes = new Array();
// IMAGENES
Imagenes[0] = 'http://farm2.static.flickr.com/197/579000_cdb5b74d8_o.jpg';
Imagenes[1] = 'http://farm2.static.flickr.com/1109/5859_fa24792397_o.jpg';
Imagenes[2] = 'http://farm2.static.flickr.com/126458120_d68c18099e_o.jpg';

var j = 0;
var p = Imagenes.length;
var preBuffer = new Array();
for (i = 0; i < p; i++){
preBuffer[i] = new Image();
preBuffer[i].src = Imagenes[i];
}
var whichImage = Math.round(Math.random()*(p-1));
document.write('<img src="'+Imagenes[whichImage]+'">');
return true;
}
</script>


En el array "Imagenes" debemos cargar las direcciones de las posibles imágenes que queremos mostrar. Luego, debemos reemplazar la etiqueta <img> en donde tengamos la imagen actual por la llamada a la función. Por ejemplo, si tenemos algo asi:


<div id="header">
<img src="imagen.jpg" alt="logo">
</div>


Debería quedarnos asi:


<div id="header">
<script type="text/javascript">MostarImagenes();</script>
</div>


NOTA: En un principio probe el script con imágenes alojadas en Picasa y funcionaba erraticamente. Muchas veces no llegaba a mostrar ninguna imagen. Al utilizar el link de las imagenes directamente en el browser, algunas veces me preguntaba para bajarmelas en vez de mostarmelas. Cuando usamos imagenes hosteadas en un servidor propio o en Flickr funciona perfectamente. Alguna idea al respecto?