Combining Stack Overflow RSS, OData and API to query

In my opinion Stack Overflow has a ton of knowledge to learn new tricks. And there are some really smart people in the SO community. I try and learn new things when I find time.

I subscribe to RSS feeds for new questions on a particular topic. Example, here is one for F# from Stack Overflow http://stackoverflow.com/feeds/tag/f%23. The advantage of the RSS feed is I get to see new questions, but the drawback is I would have to navigate to the site to look for answers. AFAIK the stacky (stack overflow API) does not provide a mechanism for querying new questions based on a tag.

It was easy for me to combine both of them to solve my problem. With RSS feed I could discover new questions and with the stacky I could get answers . And I use Linqpad as a scratchpad so it was easy to write-up something quick.


void Main()
{
 var reader = XmlReader.Create("http://stackoverflow.com/feeds/tag/f%23");
 var feed = SyndicationFeed.Load<SyndicationFeed>(reader);
 var length = "http://stackoverflow.com/questions/".Length;

 var client = new StackyClient("1.0", File.ReadAllText(@"c:tempso.txt"),HostSite.StackOverflow,new UrlClient(), new JsonProtocol());

 var feedItems = from item in feed.Items
                 let nextOccurence = item.Id.ToString().IndexOf("/",length)
                 let getId = new Func<int>(() => Convert.ToInt32( item.Id.Substring(length,nextOccurence - length)))
                 select new {Id = getId(), Title = item.Title.Text, Body = item.Summary.Text.StripHTML()};

 var answers = client.GetQuestionAnswers(feedItems.Select (y => y.Id),new AnswerOptions() { IncludeBody = true});

 // The latest F# feed questions and answers
 var qa = from question in feedItems
          join answer in answers on question.Id equals answer.QuestionId
          where answer.Accepted == true
          select new { Title = question.Title, Question = question.Body.StripHTML(), Answer = answer.Body.StripHTML()};
 qa.Dump();
}
public static class Extensions
{
      public static string StripHTML(this string s)
      {
         return Regex.Replace(s, @"<(.|n)*?>", string.Empty);
      }
}

And if you have been following F# and functional programming then you would probably know Tomas. I would also like to read what he has been answering. Again stacky does not provide an API to query user by name. This is where the SO OData comes in handy and LinqPad handles OData very well. Here is the code to get Tomas user id via OData and query for questions and answers which he has answered using stacky .

var tomas = Users.Where(u => u.DisplayName.StartsWith("Tomas Pet")).First().Id;
var tomasQA = from ans in  client.GetUsersAnswers(tomas,new AnswerOptions() { IncludeBody = true })
              select new { Title = ans.Title, Question = client.GetQuestion(ans.QuestionId,true,false).Body.StripHTML(),
              Answer = ans.Body.StripHTML()};
tomasQA.Dump();
 

Using Tech-Ed OData to download videos

I wanted to watch the Teched 2010 videos, but the problem I had was going to the site manually to download files for offline viewing.  And I was also interested only in Dev sessions which were level 300 / 400. Thanks to OData for teched http://odata.msteched.com/sessions.svc/ ,I  could write 3 statements in linqpad and had them all downloaded using wget

File.Delete(@"C:tempdownload.txt");

Sessions
.Where (s => (s.Level.StartsWith("400") ||  s.Level.StartsWith("300") ) && s.Code.StartsWith("DEV"))
.Take(10)
.ToList()
.Select (s => @"http://ecn.channel9.msdn.com/o9/te/NorthAmerica/2010/mp4/" + s.Code + ".mp4" )
.Run(s => File.AppendAllText(@"C:tempdownload.txt",s + Environment.NewLine));

Util.Cmd(@"wget.exe -b -i c:Tempdownload.txt",true);

Forgot to mention for the Run extension method is from Reactive Extensions