September 2007 - Posts

Blog changes - Part II (the joys of medium trust)
Filed under: ,
PostedFriday, September 21, 2007 3:14 PM by Nino

Earlier this month, I signed up with FeedBurner in order to have a better syndication experience for my readers.   That was Part I of the changes. Part II took a bit longer than the additional time I had allowed for it. 

"The plan" for Part II was to move off of Community Server (hereafter, CS) 2007 and onto Subtext.  Things didn't go quite as planned - imagine that. 

Why move off of CS?  CS has a lot of functionality, more than I need or use. And, it is slow sometimes (in fairness, I think that a bit of this is due to the fact that I run it on a shared server).   So, once this decision was made, off to find a new blog engine.  I quickly arrived at two options: Subtext and dasBlog.   Both of these are excellent options in my opinion.   To keep it brief, I opted for Subtext because I wanted to keep the SQL Server back end.   Ok, fair enough. 

As noted, I host nino.net at Server Intellect on a shared server (i.e. shared web and database servers). As many (most?) web hosting companies do these days with ASP.NET 2.0 in a shared environment, they mandate a state of Medium Trust.   Many things break under medium trust, if you've not designed for it. Keyvan discusses this here.

Since support exists in both CS and Subtext for BlogML, I decided to use this to do the data transfer.  For the export from CS, I used Keyvan Nayyeri's BlogML converter.  For the import, well, Phil and the Subtext team have baked that in. And the import worked flawlessly save for one post (The Mobile Minute 50), which I removed from the XML and need to figure out what is wrong with it (XML Spy says that the full BlogML export is compliant with the BlogML schema, so that's not it).

I then created "blog" directory on my root and then went to my control panel and set this directory up as both a virtual directory and virtual application. Afterwards, I installed all the spiffy Subtext bits into there.  I also followed Phil's guide for configuring Log4Net (used by Subtext) under medium trust.   Mind you, gentle reader, I ran through this exact scenario on my development server and it worked flawlessly, so I expected the same here.  (Granted, I had not yet realized that I had not actually tested under Medium Trust). 

