Craig Gibbons' Lifeblog lifeblog://tri.eat.net

8Oct/15Off

T3 MongoChef is The Best!

After recently building an application using the MEAN stack, one of the essential tools I found I needed was a good MongoDB interface. Sure you can use the command line if you're feeling hard-core and indeed sometimes that may be all you have but in general your options boil down to either web browser or native client apps. Among those, your best options (at time of writing) are RockMongo for a browser based app. RockMongo ships with the Bitnami MEAN stack. If you are using Amazon Web Services (AWS) you can create a new EC2 instance using the Bitnami MEAN AMI, which will give you a full MEAN stack server with minimal fuss. If you're looking for a native MongoDB client app you should look no further than RoboMongo and T3 MongoChef. Now, let me be absolutely clear, T3 MongoChef is overwhelmingly the better of the 2 products. As headline feature advantages over RoboMongo it has the ability to edit individual fields rather than editing the JSON of the whole document and changes can be applied to: only the current document, all documents returned by the find criteria, or all documents in the collection. As a developer this last option is key because I don't always have a 100% clear idea up-front what data I want in my document.

So, with that complete endorsement of MongoChef let me just finish by saying that while RoboMongo is entirely free for personal and commercial use, MongoChef is only free for personal use. If you have another purpose in mind, pay the money, it's well worth it.

Filed under: Tech Comments Off
17Mar/15Off

Bitcoin: the digital currency of the future?

Cass Business School In partial fulfilment of the MBA Program at Cass Business School, I was required to write a paper on a topic of my choosing called a Business Mastery Project. Given my technical background and an affinity for the topic, I decided to choose Bitcoin, the crypto-currency and consensus network which has been the source of much scandal and debate but also has the potential to be an incredible force for good and a truly disruptive technology in a space which has long been dominated by inefficient and expensive incumbents. I publish my paper here for anybody interested. The paper is published under the MIT license, you can download it here: Craig Gibbons - Cass Business School MBA BMP - Bitcoin

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

If you wish to leave any comments, questions or suggestions please submit them here:

25Oct/12Off

Getting Started with the Raspberry Pi

Raspberry PiA long time ago, in a land far away, I had a friend who helped install my first Linux operating system. At the time I had one of the latest machines on the market, sporting a 233Mhz processor, 32Mb RAM and a 2.3Gb HDD. It was my first and I was keen to see what it could do, so when said friend offered to install Linux for me I jumped at the opportunity, not knowing anything about what I was getting into. Surely, I thought, I could just click around and find my way. Later, when I was presented with a blank looking command line it wasn't feeling like such a good idea. I once even rebooted the machine because I couldn't figure out how to exit the vi editor. After reading an O'Reilly book and a lot of tinkering, I felt like I finally got it, sort of.

Fast forward>> 15 or so years and I feel like I've come full circle with the acquisition of the Raspberry Pi, the coolest piece of kit I've ever owned, or if it isn't it'll do until the coolest piece gets here. The Raspberry Pi is at the forefront of a trend towards smaller computers which are accessible to almost anybody. The unit its self costs a mere £29 (incl. postage) and you can buy one from either of the two vendors chosen by the Raspberry Pi foundation, Element 14 or RS Components. If you've found this way onto this page, you have most likely come looking for information on the RPi (see what I did there) so I'll just get onto the details.

First, while the RPi is cheap by its self, you will need some extras before it's actually usable:

  • A 5V 700mA mini USB charger. My Samsung Galaxy S2 charger worked perfectly
  • Powered USB hub (£15)
  • Mouse and keyboard
  • Monitor or TV
  • HDMI cable (£4)
  • Wi-Fi USB dongle (£10)
  • Minimum 4Gb SD card (£5)
  • Case (£10 - £15 optional)

Now, this is important; not everything will work with the RPi so make sure you check out the approved hardware page at: http://elinux.org/RPi_VerifiedPeripherals

For readers in the UK, some free advice I can give you is not to buy the USB hub included as part of the Maplin RPi starter kit, it produced some weird behaviour with the mouse on my system and it doesn't come with a mains charger. The separate charger recommended on the Maplin site goes for abut £30 in addition to the £14 for the hub. You would do better to buy all the bits you need off The Pi Hut.

A number of excellent cases are available, but I chose the Pibow, which is super easy to fit and nice and colourful. Also, I like to see the Pi board and the Pibow case exposes that nicely.

