FPW 09 - talks videos

| | Comments () | TrackBacks (0)

As you may know, last week the French Perl Workshop 2009 took place in Paris. It was a nice conference in french, where various subjects (mostly Perl related) were presented.

I gave 2 presentations :

Hello, it's time again for a small video on Curses::Toolkit.

The first part of the video shows some buttons that can have the focus, and I hit tab to switch focus. Window resizing is also supported.

The second part of the video shows a button that - when clicked using space bar - generates a new buttons, add it to the HBOX. These new buttons can themselves receive focus and be clicked to create a third type of buttons.





What's next ? I'll post about key events and key listeners, I'll try to add more widgets, and at some point publish Curses::Tookkit to CPAN.

In the mean time, enjoy.

It's this time of the year again !

The French Perl Workshop is starting tomorrow for 2 days in the wonderful city of Paris, France. It's organized by the French Perl Mongers.

A bunch of interesting talks, quite a lot of people are planned. I have to say that this year's edition looks very promising, due to a very efficient team that spent a lot of effort to organize it. Of course we'll see how well it was at the end of the two days, but I'm really excited about this edition.

I'll give 2 talks, on POE::Wheel and Curses::Toolkit. Nothing really major (compared to talks on Perl 5.10 or Perl 6...) but every little helps, I guess.

Hm, OK the real reason I'm writing this blog entry is that I'm still missing about 30 slides for my talk that is tomorrow, and it's already late, and I can't motivate my brain to actually do it. Is it the fatality that whatever effort you put in preparing things in advance, you always find yourself writing the slides of your talk the night before ? I guess that's Murphy's law...

Seriously, have you ever given a talk (for the first time) with the slides ready days or weeks ago ? If yes, let me know how you manage that :)

Anyway, if you are in Paris the next days, please head toward the Cité des Sciences and come see us !

1. Focus, the details

Please refer to the previous post for the context about Focus. Basically, Curses::Toolkit is a Perl software toolkit that let's you create nice ncurses based interfaces. It extensively uses widgets, that can have the focus.

As I said in the previous post, not every kind of widgets can have the focus : only a widget that can be interacted by the user should be focusable. For instance, a Label doesn't offer by default any interaction to the user. So a Label widget is not focusable. Likewise, a Border is just displaying a graphical border, and doesn't offer interaction to the user, so same, a Border shouldn't be focusable.

Now let's have a look at the Button widget : it should clearly be focusable, as by default a button is clickable, and do be able to "click" it using the keyboard, the user needs to position the focus on the button and trigger the enter key or the space key. So it's obvious that the Button widget should be focusable

Now let's think about the implementation : the Button widget class is just an nearly empty class that inherits from Border, provides a facility constructor that would add a label in the Border. So a Button widget is basically a Border Widget. But we want to add the focusability concept. That is the situation where you would use words like interfaces, mixins, traits and roles. I like the concept of Role, and I think it suits the purpose here, so I decided to implement the focusability with a Role.

2. Roles

A Role is basically some features (code, attributes), that are injected in the class, but unlike a mixin, it is possible to see from which roles a class has been built from, and change that. Moose offers a great implementation of Roles, as does Perl6. Alas, I haven't yet converted Curses::Toolkit to Moose, so I needed a pure Perl5 solution : multiple inheritance !

Right, multiple inheritance is wrong, it's bad, it's pure evil. That's what you've been told at least. I have to say it's true, multiple inheritance is very rarely a good thing, and it can generate a lot of issues (and make it inherently more difficult to fix them).

However in this case, I thought I could use it, provided I take care of limiting the use of multiple inheritance to implement Roles, and be careful not creating the infamous diamond-of-death structure.

3. Implementation

Here is how the Curses::Toolkit::Widget::Button class look like :

package Curses::Toolkit::Widget::Button;
use parent qw(Curses::Toolkit::Widget::Border Curses::Toolkit::Role::Focusable);

By inheriting from Border, we get all its attributes and methods. By inheriting from the Focusable role, we also signify that this widget can be focused. Let's look at the content of Curses::Toolkit::Role::Focusable :

