November 2007 Entries

I lost functionality.  I did the Blackjack rebate thing and now I need to get access to the windows directory on the phone so I can get access to my custom home screen.

Anyone know how to do this?  I could do this in Windows XP with ActiveSync.

Update:  I was just stupid, it was in the Application Data\Home directory.  Still haven't the slightest clue on how to add shortcuts though.

The previous post won't need to be done since they already did it for me.

So I have a Windows Home Server, I have Expressions Encoder, and I can program c# fairly quickly.  What do all 3 of these have in common?  The soon to be all time, best WHS plugin ... ever.

I found out I can use Encoder though command line.  I can write a simple folder watching utility to kick off an encode whenever it sees a movie file my 360 can't natively play.

Those with MSDN or MSDNAA account should have access to Encoder too.  I actually played with it today and was rather surprised at how easy it was to use too.

Few minutes for the app, figure 30 minutes to nail the syntax for Encoder, another 30 for figuring out how to do a WHS plugin and I'm good to go.

There is a 10 minute max video length.  Damn you and making me redo my video that needed to be redone anyways.

PIC-0089

My WHS's have come, oh, its on.

I was attempting to uninstall Visual Studio Express 2005 and had a little problem.  It hadn't made any progress in a few hours!  A quick search and I found out why.  The installer expects you to have the product registered!

Quan To has the quick solution to the problem, just kill the VSE process and it finishes the install.  For c#, it was VCSExpress.exe.

This problem had to have been fixed in 2008 but you never know.  You get some cool free stuff also for reg'in your copy too so just heads up.

For the bartender system, now that the timing is offloaded to the relay boards, I've run into a problem.  I have a progress bar but no real way to have it update.

In doing so, I created crappy time based progress bar.  I used a timer and inherited off the pre-existing progress bar.  This was done with Visual Studio 2008 also.  VS 2005 users will have to just drop the get/set or add in a private variable.  94ms is a rough estimation, at 1 minute, it is a secondish too long, at 93ms, it is a secondish too short.  Since this is all for visual pop, I don't think it really matters.

Why is there a public new void PerformStep()?  I had to override the base class's function and that is what I had to do.  The funny thing is I still call the base.PerformStep() in the timer_Tick function.

public class ProgressBarTimed : ProgressBar
{
private Timer timer = new Timer();
//DateTime start;

public int Milliseconds{ get; set; }

public new void PerformStep()
{
    Step = 100;
    timer.Interval = 94; // extra cycles for timer event and progress bar event
    Maximum = Milliseconds;
    timer.Tick += timer_Tick;
    timer.Start();
    //start = DateTime.Now;
}

private void timer_Tick(object sender, EventArgs e)
{
    base.PerformStep();
    if (Value == Maximum)
    {
        timer.Stop();

        //MessageBox.Show(start + "\n" + DateTime.Now + "\n" + (DateTime.Now - start).Milliseconds.ToString());
    }
}
}

Like comics?  A bit ago I became friends with a comic store owner and he just made some of the best commercials I've seen in a while.  If on the north side of Chicago, hit up the Comic Vault.

124292884_e851bed556[1] So I have a little story to share that happened to me on Thanksgiving.  My aunt needed some help figuring out how to email a very large file and I helped her out.  However, being the good Microsoft employee I am, I noticed that she had SQL Server on her computer which baffled me since there is no reason for her to have that on there.  My aunt isn't exactly a power user.  But seeing that icon in the task tray could have saved her a great deal of heart ache.

I noticed an icon that when hovered over said "RAID DISK FAILURE" and then I realized she was running a RAID 0 setup and one of her disks is throwing errors.

I have 2 Windows Home Servers (WHS) getting delivered to me.  One for myself, one for my parents.  Me being the wonderful nephew I am will route my WHS to my aunt so she can have the WHS backup all her data, have her replace the HD, then run the recovery tool so her computer is back up without her even knowing what may have happened if WHS technology wasn't around.

SO what is this horrible thing that may have occurred?  First let me explain RAID.  RAID 0 disk setups have 2 or more hard drives that run basically act as one hard drive.  You have increased performance, what appears to be a larger HD disk but have zero fault tolerance.  If one hard drive fails, basically you lose the data on all your hard drives on that RAID.  And as I mentioned, one of her hard drives is about to die.  It isn't dead dead yet, just throwing errors now.  I know from when my old PC died, she'll have a bit before she is in serious trouble.

