Posteado por: pasky en: 19 marzo, 2010
Por una Internet Libre, sin Censuras, sin recortes de Libertad, sin Patadas en la Puerta, sin Dictaduras, sin Sinde…
Posteado por: pasky en: 13 marzo, 2010
Escuchar esto en una sala de conciertos sería increíble.
Posteado por: pasky en: 13 marzo, 2010
Qué canción tan preciosa…
Posteado por: pasky en: 25 enero, 2010
Mi blog favorito sobre cine y series de televisión, De Cine y Series, celebrará próximamente su primer año de existencia. Y para celebrarlo, sortean un DVD de la película Réquiem por un sueño, de Darren Aronofsky. Para participar en el sorteo sólo hay que enviar un comentario con tu nombre y correo electrónico, así como responder a un par de preguntas muy sencillas: ¿Qué te gusta de “De Cine y Series”? ¿Qué cambiarías?
No os podéis perder esta celebración. Así que ya sabéis, a participar.
Posteado por: pasky en: 23 enero, 2010
Acaba de publicarse la última versión de Firefox 3.6. Ésta aún no está en los repositorios oficiales de Ubuntu. Así que para los impacientes como yo, hay dos alternativas para instalarla:
La primera alternativa es descargarlo desde los servidores de Mozilla, descomprimirlo en el directorio /opt/ y crear un enlace simbólico en el directorio /usr/local/bin/:
cd ~
wget http://download.mozilla.org/?product=firefox-3.6&os=linux&lang=es-ES
sudo tar -C /opt/ -xf ~/firefox-3.6.tar.bz2
sudo ln -s /opt/firefox/firefox /usr/local/bin/firefox
Tras esto, bastará que cerremos y volvamos a iniciar nuestro navegador para que se ejecute esta nueva versión.
La segunda alternativa sería añadir mozillateam/firefox-stable a nuestros repositorios e instalarlo con aptitude:
sudo add-apt-repository ppa:mozillateam/firefox-stable
sudo aptitude update
sudo aptitude full-upgrade
Luego, os recomiendo que vayáis a esta web si queréis instalar el xpi con vuestro idioma, ya que por defecto se instala en inglés.
Por cierto, podéis ver las novedades de esta nueva versión, entre las que destaca el nuevo motor Gecko 1.9.2, mejora de rendimiento en JavaScript y soporte para nuevos atributos CSS y nuevas especificaciones DOM y HTML5.
Posteado por: pasky en: 23 octubre, 2009
El otro día me dieron el CD de una aplicación realizada en PHP y que había que instalarla en uno de nuestros servidores. Copiar y pegar. La página de inicio se veía bien, pero cuando entré en una página con contenido PHP, como un formulario, se veía código PHP en el navegador. ¡WoW! Me quedé algo sorprendido.
Lo primero que hice fue buscar el archivo .php correspondiente a esa página y ver su contenido. Aparentemente todo estaba bien. Modifiqué allá y acá, y seguía viéndose el código. Entonces vi que la etiqueta para el código php era “<? … ?>” en vez de “<?php … ?>“. Misterio resuelto y solución fácil. Sólo habría que habilitar la directiva short_open_tag (etiqueta de apertura corta) en el archivo /etc/php5/apache2/php.ini. Esta modificación afecta a todas las aplicaciones, ya que se configura a nivel del servidor Apache2-PHP, lo que supone un problema con otras aplicaciones que usan etiquetas xml, las cuales también comienzan por “<?” y se confunden con las etiquetas de php. El ejemplo más claro es éste:
<?xml version=”1.0″ encoding=”UTF-8″?
Para solucionar este problemilla hay varias opciones. La primera de ellas y que me parece más chupucera es reescribir la línea anterior en todos los archivos donde aparezca y dejarla así:
<? echo ‘<’.'?xml version=”1.0″ encoding=”UTF-8″?’.'>’; ?>
Esto hace que PHP la reescriba igual que la línea original: <?xml version=”1.0″ encoding=”UTF-8″?>
La segunda opción es la más correcta, pero también la más tediosa y sería usar la etiqueta de apertura correcta “<?php” para todo nuestro código PHP. Esto supone revisar la aplicación entera y cambiar todas las etiquetas de apertura de php. No era mi intención reescribir el código, ni siquiera usando comandos tan útiles como sed o similares.
Y la tercera opción, que es un caso intermedio y por lo que he optado yo, sería habilitar short_open_tag sólo para la aplicación o directorio que deseemos. Esto es posible gracias al archivo .htaccess. Para ello, creamos dicho archivo en el directorio de nuestra aplicación (también se puede hacer a nivel de subdirectorio) y añadimos la siguiente línea:
php_flag short_open_tag on
Con esto lo que hacemos es habilitar la directiva short_open_tag de PHP sólo en el directorio donde tengamos el .htacces y en todos sus subdirectorios. Por tanto, de esta manera tendremos deshabilitadas las etiquetas cortas en el archivo php.ini pero habilitadas en archivo .htaccess del directorio deseado.
Como anécdota, voy a comentar otro problema que he tenido con este archivo .htaccess, ya que inicialmente no me funcionaba. La razón era que en la configuración de Apache2 tengo la opción AllowOverride None, por lo que se ignoran completamente los archivos .htaccess. Por tanto había que reconfigurar esta directiva de Apache2. Esto se puede hacer a nivel global o sólo para un directorio particular. Obviamente opté por lo segundo, para tener lo más seguro posible el servidor. Así pues, añadí la siguiente configuración a Apache2:
<Directory /var/www/miAplicacion/>
AllowOverride Options
</Directory>
Podéis leer más opciones para AllowOverride en la documentación de Apache: Apache Core Features.
Por último comentaros que una forma sencilla de probar si nuestro archivo .htaccess está funcionando es escribiendo cualquier texto en él, por ejemplo:
test
Si Apache no está leyendo el archivo .htaccess, la página se mostrará y Apache no dará ningún error. La causa más frecuente de esto es que tengamos la directiva “AllowOverride None“.
Sin embargo, si el archivo sí está siendo leído por Apache, éste nos dará un error “500 Internal Server Error” y en el archivo error.log de Apache nos aparecerá el siguiente mensaje de error:
[Fri Oct 23 18:22:15 2009] [alert] [client 192.168.0.10] /var/www/miAplicacion/.htaccess: Invalid command ‘test’, perhaps misspelled or defined by a module not included in the server configuration
Posteado por: pasky en: 22 octubre, 2009
Recientemente he tenido el problema de que los datos almacenados en MySQL no se guardaban correctamente. Me refiero a los datos con tilde, las eñes y demás caracteres similares. Lo que se me guardaba eran carácteres tales como estos:
áéÃóúñ
La página web desde la que introducía los datos estaba codificaba en UTF-8, forzado con la cabecera:
header('Content-Type: text/html; charset=UTF-8');
La base de datos, la tabla y el campo correspondiente estaban como utf8_spanish_ci. Los datos insertados mediante el formulario web luego se visuualizaban correctamente. Pero en la base de datos se almacenaban con otra codificación.
Buscando por Internet, encontré esta página donde explicaban la resolución a mi problema. Básicamente, éste residía en la clase mysqli de PHP, que requería especificar el charset correspondiente.
El código que no funcionaba era éste:
if (!($link = mysqli_connect($dbhost, $dbuser, $dbpass, $dbname))){
exit('Error al conectar a la base de datos.');
}
$sql = 'SELECT * FROM `mibd`.`mitabla`';
$result = mysqli_query($link, $sql);
Y lo cambié por este otro, que funcionaba perfectamente:
if (!($link = mysqli_connect($dbhost, $dbuser, $dbpass, $dbname))){
exit('Error al conectar a la base de datos.');
}
mysqli_set_charset($link, "utf8");
$sql = 'SELECT * FROM `mibd`.`mitabla`';
$result = mysqli_query($link, $sql);
Espero que le pueda ayudar a alguien.
Posteado por: pasky en: 17 octubre, 2009
Soy un aprendiz en el framework CodeIgniter y estoy haciendo pequeños progresos, pero no sé si buenos o malos. Así que voy a publicar algunos progresos para que los más expertos que lean este artículo me puedan corregir o mejorar el código.
Mi objetivo es dotar a una pequeña aplicación realizada con CI de autenticación para que no se pueda acceder anónimamente. Para ello he creado un controlador ‘principal.php‘, un modelo ‘autenticacion_model.php‘ y una vista ‘form_login.php‘. La estructura queda así:
.
|– config
|– controllers
| `– index.html
| |– principal.php
|– models
| |– autenticacion_model.php
| `– index.html
`– views
|– autenticacion
| `– form_login.php
`– index.html
El controlador principal.php tiene las siguientes funciones:
El constructor Principal carga los herlpers ‘url’ y ‘form’ y la library ‘form_validation’. Con esto podremos hacer uso de las funciones para crear urls y formularios y validaremos nuestro formulario.
La función index carga la vista ‘principal_view’ en caso de que exista la sesión de usuario, o, en caso contrario, redirige a la función login.
La función login comprueba que se ha enviado el formulario. En caso positivo, se pasan las variables ‘usuario’ y ‘contrasena’ a la función ‘verificaUsuario()’ que está en el modelo ‘Autenticacion_Model’ y que verificará que el usuario y contraseña existen en la base de datos y son correctos. Si son correctos se crean las variables de sesión ‘usuario_id’ y ‘login_ok’, y si no, genera un mensaje de error. Si el formulario no se envió, se carga la vista del formulario ‘form_login’ para que el usuario se autentique.
La función logout sólo elimina las variables de sesión anteriores y redirige al controlador ‘principal’.
<?php
class Principal extends Controller {
function Principal()
{
parent::Controller();
$this->load->helper(array('url', 'form'));
$this->load->library('form_validation');
}
// Función index. Comprueba si existe la sesión de usuario
function index()
{
// si no existe la sesión con la variable 'usuario_id'
if (!$this->session->userdata('usuario_id')){
// redirigimos a la función login
redirect('principal/login', 'refresh');
} else {
// en caso contrario cargamos la vista principal
$this->load->view('principal_view');
}
// Función login. Verifica el usuario/contraseña
function login()
{
// si se ha enviado el formulario
if ($this->input->post('usuario')){
// recogemos las variables 'usuario' y 'contrasena'
$usuario = $this->input->post('usuario');
$contrasena = sha1($this->input->post('contrasena'));
// cargamos el modelo para verificar el usuario/contraseña
$this->load->model('Autenticacion_Model');
// si el usuario y contraseña son correctos
if ($this->Admin_Model->verificaUsuario($usuario, $contrasena)){
// creamos un array con las variables de sesión 'usuario_id' y 'login_ok'
$datasession = array(
'usuario_id' => '$usuario',
'login_ok' => TRUE
);
// creamos la sesión con dichas variables
$this->session->set_userdata($datasession);
// y redirigimos al controlador principal
redirect('principal', 'refresh');
} else {
// si el usuario y contraseña son incorrectos
$this->session->set_flashdata('error', 'El usuario o contraseña son incorrectos.');
}
} else {
// cargamos el formulario de login
$this->load->view('autenticacion/form_login');
}
}
// Función logout. Elimina las variables de sesión y redirige al controlador principal
function logout()
{
// creamos un array con las variables de sesión en blanco
$datasession = array('usuario_id' => '', 'logged_in' => '');
// y eliminamos la sesión
$this->session->unset_userdata($datasession);
// redirigimos al controlador principal
redirect('principal', 'refresh');
}
}
El modelo Autenticacion_Model contiene la función ‘verificaUsuario’ que recibe como parámetros el usuario y contraseña y se conecta a la base de datos para comprobar que son correctos.
<?php
class Autenticacion_Model extends Model {
function Autenticacion_Model()
{
parent::Model();
}
function verificaUsuario($usuario, $contrasena){
// creamos la select
// SELECT `usuario`, `contrasena`
// WHERE `usuario` = $usuario AND
// `contrasena` = $contrasena
// FROM `ci_usuarios`
// LIMIT 1
$this->db->select('id, usuario');
$this->db->where('usuario', $usuario);
$this->db->where('contrasena', $contrasena);
$this->db->limit(1);
$query = $this->db->get('ci_usuarios');
// si el resultado de la query es positivo
if ($query->num_rows() > 0){
// devolvemos TRUE
return TRUE;
// si el resultado de la query no es positivo
} else {
// devolvemos FALSE
return FALSE;
}
}
}
Por último, la vista form_login sólo es un formulario solicitando usuario y contraseña:
<html>
<head>
<title>Login</title>
</head>
<body>
<?php echo form_open('principal/login') ?>
<?php echo form_label('Usuario: ', 'usuario') ?>
<?php echo form_input(array('name' => 'usuario', 'id' => 'nombre', 'size' => '50')) ?>
<?php echo form_label('Contraseña: ', 'contrasena') ?>
<?php echo form_input(array('name' => 'contrasena', 'id' => 'contrasena', 'size' => '50')) ?>
<?php echo form_submit('enviar', 'Enviar') ?>
<?php echo form_close() ?>
</body>
</html>
NOTA: Como veréis, cargué la library form_validation pero no la he usado. La razón es que aún no sé cómo funciona esa librería y espero aprenderlo en breve. En cuanto lo sepa modifico el código. Aún así, no es necesario validar el formulario para que nuestra autenticación funcione.
Posteado por: pasky en: 22 septiembre, 2009
La fragmentación de discos es algo que ocurre con todos los sistemas operativos, aunque algunos lo tienen bastante mejorado respecto a otros.
En el caso de los sistemas operativos de Microsoft, el sistema de desfragmentación de los discos ha ido mejorando con cada versión de Windows, desde los antaños Windows 95/98, que reiniciaban el proceso de desfragmentación cuando se modificaba algo en el disco, pareciendo eterna la tarea, hasta el nuevo Windows Vista, que usa funciones de baja prioridad para no bajar el rendimiento del equipo, además de integrarse perfectamente como tarea programada del equipo.
Desde Windows 2000 la cosa ha mejorado bastante. La herramienta de desfragmentación que éste tenía ya permitía desfragmentar el disco sin problemas porque otros procesos interfirieran. Pero tenía una gran pega: era una herramienta interactiva que no se podía automatizar para realizar desfragmentaciones automáticas y periódicas. Bueno, había un script en VBS para desfragmentar que mediante el uso de la función SendKeys permitía automatizarlo perfectamente. Era una chapuza, pero funcionaba.
Con Windows XP y Windows Server 2003 seguíamos teniendo la misma consola de desfragmentación de discos que Windows 2000, pero se añadió opción de una herramienta ejecutable desde línea de comandos: defrag.exe. La herramienta permitía analizar el disco y desfragmentarlo por lo que se podían programar las desfragmentaciones de disco sin problemas. Sin embargo tenía ciertas pegas a la hora de desfragmentar el archivo de paginación (pagefile.sys) o la tabla de archivos maestra (MFT). Estas limitaciones y estas otras, que ya venían desde Windows 2000, se podían solucionar parcialmente con una herramienta llamada PageDefrag. Digo parcial porque no puedo confirmar si PageDefrag desfragmenta también la MFT.
En el nuevo Windows Vista, y supongo que Windows Server 2008, se ha rediseñado la interfaz y mejorado el algoritmo. En el caso de la interfaz, simplemente ya no hay interfaz gráfica ni barra de progreso. En su lugar nos encontramos con una herramienta que nos permite programar la ejecución del desfragmentador o realizar la ejecución inmediatamente. La ejecución programada está bastante bien, ya que si ésta no se ejecutó porque el equipo estuviera apagado u ocupado, lo hará en cuanto pueda y esté inactivo. Esto quiere decir que no funciona mientras estemos trabajando, sino que lo hará sólo cuando el equipo esté ‘idle’.
Además, se ha mejorado el algoritmo de desfragmentación para que consuma menos recursos de CPU y E/S, se añade la opción por defecto para que haga una desfragmentación parcial con un ‘límite’ de 64 MB como mínimo por cada fragmento, lo cual es más óptimo que desfragmentar al 100% todos los archivos, y se ha eliminado el requisito del 15% de espacio en disco libre para poder desfragmentar. Las mejoras, como véis, son notables.
Hay una FAQ sobre el desfragmentador Windows Vista muy interesante que os recomiendo leer, aunque esté en inglés. Y esto también interesa leerlo.
Próximamente quizás ponga otro artículo analizando las distintas herramientas de desfragmentación existentes.