Skip to main content

S.A. Architect's new website

Coming this weekend is the S.A. Architect website! So I thought I would drop a quick teaser to explain all the good new features, the bad of the change and the pretty.

The Good

  • The new site allows members to register without admin intervention.
  • Ability to use Google Analytics for the states.
  • We can offer blogs to members very easily now.
  • Users can use the traditional username & password or OpenId for authentication.
  • Proper event management system – We can now create an event and have invites sent out, lists of who is coming, how many they are brining etc...
  • Printing support on every page.
  • Automatic Google group registration – so when someone signs up to the site they join the Google group too (new members can untick that option).
  • Looks great in all browsers, no more browser specific options.

The Bad

  • Every user needs to be migrated, so this weekend all users will be moved and their passwords reset. So you will get an email from the system with the new password. 

The Pretty

Below is a sneak peak at what to expect:

Clipboard01

Some flair!

In the last week I decided to add some flair to my site, as I am spending a lot of time in various communities be they online, like StackOverflow, or offline, like InformationWorker - so I wanted to add flair for those communities to my website.

Clipboard01

However the problem is that I’m in a lot of them and don’t want a page that just scrolls and scrolls so I decided to make a rotating flair block, i.e. it shows a piece of flair for a few seconds and then rotates to another one. Thankfully I already have jQuery setup on my site so this was fairly easy. One thing that caused some headache was getting away from the idea of having a loop, where I’d show one flair then wait then hide it and show the next one. This is a very bad idea because it means that it runs forever which is what I want - but not an endless loop because browsers will detect that and stop the script. Also from a performance point of view JavaScript in a loop tends to make a browser run slowly.

Clipboard01

The solution is to use events and kick them off in a staggered fashion - thankfully JavaScript natively has a function for that: setTimeout which takes a string which it will execute and an integer which is the milliseconds delay to wait for. Then on it’s turn show it, wait (using setTimeout again), then hide it and lastly wait again to show it. Because that cycle is the same for each item the staggering ensures that they do not overlap and you get a nice, smooth flowing and non-loop loop :)

Clipboard012

The technical bits

My HTML is made up of a lot of divs - each one for a flair:

<div class="flair-badge">
    <div class="flair-title">
        <a class="flair-title" href="http://www.stackoverflow.com">StackOverflow.com</a></div>
    <iframe src="http://stackoverflow.com/users/flair/53236.html" marginwidth="0" marginheight="0" frameborder="0" scrolling="no" width="210px" height="60px"></iframe>
</div>

A dash of CSS for the styling, most importantly hiding all of them initially.

And the JavaScript:

var interval = 5000;

$(document).ready(function() {
    var badges = $(".flair-badge").length;
    var counter = 0;
    for (var counter = 0; counter<badges; counter++) {
        setTimeout('BadgeRotate(' + counter + ',' + badges + ')', counter * interval);
    }
});

function BadgeRotate(badge, badgeCount) {
    $(".flair-badge:nth(" + badge + ")").fadeIn("slow");
    setTimeout('BadgeRotateEnd(' + badge + ',' + badgeCount + ')', interval);
}

function BadgeRotateEnd(badge, badgeCount) {
    $(".flair-badge:nth(" + badge + ")").hide();
    setTimeout('BadgeRotate(' + badge + ',' + badgeCount + ')', (badgeCount * interval) - interval);
}

Reading and writing to Excel 2007 or Excel 2010 from C# - Part III: Shared Strings

[Note: See the series index for a list of all parts in this series.]

Clipboard08

Excel’s file format is an interesting one compared to the rest of the Office Suite in that it can store data in two places where most others store the data in a single place. The reason Excel supports this is for good performance while keeping the size of the file small. To illustrate the scenario lets pretend we had a single sheet with some info in it:

Clipboard02

Now for each cell we need to process the value and the total size would be 32 characters of data. However with a shared strings model we get something that looks like this:

Clipboard03

The result is the same however we are processing values once and the size is less, in this example 24 characters.

The Excel format is pliable, in that it will let you do either way. Note the Excel client will always use the shared strings method, so for reading you should support it. This brings up an interesting scenario, say you are filling a spreadsheet using direct input and then you open it in Excel, what happens? Well Excel identifies the structure, remaps it automatically and then when the user wishes to close (regardless if they have made a change or not) will prompt them to save the file.

The element we loaded at the end of part 2 is that shared strings file, which in the archive is \xl\sharedstrings.xml. If we look at it, it looks something similar to this:



  
    Some
  
  
    Data
  
  
    Belongs
  
  
    Here
  