With a WHS, with multiple hard drives in the system, you'll be able to have fault tolerance and a central location to store everything.  If a computer or something bad happens, roll it back.  A hard drive failure is no longer a month long affair to recoup from.  It is more of a "lets watch House" while WHS does its magic bringing your system back online.  Accidentally deleted some files?  Backtrack and BAM, they are undeleted.  It is like Time Machine (Apple OS 10.5) but if you hose your computer, the backed up data isn't hosed too.  My aunt won't have to reinstall windows, all her applications and pictures / files since WHS has a full, current back up.

Another day in the life of Clint, nerd herd employee #1337.

image

So I got the base part of the data working.  I also figured out what was causing the noise in the item.  It was the data I was physically getting, either it would be maxed out for no reason or zeroed out once again for no reason.  The maxing worried me, the zeroing not so much.  I added in a quick if check and it fixed it programmatically.

I right now a lot of this is in the Windows Form so I need to refactor it into a proper class.  I'm also using a System.ComponentModel.BackgroundWorker thread.  These little puppies are utterly amazing.  So amazing I'm going to tell a few of my friends about them.  A few projects I did over at SpringCM should have used these in hind sight instead of crazy amounts of threading and invoking.  PLUS it reports progress!  So fracking cool.

I'm using a SparkFun IMU unit for my gyro data.

The sad thing is I'll be awake if someone wanted to drag me to black friday deals.  I don't think that is a good idea after how worked up I got last year.  Plus I'm not willing to brave subfreezing temps for 5 dollar DVDs and deals on stuff I already own.

I just added in my blog roll call for everyone who was on my old blog and added in a few more.  This layout has a few issues that are personally annoying me.  The search isn't rendering in IE properly and alter the rendering on the left nav I haven't totally figured out for some of the items.

I still need to do the footer also.  I wonder if I bring my laptop to my aunt's house if I'll get in trouble.  That gryo code isn't going to write itself and is SO cool.  Damn you fun projects!

image

This is almost a mirror of the SparkFun UI.  I'm going to mimic their logic for the most part then roll it into my Gyro.cs class.

I got a HP MediaSmart Server that runs Windows Home Server and it finally shipped.  So you're asking yourself three things right now.

  1. Why did Clint buy the WHS Server instead of building it?
  2. Why does Clint even need a WHS in the first place?
  3. What are you going to add to it?

So to answer the why didn't I build one?  I actually almost did.  However the HP server is a 100% done, known working package and competitively priced.  I got the 500gb version of the server and grabbed an additional 500gb HD off Amazon and another gig of ram too.  The HP also has a nice feature, hot swappable drives.  I love the idea of zero downtime.

SO now the next question is why do I need a home server in the first place?  Well, it actually is a nice thing to own.  WHS is based on Windows 2003 Server which provides a nice bit of security in my mind.  It also monitors your PC's health along with warns you of impending failures on itself too.  With a bunch of my stuff, you better believe I want to keep it around for as long as humanly possible.  I like the idea of my computer getting backed up every how many hours and if something bad does happen, I can just roll it back and BAM, I'm back up.  Since my data isn't on the computer that just died, getting it recovered is easy.  I also have a central drop for all my music, pictures, and videos.  Another nice thing is it acts as a gateway to my apartment.  No longer do I need an open port on my router for remote desktop along with a computer that has a client, I can just use Internet Explorer and the web interface.  The rest of the question is answered in the next answer.

SO what am I going to add to it?  This is what I'm thinking about

  1. An SVN Server (want to create a syncing plug-in)
  2. Possible Sharepoint
  3. Photosync plug-in
  4. Maybe my bartending software.

One thing I'd personally like to do is, until the Xbox 360 can natively play xvid and divx files, create an plugin that will automatically transcode stuff.  I'm thinking ffmpeg.

bb964613_VS_prodinfo_bg I've been graced with the ability to install Visual Studio 2008 Team Suite on my laptop and I was honestly surprised how quickly I got a full install on both Visual Studio and MSDN up and running.  Both installed in under 1.5 hours.  Having the files on my desktop may have sped it up slightly but I was pretty impressed.

I just need to install ReSharper and I'm set.

I got a webcam for doing conferencing at work and wanted to do some development with it.  I had the problem of the sample source code I would try out didn't work or worked poorly.

