May 2005 Entries

Not what I know now, but what I'm learning now. I recently picked up a copy of the src to FlexWikiPad. I just wanted to see how things were wired together in there: I only have a very old installation of FlexWiki sitting around that still looks like crap in FireFox.

To his credit, Craig has done an awesome job of making FlexWikiPad very testable - something I didn't think was all that easy to do in winforms. Apparently, his dialogs are very humble. He's using a pretty strict Model View Presenter (or controller, whatever) pattern throughout the application. I thought this was a lot of extra coding at first (it kinda is), but in the process Craig has made FlexWikiPad easier to maintain and update thru the use of mocks/stubs and tests with this pattern.

Currently, I've got this itch that I want to scratch with regards to PostXING that would have been so nice to be able to test my way thru. I'm just hacking thru it now, and I've done a pretty good job of messing everything up so far :) In my defense, I'm still learning unit testing and when it comes to winform applications I feel that there is a balance that I like to hit right on the line of usability and architectural beauty. Anyone who has looked at PostXING's source will soon see that my architectin' ain't so purty - it's still just a lot of different pieces from different places glued together. I don't validate everything that I should. I left fields that I intended to add functionality for disabled but visible. Even up to 1.1 versions. BUT...

...and this is a big but...

...it works. That was priority #2 for me with PostXING. Priority #1 was to make something useful that I could use to learn winforms.

Anyways, I'm hoping that I can glean some insight off of people like Craig that are way more knowledgable than me on this front. If I feel like the task for PostXING to be testable is too great, I may just try to apply this knowledge to future projects. So, thanks Craig for making FlexWikiPad follow a concise pattern that I did know about but have never seen implemented with tests in C# before.

posted @ Friday, May 27, 2005 11:07 PM | Feedback (0) | Filed Under [ PostXING ]
Do you ever get an email that has some base64 gobbledegook in it? A lot of times, based on MIME information directly preceding this junk, it's actually an image that got converted to text but never converted back to an image (duh, right? Tell me something I don't know? Okay...)

I got one of these earlier and decided to write a little utility to convert that string back into an image using the .net framework. It was pretty simple once I got the namespaces right:

using System;
using System.Drawing;
using System.IO;
using System.Collections;

public class MyClass
{
	public static void Main()
	{
		string base64 = @"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";

		Bitmap map;
		
		using(MemoryStream stream = new MemoryStream(Convert.FromBase64String(base64)))
		using(FileStream fs = File.Create(@"C:\tmp\img.gif")){
		
			map = (Bitmap)Image.FromStream(stream);
				
			map.Save(fs, System.Drawing.Imaging.ImageFormat.Gif);
		}
		
		WL("Converted Image Successfully!");
	}
	
	private static void WL(string text, params object[] args)
	{
		Console.WriteLine(text, args);	
	}
	
	private static void RL()
	{
		Console.ReadLine();	
	}
	
	private static void Break() 
	{
		System.Diagnostics.Debugger.Break();
	}
}

Slap that little snippet into Snippet Compiler and look at what is generated. I actually changed the image to something a little bit friendlier than the image I recieved in the email. Enjoy!
posted @ Friday, May 27, 2005 8:49 PM | Feedback (1) | Filed Under [ .NET ]

It seems that there was a major power failure yesterday: at least a few city blocks. For those that don't know, a city block in Houston is a pretty big area.

Looks like it's fixed for now, so the two of you can go about getting that there rss feed :)

[ Currently Playing : Karma Police - Radiohead - OK Computer (4:21) ]

I.e. Both of you...I've changed the repository structure of PostXING on vaultpub to better facilitate branching.

These crazy new ideas I've been having are so different from the current architecture of PostXING that I have to branch it just in case someone comes to me with a nasty bug they found that I just overlooked (this has happened a few times already, although not for a while). I don't like having broken software with my name on it out in the wild.

Anyways, I thought I would keep tabs on my progress for this on my blog. I feel like there is something that I'm missing in the ideas that I'm having, so I'm taking this slowly, step by step. To be honest, I've always had this idea in my head for PostXING. It's why it's built the way it is - I've left extensibility points open at the expense of writing a bit more code on the onset. When I'm done, a developer that has a good handle on the API they want to post to will be able to author a plugin/provider, drop it into a subdirectory off of the application root, and be able to use PostXING as kind of a shell to post to their custom API.

