Updated 2011-03-23 11:56:27 by RLE

Tips for creating NiChannel[1] style forum software implemented in TclHttpd.

Generating captcha images (http://www.captcha.net) for anti-spam purposes.

Using [ImageMagick] convert routine, where the captcha code is RKS876:
   convert captcha.png -gravity center -pointsize 24 -fill white -annotate 0 'RKS876' -swirl 90 captcha-done.png

Using a random sequence of numbers and letters for the captcha code.
   proc randomCode {size} {
      set data [list 1 2 3 4 5 6 7 8 9 0 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z]
      set code [list]
      for {set n 0} {$n < $size} {incr n} {
        lappend code [lindex $data [expr {int(rand()*[llength $data])}]]
      }
      return [join $code ""]
    }

Generating the captcha image. Use a hash of the key to make sure it can't be scraped from the html page:
  proc genCaptcha {code} {
    set key $code
    set stamp [clock seconds]
    set hash [md5::md5 $key]
    set target $hash-$stamp.png
    exec convert -size 100x50 plasma: -gravity center -pointsize 24 -fill white -annotate 0 '$code' -swirl 90 png:$target
    mk::row append db.captchas key $key stamp $stamp
    return $target
  }

I could store the image inside of a metakit database, but I'm uncertain how to use that in a tml page.
  mk::file open db data.dat
  mk::view layout db.captchas {key stamp data:B}

  mk::row append db.captchas key $key stamp $stamp data [exec convert captcha.png -gravity center -pointsize 24 -fill white -annotate 0 '$code' -swirl 90 png:-]

CJL added: The source image ('captcha.png') doesn't need to exist as a file, e.g.:
  exec convert -size 120x60 xc:black -gravity center -pointsize 24 -fill white -annotate 0 '$code' -swirl 90 png:$target

That's even better. Add the plasma as part of the convert and eliminate actual files altogether. Just store the result in the MK database. I still need to figure out how to display the image out of the database into the resulting web page. The following would add the plasma effect (which is what the captcha.png was) in order to further "obscure" the code from any OCR type spammers.
  exec convert -size 100x50 plasma: -gravity center -pointsize 24 -fill white -annotate 0 '$code' -swirl 90 png:$target

Updated the code above for genCaptcha

Expire the generated images quickly, since they are only served once each. Each time a new image is generated, possibly, search for images that are more than 60 seconds old and delete them.

Storing threads/posts in metakit.

Metakit seems like a perfectly designed system for separate "boards" storing their own data? I.e. layout of {board {threads {title stamp data {posts {subject stamp data}}}} ???

Need to autogenerate thread and post id numbers.

For a completely anonymous, non-tripcode board this would be fine.