Archivo de la Categoría 'Páginas web'

Nuevo proyecto fotográfico ‘365 photos a year’.

Lo admito. Soy de esos que cuando se va terminando el año suelen pensar en algunos buenos propósitos para el que empieza. Podría ser algo más precavido y pensar en ello unos días o semanas antes y con toda seguridad saldrían ideas más sensatas. Pero procastino hasta en esto y al final, claro, me salen unos propósitos que no van más allá de mediados de enero -cuando llegan-. Pero este año no va a ser así. Este año no voy a incumplir mi lista de buenos propósitos porque no va a haber tal lista.

Solo un pequeño proyecto personal que verá la luz con la llegada del 2009 y que me ilusiona especialmente: ‘365 photos a year’. Se trata de un blog eminentemente fotográfico que inauguro mañana. La idea es bien simple: cada día una fotografía. Algunas pretenderán ser más artísticas. Otras serán de lo más cotidianas y no tendrán otra misión que la de mostrar en una imagen algo que me haya resultado interesante, o gracioso, o conmovedor, o lo que sea cada día. Por lo general la imagen que publique estará tomada ese mismo día, aunque me reservo la posibilidad de crear alguna categoría retrospectica para poder añadir imágenes provenientes de algún proyecto photoblog anterior que quedó en el olvido y que pronto pasará a mejor vida (léase www.pijus.com) o de mi propio archivo fotográfico. Eso sí, las imágenes estarán siempre tomadas por un servidor con mi propia cámara.

La frecuencia de posteo será diaria de media, pero no necesariamente habrá un post todos los días. Cabe la posibilidad de que en algunas ocasiones se acumulen algunas fotografías para cuando tenga unos minutos en que pasarlas de la cámara al portátil y subirlas al blog.

Ni que decir tiene que todo el contenido del proyecto ‘365 photos a year’ está sujeto a una licencia Creative Commons, por lo que si en algún momento alguien encuentra alguna foto que le pueda servir para ilustrar algún post o lo que sea, podrá utilizarla sin problemas.

Y poco más queda por añadir. Simplemente que se trata de un proyecto que me ilusiona porque la fotografía me ha resultado apasionante desde que tuve mi primera (y actual) cámara digital y confío que con esta pequeña obligación autoimpuesta consiga dar más rienda suelta a una de mis principales aficiones.

La dirección web es la fácilmente deducible www.365photosayear.com (o www.365photosayear.net). Básicamente porque barajé varias alternativas para el nombre del proyecto y finalmente escogí la que más me gustaba de entre las que tenían los dominios .com y .net libres. Por supuesto tiene posibilidad de suscribirse vía RSS y en tanto que los posts serán una fotografía y un texto muy breve, no resultará demasiado intrusivo estar suscrito, así que os animo a ello.

Calendario en JavaScript traído del baúl de los recuerdos.

Ordenando estos días viejos archivos que tenía en discos duros varios, he topado con algunas cosas que había desarrollado hace ya tiempo y que en algunos casos ni recordaba. Una de las que me ha parecido más interesante es este calendario para página web creado con JavaScript que presento hoy. Recuerdo que lo creé para recoger una fecha con la que acotar una consulta. Quería evitar problemas con los formatos de entrada de fechas (día/mes/año, mes/día/año, etc) y además me apetecía crear algo más estético que un simple cuadro de texto. Por eso surgió este calendario. De modo que todo el código es de hace unos cuantos años, cuando era un programador 100% amateur, así que no se aceptan críticas despiadadas sobre su corrección… ;-) Ahora simplemente le he echado un vistazo por encima y le he puesto algún comentario y alguna tabulación, nada más.

No tiene mucho misterio explicar cómo funciona, solo hay que crear el calendario en el punto de la página web que se desee con una llamada así:

<script>drawCalendar('date01');</script>

Y después tener algún cuadro de texto que recoja la fecha que se selecciona en el calendario. Este cuadro lo podemos hacer visible o invisible a nuestro antojo, pero tenemos que tener la precaución de asignarle un identificador igual al parámetro que hemos pasado como argumento a la función drawCalendar:

<input type="textbox" id="date01" value=" "/>