I found Mark Schmidt's awesome vista gadget using a webcam and asked for the source.  Mark cleaned it up and graciously posted it for everyone to check out.  His example uses DirectShow to interface with the camera instead of WIA.

Now I just need remember what I was going to use this for, but that is a different problem.

So I got a JVC  Everio camera and I can honest say video editing software sucks.  JVC has a version of PowerDirector and it can't do what I need.  Windows Movie Player can't either.  I can cheat and use my MacBook Pro and use iMovie.  I found a nice little program called SDCopy that transforms the crappy .MOD format to Mpeg2 which is handles the proprietary format of the JVC camera.  BUT iMovie can't handle mpeg2 without a $20 encoder/decoder for QuickTime..  Which then means I would have to transcode the mpeg2 to divx (or something else).

The JVC software is horrid.  I mean, like, someone please shoot me.

Windows Movie maker ALMOST does it but lacks the ability to speed up and slow down tracks.  This is why  I can't use it.  iMovie does have this ability.  Update:  Windows Movie Maker can do this but it is very restrictive.  Slow up 2x or slow down 2x.  This is in the Effects section.

HOWEVER, I did find out iMovie HD 6.0.3 is having issues importing a larger divx file.  Come on, it is only 320 MB.  How the hell is this seriously suppose to edit people's home movies if it can't import a 30 minute long video?  Why don't I upgrade to iLife '08?  Cause I don't want to spend the money.

On the upside, I do know I finally found something that can max out my quad-core computer.  It is called movie editing.

image

livewriter02[1] I recently joined Flickr and I've been using Live Writer for doing blog entries for a decent amount of time.  I have to say I really like Live Writer since I just need to type and it takes a lot of the grunt work out of formatting, uploading images, tags, valid XHTML .... 

Tim Heuer created a really sweet flickr plugin for Live Writer but it has a major flaw in my opinion.  It gets the pictures from oldest to newest.

Now if you have 100 pictures in one set, as I do, this starts to become annoying quick.  But fear not, Tim has made Flickr4Writer open source on CodePlex!  I'm going to mod it and add in that additional functionality.  Now sure how you are allowed to put source back into Codeplex though.

May check out how the Tags works since it wasn't playing very nicely for me last night after I uploaded some new photos too.  That could have been a propagation issue on Flickr's end however.

Close up of the relay board with some braided wire.

IMG_3927

I had to steal the cord from my AVR programmer

IMG_3926

So much yellow tubing.  DAMN YOU FOR BEING CHEAP (only $33, but only way I could get colored tubing too)!

IMG_3925

Close up of the finished wiring.

IMG_3924

The wire rack with valves and wiring fully assembled.  Tubing is all that is left.

IMG_3923

Now striking a pose on my macbook pro

IMG_3922

Yet another close up

IMG_3928

This is an older shot where I did wiring before completing the code for the relay board, so I had to undo all my hard work.

IMG_3918

Surprising amount of wiring

IMG_3921

Premarked the container to open it up with a dremmel.

IMG_3920

Using my laptop as a counter balance so the relay board doesn't slide off.

IMG_3919

I'm in the process of editing the first webcast for the drunktender (automated bartender) and after viewing 58 files, of which at least 45 are screw ups, each ending with a colorful version of the f-bomb.  I should do a short episode of me just swearing.  It may actually be longer than 15 minutes too.

Every programmer I know seemed to swear more than me ... this is kind of scary.  I wonder if I do little kid approach and say fudge that people will still respect me.  BUT that requires first, that they respect me.  That is a totally different issue than me swearing. 

Using fudge instead is actually semi comical though.  I found myself chuckling a few times.

th_cartman_retard[1] So I started working on the relay code again just now (Halo 3 / Guitar Hero / Bears had to be watched / played) and I literally have no clue why the code is doing what it is doing.

Could be partly I'm not really in a mood to code but seriously ... I should be wearing the dumbass helmet like Cartman because memories of me in English class and not understanding any of the basic concepts like nouns and adverbs are flashing back and scaring me.

I think I finally learned my lesson to comment my code.  It only took, you know, 1 day shy of 26 years.  I think my new rule should be, I'll comment my code to the point where on my "I'm mentally deficient" I'll still know what is going on.

Update:

I figured out pretty quick what confused me.  Right now the code is heavily incomplete and one variable who's name made me think it is a bit more important than it really was ... I think.