package Curses::Toolkit::Role::Focusable;
[...]
sub new {
    my ($class) = shift;
    die "role class, has no constructor";
}
[...]
sub is_focusable {
    my ($self) = @_;
	return 1; # in real life it's less trivial 
}
sub is_focused {
	my ($self) = @_;
	return $self->get_property(basic => 'focused');
}
sub set_focus {
	my $self = shift;
	my ($focus) = validate_pos( @_, { type => BOOLEAN } );

	if ($self->is_focusable()) {
		$self->set_property(basic => 'focused', $focus ? 1 : 0);
[...]

As you can see, we protect users from instantiating this class, and then we implement the various role attributes and methods. This implementation is easy to use and flexible : to know if a widget is focusable, just use :

$widget->isa('Curses::Toolkit::Role::Focusable');

Once you know it's focusable, you can use set_focus, is_focused, etc...

One could also imagine needing to remove the focusability at run time on an existing widget. filtering out Curses::Toolkit::Role::Focusable from its @ISA would do the trick, even if it's not very clean.

So, I know all this is not very modern, and it'll disappear when switching to moose (and Perl6 soon ?), but in the mean time, I just wanted to share this trick. Eh, it's not everyday you can argue positively about multiple inheritance !

PS : I am by no mean a good OO designer, and what I just exposed might be just plain wrong. I'd be more than happy to be enlightened :) If there is a better way to do this in old-school Perl5 way, drop me a note.

Today let's have a look at a widget I'd like to implement in Curses::Toolkit : a Button widget. That doesn't look very difficult, but in fact you'll see it requires that a lot of things are in place under the hood for the Button widget to be fully usable.

At a first glance a button is very basic : it has a border, a label, and you can click on it. Actually, it can have anything inside, not only a label. So a Button can be designed as a widget that inherits from Border, and that has an additional constructor ( new_with_label ), that would create and add a Curses::Toolkit::Widget::Label in the border. The button class is Curses::Toolkit::Widget::Button.

So far so good. However, a button is not a button if you can't click on it. That means a new concept needs to be added : the "click" event, or something similar. But to be able to click it, the user has to be able to focus the button. So here we go, a new concept : focusability !

When a widget has focus, it means that the user can interact with it. But not all widgets can be focused : a border as no interaction to propose to the user, so a border should not receive the focus. However, a button is something that can be interacted with, so it should be able to be focused. To implement that, I decided to use a Role. I'm not yet using Moose in Curses::Toolkit (I'll switch to Moose at some point), so I'll implement Roles using multiple inheritance, a Role being an abstract class. With some care, I shall avoid multiple inheritance caveats. This new Role is called Curses::Toolkit::Role::Focusable. I'll come to the details a bit later.

So when is a widget (that is, the class of the widget) focusable ? When it has the Curses::Toolkit::Role::Focusable role. AND when it's sensitive. Indeed, I'm sure you remember these "grayed-out" widget in modern graphical user interfaces ? It's the sensitivity of the widget that determines if it's normal or grayed-out. When in non-sensitive state, a widget cannot be focused. So again, a new concept : sensitivity. We'll say that upon creations, widgets are sensitive.

Sensitivity, focusability, that's nice, but the user needs to be able to click on the button, and change the focus. We'll start by implementing "clicking" with "pressing a key on the focused widget". We'll see how to support the mouse a bit later. Curses::Toolkit needs to be aware that the keyboard has been used, and have a mechanism to handle the keystrokes. That implies to have some sort of events to send the information related to the keyboard. And also to have some kind of event listeners that the user can set, to listen to an event and act accordingly.

That's indeed a lot of new concepts introduced. We'll see in the next posts how to implement them.

POE-Wheel-GnuPG

| | Comments () | TrackBacks (0)

Today I'd like to present POE::Wheel::GnuPG (source code here ).

I guess you know what GnuPG is. Right, so when you want to encrypt/decrypt data or do other GPG actions in Perl, the best thing to do is to rely on a GnuPG module. I always use GnuPG::Interface because it is very reliable : it's just a wrapper around a fork/exec of the gnupg program installed on your system. Granted, the drawback is that you need gnupg installed and executable, and this is not suitable for all situations. But the benefit is that it's fast, and it's not subject to bugs of pure Perl (or other languages) reimplementation. And it gives you access to all features of GnuPG, like keys management, etc...

So far so good, using GnuPG::Interface is not completely trivial, but it's easy enough. Now, I was trying to solve the following issue : imagine you have a very big encrypted file to decrypt. It's not likely to fit in RAM, but for security (or other reasons), you don't want the decrypted content to be saved in a file. What you want is decrypt the file bits by bits, and process the decrypted file as soon as data are available.

To do that, we'll create a module that interacts with GnuPG::Interface and do non-blocking monitoring of file handles to check when crypted data is needed, and decrypted data is available. I soon realized that this module would be a perfect candidate for a POE::Wheel, as POE provides all necessary tools to monitor file handles and child processes.

Let's see how to use POE::Wheel::GnuPG to do a simple encryption :

  # use POE with the wheel
  use POE qw(Wheel::GnuPG);

  POE::Session->create(
    inline_states => {
      _start => sub {

        # initialize the wheel with the bare minimum
        my $gnupg = POE::Wheel::GnuPG->new(
          ready_to_input_data => 'ready_to_input_data',
          something_on_stdout => 'something_on_stdout',
          end_of_process => 'the_end',
        );
        # Save the gnupg object in the heap for later use
        $_[HEAP]{gnupg} = $gnupg;

        # The Wheel inherits of GnuPG::Interface so
        # it's supports the same options.
        # I indicate that I want an ascii encrypted
        # content, crypted against my gpg key
        $gnupg->options->hash_init(
                        armor   => 1,
                        homedir => '/Users/dams/.gnupg' );
        $gnupg->options->push_recipients('dams@gentoo.org');
        $gnupg->options->meta_interactive( 0 );

        # Let's start the encryption !
        $gnupg->encrypt();
      },

      ready_to_input_data => sub {

        # This is called when gnupg is ready to receive
        # the data to encrypt
        my $input_fh = $_[ARG0];
        print $input_fh "This is the secret data!";

        # This is important to signify gnupg that it should
        # not wait any more data to encrypt
        $_[HEAP]{gnupg}->finished_writing_input();
      },

      something_on_stdout => sub {
          # And now we can read the crypted data
          # from the filehandles
          my $stdout_fh = $_[ARG0];
          return if eof $stdout_fh;
          my @output = <$stdout_fh>;
          print "Received crypted data : @output\n";
      },
      the_end => sub {
          # clean up
          $_[HEAP]{gnupg}->destroy();
          exit();
      },
    }
  );
  POE::Kernel->run();
  exit;

For more detailed usage description, see the POD.

That program performs a simple encryption. In the POD, I provide an example to do asynchronous decryption : check example n°1 in the SYNOPSIS

I used this example to decrypt a big file, printing out the character '.' when sending an encrypted line to the wheel, and printing out 'O' when reading out a decrypted line. Here is the start of the output :

macpro:bin dams$ perl ./test.pl
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................................
..................................O.O.O.O.O.O.O.O.
.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O
.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O
.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O
.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O
.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O
.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O
.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O
.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O
.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O
.O.O.O.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
[...]
.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O
.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O
.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O
.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
[...]

And so on. You can see that the encrypted data is first read to fill up the buffer, then decrypted data is read out at the same time. At some point, there is too much decrypted data to print, that's why there are a lot of 'OOOO's. Then it all starts again :) I think it's a good demonstration of asynchronous GPG decryption !

The previous posts about Curses::Toolkit were basically teasers :)