Con esto el calendario queda ya plenamente operativo. Aquí va un ejemplo:

Y aquí os dejo el código JavaScript completo del archivo calendar.js:

/*-------------------------------------------------------------------
 Author:      Albert Mata (www.albertmata.net)
 Date:        20080718
 Description: Old JavaScript calendar I programmed a long time ago. 
-------------------------------------------------------------------*/

/*-------------------------------------------------------------------
 Attributes.
-------------------------------------------------------------------*/

var monthShown;
var yearShown;
var textboxId;
var firstMonthWeekDay;

/*-------------------------------------------------------------------
 Draws calendar giving identifiers to each button.
-------------------------------------------------------------------*/
function drawCalendar(txtId) {
    var currentDate;

    textboxId = txtId;

    /* Getting current month and year. */
    currentDate = new Date();
    monthShown = currentDate.getMonth();
    yearShown = currentDate.getFullYear();

    /* Opening HTML table. */
    document.write('<table width="126" bgcolor="#FFFFFF"' 
                 + 'align="center" cellspacing="0" cellpadding="0"'
                 + 'border="0">');
    document.write('<tr><td width="6"><img src="left.gif"' 
                 + 'style="cursor: hand;" onClick="SafeRefill(1);"/>'
                 + '</td><td width="60"><input type="button"' 
                 + 'style="width: 60px; background-color: #FFFFFF;'
                 + 'font-size: 10px; text-align: center;' 
                 + 'font-family: Arial, Helvetica, sans-serif;' 
                 + 'border: 0px;" id="mth"' 
                 + 'value="'+monthName(monthShown)+'"/></td>'
                 + '<td width="6"><img src="right.gif"' 
                 + 'style="cursor: hand;" onClick="SafeRefill(2);"/>'
                 + '</td><td width="10"></td><td width="6">'
                 + '<img src="left.gif" style="cursor: hand;"' 
                 + 'onClick="SafeRefill(3);"/></td>'
                 + '<td width="32"><input type="button"' 
                 + 'style="width: 32px; background-color: #FFFFFF;'
                 + 'font-size: 10px; text-align: center;' 
                 + 'font-family: Arial, Helvetica, sans-serif;' 
                 + 'border: 0px;" id="yea" value="'+yearShown+'"/>'
                 + '</td><td width="6"><img src="right.gif"' 
                 + 'style="cursor: hand;" onClick="SafeRefill(4);"/>'
                 + '</td></tr>');
    document.write('<tr><td width="126" colspan="7">');
   
    /* Adding buttons. */
    for (i = 0; i < 42; i++) {
        document.write('<input type="button" style="width: 18px;' 
                     + 'background-color: #FFFFFF; font-size: 10px;'
                     + 'text-align: center;' 
                     + 'font-family: Arial, Helvetica, sans-serif;'
                     + 'border: 0px;" id="day' + i + '" value=" "'
                     + 'onMouseOver="Hover('+i+',1);"' 
                     + 'onMouseOut="Hover('+i+',0);"' 
                     + 'onClick="ShowDate(' + i + ');"/>');
        if (((i+1) % 7) == 0) {
            document.write('<br/>');
        }
    }

    /* Closing HTML table. */
    document.write('</td></tr>');
    document.write('</table>');

    Refill();
}

/*-------------------------------------------------------------------
 Prevents possible wrong values for month and refills calendar.
-------------------------------------------------------------------*/
function SafeRefill(action) {
    /* Increasing or decreasing month and year. */
    if (action == 1) { monthShown-- }
    if (action == 2) { monthShown++ }
    if (action == 3) { yearShown-- }
    if (action == 4) { yearShown++ }
   
    /* Moving from January to December. */
    if (monthShown == -1) {
        monthShown = 11;
        yearShown--;
    }
   
    /* Moving from December to January. */
    if (monthShown == 12) {
        monthShown = 0;
        yearShown++;
    }
   
    Refill();
}

