List ebooks with HTML::Pager

自从皈依了FOSS,盗版软件是不用了,电子书还是照下不误。曾经想过用apache和scuttle来管理,然而使用起来仍然很麻烦,所以找书的时候还是到各个目录里面去翻。

feedman的时候学会了HTML::Pager,于是写了一个简单的CGI脚本,放到电子书的根目录下。缺省情况下,apache打开一个目录的样子很难看,而且长一点的文件名都被截断了,偏偏电子书的文件名都很长。这个CGI程序的作用就是输出一个文件列表,提供完成的文件名和链接。程序出奇的简单,首先用File::Find找出想要列出的文件,如所有的chm和pdf文件。

#!/usr/bin/perl -T

use File::Find;
use HTML::Pager;
use CGI;
use URI::Escape;
use File::Basename;

my @books;
find({ wanted => sub{ push @books $_ if /.(?:chm|pdf)$/ },
       no_chdir => 1 },
     '.');

my $num_of_books = scalar @books;

这样,所有的文件名就保存在数组@books里面,文件总数保存在变量$num_of_books里面。接下来我们要写一个函数,从@books中抽取出部分文件,供HTML::Pager输出到页面上。

sub list_book_callback {
  my ($offset, $rows) = @_;
  my $current_books;

  for my $b ($offset .. $offset + $rows - 1) {
    last if $b == $num_of_books;
    my $filename = $books[$b];
    $filename =~ s{^./}{};
    my $url = 'http://localhost/book/'
              . uri_escape($filename);
    my $title = basename($filename);
    if ($title =~ /^(?:ch(?:apter)?)?d+.(?:chm|pdf)$/i) {
         $title = $filename;
    }
    push @current_books, [ qq(<a href="$url">$title</a>) ];
  }
  return @current_books;
}

这段函数对文件名做了一些特殊的处理,一般来讲,文件名即书名,我们可以去掉路径部分。而有些特殊的文件名字可能为ch01.pdf或ch02.pdf等等,上一层目录名才是书名,这时就将路径和文件名一起输出。最后就是用HTML::Pager生成列表并用CGI输出。

my $cgi = CGI->new;

my $pager = HTML::Pager->new
    (query => $cgi,
     get_data_callback => &list_book_callback,
     rows => $num_of_books,
     page_size => 25,
    );

print $cgi->header,
   $cgi->start_html,
   $pager->output,
   $cgi->end_html;

程序运行结果如截图:

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据