Now I think it's time to present in more details the concepts.

If you need an introduction to what Curses::Toolkit is, please refer to the first post here ( very briefly, Curses::Toolkit is a modern Curses console based toolkit in Perl).

1. Event Loop and Renderer

By itself the Curses::Toolkit Perl module is only what I would call a
Renderer.

The Renderer is in charge of building the widgets, calculating the various
coordinates, and rendering the widgets using the associated theme. It is
also in charge of processing external events, like keyboard inputs, and internal events, like buttons clicked, etc... However it is not responsible for actually listening to the events.

The event Loop is in charge of listening to system events, and pass them to the
Renderer. It's also in charge of getting internal events from the Renderer, and
handle them when it has time to do so.

Why have two different layers ?

Existing Perl Curses modules mix the event loop with the renderer. That means
the event loops are always reinvented, and in real life they lack features.
It's quite hard to have a good event loop, and you can have a different
orientation if you want your event loop to be multi-thread, online, or
mono-thread oriented.

Separating the two layers makes sense (at least to me) : you can use any Event Loop, provided you build the matching thin wrapper so that
the event communication is compatible.

Let's look at the Renderer Layer.


2. The Renderer

The Curses::Toolkit module is the renderer. The main concepts are :

  • The root window (with a Shape)
  • Windows
  • Widgets (contained in windows) : boxes, buttons, borders, labels, ...