The Raspberry Pi website explains in detail how to get up and running so I won't cover that here, but in general you can either buy a pre-installed 4Gb SD card loaded with a beginner version of Linux or you need to download an 'image' (approx. 440Mb) and write it to the SD card. The RPi then boots from the SD card. I had everything up and running in about 10 minutes from unpacking the RPi and the beginner version is great. It boots right into its window mode, LXDE. Windows users will feel immediately at home. I then went about installing some software to see what the Pi could actually do. As it turns out, quite a lot! Among many others, the following are available:

  • Chromium - identical to the Google Chrome browser (sudo apt-get install chromium-browser)
  • OpenOffice - a replacement for Microsoft Office (sudo apt-get install openoffice.org)
  • GIMP - a graphics application similar to Adobe Photoshop (sudo apt-get install gimp)
  • IceDove - identical to the Mozilla Thunderbird email client (sudo apt-get install icedove)
  • FileZilla - a FTP client (sudo apt-get install filezilla)
  • The LAMP stack - Linux, Apache, MySql, PHP (sudo apt-get install apache2 php5 php5-mysql mysql-server)
  • ... and I'm working on Git or SVN and node.js

Edit Oct 26th, 2012: Since installing Chromium and Icedove, the performance of the RPi has been very poor. The CPU runs at 100% constantly and it's almost impossible to get anything done. I've reverted back to the default browser Midori which is doing the job admirably and instead of Icedove I've installed Claws Mail (sudo apt-get install claws-mail), which appears to be a lot lighter with no loss of functionality, indeed I may prefer it.

I hope this brief post has provided some helpful information for newcomers and whet the appetite of those not yet signed-up. And in case you were wondering, yes, this post was created using the Chromium browser and GIMP for the picture on a Raspberry Pi Model B.

Filed under: Cool kit, Tech Comments Off
23Aug/060

Adding META, CSS, JavaScript or any other kind of tag to a Page or MasterPage header

In .NET there is always a way. As far as I can tell, after working
extensively with the Framework for about 4 years, nothing has been
omitted. One might encounter the odd anomaly, but for the most part
there is always several workarounds to any problem which may arise.
Working with MasterPages poses some of its own problems. One such
problem is the adding of tags to the Page header. Such tags include
META, CSS and JavaScript, but this could be anything defined by the
standard. The tags can of course be entered straight into the page
code, but if you want to conditionally include something or use a
virtual path, you need to do this programmatically. The following three
code snippets show how to add META, CSS and any other tag to the Page
header.

META Tags

protected void Page_Load(object sender, System.EventArgs e) {
    HtmlMeta meta = new HtmlMeta();
    meta.HttpEquiv = "refresh";
    meta.Content = "5;http://www.gibbons.co.za";
    Page.Header.Controls.Add(meta);
}

CSS Tags

protected void Page_Load(object sender, System.EventArgs e) {
    HtmlLink css = new HtmlLink()
    css.Href = "http://www.gibbons.co.za/Style.css";
    css.Attributes["rel"] = "stylesheet";
    css.Attributes["type"] = "text/css";
    Page.Header.Controls.Add(css);
}

Any other tag (e.g. JavaScript include)

protected void Page_Load(object sender, System.EventArgs e) {
    HtmlGenericControl control = new HtmlGenericControl("script");
    control.Attributes["src"] = "common.js";
    control.Attributes["type"] = "text/javascript";
    control.Attributes["language"] = "javascript";
    Page.Header.Controls.Add(control);
}

Alternatively, you can always use a HtmlGenericControl and use the Attributes collection to write any attributes you desire.

Filed under: Tech No Comments
23Aug/060

ASP.NET DropDownList with OPTGROUP support

