Sunday, February 28

.NET PubSubHubbub Subscriber Client

Finally had a chance to clean up the simple .NET PubSubHubbub client and callback handler I wrote last weekend. Currently implements just a Subscriber Client and an ASHX handler for processing subscription verification and push notification receipt.

I don't believe pubsubhubbub.appspot.com supports localhost callbacks, so you'll need to have a publicly exposed IP address or domain name to host the callback handler. I use DynDNS myself. (I could be wrong, I'm a dilettante when it comes to this PubSubHubbub stuff.)

NPubSubHubbub - find it here.

Saturday, February 27

Unpaid product endorsement: Sorel "Blizzard" Boots

In the midst of the wet, heavy snow followed by rain, freezing rain and sleet upstate New York has enjoyed this week, I've been appreciating the heck out of my winter boots. I have had these boots since I delivered papers and cleared driveways as a kid, some 16-17 winters now.

The boots in question are Sorel "Blizzard" Boots, rated to -35 or -40. I believe I got them at some sort of outlet or discount store in the Lake George "Million Dollar Half Mile," and they are one of the earliest and also most worthwhile, lasting clothing/gear purchases I ever made. I think I paid $45 or $55, maybe a little more. You can find an example here:

Sorel Blizzard Boots (sold out)

Sierra Trading Post - Sorel Blizzard Boots (sold out)

I'm not sure if mine were made in China or not, as it looks like the most recent generations were. I can't find the Blizzards on the Sorel website, so sadly, it's possible they don't even make them anymore.

These boots have been great for everything from newspaper delivery to dog walking to snowblowing to walking through downtown slop after parking six blocks from the office to being urinated on by cats. The original laces, after a cleaning, are still going strong. The waterproof bottoms are still 100% intact and keeping my feet dry. The nylon uppers are still in like-new condition as well. The liners are in great shape as well -- no real signs of wear on anything, 16 or 17 years later. These are a great utility muck boot for winter and early spring. I wish more products made these days had this kind of value and staying power.

Parting word: I hope Sorel still makes the Blizzard -- I don't see another men's winter boot in their lineup that fits the same niche at the same price point.

Monday, February 22

My First Google Buzz App: Who gives a frak?

Subhead: My impression of Google Buzz/the Google Buzz "API."



As most are probably aware, Google Buzz recently launched, while with much less fanfare than the anti-climactic and rather disappointingly immature, but retaining potential, Google Wave, still plenty of hype, noise and clamor.

OK, Google Buzz itself is decent. Nothing super special, but it has potential. Aggregation can make my life easier in various projects. I'm not wowed by it, but, without having had anything in the way of expectations, I'm not disappointed, either.

Now, on the API side ... WHAT API!? There's really not a whole lot of programming to do against Google Buzz yet. Users can associate various accounts for aggregation from other well-known social media services, and Google Buzz provides some XFN markup for non-standard content or services to enable custom associations:

<link rel="me" type="text/html" href="http://www.google.com/profiles/your.username"/>

As far as I can tell, though I'll grant you my weekend was spent on the output side of Buzz and not so much the input, the only way to get content into Google Buzz right now is by an associated service or feed -- which can include your own RSS or ATOM feed, but you can't directly post an update to Google Buzz via API.

On the consumer side, you can pull a user's Buzz updates as ATOM using:

http://buzz.googleapis.com/feeds/{33-digit profile ID}/public/posted "ugly URL"

(You are supposed to be able to use your username, i.e. andrew.badera, instead of that 33-digit profile ID but apparently those so-called "friendly URLs" aren't pushing updates as properly or completely to the hub as the ugly URL-based subscriptions.)

You can subscribe to push notifications of a user's feed via pubsubhubbub.appspot.com. I didn't spend a ton of time digging, but in what time I did spend, I didn't find a .NET PubSubHubbub client subscriber or push notification callback handler floating around the internets. I've written a C# subscriber utility and an ASP.NET .ASHX handler for subscription verification and push callback receipt and handling which I'll be posting later today after hosting it somewhere like Google Code.

So far, Google Buzz and its API seem like Just Another Aggregator. Yes, the PubSubHubbub protocol is pretty freakin' cool, and, at least for now, seems highly responsive when it comes to subscription requests and push deliveries. I'm not yet sure however what's going to entice mainstream social network users to make the leap to Buzz. I'm compelled for business purposes, not personal, and social networking apps don't make the leap without personal engagement and enthusiasm.

Sunday, February 21

Update: Custom URL Shortener

This is an update to a previous piece on shortening a URL/encoding an ID.

TSQL CHARINDEX starting at position zero returns an unexpected value of ' '. TSQL updated to do some explicit swaps around position 0, as well as to better randomize the encoding characterset.

ShortenID:

CREATE PROCEDURE [dbo].[ShortenID]
@idToShorten numeric(18,0),
@debug bit = 0,
@shortenedID varchar(20) OUT
AS

BEGIN
SET @shortenedID = 'NULL ID'

IF @idToShorten < 1
RETURN

DECLARE @i int = 0
DECLARE @ShortChars varchar(100) = 'TrCn8A2faBpb95ceDYdFhGjK6kmL3NxORPqSUtV7XvyH4zuQMsgJ'
DECLARE @charBase int = LEN(@ShortChars)
DECLARE @currentCharacter char
DECLARE @currPos int

DECLARE @shortened varchar(20) = ''

WHILE @idToShorten > 0
BEGIN
IF @debug = 1
BEGIN
PRINT CONVERT(varchar(20), @i) + ': @idToShorten: ' + CONVERT(varchar(20), @idToShorten)
END

SET @currPos = (@idToShorten % @charBase)
IF @debug = 1
BEGIN
PRINT '@currPos: ' + CONVERT(varchar(20), @currPos)
END

SET @currentCharacter = SUBSTRING(@ShortChars, @currPos, 1)
IF @debug = 1
BEGIN
PRINT '@currentCharacter: ' + CONVERT(varchar(20), @currentCharacter)
END

IF @currentCharacter = ' '
BEGIN
SET @currentCharacter = 'Z'
END

SELECT @shortened = @currentCharacter + @shortened
IF @debug = 1
BEGIN
PRINT '@shortened: ' + CONVERT(varchar(20), @shortened)
END

SET @idToShorten = FLOOR(@idToShorten/@charBase)
SET @i = @i + 1
END

SELECT @shortenedID = @shortened
END


ExplodeID

CREATE PROCEDURE [dbo].[ExplodeShortID]
@shortenedID varchar(20),
@debug bit = 0,
@idExploded numeric(18,0) OUT
AS

BEGIN
SET @idExploded = -1

IF LTRIM(RTRIM(@shortenedID)) = ''
RETURN

DECLARE @ShortChars varchar(100) = 'TrCn8A2faBpb95ceDYdFhGjK6kmL3NxORPqSUtV7XvyH4zuQMsgJ'
DECLARE @charBase int = LEN(@ShortChars)
DECLARE @currentCharacter char
DECLARE @currPos int = 0

DECLARE @exploded numeric (18, 0) = 0

DECLARE @lenShortenedID int = LEN(@shortenedID)
DECLARE @i int = @lenShortenedID
DECLARE @pow int = 0;
DECLARE @currPosSource int = 0

WHILE (@i > 0)
BEGIN
IF @debug = 1
BEGIN
PRINT '@i: ' + CONVERT(varchar(20), @i)
END

SET @currPosSource = (-1 * ( @i - LEN(@shortenedID) ))
IF @debug = 1
BEGIN
PRINT '@currPosSource: ' + CONVERT(varchar(20), @currPosSource)
END

SET @currentCharacter = SUBSTRING( @shortenedID, @currPosSource + 1, 1 )
IF @debug = 1
BEGIN
PRINT '@currentCharacter: ' + CONVERT(varchar(20), @currentCharacter)
END

IF @currentCharacter = 'Z'
BEGIN
SET @currentCharacter = ' '
END

SET @currPos = CHARINDEX(@currentCharacter, @ShortChars COLLATE Latin1_General_CS_AS)
IF @debug = 1
BEGIN
PRINT '@currPos: ' + CONVERT(varchar(20), @currPos)
END

SET @pow = POWER(@charBase, @i-1)
IF @debug = 1
BEGIN
PRINT '@pow: ' + CONVERT(varchar(20), @pow)
END

SET @exploded = @exploded + (@currPos * @pow)
IF @debug = 1
BEGIN
PRINT '@exploded: ' + CONVERT(varchar(20), @exploded)
END

SET @i = @i - 1
END

SET @idExploded = @exploded
END

Study: Ages of social network users

Interesting, and to me at least, a little bit surprising.

Study: Ages of social network users | Royal Pingdom

Wednesday, February 10

Twitter engineering blog, Twitter Text library in C#

Dewald Pretorius came across and shared on the Twitter dev-talk list the recently created Twitter engineering blog. Interesting engineering stuff to be read there, and not necessarily Twitter-specific by any means.

One of the entries mentions Twitter Text libraries for Ruby and Java. These libraries allow external consumers to, in theory, parse tweet text for URLs, screenname mentions and hashtags the same way Twitter does.

I grabbed Matt Sanford's twitter-text-java and created a quick C# port, NTwitterText. It looks like one or two of the URL regex patterns need some tweaking, but otherwise all functionality ported over pretty easily and cleanly.

Friday, February 5

Would like to share



Would like to share the StorageByMail website which we revamped over the past couple months, and relaunched on Rackspace Cloud servers for the client last weekend. StorageByMail is an NYC-based startup that enables customers to conveniently ship items into and out of storage.

The original site was in classic ASP, using all dynamic SQL. The new, more secure site is in ASP.NET with bound parameters, uses updated cryptography and the MembershipProvider and RoleProvider to replace a legacy homegrown user repository. Various new functionality has been added, as well as Telerik GUI controls for improved usability and user experience. AJAX abounds.

Dan @ SBM, we enjoyed working with you, and certainly hope to do so again.