Each <t> node is a value and it corresponds to a value in the sheet which we will parse later. The sheet will have a value in it, which is the key to the item in the share string. The key is an zero based index. So in the above example the first <t> node (Some) will be stored as 0, the second (Data) will be 1 and so on. The code to parse it which I wrote looks like this:
private static void ParseSharedStrings(XElement SharedStringsElement, Dictionary<int, string>sharedStrings)
{
    IEnumerable<XElement> sharedStringsElements = from s in SharedStringsElement.Descendants(ExcelNamespaces.excelNamespace + "t")
                                                  select s;

    int Counter = 0;
    foreach (XElement sharedString in sharedStringsElements)
    {
        sharedStrings.Add(Counter, sharedString.Value);
        Counter++;
    }
}

Using this I am parsing the node and putting the results into a Dictionary<int,string>.

Reading and Writing to Excel 2007 or Excel 2010 from C# - Part II: Basics

[Note: See the series index for a list of all parts in this series.]

image

To get support for the technologies we will use in this we need to add a few assembly references to our solution:

  • WindowsBase.dll
  • System.Xml
  • System.Xml.Linq
  • System.Core

Next make sure you have the following namespaces added to your using/imports:

  • System.IO.Packaging: This provides the functionality to open the files.
  • System.Xml
  • System.Xml.Linq
  • System.Linq
  • System.IO

Right next there is a XML namespace (not to be confused with .NET code name spaces) we need to use for most of our queries: http://schemas.openxmlformats.org/spreadsheetml/2006/main and there is a second one we will use seldom http://schemas.openxmlformats.org/officeDocument/2006/relationships. So I dumped this into a nice static class as follows:

namespace XlsxWriter
{
    using System.Xml.Linq;

    internal static class ExcelNamespaces
    {
        internal static XNamespace excelNamespace = XNamespace.Get("http://schemas.openxmlformats.org/spreadsheetml/2006/main");
        internal static XNamespace excelRelationshipsNamepace = XNamespace.Get("http://schemas.openxmlformats.org/officeDocument/2006/relationships");
    }
}

Next we need to create an instance of the System.IO.Packaging.Package class (from WindowsBase.dll) and instantiate it by calling the static method Open.

 Package xlsxPackage = Package.Open(fileName, FileMode.Open, FileAccess.ReadWrite);

Note: It is at this point that the file is opened, this is important since Excel will LOCK an open file. This is an important issue to be aware of because when you open a file that is locked a lovely exception is thrown. To correct that you must make sure to call the close method on the package, for example:

xlsxPackage.Close();

When you open the XLSX file manually, the first file you’ll see is the [Content_Types].xml file which is a manifest of all the files in the ZIP archive. What is nice with using Packaging is that you can call the GetParts method to get a collection of Parts, which are actually just the files within the XLSX file.

image
The contents of the XLSX if renamed to a ZIP file and opened.
image
The various files listed in the [Content_Types].xml file.

What we will use during this is the ContentType parameter to filter the parts to the specific item we want to work with. The second image above to identify the value for the ContentType. For example the ContentType for a worksheet is: application/vnd.openxmlformats-officedocument.speadsheetml.worksheet+xml.

Once we have all the parts of the XLSX file we can navigate through it to get the bits we need to read the content, which involves two steps:

  1. Finding the shared strings part. This is another XML file which allows for strings of values to shared between worksheets. This is optional for writing, to use but does save space and speed up loading. For reading values it is required as Excel will use it.
  2. Finding the worksheet that we want to read from, this is a separate part from the shared strings.

Lets start with reading the shared strings part, this will be basis for reading any part later in series. What we need to do is get the first PackagePart with the type: application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml

PackagePart sharedStringsPart = (from part in allParts
    where part.ContentType.Equals("application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml")
    select part).Single();

Now we need to get the XML content out of the PackagePart, which is easy with the GetStream method, which we load into an XmlReader so that it can be loaded into a XElement. This is a bit convoluted but it is just one line to get it from one type to another and the benefits of using LINQ to XML are worth it:

XElement sharedStringsElement = XElement.Load(XmlReader.Create(sharedStringsPart.GetStream()));

Now we have the ability to work with the XElement and do some real work. In the next parts, we’ll look at what we can do with it and how to get from a single part to an actual sheet.

Gallery2 + C# - Beta 2 Available