One of the new tags in the XHTML standard is OPTGROUP. This long
missing tag provides the ability to group elements into sub-sections
inside a SELECT element. Unfortunately, the ASP.NET DropDownList server
control lacks the ability to add OPTGROUP’s to its items collection, so
it falls to the developer to provide a custom solution for this. I did
some looking around and found a few solutions to the problem, but none
of them really looked like the real deal, until I discovered Control
Adapters in .NET 2.0! Essentially, Control Adapters allow you to
override any method of a control by providing your own implementation.
Even better still, you can use this technology to target different
browsers in different ways by using a browser file. From there, the
solution was quite simple. The steps and associated code are as follows:

  1. Create a .browser file. Paste in the following code:

    <browsers>

      <browser refID="IE6to9">

        <controlAdapters>

          <adapter controlType="System.Web.UI.WebControls.DropDownList"

          adapterType="DropDownListAdapter" />

        </controlAdapters>

      </browser>

    </browsers>

  2. Create a file called DropDownListAdapter.cs in App_Code or a sub
    directory thereof (I use a folder called Adapters), paste in the
    following code:
    public class DropDownListAdapter : System.Web.UI.WebControls.Adapters.WebControlAdapter {
        protected override void RenderContents(HtmlTextWriter writer) {
            DropDownList list = this.Control as DropDownList;

            string currentOptionGroup;
            List<string> renderedOptionGroups = new List<string>();

            foreach(ListItem item in list.Items) {
                if(item.Attributes["OptionGroup"] == null) {
                    RenderListItem(item, writer);
                } else {
                   
    currentOptionGroup = item.Attributes["OptionGroup"];

                   
    if(renderedOptionGroups.Contains(currentOptionGroup)) {
                       
    RenderListItem(item, writer);
                    } else {
                       
    if(renderedOptionGroups.Count > 0) {
                           
    RenderOptionGroupEndTag(writer);
                        }

                       
    RenderOptionGroupBeginTag(currentOptionGroup, writer);
                       
    renderedOptionGroups.Add(currentOptionGroup);

                       
    RenderListItem(item, writer);
                    }
                }
            }

            if(renderedOptionGroups.Count > 0) {
                RenderOptionGroupEndTag(writer);
            }
        }

        private void RenderOptionGroupBeginTag(string name, HtmlTextWriter writer) {
            writer.WriteBeginTag("optgroup");
            writer.WriteAttribute("label", name);
            writer.Write(HtmlTextWriter.TagRightChar);
            writer.WriteLine();
        }

        private void RenderOptionGroupEndTag(HtmlTextWriter writer) {
            writer.WriteEndTag("optgroup");
            writer.WriteLine();
        }

        private void RenderListItem(ListItem item, HtmlTextWriter writer) {
            writer.WriteBeginTag("option");
            writer.WriteAttribute("value", item.Value, true);

            if(item.Selected) {
                writer.WriteAttribute("selected", "selected", false);
            }

            foreach(string key in item.Attributes.Keys) {
                writer.WriteAttribute(key, item.Attributes[key]);
            }

            writer.Write(HtmlTextWriter.TagRightChar);
            HttpUtility.HtmlEncode(item.Text, writer);
            writer.WriteEndTag("option");
            writer.WriteLine();
        }
    }

From there, usage of the DropDownList is exactly the same, except you
need to add an OptionGroup attribute to any items you wish to add to a
given group, sample code as follows:

ListItem item1 = new ListItem(“South Africa”, “SA”);
ListItem item2 = new ListItem(“United States”, “US”);
ListItem item3 = new ListItem(“United Kingdom”, “UK”);
item1.Attributes[“OptionGroup”] = “Countries”;
item1.Attributes[“OptionGroup”] = “Countries”;
item1.Attributes[“OptionGroup”] = “Countries”;

ddlCountries.Items.Add(item1);
ddlCountries.Items.Add(item2);
ddlCountries.Items.Add(item3);

Filed under: Tech No Comments
17Mar/060

Side-by-side VS2003 and VS2005: Unable to start debugging on the web server

Today I came across a big problem with an obvious easy solution. I had just installed a new machine with IIS, VS6, VS2003 and VS2005 side-by-side. To Microsoft's credit, this works flawlessly. However, after getting some of my old VS2003 (.NET 1.1) projects from SourceSafe, I found I couldn't run the project in debug mode. At first I thought this was due to the side-by-side installation or an error in the installation, so I ran a repair on the VS2003 installation but found the problem persisted even after that completed successfully.

Turns out it has to do with the version of the .NET runtime the virtual directory is setup for. To solve, open Internet Services Manager, and open the Properties dialog on the Virtual Folder of the application in question. On the far right, you'll find an "ASP.NET" tab. Check the ASP.NET dropdown is set to the version of the runtime the site was developed in.

There are several other reasons why debugging may not work on your machine, but those are all documented in the VS help.

Filed under: Tech No Comments
9Feb/060

Creating a DropDownList from an Enum using Attributes and Reflection

Often in software development, one has a need to map the values in a lookup table to an enumeration in code. In this way, the values of the lookup table can be readily accessed in a strongly typed way. The only drawback to this approach is that the enum and the table can often get out of sync if values in the table change. That is however an entirely different problem and will not be discussed here. It is also often the case, in web development anyway, that one needs to display the values in the table and hence the enumeration, in a DropDowList. There are two possibly approaches to this problem.

  1. Get the values from the database in a IDataReader (or DataTable or whatever) and bind it to the DropDownList
  2. Use the values in the enumeration to generate the ListItems for the DropDownList.

