MIX09 Session Videos – How I Did It

On my last post I introduced the feeds I created to subscribe to Mix09 session videos.

In case someone is interested on how I did it, here it is:

<%@ WebHandler Language="C#" Class="mix09" %>

using System;
using System.IO;
using System.Web;
using System.Linq;
using System.Xml.Linq;
using System.Net;
using System.Xml;

public class mix09 : IHttpHandler, IHttpAsyncHandler
{
    class WebClientOpenReadAsyncResult : IAsyncResult
    {
        private AsyncCallback callback;

        public WebClientOpenReadAsyncResult()
        {
            this.IsCompleted = true;
            this.CompletedSynchronously = true;
        }

        public WebClientOpenReadAsyncResult(AsyncCallback callback)
        {
            this.callback = callback;
            this.IsCompleted = false;
            this.CompletedSynchronously = false;
        }

        public object AsyncState
        {
            get { return null; }
        }

        public bool CompletedSynchronously { get; private set; }

        public System.Threading.WaitHandle AsyncWaitHandle
        {
            get { throw new InvalidOperationException("ASP.NET should not use this property ."); }
        }

        public bool IsCompleted { get; private set; }

        public Stream Stream { get; private set; }

        public void Completed(object sender, OpenReadCompletedEventArgs e)
        {
            this.IsCompleted = true;
            this.Stream = e.Result;
            if (this.callback != null)
            {
                this.callback(this);
            }
        }

    }

    private static Uri mixSessionsUri = new Uri("http://sessions.visitmix.com/RSS");

    private HttpContext context;

    private string type;

    #region IHttpHandler Members

    public bool IsReusable
    {
        get { return true; }
    }

    public void ProcessRequest(HttpContext context)
    {
        WebClient wc = InitializeRequest(context);

        if (wc == null)
        {
            return;
        }

        OutputFeed(wc.OpenRead(mixSessionsUri));
    }

    #endregion

    #region IHttpAsyncHandler Members

    public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
    {
        WebClient wc = InitializeRequest(context);

        if (wc == null)
        {
            return new WebClientOpenReadAsyncResult();
        }

        WebClientOpenReadAsyncResult ar = new WebClientOpenReadAsyncResult(cb);

        wc.OpenReadCompleted += ar.Completed;

        wc.OpenReadAsync(mixSessionsUri, extraData);

        return ar;
    }

    public void EndProcessRequest(IAsyncResult result)
    {
        Stream stream = (result as WebClientOpenReadAsyncResult).Stream;

        if (stream != null)
        {
            OutputFeed(stream);
        }
    }

    #endregion

    private WebClient InitializeRequest(HttpContext context)
    {
        this.context = context;
        this.type = context.Request.QueryString["type"];

        if (string.IsNullOrEmpty(this.type))
        {
            return null;
        }

        WebClient wc = new WebClient();
        wc.Headers[HttpRequestHeader.UserAgent] = "Required User Agent";
        return wc;
    }

    private void OutputFeed(Stream source)
    {
        XmlReader feedReader = XmlReader.Create(source);

        XDocument feed = XDocument.Load(feedReader);

        var rss = feed.Element("rss");
        var channel = rss.Element("channel");
        var title = channel.Element("title");

        title.Value = string.Format("{0} ({1})", title.Value, this.type.ToUpper());
        channel.Element("link").Value = "http://cli.gs/Mix09Sessions";

        foreach (var item in channel.Elements("item"))
        {
            string link = item.Element("link").Value;
            string session = link.Substring(link.LastIndexOf('/') + 1).ToLower();
            string enclosureUrl = string.Format("http://mschannel9.vo.msecnd.net/o9/mix/09/{0}/{1}.wmv", this.type.ToLower(), session);

            item.Add(
                new XElement("enclosure",
                    new XAttribute("url", enclosureUrl)));
        }

        this.context.Response.Write(feed.ToString());

        this.context.Response.ContentType = "application/rss+xml";

        HttpCachePolicy cache = this.context.Response.Cache;
        cache.SetCacheability(HttpCacheability.ServerAndPrivate);
        cache.SetExpires(DateTime.Now.AddHours(1));
        cache.VaryByParams["type"] = true;
        cache.SetValidUntilExpires(true);
    }
}

Comments are closed.