A design dock would be amazing right about now.  Or just retreating to Halo 3 ... I think Halo might win out.

QueueExperiment2[1]

So for the relay boards, there is a max amount of commands I can send to the master board.  So how does one respect the entire command but allow for additional commands to be sent without their order being respected?

Create a double queue, the worst type of queue.  The first queue will break apart the command into usable chunks while the second queue will contain these multiple queues.

FYI, I'm being sarcastic about a double queue being the worst type of queue.  I can easily think of 20 other queues that could be worst, like the DMV, security line at the airport, being on support with Comcast or Charter cable ...

I've mounted the container tops along with tinned a few of the ends of the braided wire.

tinning

IMG_3914

the process of tinning

IMG_3913

My apartment the next morning

IMG_3915

the assembly mounted for a test fitting

IMG_3911

testing how to mount

IMG_3907

I can mount 4 boxes with ease

IMG_3908

Just applied the glue.

IMG_3910

Another angle

IMG_3909

The thumbscrews glued.  Next time I'll drill the box and use rubber washers.

IMG_3906

Glue set

IMG_3917

glued

IMG_3916

You're going to get nailed no matter what you do when porting data to a new system.  I got nailed with how I linked to images in my old posts.

<img src="images/blargh.jpg" /> is a virtual path.  So if I have html page at http://betterthaneveryone.com/default.aspx, the image's path is different than if it was betterthaneveryone.com/sub1/default.aspx.  In the 2nd link, the path for the image would be sub1/images/blargh.jpg when the image is actually housed at /images/blargh.jpg.

With all that blargh explained, here is my mini app.  I used the SQL class from my drunktender project.  I used SqlParameters for the updating too.  I highly suggest using them whenever possible.  Could have refactored the code slightly more but not bad for 1 pass.  This took all of 10 minutes to write.  I think the UI took longer than the code to be honest.  Notice the checkbox I added for verifying I want to process the live data.  I didn't want a mishap.

I was going to try PowerShell for this but decided I shouldn't screw up my production database goofing off with new tech I haven't played with.

image

private DataSet dsTempObjects;
private int index = 0;

private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
    btnProcess.Enabled = (checkBox1.CheckState == CheckState.Checked);
}

private SQL getSqlObject()
{
    return new SQL(txtIP.Text, txtDatabase.Text, txtUser.Text, txtPassword.Text);
}

private void btnGetTestData_Click(object sender, EventArgs e)
{
    using (SQL sql = getSqlObject())
    {
        dsTempObjects = sql.ExecuteDataSetByQuery("select * from subtext_content where [text] like '%<img src=\"images/%'");
        index = 0;
        btnCheckNext.Enabled = true;
        btnCheckNext_Click(sender, e);
    }
}

private static string replaceBadText(string input)
{
    return Regex.Replace(input, "src=\"images", "src=\"/images");
}

private void populateInputOutput()
{
    if( dsTempObjects.Tables[0].Rows.Count > index )
    {
        string input = dsTempObjects.Tables[0].Rows[index]["text"].ToString();
        string output = replaceBadText(input);

        txtInputData.Text = input;
        txtOutputData.Text = output;
    }
    index++;
}

private void btnCheckNext_Click(object sender, EventArgs e)
{
    populateInputOutput();
}

private void btnProcess_Click(object sender, EventArgs e)
{
    using (SQL sql = getSqlObject())
    {
        dsTempObjects = sql.ExecuteDataSetByQuery("select * from subtext_content where [text] like '%<img src=\"images/%'");

        foreach (DataRow dr in dsTempObjects.Tables[0].Rows)
        {
            string newText = replaceBadText(dr["text"].ToString());
            string id = dr["ID"].ToString();

            sql.ExecuteNonQueryByQuery(
                "update subtext_content set [Text] = @newText where id = @Id",
                new SqlParameter("@newText", newText),
                new SqlParameter("@Id", id));
        }
    }

    MessageBox.Show("done");
}

So I'm writing my updater app to fix the image problem I outlined and saw I actually have a problem with the SQL I wrote anyways.  The replace error on an Ntext datatype would still happen, but even if that error wouldn't happen, another problem would have happened.

The problem of nothing actually happening.  I was replacing the same string with itself.  I needed the /image/ to reset the image tag back to the domain root.

