Napkin Drawing

Notes, Doodles, and Projects

Napkin Drawing     ·     Users   ·   Blag   ·   Bookmarks   ·   Photos

Recent Photos

Pumpkin Carrot Wheat Bran Chocolate Chip Mini-Muffins Photo via Email Carolina Renn Fest Photo via Email img_0587.jpg

Recent Bookmarks

SessionFactory (Hibernate API Documentation)

11/19/2008 by fansipans to [ hibernate java database jdbc ]

OpenLDAP Software 2.4 Administrator's Guide: Access Control

11/19/2008 by fansipans to [ openldap admin configuration ]

OpenLDAP Software 2.4 Administrator's Guide: A Quick-Start G...

11/19/2008 by fansipans to [ openldap configuration admin ]

hCalendar ยท Microformats Wiki

11/18/2008 by fansipans to [ hcalendar calendar event format specification reference ]

Boxes and Arrows: The design behind the design

11/18/2008 by fansipans to [ web design user interface usability html css ]

Recent Blaaag Posts

What Did I Learn Today?

11/14/2008 by fansipans to [ learntoday accessibility web design ]

There's a lot of cool stuff going on in the Web Accessibility world.

WCAG: Web Content Accessibility Guidelines. (See See WCAG 2.0 quick reference here.)

The Web Content Accessibility Guidelines are a standard set of ways to better organize content for accessibility. Mainly just big fat checklists of dos & don'ts, easy to scan/peruse. Great for well-designed sites overall, not just for accessibility issues.

WAI-ARIA: Web Accessibility Initiative - Accessible Rich Internet Applications (Also see a simple ARIA primer here)

The WAI-ARIA project is trying to manage accessibility issues for the rapidly expanding landscape of Rich Internet Applications. Modern web applications often take advantage of or bastardize every possible feature of modern browsers to implement functionality for which screen readers and users with accessibility issues have no way to use. Preliminary support for the WAI-ARIA specification already exists in major screen readers and recent browsers (Firefox 3, IE8).

Web Accessibility is growing by leaps and bounds, and stands to be a major motive force in making current internet applications suck less. Designing for accessibility reinforces good user interface, user experience, and usability. Any pressure to focus on user experience and usability can often lead to better applications overall, as it can expose and express or better address confusing business logic and requirements.

Hell of such as meow

11/07/2008 by fansipans to [ achewood comic cat ]

The Future

11/05/2008 by fansipans to [ web design html css html5 css3 interface ]

For warm fuzzies, read through the following documents:

The Working Specification of HTML5: New and better tags, client-side databases, native video and multimedia (goodbye flash!), canvas for drawing and rendering, input type "date", native tags for tree, list, and tabular data, a "command" tag (goodbye href="#" and href="javascript:void(0)" !)

CSS3, Current CSS Initiatives: A bonanza of syntax, attributes, and features to style HTML content in radically more ways than before. The wealth here is in the hundreds of little new features and attributes like: curved border corners with border-radius, an "opacity" property (opacity examples), color specification by hue, saturation, value, and optionally, alpha, and many, many, more.

Practice, Practice

10/10/2008 by fansipans to [ javascript programming learning functional ]

Seeing a complaint about function chaining / nesting with setTimeout made me think that there had to be a better way to take advantage of JavaScript's functional abilities.

The issue at hand was how to take a number of functions, and execute them serially, with a delay between functions. The least flexible and most trivial implementation would be something like:

function() {

do_something();
setTimeout(function() {
do_something_else();
setTimeout(function() {
do_something_other()
...
}, 1000);
}, 1000);
}


It's an unusual problem for people not versed in event-driven programming, and those of us working in moderately crippled event-driven environments like the glorious modern Web Browser. The issue is that the functions passed to setTimeouts float off into space until their time runs out, and setTimeout immediately returns. So it's not as simple as iterating through the functions, the calls need to be nested - or ideally - chained.

So after banging out some code, a good amount of refactoring, and getting a better feel for closures and scope in JavaScript, I came up with executeFunctions().

executeFunctions(funcs, transitionFunc) takes two arguments:

