#!/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{ncdu/scr} => \&ncduscr, qr{ncdc} => \&ncdc, qr{ncdc/faq} => \&ncdcfaq, qr{ncdc/changes} => \&ncdcchangelog, qr{ncdc/man} => \&ncdcmanual, qr{ncdc/scr} => \&ncdcscr, qr{tuwf} => \&tuwf, qr{tuwf/man(?:/(db|misc|request|response|xml))?} => \&tuwfmanual, qr{doc} => \&docindex, qr{doc/sqlaccess} => \&docsqlaccess, 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 => \¬found, ); 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-12-30'; txt ' ncdc 1.7 released!'; br; b '2011-12-07'; txt ' ncdc 1.6 released!'; br; b '2011-11-26'; txt ' Added article section and the article on SQLite.'; br; b '2011-11-03'; txt ' ncdc 1.5 and ncdu 1.8 released!'; br; b '2011-10-26'; txt ' ncdc 1.4 released!'; br; b '2011-10-19'; txt ' PGP-signed all releases of ncdu, ncdc and TUWF.'; br; b '2011-10-14'; txt ' ncdc 1.3 released!'; br; b '2011-09-25'; txt ' ncdc 1.1 released - follwed by a 1.2 quickfix.'; br; b '2011-09-16'; txt ' ncdc 1.0 released!'; br; b '2011-09-15'; txt ' Added some screenshots for ncdu.'; br; 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.8 ('; $s->htmlDLLink('ncdu-1.8.tar.gz', 'download'); txt ' - '; a href => '/ncdu/changes', 'changes'; txt ' - '; a href => 'http://sourceforge.net/project/showfiles.php?group_id=200175', 'mirror'; 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://packages.agilialinux.ru/search.php?tag=sys-fs', 'AgiliaLinux';txt ' - '; a href => 'http://www.perzl.org/aix/index.php?n=Main.Ncdu', 'AIX'; txt ' - '; a href => 'http://sisyphus.ru/en/srpm/Sisyphus/ncdu', 'ALT Linux'; txt ' - '; 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://frugalware.org/packages/?op=pkg&srch=ncdu&arch=all&ver=all', 'Frugalware'; txt ' - '; a href => 'http://packages.gentoo.org/package/sys-fs/ncdu', 'Gentoo'; txt ' - '; a href => 'http://www.ipadd.de/binary-v2.html', '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://pdb.finkproject.org/pdb/package.php/ncdu', 'Fink'; txt '-'; a href => 'http://mxcl.github.com/homebrew/', 'Homebrew'; txt '-'; a href => 'http://www.macports.org/ports.php?by=name&substr=ncdu', 'MacPorts'; txt ') - '; a href => 'http://packages.pardus.org.tr/info/2011/devel/source/ncdu.html', 'Pardus'; txt ' - '; a href => 'http://www.murga-linux.com/puppy/viewtopic.php?t=35024', 'Puppy Linux';txt ' - '; txt 'Solaris ('; a href => 'http://www.opencsw.org/packages/ncdu', 'CSW'; txt '-'; a href => 'http://www.sunfreeware.com/', 'sunfreeware'; txt ') - '; txt 'Slackware ('; a href => 'http://slackbuilds.org/repository/13.37/system/ncdu/', 'Slackbuilds'; txt '-'; a href => 'http://www.slackers.it/repository/ncdu/', 'Slackers.it'; 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; txt 'ncdu is also available on the '; a href => 'https://build.opensuse.org/package/show?package=ncdu&project=utilities', 'Open Build Service'; txt ', which provides packages for a variaty of Linux distributions.'; br; br; txt 'Subscribe to '; a href => 'http://freecode.com/projects/ncdu', 'freecode'; 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 ' - GTK, using a treeview.'; br; a href => 'http://www.marzocca.net/linux/baobab.html', 'Baobab'; txt ' - GTK, using pie-charts, a treeview and a treemap. Comes with GNOME.'; br; a href => 'http://gdmap.sourceforge.net/', 'GdMap'; txt ' - GTK, with a treemap display.'; br; a href => 'http://www.methylblue.com/filelight/', 'Filelight'; txt ' - KDE, using pie-charts.'; br; a href => 'http://kdirstat.sourceforge.net/', 'KDirStat'; txt ' - KDE, with a treemap display.'; br; a href => 'http://qt-apps.org/content/show.php/QDiskUsage?content=107012', 'QDiskUsage'; txt ' - Qt, using pie-charts.'; br; a href => 'http://xdiskusage.sourceforge.net/', 'xdiskusage';txt ' - FLTK, with a treemap display.'; br; a href => 'http://fsv.sourceforge.net/', 'fsv'; txt ' - 3D visualization.'; br; a href => 'http://zevv.nl/play/code/philesight/', 'Philesight';txt ' - Web-based clone of Filelight.'; br; a href => 'http://www.jgoodies.com/freeware/jdiskreport/','JDiskReport';txt ' - Java, using pie-charts and a treeview.'; $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, '<:utf8', "$ROOT/dat/ncdu-man" or die $!; pre; txt $_ while(<$F>); end; close $F; $s->htmlFooter; } sub ncduscr { my $s = shift; $s->htmlHeader(title => 'Screenshots', page => 'ncdu', tab => 'scr'); p; txt 'Note: While these screenshots are from version 1.7, the latest version has only little visible changes.'; br; br; txt 'Scanning...'; img src => '/img/ncduscan.png', class => 'scr', alt => 'Ncdu scanning a large directory.'; br;br; txt 'Done scanning'; img src => '/img/ncdudone.png', class => 'scr', alt => 'Ncdu done scanning a large directory.'; br;br; txt 'Directory information'; img src => '/img/ncduinfo.png', class => 'scr', alt => 'Ncdu displaying directory information.'; br;br; txt 'Delete confirmation'; img src => '/img/ncduconfirm.png', class => 'scr', alt => 'Ncdu asking for confirmation to delete a file.'; br;br; txt 'Help screen'; img src => '/img/ncduhelp1.png', class => 'scr', alt => 'Ncdu help screen.'; br;br; txt 'About screen'; img src => '/img/ncduhelp2.png', class => 'scr', alt => 'Ncdu about screen.'; end; $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 'Get ncdc!'; p; b 'Latest version:'; txt ' 1.7 ('; $s->htmlDLLink('ncdc-1.7.tar.gz', 'download'); txt ' - '; a href => '/ncdc/changes', 'changes'; txt ' - '; a href => 'https://sourceforge.net/projects/ncdc/files/ncdc/', 'mirror'; txt ')'; br; txt 'The latest development version can be fetched from the git repository at '; code 'git://g.blicky.net/ncdc.git'; txt ' and is available for '; a href => 'http://g.blicky.net/ncdc.git/', 'online browsing'; txt '. The README includes instructions to build ncdc. Check out the '; a href => '/ncdc/man', 'manual'; txt ' to get started.'; br;br; txt 'Packages/ports are available for the following systems: '; br; a href => 'http://aur.archlinux.org/packages.php?ID=50949', 'Arch Linux'; txt ' - '; a href => 'http://www.freshports.org/net-p2p/ncdc/', 'FreeBSD'; txt ' - '; a href => 'http://frugalware.org/packages/136807', 'Frugalware'; txt ' - '; a href => 'http://packages.gentoo.org/package/net-p2p/ncdc', 'Gentoo'; txt ' - '; txt 'Mac OS X ('; a href => 'http://www.macports.org/ports.php?by=name&substr=ncdc', 'MacPorts'; txt ') - '; a href => 'http://packman.links2linux.org/package/ncdc', 'OpenSUSE'; txt '.'; end; h2 'Features'; p 'Common features that all modern DC clients (should) have:'; ul; li 'Connecting to multiple hubs at the same time,'; li 'Support for both ADC and NMDC protocols,'; li 'Chatting and private messaging,'; li 'Browsing the user list of a connected hub,'; li 'Share management and file uploading,'; li 'Connections and download queue management,'; li 'File list browsing,'; li 'Multi-source and TTH-checked file downloading,'; li 'Searching for files,'; li 'Secure hub (adcs:// and nmdcs://) and client connections on both protocols.'; end; br; p 'Special features not commonly found in other clients:'; ul; li 'Subdirectory refreshing,'; li 'Nick notification and highlighting in chat windows,'; li 'Detecting changes to the TLS certificate of a hub,'; li 'Efficient file uploads using sendfile(),'; li 'Large file lists are opened in a background thread,'; li '(Relatively...) low memory usage.'; end; h2 'What doesn\'t ncdc do?'; p "Since the above list is getting larger and larger every time, it may be more interesting to list a few features that are (relatively) common in other DC clients, but which ncdc doesn\'t do. Yet."; ul; li 'Segmented downloading,'; li 'Bandwidth throttling,'; li 'OP features (e.g. client detection, file list scanning and other useful stuff for OPs),'; li 'SOCKS support.'; end; p 'Of course, there are many more features that could be implemented or improved. These will all be addressed in later versions (hopefully :).'; h2 'Requirements'; p; lit <<' E;'; The following libraries are required: ncurses, bzip2, sqlite3, glib2 and libxml2.
For TLS support, you will need at least glib2 version 2.28.0 and glib-networking installed.
These dependencies should be easy to satisfy. Depending on your system, you may have all of these installed already.
Ncdc has been developed on Arch Linux, but I have received reports from people who successfully used it on CentOS, Debian, FreeBSD, Gentoo, Mac OS X, OpenSUSE, Solaris and Ubuntu. It should be fairly trivial to port to other POSIX-like systems.
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!'; br; br; $s->htmlPOD("$ROOT/dat/ncdc-faq"); $s->htmlFooter; } sub ncdcmanual { my $s = shift; $s->htmlHeader(title => 'Manual page', page => 'ncdc', tab => 'man'); open my $F, '<:utf8', "$ROOT/dat/ncdc-man" or die $!; pre; txt $_ while(<$F>); end; close $F; $s->htmlFooter; } sub ncdcchangelog { my $s = shift; $s->htmlHeader(title => 'Version history', page => 'ncdc', tab => 'changes'); $s->htmlChangeLog('ncdc'); $s->htmlFooter; } sub ncdcscr { my $s = shift; $s->htmlHeader(title => 'Screenshots', page => 'ncdc', tab => 'scr'); p; txt 'Note: While these screenshots are from version 1.5, the latest version has only little visible changes.'; br; br; txt 'Main chat'; img src => '/img/ncdchub.png', class => 'scr', alt => 'Ncdc in the mainchat.'; br;br; txt 'File browser'; img src => '/img/ncdcbrowse.png', class => 'scr', alt => 'Simple file list browser.'; br;br; txt 'User list'; img src => '/img/ncdcusers.png', class => 'scr', alt => 'Ncdc displaying the userlist of a hub.'; br;br; txt 'Built-in help'; img src => '/img/ncdchelp.png', class => 'scr', alt => 'Ncdc built-in help.'; end; $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 description in the documentation for more information and details. E; h2 'Download'; p; b 'Latest packaged version:'; txt '0.1 ('; $s->htmlDLLink('TUWF-0.1.tar.gz', 'download'); txt ' - '; a href => 'http://search.cpan.org/dist/TUWF/', 'CPAN mirror'; txt ')'; br; txt 'TUWF is also available on a git repository at '; a href => 'http://g.blicky.net/tuwf.git/', 'http://g.blicky.net/tuwf.git/'; txt '.'; 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; } # D O C S T U F F sub docindex { my $s = shift; $s->htmlHeader(title => 'Articles', page => 'doc'); p 'When programming stuff, I sometimes come across a situation where I am not happy with the documentation or articles available online, and feel the urge to do something about this situation. Most of the time I resist this urge because I otherwise won\'t get any programming done, but sometimes this urge is just too hard to resist.'; p 'I don\'t really have a blog - at least not one that I take seriously - so I\'ll just use this site to publish my articles. Since I\'ve just started writing these, this page is still quite empty. I\'ll add more as soon as my urge to write an article surprasses my urge to get some programming done again.'; br; p; txt '2011-11-26 - '; b 'Multi-threaded Access to an SQLite3 Database'; txt ' ['; a href => '/doc/sqlaccess', 'HTML'; txt ' - '; a href => '/dat/sqlaccess', rel => 'nofollow', 'POD'; txt ']'; span 'So you have a single database and some threads. How do you combine these in a program?'; txt '2010-06-02 - '; b 'Design and implementation of a compressed linked list library'; txt ' ['; a href => '/download/doc/compll.pdf', 'PDF'; txt ']'; span q|This isn't really an article. It's the report for the final project of my professional (HBO) bachelor of Electrical Engineering. I was very liberal with some terminology in this report. For example, "linked lists" aren't what you think they are, and I didn't even use the term "locality of reference" where I really should have. It was also written for an audience with little knowledge on the subject, so I elaborated on a lot of things that should be obvious for most people in the field. Then there is a lot of uninteresting overhead about the project itself, which just happened to be mandatory for this report. Nonetheless, if you can ignore these faults it's not such a bad read, if I may say so myself. :-)|; end; $s->htmlFooter; } sub docsqlaccess { my $s = shift; $s->htmlHeader(title => 'Multi-threaded Access to an SQLite3 Database', page => 'doc', tab => 'sqlaccess'); p; lit <<' E;'; Written on 2011-11-26. Also available in POD format.
Feedback, questions, comments, additions? Forward those to projects@yorhel.nl. E; end; br;br; $s->htmlPOD("$ROOT/dat/sqlaccess"); $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 microdc2 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 public VNDB API 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 public VNDB API 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; h2 'ncdc-transfer-stats'; p; lit <<' E;'; September 2011. ncdc gained transfer logging features, and I wrote a quick Perl script to fetch some simple statistics from it. E; a href => 'http://p.blicky.net/agolr', 'source'; end; h2 'ncdc-share-report'; p; lit <<' E;'; December 2011. Playing around with the Go programming language, I wrote another transfer log parser and statistics generator for ncdc. latest source (0.1) E; 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 demoscene, 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 Evoke. 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 rename command that comes with a Perl module.

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 $_=sprintf'%03d.txt',$i. 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 -X 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 'On most terminals, setting the foreground and background colour to the same value without applying the A_BOLD attribute will make the text invisible. Don\'t rely on this, however, as this is not the case on OS X.'; 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)', ubuntu => 'Ubuntu 11.10, Gnome-terminal', debian => 'Debian Squeeze, VT (default settings)', fbsd => 'FreeBSD, VT (default settings)', 'osx-terminal' => 'Mac OS X, Terminal', 'osx-iterm2' => 'Mac OS X, iTerm2', ); 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' ], [ 'ncdc/guide', '/ncdc/man' ], [ '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 => '/doc', $o{page} eq 'doc' ? (class => 'sel') : (), 'articles'; 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/man', $o{tab} eq 'man' ? (class => 'sel') : (), 'manual'; txt ' '; a href => '/ncdu/changes', $o{tab} eq 'changes' ? (class => 'sel') : (), 'changelog'; txt ' '; a href => '/ncdu/scr', $o{tab} eq 'scr' ? (class => 'sel') : (), 'screenshots'; 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/man', $o{tab} eq 'man' ? (class => 'sel') : (), 'manual'; txt ' '; a href => '/ncdc/changes', $o{tab} eq 'changes' ? (class => 'sel') : (), 'changelog'; txt ' '; a href => '/ncdc/scr', $o{tab} eq 'scr' ? (class => 'sel') : (), 'screenshots'; 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 'doc' && $o{tab}) { use utf8; div id => 'mtabs', style => 'margin-right: 620px'; a href => '/doc', '« article index'; 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 » '; 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'; txt ' - '; a href => 'http://pgp.mit.edu:11371/pks/lookup?search=0x8c2739fa', 'pgp'; end; end 'body'; end 'html'; } sub htmlDLLink { my($s, $f, $m) = @_; a href => "/download/$f", $m||$f; b class => 'sig'; txt '['; a href => "/download/$f.asc", 'PGP'; txt '-'; a href => "/download/$f.sha1", 'SHA1'; txt '-'; a href => "/download/$f.md5", 'MD5'; txt ']'; end; } 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 - "; $s->htmlDLLink("$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_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 } .sig { vertical-align: super; padding-left: 3px; color: #666!important } .sig, .sig a { font-size: 10px; color: #ccc } .scr { margin: 5px 0 0 0; border: 1px solid #999 } 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; } span { display: block; font-size: 12px; margin: 3px 10px 10px 30px } .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 } __ }