2011 was my first TechEd and to help navigate around I wrote an mvc app to keep track of what was happening in each room. This is the 2012 edition.

AuTechEd 2012 session schedule

When the schedule builder first appeared on the TechEd Australia site I got excited at the content but frustrated with the presentation. What I really wanted was to figure out for each timeslot, what sessions were on. In other words

At any given moment which sessions are competing for my attention?

Remembering how ridiculously easy it was to query the session OData feed last year I flicked a query over to the ever-friendly @auteched crew. I got an immediate response that the OData feed was not available yet but on it's way.

I will wait for the OData.

A couple of days later the @auteched peeps pinged me to let me know that the feed was up (personal service FTW!) and I got to work in my Visual Shed (LinqPad). Adding an OData service to a LINQPad query is very easy.

alt text

Then you can write a tiny bit of code to query the Sessions (and eager load some other bits) and dump them into a grid:

Sessions.Expand("Track")
        .Expand("SessionType")
        .Expand("Speakers")
        .Expand("Level")
        .Dump(true);

The grid has hyperlinks to allow you to drill into the data. This is nice but what I really want is to see a drill-down like this

Day -- Time -- Sessions

After a bit of trial-and-error (LINQPad is a great tool for experimenting with complex queries) I came up with a single query that formed the data into the shape I wanted to see it. The resulting .linq file is

<Query Kind="Program">
  <Connection>
    <ID>a4105d7e-13eb-49e8-b234-4efcf3e35f39</ID>
    <Persist>true</Persist>
    <Driver>AstoriaAuto</Driver>
    <Server>http://odata.msteched.com/teau12/sessions.svc</Server>
  </Connection>
</Query>

void Main()
{
    var blocks = new [] {
    	new Block("12am", "8:15am"), // For Completeness

    	new Block("8:15am", "9:40am"),
    	new Block("9:45am", "11:00am"),
    	new Block("11:00am", "11:30am"),
    	new Block("11:30am", "12:45pm"),
    	new Block("12:45pm", "1:45pm"),
    	new Block("1:45pm", "3:00pm"),

    	new Block("3:00pm", "3:30pm"),
    	new Block("3:30pm", "4:45pm"),
    	new Block("5pm", "6:15pm"),
    	new Block("6:30pm", "7:45pm"),

    	new Block("7:45pm", "12am") // For completeness
    };

    var schedule = (from s in Sessions.Cache("Sessions").ToList()
    group s by s.Date into g
    orderby g.Key.Value.Date
    select new {
    	Day = g.Key.Value.DayOfWeek,
    	Blocks = (
    		from bl in (from s in g
    					from b in blocks
    					where b.Contains(s.StartTime)
    					select new { s, b })
    		group bl by bl.b into cl
    		orderby cl.Key.Start
    		select new { 
    			Block = cl.Key.ToString(), 
    			Sessions = cl.Select(x => new { 
    										Start = x.s.StartTime.Value, 
    										End = x.s.EndTime.Value,
    										x.s.Room,
    										x.s.Title, 
    										x.s.Abstract
    								}).OrderBy(x => x.Start)
    								  .ThenByDescending(x => x.End)
    								  .ThenBy (x => x.Room) 
    		})
    }).Dump(true);

    foreach(var day in schedule)
    {
    	Console.WriteLine ();
    	Console.WriteLine ();
    	Console.WriteLine ();
    	Console.WriteLine (day.Day);
    	Console.WriteLine ("---------------");

    	foreach(var block in day.Blocks)
    	{
    		Console.WriteLine (block.Block);
    		DateTime prevStart = block.Sessions.First().Start;
    		DateTime prevEnd = block.Sessions.First().End;
    		foreach(var session in block.Sessions)
    		{
    			if(prevStart == session.Start && prevEnd == session.End)
    				Console.WriteLine("{0,19} {2,-20} {1}", "  ", session.Title, session.Room);
    			else
    				Console.WriteLine("{0,9} {1,9} {3,-20} {2}", session.Start.ToShortTimeString(), session.End.ToShortTimeString(), session.Title, session.Room);
    			prevStart = session.Start;
    			prevEnd = session.End;
    		}
    		Console.WriteLine ();
    	}
    }
}

class Block
{
    public Block(string start, string end)
    {
    	Start = DateTime.Parse(start).TimeOfDay;
    	End = DateTime.Parse(end).TimeOfDay;
    }

    public TimeSpan Start { get; set; }
    public TimeSpan End { get; set; }

    public bool Contains(DateTime? dt)
    {
    	if(dt.HasValue == false)
    		return false;
    	return dt.Value.TimeOfDay >= Start && dt.Value.TimeOfDay < End;
    }

    public override string ToString()
    {
    	return DateTime.Today.Add(Start).ToShortTimeString() + " -> " + DateTime.Today.Add(End).ToShortTimeString();
    }
}

The results come out in a grid with the drill-down I wanted. The second part of the script also produces text output that looks like this.

Which I printed and used to start putting a schedule together.

But I'm not going to wander around TechEd with a 16 page printout and I'm not going to bust open my laptop every 75 minutes and run a LINQPad query. What I needed was a web app that I could use from my phone or tablet.

Well, I have the query already and this sounds like a job for jquery.mobile! I've never used jQuery.Mobile before so this was an exciting opportunity to try it out. It was really easy (for what I needed) and the documentation is superb. The code for the resulting site is on http://github.com/wolfbyte/TechEdSessions

Almost there. Last year I hosted my session app on AppHarbor and enjoyed the git-push style deployment model. Well, I have heard that Azure has enabled a similar model now so I thought I'd give that a go. Azure has been one of those technologies that I was aware of but had never actually used so I wanted to see how easy it was.

Wow.

I signed up with a single form (I had to enter credit card details but I start with spending limit of $0 so my stuff will just get shut down if I screw up) for the 3 month free trial. I selected Create New -> Site -> Quick Site. Set the name of my site and BAM! a new site is born.

alt text

In the site I clicked a link that said something like "Enable git deployment". I gave them a username and password (to authenticate against when I push changes) and then the site gave me the exact command line statements I needed to use to push my site.

# make this folder a git repository
git init
# add ALL the files to the working set
git add .
# commit the working set
git commit -m "initial commit"
# add azure as a remote (wolfbyte was the username I picked)
git remote add azure https://wolfbyte@codermike.scm.azurewebsites.net/codermike.git
# PUSH my changes to the master branch of the remote named azure 
git push azure master

When I hit enter on that last command I had to enter my password and then I went back to the Azure panel and noted that the site was being built (I only had one project so I guess they know which one I wanted) and then it was deployed. SUCCESS!

It's here: http://techedau2012.azurewebsites.net

Once the site was up I could verify that it works on my tablet and phone. I then added github as a remote and pushed the code there as well. Having two remotes is a great thing.

Now the only thing left to do is to figure out which sessions to go to. Judging from this experience I think I may spend a lot of time in the Azure track soaking up the awesome-ness. What are you looking forward to? And if you see a tubby wookie wandering around the expo floor, come and say hi!

Posted by: Mike Minutillo
Last revised: 01 Sep, 2012 03:58 AM History

Comments

No comments yet. Be the first!

No new comments are allowed on this post.