The code SHOULD be:

begin tran
Update     subtext_Content
    Set    [text] = replace([text], '<img src="images/', '<img src="/images/')

select * from subtext_Content where [text] like '%<img src="images/%'

I finally got my ass in gear and started doing stuff.  Actually I've been getting a video podcast in the works for this project.  Here I'm mounting the screws the the plastic container I got to protect the relay electronics from harm.

The ironic thing was after I glued the screws, I wondered why I didn't just drill the container and used some rubber washers to create the seal.  Why must hindsight be such a bragging SOB.

If the glue doesn't actually hold, I'll go that route.

IMG_3902

IMG_3906

IMG_3904

I finally joined and decided that is where my pictures shall now be.

Drunktender / Automated Bartender Pictures

IMG_2663

Disco dance floor pictures

IMG_1245

Maker Faire pictures

IMG_2815

I just ordered the last few parts I need for for the bartender, I got some threaded 1/4" quick disconnects for my new valves and two types of polyethylene tubing.  Clear and solid yellow color tubing.  The last major thing I think I should purchase is a larger diameter heat to help protect the wiring and electronics.  I should order that tonight too so I can finish up this project before Thanksgiving.

The other big thing right now I should try out is if I can fire the 24v valves with a 12v current.  If so, a computer PSU will be my best friend.

My manager, Martin Schray, created a nice little installer for the Delayed Startup Application and posted an online video on how to do it.  Using Visual Studio 2005, this is remarkable easy.  I remember having to use installshield and gouge my eyes out while repeatedly slamming my head against a wall since it would just decide it would no longer compile when nothing changed.


Video: Delayed Startup Setup Project

 

Update:  Here is the installer

key3_l[1] Today I had my first major trouble with my car and it really wasn't its fault.  I got into my Acura TSX and tried to turn the key and couldn't.  I tried again, still nothing.  * insert swearing and colorful language*  Finally I give up and call Acura's road side assistance and the nice woman tells me to jerk my wheel.  I'm puzzled by this since it seems, to be honest, like a stupid and pointless thing.  Sure enough, I jerk it (hehe), and the key turned again.  Turning the key took way more effort than normal but it worked.  And turning it on and off again a few times verified that it wasn't going to lock up again.

Now for some new reader, I haven't owned a car for over 8 years.  I drove only when I was at my parent's house or needed to borrow a car which was extremely rare due to living in Chicago.  Moving to St. Louis and getting my job at Microsoft required me to start burning fossil fuels so I finally ponied up and got a car.  While I like my car, I'd go back to riding the El and Taxis in a second, it saved so much money and was rather effective at getting around with time to read.

I consulted a few of my friends after I failed to do my needed update for backwards image support due to the change in URL structure and found out I couldn't do what I wanted.

Here was the SQL I was planning on running:

begin tran
Update     subtext_Content
    Set    [text] = replace([text], '<img src="images/', '<img src="images/')

select * from subtext_Content where [text] like '%<img src="images/%'

As you can see, pretty straight forward, however it wouldn't work since the column data type for Text was an nText.  I used a transaction just incase I wanted to roll back.

My solution to this will be creating a small c# application that will loop through all the rows and then updates the rows.

Ok, looks like I need to fix all image links since their URLs are virtual and incorrect.  On the plus side, this can be done via SQL I think.
  • Add in the 3 perm pages from WordPress.
  • Fix an IE issue with the sub tagline
  • Get a new FavIcon
  • Add in some flickr support for images.  This way I can have some awesome galleries posted with ease.
    • Post a lot more images
  • Post movies
    • I could actually post a movie about doing this conversion if people want it.
  • A friend, Scott Parker, mentioned there may be a few patches I may want to pop on too.
  • Add in a proper footer with a disclaimer.  Gotta do the CYA.

banner_squarepeg[1] Ok, so this was a rather long, drawn out, painful process.  I actually blew one entire weekend getting this working. SubText itself is good, Wordpress too. Converting one’s data to the other kind of sucked. Nah, it really sucked.  I think I started this about a month ago but I'd give myself over 2 days of time getting this to work correctly.

So I managed to get the conversion to work and I bet I pissed off a few of my friends while I was at it due to trackbacks. So here is my disjointed story on doing it.

Here is a little background on the two blog services. Wordpress is a well known, PHP / MySQL based blog engine. SubText is a c# / ASP.Net / SQL Server based blog engine. This is literally a square peg in a round hole to do the conversion.

