$(document).ready(function() {
    // A mapping of fedmsg topic fragments to DOM elements.
    var selectors = {
        'appliance': '#appliance',
        'livecd': '#livecd',
    }

    var get_msg = function(artifact, callback) {
        var data = $.param({
            'delta': 3600000,
            'rows_per_page': 100,
            'order': 'desc',
            'meta': 'link',
            'user': 'masher',
        });
        $.ajax({
            url: "https://apps.fedoraproject.org/datagrepper/raw/",
            data: data,
            dataType: "jsonp",
            success: function(data) {
                callback(data, artifact);
            },
            error: function(data, statusCode) {
                console.log("Status code: " + statusCode);
                console.log(data);
                console.log(data.responseText);
                console.log(data.status);
            }
        });
    }
    var hollaback = function(data, artifact) {
        var selector_prefix = selectors[artifact];
        var seen = [];
        $.each(data.raw_messages, function(i, msg) {
            // We only want artifacts, not other people's scratch builds.
            if (msg.msg.method != artifact) {
                return;
            }

            var tokens = msg.msg.srpm.split('-');
            var arch = tokens[tokens.length - 1];

            // Some of the appliance builds come in different formats.
            // Here we mangle the "srpm" name so that we can distinguish them.
            // Not all tasks have this info, so we have to proceed carefully.
            var info = msg.msg['info'];
            if (info != undefined) {
                var options = info.request[info.request.length - 1];
                if (options.format != undefined) {
                    msg.msg.srpm = msg.msg.srpm + " (" + options.format + ")";
                }
            }

            // We only want to process srpms once.  Have seen already?
            if ($.inArray(msg.msg.srpm, seen) != -1) {
                // Bail out
                return;
            } else {
                // Throw it in the array so we'll see it next time.
                seen.push(msg.msg.srpm);
            }

            var selector = selector_prefix + "-" + arch;
            var class_lookup = {
                'CLOSED': 'text-primary',
                'FAILED': 'text-danger',
                'OPEN': 'text-warning',
            }
            var text_lookup = {
                'CLOSED': 'completed',
                'FAILED': 'failed',
                'OPEN': 'started',
            }
            var now = moment();
            var one_day_ago = now.subtract('hours', 24);
            var time = moment(msg.timestamp.toString(), '%X');
            var cls = class_lookup[msg.msg.new];
            if (time.isBefore(one_day_ago)) {
                // Because it is old and stale.
                cls = 'text-muted';
            }
            $(selector).append(
                "<p class='" + cls + "'>" +
                msg.msg.srpm + " " +
                "</br>" +
                "<small>" +
                text_lookup[msg.msg.new] +" " +
                time.fromNow() + " " +
                "</small> " +
                "<strong><a href='" + msg.meta.link + "'>(details)</a></strong>" +
                "</p>"
            );
        });
    }

    // Kick off our on page load initialization.
    $.each(selectors, function(name, selector) {
        get_msg(name, hollaback);
    })
});

@@ -1880,32 +1880,1373 @@
 %0A            %7D%0A%0A
+            // If possible, construct a direct download link to the product of%0A            // the livecd or appliance build.  This is pretty ugly.%0A            var children = info%5B'children'%5D;%0A            var SRPM = msg.msg.srpm;%0A            if (msg.msg.new == 'CLOSED' && children != undefined && children.length == 1) %7B%0A                var id = children%5B0%5D%5B'id'%5D;%0A                var result = info%5B'result'%5D.split(%22 %22);%0A                result = result%5Bresult.length - 1%5D;%0A                tokens = result.split('/');%0A                var thing = tokens%5B5%5D;%0A%0A                var r = info%5B'request'%5D;%0A                var opts = r%5B5%5D;%0A%0A                var file = r%5B0%5D + %22-%22 + r%5B1%5D + %22-%22 + opts%5B'release'%5D;%0A%0A                if (opts%5B'format'%5D === undefined) %7B%0A                    file = file + %22.iso%22;%0A                %7D else if (opts%5B'format'%5D == 'qcow2') %7B%0A                    file = file + %22-sda.qcow2%22;%0A                %7D else if (opts%5B'format'%5D == 'raw') %7B%0A                    file = file + %22-sda.raw.xz%22;%0A                %7D%0A%0A                var base = %22http://kojipkgs.fedoraproject.org/work/tasks/%22;%0A%0A                var download_link = base + thing + %22/%22 + id + %22/%22 + file;%0A                %224886/6714886/Fedora-Live-LXDE-x86_64-rawhide-20140407.iso%22%0A%0A                SRPM = %22%3Ca href='%22 + download_link + %22'%3E%22 + SRPM + %22%3C/a%3E%22;%0A            %7D%0A%0A
             // W
@@ -3300,16 +3300,16 @@
 lready?%0A
-
         
@@ -4272,32 +4272,33 @@
 ;%0A            %7D%0A
+%0A
             $(se
@@ -4373,28 +4373,20 @@
         
-msg.msg.srpm
+SRPM
  + %22 %22 +

Add a direct download link for livecd and appliance.