Teleporting a Kangaroo

scott sappenfield

Remember this guy? He’s our friendly kangaroo lying around in the sun.

Well, he’s bored sitting in isolation in my iPhone photo gallery and wants to go up to the web to be shared with everyone. I haven’t looked up the definition of teleportation, but I have to imagine there’s a sender and a receiver.  So in this case, he’s going to be teleported from my iPhone (that’s the transmission sender) all the way up to the world wide web (that’s the transmission receiver).

Disclaimer

No actual animals have been harmed for the purposes of this post. Sorry, that’s another lame attempt at humor. It’s tough for me to make the nuts and bolts of technical stuff entertaining, but I try.

The Nuts and Bolts

Let’s see what’s going on with the code ( I took some code out, moved some other code around and added some commentary just for simplicity and clarity.)  In my actual code, there are things you don’t need to concern yourself with.  For instance, I start spinning an animator.  While that’s useful, you don’t need those details here.

The Sender

My iPhone.  Let’s send it on up to the receiver.  This method is dispatched in a separate thread, so keep that in mind.  If you don’t do that, make sure you do an asynch request so as to not tie things up unnecessarily.

(void)uploadMyNewPictureToWeb {

        //your web service that's on the lookout for Mr. Kangaroo
        NSMutableString *customWebPage = [NSMutableString stringWithString:@"your web service URL would go here"];
        NSURL *aUrl = [NSURL URLWithString:customWebPage];
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:aUrl];

        //this is your POST, PUT, whatever restful protocol you support
        [request setHTTPMethod:@"POST"];

        //set the content type
        //the spec calls for a unique string of characters as a separator, so use something random, but unique
        //also, I can't stress enough how important it is to get all the \r\n's correct
        NSString *boundary = @"DK39FJK4589FDKJSW893JKLR89DFJK238934IOSO";
        NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
        [request setValue:contentType forHTTPHeaderField:@"Content-Type"];

        //body
        NSMutableData *body = [NSMutableData data];

        //add all the textual params first (I'm going to assume you have some things to transmit other than just a photo
        //let's call them param1 and param2
        [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", @"param1"] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"%@\r\n", _param1] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", @"param2"] dataUsingEncoding:NSUTF8StringEncoding]];
        [body appendData:[[NSString stringWithFormat:@"%@\r\n", _param2] dataUsingEncoding:NSUTF8StringEncoding]];

        //now add the image data, remember in the original post, I used a button, you could get this from local documents storage or wherever
        NSData *imageData = UIImagePNGRepresentation(_profilePictureButton.imageView.image);
        if (imageData) {
            [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
            [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"mrkangaroo.png\"\r\n", @"mrkangaroo"] dataUsingEncoding:NSUTF8StringEncoding]];
            [body appendData:[[NSString stringWithFormat:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
            [body appendData:[NSData dataWithData:imageData]];
            [body appendData:[[NSString stringWithFormat:@"%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
        }
        [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

        //set the body to the request
        [request setHTTPBody:body];

        //set the content length
        NSString *postLength = [NSString stringWithFormat:@"%d", [body length]];
        [request setValue:postLength forHTTPHeaderField:@"Content-Length"];

        NSURLResponse *response;
        NSError *error;

        //send it and do something with the response...response parsing is left off here for simplicity
        NSData *myJSONNetworkData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

        //parsing response...
}

The Receiver

A web service keeping an eye out for Mr. Kangaroo.

You probably don’t need an example, but sometimes it helps to see how to handle things on the receiving end.  Whatever you use (ROR, PHP, JSP) on the receiving end will be able to easily parse this data.  SitterSat.com was written in ASP.Net/VB on the server-side, so here it is in that language. Again, I’ve removed a lot because you don’t need all that, just the relevant pieces.

//ASP.Net libraries have many useful collection for you, one being files in the request object
Dim fileCollection As HttpFileCollection = Request.Files

//Code works, but is simplified here for you, meaning you'll want more robust error handling and logging
For Each uploadedFileName In fileCollection
  Dim uploadedFile As HttpPostedFile = fileCollection(uploadedFileName)
  If Not uploadedFile Is Nothing Then
    If (uploadedFile.ContentLength > 0) Then
        //Save it somewhere on the server, whatever path conventions you have
        //also, this doesn't save it with a file extension, but you could that just the same
        uploadedFile.SaveAs(Server.MapPath("~/Pictures/mrkangaroo"))
    End If
  End If
Next

I hope this will help you out should you ever need to get into the business of transporting. Best of luck, let me know if I can help with anything.  You know, now that I’m thinking about it, I went to all this trouble, why didn’t I just tweet or FB him?  Oh well.

HTML5 Facelift

This past weekend, I thought I developed a new allergy.  It’s not pollen, I already have that allergy.  I thought had I developed an allergy to Internet Explorer.

Here’s what I did to SitterSat.com over the weekend.  I overhauled it in an effort to make it HTML5 compliant.  I want to do a bunch of cool graphic stuff like add a million stars to the page.  Well, no not really, although that is really cool.  Great use of Three.js.  No, instead I bootstrapped it.  Github to the rescue!

The reason I thought I had a new allergy to IE is because when something didn’t work in IE I used to be able to find all kinds of work-arounds to get everything to work fine in that browser.  Things that worked well in Chrome without workarounds.  But it called for all this nasty little code I had to maintain.  This time however, I just grew tired of it.  I’d rather not have all that nasty little code.  So for now I put a disclaimer at the footer of the page for IE users saying something like “This site works fine in IE, but looks better in Firefox and best in Chrome or Safari.”  Fortunately, for us, only 7% of our user base visits us with IE.  Oh yes and I figure very little to none of that 7% is using IE 10 with Windows 8 which actually seems to work fine from my own testing.

So here’s where I think we’ll end up!  Everything should work just fine in these cases:

Safari (41% of user base) – will work just fine

Chrome (46% of user base) – will work just fine

Firefox (4% of user base) – will work just fine in >v17

Opera (0% of user base) – will work just fine in >v12

IE (7% of user base) – will work just fine in >v10

A couple of pain points

Placeholder text

This is a small thing, but placeholder text doesn’t seem to work in IE (< v10).  That’s the nice little text you get inside a textbox to aid you in remembering what the input in that box is supposed to be provided.  The placeholder text eliminates unnecessary labels elsewhere and frees up valuable real estate, plus it just looks nice and cool.

CSS3

Gradients, transitions and animations aren’t doing so well in IE  (< v10).  We’ll just have to look at a non-moving red box.  To accomodate, I’ve added in some text above the box, “Fetching…” which in hindsight is valuable anyhow.  You wouldn’t know what that progress bar is for if I didn’t say so I’m glad that’s in there.

For an example of what I’m talking about, go to SitterSat.com and look at the page while the latest 2 blog posts load on the right hand side.  If you look very quickly (because it may load really fast), you should see something like this bar below (but animating, like an old barber’s pole).  That is, unless you’re using an older version of IE (< v10):

loadingblogstriper

I put this progress bar in to let you know some fetching was taking place.  I changed the way I’m loading those latest 2 blog posts.  Previously, I was loading the posts synchronously which was a real drag, literally, the page wouldn’t fully load until that processing was complete.  Yuck.  Now, I’m asynchronously loading from another domain (sittersatblog.com) using a jquery ajax call.  Partial Yippee.  In Chrome, looks great, very nice, in IE (< v10), not so good, just a red bar.  I will look into caching it, there’s no need to go get that so often.  That’ll be Full Yippee.  Why we have a separate domain for the blog is another discussion entirely.

Now onto the good stuff

So now that’s out of the way.  Let’s move onto what I love about this effort.  It’s certainly not banging away at a keyboard all weekend.  I should mention that all weekend is a bit of an exaggeration, I started Saturday morning and finished up Sunday evening around 9p.m..  And that incorporates the fact that I tinker and tinker and tinker and tinker with the smaller details until I’m happy with it.  That slows me down quite a bit.  During that time, we got a Christmas tree, put up decorations, played with the kids and intervened on a few seemingly pointless kid arguments.  My point is that this mini project was secondary and can be done here and there without too much fuss.  Of course, as I type this I can’t help but reflect on that fact that I have an ever patient wife.

What I love about the bootstrapping process was the clean transition to HTML5 compliancy.  Plus, I got some insight into the geniuses that created all this stuff.  How generous for them to have created it all for public consumption!

Here’s the path I took to get there:

1. Go out and git yourself a good zipball of fun, from github or another source.  I actually ended up using a custom download from Initializr that includes Modernizr.  Inside it will look something like this, as you’ll notice very straightforward:

Bootstrap zipball

– css

– img (glyphicons halflings – they’ve worked out a special arrangement with github so you get these for free)

– js

2. Update your files to HTML5 compliancy (<!DOCTYPE html> and stuff like that).  You can do all this manually, but you can also start with some of Bootstrap’s barebones HTML5 compliant templates and just plug in the dynamic stuff.  I didn’t use a template, but I did take some elements out of the templates, some for use, some for study, like the hero template, navbar (loved the collapsing menu), narrow marketing container and nice large carousel jumbotron.

That’s it.  Oh yes, I love the doctype declaration by the way.  The pre-HTML5 way has always annoyed me.  You’ll probably like the other small changes like meta, stylesheet and javascript declaration changes for the same reason.

Oprah’s Scott’s favorite thing

Best of all, my most favorite thing?  Without question, the responsive 12 grid layout available with bootstrap.  I love it.  It’s not for everyone, but nothing is.  For me, it provides flexibility with ease of use and most of all speed.  I can quit messing around with the basic layout so much, everything is right there in div and CSS, everything I need to move fast.  And it works great for tablets and smartphones.

Previously, I had a couple of inserts of some nasty code, something where I look at the user’s useragent to determine if they are using something other than a desktop browser.  If they were, I changed the look and feel.  While it worked, I never really liked the way it look on smartphones and tablets.  Not only was the formatting slightly askew, I had removed some things from the view.  All this time I had previously spent on making it look good while botching up the code.  It wasn’t that bad, I make it sound worse that it was, but still I just didn’t like it that much.  I wanted something responsive, something where the stylesheets would more appropriately determine where things land and how they look on the page for various screen sizes.  And I wanted my code to be cleaner!  That’s as it should be after all.  It is more so now than ever and I’m happy.

So now that the basic HTML5 implementation is in place, I can focus on replacing some more of my other homegrown code with standard goodies from bootstrap and jquery.  All while trying to implement new and relevant HTML5 specific features.  I just need to think about what those features would be!

Wake on LAN

Wake on LAN with ASP.Net and Magic Packets

Many props have to go out to this individual:  http://devinfra-us.blogspot.com/2011/02/using-powershell-20-from-aspnet-part-1.html

After reading this post, I was able to do something quick and dirty that helped me a lot.  I wanted an Intranet page that I could use to remotely wake up servers on the LAN. Bassicaly, you’re sending a magic packet to a server and asking it to wake up. To do that, you need to configure that server to wake up, usually in the BIOS, wake on ethernet or something similar.

Running Processes PowerShell OutputWhat I do like about powershell is being able to combine so much into simple one liners…it makes it very easy to construct the required magic packet (first 6 bytes are FF hex/255 int followed by 16 repetitions of the target MAC address for the spec’s required 102 bytes). Here’s a snapshot of how I used it to grab a list of running processes.

Anyhow, here’s the skinny:

1.  Add a reference in your project to System.Management.Automation in your Visual Studio project

2.  Front-end code (you can take out all that Jquery stuff)

<%@ Page Title="Home Page" Language="vb" MasterPageFile="~/Site.Master" AutoEventWireup="false"
    CodeBehind="Default.aspx.vb" Inherits="PowerShellApp._Default" %>

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <script src="Scripts/jquery-1.4.1.min.js" language="javascript" type="text/javascript"></script>
    <script type="text/javascript">
        function SetScript() {
            document.getElementById('MainContent_PowerShellCodeBox').value = "get-process|out-string"
        }
        function ClearScript() {
            document.getElementById('MainContent_PowerShellCodeBox').value = ""
        }
    </script>
    <center>
        <div>
            <table border="0">
                <tr><td><h1>PowerShell Tool</h1></td></tr>
                <tr><td><h3>PowerShell Script (Script runs on Intranet Server)</h3></td></tr>

                <tr><td>
                    <asp:TextBox ID="PowerShellCodeBox" runat="server" TextMode="MultiLine" BackColor="DarkBlue" ForeColor="White" Width="700" Height="100"></asp:TextBox>
                </td></tr>

                <tr><td>
                    <asp:Button ID="ExecuteCode" runat="server" Text="Run It" Width="200" onclick="ExecuteCode_Click" /><asp:Button ID="TestCode" runat="server" Text="Test Me" Width="200" onclick="ExecuteCode_Click" />
                </td></tr>

                <tr><td><h3>Result</h3></td></tr>
        
                <tr><td>
                    <asp:TextBox  ID="ResultBox" TextMode="MultiLine" Width="700" Height="200" BackColor="DarkBlue" ForeColor="White" runat="server"></asp:TextBox>
                </td></tr>

            </table>
        </div>
        <div id="sampletext" style="text-align:left;width: 75%">
                $mac = [byte[]]("F4-CE-46-B6-1C-2C".split('-') |% {[int]"0x$_"})<br />
                $UDPclient = new-Object System.Net.Sockets.UdpClient<br />
                $UDPclient.Connect(([System.Net.IPAddress]::Broadcast),4000)<br />
                $packet = [byte[]](,0xFF * 102)<br />
                6..101 |% { $packet[$_] = $mac[($_%6)]}<br />
                $UDPclient.Send($packet, $packet.Length)<br />
        </div>
        <div id="defaultspinner"></div>
    </center>
    <script type="text/javascript">
        $(document).ready(function () {
            $("#sampletext").show();
            $("#defaultspinner").hide();
        });
        $("#MainContent_TestCode").click(function (event) {
            $("#sampletext").hide();
            $("#defaultspinner").show();
            $("#defaultspinner").load("DefaultSpinner.aspx");
        });
    </script>
</asp:Content>

3. Back-end code (remember, quick and dirty here, no separation of presentation, no exception handling, etc…)

Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Management.Automation
Imports System.Management.Automation.Runspaces
Imports System.Text
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls

Public Class _Default

    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        TestCode.Attributes.Add("onmouseover", "SetScript();")
        TestCode.Attributes.Add("onmouseout", "ClearScript();")

    End Sub

    Protected Sub ExecuteCode_Click()

        ' Clean the Result TextBox
        ResultBox.Text = ""

        ' Validate there was something in the box
        If (PowerShellCodeBox.Text.Length <= 0) Then             ResultBox.Text = "You need to give me a script so I can run it."             Exit Sub         End If         ' Initialize PowerShell engine         Dim shell As PowerShell         shell = PowerShell.Create         ' Add the script to the PowerShell object         shell.Commands.AddScript(PowerShellCodeBox.Text)         ' Execute the script         Dim results = shell.Invoke         ' display results, with BaseObject converted to string         ' Note : use |out-string for console-like output         If (results.Count > 0) Then

            ' We use a string builder ton create our result text
            Dim builder = New StringBuilder

            Dim psOjbect As PSObject
            For Each psOjbect In results

                ' Convert the Base Object to a string and append it to the string builder.
                ' Add \r\n for line breaks
                builder.Append(psOjbect.BaseObject.ToString() + "\r\n")

            Next

            ' Encode the string in HTML (prevent security issue with 'dangerous' caracters like < >
            ResultBox.Text = Server.HtmlEncode(builder.ToString())

        Else

            ResultBox.Text = "The command did not produce results or there was a syntax error."

        End If

    End Sub

End Class