SCode Image Reload

Sometimes the numbers on SCodePlugin-generated CAPTCHA image are not easy to read. And rather than refreshing the whole page, it would be nice to reload only the image and generate a new / more readable code.

In order to give this a go, I modified the comment form on Melbourne photoblog and added a short Javascript code to refresh the image source. You can try it yourself on this form, just click the text “Generate another code” and wait shortly for the image to be reloaded with a new code.

I have updated the Usage sample code on SCode Plugin wiki page with this improvement.

As a side note, I found a problem where modifying img.src value via anchor tag’s onclick attribute does not work on IE 6 and the image will just disappear, while it works just fine on Firefox 2 and Opera 8.5 .

function reloadSCode() {
  var scodeImage = document.getElementById("scodeImage");
  scodeImage.src="$BLOJSOM_BLOG.getBlogBaseURL()/captcha?flavor=kink&t=" + (new Date()).getMilliseconds();
<a href="javascript: void(0);" onclick="reloadSCode();">Generate another code</a>.

After some mucking around, I found out that the function call must be made from the href attribute. This works on the browsers mentioned above.

<a href="javascript: reloadSCode();">Generate another code</a>.

Them browsers better implement proper Javascript standard before doomsday comes.

GateKeeper Plugin v0.1 And IMNotification Plugin v0.1

GateKeeper Plugin v0.1 and IMNotification Plugin v0.1 have been released.

I implemented GateKeeper Plugin for Blojsom following the earlier discussion on a simple anti-bot solution to fight comment spams. This blog has been using GateKeeper Plugin (with very simple challenges for now) and it has worked like a charm with 100% success rate, though I think that the success is actually contributed from the fact that the spammers have been focusing their effort on breaking more mainstream anti-spam solutions like CAPTCHAs.

I’ve also been using IMNotification Plugin with Jabber server and Pandion client. This plugin provides an alternative to email notifications, and it’s handy for those with IM windows.

SCodePlugin v0.5

SCodePlugin v0.5 has been released, expect the jar and source downloads to be available from SourceForge mirrors in the next few days. As usual, if you want it earlier, just email me and I’ll send it to you.


  • Introduced KaptchaImageEngine using Kaptcha (was Simple Captcha) library, with 3 new flavours from KinkImageEngine, FishEyeImageEngine, and ShadowImageEngine.
  • Replaced image engine class loading in image factory with constructor injection. SCodePlugin passes the image factory to SCodeServlet, instead of passing the image engines.
  • Set ImageIO caching off during SCodeServlet initialisation. This improves performance and prevents any temporary disk-based image creation.

Upgrade instruction:

  • In WEB-INF/lib directory, replace scodeplugin-0.4.jar with scodeplugin-0.5.jar, and add kaptcha-1.1.jar .
  • On /WEB-INF/classes/blojsom-plugins.xml file, replace the scode bean declaration you have for SCodePlugin v0.4:
    <bean id="scode" class="com.mbledug.blojsom.plugin.scode.SCodePlugin" init-method="init" destroy-method="destroy">
                <entry key="simple" value="com.mbledug.blojsom.plugin.scode.engine.SimpleImageEngine"/>
                <entry key="gradient" value="com.mbledug.blojsom.plugin.scode.engine.GradientImageEngine"/>
                <entry key="funky" value="com.mbledug.blojsom.plugin.scode.engine.FunkyImageEngine"/>

    with this for SCodePlugin v0.5:

    <bean id="scodeSimpleImageEngine" class="com.mbledug.blojsom.plugin.scode.engine.SimpleImageEngine"/>
    <bean id="scodeGradientImageEngine" class="com.mbledug.blojsom.plugin.scode.engine.GradientImageEngine"/>
    <bean id="scodeFunkyImageEngine" class="com.mbledug.blojsom.plugin.scode.engine.FunkyImageEngine"/>
    <bean id="scodeKinkImageEngine" class="com.mbledug.blojsom.plugin.scode.engine.KinkImageEngine"/>
    <bean id="scodeFishEyeImageEngine" class="com.mbledug.blojsom.plugin.scode.engine.FishEyeImageEngine"/>
    <bean id="scodeShadowImageEngine" class="com.mbledug.blojsom.plugin.scode.engine.ShadowImageEngine"/>
    <bean id="scodeImageFactory" class="com.mbledug.blojsom.plugin.scode.ImageFactory">
                <entry key="simple" value-ref="scodeSimpleImageEngine"/>
                <entry key="gradient" value-ref="scodeGradientImageEngine"/>
                <entry key="funky" value-ref="scodeFunkyImageEngine"/>
                <entry key="kink" value-ref="scodeKinkImageEngine"/>
                <entry key="fisheye" value-ref="scodeFishEyeImageEngine"/>
                <entry key="shadow" value-ref="scodeShadowImageEngine"/>
    <bean id="scode" class="com.mbledug.blojsom.plugin.scode.SCodePlugin" init-method="init" destroy-method="destroy">
            <ref bean="scodeImageFactory"/>

Kink, New SCode Flavor

Jon Stevens resurrected Simple Captcha in the form of Kaptcha. The good thing about Simple Captcha / Kaptcha is that it generates an image similar to the ones used at Yahoo!. Other than that, it’s really straightforward to use.

I quickly integrated Kaptcha into SCode Plugin by introducing KinkImageEngine, exposed to Blojsom via “kink” flavor. Here’s how it looks like:

This flavor will be included in SCode Plugin 0.5 (yet to be released).

Blojsom 3 Plugins Update Wrap Up

Blojsom 3 was first mentioned on March 23rd 2006, and it was finally released (post milestone releases) on September 29th 2006.

The first time I mentioned about updating my plugins was on March 27th 2006. And today, March 25th 2007, almost a year later, I finally finished updating all plugins with necessary improvements along with documentation updates. Phew.

Here are some notes of each plugin:

BlogTimes Plugin

In Blojsom 2, BlogTimes Plugin only draws the current entries on the page, which means it only draws one blog time on a permalink view. This doesn’t give a good indication on the user’s blogging time pattern. In Blojsom 3, it draws a configurable number of N latest entries. So if you set it to a large value, e.g. 100, then you’ll get better graph on the time you post your last 100 blogs regardless whether you’re on a permalink view or not.

Galleryr Plugin

I was planning to upgrade Flickrj library from 1.0a8 to 1.0a9 for Galleryr Plugin for Blojsom 3, but I hit a problem with URL retrieval to which no one on Flickrj mailing list replied. I tried checking the source code to figure out the root cause of the problem, but SourceForge’s CVS was down all the time. I remember that I checked it on 3 different occasions. I also tried decompiling the binary class one by one, but at the end it was just a waste of time. I decided that I could live with 1.0a8 as long as it works as expected, though I really wanted to ditch the need to have GalleryrPhoto class.

Gravatar Plugin

In Blojsom 3, Gravatar Plugin stores Gravatar ID as comment metadata. This is to ensure Gravatar ID calculation is done only once, either when the comment is first posted or (for comments migrated from Blojsom 2 installation) when it’s viewed the first time. In Blojsom 2, Gravatar ID calculation is done every time the comment is viewed.

IpToCountry Plugin

The biggest problem with Blojsom 2’s IpToCountry Plugin is with data storage (country data stored in a large memory footprint) and retrieval process (pulling the country data repetitively on every comment view). While in Blojsom 3, this plugin stores the country data in the database, while country information is retrieved just once (similar to Gravatar Plugin approach) and stored as comment metadata. In short, IpToCountry Plugin no longer has a performance problem in Blojsom 3.

Pager Plugin

Pager Plugin is no more, it’s basically replaced by SkipFilterHelper Plugin in Blojsom 3. But I still did port pager.vm to work with SkipFilterHelper Plugin so you can still have the good ole page based navigation in Blojsom 3.

Param2Ctx Plugin

Still alive in Blojsom 3, still the simplest plugin ever.

SCode Plugin

I upgraded JCaptcha library from 1.0-RC1 in Blojsom 2’s SCode Plugin to 1.0-RC2.0.1 in Blojsom 3. This plugin still has all 3 of the original flavours (simple, gradient, and funky), I was thinking of adding more flavours but ended up wanting to finish the implementation a.s.a.p and stuck with the existing flavours. One problem that I’m starting to regret is the use of class loader in ImageFactory, I should’ve just injected the image engines via ImageFactory constructor instead.

TrackbackKeyword Plugin

TrackbackKeyword Plugin has some minor improvements in its Blojsom 3 implementation where it’s now possible to specify between checking all keywords or just one of the keywords to determine a trackback spam suspect, other than that it’s also now possible to configure proxy authentication for the plugin.

Myqanda, Possibly A Simple Anti-Bot Solution To Fight Coment Spams?

I just checked my server log between Dec 19, 2006 and today. SCode Plugin has successfully prevented 2140 comment spams, but there were 122 spams which slipped through the cracks. Those 122 provided correct answers from the CAPTCHA image. And judging from the timestamps, I’m pretty sure that those 122 were automated spam attacks using bots. However, considering that evil spammers would go as far as hiring freelancers to solve CAPTCHAs manually, there’s a chance that some people out there somewhere ‘unintentionally’ spammed my blog manually 122 times since Dec 2006. Ouch!

There have been many attempts to fight comment spams: nofollow, blacklist, whitelist, greylist, captcha, spam karma, akismet (the most popular nowadays with a small number of false positives), etc, etc. They succeeded to a certain degree, but why are the spambots still happily crawling around?

I would like to separate the 2 issues here: the first one is identifying spams (where akismet has been highly successful), the second one is identifying bots vs humans (this is where we are playing cat and mouse with the spammers).

If we eliminated the usefulness of a spambot, then we reduced the amount comment spams.

Spammers have been successful largely because of spambots. If they don’t have an automated way to spam, would they spam blog comments manually? Less likely. At least it should be a more costly process for them, and if it is costly enough maybe the value of spamming will ‘degrade’ even further. So I’m thinking if we can make the spammers think that bots are useless, then a very large portion of comment spam attempts will be reduced.

I’m proposing that we make each blog’s comment form unique enough by setting up a pair of static question and answer which would be different between blogs, so if there are 1000 blogs, there will be 1000 unique answers with unpatterned questions. By removing the common patterns in spam prevention efforts, we will reduce the functionality of a spambot.

The Q and As can be as simple as:

  • Q: Please type abcdef, A: abcdef
  • Q: What comes after 9, A: 10
  • Q: Just type MONEY in lowercase, A: money
  • Q: 77 times 2 is, A: 154
  • Q: Your passkey is ‘homer’ (without the quotes), A: homer
  • Q: Please fix this typo: hapipness, A: happiness
  • Q: Type the word blue with a space between b and l, A: b lue
  • Q: Do you think you’re cool? Just type yes, dude!, A: yes

It’s simple to set up, it’s simple to answer, and it would be hard enough for a bot to cater every question and answer combination in this world. This text-based approach is definitely more usable than CAPTCHA images, plus it should be easy enough to internationalize.

I just finished a Blojsom plugin that implements the above, installed the SNAPSHOT version about 20 minutes ago, and it has prevented 28 comment spams since then.

MyQAndA Plugin is a Blojsom plugin that allows you to specify your own static question and answer for commenters to key in. The idea is to make each blog requires a unique answer (varying answers between various blogs), which will then create a situation where there’s no problem solving to automate and the value of spambots will degrade.

I’m fully aware that this blog post itself might have comment spams by the time I wake up in the morning, but I can be certain that the spammer is a human.

Ressurecting Page By Page View A La Pager Plugin In Blojsom 3

After upgrading this blog to Blojsom 3.1, I hooked up Pager Plugin‘s pager.vm velocity code to SkipFilterHelper Plugin, and the result is as you can see at the bottom of my blog when you’re not viewing this post via feed or permalink (e.g. try the blog home page).

There is a bug with SkipFilterHelper Plugin in Blojsom 3.1 (registered in JIRA as BLOJSOM-195, David checked in the fix to CVS), which is about incorrect total pages on boundary cases. I immediately noticed this error because it also exists in Pager Plugin 0.2 . The SkipFilterHelper Plugin fix will be included in Blojsom 3.2, and in the mean time you can either apply the fix yourself to Blojsom 3.1 and rebuild from source, or email me and I’ll send you the patched jar.

Here’s what you have to do to get the page by page view on Blojsom 3.1:

  1. Set up SkipFilterHelper Plugin.
  2. Download pager.vm and place it on WEB-INF/blogs/[your-blog]/templates/ directory.
  3. Include pager.vm from your blog’s theme template, e.g. add the code #parse( “pager.vm” ) to asual.vm .

In case of error, you can debug whether your SkipFilterHelper Plugin installation was successful or not by displaying the values of $BLOJSOM_TOTAL_PAGES and $BLOJSOM_CURRENT_PAGE.

Moving forward, it would be nice if the code in pager.vm can be included as a macro in Blojsom 3.2 onward so people don’t have to set up pager.vm manually. And perhaps SkipEntriesFilter should handle criterias, e.g. category, so that we can have page by page view within a category instead of the whole blog.

Update: (03-04-2007) this functionality has been included in Blojsom 3.2 (registered in JIRA as BLOJSOM-211).

Update: someone (I don’t know the person’s name) made a Japanese translation of Pager Plugin installation for Blojsom 2. That’s the first non-English documentation on something I made, yay.

Plugins Update For Blojsom 3

Update: all plugins are now available for download from Source Forge.

I’ve finished updating most of my plugins to work with Blojsom 3, they’re currently in testing on both this blog and Melbourne Photoblog.

If you want to try the SNAPSHOT versions on your Blojsom 3 installation, you can download them temporarily from my server (I’ll add the released versions to SourceForge later on): blogtimesplugin-0.2-SNAPSHOT.jar, galleryrplugin-0.2-SNAPSHOT.jar, gravatarplugin-0.2-SNAPSHOT.jar, param2ctxplugin-0.2-SNAPSHOT.jar, scodeplugin-0.4-SNAPSHOT.jar, trackbackkeywordplugin-0.2-SNAPSHOT.jar.

I’ve also updated the wiki pages for Blojsom 3 plugins: BlogTimes Plugin, Galleryr Plugin, Gravatar Plugin, Param2Ctx Plugin, SCode Plugin, TrackbackKeyword Plugin. The source code is available at Google Code SVN, use Maven 2 to build the packages.

Overall, there isn’t much impact to my plugins with the change of Blojsom plugin API in version 3 compared to Blojsom 2 apart from method signature changes and some new events. Most of my effort was spent on adding unit tests which paid off when I started testing the plugins on a real Blojsom 3.0 installation and needed to 1) modify the configurations implementation, 2) add event broadcaster, and 3) change the event handling.

There were several minor improvements, code cleanup, and library dependencies upgrade (Flickrj for Galleryr Plugin and JCaptcha for SCode Plugin), but with only few hours per week spent on these plugins, I had to leave many of them out for later (most notably, I want to add more image engines and introduce audio engine capability to SCode Plugin).

Next on the list would be IpToCountry Plugin. This time we have database storage in Blojsom 3, whereas IpToCountry Plugin for Blojsom 2 was a memory hog where data is stored in a flat file and country search is done in-memory.

Pager Plugin is almost certainly discontinued with the existence of Skip Filter Helper Plugin in Blojsom 3.1, though I can still see the use of pager.vm file integrated with the data from Skip Filter Helper Plugin to generate the page navigation, maybe this can be done via a macro.