funcs is an Array that contains Arrays with two indices, 0 and 1. This two value Array contains the Function to execute, and an Array of arguments to pass to the Function, respectively.

transitionFunc is optional. It's simply a Function that must accept one argument (a Function). If specified, transitionFunc is called each time before the functions in funcs are executed. If transitionFunc executes the function it was given, then funcs will continue to be executed. If not, execution stops. If not specified, all the functions in funcs will be executed in the order they appear.

What does this mean? It means the setTimeout example specified above can be executed from a simple Array of functions with the following extension to executeFunctions:

function executeFunctionsWithTimeout(funcs, timeout) {

var transitionByTimeout = function(f) {
window.setTimeout(f,timeout);
};
executeFunctions(funcs, transitionByTimeout);
}


This is still a recursive solution to a recursive problem, but it lets the user define the code in a much more manageable way. If I let myself use jQuery I'd probably setup a queue of functions and use events to fire them off and detect completion (to fire off the next event), so that each function wasn't actually invoking the next, but this code is trivial, and handles blocking and detached transitions with ease.

I also had the Function Efficiency Considerations section of Mozilla's Core JavaScript Reference gently reminding me to be careful with closures as they can get tricky with garbage collection. I want to say that executeFunctions is ok in this regard, since it's not returning anything into global or any other persistent scope, but I'm still a little new to JavaScript to say for sure.

The demos of executeFunctions() include the use of setTimeout, mouseOver, confirm, and no transitions.

Tested in FF3, IE6, IE7, and Safari.

Spam Jazz

10/08/2008 by fansipans to [ qmail spam rblsmtpd smtp email mail networking server configuration blacklist spamcop ]

Three cheers for Dan Bernstein's rblsmtpd!

After initially setting up qmail and procmail years ago, one of the long-lingering items on my todo list was make napkindrawing's spam handling much better. I've basically been operating in whitelist mode, with aggressive procmail rules, which required somewhat regular scans through my Junk and Unfiltered folders to check for valid mail marked as spam. I'd always assumed that a more reliable option would take a few hours of configuration and tweaking.

Well I finally took a few minutes to see if could tweak my existing anti-spam setup (procmail), and see what my other options are, what would be the easiest path given my current setup. I quickly realized that rblsmtpd is already installed, and simply needs to be uncommented in my qmail init script!

rblsmtpd is a simple program that serves a tiny purpose, in the spirit of all of Dan Bernstein's other software. It sits between tcpserver, which actually listens for connections, and qmail, which handles mail delivery. rblsmtpd is passed domain names on the command line like "bl.foo.com", which are run by organizations maintaining ip address blacklists. When a remote server, say with ip address from a.b.c.d, connects to deliver mail, rblsmtpd does a DNS lookup on the domain "d.c.b.a.bl.foo.com". If the DNS server for bl.foo.com returns a TXT record, the connection is denied, and the contents of the TXT record are displayed to the client, and logged locally. So you get the speed, configurability, and hierarchical nature of DNS giving a practically instant, fresh, YES/NO answer as to whether the sending party is in the blacklist or not. Sweet!

After enabling rblsmtpd, and adding bl.spamcop.net, and removing relays.ordb.org, I'm seeing it block an average of 5 emails per hour, which is almost all of my spam. The remaining couple that slip through I've been forwarding to spamcop, and adding to my procmail rules.

Forwarding the remaining spam to spamcop helps all users of spamcop. They also provide relatively long-term subscriptions for reasonable prices, which I'll certainly consider after I've run this setup enough to trust it.


Edit: The most effective DNS BlackList seems to be zen.spamhaus.org. It's a combination of a number of other blacklists, and no spam has managed to get through in the last few hours since I added it. We'll see ...

Edit Edit: After a week or so of using Spamhaus' Zen DNSBL, only a few junk emails get through every day, out of 300+ attempts. My use of spamcop catches about 10 spams a day (that Zen misses), and the few that get through I've noticed on spamcop's reporting site are usually registered in cbl.abuseat.org's DNSBL, so I've added cbl.abuseat.org as the third DNSBL to check. That should drop it to no more than one junk message every other day :)