So what’s this blog currently made of?

  • .Text 0.95, extremely customized
  • Windows 2003 Server, IIS 6, & MSSQL 2000
  • Dell Optiplex 733Mhz, 384MB RAM, ~10GB mirrored drives, and a crappy Belkin UPS
  • ~3mBps / 1mBps residential ADSL
  • much love, frustration, and self-nitpicking

Nothing so fancy as a kitchen appliance, but I’m impressed anyway.

Figured I’d better justify the “meta-throbs” post category.  Hey wait a sec, was that meta-meta??

my Code: wipe_commentrange

*sigh*, more comment Spam today — 150 in a few minutes, despite my nice new .Text spam filters (they were all identical).

Unfortunately, I can’t just go into blog_content and delete the range (since the comment count wouldn’t be updated), and I didn’t want to click [Delete], [Yes], [Continue] 150 times, SO: I just fired-up SQL Profiler, reverse-engineered a standard delete call, and slapped together a utility Stored Procedure to loop that call, for big cleanup jobs.

It takes IDs for the first and last comment spam which make it through, and wipes them all out with .Text’s native blog_DeletePost stored proc.  Just paste this into Query Analyzer and run to install:

CREATE PROCEDURE re_wipe_commentrange 
@p_ID int,
@p_lastID int

DECLARE @v_sql varchar(8000)
WHILE @p_ID <= @p_lastID
	SET @v_sql = 'exec blog_DeletePost @ID = ' + cast(@p_ID as varchar(5)) + ', @BlogID = 0'
	SET @p_ID = @p_ID + 1

(Note: this is for single user .Text blogs.  Multiple-user blogs will need fiddling with the embedded BlogID parameter.)

Then to use it, call like so in QA: EXEC re_wipe_commentrange 900, 1000.