I have always favoured the second approach, but enums are quite limited in the data they can hold. Really, it's nothing more than a stringly typed key/value pair, usually of type int. Sometimes however, we want to store more information with the enumeration for display in the UI. We may for example, have an enum with the following values:

public enum Vendors {
Microsoft,
Oracle,
IBM
}

But, we may like to display something like "Microsoft Developmer Network" in a Drop Down. Enter Attributes! An Attribute can be applied to just about anything and can be easily consumed using Reflection. All the developer need do is create a class derived from the Attribute base class. It doesn't have to be particularly complex. The following will suffice:

public class EnumMetaDataAttribute : Attribute {
string _description;

public string Description {
get {
return _description;
}
}

public EnumMetaDataAttribute(string description) {
_description = description;
}
}

Then the attribute needs to be applied to the enum values:

public enum Vendors {
[EnumMetaData("Microsoft Developer Network")] Microsoft,
[EnumMetaData("Oracle Technology Network")] Oracle,
[EnumMetaData("IBM developerWorks")] IBM
}

So far, we have no way of consuming these attributes, but this is easily overcome using some basic reflection techniques. The following function should be fairly self explanatory. The .NET help should be sufficient reference for the reflection properties and methods:

public static void GetEnumDropDown(DropDownList dropDown, System.Type enumType) {
FieldInfo[] fields = enumType.GetFields();
foreach(FieldInfo field in fields) {
if(field.IsSpecialName) {
continue;
}

int value = Convert.ToInt32(field.GetValue(0));
EnumMetaDataAttribute attribute = field.GetCustomAttributes(typeof(EnumMetaDataAttribute), false)[0] as EnumMetaDataAttribute;

dropDown.Items.Add(new ListItem(attribute.Description, value.ToString()));
}

Which may then be called in the following way:

GetEnumDropDown(ddlDropDownName, typeof(Vendors));

Filed under: Tech No Comments
3Feb/060

Manage Recent Projects list in VS2005

It seems like an obvious thing to be able to do in Visual Studio 2005, but there is really no in-built way to manage items in the Recent Projects list on the Start Page. If you're like me, you end up with a bunch of project names from various things, with some duplicates even. It can rapidly become unwieldy to figure out what project you're actually trying to open. I did a little looking around and it seems the only way to actually manage items in that list is via the registry.

Go Start -> Run and type "regedit".

The keys you're looking for can be found in: HKCU\Software\Microsoft\VisualStudio\8.0\ProjectMRUList

Just delete the ones you no longer want and restart VS.

Filed under: Tech No Comments
20Jan/060

A generic C# function for casting from Object to any type

A very common scenario in software development is getting data from a database and then reading that data into strongly typed variables. Mostly I do this in an OR (Object Relational) layer, but really it could be done anywhere. Prior to .NET 2.0 and the introduction of generics, one had to cast the values from a DataRow or IDataReader column value, returned as an object, as follows:

string description = Convert.ToString(row["Description"]);

This works, but one needs to do a Convert operation for every data type. Furthermore, the object may be a DBNull, in which case you'll get an InvalidCastException. There are various strategies for getting around this. I offer my solution here.

public static T ToType<T>(object value) {
 if(Convert.IsDBNull(value)) {
  return default(T);
 }

 return (T)Convert.ChangeType(value, typeof(T));
}

Typically, this function would reside in a helper class of some kind and called in the following way:

string description = DbHelper.ToType<string>(reader["Description"]);

For any other data type, simply replace <string> with whatever cast you wish to perform.

Filed under: Tech No Comments
14Dec/050

DataList ItemDataBound e.Item.Visible = false doesn’t work

I came across a small problem today when trying to set items in a DataList to Visible = false in the ItemDataBound event. Quite simply, it just plain wasn't working. I did a bit of Googling and found several reported instances of this, but only one suggested any type of resolution. That forum thread can be found here: http://www.codecomments.com/archive320-2005-10-657712.html

Strangely, the problem only occurs when the RepeatLayout property of the DataList is set to Table. Change the RepeatLayout to Flow and the problem goes away.

Alternatively, Do something like this:

e.Item.CssClass = "hidden";

Then, add a CSS class "hidden" to your stylesheet:

.hidden {
display:none;
}

Filed under: Tech No Comments