A few of Clint's rules:

Rule 13492:  Never destroy what you have until you get everything working 100%
Rule 29695:  Don't leave until everything old works on what is new
Rule 91683:  Be sure the new system works before destroying the old system.

Even right now, I actually still have the instance of Wordpress running in the background JUST IN CASE.  This move has lots of moving parts and I actually had it fail on me after I did 2 successful runs on my testing domain.  Scary, no?

The Data Conversion
BlogML got me about 90% of the way there but as I outlined, I ran into a little formatting problem.  Wordpress does post processing on the text and doesn't keep all the HTML in the database per post.  DasBlog and SubText doesn't like this idea.  So I had to reverse engineer how Wordpress does this.  Reading PHP to me is a bit of a pain in the ass since I lack a proper IDE and in my opinion, it seemed crazy with what they were doing.  I like to think PHP is to Perl.  Only the person who wrote it can read it.

I modified BlogML’s Wordpress export PHP script and added in wpautop function to the output to get my posts to format correctly. This took a bit to track down but it worked. There were more issues I’ll outline later on.  Getting the BlogML data into SubText is easy.  You just say "Create a new blog" after you "installed" the files and then there is an option to import data.  This is different than how you'd do it with DasBlog.  It confused me since I tried DasBlog first so I figured I'd mention it.

Keeping with backwards compatibility
All my links have ?p or ?page_id that enter me. This means I have to support it. It my last post, I outlined how to do this. What I forgot to add in and remembered due to Scott Hanselman’s bits of advice was to remember my RSS feed. With a quickie HttpHeader add in due to adding in the ?p support, this instantly solved the RSS feed problem.  This has been verified by checking out my reader.google.com threads.

Here is the line from the web.config for the RSS feed and keeping the old crappy perm link support:

<HttpHandler pattern="(?:default\.aspx\?feed=rss2)$" type="Subtext.Framework.Syndication.RssHandler, Subtext.Framework" handlerType="Direct"/>
<HttpHandler pattern="(?:default\.aspx\?(p|page_id)=\d+)$" controls="viewpost.ascx,Comments.ascx,PostComment.ascx"/>

So running the straight up BlogML importer for me wasn’t going to work due to how SubText imports data. It does a straight up insert instead of keeping the IDs synced up. I didn’t want to destroy the ability to really update my blog’s software later on down the line so I minimized the zones of impact. Anywhere I’d have to modify for the BlogML importer, I created a new mirrored function.  This protects me from breaking everything else.  Neat, huh?  Best of all, it is 1 time use code more or less.  If people want this code, I can post it.  After running the importer, I also had to run one additional script.

update subtext_content
    set author = 'Clint', email='clint@rutkas.com'

Now the code to do the importing, the SQL below included, can be thrown away.  The code for the query string must be added back after each upgrade.  By having my blog, I've documented what I've done so this isn't the end of the world.