There is only one Root Window. The Root Window is the terminal background, as
you have the root window in X. The Root Window cannot be drawn on directly (it
cannot contain widgets directly), but Windows can be added to it.

Windows are special widgets :

  • they are the only one that can be added in he root window
  • they are the only one that can have absolute positions (or relatives to the Root Window's shape)


Widgets

  • have to be added in a window or another widget
  • cannot have absolute position

I'll show you in future posts some code that make use of the different parts.

Of course, Curses::Toolkit uses Themes to display the widgets. For now however there are only 2 default themes, one colored and one monochrome. By the way I'm facing some difficulties with themes : should the themes allow a flexible way to draw widgets, changing its shape, and making the coordinates calculation depending of the themes ? Or should themes only be a matter of colors ? Let me know what you think.


3. Events

Events are "things that happens". It seems that there are 2 main categories of events : the system ones, and the internal ones.

System events are mainly : keys pressed, root window resized, mouse interaction,
timers, and similar things that are really bound to the system, or external interaction to the program.

Internal (or toolkit) events are basically Widgets interactions : clicks, Window resizing (not Root Window resizing), Panes resizing, drag'n'drop, text added in an Entry, etc.

Finally, there is a Special event that don't really fit in both categories : the Redraw Event. It can be sent by the toolkit (that is, internally), or by the system, and it basically ask the toolkit to redraw itself. Internally there is a difference between redraw() and render(), the first one recalculating the screen, the second one just displaying it. But these are details I don't want to go into in this post.

The events are stored, send and received in a standardized way, specific to Curses::Toolkit. That is, Curses::Toolkit is not able to process any operating specific event, but it has its own event structure and callbacks. That way, I'm sure Curses::Toolkit is system agnostic (and also Event Loop agnostic)

So now we have a Renderer, and Events. Let's talk about the Event Loop.


4. The Event Loop

The goal is to provide Curses::Toolkit with at least one working Event Loop,
and its compatibility layer, so that it is usable straight away. Later on,
development will be done to add more event loops, if needed.

For the start, Curses::Toolkit will use POE as Event Loop. POE is probably the
best thing around these days, and is very easy to use.

POE::Component::Curses is the default (and for now only) Event Loop for Curses::Toolkit.

  • it spawns a Curses Toolkit object
  • it listens to system events (keyboard, Root Window resizing, timers, etc)
  • it also listens to the Special Event (redraw)
  • it instanciates a POE::Component::Curses::Mainloop

POE::Component::Curses::Mainloop is the compatibility (or translation) layer. It translates the POE events into Curses::Toolkit events back and forth.


5. A word of warning

These concepts are part of a work in progress. I may change them, or remove/add layers if needed. However, I'd love to hear any feedbacks you have :)


Curses::Toolkit (part 3)

| | Comments () | TrackBacks (0)

Hi !
Here is an other small video of new features of Curses::Toolkit

I promise, the next post will be more verbose, and explain more about the architecture. But there is still few things to say about this video.

As you can probably see, this video demonstrates that Curses::Toolkit handles properly window resizing. But to be able to do so, Curses::Toolkit needs to listen to the window resizing signal and handle it. That means that there is some kind of event loop somewhere. The event loop is POE::Component::Curses, a new module I introduced. This module listens to keyboard and system signals, spawns a Curses::Toolkit object for you, and uses POE::Component::Curses::Mainloop to bridge to it, and redirect back and forth the event to / from the Curses::Toolkit object. I'll explain that in details in a next post.

This video shows a visible border and a label, ajusting to the terminal window. That is possible because I have now introduced Widget::Window coordinates that can be proportionals to the terminal window, that is known as the Root Window. The Root Window now has a Curses::Toolkit::Object::Shape, to store the Root Window size, and future other status flags.

So now, the link to POE is done, I have a rudimentary keyboard and window size events handler. I'll now concentrate on better keyboard and internal events (like button pressed, etc...) handling. Then I'll add new widgets.

In the mean time, enjoy this video. At the end, I include the code used to produce this.




And here is the source code.


    use POE::Component::Curses;
    use Curses::Toolkit::Widget::Window;
    use Curses::Toolkit::Widget::Border;
    use Curses::Toolkit::Widget::Label;

    my $root = POE::Component::Curses->spawn();

    $root->add_window(
        my $window = Curses::Toolkit::Widget::Window
          ->new()
          ->add_widget(
            my $border1 = Curses::Toolkit::Widget::Border
              ->new()
              ->add_widget(
                my $label1 = Curses::Toolkit::Widget::Label
                  ->new()
                  ->set_text('This demonstrates the use of Curses::Toolkit used with its POE Event Loop : POE::Component::Curses. Keyboard events and window resizing are supported')
              ),
          )
          ->set_coordinates(x1 => 0,   y1 => 0,
                            x2 => '100%',
                            y2 => '100%',
                          )
      );
	POE::Kernel->run();

Curses::Toolkit (part 2)

| | Comments () | TrackBacks (0)

Following my previous post, here is an update of what Curses::Toolkit can do.

As you can see on this small video, Curses::Toolkit is happy to manage VBoxes, HBoxes, borders, wrapping labels. The most difficult part is done, now I can say that the coordinates are properly calculated in all cases. Coding using Curses::Toolkit is really like oding in GTK, and that's what I wanted.

There is a lot more to come though :

  • I have started POE::Component::Curses, and guess what, it's already working a bit.
  • Next week I'll give a code example on how to use Curses::Toolkit (with or without POE).
  • If everything goes well, I'll be able to give a talk about it at the FPW'09 (you are coming there, aren't you ?)

All this is still in alpha stage, but I'm happy with the code architecture for now, so with a bit of luck, I should be able to release a beta to CPAN soonish.

The code is available on github, the project is registered on ohloh.

Open msg files on Mac OS X

| | Comments () | TrackBacks (0)

I've been given a .msg file that contains important information for me to read.

.msg files are email messages saved from Outlook. As you guess, it uses a crazy file format that is everything but compatible.

Now, how to open that file on Mac OS X ? Many solutions are available when looking on internet, but the one I found almost all involve one of :

  • Mac OS Classic
  • Entourage for Mac
  • Outlook Express on some (virtual) machine
  • Thunderbird
  • ...

Then I found MSGConvert : a Perl script that uses Email::Outlook::Message and some other modules to extract text from .msg files. Warning, this script will probably fail extracting non text data from .msg files.

However, this script should work properly on any Mac !

Let's start by opening a Terminal window and firing cpan :

$ sudo cpan

Enter your password, and type this on one line :

install Email::Outlook::Message Email::LocalDelivery Getopt::Long
 Pod::Usage File::Basename

cpan will probably need dependencies to be installed. It will ask you if you want cpan to get and install them for you. Hit Enter each time.

When everything is installed (if it fails drop me a note), you can now use the converter script :

perl msgconvert.pl the_file.msg

This will create a .mime file in the same directory. Open the Finder and double click on this .mime file. It will create a new file ending with .attachment00 or similar. That's it !

Now open that .attachment00 with TextEdit, and you should see the text content of the original .msg file

July 2009

Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
www.flickr.com
Voici un module Flickr utilisant des photos publiques de damsieboy. Cliquez ici pour créer votre module.
-->

Ohloh

My Flickr

www.flickr.com
Voici un module Flickr utilisant des photos publiques de damsieboy. Cliquez ici pour créer votre module.

My Trips