Once I realized the issue (I first revisited Phil's post on Log4Net under ASP.NET 2.0 Medium Trust to verify I had things set up correctly), I also realized that I then, recalling from prior research, had two quick options to resolve this: move my blog to the root, or create a blog sub-domain.  I was not fond of either option.  Not to mention the fact that well, my blog was down. Feh.   I rolled back to CS (just had to whack the /blog dir and its settings) and settled in for further research.

My options at this point:
1. Put Subtext on the root (i.e. http://nino.net) or sub-domain it (i.e. http://blog.nino.net).
2. Contact my host and ask them for an exception to the medium trust, please. (btw, my problem was with FileIOPermission).
3. Keep with CS and dedicate some future time to resolve the issue.

Given a time crunch, I optioned for option 3.  Now, that said, I still wanted to change my URL to http://nino.net/blog from http://nino.net/blogs/nino since this is the only blog here - and let's face it, I was delusional when I thought I might have other blogs at this site. ;-)

So, how to do that?  CS config goodness and some URL rewriting to keep things all search engine friendly.

I queried the CS forums (specificially Blogs and Setup and Installation) and did a little searching elsewhere. I particularly recommend Jayson Knight's post on CS Config File Overrides and this thread, started by Scott Watermasysk, on converting CS to single blog. A note of thanks to Ken Robertson for his assistance in getting me to see the obvious in the siteurls_override.config.  Speaking of overrides, one could simply edit the communityserver.config and siteurls.config files directly instead of leveraging override files, which I just may do now that I understand what needs set.

To see how I converted my CS installation to a single-blog setup and implemented URL rewriting, see my post about it.

For Part III of my blog changes, which I won't blog about other than this mention, the changes are all superficial - skinning and theming - which most of you, if my stats are correct, won't see as you get here via RSS.  Those of you who do visit the site via your browser will see some changes shortly.

In sum, blog URL is now: http://nino.net/blog  and syndication is: http://feeds.feedburner.com/NinoBenvenuti

Single-blog setup in CS2007 with a dash of URL rewriting on top
PostedFriday, September 21, 2007 3:12 PM by Nino

My goal here was convert my Community Server 2007 installation to have a single blog (and have a URL of the format http://domain.tld/blog) and maintain my file library (at http://domain.tld/files). Since I switched to SmugMug, I have photo galleries disabled in addition to turning off forums, FeedReader, and BlogRoller.  To accomplish the transition to a single-blog, I added a communityserver_override.config, siteurls_override.config, and then added some URL rewriting so that all the old links across other blogs and in search engines do not break.

My communityserver_override.config file looks like this:

 1: <?xml version="1.0" encoding="utf-8" ?> 
 2: <Overrides>
 3:  <Override xpath="/CommunityServer/Tasks/Threads/Thread/task[@name='ForumsIndexing']" mode="remove" />
 4:  <Override xpath="/CommunityServer/Tasks/Threads/Thread/task[@name='GalleryIndexing']" mode="remove" />
 5:  <Override xpath="/CommunityServer/Tasks/Threads/Thread/task[@name='FilesIndexing']" mode="remove" />
 6:  <Override xpath="/CommunityServer/Tasks/Threads/Thread/task[@name='FeedUpdater']" mode="remove" />
 7:  <Override xpath="/CommunityServer/Tasks/Threads/Thread/task[@name='RollerBlogsUpdater']" mode="remove" />
 8:  <Override xpath="/CommunityServer/Tasks/Threads/Thread/task[@name='ImportPhotoJob']" mode="remove" />
 9:  <Override xpath="/CommunityServer/Tasks/Threads/Thread/task[@name='UserInvitationExpiration']" mode="remove" />
 10:  <Override xpath="/CommunityServer/Tasks/Threads/Thread/task[@name='ReportingVisitors']" mode="remove" />
 11:  <Override xpath="/CommunityServer/Tasks/Threads/Thread/task[@name='ReportingPageViews']" mode="remove" />
 12:  <Override xpath="/CommunityServer/Tasks/Threads/Thread/task[@name='RebuildThumbnailsJob']" mode="remove" />
 13:  
 14:  <Override xpath="/CommunityServer/Tasks/Threads/Thread[@minutes='5']" mode="update">
 15:  <Thread minutes="1">
 16:  <task name="Emails" type="CommunityServer.MailRoom.Components.EmailJob, CommunityServer.MailGateway.MailRoom" enabled="true" enableShutDown="false" failureInterval="1" numberOfTries="10" />
 17:  </Thread>
 18:  </Override>
 19:  
 20:  <Override xpath="/CommunityServer/Weblog" mode="change" name="blogFileStorageLocation" value="~/images" />
 21:  <Override xpath="/CommunityServer/Weblog" mode="new" name="defaultApplicationKey" value="nino" />
 22:  
 23:  <Override xpath="/CommunityServer/CSModules/add[@name='RollerBlogRules']" mode="remove" />
 24:  <Override xpath="/CommunityServer/CSModules/add[@name='WeblogPostandArticleHtmlScrubbing']" mode="remove" />
 25:  <Override xpath="/CommunityServer/CSModules/add[@name='AutoBlogCreate']" mode="remove" />
 26:  <Override xpath="/CommunityServer/CSModules/add[@name='AutoApproveForumModule']" mode="remove" />
 27:  <Override xpath="/CommunityServer/CSModules/add[@name='BBcodeToHtml']" mode="remove" />
 28:  <Override xpath="/CommunityServer/CSModules/add[@name='IrcCommands']" mode="remove" />
 29:  <Override xpath="/CommunityServer/CSModules/add[@name='ForumCensorship']" mode="remove" />
 30:  <Override xpath="/CommunityServer/CSModules/add[@name='ForumEmoticon']" mode="remove" />
 31:  <Override xpath="/CommunityServer/CSModules/add[@name='ForumSourceCode']" mode="remove" />
 32:  <Override xpath="/CommunityServer/CSModules/add[@name='HtmlNestingCorrectionModule']" mode="remove" />
 33: </Overrides>

Of particular note here is the setting of the defaultApplicationKey value (line 21).  You will need to set this to your blog app key (You can view the application key for your blog in Control Panel > Administration > Blogs > Blogs. It is the value of the "Name" column for the given blog.). 

My siteurls_override.config looks like this:

 1: <?xml version="1.0" encoding="utf-8" ?> 
 2: <Overrides>
 3:  <Override xpath="/SiteUrls/transformers/add[@key='##blogdirectory##']" mode="change" name="value" value="" />
 4:  <Override xpath="/SiteUrls/locations/location[@name='weblogs']" mode="change" name="path" value="/blog/" />
 5:  <Override xpath="/SiteUrls/locations/location[@name='weblogs']" mode="new" name="physicalPath" value="/blogs/" />
 6:  <Override xpath="/SiteUrls/locations/location[@name='weblogs']" mode="change" name="type" value="CommunityServer.Blogs.Components.SingleBlogLocation, CommunityServer.Blogs" />
 7: </Overrides>

I would like to point out that in the original guidance from Ken, he said that the ##blogdirectory## transform value (line 3) should be "/"; however, this resulted in odd-looking URLs of the sort http://nino.net/blog//archive/2007/04.aspx It is certainly legitimate, but the "//" bothered me, so I changed the value to "" and it works just fine.  Note that you need to restart the app pool (via a direct recycle or by touching the web.config) in order for CS to pick up the _override.config files.

Now, I have my blog in single-blog 'mode', and I my blog URL is now http://nino.net/blog .   Swell.  Unfortuantely this now breaks links search engines and from other blogs.  Time for some URL rewriting. Can't I just do this via the URL rewriting in CS? Not quite. 

I settled on using the UrlRewriter.Net HttpModule. Configuring this HttpModule required a little RegEx action. I turned to the excellent Expresso regex development tool to help me validate my regex.  To get UrlRewriter.net up and running I had to, generically, do two things:  drop the .dll in my /bin and edit my web.config.  My web config edits are as follows:

I added a <configSections> node.  Remember, this section, if it exists, must be the first section under the <configuration> node.

 <configSections> <section name="urlrewritingnet" restartOnExternalChanges="true" requirePermission ="false" type="UrlRewritingNet.Configuration.UrlRewriteSection, UrlRewritingNet.UrlRewriter" /> </configSections>

I then located the <httpModules> section and added the UrlRewriteModule entry like so:

 <httpModules> <add name="UrlRewriteModule" type="UrlRewritingNet.Web.UrlRewriteModule, UrlRewritingNet.UrlRewriter" />

(remainder of <httpModules> section omitted for brevity)

Lastly, I added the <urlrewritingnet> section (this needs to be outside of <system.web>, but inside <configuration>):

 1:  <urlrewritingnet 
 2:  rewriteOnlyVirtualUrls="true" 
 3:  defaultPage="default.aspx" 
 4:  xmlns="http://www.urlrewriting.net/schemas/config/2006/07" > 
 5:  <rewrites> 
 6:  <add name="Blog" 
 7:  virtualUrl="~/blogs/nino/default.aspx"
 8:  destinationUrl="~/blog/default.aspx"
 9:  redirect="Application"
 10:  redirectMode="Permanent"
 11:  rewriteUrlParameter="ExcludeFromClientQueryString" 
 12:  ignoreCase="true" /> 
 13:  <add name="FullyQualifiedBlogEntry" 
 14:  virtualUrl="~/blogs/nino/archive/(20\d\d)/(0[1-9]|1[012])/(0[1-9]|[12][0-9]|3[01])/(.*).aspx"
 15:  destinationUrl="~/blog/archive/$1/$2/$3/$4.aspx"
 16:  redirect="Application"
 17:  redirectMode="Permanent"
 18:  rewriteUrlParameter="ExcludeFromClientQueryString" 
 19:  ignoreCase="true" /> 
 20:  <add name="FullyQualifiedBlogEntryComment" 
 21:  virtualUrl="~/blogs/nino/archive/(20\d\d)/(0[1-9]|1[012])/(0[1-9]|[12][0-9]|3[01])/(.*).aspx#comments"
 22:  destinationUrl="~/blog/archive/$1/$2/$3/$4.aspx#comments"
 23:  redirect="Application"
 24:  redirectMode="Permanent"
 25:  rewriteUrlParameter="ExcludeFromClientQueryString" 
 26:  ignoreCase="true" /> 
 27:  <add name="MonthlyArchive" 
 28:  virtualUrl="~/blogs/nino/archive/(20\d\d)/(0[1-9]|1[012]).aspx"
 29:  destinationUrl="~/blog/archive/$1/$2.aspx"
 30:  redirect="Application"
 31:  redirectMode="Permanent"
 32:  rewriteUrlParameter="ExcludeFromClientQueryString" 
 33:  ignoreCase="true" /> 
 34:  <add name="Tags" 
 35:  virtualUrl="~/blogs/nino/archive/tags/(.*)/default.aspx"
 36:  destinationUrl="~/blog/archive/tags/$1/default.aspx"
 37:  redirect="Application"
 38:  redirectMode="Permanent"
 39:  rewriteUrlParameter="ExcludeFromClientQueryString" 
 40:  ignoreCase="true" /> 
 41:  <add name="AboutMe" 
 42:  virtualUrl="~/blogs/nino/pages/about-me.aspx"
 43:  destinationUrl="~/blog/pages/about-me.aspx"
 44:  redirect="Application"
 45:  redirectMode="Permanent"
 46:  rewriteUrlParameter="ExcludeFromClientQueryString" 
 47:  ignoreCase="true" /> 
 48:  <add name="Syndication" 
 49:  virtualUrl="http\://nino.net/blogs/nino/(rss|atom).aspx"
 50:  destinationUrl="http://feeds.feedburner.com/NinoBenvenuti"
 51:  redirect="Domain"
 52:  redirectMode="Permanent"
 53:  rewriteUrlParameter="ExcludeFromClientQueryString" 
 54:  ignoreCase="true" /> 
 55:  </rewrites> 
 56:  </urlrewritingnet>
 

In these seven entries, I have covered the base blog URL, a fully-qualified blog entry, blog entry comments, monthly archives, tags, the "About Me" page, and my syndication URLs. The regex is, IMO, straightforward.  I suggest the excellent http://www.regular-expressions.info/ for further study on regular expressions.  I would like to note that for the regex on lines 14 and 21, I could have used virtualUrl="~/blogs/archive/(.*)/(.*)/(.*)/(.*).aspx" or virtualUrl="~/blogs/archive/20[0-9][0-9]/[0-1][0-9]/[0-3][0-9]/(.*).aspx", but my final solution is more efficient (definitely more efficient than using the dot "(.*)").  Also note that I have the redirectMode set to "Permanent"; this will send the browser a HTTP 301 response, telling it that this change is permanent (as opposed to setting it to "Temporary" which would result in the browser receiving a HTTP 302).

Since I was so pleased with the UrlRewriting.net HttpModule and wanted to thank the authors in a way other than linking to them, I gave them a small donation. It felt good, too.  

The Mobile Minute 158
Filed under:
PostedTuesday, September 11, 2007 12:02 AM by Nino

Hardware

 Software

Development

Community

Enzo At Two Months
Filed under:
PostedMonday, September 10, 2007 4:31 PM by Nino

Enzo is now eight weeks, one day old. What a long eight weeks and one day it has been.

The first week was relatively easy, in retrospect. Basking in the joy of a newborn, we were pretty excited and nervous all at the same time. He cried, we fed him, he slept. During this week we also had our first visit to the hospital (one of the top ten in the US, btw) because he had hyperbilirubinemia. He spent twenty-four hours in the hospital getting phototherapy to address this.

Week two started to get a bit more labor intensive. He started become a bit fussier and the sleep started getting random. Near the end of week three, we switch his formula from Similac Organic to Similac Sensitive (to help with fussiness and gas). The first two days of this showed some improvement, but then it dropped off.

At the beginning of week four, I returned to work. For the next two weeks we got very little sleep. He got to where he was sleeping a total of six or seven hours per day, and spent the rest of his waking moment fussy and unhappy. Frustration crept in quickly. Lack of sleep plus constant crying from your infant (and not being able to console him in any manner) does not make for a pleasant household. Not to mention not knowing what the problem is, but knowing he is in pain.

It is during this time of sheer exhaustion and frustration we became so irritated with him. It sounds awful to say that, but our exhaustion and frustration plus his constant crying and fussing brought us to that place. I still feel horribly about the stern words and glaring looks he received from me. Make no mistake, we love him dearly, we just didn't like him much, each other, or ourselves much during this time.

Our pediatrician diagnosed him with both laryngomalacia and GERD. We started him on infant Zantac. We also, per our pediatrician's recommendation, switch his formula again, to Similac Alimentum, a hypoallergenic formula. Within twenty-four hours of switching his formula, we had a different baby on our hands.

At the end of week six, a new evening sleep pattern began: We would feed him about 10pm or so and then put him down - he slept until 4:30am. Some nights he would even make it to 5:15am. I cannot tell you how happy this made us. During the day he was still fairly fussy, which constantly tested my wife's patience (and then mine, when I got home from work).

Now, at week eight, he has broken the overnight sleep pattern and we're trying to figure out the new pattern and still maintain some semblance of our sanity. Yep, that's the great thing <snort> - his randomness and creating and breaking of patterns. What is soothing today may be antagonistic tomorrow.

If there is one thing that is absolutely true as a parent it is this: every pregnancy and every child is different. A lot of similarities between them, but still different and unique.

Since the Zantac has been of minimal help, our pediatrician has switched us to Prevacid, which, while only once a day, is a pain to administer. The tablet doesn't dissolve well, so it is a challenge to make sure he gets a proper dose. The Zantac was in syrup form that was easy to give to him.

He's going in for 'surgery' next week to get a laryngoscopy, a tracheoscopy, and a bronchoscopy. We're both a little nervous about the fact that he'll be fully anesthetized. Not to mention my general dislike of hospitals, and particularly seeing my son in one.

We would love for him to return to his (approximately) six hour overnight sleep schedule, but above that, we want what every parent wants for their child - the child to be healthy and happy. If he would feel better, he'd not be so inconsolable during the day.

The picture above was taken (using my HTC S620) on Labor Day 2007, one of his few good (i.e. mellow, dare I say 'happy') days since he's been born.

Fatherhood - Part I
Filed under:
PostedMonday, September 10, 2007 4:24 PM by Nino

Overwhelmed.

Exhausted. Frustrated. Awestruck. Relieved. Proud. Scared. Humbled.  These words describe what I've felt these first two months of fatherhood. It was a difficult journey for him to get here, and now that he's here, Enzo has changed everything. Forever.

No return, no refund. The fact that my wife and I are responsible for the care, feeding, and upbringing of our son so that he may be an educated, well-rounded, responsible, participating member of society is, well, overwhelming.  There was no test, no certification, no licensure.  Pretty much the one thing we were required to do [in order to bring him home from the hospital] was have an infant car seat[1].

A friend said "welcome to the new normal" - we're still trying to figure out exactly what that is.

The biggest challenge for me right now is trying to regain balance.  How do I now re-allocate my time to my marriage, my family, my friends, my employer, my customer, the community, and last, but not least, myself ? 

I don't know. I'm still sorting that; hopefully I'll have a good answer to that question such that my at least my family comes out on top.  (They haven't been, or, more accurately, my wife hasn't been, and she has been beyond patient with the high amount of overtime and travel I've put in throughout all of the death march projects I've been on over the last N years. Through that time, I've pretty much put work first (Delivery, Delivery, Delivery!). 

Perhaps I've already started to realign things.  I've been working locally since early spring (and needed to as my wife was having some significant issues with the pregnancy).  Of course, the question now is what to do when I roll off of this one (slated for January).

Feed URL changing
Filed under:
PostedWednesday, September 05, 2007 10:28 PM by Nino

I'm going to be making a number of changes to nino.net, namely around the blog, and to make the transition painless for my readers, I have changed to FeedBurner for my syndication URL.   Please update your RSS readers to point to: http://feeds.feedburner.com/NinoBenvenuti

Thanks!