Please ignore some of the weird styles, doing a big HTML5 upgrade, and it's not quite done yet.

Daniel's Blog

The ramblings of a 22 year old guy.

C# Convert XML to an object or list of an object

Instead of doing my normal “write up an object and then parse the xml into it’s properties”, I decided to have a look at the XML deserialiser (well, deserializer in C# itself) – which has worked, and has saved me a lot of time.

Obviously you will need to create your object first, so here’s a person one:

[XmlRoot(ElementName = "person")] 
public class Person 
{
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
}

Note the XmlRoot attribute – you will need to set this to the XML node that contains your properties.

Next you will need an XML document, here’s my sample one:

	<people>
		<person>
			<FirstName>Daniel</FirstName>
			<LastName>Wylie</LastName>
		</person>
		<person>
			<FirstName>Jhon</FirstName>
			<LastName>Smith</LastName>
		</person>
			<person>
			<FirstName>Sam</FirstName>
			<LastName>Brown</LastName>
		</person>
	</people>

And of course, the XML Deserialiser class

using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace SampleApplication.Common 
{ 
    public class Convertors 
    { 
        /// <summary> 
        /// Converts a single XML tree to the type of T 
        /// </summary> 
        /// <typeparam name="T">Type to return</typeparam> 
        /// <param name="xml">XML string to convert</param> 
        /// <returns></returns> 
        public static T XmlToObject<T>(string xml) 
        { 
            using (var xmlStream = new StringReader(xml)) 
            { 
                var serializer = new XmlSerializer(typeof(T));
                return (T)serializer.Deserialize(XmlReader.Create(xmlStream)); 
            } 
        }

       /// <summary> 
       /// Converts the XML to a list of T
       /// </summary> 
       /// <typeparam name="T">Type to return</typeparam> 
       /// <param name="xml">XML string to convert</param> 
       /// <param name="nodePath">XML Node path to select <example>//People/Person</example></param> 
        /// <returns></returns> 
        public static List<T> XmlToObjectList<T>(string xml, string nodePath) 
        { 
            var xmlDocument = new XmlDocument(); 
            xmlDocument.LoadXml(xml);

            var returnItemsList = new List<T>();

            foreach (XmlNode xmlNode in xmlDocument.SelectNodes(nodePath)) 
            { 
                returnItemsList.Add(XmlToObject<T>(xmlNode.OuterXml)); 
            }

            return returnItemsList; 
        } 
    } 
}

Usage:

var List<Person> = Convertors.XmlToObjectList<Person>(PeopleXML (Load how you wish), "//People/Person");

Useful Windows 7 keyboard shortcuts

Right, I know I’m miles behind the times here – but I have just found a whole bunch of new Windows 7 keyboard shortcuts that mean I hardly have to pickup that thing we call a mouse.

My all time favourite ones are the Windows Key + Up Arrow and Windows Key + Down Arrow for maximizing and restoring windows, which is obviously very useful.

Of the new ones I have just found, my favourite is Windows Key + T which selects the first item on the taskbar for you. You then use the arrow keys to navigate your open windows, and hit enter to select the one you want. Of course, good old Alt-Tab will do the same, just in a slightly less eye candy based way.

windowst

The other one that caught my attention was the Windows + Shift + Left/Right Arrow which moves the whole window, maximized or not, between your monitors (assuming you have more than one, which you should).

Aero snaps is also something you should have a play with if you haven’t heard about it yet – take a restored window, and drag it to the top of your screen – it should now maximize. You can do the opposite to restore the window as well. This also comes in very useful when dragging full screen windows between monitors, so you no longer need to install any of those “display helpers” (Unless you want your taskbar on more than one monitor).

Microsoft have a list of useful Windows + Key shortcuts here:
http://www.microsoft.com/nz/digitallife/basics/windows-7-shortcut-keys.mspx

Awesome pictures of the Courtney Place exchange

Being someone who’s always been interested in networks/telecommunications, I  got rather excited when I saw @freitasm posting images from his tour of the Telecom exchange on Courtney Place.

All images and tweets (Shown here as titles) courteously of @freitasm from GeekZone. Thanks! Can’t wait to read your post on the tour later.

The cables coming into the Courtenay Exchange

68835101[1]

Some serious power

68836062[1]

And more power for the Exchange

68836317-bee4f7d98fa60ffcf153b2f8f8ee050a.4b849a6e-scaled[1]

I hope these generators don't start while we are here

68837123-196ca148f651d19a833c886c00e2a6d7.4b849ac7-scaled[1]

And some @telstraclearnz gear inside @telecomnz exchange (Tweet)

68838755-93383133a348375aa2582bfb44281d2a.4b849b03-scaled[1]

And the copper gets inside

68839798[1]

And here is the fibre coming in @telecomnz (multiple these for a few around here)

68841177[1]

An old copper cabinet from the 80s... Can see no space for unbundling, no ventilation in old design

68857844[1]

And these are the latest copper cabinets

68862272-16534b7a5b7fa60dc78b58a9389a1312.4b849ebb-scaled[1]

This cabinet allows unbundling and comes with power

 

68862794[1]

And this is the equipment inside the cabinet

68863416[1]

(For some reason Live Writer has moved the images to my server - to view the originals, see the tweets)

Simple C# BlogML Parser

I promised that I would be releasing some code from Kustom Page – And here it is, straight from the guts of Kustom Page!

This little class read in an XML document, formatted to the BlogML standard, and give you an object back. The library is very very simple. You will need to do validation etc yourself (And I highly recommend you do).

Sample Usage

var blogMLImport = BlogMLObject.Parse("BlogML.xml");

            var blogMLImport = BlogMLObject.Parse("BlogML.xml");

            foreach (var post in blogMLImport.Posts)
            {
                Console.WriteLine(string.Format("Post: {0} Written by: {1} on: {2}", post.Title, post.Authors.First().Title, post.DateCreated));
            }

Download Library (8 kb)

Blog "Re-Brand"

After well over a year of my dark, black theme, I decided it was time for something new. The old theme was something that I whipped up in a couple of hours one cold winters night, and never got around to updating again. The font was small and hard to read, the content was squashed, and man, there was a lot of crap on the page. It was also running on a very old version of BlogEngine.Net, and an upgrade was going to be a nightmare. So I decided it was time for “Daniels Blog – Version 2”.

I started off playing around with WordPress, as Kustom Page hadn’t even been born yet. It went well – it was easy to use, and seemed to do most of what I wanted. And then I started working on Kustom Page, and the whole WordPress conversion stopped.

So after hanging out with Blog Engine for 6 or so months longer, Kustom Page reached a stage where I could comfortably move this blog over, and not have to worry too much about it. Well that was my dream. Turned out some parts of Kustom Page made sense in “developer land”, but not so much in the real world. So I went back to the drawing board, fixed up the major flaws, and tried again.

And here we are. My whole blog, with every bit of content and comment that’s ever been posted, running on Kustom Page, with it’s shiny new theme!

Converting UTC Dates to a user specified time zone in C#/ASP.NET

I have been pissing around with this one for months – when someone posts anything on Kustom Page, the date gets stored in UTC, which is all good for storing date. But, of course, when they want to display a date on their site, say a blog post date, it comes up with that UTC date, which, if you live in New Zealand like I do, is 12 hours behind when you actually posted it. And who posts blogs at 3am in the morning?

My aim was always to allow users to set their own time zone, and then pass the dates through a convertor wherever it will be displayed on the screen. Sounds easy right? Actually it is. After reading this post at least.

So I wrote up a quick little class that takes care of that conversion, and can also return you a list of time zones

 public class TimezoneConvertor
    {
        public static DateTime Convert(DateTime UTCDate, string TimezoneID)
        {
            return TimeZoneInfo.ConvertTimeFromUtc(UTCDate,
                                                   TimeZoneInfo.FindSystemTimeZoneById(TimezoneID));
        }

        public static string Convert(DateTime UTCDate, string TimezoneID, string Format)
        {
            return TimeZoneInfo.ConvertTimeFromUtc(UTCDate,
                                                   TimeZoneInfo.FindSystemTimeZoneById(TimezoneID)).ToString(Format);
        }

        public static ReadOnlyCollection GetTimeZones()
        {
            return TimeZoneInfo.GetSystemTimeZones();
        }
    }

Obviously you’ll need to know the users time zone, which you could store in the database, or wherever you normally store your users settings.

For those of you using ASP.NET MVC, here’s a quick little conversion method to a list of SelectItems

   public static List TimeZoneSelectList(string SelectedName)
        {
            var timeZones = TimezoneConvertor.GetTimeZones();
            var listOfTimeZones = new List();
            foreach (var zone in timeZones)
            {
                var item = new SelectListItem();
                item.Text = zone.DisplayName;
                item.Value = zone.Id;

                if(item.Text == SelectedName)
                    item.Selected = true;

                listOfTimeZones.Add(item);
            }

            return listOfTimeZones;
        }

File Sorter

I got sick of sorting out files... So I wrote a quick little C# app that does all the work for me. Reads in filenames setup as ProgramNameS01E10.avi etc

 

using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
namespace TorrentSorter
{
class Program
{
   public static string FileInfoRegex = @"(.+)S(\d+)E(\d+)(.+)";
   public static string PathToScan = "";
   public static string OutputDirectory = "";
   static void Main(string[] args)
   {
      // If there aren't any arguments passed in at start, we need to ask the user for the info
      if (args.Length == 0)
      {
         Console.Write("Directory to scan: ");
         PathToScan = Console.ReadLine();
         Console.Write(string.Format("{0}Directory to move too: ", Environment.NewLine));
         OutputDirectory = Console.ReadLine();
      }
      else
      {
         PathToScan = args[0];
         OutputDirectory = args[1];
         // Allow people to pass in a custom regex pattern if run with arguments
         if (args.Length == 3)
            FileInfoRegex = args[2];
      }
      // Start processing the files
      ProcessDirectory(PathToScan, true);
      Console.WriteLine("Done!");
      Console.ReadKey();
   }
   static void ProcessDirectory(string filePath, bool recursive)
   {
      // If recursive is true, then we'll go through all the directories we can find and process them
      if (recursive)
      {
         foreach (var directory in Directory.GetDirectories(filePath))
         {
            ProcessDirectory(directory, recursive);
         }
}
      // Gets a list of files from given directory
      var listOfFiles = Directory.GetFiles(filePath).ToList();
      foreach (var file in listOfFiles)
      {
         var info = new FileInfo(file);
         var reg = new Regex(FileInfoRegex);
         var match = reg.Match(info.Name);
         // If theres a match, and the extention is not .torrent (for people who store the .torrent files in the directory they're using), start sorting
         if (match.Success && info.Extension.ToLowerInvariant() != ".torrent")
         {
            Console.Write(string.Format("{1}Moving file {0}...", info.Name, Environment.NewLine));
            // Get the program name and season number from the Regex matches
            string programName = FixFileName(match.Groups[1].Value);
            string seasonNumber = match.Groups[2].Value;
            // Work out the program and season folder. Append the word season in front of the number
            string programFolder = Path.Combine(OutputDirectory, programName);
            string seasonFolder = Path.Combine(programFolder, string.Format("Season {0}", seasonNumber));
            // Create the program folder if it doesn't already exist
            if (!Directory.Exists(programFolder))
               Directory.CreateDirectory(programFolder);
            // Create the season folder if it doesn't already exist
            if (!Directory.Exists(seasonFolder))
               Directory.CreateDirectory(seasonFolder);
            // Check that the file doesn't already exist, and copy it
            if (!File.Exists(Path.Combine(seasonFolder, info.Name)))
            {
               File.Copy(file, Path.Combine(seasonFolder, info.Name));
               Console.Write("done.");
            }
            else
            {
               Console.Write("already done.");
            }
         }
      }
   }
   /// 
   /// Removes the crap out of file names
   /// 
   /// 
   /// 
   protected static string FixFileName(string fileName)
   {
      fileName = fileName.Replace(".", " ");
      fileName = fileName.Replace("_", " ");
      fileName = fileName.Replace("-", " ");
      fileName = fileName.Replace("+", " ");
      fileName = fileName.Trim();
      return fileName;
   }
}
}

Don't have a c# complier? Download exe:

FileSorter.exe (6.50 kb)

Kustom Page: Coming up next

It’s a week on Wednesday since I first pushed Kustom Page out the door and into the world, and I am rather proud of it. It is currently purring along on the new server commissioned just before launch, and have been tempting people to signup.

Quick Stats:

Active Users: 10 (2 people haven’t confirmed their accounts, and therefore aren’t counted)
Websites: 12
Domains: 19

While obviously not mind boggling, I personally feel it’s not all that bad considering it’s been out a week, and is still in very early beta.

Thanks to everyone who has signed up!

What’s coming up next?

In the next release, due around the 17th on the 23rd of September, we are working hard to get the following features packed in:

Blogging System – This is the big feature for this release. It supports all the common blogging tasks: Blogging (obviously), Comments, Categories and RSS Feeds.

I’m also planning on moving this blog over to the Kustom Page blog as soon as possible.

Blog

Redirect Domains – Allows you to setup domains that point to another domain. Say you have 2 domains registered, one hardtospelldomain.com and hardtospeldomain.com, you can make it so that the incorrectly spelt domain redirects to your correctly spelt one.

Domains

View My Site Link – While only a very minor “feature”, this has to be the most requested feature by beta users. You can now click View My Site from any admin page, and it will open a new browser window containing your site.

view website

Kustom Page Beta has launched!

Late last night I finally managed to push a beta version of Kustom Page out the door, 5 months after writing the first line of code. And I must say, it finally feels like it’s getting somewhere.

The beta is still very rough, and still very basic, but it’s time to get people (like you) involved in the process and make sure that we’re actually on the right track to building a product people really want.

We are aiming at doing 2 weekly releases during beta – so chances are, if you find a bug, it’ll be fixed in the next release. You can log bugs using the Support link above the menu on all Kustom Page screens.

We have heaps planned for the next release, so stay tuned!

So feel free to sign up and give it a whirl!


kp2

It's been a while

And wow, it’s been busy. I have bought a new car, started a new project, found someone to help with that project, setup a home office. And it’s even starting to feel like spring.

So here’s an update of recent happenings… I’ll try to keep it short. I promise.

Car

Decided that after two years of my trusty Corolla, it was time to move up in the world. Don’t get me wrong, it was a great car, haven’t done anything mechanical to it in over two years. But I had a huge desire to get something more.

That something ended up being a twin-turbocharged Subaru Legacy wagon. I may have spent a tad too much on it already (Tyres, Battery and the break calliper stuffed up last week, now break pads) but, somehow, the whole shine of it still hasn’t disappeared. That car does something to you, it’s an amazing machine.

Home Office

When we moved into our flat, everything got chucked where ever it would fit. It could have been worse, but sitting in a corner looking at walls, to me at least, is very uninspirational. So the time came last night to change that around. We have ended up with the room effectively divided in two. One half for the “office” and the other half for living.

New lounge office layout

Kustom Page

Kustom Page lives again!

I have spent the last 4 and a half months developing a hosted content management system along with my cousin, Alex. Due for public beta in late September, we are working to re-invent what content management is all about. Forget the days where you spend your weekend reading the help documentation just to find that the latest version is different. Or that you go to upgrade your companies website, and everything breaks.

Our aim is to create something that just works. And always works. Leaving you to worry about driving traffic to your site and increasing your profits.

kp

Will be releasing more info on Kustom Page in the coming months, offering beta invite codes, and even releasing some of the code, so stay tuned!

Spring

Feels like winter dragged on and on, but as we get closer to September, it’s feeling like spring’s getting here. And what a great feeling that is. Bring on summer already!

Looking to Wellington from Petone Beach