A few weeks back I posted beta 2 of the gallery 2 .net toolkit where I have done considerable more work on it than I ever expected I would. Lots of need bits of code and features available. What’s in it now:

There are four items currently available:

  • (Tool) For people just wanting to export all their images out of Gallery2, there is g2Export which is a command line tool to export images.
  • (Tool) For people wanting to get information out of Gallery2 into a sane format, there is g2 Album Management which is an Excel 2007 add-in to export information about albums and images to Excel.
  • (API) For developers wanting to write their own tools or integrations, there is the SADev.Gallery2.Protocol which wraps the Gallery2 remote API. Please see the What you should know? page for information on using the API.
  • (Source) Lastly for developers needing some help, there is the source code for the the g2 Export Tool and the g2 Album Management Excel Add-in
Here is a screen shot of g2 Album Management in action:

Here is a screen shot of g2Export in action:

If you are interested in how much of the Gallery2 API is catered for, it’s most of it (the file upload parts are the only major outstanding ones). The key thing to note on the table is the tested column. While the code is written, it may not be tested and may not work at all. I have found the documentation is not 100% in line with the actual gallery2 code so something it needs considerable rework for it to actually work.

API Call Basic Request Basic Response Tested Advanced Request Advanced Response
login done done done done done
fetch-albums done done done done done
fetch-albums-prune done done done done done
add-item (upload)   done     done
add-item (url) done done   done done
album-properties done done done done done
new-album done done   done done
fetch-album-images done done done done done
move-album done done   done done
increment-view-count done done   done done
image-properties done done done done done
no-op done done done done done

Proven Source Control Practises Poster

Proven Practises Poster

Maybe one of the toughest things in software development to get right all the time: source control. Well now with this nice bright A3 poster printed on your wall (or maybe above the monitor of the guy who breaks the builds daily) you’ll never go wrong again.

It covers 17 proven practises broken into 5 key areas:

Things YOU should do

  • Keep up to date
  • Be light and quick with checkouts
  • Don’t check in unneeded binaries
  • Working folders should be disposable
  • Use undo/revert sparingly

Branching

  • Plan your branching
  • Own the merge
  • Look after branches

Management

  • Useful & meaningful check in messages
  • Don’t use the audit trial for blame

Repository

  • Don’t break the build
  • Separate your repo
  • Don’t forget to shelve
  • Use labels

Technology

  • Try concurrent access
  • Don’t be afraid of branching concepts
  • Automerge for checkout only

    Outlook 101 Poster

    poster

    I created this poster (A3 in size) which covers the 8 key areas of Outlook

    • Email
    • Contacts
    • Outlook Web Access
    • SharePoint Integration
    • Calendar
    • Tasks
    • Misc Outlook Features, like out of office assistant and inline preview
    • RSS

    The poster also has three areas where you can write key information that will be specific for your organisation like mailbox size limit, SharePoint & OWA URL’s.

    Direct Download

    More posters at www.drp.co.za

    Gallery2 + C#

    Gallery2 is a web based PHP gallery system with a remote API for doing many things. I have been using it for a while, but have decided to change and so I wanted to export my images, which is harder than it sounds. To actually get this done I ended up writing a basic wrapper for the Gallery2 remote API and implementing a small console application to do the export.

    If you are interested in the wrapper or the tool itself, I have setup a CodePlex project for it where you can download those: http://gallery2.codeplex.com/

    The reason it is there, is because I have decided to open source it because it is useful to people besides me and I have gotten what I need from it, so I doubt I’ll spend much time getting it feature complete. This way someone else can get the tool (if that is all they need) or get the source and add to it.

    FileDownload[1]

    Screen shot of the tool running.

    Some new presentations

    I’ve been presenting up a storm recently: mostly because I have been on a presentation skills course ;) where I learnt a lot of the soft skills about how to be a better presenter. For that course I had to present with slides on something I knew about, so I choose LINQ. You can watch me do my presentation (it’s a mere 7min) or grab a copy of the slides.

     

    After all that was done I have been presenting on the joys of jQuery recently, and rather than actually bore the audience with slides and constant switching to demos I decided to build a presentation system in jQuery which did both the slides and demos. Which you can view below. A few notes on it, to move to the next slide you need to click the globes at the top or press = and pressing - will make you move back a slide. You can also press the print button in the top section to give you a single page print view (i.e. stripped of colours & with my slide notes). What is great is that the entire thing is a single html page and about 100 lines of JavaScript for the slideshow system. Click the thumb nail below to view it:

    image