[ Currently Playing : Sad Statue - System of a Down - Mezmerize (3:25) ]

Thanks to Sir Wally for the first one...it's simple really, Wally just asked if I would cache a list of the categories for each configured blog to aid with offline posting. I pretty much always use PostXING while online, so this particular feature didn't even cross my mind. As a side effect, this will let me add categories to posts off of my CS blog which gives a nice little error when I try to get the comments list currently. Good one, Wally.

The other thing is that I want to expand the abilities of where PostXING can post - not just using the Metablog API, but being able to use different services. I don't want to use the "provider model" because I don't think that particular pattern fits what I have in my head to make this work. Close, as a matter of fact, very close, but not exactly what I'm looking for.

The basic idea that I have now is based on the fact that a lot of the functionality that PostXING uses now already sits in separate dll's in the application root. I think that I can factor out the API specific functionality into kind of a plugin - thereby expanding the end applications that can be posted to from PostXING. I haven't hashed out all of the details yet. This is still a brainstorm at this point. However it works out, it's going to be a major version change.

If this can work out the way I think it can, this could be a very cool addition to PostXING. Very cool indeed.

I've been doing just that on my blogs - way back to when this one was hosted on dotnetweblogs.com.

Geez, I was such a dork...okay, maybe I'm still a dork. But that's a maybe. I admit nothing.

The Personal Website Starter Kit is a great resource for getting up and running with asp.net 2.0 beta. I've been using it to check out some features while waiting for other projects to get to a point where I feel like I can contribute more than just criticism (sorry y'all :) That said, the default.aspx page comes with a FormsView that rotates pictures from your PSKit albums, but everything else is static content! That is, you're greeted on the front page with something like:

Welcome to my Website!

On this site you will find lorem ipsum dolor sit amet...

Earlier, I had tried using one of the new data controls in asp.net - namely the FormView. I ran into a few issues with this control, mostly having to do with having to know what ID I was using in the database to set or edit the FormView's contents - I'm sure I could have worked out a way to set the ID to use in some clever way, but then I looked at the actual content that comes stock with the PSKit and it hit me...

A DataList.

It's already separated by a horizontal rule - all I really need is to bind a good old DataList to a couple of database entries and I've got something that I can update, oh, say twice a year or whatever. heh.

I used a similar table structure to the one from before:

Content
ContentID
Heading
Content
IsVisible

I had to actually write code (gasp!) to get it working the way I wanted it to, but it was pretty stock stuff thankfully. I just set up a SqlDataSource pointing to this table's CRUD procedures:

                <asp:SqlDataSource ID="SqlDataSource1" 
runat="server"
ConnectionString="<%$ ConnectionStrings:Personal %>"
ProviderName="System.Data.SqlClient" SelectCommand="GetContents"
SelectCommandType="StoredProcedure"
DeleteCommand="RemoveContent"
DeleteCommandType="StoredProcedure"
InsertCommand="AddContent"
InsertCommandType="StoredProcedure"
UpdateCommand="EditContent"
UpdateCommandType="StoredProcedure"> <DeleteParameters> <asp:Parameter Name="Content_ID" Type="Int32" /> </DeleteParameters> <UpdateParameters> <asp:Parameter Name="Content_ID" Type="Int32" /> <asp:Parameter Name="Heading" Type="String" /> <asp:Parameter Name="Content" Type="String" /> <asp:Parameter Name="IsVisible" Type="Boolean" /> </UpdateParameters> <InsertParameters> <asp:Parameter Direction="InputOutput" Name="Content_ID" Type="Int32" /> <asp:Parameter Name="Heading" Type="String" /> <asp:Parameter Name="Content" Type="String" /> <asp:Parameter Name="IsVisible" Type="Boolean" /> </InsertParameters> </asp:SqlDataSource>


Then the DataList itself:

			<asp:DataList ID="DataList1" 