/*-------------------------------------------------------------------
 Redraws calendar when month or year has changed, using identifiers
 previously given to all buttons.
-------------------------------------------------------------------*/
function Refill() {
    var firstMonthDay;
    var lastMonthDay;
    var lastMonthWeekDay;

    /* Getting first month day and weekday. */
    firstMonthDay = new Date(yearShown,monthShown,1);
    firstMonthWeekDay = firstMonthDay.getDay();
    if (firstMonthWeekDay == 0) {
        firstMonthWeekDay = 7;
    } 

    /* Getting last month day and weekday. */
    lastMonthDay = new Date(yearShown,monthShown,
                            monthDays(monthShown,yearShown));
    lastMonthWeekDay = lastMonthDay.getDay();
    if (lastMonthWeekDay == 0) {
        lastMonthWeekDay = 7;
    } 

    /* Clearing all buttons. */
    for (i = 0; i < 42; i++) {
        document.getElementById('day'+i).value = " ";
        document.getElementById('day'+i).style.cursor = 'default';
    }

    /* Giving new values to buttons. */
    for (i = 1; i <= monthDays(monthShown,yearShown); i++) {
        document.getElementById('day'+(i+firstMonthWeekDay-2))
                                              .value = i;
        document.getElementById('day'+(i+firstMonthWeekDay-2))
                                              .style.cursor = 'hand';
    }

    /* Giving new values to month and year buttons. */
    document.getElementById('mth').value = monthName(monthShown);
    document.getElementById('yea').value = yearShown;
}

/*-------------------------------------------------------------------
 Function to calculate a month's number of days depending on it's a 
 leap year or not. It's a leap year when it can be divided by 4, but
 it's not when it can be divided by 100 as well. And it's a leap
 year again when it can be divided by 100 and by 400.
-------------------------------------------------------------------*/
function monthDays (mm, yyyy) {
    var februaryDays;
    var daysNumber;

    februaryDays = 28;

    /* Deciding number of days for February. */
    if ((yyyy % 4) == 0) {
        if ((yyyy % 100) == 0) {
            if ((yyyy % 400) == 0) { 
                februaryDays = 29;
            } 
        } else { 
            februaryDays = 29;
        }
    } 

    daysNumber = new Array (31, februaryDays, 31, 30, 31, 30, 
                            31, 31, 30, 31, 30, 31);

    /* Returning number of days for selected month and year. */
    return daysNumber[mm];
}

/*-------------------------------------------------------------------
 Returns month name.
-------------------------------------------------------------------*/
function monthName (mm) {
   var monthNames;

   monthNames = new Array('enero','febrero','marzo','abril',
                          'mayo','junio','julio','agosto',
                          'septiembre','octubre','noviembre',
                          'diciembre');

   return monthNames[mm];
}

/*-------------------------------------------------------------------
 Customizes mouseOver effects.
-------------------------------------------------------------------*/
function Hover(dd,x) {
    if (document.getElementById('day'+dd).value != " ") {
        if (x == 1) {
            document.getElementById('day'+dd).style.background = 
                                                       '#CCCCFF' 
        } else { 
            document.getElementById('day'+dd).style.background = 
                                                       '#FFFFFF' 
        }
    }
}

/*-------------------------------------------------------------------
 Returns selected data to textbox.
-------------------------------------------------------------------*/
function ShowDate(dd) {
    var selDay;
    var selMonth;

    /* Formatting day. */
    if ((dd - firstMonthWeekDay + 2) < 10) {
        selDay = '0' + (dd - firstMonthWeekDay + 2);
    } else {
        selDay = (dd - firstMonthWeekDay + 2);
    }

    /* Formatting month. */
    if ((1+monthShown) < 10) {
        selMonth = '0' + (1 + monthShown);
    } else {
        selMonth = (1 + monthShown);
    }

    /* Returning date to textbox. */
    if (document.getElementById('day'+dd).value != ' ' ) { 
        /* Customize this line to change output format!!! */
        document.getElementById(textboxId).value = selDay + '/' 
                                                 + selMonth + '/' 
                                                 + yearShown; 
    }
}

Para que funcione bonito es preciso que en el mismo directorio donde esté ubicado el archivo calendar.js se encuentren también las imágenes left.gif y right.gif que se pueden descargar desde esta misma página haciendo click derecho en las propias imágenes (los triangulitos azules que aparecen en el calendario para desplazarse entre meses y/o años).

