| 8.1.2010 | The year I started blogging (blogware) |
| 9.1.2010 | Linux initramfs with iSCSI and bonding support for PXE booting |
| 9.1.2010 | Using manually tweaked PTX assembly in your CUDA 2 program |
| 9.1.2010 | OpenCL autoconf m4 macro |
| 9.1.2010 | Mandelbrot with MPI |
| 10.1.2010 | Using dynamic libraries for modular client threads |
| 11.1.2010 | Creating an OpenGL 3 context with GLX |
| 11.1.2010 | Creating a double buffered X window with the DBE X extension |
| 12.1.2010 | A simple random file read benchmark |
| 14.12.2011 | Change local passwords via RoundCube safer |
| 5.1.2012 | Multi-GPU CUDA stress test |
| 6.1.2012 | CUDA (Driver API) + nvcc autoconf macro |
| 29.5.2012 | CUDA (or OpenGL) video capture in Linux |
| 31.7.2012 | GPGPU abstraction framework (CUDA/OpenCL + OpenGL) |
| 7.8.2012 | OpenGL (4.3) compute shader example |
| 10.12.2012 | GPGPU face-off: K20 vs 7970 vs GTX680 vs M2050 vs GTX580 |
| 4.8.2013 | DAViCal with Windows Phone 8 GDR2 |
| 5.5.2015 | Sample pattern generator |
Although I haven't figured out the value of public personal blogs so far, I did recently have to admit that for Unix hackers and programmers, technical blogs do seem to fill a certain gap between forum discussions and HOWTOs/white papers. So, I decided to join the movement and make a blog about hacks I wouldn't otherwise document, if merely for a future personal reference :-)
So, to start was to find an appropriate blogware, but I instantly got confused by the choices. It didn't take me long to figure out that I wasn't really after anything fancy or bloated with features, but I did have an existing web site and would have preferred something with the exact same look. Also, I'm more comfortable creating the HTML content myself, as I can use the tools I'm already familiar with (e.g. for creating syntax highlighted code print-outs). So I decided to write a few scripts myself to serve as the blogware, and make my first blog entry about them. :-)
I hardly think these scripts are of much interest to anyone, to be perfectly honest. But if it so happens that you're exactly in the same situation as I were, and would like to save a day of quality time with your favourite scripting language, here you go.
The idea is to have an existing HTML template tagged with anchor keywords, which the scripts then replace with blog content. For commenting, a form is created for each blog entry from a template. The form calls a cgi script, which sanitizes the input, adds the comment to the appropriate comment file, and calls a script to re-create the static HTMLs.
Let's start off with the main script that actually generates the HTMLs from the templates. When adding a new blog entry, just create a new directory under entries with the following files: description (date<newline>description), content.html (the actual HTML content of the blog entry), comments (empty at first). Then call the src/genroot.pl script manually in the root directory of your blog to create the initial HTMLs. Make sure that the HTTP service is allowed to create or change the HTML files, and to increment the comment files.
This is the main script that creates the HTMLs:
The above script delegates content creation to the following module:
This is the CGI script that processes comments posted via HTTP:
Grab this package to get all the example templates and such as well.
Commenting has been offline for some while since I didn't have any kind of spam filtering. Now I do and it's back online.
I simply consult spamassassin on my mail server to query the bayesian spam probability of the message body.
If you want to do the same, this is the perl code I use:
###
use IPC::Open2;
my @spamcCmd = ('/usr/bin/ssh', '-i/your/login/key', 'spam@your.spamassassin.host', 'spamc');
# Or if you have it locally:
#my @spamcCmd = ('/usr/bin/spamc');
my $spamLimit = 0.5; # 50% bayesian probability
sub isSpam {
my $input = $_[0];
my $pid = open2(OUT, IN, @spamcCmd) || die "Content-type: text/html\n\nCan't contact spam filter";
print IN $input;
close(IN);
my $score = 0.0;
while (<OUT>) {
if (s/[^\]]*\[score: ([^\]]+)\]/\1/) {
$score = $_;
}
}
#print "score: $score\n";
waitpid $pid, 0;
return $score >= $spamLimit;
}
###
And if you want to integrate this into the commenting system described in this entry, change the comment writing section of the comment.cgi script to this:
###
my $comment = getSaneComment();
if (isSpam($comment)) {
open(SPAM, ">>$filepath"."SPAM") or die print "Content-type: text/html\n\nCouldn't open spam DB for $filepath";
print SPAM getDate()." #".getSaneName()." #".getSaneEmail()." #".getSaneComment()." #";
close(SPAM);
die print "Content-type: text/html\n\nThis message was considered spam. Not posting. If you are a real person, e-mail me and I re-train my filter (the message is stored).";
} else {
print COMMENTS getDate()." #".getSaneName()." #".getSaneEmail()." #".getSaneComment()." #";
}
close(COMMENTS);
- wili