runat="server"
DataSourceID="SqlDataSource1"
Width="100%"
OnCancelCommand="DataList1_CancelCommand"
OnEditCommand="DataList1_EditCommand"
OnUpdateCommand="DataList1_UpdateCommand"
OnDeleteCommand="DataList1_DeleteCommand"
OnItemCommand="DataList1_ItemCommand"
RepeatLayout="Flow" > <ItemTemplate> <asp:Panel ID="contentPanel"
runat="server"
Visible='<%# Eval("IsVisible") %>'> <h3><asp:Label ID="HeadingLabel"
runat="server"
Text='<%# Eval("Heading") %>'></asp:Label></h3> <asp:Label ID="ContentLabel"
runat="server"
Text='<%# Eval("Content") %>'></asp:Label>
<asp:HiddenField ID="hdnContentID"
runat="server"
Value='<%# Eval("Content_ID") %>' /> </asp:Panel> <asp:Panel ID="Panel1"
Visible='<%# User.IsInRole("Administrators") %>'
runat=
"server" Height="50px" Width="125px"> <asp:LinkButton ID="LinkButton3"
runat="server"
CommandName="edit">Edit</asp:LinkButton>&nbsp;&nbsp;
<asp:LinkButton ID="LinkButton4"
runat="server"
CommandName="delete">Delete</asp:LinkButton></asp:Panel> </ItemTemplate> <SeparatorTemplate> <hr /> </SeparatorTemplate> <EditItemTemplate> <asp:TextBox ID="txtHeading"
runat="server"
Text='<%# Bind("Heading") %>'></asp:TextBox> <asp:CheckBox ID="chkVisible"
runat="server"
Checked='<%# Bind("IsVisible") %>'
Text=
"Visible" />
ContentID:
<asp:Label ID="lblContentID"
runat="server"
Text='<%# Eval("Content_ID") %>'></asp:Label> <asp:TextBox ID="txtContent"
runat="server"
Columns="40" Rows="20"
Text='<%# Bind("Content") %>' TextMode="MultiLine"></asp:TextBox>
<br /> <br /> <asp:LinkButton ID="LinkButton1"
runat="server"
CommandName="update">Update</asp:LinkButton>&nbsp;&nbsp; <asp:LinkButton ID="LinkButton2"
runat="server"
CausesValidation="False"
CommandName="cancel">Cancel</asp:LinkButton>&nbsp;&nbsp; <asp:LinkButton ID="LinkButton5"
runat="server"
CommandName="add">Create as New</asp:LinkButton> </EditItemTemplate> </asp:DataList>