Por último, ni que decir tiene que este calendario es muy mejorable y ampliable en funciones… ¡pero no seré yo quien lo haga! Simplemente lo dejo aquí por si a alguien puede servirle o puede aportarle alguna idea. ;-)

Servidor de bolsillo con WOS Portable.

En el proyecto en el que actualmente estoy trabajando, decidimos utilizar una base de datos MySQL por su bajo coste y excelente rendimiento. De hecho fue una recomendación mía que la Dirección aceptó, por lo cual celebro que de momento nos esté dando el resultado tan bueno que nos está dando.

Así pues en mi portátil de trabajo tengo instalado un servidor MySQL en local. En él hago toda la fase de desarrollo antes de pasar tablas, triggers, procedimientos y demás al servidor MySQL del servidor de la empresa. Pero en ocasiones no tengo mi portátil a mano y me gustaría poder probar algunas cosas en otro PC. Hasta ahora tenía que desestimar la idea porque andar instalando el servidor MySQL en ordenadores ajenos es inviable. Pero hace poco he descubierto WOS Portable. Una maravilla. WOS Portable es un software que se instala en un pendrive cualquiera (bueno, dicen que algunos modelos dan problemas, pero parecen ser los menos y en cualquier caso a mí no me ha ocurrido) y nos permite que al conectar después ese pendrive en cualquier PC con Windows y ejecutar el archivo wos.exe automáticamente dispondremos de un servidor Apache + PHP + MySQL funcionando perfectamente, de tal manera que si en un navegador escribimos:

http://localhost

Obtendremos la página index.php que tenemos alojada en el pendrive (en el directorio www). Y si en una consola escribimos:

mysql -u root

Tendremos un servidor MySQL a nuestra entera disposición. (ver nota 1)

Personalmente este software me ha parecido una maravilla y creo que es muy útil para desarrolladores que solemos trabajar con más de un PC, ya que así nuestros datos pueden estar siempre en el pendrive y no tenemos que andar backupeándolos y restaurándolos constantemente. También se me ha ocurrido que puede resultar extremadamente útil como sistema de seguridad. Me explico: en mi empresa las aplicaciones funcionan como he dicho contra una base de datos MySQL alojada en el servidor. Si éste sufriera un accidente o cualquier imprevisto, la actividad se paralizaría y hasta que se restaurara el correcto funcionamiento del servidor podrían pasar horas o incluso días. En cambio ahora tenemos un pendrive con WOS Portable y cada X días le restauramos una copia de seguridad de la base de datos productiva. Con ello, ante cualquier eventualidad nos basta con conectar este pendrive, hacer un doble clic y ya tenemos de nuevo las aplicaciones funcionando. Realmente genial y recomendable.

Pues bien, WOS Portable se puede descargar libremente (es GNU-GPL) desde su sitio web. Para ello la única peculiaridad es que en lugar de bajarnos un archivo estándar podemos configurar qué aplicaciones extras (Joomla, Mambo, Wordpress, etc) queremos incorporar al paquete de instalación. Lo básico es Apache + PHP + MySQL, y personalmente no recomiendo añadirle mucha cosa más desde un inicio, puesto que siempre estamos a tiempo de hacer actualizaciones con nuevos paquetes. No obstante, yo sí le añadí el phpMyAdmin porque considero que en ocasiones resulta muy útil.

Una vez seleccionados los componentes nos generarán un archivo comprimido personalizado que sólo tendremos que bajarnos, descomprimirlo en el pendrive y ejecutar el fichero wos.exe. Con eso se llevará a cabo un proceso de configuración que tarda un ratito pero que no tiene complicación alguna. ;-)

Nota 1.

Para que esta sentencia funcione tenemos que tener un cliente MySQL (un archivo mysql.exe) en el PC y la ruta donde éste se encuentra guardada en la variable del sistema Path. Si no es así, cosa probable si no estamos en nuestro PC, siempre podemos ir primero a buscar el cliente:

F:
cd mysql/bin
mysql -u root



Creative Commons License
El blog de Albert Mata by Albert Mata is licensed under a Creative Commons Reconocimiento-Compartir bajo la misma licencia 2.5 España License.