domingo, 10 de agosto de 2014

Tip: Cómo agregar texto a una imagen con ImageMagick

Hola!

    Necesito agregar la fecha a una imagen. Algún día les contaré qué estoy haciendo :P



    Tengo esta imagen, saca de The Humble Yogini - Observations from the realm of Samsara:








Y con este comando, ¡pasen y vean! , le agregamos tóscamente la fecha:
 /usr/bin/convert \
        Computer_color_spectrum.jpg \
        -pointsize 38 -font URW-Bookman-L-Light \
        -annotate +80+100 "$(date --rfc-3339=date)"  \
         /tmp/colores.gif
 


Y quedó así:



         Tada!





Saludos!
 -- Diego.



sábado, 9 de agosto de 2014

Cómo sacar algunos sigils ($@%&), parte 4

Esto es... no sé qué es. Es una chanchada. Es otro forma de sacar sigils. No creo que deba usarse, pero acá está:

Cuando uno usa objetos en perl (sean hechos con Moo(se) o de cualquier otra forma) (pero hay que usar Moo(se) :) ), hace algo así:

use MiClase;
my $objeto = MiClase->new();

Y después usamos los atributos y métodos de $objeto. Supongamos que sirve para guardar frases célebres:

use Quote;
my $q = Quote->new();
$q->set_phrase("Un problema imaginario es la raíz de
                               todo pensamiento negativo");

print "La frase es: " . $q->get_phrase . "\n";

Con esto podemos tener (instanciar) un montón de objetos "Quote".

my $q = Quote->new();
my $otra_q = Quote->new()
my $otro = Quote->new()
Pero también podríamos evitar los sigils, no instanciando (creando) un objeto, sino usando la clase. Esto es horrible, y no debe hacerse, pero WTH, lo hago igual :)

 use Quote;
Quote->set_phrase("Un problema imaginario es la raíz de
                                    todo pensamiento negativo
");
print Quote->get_phrase() . "\n";
 Este es el código de Quote.pm

package Quote;

use strict;

our $self;

# Cuando se llama a la clase directamente, el primer argumento
# es justamente el nombre de la clase. No nos interesa.
sub set_phrase {
  my $class = shift;
  my $phrase = shift;
  $self->{phrase} = $phrase;
}

sub get_phrase {
  my $class = shift;
  return $self->{phrase};
}

1;
Sinceramente, no sé cuán horrible es esto. Qué efectos secundarios tendrá. Le encontré por lo menos una, que es que la clase/objeto es global. Osea, si le ponés un valor a la frase, lo va a tener dentro de toda sub. Supongo que hay alguna forma de cambiarlo. Les dejo un gato:






domingo, 3 de agosto de 2014

Pequeño ejemplo de crear archivos ical con Perl

¡Hola de nuevo!

    Estuve trabajando en un programa que en una parte guarda eventos en un archivo ical. Me costó un poco encontrar un buen módulo. El mejor y más sencillo es Tie::iCal, aunque verán que tiene un bug al final.

sub guardar_evento {
    # segundos: tiempo que falta para el final del evento
    # contenido: la descripción del evento (ej "Reunión con Pepe")
    my ($segundos, $contenido) = @_;
    my %my_events;
    my $calfile = "/.mycalendar.ics";
    tie %my_events, 'Tie::iCal', $calfile or die "Failed to tie file!\n";

    # Summary no puede tener enter, así que lo cambio por \n
    $contenido =~ s/\n/\\n/gs;



    # Cada evento es una entrada, y c/u tiene un UID
    my $uid = time();
    $my_events{$uid} = [
    'VEVENT',
             {
              'SUMMARY' => $contenido,
              'DTSTART' => secs_to_ical_date(0),
              'DTEND'   => secs_to_ical_date($segundos),
             }
    ];
    untie %my_events;
}



# Esta func agrega $secs segundos a la fecha/hora actual
# y lo devuevle en el formato para iCal
sub secs_to_ical_date {
    my ($secs) = @_;


  
    # Usamos Time::Piece, que viene con Perl y nos lo hace más facil
    my $now = mk_time_piece_now();
    $now += $secs;
    my $date = $now->strftime( "%Y%m%d" )  . "T" .
               $now->strftime( "%H%M00" ) . "Z";
    return $date;
}

sub mk_time_piece_now {
      # Esto pasa porque el objeto Time::Piece que resulta de

      # localtime tiene mal el timezone. Así que lo hago string,
      # y lo vuelvo a hacer objeto. Grrrr.
      my $now        = localtime;
      my $now_string = $now->strftime("%d-%m-%Y %H:%M");
         $now        = Time::Piece->strptime($now_string, 

                                            "%d-%m-%Y %H:%M");
      return $now;
}



Pero resulta que el archivo iCal queda mal hecho, así que este pedazo de código lo arregla. Reporté el bug acá.

open( my $ical, "<", ".mycalendar.ics") or die $!;

my $head = "";
foreach my $n (1, 2, 3) {
     my $temp = <$ical>;
     $head = $head . $temp;
}


my $body = "";
while ( <$ical> ) {
    next if ( /BEGIN:VCALENDAR/ );
    next if ( /VERSION:/ );
    next if ( /PRODID:/ );
    next if ( /END:VCALENDAR/ );
    $body = $body . $_;
}

my $foot = "END:VCALENDAR\n";


# Y escribirlo a un archivo.
use File::Slurp;
write_file( ".mycalendar_fixed.ics", $head . $body . $foot );



Dos bugs. No está nada bien :(

Les dejo un conejo.



Saludos!
-- Diego



Slides sobre Moose, la implementación moderna de OO de perl

estoy con fiaca de escribir :P

Diapositivas, o tutorial con pocas letras sobre el sistema de OO de perl (el nuevo), con todos los roles, mixins y magia que hay en el mundo de la programación OO.


Les dejo un camello:


Algo más quería postear, pero no me acuerdo...