Several points of interest in the DataList declaration:

  • No more pesky DataBinder.Eval(Container.DataItem, "field") syntax - much leaner and meaner Eval() syntax for one-way binding.
  • Two-way binding happens via the Bind() syntax - notice that Bind() only happens in the EditItemTemplate, since the ItemTemplate is readonly.
  • I'm only showing the edit/delete buttons based on what role the current user is in. I wasn't sure if this (# User.IsInRole("Administrators")) would work at first because it's deceptively simple. But yeah, it does work. Works great!
  • I did most of this visually - there is no longer a reason to fear the designer in asp.net (thanks Venus team!)
  • I had to disable Page input validation because I want the Content to contain html, and by default, it don't like that.

As for the codebehind, I guess I could have refactored it a little bit, but since this is not a mission-critical application (it is just a personal site, after all!) I just went the easy route and duplicated a lot of code. Probably the best thing to do would be to handle just the ItemCommand because there is no default handler for add and use a clever mix of a switch statement and defaulting the value of EditItemIndex to -1. But this isn't about best practices, it's about getting the stuff to work, ya know? Anyway, here's the code:

  1 	protected void DataList1_CancelCommand(object source, DataListCommandEventArgs e)
  2 	{
  3 		this.DataList1.EditItemIndex = -1;
  4 		this.DataList1.DataBind();
  5 	}
  6 	protected void DataList1_UpdateCommand(object source, DataListCommandEventArgs e)
  7 	{
  8 		string heading = ((TextBox)e.Item.FindControl("txtHeading")).Text;
  9 		string content = ((TextBox)e.Item.FindControl("txtContent")).Text;
 10 		string isvisible = ((CheckBox)e.Item.FindControl("chkVisible")).Checked.ToString();
 11 		string id = ((Label)e.Item.FindControl("lblContentID")).Text;
 12 
 13 		this.SqlDataSource1.UpdateParameters["Content_ID"].DefaultValue = id;
 14 		this.SqlDataSource1.UpdateParameters["Heading"].DefaultValue = heading;
 15 		this.SqlDataSource1.UpdateParameters["Content"].DefaultValue = content;
 16 		this.SqlDataSource1.UpdateParameters["IsVisible"].DefaultValue = isvisible;
 17 
 18 		this.SqlDataSource1.Update();
 19 
 20 		this.DataList1.EditItemIndex = -1;
 21 		this.DataList1.DataBind();
 22 	}
 23 	protected void DataList1_DeleteCommand(object source, DataListCommandEventArgs e)
 24 	{
 25 		string id = ((HiddenField)e.Item.FindControl("hdnContentID")).Value;
 26 		this.SqlDataSource1.DeleteParameters["Content_ID"].DefaultValue = id;
 27 
 28 		this.SqlDataSource1.Delete();
 29 
 30 		this.DataList1.EditItemIndex = -1;
 31 		this.DataList1.DataBind();
 32 	}
 33 	protected void DataList1_ItemCommand(object source, DataListCommandEventArgs e)
 34 	{
 35 		switch (e.CommandName)
 36 		{
 37 			case "add":
 38 				string heading = ((TextBox)e.Item.FindControl("txtHeading")).Text;
 39 				string content = ((TextBox)e.Item.FindControl("txtContent")).Text;
 40 				string isvisible = ((CheckBox)e.Item.FindControl("chkVisible")).Checked.ToString();
 41 
 42 				this.SqlDataSource1.InsertParameters["Heading"].DefaultValue = heading;
 43 				this.SqlDataSource1.InsertParameters["Content"].DefaultValue = content;
 44 				this.SqlDataSource1.InsertParameters["IsVisible"].DefaultValue = isvisible;
 45 
 46 				this.SqlDataSource1.Insert();
 47 
 48 				this.DataList1.EditItemIndex = -1;
 49 				this.DataList1.DataBind();
 50 				break;
 51 		}
 52 	}

This is the quickest way I could figure out to make things work, and yeah, it does work. So, there you have it - even though there are only two items currently in the table, it's very easy to add content via in-place editing and change what is currently there as well. You can view it live over at www.bluefenix.net.

[ Currently Playing : Voices - Godsmack - Other Side (3:44) ]

I use Azureus as my bittorrent client. It has this nifty feature that is similar to the Updater Application Block that will automatically check for and download updates on startup of the application. The only downside for me is that since I was running JRE 1.4, and after a little battle with my wireless router, I could contact trackers okay, but not peers.

Balls.

So I look around the program to see what I can see. Oh look! There's an irc client that is loaded as a plugin! I haven't been on an irc channel since like '98 or '99, but it can't have changed that much, right? /join, /msg, yeah, I think I'm good to go.

So I hop on the channel, fully expecting some random bs to be flying around like it used to be. How wrong I was. Myself along with about 4 or 5 others having issues with azureus got coached thru getting azureus running like a champ. In particular, two people helped me not only get az up and running correctly again, but also coached me on getting it set to its optimal settings for my cable internet link at home.

I'd like to thank martouf5 (no link given) and PhilKC for being such a big help with my n00b azureus hurdles. A couple of things that I learned thru this:

  • The channel has a very helpful, friendly tone - this was even true when I returned later to ask permission to use these guys' nicks on my blog, so it wasn't a fluke afaict.
  • You can test your connection speed on www.dslreports.com or www.testmy.net You gotta dig a little bit for the one on dslreports, but they both give you pretty much the same information.
  • Installing the JRE v1.5 does not uninstall previous versions. It's been a while since I've done any kind of Java development, but I wonder if this is because they have a SxS story like there is with the .NETfx? If so, there must be a way to tell a program which runtime to use...
  • There is a bot (AzBot) on the channel (irc.freenode.net, #azureus-users) that will tell you the optimal settings to use with azureus by typing a command like /msg AzBot upspeed 5008. I find that simply incredible. And incredibly useful.

I was told by martouf5 that the motto of bittorrent is "give and you shall receive" - he said that was pretty much the attitude of this particular channel, and they all volunteer and help out people as they can. Judging from the conversations that I saw briefly, they get pretty much the same questions over and over, so I guess that helps in its way. He also humbly claimed that he was not one of the channel's "heavyweights" - that there were others there that helped a lot more than he does - but he helped me darnit, so he gets the credit he deserves here. PhilKC is actually what martouf5 would call a "heavyweight" and they both helped me when I needed it...so thanks, y'all.

[ Currently Playing : Right Here, Right Now - Fatboy Slim - You've Come a Long Way, Baby (6:27) ]

Awesome. I had a feeling I was going to see something like this sooner or later.
posted @ Thursday, May 05, 2005 6:11 AM | Feedback (0) | Filed Under [ dotText ]