yhdev/index.cgi
2011-09-04 12:48:28 +02:00

1160 lines
47 KiB
Perl
Executable file

#!/usr/bin/perl
use strict;
use warnings;
use TUWF ':html';
use Cwd 'abs_path';
our $ROOT;
BEGIN { ($ROOT = abs_path $0) =~ s{index\.cgi$}{}; }
TUWF::register(
qr{} => \&home,
qr{ncdu} => \&ncdu,
qr{ncdu/changes} => \&ncduchangelog,
qr{ncdu/man} => \&ncdumanual,
qr{ncdc} => \&ncdc,
qr{ncdc/faq} => \&ncdcfaq,
qr{ncdc/guide} => \&ncdcguide,
qr{ncdc/changes} => \&ncdcchangelog,
qr{tuwf} => \&tuwf,
qr{tuwf/man(?:/(db|misc|request|response|xml))?}
=> \&tuwfmanual,
qr{dump} => \&dump,
qr{demo} => \&dumpdemo,
qr{dump/awshrink} => \&dumpawshrink,
qr{dump/grenamr} => \&dumpgrenamr,
qr{dump/nccolour} => \&dumpnccolour,
);
TUWF::set(
logfile => '/www/err.log',
error_404_handler => \&notfound,
);
TUWF::run();
# H O M E P A G E
sub home {
my $s = shift;
$s->htmlHeader(title => 'Yorhel\'s projects');
p;
lit <<' E;';
This site is an attempt to publish and organise my various opensource programs
and libraries on one central location, possibly documented as well as possible
so it might actually be useful to anyone. Some of these projects might end up to
be total crap, and some might not be useful to anyone at all. I'll simply try to
dump most of the things I create here, and leave it up to you whatever you decide
to do with it.
E;
end;
h2 'Updates';
b '2011-09-03'; txt ' ncdc 0.9 released!'; br;
b '2011-08-26'; txt ' ncdc 0.8 released!'; br;
b '2011-08-17'; txt ' ncdc 0.7 released!'; br;
b '2011-08-08'; txt ' ncdc 0.6 released & user guide updated'; br;
b '2011-08-02'; txt ' ncdc 0.5 released!'; br;
b '2011-07-23'; txt ' ncdc 0.4 released!'; br;
b '2011-07-15'; txt ' ncdc 0.3 released!'; br;
b '2011-06-27'; txt ' ncdc 0.2 released!'; br;
b '2011-06-20'; txt ' ncdc 0.1 released! And wrote a user guide for it.'; br;
b '2011-06-11'; txt ' Added NCurses colour experiment at code dump => nc-colour'; br;
b '2011-06-03'; txt ' Added my latest project: ncdc'; br;
b '2011-02-07'; txt ' TUWF 0.1 released and now also available on CPAN'; br;
b '2011-01-27'; txt ' Documented and uploaded one of my older projects: TUWF'; br;
b '2011-01-09'; txt ' Added my json.mll OCaml library to code dump'; br;
b '2010-08-13'; txt ' ncdu 1.7 released!'; br;
b '2009-12-22'; txt ' Added vinfo.c script to code dump'; br;
b '2009-10-23'; txt ' ncdu 1.6 released!'; br;
b '2009-09-21'; txt ' Tiny CSS fix to make this site look good in certain configurations.'; br;
b '2009-05-02'; txt ' ncdu 1.5 released!'; br;
b '2009-04-30'; txt " Site redesign and reorganisation."; br;
$s->htmlFooter;
}
# N C D U
sub ncdu {
my $s = shift;
$s->htmlHeader(title => 'NCurses Disk Usage', page => 'ncdu');
img style => 'float: right', src => '/img/ncdu.png', alt => 'ncdu';
p;
lit <<' E;';
Not quite happy with the available disk usage analyzers and looking for a fun
project to get used to C programming, I started working on ncdu: A disk usage
analyzer with an ncurses interface, aimed to be run on a remote server where
you don't have an entire gaphical setup, but have to do with a simple SSH
connection. ncdu aims to be fast, simple and easy to use, and should be able
to run in any minimal POSIX-like environment with ncurses installed.
E;
br; br;
b 'Latest version: ';
txt '1.7 (';
a href => 'http://dev.yorhel.nl/download/ncdu-1.7.tar.gz', 'download';
txt ' - ';
a href => '/ncdu/changes', 'changes';
txt ' - ';
a href => 'http://sourceforge.net/project/showfiles.php?group_id=200175', 'mirror';
txt ' - ';
a href => '/download/ncdu.md5', 'md5';
txt ' - ';
a href => '/download/ncdu.sha1', 'sha1';
txt ")"; br;
b 'Requirements: '; txt 'A POSIX-like system and the ncurses library'; br;
txt 'Entirely written in C and available under a liberal MIT license.';
end;
h2 'Packages and ports';
p 'ncdu has been packaged for various systems already, here\'s a list of the ones I am aware of:';
a href => 'http://www.archlinux.org/packages/?q=ncdu', 'Arch Linux'; txt ' - ';
a href => 'http://crux.nu/portdb/?q=ncdu&a=search', 'CRUX'; txt ' - ';
a href => 'http://cygwin.com/packages/ncdu/', 'Cygwin'; txt ' - ';
a href => 'http://packages.debian.org/ncdu', 'Debian'; txt ' - ';
a href => 'https://admin.fedoraproject.org/pkgdb/acls/name/ncdu', 'Fedora'; txt ' - ';
a href => 'http://www.freshports.org/sysutils/ncdu/', 'FreeBSD'; txt ' - ';
a href => 'http://packages.gentoo.org/package/sys-fs/ncdu', 'Gentoo'; txt ' - ';
a href => 'http://www.ipcopaddons.org/addondb.php?action=detail&addonid=67', 'IPCop'; txt ' - ';
a href => 'http://www.openbsd.org/cgi-bin/cvsweb/ports/sysutils/ncdu/', 'OpenBSD'; txt ' - ';
a href => 'http://packman.links2linux.de/package/ncdu/', 'OpenSUSE'; txt ' - ';
txt 'Mac OS X (';
a href => 'http://ncdu.darwinports.com/', 'Darwin Ports'; txt '-';
a href => 'http://pdb.finkproject.org/pdb/package.php/ncdu', 'Fink';
txt ') - ';
a href => 'http://paketler.pardus.org.tr/info/2009/stable/source/ncdu.html', 'Pardus'; txt ' - ';
txt 'Solaris (';
a href => 'http://www.opencsw.org/packages/ncdu', 'CSW'; txt '-';
a href => 'http://www.sunfreeware.com/', 'sunfreeware';
txt ') - ';
a href => 'http://slackbuilds.org/repository/13.37/system/ncdu/', 'Slackware'; txt ' - ';
a href => 'http://packages.ubuntu.com/search?searchon=sourcenames&keywords=ncdu', 'Ubuntu'; txt ' - ';
a href => 'http://zur.zenwalk.org/view/package/name/ncdu', 'Zenwalk';
br; br;
txt 'Subscribe to ';
a href => 'http://freshmeat.net/projects/ncdu', 'freshmeat';
txt ' or to ';
a href => 'https://sourceforge.net/api/file/index/project-id/200175/mtime/desc/rss', 'this RSS feed at sf.net';
txt ' to receive notifications for new releases.';
h2 'Development access';
p;
txt 'The most recent code is available on a git repository and is ';
a href => 'http://g.blicky.net/ncdu.git/', 'available for online browsing';
txt '.';
end;
h2 'Similar projects';
a href => 'http://gt5.sourceforge.net/', 'gt5'; txt " - Quite similar to ncdu, but a different approach."; br;
a href => 'http://webonastick.com/tdu/', 'tdu'; txt " - Another small ncurses-based disk usage visualization utility."; br;
a href => 'http://treesize.sourceforge.net/', 'TreeSize'; txt " - Same goal, but in GTK this time."; br;
a href => 'http://www.marzocca.net/linux/baobab.html', 'Baobab'; txt " - Another GTK disk usage analyzer, comes with GNOME."; br;
a href => 'http://www.methylblue.com/filelight/', 'Filelight'; txt " - And one for KDE."; br;
$s->htmlFooter;
}
sub ncduchangelog {
my $s = shift;
$s->htmlHeader(title => 'Version history', page => 'ncdu', tab => 'changes');
$s->htmlChangeLog('ncdu');
$s->htmlFooter;
}
sub ncdumanual {
my $s = shift;
$s->htmlHeader(title => 'Manual page', page => 'ncdu', tab => 'man');
open my $F, '<', "$ROOT/dat/ncdu-man" or die $!;
pre;
txt $_ while(<$F>);
end;
close $F;
$s->htmlFooter;
}
# N C D C
sub ncdc {
my $s = shift;
$s->htmlHeader(title => 'NCurses Direct Connect', page => 'ncdc');
p style => 'float:right; margin-top: -27px; font-size: 12px; line-height: 11px';
txt 'Join the development hub! '; b style => 'font-size: 12px', 'adc://dc.blicky.net:2780/';
end;
p;
lit <<' E;';
Ncdc is a modern and lightweight direct connect client with a friendly
ncurses interface.
E;
end;
h2 'Current Status';
p 'Ncdc is currently still in development, and therefore lacks a few features
one would expect from a full-blown DC client. The following is a list of
features that have been implemented so far:';
ul;
li 'Connecting to multiple hubs at the same time,';
li 'Chatting and private messaging,';
li 'Browsing the user list of a connected hub,';
li 'Share management (file list generation, hashing, refreshing, etc),';
li 'Replying to search requests from other clients,';
li 'File uploading in active and passive mode,';
li 'Connections and download queue management,';
li 'File list browsing,';
li 'Single-source and TTH-checked file downloading,';
li 'Searching for files,';
li 'Secure hub (adcs:// and nmdcs://) and client (ADCS) connections.';
end;
h2 'Try it out';
p;
b 'Latest version:'; txt ' 0.9 (';
a href => '/download/ncdc-0.9.tar.gz', 'download';
txt ' - '; a href => '/ncdc/changes', 'changes';
txt ' - '; a href => '/download/ncdc.md5', 'md5';
txt ' - '; a href => '/download/ncdc.sha1', 'sha1';
txt ')'; br;
txt 'You can also get the latest development version of ncdc from ';
a href => 'http://g.blicky.net/ncdc.git/', 'this git repository';
txt '. The README includes instructions to build ncdc.'; br;
txt 'Check out the '; a href => '/ncdc/guide', 'user guide';
txt ' to get started. Connect to adc://dc.blicky.net:2780/ to join the (chat-only) development hub!';
end;
h2 'Requirements';
p;
lit <<' E;';
The following libraries are required: ncurses, bzip2, gdbm, glib2 and libxml2.<br />
For TLS support, you will need at least glib2 version 2.28.0 and
glib-networking installed.<br />
These dependencies should be easy to satisfy. Depending on your system, you
may have all of these installed already.<br />
Ncdc has been developed on a recent Arch Linux installation and has been
tested on FreeBSD 8.2 and Debian Squeeze. I have also received reports from
people who successfully used it on Gentoo, Mac OS X, Ubuntu and CentOS. It
should be fairly trivial to port to other POSIX-like systems.<br />
Ncdc is entirely written in C and available under a liberal MIT license.
E;
end;
$s->htmlFooter;
}
sub ncdcfaq {
my $s = shift;
$s->htmlHeader(title => 'Ncdc Q&A', page => 'ncdc', tab => 'faq');
p 'On this page I collect several questions that people may have and try to
answer them. If you have a question that is not covered here, don\'t hesitate
to ask!';
div class => 'pod';
h2 'What about other text-mode clients?';
p;
a href => 'http://corsair626.no-ip.org/microdc/', 'microdc2';
txt ' - A rather nice client, yet not exactly there. It\'s limited to
connecting to a single hub, hasn\'t been updated since 2006, and the
readline interface is slightly awkward to use.'; br;
a href => 'http://sourceforge.net/projects/nanodc/', 'nanodc';
txt ' - Can\'t comment much on this, except maybe that rocket science is
perhaps easier than getting nanodc to compile.'; br;
txt 'LDCC - Uses DCTC as backend and an interface based on TurboVision.
All mentioned projects are dead: neither LDCC, DCTC nor TurboVision are
seeing any recent development.';
end;
h2 'Why did you start from scratch? Why not use the DC++ core?';
p;
lit <<' E;';
There are many reasons why I chose not to use code from existing projects,
but all of them boil down to the following two: 1) I am a control freak,
and 2) personal preferences.<br />
That is the short answer. The long answer will require a full article,
and I don't feel like writing that much at this point. &gt;_&gt;
E;
end;
h2 'Can ncdc use the hash data or configuration from an existing DC++ installation?';
p 'No, ncdc uses its own configuration and hash storage directory.
However, on popular demand I could write a conversion utility to transfer
the hash data from other clients to ncdc\'s format.';
h2 'Can ncdc run in the background / as a daemon?';
p;
lit <<' E;';
As with most ncurses applications: no. At least, it does not have this
functionality built-in. Ncdc is designed to be used in combination with a
separate terminal multiplexer or detach utility to handle this. Have a look
at <a href="http://www.gnu.org/s/screen/">GNU screen</a>,
<a href="http://tmux.sourceforge.net/">tmux</a> or
<a href="http://dtach.sourceforge.net/">dtach</a>.
E;
end;
h2 'Does ncdc support TLS?';
p;
lit <<' E;';
Yes! To make use of this, however, you need to have relatively new version
of glib2. If you're still working with an outdated system, an alternative
is to use <a href="http://www.stunnel.org/">stunnel</a> to connect to
TLS-enabled hubs. This trick does not allow encrypted client-to-client
connections, so your file transfers will remain unencrypted.<br />
The following example stunnel configuration is what I used to connect to
the DC Development hub before ncdc had native TLS support:</p>
<pre>[dcdev]<br />client = yes<br />accept = 127.0.0.1:16591<br />connect = devpublic.adcportal.com:16591</pre>
<p>The URL `adc://127.0.0.1:16591/' can then be used to connect to the hub
from within ncdc.
E;
end;
h2 'Does ncdc support UPnP?';
p;
lit <<' E;';
Not natively. However, it is possible to use <a
href="http://www.howtoforge.com/administrating-your-gateway-device-via-upnp">this
script</a> and manually keep a port open using a cron job. I have no
experience with this myself, though. I just run ncdc directly on my router. :-)
E;
end;
h2 'What protocol features does ncdc support?';
p;
lit <<' E;';
For ADC: BASE, RF, TIGR, BZIP, ADCS and KEYP.<br />
For NMDC: NoGetINFO, NoHello, MiniSlots, XmlBZList, ADCGet, TTHL and TTHF.<br />
That is pretty much everything you'd expect any modern client to have. Note
that ncdc does not support some of the older NMDC protocol features, like $Get,
$GetZBlock, $CHUNK, $Cancel or non-XML file lists. I am not aware of an
other up-to-date client that still uses any of these features.
E;
end;
end 'div';
$s->htmlFooter;
}
sub ncdcguide {
my $s = shift;
$s->htmlHeader(title => 'Ncdc User Guide', page => 'ncdc', tab => 'guide');
p 'Since the built-in documentation of ncdc is not really complete yet, it
may be a bit hard to use for first-timers. This is a short guide to help
you get started with ncdc and to make up for the lack of proper
documentation. I\'m assuming that you already managed to install a recent
version of ncdc.';
h2 'Starting up';
p 'Simply run `ncdc\', and you should see something like the following screenshot:';
img src => '/img/ncdcstart.png', style => 'margin: 5px 0 0 10px; border: 1px solid #999', alt => 'Ncdc start-up screen.';
h2 'Basic settings';
p 'When you just started ncdc, the first thing you want to do is to change some basic settings:';
pre class => 'code';
txt '/set nick '; b 'MyNick';
end;
p 'And optionally, you may also want to change these:';
pre class => 'code';
txt '/set description '; b 'ncdc is awesome!'; br;
txt '/set connection '; b '10'; br;
txt '/set email '; b 'user@example.com';
end;
p 'What you can use with the \'connection\' setting is a bit vague, but
you\'re safe if you just set it to your upload speed, in MBit/s. On public
hubs, you probably don\'t want to set an email address.';
p 'Note: these settings can also be changed on a per-hub basis. More on that below.';
h2 'Sharing';
p 'You can skip this section if you don\'t intent to share any files. To add a directory to your share, use the following command:';
pre class => 'code';
txt '/share '; b 'Virtual_name /path/to/actual/dir';
end;
p "And '/path/to/actual/dir' will be shared under the virtual directory
'Virtual_name', for which you are free to choose a name. Ncdc will
automatically index and hash the files in this directory. You can use
'/unshare' to remove a directory from your share and '/refresh' to
manually keep the index updated on changes. A refresh is automatically done
every hour by default, but can be changed using '/set autorefresh'.";
h2 'Active vs. passive';
p 'By default ncdc will use passive mode. If you are connected directly to
the internet or are behind a router that allows port forwarding, you will
probably want to enable active mode. To do so, issue the following
commands:';
pre class => 'code';
txt '/set active_ip '; b $s->reqIP; br;
txt '/set active_port '; b '34194'; br;
txt '/set active '; b 'true';
end;
p "And make sure the port you specified is properly forwarded for both TCP and UDP.";
h2 'Connecting to hubs';
p "This is where ncdc differs a bit from other DC or even IRC clients. To
connect to a hub, you first need to name and open a 'hub tab', after which
you can use '/connect' to actually connect to the hub:";
pre class => 'code';
txt '/open '; b 'ncdc'; br;
txt '/connect '; b 'adc://dc.blicky.net:2780/';
end;
p "The name you specify with '/open' will be used by ncdc to refer to this
hub. After this, you can always reconnect to this hub simply by typing '/open
ncdc', without having to use the '/connect' again.";
p "Some settings can be changed on a per-hub basis, for example your nick.
Using the '/set' command on a hub tab will change the setting only for that
hub. You can use '/unset' to change a setting back to its global value.";
h2 'Global keybindings and commands';
p "You have probably noticed that '/open' created a new tab, and are probably
wondering how to switch between multiple tabs and do other funky stuff. The
following ASCII table lists some of the global keybindings you can use:";
pre class => 'code';
b 'Alt+j'; txt ' open previous tab.'; br;
b 'Alt+k'; txt ' open next tab.'; br;
b 'Alt+h'; txt ' move current tab left.'; br;
b 'Alt+l'; txt ' move current tab right.'; br;
b 'Alt+<num>'; txt ' open tab with number <num>.'; br;
b 'Alt+c'; txt ' close current tab.'; br;
b 'Alt+n'; txt ' open the connections tab.'; br;
b 'Alt+q'; txt ' open the download queue.'; br;
b 'Alt+o'; txt ' open own file list.'; br;
b 'Ctrl+c'; txt ' quit ncdc.'; br;
end;
p "Lots of functionality is hidden behind commands and settings, use '/help'
to get a list of the commands and '/help <command>' for information about a
specific commands. '/set' can be used to get the list of available
settings, but these are not documented yet.";
h2 'User list';
p "To open the user list of a hub, use the '/userlist' command or hit Alt+u.
Here's a list of the keys you can use:";
pre class => 'code';
b 'j'; txt ' scroll down.'; br;
b 'k'; txt ' scroll up.'; br;
b 'l'; txt ' open selected directory.'; br;
b 'h'; txt ' open parent directory.'; br;
b 's'; txt ' order by share size.'; br;
b 'u'; txt ' order by username.'; br;
b 'o'; txt ' toggle sort OPs before others.'; br;
b 'd'; txt ' toggle description column.'; br;
b 'e'; txt ' toggle email column.'; br;
b 'c'; txt ' toggle connection column.'; br;
b 'i'; txt ' toggle information box.'; br;
b 'm'; txt ' PM the selected user.'; br;
b 'b'; txt ' browse the selected users\' list.'; br;
end;
h2 'Searching';
p "To search for files to download, use the '/search' command:";
pre class => 'code';
lit '/search <b>gentoo</b>';
end;
p style => 'font-size: 9px; padding-left: 25px; padding-bottom: 3px',
"My apologies for using such a generic search term as example. It just
happens to be one that doesn't advocate piracy yet gives some results on
most hubs.";
p "See '/help search' for more options. A new tab will be opened with the
search results, where the following keys can be used:";
pre class => 'code';
b 'j/k'; txt ' the usual down/up keys.'; br;
b 'b'; txt ' browse users\' file list.'; br;
b 'd'; txt ' add selected file to download queue.'; br;
b 'f'; txt ' find user in the user list.'; br;
b 'h'; txt ' show/hide hub column.'; br;
b 'u'; txt ' order by username.'; br;
b 's'; txt ' order by file size.'; br;
b 'l'; txt ' order by available slots.'; br;
b 'n'; txt ' order by file name.'; br;
end;
h2 'Browsing file lists';
p "If you were paying attention to the previous sections, you would have
noticed that three ways to open a file list have been mentioned: The global
Alt+o key to open your own, the 'b' key in the user list to browse a users'
list, and a similar 'b' key for the search results. There is a fourth
method, and that is the '/browse' command, see '/help browse' for details
on that one. Regardless of how you open a file list, the following keys
are available while browsing one:";
pre class => 'code';
b 'j/k'; txt ' the usual down/up keys. (this is getting boring)'; br;
b 'l'; txt ' open selected directory.'; br;
b 'h'; txt ' open parent directory.'; br;
b 'd'; txt ' add selected file to download queue.'; br;
end;
h2 'Download queue management';
p "Both the the search results and the file list browser have a 'd' key to
add a file to the download queue. Any queud files will be downloaded
automatically and this process will usually not require any further input.
Nonetheless, there is a download queue manager which can be accessed with
the global Alt+q key. The following keys can be used on this tab:";
pre class => 'code';
b 'j/k'; txt ' again, the down/up keys.'; br;
b 'f'; txt ' find user in the user list.'; br;
b 'd'; txt ' remove selected file from the queue.'; br;
b 'c'; txt ' find the related download connection in the connection list.'; br;
b '+'; txt ' increase download priority.'; br;
b '-'; txt ' decrease download priority.'; br;
end;
p "A little note on the download priorities: if you see that an item has
'ERR' as priority, this means that something went wrong while downloading.
In these cases you have two choices: remove the item from the queue ('d'
key), or tell ncdc to try it again by clearing the error status (that is,
by increasing the priority. That is, the '+' key.).";
h2 'Connection management';
p 'Last but not least, you can also monitor your currently active uploads and
downloads with the connections tab, which can be accessed with Alt+n. Keys:';
pre class => 'code';
b 'j/k'; txt ' guess.'; br;
b 'd'; txt ' disconnect selected connection.'; br;
b 'i'; txt ' toggle information box.'; br;
b 'f'; txt ' find user in the user list.'; br;
b 'q'; txt ' find item in the download queue.'; br;
end;
$s->htmlFooter;
}
sub ncdcchangelog {
my $s = shift;
$s->htmlHeader(title => 'Version history', page => 'ncdc', tab => 'changes');
$s->htmlChangeLog('ncdc');
$s->htmlFooter;
}
# T U W F
sub tuwf {
my $s = shift;
$s->htmlHeader(title => 'The Ultimate Website Framework', page => 'tuwf');
lit <<' E;';
TUWF is a very small and lightweight web development framework for Perl. It
has evolved from being a few abstraction layers in two large websites to a
separate set of modules. While initially designed to be used for large and
complex websites, it is also perfectly suited for small single-file
websites.
E;
h2 'Main features';
ul;
li 'Very small, and no extra modules required,';
li 'Easy URI-to-function mapping using regular expressions,';
li 'Handy form validation functions,';
li 'Easy XML/XHTML output generation functions,';
li 'Response buffering and output compression,';
li 'Easy access to GET/POST data and cookies,';
li 'Support for CGI and FastCGI - optimized for FastCGI,';
li 'Uses UTF-8 for all text,';
li 'Convenient SQL execution functions and correct transaction handling,';
li 'Promotes code re-use,';
li 'Open source (duh!) and available under a liberal MIT license.';
end;
lit <<' E;';
Read the <a href="/tuwf/man#DESCRIPTION">description</a> in the
documentation for more information and details.
E;
h2 'Download';
p;
lit <<' E;';
<b>Latest packaged version:</b> 0.1 (<a href="/download/TUWF-0.1.tar.gz">download</a>
- <a href="http://search.cpan.org/dist/TUWF/">CPAN mirror</a>)
<br />
TUWF is also available on a git repository at <a href="http://g.blicky.net/tuwf.git/">
http://g.blicky.net/tuwf.git/</a>.
E;
end;
h2 'Websites using TUWF';
txt '(Not a whole lot)';
ul;
li;
a href => 'http://vndb.org/', 'VNDB.org';
txt ' (the site that spawned TUWF - ';
a href => 'http://g.blicky.net/vndb.git/', 'open source';
txt ')';
end;
li;
a href => 'http://dev.yorhel.nl/', 'This website'; txt ' (also ';
a href => 'http://g.blicky.net/yorhel-dev.git/tree/index.cgi', 'open source'; txt ')';
end;
li;
a href => 'http://p.blicky.net/', 'Blicky.net Pastebin'; txt ' (';
a href => 'http://g.blicky.net/bpaste.git/tree/index.cgi', 'open source'; txt ')';
end;
li; txt 'The website embedded in the '; a href => 'http://www.d-r.nl/AXUM/AXUM.htm', 'D&R Axum'; txt ' mixing console.'; end;
li; a href => 'http://yorhel.nl/', 'Yorhel.nl'; end;
end;
$s->htmlFooter;
}
sub tuwfmanual {
my $s = shift;
my $man = shift || '';
$s->htmlHeader(title => 'TUWF Documentation', page => 'tuwf', tab => 'man');
my %mod = (qw|db DB xml XML|);
for ('', qw|db misc request response xml|) {
my $n = 'TUWF'.($_ ? '::'.(($mod{$_} || ucfirst $_)) : '');
txt ', ' if $_;
a href => '/tuwf/man'.($_ ? "/$_" : ''), $n
if $_ ne $man;
b $n if $_ eq $man;
}
br; br;
my $mod = 'TUWF';
$mod .= '/'.($mod{$man} || ucfirst $man) if $man;
(my $f = $INC{"$mod.pm"}) =~ s/\.pm$/.pod/;
$s->htmlPOD($f);
$s->htmlFooter;
}
# C O D E D U M P
sub dump {
my $s = shift;
$s->htmlHeader(title => 'Code Dump', page => 'dump');
p 'Most of the things I write are simple perl/shell scripts or programs that only '
.'serve the purpose of learning something new. This page is a listing of those I '
.'thought might be of interest to others as well.';
h2 'bbcode.c';
p;
txt 'January 2006. Simple BBCode to HTML converter written in plain C, for learning '
.'puroses. ';
a href => '/download/code/bbcode.c', 'source';
end;
h2 'echoserv.c';
p;
txt 'February 2006. A simple non-blocking single-threaded TCP echo server, '
.'displaying how the select() system call can be used to handle multiple '
.'connections. ';
a href => '/download/code/echoserv.c', 'source';
end;
h2 'yapong.c';
p;
txt 'Feburary 2006. Yet Another Pong, and yet another program written just for testing/'
.'learning purposes. Tested to work with the ncurses or pdcurses libraries. ';
a href => '/download/code/yapong.c', 'source';
txt ' (';
a href => '/download/code/yapong-0.01.c', '0.01';
txt ')';
end;
h2 'Microdc2 log file parser';
p;
lit <<' E;';
June 2007. Simple perl script that parses log files created by
<a href="http://corsair626.no-ip.org/microdc/">microdc2</a> and outputs a simple and
ugly html file with all uploaded files. It correctly merges chunked uploads, calculates
average upload speed per file and total bandwidth used for uploads.
E;
a href => '/download/code/mdc2-parse.pl', 'source';
end;
h2 'vinfo.c';
p;
lit <<' E;';
November 2009. The <a href="http://vndb.org/d11">public VNDB API</a> was designed to be
easy to use even from low level languages. I wrote this simple program to see how much
work it would be to use the API in C, and as example code for anyone wishing to use the
API for something more useful. Read the comments for more info.
E;
a href => '/download/code/vinfo.c', 'source';
end;
h2 'json.mll';
p;
lit <<' E;';
December 2010. I was writing a client for the <a
href="http://vndb.org/d11">public VNDB API</a> in OCaml and needed a JSON
parser/generator. Since I wasn't happy with the currently available
solutions - they try to do too many things and have too many dependencies -
I decided to write a minimal JSON library myself.
E;
a href => 'http://g.blicky.net/serika.git/tree/json.mll', 'source';
end;
$s->htmlFooter;
}
sub dumpdemo {
my $s = shift;
$s->htmlHeader(title => 'Demos', page => 'dump', tab => 'demo');
p;
lit <<' E;';
Yes, I realise that the title is plural, suggesting there's more than one demo. That is
not quite true, unfortunately. The reason I chose to use plural form is simply in the
hopes that I do, in fact, write more demos, and that this page will actually get more
content in the future. I still happen to be a huge fan of the <a href="http://demoscene.info/">
demoscene</a>, and still wish to contribute to it... if only I could find the time and
self-discipline to do so. In the meanwhile, here's one demo I did write some time ago:
E;
end;
h2 'Blue Cubes';
img src => '/img/bluecubes.png', style => 'float: right', alt => 'Blue Cubes';
p;
lit <<' E;';
August 2006. My first demo - or more exact: intro. Blue Cubes is a 64kB intro written in
OpenGL/SDL with Linux as target OS. I wrote this intro within 10 days without any prior
experience in any of the fields of computer generated graphics or music. So needlessly to
say, it sucks. I am ashamed even of the thought of releasing it at a respectable demoparty
like <a href="http://www.evoke.eu/2006/">Evoke</a>. Still, it didn't feel I was unwelcome,
I did actually receive three prices: 3rd price in the 64k competition (there were only 3
actual entries, but oh well), best non-windows 64k intro (it was the only one in the
competition), and the Digitale Kultur newcomer award, which actually is something to be
proud of, I guess.
E;
br; br;
a href => '/download/yorhel~bluecubes.zip', 'download';
txt ' - ';
a href => 'http://scene.org/file.php?file=/parties/2006/evoke06/in64/yorhel_bluecubes.zip&fileinfo', 'mirror';
txt " (includes linux binaries, windows port, and sources)"; br;
a href => 'http://pouet.net/prod.php?which=25866', 'pouet'; txt ' - ';
a href => 'http://demoscene.tv/page.php?id=172&lang=uk&vsmaction=view_prod&id_prod=12653', 'demoscene.tv'; txt ' - ';
a href => 'http://demozoo.org/productions/32253', 'demozoo';
end;
$s->htmlFooter;
}
sub dumpawshrink {
my $s = shift;
$s->htmlHeader(title => 'AWStats data file shrinker', page => 'dump', tab => 'awshrink');
p;
txt 'People who run AWStats on large log files have most likely noticed: the data files can '
.'grow quite large, resulting in both a waste of disk space and longer page generation '
.'times for the AWStats pages. I wrote a small script that analyzes these data files and '
."can remove any information you think is unnecessary.";
br; br;
b 'Download: ';
a href => '/download/code/awshrink', 'awshrink';
txt ' (copy to /usr/bin to install)';
end;
h2 'Important';
txt 'Do NOT use this script on data files that are not completed yet (i.e. data files of the '
.'month you\'re living in). This will result in inaccurate sorting of visits, pages, '
.'referers and whatever other list you\'re shrinking. Also, keep in mind that this is just '
.'a fast written perl hack, it is by no means fast and may hog some memory while shrinking '
.'data files.';
h2 'Usage';
pre class => 'code', q|awshrink [-c -s] [-SECTION LINES] [..] datafile
-s Show statistics
-c Overwrite datafile instead of writing to a backupfile (datafile~)
-SECTION LINES
Shrink the selected SECTION to LINES lines. (See example below)|;
h2 'Typical command-line usage';
p 'While awshrink is most useful for monthly cron jobs, here\'s an example of basic command line '
.'usage to demonstrate what the script can do:';
pre class => 'code', join "\n", grep s/^\s{4}//||1, split /\n/, <<' E;';
$ wc -c awstats122007.nedtlyrics.txt
29916817 awstats122007.nedtlyrics.txt
$ awshrink -s awstats122007.nedtlyrics.txt
Section Size (Bytes) Lines
SCREENSIZE* 74 0
WORMS 131 0
EMAILRECEIVER 135 0
EMAILSENDER 143 0
CLUSTER* 144 0
LOGIN 155 0
ORIGIN* 178 6
ERRORS* 229 10
SESSION* 236 7
FILETYPES* 340 12
MISC* 341 10
GENERAL* 362 8
OS* 414 29
SEREFERRALS 587 34
TIME* 1270 24
DAY* 1293 31
ROBOT 1644 40
BROWSER 1992 127
DOMAIN 2377 131
UNKNOWNREFERERBROWSER 5439 105
UNKNOWNREFERER 20585 317
SIDER_404 74717 2199
PAGEREFS 130982 2500
KEYWORDS 288189 27036
SIDER 1058723 25470
SEARCHWORDS 5038611 157807
VISITOR 23285662 416084
* = not shrinkable
$ awshrink -s -c -VISITOR 100 -SEARCHWORDS 100 -SIDER 100 awstats122007.nedtlyrics.txt
Section Size (Bytes) Lines
SCREENSIZE* 74 0
WORMS 131 0
EMAILRECEIVER 135 0
EMAILSENDER 143 0
CLUSTER* 144 0
LOGIN 155 0
ORIGIN* 178 6
ERRORS* 229 10
SESSION* 236 7
FILETYPES* 340 12
MISC* 341 10
GENERAL* 362 8
OS* 414 29
SEREFERRALS 587 34
TIME* 1270 24
DAY* 1293 31
ROBOT 1644 40
BROWSER 1992 127
SEARCHWORDS 2289 100
DOMAIN 2377 131
SIDER 3984 100
UNKNOWNREFERERBROWSER 5439 105
VISITOR 5980 100
UNKNOWNREFERER 20585 317
SIDER_404 74717 2199
PAGEREFS 130982 2500
KEYWORDS 288189 27036
* = not shrinkable
$ wc -c awstats122007.nedtlyrics.txt
546074 awstats122007.nedtlyrics.txt
E;
$s->htmlFooter;
}
sub dumpgrenamr {
my $s = shift;
$s->htmlHeader(title => 'GTK+ Mass File Renamer', page => 'dump', tab => 'grenamr');
p;
lit <<' E;';
GRenamR is a GTK+ mass file renamer written in Perl, the functionality is insipred
by the <a href="http://search.cpan.org/~rmbarker/File-Rename-0.05/rename.PL">rename</a>
command that comes with a Perl module.<br />
<br />
GRenamR allows multiple file renaming using perl expressions. You can see the effects
of your expression while typing it, and can preview your action before applying them.
The accepted expressions are mostly the same as the rename command (see above paragrah):
your expression will be evaluated with $_ set to the filename, and any modifications
to this variable will result in the renaming of the file. There's one other variable
that the rename command does not have: $i, which reflects the file number (starting from
0) in the current list. This allows expressions such as as <code>$_=sprintf'%03d.txt',$i</code>.
E;
br; br;
b 'Download: ';
a href => '/download/code/grenamr-0.1.pl', 'grenamr';
txt " (copy to /usr/bin/ to install)"; br;
txt "Requires the Gtk2 Perl module (most distributions have a perl-gtk2 package)"; br;
end;
h2 'Example expressions';
table;
Tr; td style => 'width: 40%'; code 'y/A-Z/a-z/'; txt ' or '; code '$_=lc'; end; td 'Convert filenames to lowercase'; end;
Tr; td; code 's/\.txt$/.utf8/'; end; td "Change all '.txt' extensions to '.utf8'"; end;
Tr; td; code q|s/([0-9]+)/sprintf'%04d',$1/eg|; end; td 'Zero-pad all numbers in filenames'; end;
Tr; td; code q|s/^.+\.jpg$/sprintf'%03d.jpg',$i+1/e|; end; td 'Replace each image filename with a zero-padded number starting from 1'; end;
end;
h2 'Caveats / bugs / TODO';
ul;
li q|Calling functions as 'sleep' or 'exit' in the expression will trash the program|;
li q|It's currently not possible to manually order the file list, so $i is not useful in every situation|;
li q|It's currently not possible to manually rename files or exclude items from being effected by the expression|;
li; lit q|The expression isn't executed in the opened directory, so things like
<a href="http://perldoc.perl.org/functions/-X.html">-X</a> won't work|; end;
end;
h2 'Screenshot';
img src => '/img/grenamr.png', alt => 'GRenamR';
$s->htmlFooter;
}
sub dumpnccolour {
my $s = shift;
$s->htmlHeader(title => 'Colours in NCurses', page => 'dump', tab => 'nccolour');
p;
lit <<' E;';
I decided to do some experimentation with how the colours defined in
ncurses are actually displayed in terminals, what the effects are of
combining these colours with other attributes, and how colour schemes of a
terminal can affect the displayed colours. To this end I wrote a small c
file and ran it in different terminals and different configurations. Note
that only the 8 basic NCurses colours are tested, the more flexible
init_color() function is not used.
E;
br;br;
b 'Source code: ';
a href => '/download/code/nccolour.c', 'nccolour.c';
txt " ("; a href => 'http://p.blicky.net/xu35c', 'syntax highlighed version'; txt ')';
br;
txt 'Some screenshots can be found below, but more screenshots are always
welcome! Please send your (.png) screenshots to projects@yorhel.nl.';
end;
h2 'Notes / observations';
ul;
li 'The most obvious conclusion: the displayed colours do not have the exact
same colour value in every terminal. Some terminals also allow users to
modify these colours.';
li 'You can not assume that the default foreground or background colour can
be represented by one of the 8 basic colours defined by NCurses.';
li 'Specifying -1 as colour, to indicate the default foreground or
background colour, seems to work fine in any terminal tested so far.';
li 'All tested terminals render the foreground colour in a lighter shade
when the A_BOLD attribute is set. This does not apply to the background
colour. The result of this is that the text becomes visible when using
A_BOLD when the foreground and background colour are set to the same
value.';
li 'Unfortunately, not all terminals are configured in such a way that all
possible colours are readable. So as a developer you\'ll still have to
support configurable colour schemes in your ncurses application. :-(';
li 'None of the tested terminals make an attempt to change the foreground
colour if it is (almost) invisible on the selected background colour. This
can be a good thing or a bad thing, depending on what you want.';
end;
h2 'Full screenshot';
p;
txt 'To avoid wasting unecessary space, the comparison screenshots below
only display the colour table. Here\'s a screenshot of the full output of
the program, which also explains what each column means.';
br;
img style => 'margin: 10px 0 0 25px', src => "/img/nccol-full.png";
end;
h2 'Screenshots';
my @img = (
'rox-b' => 'Arch Linux, Roxterm, Default color scheme',
'rox-w' => 'Arch Linux, Roxterm, GTK color scheme',
'rox-t' => 'Arch Linux, Roxterm, Tango color scheme',
'rox-c' => 'Arch Linux, Roxterm, Modified Tango color scheme',
xterm => 'Arch Linux, xterm (default settings)',
debian => 'Debian Squeeze, VT (default settings)',
fbsd => 'FreeBSD, VT (default settings)',
);
while(@img) {
my($n, $t) = (shift(@img), shift(@img));
txt $t;
br;
img style => 'margin: 5px 0 10px 25px; border: 1px solid #999', src => "/img/nccol-$n.png", alt => "NCurses colours on $t";
br;
}
$s->htmlFooter;
}
sub notfound {
my $s = shift;
my $u = lc $s->reqPath;
($_->[0] eq $u || $_->[0] eq "$u/") && return $s->resRedirect($_->[1], 'perm') for (
[ 'bluecubes', '/demo' ],
[ 'dump', '/dump' ],
[ 'dump/index2', '/dump' ],
[ 'dump/pmdc2-parse', '/dump' ],
[ 'dump/cbbcode', '/dump' ],
[ 'dump/cechoserv', '/dump' ],
[ 'dump/cyapong', '/dump' ],
[ 'dump/awshrink', '/dump/awshrink' ],
[ 'dump/grenamr', '/dump/grenamr' ],
);
return $s->resRedirect("/$u", 'perm') if $u =~ s/\/$//;
$s->resStatus(404);
$s->htmlHeader(title => 'Page Not Found');
$s->htmlFooter;
}
# U T I L I T Y M E T H O D S
package TUWF::Object;
use TUWF ':html';
sub htmlHeader {
my($self, %o) = @_;
$o{page} ||= '';
$o{tab} ||= '';
html;
head;
title $o{title};
style type => 'text/css';
lit $self->css;
end;
end;
body;
div id => 'menu';
a href => '/', !$o{page} ? (class => 'sel') : (), 'home'; txt ' ';
a href => '/ncdu', $o{page} eq 'ncdu' ? (class => 'sel') : (), 'ncdu'; txt ' ';
a href => '/ncdc', $o{page} eq 'ncdc' ? (class => 'sel') : (), 'ncdc'; txt ' ';
a href => '/tuwf', $o{page} eq 'tuwf' ? (class => 'sel') : (), 'tuwf'; txt ' ';
a href => '/dump', $o{page} eq 'dump' ? (class => 'sel') : (), 'code dump';
end;
if($o{page} eq 'ncdu') {
div id => 'mtabs';
a href => '/ncdu', !$o{tab} ? (class => 'sel') : (), 'main'; txt ' ';
a href => '/ncdu/changes', $o{tab} eq 'changes' ? (class => 'sel') : (), 'changelog'; txt ' ';
a href => '/ncdu/man', $o{tab} eq 'man' ? (class => 'sel') : (), 'manual'; txt ' ';
a href => 'http://sourceforge.net/tracker/?group_id=200175', 'bug tracker (sf)';
end;
}
if($o{page} eq 'ncdc') {
div id => 'mtabs';
a href => '/ncdc', !$o{tab} ? (class => 'sel') : (), 'main'; txt ' ';
a href => '/ncdc/faq', $o{tab} eq 'faq' ? (class => 'sel') : (), 'Q&A'; txt ' ';
a href => '/ncdc/guide', $o{tab} eq 'guide' ? (class => 'sel') : (), 'user guide'; txt ' ';
a href => '/ncdc/changes', $o{tab} eq 'changes' ? (class => 'sel') : (), 'changelog'; txt ' ';
end;
}
if($o{page} eq 'tuwf') {
div id => 'mtabs';
a href => '/tuwf', !$o{tab} ? (class => 'sel') : (), 'main'; txt ' ';
a href => '/tuwf/man', $o{tab} eq 'man' ? (class => 'sel') : (), 'manual'; txt ' ';
end;
}
if($o{page} eq 'dump') {
div id => 'mtabs';
a href => '/dump', !$o{tab} ? (class => 'sel') : (), 'misc'; txt ' ';
a href => '/demo', $o{tab} eq 'demo' ? (class => 'sel') : (), 'demos'; txt ' ';
a href => '/dump/awshrink', $o{tab} eq 'awshrink' ? (class => 'sel') : (), 'awshrink'; txt ' ';
a href => '/dump/grenamr', $o{tab} eq 'grenamr' ? (class => 'sel') : (), 'grenamr'; txt ' ';
a href => '/dump/nccolour', $o{tab} eq 'nccolour' ? (class => 'sel') : (), 'nc-colour';
end;
}
div id => 'main';
h1 $o{title};
}
sub htmlFooter {
end 'div';
p id => 'footer';
lit 'feedback &raquo; ';
a href => 'mailto:projects@yorhel.nl', 'projects@yorhel.nl';
br;
a href => 'http://yorhel.nl', 'yh';
txt ' - ';
a href => 'http://g.blicky.net', 'git';
txt ' - ';
a href => 'http://svn.blicky.net', 'svn';
end;
end 'body';
end 'html';
}
sub htmlChangeLog {
my ($s, $p) = @_;
open my $F, '<', "$ROOT/dat/$p-changelog" or die $!;
ul style => 'margin-left: 0';
for my $v (split /\n\n/, join '', <$F>) {
$v =~ s/^([0-9]+\.[0-9]+)\s+-\s+([0-9]{4}-[0-9]{2}-[0-9]{2})//;
li style => 'list-style-type: none;';
b $1;
txt " - $2 - ";
a href => "/download/$p-$1.tar.gz", "$p-$1.tar.gz";
br;
ul;
for (split(/\r?\n\s+-\s+/, $v)) {
s/[\r\n\s]{2,50}/ /;
li $_ if $_;
}
end;
br;
end;
}
end;
close $F;
}
sub htmlPOD {
my($s, $file) = @_;
require Pod::Simple::HTML;
require Encode; # not really necessary, since the docs are ASCII anyway
my $p = Pod::Simple::HTML->new();
my $html = '';
$p->html_header_before_title('<!--');
$p->html_header_after_title('-->');
$p->html_footer('');
$p->output_string(\$html);
$p->{podhtml_LOT} = {
'TUWF' => '/tuwf/man',
'TUWF::DB' => '/tuwf/man/db',
'TUWF::Misc' => '/tuwf/man/misc',
'TUWF::Request' => '/tuwf/man/request',
'TUWF::Response' => '/tuwf/man/response',
'TUWF::XML' => '/tuwf/man/xml',
};
$p->parse_file($file);
h1 'Table of Contents';
lit Encode::decode_utf8($p->index_as_html());
div class => 'pod';
lit Encode::decode_utf8($html);
end;
}
sub css {
return <<__;
* { padding: 0; margin: 0; font: 15px "Lucida Grande", "Arial", "Helvetica", "Verdana", sans-serif; }
body { background: #222; text-align: center; color: #ccc }
a { text-decoration: none; color: #666 }
a:hover { text-decoration: underline }
#menu { background: #000; border-bottom: 1px solid #666; width: 100%; margin: 0; }
#menu a { line-height: 25px; padding: 5px 8px; margin: 0 2px; color: #ccc; }
#menu a:hover, #menu a.sel { background-color: #222; text-decoration: none }
#main { margin: 30px auto 5px auto; background-color: #000; width: 700px; border: 2px solid #666; text-align: left; padding: 5px 10px 10px 10px }
#mtabs { margin: 30px 0 -28px 0; }
#mtabs a { background-color: #222; color: #ccc; font-size: 13px; margin: 0 2px; padding: 0 10px 3px 10px; border: 1px solid #666; border-bottom: 2px solid #666 }
#mtabs a:hover { background-color: #000; text-decoration: none }
#mtabs a.sel { border-bottom: 2px solid #000; background-color: #000; }
#footer, #footer a { color: #444; margin-bottom: 10px }
h1 { font-size: 19px; color: #888; margin-bottom: 5px; }
h2 { font-size: 16px; color: #888; margin-top: 25px; margin-bottom: 1px; }
b { font-weight: bold; color: #fff }
ul { margin-left: 20px }
pre, code, pre b { font: 11px monospace; }
pre b { font-weight: bold }
pre.code, .pod pre { background: #111; border: 1px dotted #666; margin: 5px 10px; display: block; padding: 5px; }
.indexgroup ul { margin-left: 5px; list-style-type: none }
.indexgroup ul ul { margin-left: 20px }
.pod p { margin: 3px 15px 13px 15px; text-align: justify }
.pod ul, .pod ol { margin-left: 35px }
.pod ul li, .pod ol li { margin-right: 15px; text-align: justify }
.pod pre { padding-left: 0 }
.pod h1 a, .pod h2 a { color: #888; font-weight: bold; font-size: 19px }
.pod h1 { margin-top: 50px }
.pod h2 a { font-size: 16px }
.pod dd { margin-left: 15px }
.pod dt a { color: #888 }
.pod dt { margin-left: 10px }
.pod i { font-style: italic }
__
}