GORILLA.BAS, QBasic & Edit

Nostalgia time!

Back when I got my first PC, QBasic was part of the operating system.

I spent hours and hours playing around with QBasic and MS-DOS Editor (or simply edit as we all knew it) to see what graphics and games I could whisk up.

There was a game that came with QBasic and MS-DOS called Gorillas, which was effectively like Worms and Scorched Earth.

Look at those mind-blowing graphics!

Man, have editors and IDEs come a long way; but edit was a great editor for its time. What a twinge of nostalgia I feel when I see this screen:

http://www.computerhope.com/jargon/e/doseditwindow.jpg

Edit came along for the ride all the way to Windows 7; but sadly, it doesn’t come with any 64 bit OSes.

RIP, old friend.

Asychronously upload a file using jQuery to a Web API controller

Here’s the code for the HTML5 form:

<form id="upload">
    <div>
        <label for="myFile"></label>
        <div>
            <input type="file" id="myFile" />
        </div>
    </div>
    <button type="submit">Upload</button>
</form>

We need to use jQuery to handle when the user submits the upload, to make sure it gets handled asynchronously and posted to our Web API controller:

        // Hook into the form's submit event.
        $('#upload').submit(function () {

            // To keep things simple in this example, we'll
            // use the FormData XMLHttpRequest Level 2 object (which
            // requires modern browsers e.g. IE10+, Firefox 4+, Chrome 7+, Opera 12+ etc).
            var formData = new FormData();

            // We'll grab our file upload form element (there's only one, hence [0]).
            var opmlFile = $('#opmlFile')[0];

            // If this example we'll just grab the one file (and hope there's at least one).
            formData.append("opmlFile", opmlFile.files[0]);

            // Now we can send our upload!
            $.ajax({
                url: 'api/upload', // We'll send to our Web API UploadController
                data: formData, // Pass through our fancy form data

                // To prevent jQuery from trying to do clever things with our post which
                // will break our upload, we'll set the following to false
                cache: false,
                contentType: false,
                processData: false,

                // We're doing a post, obviously.
                type: 'POST',

                success: function () {
                    // Success!
                    alert('Woot!');
                }
            });

            // Returning false will prevent the event from
            // bubbling and re-posting the form (synchronously).
            return false;
        });


Ok and now in our controller, we can deal with the uploaded file(s):

    using System;
    using System.IO;
    using System.Net;
    using System.Net.Http;
    using System.Web;
    using System.Web.Http;

    class UploadController : ApiController
    {
        public async void Post()
        {
            if (!Request.Content.IsMimeMultipartContent())
            {
                throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted"));
            }

            // We'll store the uploaded files in an Uploads folder under the web app's App_Data special folder
            var streamProvider = new MultipartFormDataStreamProvider(HttpContext.Current.Server.MapPath("~/App_Data/Uploads/"));

            // Once the files have been written out, we can then process them.
            await Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith(t =>
            {
                if (t.IsFaulted || t.IsCanceled)
                {
                    throw new HttpResponseException(HttpStatusCode.InternalServerError);
                }

                // Here we can iterate over each file that got uploaded.
                foreach (var fileData in t.Result.FileData)
                {
                    // Some good things to do are to check the MIME type before we do the processing, e.g. for XML:
                    if (fileData.Headers.ContentType.MediaType.Equals("text/xml", StringComparison.InvariantCultureIgnoreCase))
                    {
                        // And this is how we can read the contents (note you would probably want to do this asychronously
                        // but let's try keep things simple for now).
                        string contents = File.ReadAllText(fileData.LocalFileName);
                    }
                }
            });
        }
    }

Uninstalling VMWare Workstation when Hyper-V is installed

Well, it was annoying enough that VMWare doesn’t launch on my machine when Hyper-V is installed. I’m skeptical that VMWare wouldn’t run if Hyper-V isn’t running at the same time, and this check just reeks of anti-competition.

Unfortunately for VMWare, that can work against them rather than encourage me to uninstall Hyper-V. That means I’m ditching them for now (mainly as Visual Studio integration with Hyper-V for things like Windows 8 and Windows Phone 8 development is good; not to mention, Hyper-V is built in and doesn’t cost extra).

I went to uninstall VMWare today but got this error:

image

Wow! Talk about pain in the ass.

Fortunately a quick search later, Jussi Palo has a simple solution, altering the installer’s lua script to skip this check:

Remove VMware Workstation or Player when Hyper-V is installed

And now I can uninstall.

Baby Blacks give Ireland beating; David Moore pinged for high tackle

The New Zealand Under-20 rugby team is playing in the inaugural IRB Junior World Championship and just thrashed Ireland 65-10.

I watched some of the coverage at the TVNZ site (they have full footage of both halves here).

There was a flanker playing for Ireland called David Moore. While I skipped through the video I managed to see him give away a couple of penalties, including for a blatant head-high clothes-hanger tackle. Good stuff, repping the David Moore name!

While it’s good to see the rough stuff still in rugby, these transgressions might be brought up at the next annual David Moore Secret International Underground Society meeting. Think of a cross between Freemasons & Illuminati, except the membership is even more exclusive (with the first criteria being you need to be called David Moore).