Prezentari cu S5 – partea a 2-a
Dupa cum ziceam in articolul de ieri, toate bune si frumoase cu slide-urile in S5 (chiar, dat fiind ca nu sunt diapozitive, mai are rost sa le zicem "slide-uri"? Oh well...), dar formatul are doua dezavantaje care se vad dupa prezentarea propriu-zisa: nu e single-file, ceea ce face putin mai dificil copiatul prin alte parti, si nu poate fi usor uploadabil pe slideshare (sunt unii carora le pasa). Raspunsul la aceste situatii ar fi un pdf.
S5 vine cu stylesheeturi pt. print dar, guess what, sunt gandite pentru hartie, nu pentru ecran. Adica apare frumos textul pe pagina, eventual cu headere si footere, fara "efecte". Ceea ce are foarte multa noima la o prezentare propriu-zisa, cu mult content, dar la cea a mea cu cate doua vorbe per slide, ies niste pagini goale (sunt putin vinovat pt. ca am introdus un page break dupa fiecare slide, la prima incercare de a face print to file).
Solutia ar fi randarea cu un browser propriu-zis care sa faca toate pozitionarile,si luata cate o captura de ecran la fiecare click. Daca pana acum ceva vreme, asta ar fi fost munca manuala, se poate automatiza cu Selenium, asta fiind si o ocazie foarte faina de a ma juca cu aceasta tehnologie
Selenium (sau cel putin selenium-rc cu care m-am jucat) e o aplicatie care porneste un browser si interactioneaza cu el intr-un mod destul de apropiat de un utilizator uman, fiind o aplicatie gandita pentru testarea site-urilor dependente de JS si CSS, la care abordari traditionale gen WWW::Mechanize nu functioneaza.
Din cauza ca selenium-rc nu e impachetat pentru Debian (exista un RFP, bugul #552096, poate s-o gasi un binevoitor), am downloadat arhiva de la ei de pe site, e vorba de fapt de un singur .jar. Dupa aceea am facut un program in perl care sa-l manipuleze (folosind modulul WWW::Selenium, din pachetul libtest-www-selenium-perl) si care sa dea clicuri si sa salveze screenshoturi.
Inainte sa trec la programul propriu-zis, cateva precizari:
- am laptop dual-stack, asa ca java s-a legat doar pe [::1] implicit, iar WWW::Selenium se supara daca-i dau adrese dintr-astea, asa ca a trebuit sa rulez un sysctl net.ipv6.bindv6only=0 inainte;
- ca sa nu depind de Xorg, am folosit Xvfb (aptitude install xvfb) pentru a avea un framebuffer separat. L-am pornit cu o rezolutie ceva mai "speciala" ca sa obtin rezolutia pe care o voiam la screenshot (maximize minus toolbars), mi-au iesit 141 de pixeli pe verticala si 0 pe orizontala, dar YMMV;
- xvfb a fost pornit cu Xvfb :99 -screen 0 800x741x24 -ac si lasat in background, dupa care am pornit selenium cu DISPLAY=:99 java -jar selenium-server.jar, lasat si el in background;
- la incarcarea paginii dau un refresh, intrucat rutina de font scaling din ui/default/slides.js are uneori probleme cu gecko care se rezolva la refresh (documentat si in cod);
- am pus un sleep de 0.15 sec (fair dice roll value) intre clickuri, intrucat imi ieseau unele screenshoturi incomplete si am zis ca de la repozitionarea css-ului, aparent a ajutat;
- am incercat cu diverse scamatorii de selectori sa obtin slide-ul curent, dar din cauza ca n-aveam cum obtine via xpath sau css selectors (in cazul particular al S5, din cauza ca jongleaza cu proprietati de css dupap care nu pot face query-uri directe), asa ca m-am folosit de variabilele din javascript direct, cu get_eval. De notat ca scriptul presupune ca n-am vreo secventa pe ultimul slide si face un singur screenshot;
- n-am reusit (nu stiu de ce) sa fac trigger direct la eventul "onclick", asa ca dau click pe div-ul "master" la coordonatele (10,10) - iarasi fair dice roll, cat sa n-ajunga in dreapta jos sa risc sa dea peste controalele de navigare;
- dupa ce am salvat png-urile, le-am concatenat intr-un PDF cu imagemagick, cu "convert /tmp/slides-*png slides.pdf"
Uite si perlachele:
#!/usr/bin/perl -w
use strict;
use warnings;
use WWW::Selenium;
use Time::HiRes;
sub screenshot {
my ( $sel, $basename, $id ) = @_;
$sel->capture_entire_page_screenshot(
$basename . sprintf( '%02d', $id ) . '.png', '' );
Time::HiRes::usleep(150);
}
my $url = 'file:///home/petre/Desktop/slides-februarie/index.html';
my $rc = WWW::Selenium->new(
host => 'localhost',
port => 4444,
browser => '*firefox',
browser_url => 'http://localhost/',
);
$rc->start;
$rc->open($url);
$rc->window_maximize;
$rc->refresh;
$rc->wait_for_page_to_load(1000);
my $last_slide = $rc->get_eval('window.smax');
my $num = 1;
screenshot( $rc, '/tmp/slides-', $num );
while ( $rc->get_eval('window.snum') < ( $last_slide - 1 ) ) {
$rc->click_at( q{//div[@class='presentation']}, '10,10' );
screenshot( $rc, '/tmp/slides-', ++$num );
}
$rc->stop;
Cui ii place cu culori, e disponibil si in format html. Ask me anything!