Might save someone a few minutes (even with writing and posting it here, I think I'd still be clicking delete right now).

Time to consider a way to implement MT-Blacklist...

How do you decide?

My friend Mike Butler posted a thought-provoker about blog self-censorship and choosing topics.

I’ve struggled with that dilemma too.

One one hand, I want my family, friends, and strangers to be able to read my blog without being offended or bored.  On the other, I need to express myself freely.  I realized early with this blogging venture that I have a habit of putting on personas for each situation.  That bugged me since it seemed disingenuous, and it was making me second guess myself.  I think I settled on making my blog just For Me (at least as far as topics) — including the tech-geek, the father, the immature Jr. High dork, the business man, the music-fan, the navel-gazing philosopher, etc.

If a subject bores or bothers someone in real life, they have to grit their teeth.  Here at least they can ignore me without worrying about my feelings :>

I think my goal is no longer about avoiding boring/scaring people away, but rather trying to attract people by giving each of my facets a balanced representation.  For example, Me-the-father hasn’t really posted yet (mostly due to the sheer magnitude of the thoughts I want to distill into a post), so there’s a whole audience I’ve missed so far. 

Good food for thought.  Thanks Mike.


I’ve implemented Dean Edwards‘ Star-Light for code-formatting here.  It’s an awesome (and useful!) demonstration of the power of DHTML Behaviors.

Oh, and it’s free (just a Creative Commons license).

And it works in both IE and Firefox*.

All it takes is a linked stylesheet and a CSS class on the target code section (specifying the language of the code), and Star-Light dynamically formats and colors it in the browser. 
For example, this code:

<pre class="vbscript">
' this is a "comment"
'' so is 'this'
DIM string
string = "' string '"
call msgbox("Hello ""Dean""!")
FUNCTION getText(a, b, c)
	getText = a + b & cstr(c)

displays thusly:

' this is a "comment"
'' so is 'this'
DIM string
string = "' string '"
call msgbox("Hello ""Dean""!")
FUNCTION getText(a, b, c)
	getText = a + b & cstr(c)

The supported languages are CSS, HTML, Javascript, PHP, and XML.  (For fun, it can also enhance plaintext conversation text: emoticons into images, *bold* into bold, /italic/ to italic, _underline_ to underline, plus enhancing “>” quoted sections.)

Coolest of all, though, it’s highly extensible via language modules.  I glanced through the code to see if I could make it support VBScript.  The engine is pretty complicated, but each module is a simple HTC file.

From there, it was easy to create a new module for VBScript and plugin the appropriate keywords straight from Microsoft’s Windows Script 5.6 Documentation.  I sent my VBScript module (working above) to Dean — he made a couple improvements, and said he’ll include it with the rest soon.  (I may also create modules for VB6 or VB.Net, but there’s a lot stuff to those languages…)

I don’t mean to gush, but: Very Cool.

Unfortunately, Dean hasn’t yet documented how to do write your own module (I figured it out on my own), but it’s pretty easy for someone who knows HTCs and has a language reference to copy/paste.

* Another gee-whiz bit: despite the coolness of DHTML Behaviors, they are normally only supported by Internet Explorer.  But Dean’s done a wonder, and written a Mozilla XBL wrapper which makes Mozilla/Firefox support DHTML Behaviors too! (which is of course wrapped into Star-Light).  This situation should be the poster child for the de-facto standards camp -vs- the slow academic W3C types, but more on that another day.  Meanwhile, I’ll sit back and regret my rationale “DHTML Behaviors are IE-only anyway, so I’ll go ahead and use all this other IE-specific code.” Like, uh, VBScript….. (dough!)

An observation: Door Store -vs- Vote-For-Me yard signs

Traditional email spam like the unsolicited Door Store ads they drop on my step (in plastic covers to maximize slipping).

Comment spam is a “We’re voting for Mr. Shmiggle” sign put in my yard without my consent.

Now that I’ve worked it out, I understand why comment spam irks me so much more, because it (ab)uses my reputation for its own (search engine) advancement.  But I don’t want to put up a fence by closing comments tho, because I do want my friendly neighbors to visit and talk to me.

So anyway, if anyone using .Text 0.95 is interested, here’s my code to negate the search engine benefit to the comment spammers:

Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
	Dim reqURL As String = Request.CurrentExecutionFilePath
	IF reqURL.toLower().indexOf("/archive/")<0 OR Request.Form.ToString()<>"" THEN EXIT SUB
	'-- get content
	Dim oWriter As New StringWriter()
	Server.Execute(reqURL, oWriter)
	Dim strResponse As String = oWriter.ToString()
	oWriter = Nothing

	'-- find comment section
	Dim iStart As Integer, iStop As Integer
	iStart = strResponse.IndexOf("<div id=""comments"">")
	IF iStart>0 THEN iStop = strResponse.IndexOf("</div>", iStart)

	If iStart <> -1 And iStop <> -1 Then
		'-- nofollow comment section's links
		DIM strTarget as string = strResponse.Substring(iStart, iStop - iStart)
		DIM strTargetFixed as string = _
			strTarget.replace("<a target=""_new"" href=""http", _
			"<a target=""_new"" rel=""nofollow"" href=""http")
		strResponse = strResponse.replace(strTarget, strTargetFixed)
	End If

	'-- send content
	Response.End()		'prevent conventional response
End Sub

Just replace the standard Application_BeginRequest procedure with this one in the global.asax.vb file (or absorb mine into it.)  It intercepts outgoing comments and dynamically inserts rel=”nofollow” into any contained links.

It won’t prevent comment spam, but it will negate the search engine benefit to the comment spammer, turning the “Vote-For-Me” signs into mere litter in your yard.

One catch:  this breaks .Text’s inline “Remove Comment” links.  You can still delete them in the the admin area’s Feedback section, tho.  Since the comment spam seems to come in waves, that’s an easier way to delete them all at once anyway.

(I guess my next goal is actually preventing comment spam via a captcha or challenge-reponse mechanism, but til then I feel more luxury of time to explore possibilities.)