Paulo Morgado

.NET Development & Architecture

Recent Articles

view all

Events

Projects

Recent Readers

Visitor Locations

Visitor Locations

Disclaimer

The opinions and viewpoints expressed in this site are mine and do not necessarily reflect those of Microsoft, my employer or any community that I belong to. Any code or opinions are offered as is. Products or services mentioned are purchased by me, made available to me by my employer or the manufacturer/vendor which doesn't influence my opinion in any way.

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

No Comments

Leave a Comment

(required) 

(required) 

(optional)

(required)