Here is the stored procedure:  (the big thing is the SET IDENTITY_INSERT [subtext_Content] ON line to be able to get the ID's to be non-auto-incremental)

USE [better_subtext]
GO
/****** Object:  StoredProcedure [dbo].[subtext_InsertEntry2]    Script Date: 11/04/2007 17:47:31 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER OFF
GO
CREATE PROC [dbo].[subtext_InsertEntry2]
(
    @Title nvarchar(255)
    , @Text ntext = NULL
    , @PostType int
    , @Author nvarchar(50) = NULL
    , @Email nvarchar(50) = NULL
    , @Description nvarchar(500) = NULL
    , @BlogId int
    , @DateAdded datetime
    , @PostConfig int
    , @EntryName nvarchar(150) = NULL
    , @DateSyndicated DateTime = NULL
    , @ID int output
)
AS

IF(LEN(RTRIM(LTRIM(@EntryName))) = 0)
    SET @EntryName = NULL

IF(@EntryName IS NOT NULL)
BEGIN
    IF EXISTS(SELECT EntryName FROM [dbo].[subtext_Content] WHERE BlogId = @BlogId AND EntryName = @EntryName)
    BEGIN
        RAISERROR('The EntryName of your entry is already in use with in this Blog. Please pick a unique EntryName.', 11, 1) 
        RETURN 1
    END
END
IF(LTRIM(RTRIM(@Description)) = '')
SET @Description = NULL
SET IDENTITY_INSERT [subtext_Content] ON
INSERT INTO subtext_Content 
(
    Title
    , [Text]
    , PostType
    , Author
    , Email
    , DateAdded
    , DateUpdated
    , [Description]
    , PostConfig
    , FeedbackCount
    , BlogId
    , EntryName 
    , DateSyndicated
    , Id
)
VALUES 
(
    @Title
    , @Text
    , @PostType
    , @Author
    , @Email
    , @DateAdded
    , @DateAdded
    , @Description
    , @PostConfig
    , 0 
    , @BlogId
    , @EntryName
    , @DateSyndicated
    , @ID
)
--SELECT @ID = SCOPE_IDENTITY()

EXEC [dbo].[subtext_UpdateConfigUpdateTime] @BlogId, @DateAdded
EXEC [dbo].[subtext_UpdateBlogStats] @BlogId

enso[1]Well, I got hacked in support in the Cacher.cs, UrlReWriteHandlerFactory, and adding in a httphandler.

It took a bit of tracking down but due to you mentioning the UrlRewrite Engine, I figured out it only matches the path, not the RawUrl.  Added in || handler.IsMatch(context.Request.RawUrl to the if statement.  Line 77 in the UrlReWriteHandlerFactory.cs in the GetHandler method

The Cacher was GetEntryFromRequest(CacheDuration cacheDuration, bool allowRedirectToEntryName) method and checking if there was a query string and if it was p or page_id then check if it was numeric.  If so then move on with how the function worked.

The regex for the httphandler in the webconfig was (?:default\.aspx\?(p|page_id)=\d+)$

...

SO how did I actually figure out how to do this?  Besides being awesome and semi-bored on a Friday night after work, I did what every good developer does, debug.  Yes, this isn't the first web project I've worked on.  Yes, I did this professionally for a bit.  Yes, I work for Microsoft.  And yes, you too can do what I just did.  It really isn't that hard if you read and have a little help.

The SubText project is a decently sized and coming in fresh is like putting a teenager in the playboy mansion and telling him to make his move and expect him to actually be successful at the end of the night.

I posted a question on the Subtext forum and got a bit of guidance on my question.  Steve Harman gave me a rough idea on where to look and I had figured out one area to look too.  From there I started to debug.

I actually never used a HttpHandler before but looking at the webconfig, I knew that was an area I had to start poking around in.  I found in the UrlReWriteHandlerFactory that it had all the handlers with the nice Regex pattern I knew I needed to match.  Since I had the code working in the Cacher but couldn't get it to work with http://test/?p=40 but it worked with something like http://test/page/40/40/03?p=40.  SO this told me a few things.

SubText wasn't respecting a full URL, just the Path.  So I started to add break points where I thought code may start firing off.  I knew I had to start looking at HttpHandlers so that is where I started looking.  In the UrlWriteHandlerFactory I found what I was looking for.  I added in the extra check for the RawUrl on top of the Path.

Simple as pie, right?  Next time I'll record me debugging and doing a diagnostic diagnosis to figure out what is wrong.  It will be like an episode of House just with more swearing and showing off exactly how wrong I normally am and how blogging my success magically erases all my mistakes.

Bartender:

  • Order polyethylene tubing
  • Order plastic nuts and screws (Use these to mount the relays to the box)
  • Order some quick fits that are threaded on one end
  • Create the relay c# file
  • Fix a few small UI bugs

Skateboard Segway:

  • Create c# application for the gyro
  • Order speed controller
  • Order wheels
  • Figure out Dead-man switch
  • Figure out Compact Framework
  • Actually, you know, create the device
  • Add in a Kalman filter to reduce noise in the gyro
  • Hurt self using device (Promptly ordering safety gear afterwards)

Blog Conversion:

  • Figure out how SubText handles article ID's
  • Alter SubText code to support legacy links into Better than everyone. (this means ?p= and ?page_id= for my articles and pages.)
  • Get the BlogML Wordpress Exporter to include Wordpress formatting.

Building a Windows Home Server:

  • Order the barebones system from Asus.
  • Order processor, low end, low power processor
  • Order RAM
  • Order some massive hard drives
  • Build, rinse and repeat for parents

Long Term for Bartender:

  • Create Kits
  • Add more drinks
  • Create better admin tools