<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>DevHawk</title><link>http://devhawk.net/</link><description>Passion * Technology * Ruthless Competence</description><language>en-us</language><copyright>Harry Pierson</copyright><managingEditor>harry@devhawk.net</managingEditor><lastBuildDate>Thu, 08 Jan 2009 13:19:00 -0600</lastBuildDate><generator>newtelligence dasBlog 2.0.7226.0</generator><geo:lat>47.640972</geo:lat><geo:long>-122.033189</geo:long><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/Devhawk" type="application/rss+xml" /><feedburner:browserFriendly>(Enter a personal message you would like to have appear at the top of your feed.)</feedburner:browserFriendly><item><title>Kid Programming with Kodu Coming to Xbox 360</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/506472836/Kid+Programming+With+Kodu+Coming+To+Xbox+360.aspx</link><category>Development</category><category>Kodu</category><category>Xbox 360</category><category>XNA</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Harry Pierson</dc:creator><pubDate>Thu, 08 Jan 2009 13:19:00 -0600</pubDate><guid isPermaLink="false">http://devhawk.net/PermaLink,guid,3c48c67a-69ef-43d3-a7fd-05b5fe2f8ce5.aspx</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
        <p>
As I’ve <a href="http://devhawk.net/2005/07/06/The+Inform+Language.aspx">written before</a>,
I originally got the programming bug from a desire to build my own text adventure
games. with significant influence from <a href="http://cid-885df99f8fd01cd9.profile.live.com/">my
dad</a>. Now that I’m a father myself, I want my kids to have a similar opportunity,
even if they never choose to go into the “family business”. 
</p>
        <p>
          <a href="http://research.microsoft.com/en-us/projects/kodu/default.aspx">
            <img title="kodu_guy" style="border-right: 0px; border-top: 0px; display: inline; margin-left: 0px; border-left: 0px; margin-right: 0px; border-bottom: 0px" height="121" alt="kodu_guy" src="http://devhawk.net/content/binary/WindowsLiveWriter/KidProgrammingwithKoduComingtoXbox360_9F23/kodu_guy_5.jpg" width="96" align="left" border="0"></img>
          </a> Of
course, the technology has moved on significantly since the days of “You are in a
maze of twisty little passages, all alike”. At CES yesterday, Microsoft <a href="http://www.xbox.com/en-US/community/news/2009/0107-kodu.htm">announced</a> Kodu
which I’ve <a href="http://devhawk.net/2007/03/08/Morning+Coffee+41+TechFest+Edition.aspx">written
about before</a> under it’s original name Boku. Kodu came out of <a href="http://research.microsoft.com/en-us/projects/kodu/default.aspx">Microsoft
Research</a> as a tool for teaching kids how to program. The programming language
is very visual and iconic and you use the Xbox controller exclusively for all input.
Here’s a screenshot:
</p>
        <p>
          <img style="display: block; float: none; margin-left: auto; margin-right: auto" src="http://research.microsoft.com/en-us/projects/kodu/programming_ui.jpg"></img>
        </p>
        <p>
To demo Kodu at CES, Robbie Bach brought a 12 year old girl named Sparrow up on stage
to demo. I showed the video to my kids this morning and they went gaga for it. They’re
a little young - Patrick turns 6 next month and Riley turns 4 later this year – but
I think they’ll be able to get the hang of it (with a little help from dad). Below
is the video of the CES demo, and there are more Kodu videos at On10 (<a href="http://on10.net/blogs/larry/CES-2009-Matthew-MacLaurin-on-Kodu/">Matthew
MacLaurin on Kodu</a> and <a href="http://on10.net/blogs/larry/CES-2009-Watch-Kodu-in-Action/">Watch
Kodu in Action</a>).
</p>
        <iframe align="center" src="http://www.microsoft.com/presspass/silverlightApps/videoplayer2/standalone.aspx?contentId=keynoteClip5&amp;src=/presspass/events/ces/channel.xml&amp;WT.cg_n=CES&amp;WT.z_convert=embed" frameborder="0" width="400" scrolling="no" height="335">
        </iframe>
        <p>
Personally, I think this is brilliant. I have been eagerly waiting a change to play
this with my kids for over a year, so I’m very excited that they’re bringing this
to market. Seriously, <a href="http://www.xbox.com/games/halowars/">Halo Wars</a> just
got bumped to the #2 slot on my “Most Anticipated Xbox Games of 2009” list. 
</p>
        <p>
I’m most interested in how these creations will be shared online. I couldn’t find
any details, but Robbie <a href="http://www.microsoft.com/presspass/exec/steve/2009/01-07ces.mspx">specifically
said</a> “And on Xbox Live they can distribute and share those finished games with
other people.” Will there be a charge? (“normal” Community Games <a href="http://creators.xna.com/en-US/faq#anchor_2_5">cost</a> between
$2.50 and $10 a pop) How will <a href="http://creators.xna.com/en-US/faq#anchor_1_12">parental
controls</a> affect shared Kodu games? I guess those details will come closer to release.
</p>
        <img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=3c48c67a-69ef-43d3-a7fd-05b5fe2f8ce5"></img>
      <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Devhawk?a=YlzDOc.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=YlzDOc.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=fxAQTh.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=fxAQTh.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=Kgpr8t.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=Kgpr8t.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=rnfpHX.p"><img src="http://feeds.feedburner.com/~f/Devhawk?i=rnfpHX.p" border="0"></img></a>
</div>]]></content:encoded><description>&lt;p&gt;
As I’ve &lt;a href="http://devhawk.net/2005/07/06/The+Inform+Language.aspx"&gt;written before&lt;/a&gt;,
I originally got the programming bug from a desire to build my own text adventure
games. with significant influence from &lt;a href="http://cid-885df99f8fd01cd9.profile.live.com/"&gt;my
dad&lt;/a&gt;. Now that I’m a father myself, I want my kids to have a similar opportunity,
even if they never choose to go into the “family business”. 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://research.microsoft.com/en-us/projects/kodu/default.aspx"&gt;&lt;img title="kodu_guy" style="border-right: 0px; border-top: 0px; display: inline; margin-left: 0px; border-left: 0px; margin-right: 0px; border-bottom: 0px" height="121" alt="kodu_guy" src="http://devhawk.net/content/binary/WindowsLiveWriter/KidProgrammingwithKoduComingtoXbox360_9F23/kodu_guy_5.jpg" width="96" align="left" border="0" /&gt;&lt;/a&gt; Of
course, the technology has moved on significantly since the days of “You are in a
maze of twisty little passages, all alike”. At CES yesterday, Microsoft &lt;a href="http://www.xbox.com/en-US/community/news/2009/0107-kodu.htm"&gt;announced&lt;/a&gt; Kodu
which I’ve &lt;a href="http://devhawk.net/2007/03/08/Morning+Coffee+41+TechFest+Edition.aspx"&gt;written
about before&lt;/a&gt; under it’s original name Boku. Kodu came out of &lt;a href="http://research.microsoft.com/en-us/projects/kodu/default.aspx"&gt;Microsoft
Research&lt;/a&gt; as a tool for teaching kids how to program. The programming language
is very visual and iconic and you use the Xbox controller exclusively for all input.
Here’s a screenshot:
&lt;/p&gt;
&lt;p&gt;
&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto" src="http://research.microsoft.com/en-us/projects/kodu/programming_ui.jpg" /&gt;
&lt;/p&gt;
&lt;p&gt;
To demo Kodu at CES, Robbie Bach brought a 12 year old girl named Sparrow up on stage
to demo. I showed the video to my kids this morning and they went gaga for it. They’re
a little young - Patrick turns 6 next month and Riley turns 4 later this year – but
I think they’ll be able to get the hang of it (with a little help from dad). Below
is the video of the CES demo, and there are more Kodu videos at On10 (&lt;a href="http://on10.net/blogs/larry/CES-2009-Matthew-MacLaurin-on-Kodu/"&gt;Matthew
MacLaurin on Kodu&lt;/a&gt; and &lt;a href="http://on10.net/blogs/larry/CES-2009-Watch-Kodu-in-Action/"&gt;Watch
Kodu in Action&lt;/a&gt;).
&lt;/p&gt;
&lt;iframe align="center" src="http://www.microsoft.com/presspass/silverlightApps/videoplayer2/standalone.aspx?contentId=keynoteClip5&amp;amp;src=/presspass/events/ces/channel.xml&amp;amp;WT.cg_n=CES&amp;amp;WT.z_convert=embed" frameborder="0" width="400" scrolling="no" height="335"&gt;
&lt;/iframe&gt;
&lt;p&gt;
Personally, I think this is brilliant. I have been eagerly waiting a change to play
this with my kids for over a year, so I’m very excited that they’re bringing this
to market. Seriously, &lt;a href="http://www.xbox.com/games/halowars/"&gt;Halo Wars&lt;/a&gt; just
got bumped to the #2 slot on my “Most Anticipated Xbox Games of 2009” list. 
&lt;/p&gt;
&lt;p&gt;
I’m most interested in how these creations will be shared online. I couldn’t find
any details, but Robbie &lt;a href="http://www.microsoft.com/presspass/exec/steve/2009/01-07ces.mspx"&gt;specifically
said&lt;/a&gt; “And on Xbox Live they can distribute and share those finished games with
other people.” Will there be a charge? (“normal” Community Games &lt;a href="http://creators.xna.com/en-US/faq#anchor_2_5"&gt;cost&lt;/a&gt; between
$2.50 and $10 a pop) How will &lt;a href="http://creators.xna.com/en-US/faq#anchor_1_12"&gt;parental
controls&lt;/a&gt; affect shared Kodu games? I guess those details will come closer to release.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=3c48c67a-69ef-43d3-a7fd-05b5fe2f8ce5" /&gt;</description><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://devhawk.net/Trackback.aspx?guid=3c48c67a-69ef-43d3-a7fd-05b5fe2f8ce5</trackback:ping><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/pingback.aspx</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/PermaLink,guid,3c48c67a-69ef-43d3-a7fd-05b5fe2f8ce5.aspx</pingback:target><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/CommentView,guid,3c48c67a-69ef-43d3-a7fd-05b5fe2f8ce5.aspx</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/SyndicationService.asmx/GetEntryCommentsRss?guid=3c48c67a-69ef-43d3-a7fd-05b5fe2f8ce5</wfw:commentRss><feedburner:origLink>http://devhawk.net/2009/01/08/Kid+Programming+With+Kodu+Coming+To+Xbox+360.aspx</feedburner:origLink></item><item><title>Nightly Builds Technical Info</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/505685361/Nightly+Builds+Technical+Info.aspx</link><category>Azure</category><category>IronPython</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Harry Pierson</dc:creator><pubDate>Wed, 07 Jan 2009 17:23:26 -0600</pubDate><guid isPermaLink="false">http://devhawk.net/PermaLink,guid,9ecbf637-0b38-475e-90ad-33af18381878.aspx</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
        <p>
Here are some technical details on my <a href="http://devhawk.net/2009/01/07/IronPython+Nightly+Builds.aspx">Nightly
Builds solution</a>. I broke them into a separate post because I figured most people
are more interested in the actual service than how it’s built.
</p>
        <p>
As you might expect, I built most of the solution in IronPython. All of the download,
build, compress and Azure upload code was written in IPy. The one part I didn’t write
in IPy was the Azure cloud web app, which I wrote in C#. Jon Udell’s been investigating <a href="http://blog.jonudell.net/2008/12/22/azure-calendar-aggregator-part-1/">getting
IPy to run in Azure</a>, but I just wanted something quick and dirty (as you can see
from the <a href="http://nightlybuilds.cloudapp.net/">utter lack of formatting</a>)
so I decided to use C# instead. Man, were my ASP.NET skills rusty.
</p>
        <p>
As for the IronPython parts, for the most part I’m using external tools for downloading,
building and compressing. I use the <a href="http://www.codeplex.com/IronPython/Project/ProjectRss.aspx?ProjectRSSFeed=codeplex%3a%2f%2fsourcecontrol%2fIronPython">Source
Control RSS Feed</a> to discover recent source code changesets, <a href="http://www.codeplex.com/CodePlexClient">CodePlex
Client</a> to download source from CodePlex, <a href="http://msdn.microsoft.com/en-us/library/wea2sca5.aspx">MSBuild</a> to
build the binaries, <a href="http://www.7-zip.org/">7-zip</a> to compress the binaries
and the <a href="http://msdn.microsoft.com/en-us/library/dd135716.aspx">StorageClient
library sample</a> to upload the compressed binaries up to Azure blob storage. 
</p>
        <p>
For building and compressing, I’m literally shelling out to MSBuild and 7-Zip via <a href="http://www.python.org/doc/2.5.2/lib/os-process.html">os.system</a>.
I looked at <a href="http://www.ironpython.info/index.php/Automating_MSBuild">programmatically
building</a> via the MSBuild API, but I ran into an <a href="http://blogs.microsoft.co.il/blogs/idof/archive/2008/11/24/what-does-entity-framework-has-to-do-with-msbuild.aspx">assembly
binding bug</a> that I wasn’t motivated enough to work around. As for creating zip
files programmatically, IronPython doesn’t have a <a href="http://www.python.org/doc/2.5.2/lib/module-zlib.html">zlib
module</a> implementation yet so I just used 7-Zip’s command line utility instead.
</p>
        <p>
For downloading form CodePlex, I originally started by shelling out to CodePlex Client.
However, I wanted the ability to cloak folders – for example \Tutorial and \Src\Tests
– that weren’t required to build. CodePlex Client has a very useful TFS library embedded
in it – the build process combines all the libraries into a single executable via <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=22914587-b4ad-4eae-87cf-b14ae6a939b0&amp;displaylang=en">ILMerge</a>.
I could have compiled my own version of the TFS library, but instead I just load cpc.exe
as an assembly reference via clr.AddReferenceToFileAndPath. It’s a nifty trick <a href="http://blogs.msdn.com/hugunin/">Jim
Hugunin</a> showed me once. 
</p>
        <p>
Uploading to Azure was very straightforward because of the StorageClient library.
Here’s the code to create a blob container object (creating the actual blob container
if it doesn’t already exist) and to upload a file to a container.
</p>
        <div style="font-family: consolas,lucida console,courier new">
          <span style="color: blue">def</span> get_blob_container<span style="color: blue">(</span>prj<span style="color: blue">)</span><span style="color: blue">:</span><br>
  azure_account = StorageAccountInfo<span style="color: blue">(</span>endpoint,
None, azure_name, azure_key<span style="color: blue">)</span><br>
  storage = BlobStorage<span style="color: blue">.</span>Create<span style="color: blue">(</span>azure_account<span style="color: blue">)</span><br>
  container = storage<span style="color: blue">.</span>GetBlobContainer<span style="color: blue">(</span>prj<span style="color: blue">.</span>lower<span style="color: blue">(</span><span style="color: blue">)</span><span style="color: blue">)</span><br>
  <span style="color: blue">if</span> <span style="color: blue">not</span> container<span style="color: blue">.</span>DoesContainerExist<span style="color: blue">(</span><span style="color: blue">)</span><span style="color: blue">:</span><br>
    <span style="color: blue">print</span> <span style="color: maroon">"Creating"</span>,
prj, <span style="color: maroon">"Azure Blob Storage Container"</span><br>
    container<span style="color: blue">.</span>CreateContainer<span style="color: blue">(</span>None,
ContainerAccessControl<span style="color: blue">.</span>Public<span style="color: blue">)</span><br>
  <span style="color: blue">return</span> container 
<br><br><span style="color: blue">def</span> upload_to_azure<span style="color: blue">(</span>container,
upload_filepath, azure_filename, metadata<span style="color: blue">)</span><span style="color: blue">:</span><br>
    <span style="color: blue">print</span> <span style="color: maroon">"Uploading"</span>,
azure_filename, <span style="color: maroon">"to Azure"</span><br>
    prop = BlobProperties<span style="color: blue">(</span>azure_filename<span style="color: blue">)</span><br>
    nv = NameValueCollection<span style="color: blue">(</span><span style="color: blue">)</span><br>
    <span style="color: blue">for</span> key <span style="color: blue">in</span> metadata<span style="color: blue">:</span><br>
      nv<span style="color: blue">[</span>key<span style="color: blue">]</span> =
metadata<span style="color: blue">[</span>key<span style="color: blue">]</span><br>
    prop<span style="color: blue">.</span>Metadata = nv 
<br>
     
<br>
    <span style="color: blue">with</span> File<span style="color: blue">.</span>OpenRead<span style="color: blue">(</span>upload_filepath<span style="color: blue">)</span> <span style="color: blue">as</span> stream<span style="color: blue">:</span><br>
      contents = BlobContents<span style="color: blue">(</span>stream<span style="color: blue">)</span><br>
      <span style="color: blue">if</span> <span style="color: blue">not</span> container<span style="color: blue">.</span>CreateBlob<span style="color: blue">(</span>prop,
contents, True<span style="color: blue">)</span><span style="color: blue">:</span><br>
        <span style="color: blue">raise</span> <span style="color: maroon">"Uploading
"</span> + azure_filename + <span style="color: maroon">" to Azure failed"</span></div>
        <p>
I’ve been working on some pure IronPython code to access the <a href="http://msdn.microsoft.com/en-us/library/dd179355.aspx">blob
storage REST API</a> directly, but that’s primarily to familiarize myself with the
service. At some point, I’m going to want to leverage <a href="http://msdn.microsoft.com/en-us/library/dd179423.aspx">Table
Storage</a> but my brief experimentation with the StorageClient Table Storage interface
makes me think that it depends on static typing too much to be useful for IPy. If
that turns out to be true, the Table Storage REST API will be my only option.
</p>
        <p>
As you can see in the code above, these Azure blob containers are set to be publically
accessible (via ContainerAccessControl<span style="color: blue">.</span>Public argument
passed to CreateContainer). So for my C# app, I’m simply using calling XDocument.Load
with the <a href="http://msdn.microsoft.com/en-us/library/dd135734.aspx">List Blobs
operation url</a>, shaping the results via LINQ to XML and binding them to nested
ASP.NET Repeater controls. 
</p>
        <p>
Assuming people find this useful, I’m thinking of some additional improvements, in
order of what I’m likely to get to first:
</p>
        <ul>
          <li>
Caching Project Info in the cloud app 
<br>
Currently, I’m hitting getting and processing the list of binary releases on every
request. I’m sure caching that data to make it more efficient. 
</li>
          <li>
Virtual Build Environment 
<br>
Currently, I’m just building on my laptop. It would be nice to have a clean environment
dedicated to running the build script. 
</li>
          <li>
Auto-Build 
<br>
My script uses the RSS feed to find the recent checkins, but I have to manually kick
off the process. I’d like it to set it up as a service that periodically checks the
source code RSS feed automatically and downloads and builds any new releases that
it finds. 
</li>
          <li>
Table Storage for Build Metadata 
<br>
Today, I am simply grabbing the list of all uploaded compressed binaries for a given
project, parsing their names, and displaying that as a hierarchical list on the <a href="http://nightlybuilds.cloudapp.net/Project.aspx?project=ironpython">project
page</a>. If I used Table Storage, I could add additional metadata including social
software features like ratings and comments. 
</li>
          <li>
Amazon EC2 Virtual Build Environment 
<br>
If I’m creating a virtual machine for my build environment, I could look at hosting
it on <a href="http://aws.amazon.com/ec2/">Amazon EC2</a>. They <a href="http://aws.amazon.com/windows/">support
Windows now</a> after all. Ideally, I’d use an <a href="http://msdn.microsoft.com/en-us/library/dd179341.aspx">Azure
worker role</a> for compiling and compressing builds, but our build tools need access
to the file system. 
</li>
        </ul>
        <img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=9ecbf637-0b38-475e-90ad-33af18381878"></img>
      <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Devhawk?a=pa9Yyo.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=pa9Yyo.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=17tphM.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=17tphM.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=Snnz67.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=Snnz67.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=FVNfNO.p"><img src="http://feeds.feedburner.com/~f/Devhawk?i=FVNfNO.p" border="0"></img></a>
</div>]]></content:encoded><description>&lt;p&gt;
Here are some technical details on my &lt;a href="http://devhawk.net/2009/01/07/IronPython+Nightly+Builds.aspx"&gt;Nightly
Builds solution&lt;/a&gt;. I broke them into a separate post because I figured most people
are more interested in the actual service than how it’s built.
&lt;/p&gt;
&lt;p&gt;
As you might expect, I built most of the solution in IronPython. All of the download,
build, compress and Azure upload code was written in IPy. The one part I didn’t write
in IPy was the Azure cloud web app, which I wrote in C#. Jon Udell’s been investigating &lt;a href="http://blog.jonudell.net/2008/12/22/azure-calendar-aggregator-part-1/"&gt;getting
IPy to run in Azure&lt;/a&gt;, but I just wanted something quick and dirty (as you can see
from the &lt;a href="http://nightlybuilds.cloudapp.net/"&gt;utter lack of formatting&lt;/a&gt;)
so I decided to use C# instead. Man, were my ASP.NET skills rusty.
&lt;/p&gt;
&lt;p&gt;
As for the IronPython parts, for the most part I’m using external tools for downloading,
building and compressing. I use the &lt;a href="http://www.codeplex.com/IronPython/Project/ProjectRss.aspx?ProjectRSSFeed=codeplex%3a%2f%2fsourcecontrol%2fIronPython"&gt;Source
Control RSS Feed&lt;/a&gt; to discover recent source code changesets, &lt;a href="http://www.codeplex.com/CodePlexClient"&gt;CodePlex
Client&lt;/a&gt; to download source from CodePlex, &lt;a href="http://msdn.microsoft.com/en-us/library/wea2sca5.aspx"&gt;MSBuild&lt;/a&gt; to
build the binaries, &lt;a href="http://www.7-zip.org/"&gt;7-zip&lt;/a&gt; to compress the binaries
and the &lt;a href="http://msdn.microsoft.com/en-us/library/dd135716.aspx"&gt;StorageClient
library sample&lt;/a&gt; to upload the compressed binaries up to Azure blob storage. 
&lt;/p&gt;
&lt;p&gt;
For building and compressing, I’m literally shelling out to MSBuild and 7-Zip via &lt;a href="http://www.python.org/doc/2.5.2/lib/os-process.html"&gt;os.system&lt;/a&gt;.
I looked at &lt;a href="http://www.ironpython.info/index.php/Automating_MSBuild"&gt;programmatically
building&lt;/a&gt; via the MSBuild API, but I ran into an &lt;a href="http://blogs.microsoft.co.il/blogs/idof/archive/2008/11/24/what-does-entity-framework-has-to-do-with-msbuild.aspx"&gt;assembly
binding bug&lt;/a&gt; that I wasn’t motivated enough to work around. As for creating zip
files programmatically, IronPython doesn’t have a &lt;a href="http://www.python.org/doc/2.5.2/lib/module-zlib.html"&gt;zlib
module&lt;/a&gt; implementation yet so I just used 7-Zip’s command line utility instead.
&lt;/p&gt;
&lt;p&gt;
For downloading form CodePlex, I originally started by shelling out to CodePlex Client.
However, I wanted the ability to cloak folders – for example \Tutorial and \Src\Tests
– that weren’t required to build. CodePlex Client has a very useful TFS library embedded
in it – the build process combines all the libraries into a single executable via &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=22914587-b4ad-4eae-87cf-b14ae6a939b0&amp;amp;displaylang=en"&gt;ILMerge&lt;/a&gt;.
I could have compiled my own version of the TFS library, but instead I just load cpc.exe
as an assembly reference via clr.AddReferenceToFileAndPath. It’s a nifty trick &lt;a href="http://blogs.msdn.com/hugunin/"&gt;Jim
Hugunin&lt;/a&gt; showed me once. 
&lt;/p&gt;
&lt;p&gt;
Uploading to Azure was very straightforward because of the StorageClient library.
Here’s the code to create a blob container object (creating the actual blob container
if it doesn’t already exist) and to upload a file to a container.
&lt;/p&gt;
&lt;div style="font-family: consolas,lucida console,courier new"&gt;&lt;span style="color: blue"&gt;def&lt;/span&gt; get_blob_container&lt;span style="color: blue"&gt;(&lt;/span&gt;prj&lt;span style="color: blue"&gt;)&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt; 
&lt;br /&gt;
&amp;#160; azure_account = StorageAccountInfo&lt;span style="color: blue"&gt;(&lt;/span&gt;endpoint,
None, azure_name, azure_key&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&amp;#160; storage = BlobStorage&lt;span style="color: blue"&gt;.&lt;/span&gt;Create&lt;span style="color: blue"&gt;(&lt;/span&gt;azure_account&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&amp;#160; container = storage&lt;span style="color: blue"&gt;.&lt;/span&gt;GetBlobContainer&lt;span style="color: blue"&gt;(&lt;/span&gt;prj&lt;span style="color: blue"&gt;.&lt;/span&gt;lower&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&amp;#160; &lt;span style="color: blue"&gt;if&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;not&lt;/span&gt; container&lt;span style="color: blue"&gt;.&lt;/span&gt;DoesContainerExist&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;print&lt;/span&gt;&amp;#160;&lt;span style="color: maroon"&gt;&amp;quot;Creating&amp;quot;&lt;/span&gt;,
prj, &lt;span style="color: maroon"&gt;&amp;quot;Azure Blob Storage Container&amp;quot;&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; container&lt;span style="color: blue"&gt;.&lt;/span&gt;CreateContainer&lt;span style="color: blue"&gt;(&lt;/span&gt;None,
ContainerAccessControl&lt;span style="color: blue"&gt;.&lt;/span&gt;Public&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt; container 
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue"&gt;def&lt;/span&gt; upload_to_azure&lt;span style="color: blue"&gt;(&lt;/span&gt;container,
upload_filepath, azure_filename, metadata&lt;span style="color: blue"&gt;)&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;print&lt;/span&gt;&amp;#160;&lt;span style="color: maroon"&gt;&amp;quot;Uploading&amp;quot;&lt;/span&gt;,
azure_filename, &lt;span style="color: maroon"&gt;&amp;quot;to Azure&amp;quot;&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; prop = BlobProperties&lt;span style="color: blue"&gt;(&lt;/span&gt;azure_filename&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; nv = NameValueCollection&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;for&lt;/span&gt; key &lt;span style="color: blue"&gt;in&lt;/span&gt; metadata&lt;span style="color: blue"&gt;:&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; nv&lt;span style="color: blue"&gt;[&lt;/span&gt;key&lt;span style="color: blue"&gt;]&lt;/span&gt; =
metadata&lt;span style="color: blue"&gt;[&lt;/span&gt;key&lt;span style="color: blue"&gt;]&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; prop&lt;span style="color: blue"&gt;.&lt;/span&gt;Metadata = nv 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;with&lt;/span&gt; File&lt;span style="color: blue"&gt;.&lt;/span&gt;OpenRead&lt;span style="color: blue"&gt;(&lt;/span&gt;upload_filepath&lt;span style="color: blue"&gt;)&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;as&lt;/span&gt; stream&lt;span style="color: blue"&gt;:&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; contents = BlobContents&lt;span style="color: blue"&gt;(&lt;/span&gt;stream&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;if&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;not&lt;/span&gt; container&lt;span style="color: blue"&gt;.&lt;/span&gt;CreateBlob&lt;span style="color: blue"&gt;(&lt;/span&gt;prop,
contents, True&lt;span style="color: blue"&gt;)&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;raise&lt;/span&gt;&amp;#160;&lt;span style="color: maroon"&gt;&amp;quot;Uploading
&amp;quot;&lt;/span&gt; + azure_filename + &lt;span style="color: maroon"&gt;&amp;quot; to Azure failed&amp;quot;&lt;/span&gt; 
&lt;/div&gt;
&lt;p&gt;
I’ve been working on some pure IronPython code to access the &lt;a href="http://msdn.microsoft.com/en-us/library/dd179355.aspx"&gt;blob
storage REST API&lt;/a&gt; directly, but that’s primarily to familiarize myself with the
service. At some point, I’m going to want to leverage &lt;a href="http://msdn.microsoft.com/en-us/library/dd179423.aspx"&gt;Table
Storage&lt;/a&gt; but my brief experimentation with the StorageClient Table Storage interface
makes me think that it depends on static typing too much to be useful for IPy. If
that turns out to be true, the Table Storage REST API will be my only option.
&lt;/p&gt;
&lt;p&gt;
As you can see in the code above, these Azure blob containers are set to be publically
accessible (via ContainerAccessControl&lt;span style="color: blue"&gt;.&lt;/span&gt;Public argument
passed to CreateContainer). So for my C# app, I’m simply using calling XDocument.Load
with the &lt;a href="http://msdn.microsoft.com/en-us/library/dd135734.aspx"&gt;List Blobs
operation url&lt;/a&gt;, shaping the results via LINQ to XML and binding them to nested
ASP.NET Repeater controls. 
&lt;/p&gt;
&lt;p&gt;
Assuming people find this useful, I’m thinking of some additional improvements, in
order of what I’m likely to get to first:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Caching Project Info in the cloud app 
&lt;br /&gt;
Currently, I’m hitting getting and processing the list of binary releases on every
request. I’m sure caching that data to make it more efficient. 
&lt;/li&gt;
&lt;li&gt;
Virtual Build Environment 
&lt;br /&gt;
Currently, I’m just building on my laptop. It would be nice to have a clean environment
dedicated to running the build script. 
&lt;/li&gt;
&lt;li&gt;
Auto-Build 
&lt;br /&gt;
My script uses the RSS feed to find the recent checkins, but I have to manually kick
off the process. I’d like it to set it up as a service that periodically checks the
source code RSS feed automatically and downloads and builds any new releases that
it finds. 
&lt;/li&gt;
&lt;li&gt;
Table Storage for Build Metadata 
&lt;br /&gt;
Today, I am simply grabbing the list of all uploaded compressed binaries for a given
project, parsing their names, and displaying that as a hierarchical list on the &lt;a href="http://nightlybuilds.cloudapp.net/Project.aspx?project=ironpython"&gt;project
page&lt;/a&gt;. If I used Table Storage, I could add additional metadata including social
software features like ratings and comments. 
&lt;/li&gt;
&lt;li&gt;
Amazon EC2 Virtual Build Environment 
&lt;br /&gt;
If I’m creating a virtual machine for my build environment, I could look at hosting
it on &lt;a href="http://aws.amazon.com/ec2/"&gt;Amazon EC2&lt;/a&gt;. They &lt;a href="http://aws.amazon.com/windows/"&gt;support
Windows now&lt;/a&gt; after all. Ideally, I’d use an &lt;a href="http://msdn.microsoft.com/en-us/library/dd179341.aspx"&gt;Azure
worker role&lt;/a&gt; for compiling and compressing builds, but our build tools need access
to the file system. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=9ecbf637-0b38-475e-90ad-33af18381878" /&gt;</description><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://devhawk.net/Trackback.aspx?guid=9ecbf637-0b38-475e-90ad-33af18381878</trackback:ping><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/pingback.aspx</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/PermaLink,guid,9ecbf637-0b38-475e-90ad-33af18381878.aspx</pingback:target><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/CommentView,guid,9ecbf637-0b38-475e-90ad-33af18381878.aspx</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/SyndicationService.asmx/GetEntryCommentsRss?guid=9ecbf637-0b38-475e-90ad-33af18381878</wfw:commentRss><feedburner:origLink>http://devhawk.net/2009/01/07/Nightly+Builds+Technical+Info.aspx</feedburner:origLink></item><item><title>IronPython Nightly Builds</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/505680983/IronPython+Nightly+Builds.aspx</link><category>DLR</category><category>IronPython</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Harry Pierson</dc:creator><pubDate>Wed, 07 Jan 2009 17:18:13 -0600</pubDate><guid isPermaLink="false">http://devhawk.net/PermaLink,guid,96cf813b-cc2b-4941-8fea-7bc98b3a0db9.aspx</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
        <p>
          <a href="http://www.codeplex.com/IronPython/Release/ProjectReleases.aspx?ReleaseId=8365">IronPython
2.0</a> shipped <a href="http://devhawk.net/2008/12/10/IPy+RTW+FTW.aspx">about a month
ago</a>, but we’re still chugging along with our post 2.0 work. We’ve shipped seven <a href="http://www.codeplex.com/IronPython/SourceControl/ListDownloadableCommits.aspx">source
code releases</a> since we shipped 2.0 and we should be back to our normal schedule
of updating the source 2-3 times a week schedule by next week. Given how often we
ship source, we’re thinking of extending the the time between binary drops. Binary
releases have to be signed and there’s a fairly arduous process we have to go thru
in order to get each binary release out the door.
</p>
        <p>
However, there’s something nice and convenient about downloading a pre-compiled binary
release. So I spent my Christmas vacation building a script to download and build
IronPython nightly builds. Once built, I compress the binaries and upload them to <a href="http://msdn.microsoft.com/en-us/library/dd135733.aspx">Azure
blob storage</a>. Finally, I built a <a href="http://nightlybuilds.cloudapp.net/">*very*
simple cloud app</a> for users to view and download available nightly builds. As an
extra benefit, I’m also providing nightly builds of the <a href="http://codeplex.com/dlr">DLR</a>. 
</p>
        <p>
Please note, these are *NOT* official Microsoft releases of IronPython and/or DLR.
They aren’t signed and they haven’t gone through the aforementioned release process.
I’m just downloading the public source, building it with the publicly available tools,
then making them available on a a publicly accessible website.
</p>
        <p>
The website for the IronPython (and DLR) nightly builds is <a href="http://nightlybuilds.cloudapp.net">http://nightlybuilds.cloudapp.net</a>. 
</p>
        <p>
As usual, I welcome any feedback. Is having prebuilt unsigned binaries of IPy releases
useful? Do you want IronRuby binaries as well? What about social features (rating
releases, comments, etc)? Please let me know what you think. 
</p>
        <img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=96cf813b-cc2b-4941-8fea-7bc98b3a0db9"></img>
      <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Devhawk?a=t6FLgk.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=t6FLgk.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=AqwYxT.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=AqwYxT.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=ByG8WR.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=ByG8WR.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=9n5Dto.p"><img src="http://feeds.feedburner.com/~f/Devhawk?i=9n5Dto.p" border="0"></img></a>
</div>]]></content:encoded><description>&lt;p&gt;
&lt;a href="http://www.codeplex.com/IronPython/Release/ProjectReleases.aspx?ReleaseId=8365"&gt;IronPython
2.0&lt;/a&gt; shipped &lt;a href="http://devhawk.net/2008/12/10/IPy+RTW+FTW.aspx"&gt;about a month
ago&lt;/a&gt;, but we’re still chugging along with our post 2.0 work. We’ve shipped seven &lt;a href="http://www.codeplex.com/IronPython/SourceControl/ListDownloadableCommits.aspx"&gt;source
code releases&lt;/a&gt; since we shipped 2.0 and we should be back to our normal schedule
of updating the source 2-3 times a week schedule by next week. Given how often we
ship source, we’re thinking of extending the the time between binary drops. Binary
releases have to be signed and there’s a fairly arduous process we have to go thru
in order to get each binary release out the door.
&lt;/p&gt;
&lt;p&gt;
However, there’s something nice and convenient about downloading a pre-compiled binary
release. So I spent my Christmas vacation building a script to download and build
IronPython nightly builds. Once built, I compress the binaries and upload them to &lt;a href="http://msdn.microsoft.com/en-us/library/dd135733.aspx"&gt;Azure
blob storage&lt;/a&gt;. Finally, I built a &lt;a href="http://nightlybuilds.cloudapp.net/"&gt;*very*
simple cloud app&lt;/a&gt; for users to view and download available nightly builds. As an
extra benefit, I’m also providing nightly builds of the &lt;a href="http://codeplex.com/dlr"&gt;DLR&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
Please note, these are *NOT* official Microsoft releases of IronPython and/or DLR.
They aren’t signed and they haven’t gone through the aforementioned release process.
I’m just downloading the public source, building it with the publicly available tools,
then making them available on a a publicly accessible website.
&lt;/p&gt;
&lt;p&gt;
The website for the IronPython (and DLR) nightly builds is &lt;a href="http://nightlybuilds.cloudapp.net"&gt;http://nightlybuilds.cloudapp.net&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
As usual, I welcome any feedback. Is having prebuilt unsigned binaries of IPy releases
useful? Do you want IronRuby binaries as well? What about social features (rating
releases, comments, etc)? Please let me know what you think. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=96cf813b-cc2b-4941-8fea-7bc98b3a0db9" /&gt;</description><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://devhawk.net/Trackback.aspx?guid=96cf813b-cc2b-4941-8fea-7bc98b3a0db9</trackback:ping><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/pingback.aspx</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/PermaLink,guid,96cf813b-cc2b-4941-8fea-7bc98b3a0db9.aspx</pingback:target><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/CommentView,guid,96cf813b-cc2b-4941-8fea-7bc98b3a0db9.aspx</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/SyndicationService.asmx/GetEntryCommentsRss?guid=96cf813b-cc2b-4941-8fea-7bc98b3a0db9</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">1</slash:comments><feedburner:origLink>http://devhawk.net/2009/01/07/IronPython+Nightly+Builds.aspx</feedburner:origLink></item><item><title>Links for 2008-12-22 [del.icio.us]</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/492875681/harrypierson</link><pubDate>Tue, 23 Dec 2008 00:00:00 -0600</pubDate><guid isPermaLink="false">http://del.icio.us/harrypierson#2008-12-22</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[<ul>
<li><a href="http://jonas.follesoe.no/MeshenablingTheDiveLogSilverlightApplication.aspx">Mesh-enabling the Dive Log Silverlight Application</a></li>
</ul>]]></content:encoded><description>&lt;ul&gt;
&lt;li&gt;&lt;a href="http://jonas.follesoe.no/MeshenablingTheDiveLogSilverlightApplication.aspx"&gt;Mesh-enabling the Dive Log Silverlight Application&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><feedburner:origLink>http://del.icio.us/harrypierson#2008-12-22</feedburner:origLink></item><item><title>The Reese&amp;rsquo;s Peanut Butter Cups of Language Conferences</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/489246556/The+Reesersquos+Peanut+Butter+Cups+Of+Language+Conferences.aspx</link><category>Development/Lanugages</category><category>Domain Specific Languages</category><category>LangNET</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Harry Pierson</dc:creator><pubDate>Thu, 18 Dec 2008 20:32:42 -0600</pubDate><guid isPermaLink="false">http://devhawk.net/PermaLink,guid,54b16d9e-f335-468d-9a5d-351e004fe753.aspx</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
        <p>
It’s been about 11 months since the last <a href="http://www.langnetsymposium.com/">Lang.NET
Symposium</a> and we’ve been working on next year’s version. But then we discovered
that we’re not the only ones inside Microsoft thinking about having <a href="http://www.sellsbrothers.com/news/showTopic.aspx?ixTopic=2201">a
language conference</a>. A couple of meetings later, and we’ve decided to combine
them, which will assuredly lead to side conversations like this:
</p>
        <blockquote>
          <p>
DSL DevCon Attendee: Hey, you got your compiler in my DSL!
</p>
          <p>
Lang.NET Attendee: Hey, you got your DSL in my compiler!
</p>
          <p>
[They sample the combined content]
</p>
          <p>
Both Attendees: Mmmm, two great conferences that work well together!
</p>
        </blockquote>
        <p>
Well, maybe not. But seriously, it should be a great combined conference.
</p>
        <p>
However, there are some logistics things we need to work out, like how many days should
the combined conference run? We figure the “right” answer to these questions depends
on the likely overlap between the two conferences. Frankly, we don’t know what the
overlap will be so we decided to <a href="http://www.sellsbrothers.com/news/showTopic.aspx?ixTopic=2219">simply,
you know, ask</a>.
</p>
        <p>
If you are interested in attending Lang.NET, the DSL DevCon, or both next year, <u>please</u> head
over to Chris Sells blog and <a href="http://www.sellsbrothers.com/news/showTopic.aspx?ixTopic=2219">make
your voice heard</a>. 
</p>
        <img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=54b16d9e-f335-468d-9a5d-351e004fe753"></img>
      <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Devhawk?a=A84kSS.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=A84kSS.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=sUSTir.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=sUSTir.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=IPFSOJ.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=IPFSOJ.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=OsvUmO.p"><img src="http://feeds.feedburner.com/~f/Devhawk?i=OsvUmO.p" border="0"></img></a>
</div>]]></content:encoded><description>&lt;p&gt;
It’s been about 11 months since the last &lt;a href="http://www.langnetsymposium.com/"&gt;Lang.NET
Symposium&lt;/a&gt; and we’ve been working on next year’s version. But then we discovered
that we’re not the only ones inside Microsoft thinking about having &lt;a href="http://www.sellsbrothers.com/news/showTopic.aspx?ixTopic=2201"&gt;a
language conference&lt;/a&gt;. A couple of meetings later, and we’ve decided to combine
them, which will assuredly lead to side conversations like this:
&lt;/p&gt;
&lt;blockquote&gt; 
&lt;p&gt;
DSL DevCon Attendee: Hey, you got your compiler in my DSL!
&lt;/p&gt;
&lt;p&gt;
Lang.NET Attendee: Hey, you got your DSL in my compiler!
&lt;/p&gt;
&lt;p&gt;
[They sample the combined content]
&lt;/p&gt;
&lt;p&gt;
Both Attendees: Mmmm, two great conferences that work well together!
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
Well, maybe not. But seriously, it should be a great combined conference.
&lt;/p&gt;
&lt;p&gt;
However, there are some logistics things we need to work out, like how many days should
the combined conference run? We figure the “right” answer to these questions depends
on the likely overlap between the two conferences. Frankly, we don’t know what the
overlap will be so we decided to &lt;a href="http://www.sellsbrothers.com/news/showTopic.aspx?ixTopic=2219"&gt;simply,
you know, ask&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
If you are interested in attending Lang.NET, the DSL DevCon, or both next year, &lt;u&gt;please&lt;/u&gt; head
over to Chris Sells blog and &lt;a href="http://www.sellsbrothers.com/news/showTopic.aspx?ixTopic=2219"&gt;make
your voice heard&lt;/a&gt;. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=54b16d9e-f335-468d-9a5d-351e004fe753" /&gt;</description><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://devhawk.net/Trackback.aspx?guid=54b16d9e-f335-468d-9a5d-351e004fe753</trackback:ping><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/pingback.aspx</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/PermaLink,guid,54b16d9e-f335-468d-9a5d-351e004fe753.aspx</pingback:target><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/CommentView,guid,54b16d9e-f335-468d-9a5d-351e004fe753.aspx</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/SyndicationService.asmx/GetEntryCommentsRss?guid=54b16d9e-f335-468d-9a5d-351e004fe753</wfw:commentRss><feedburner:origLink>http://devhawk.net/2008/12/19/The+Reesersquos+Peanut+Butter+Cups+Of+Language+Conferences.aspx</feedburner:origLink></item><item><title>PowerShell find-to-set-alias</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/488094015/PowerShell+Findtosetalias.aspx</link><category>PowerShell</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Harry Pierson</dc:creator><pubDate>Wed, 17 Dec 2008 17:17:09 -0600</pubDate><guid isPermaLink="false">http://devhawk.net/PermaLink,guid,ae593a6d-e9b4-40ad-9a2e-fe46accd5f78.aspx</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
        <p>
I use Live Mesh to keep my PowerShell scripts folder synced between multiple machine.
Some of those machines have different things installed on them or have things installed
in different locations. For example, my laptop is x86 while my desktop is x64 so many
things on the desktop get installed into c:\Program Files(x86) instead of the plain-old
c:\Program Files folder. I wanted my shared profile script to be able to search a
set of folders for a given executable to alias, and I came up with the following function.
</p>
        <div style="font-family: consolas,lucida console,courier new">
          <span style="color: blue">function</span> find-to-<span style="color: #2b91af">set-alias</span>(<span style="color: #35687d">$foldersearch</span>, <span style="color: #35687d">$file</span>, <span style="color: #35687d">$alias</span>) 
<br>
{ 
<br>
  <span style="color: #2b91af">dir</span> <span style="color: #35687d">$foldersearch</span> |  
<br>
    %{<span style="color: #2b91af">dir</span> <span style="color: #35687d">$_</span> -Recurse
-<span style="color: blue">Filter</span> <span style="color: #35687d">$file</span>}
|  
<br>
    %{<span style="color: #2b91af">set-alias</span> <span style="color: #35687d">$alias</span> <span style="color: #35687d">$_</span>.FullName
-scope Global; <span style="color: blue">break</span>} 
<br>
}
</div>
        <p>
It’s pretty simple to use. You pass in a folder search criteria – it must have a wildcard,
or the function won’t work – the file you’re looking for and the alias you want to
set. The function finds all the folders matching the $foldersearch criteria, then
searches them recursively looking for the $file you specified. Set-alias is called
for the first matching $file found – pipeline processing is halted via the break statement. 
</p>
        <p>
Here are the find-to-set-aliases I have in my profile:
</p>
        <div style="font-family: consolas,lucida console,courier new">find-to-<span style="color: #2b91af">set-alias</span> <span style="color: maroon">'c:\program
files*\IronPython*'</span> ipy.exe ipy 
<br>
find-to-<span style="color: #2b91af">set-alias</span> <span style="color: maroon">'c:\program
files*\IronPython*'</span> chiron.exe chiron 
<br><br>
find-to-<span style="color: #2b91af">set-alias</span> <span style="color: maroon">'c:\Python*'</span> python.exe
cpy 
<br><br>
find-to-<span style="color: #2b91af">set-alias</span>  
<br>
    <span style="color: maroon">'c:\program files*\Microsoft Visual
Studio 9.0\Common7'</span> devenv.exe vs 
<br>
find-to-<span style="color: #2b91af">set-alias</span>  
<br>
    <span style="color: maroon">'c:\program files*\Microsoft Visual
Studio 9.0\Common7'</span> tf.exe tf 
<br><br>
find-to-<span style="color: #2b91af">set-alias</span> <span style="color: maroon">'c:\program
files*\FSharp*'</span> fsi.exe fsi 
<br>
find-to-<span style="color: #2b91af">set-alias</span>  
<br>
    <span style="color: maroon">'c:\program files*\Microsoft Repository
SDK*'</span> ipad.exe ipad 
<br>
find-to-<span style="color: #2b91af">set-alias</span>  
<br>
    <span style="color: maroon">'c:\program files*\Microsoft Virtual
PC*'</span> <span style="color: maroon">'Virtual pc.exe'</span> vpc 
</div>
        <p>
Python, IronPython and F# aliases, no surprise there. Chiron is the REPL server for
dynamic language Silverlight development. Typically, I use <a href="http://www.tavaresstudios.com/Blog/post/The-last-vsvars32ps1-Ill-ever-need.aspx">Chris
Tavares’ vsvars script</a> to configure the command shell for development purposes,
but I find it’s nice to have aliases for TF and DevEnv handy at all times. 
</p>
        <img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=ae593a6d-e9b4-40ad-9a2e-fe46accd5f78"></img>
      <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Devhawk?a=T4U9y0.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=T4U9y0.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=Hn5DaE.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=Hn5DaE.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=0U32jP.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=0U32jP.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=I4uZLg.p"><img src="http://feeds.feedburner.com/~f/Devhawk?i=I4uZLg.p" border="0"></img></a>
</div>]]></content:encoded><description>&lt;p&gt;
I use Live Mesh to keep my PowerShell scripts folder synced between multiple machine.
Some of those machines have different things installed on them or have things installed
in different locations. For example, my laptop is x86 while my desktop is x64 so many
things on the desktop get installed into c:\Program Files(x86) instead of the plain-old
c:\Program Files folder. I wanted my shared profile script to be able to search a
set of folders for a given executable to alias, and I came up with the following function.
&lt;/p&gt;
&lt;div style="font-family: consolas,lucida console,courier new"&gt;&lt;span style="color: blue"&gt;function&lt;/span&gt; find-to-&lt;span style="color: #2b91af"&gt;set-alias&lt;/span&gt;(&lt;span style="color: #35687d"&gt;$foldersearch&lt;/span&gt;, &lt;span style="color: #35687d"&gt;$file&lt;/span&gt;, &lt;span style="color: #35687d"&gt;$alias&lt;/span&gt;) 
&lt;br /&gt;
{ 
&lt;br /&gt;
&amp;#160; &lt;span style="color: #2b91af"&gt;dir&lt;/span&gt;&amp;#160;&lt;span style="color: #35687d"&gt;$foldersearch&lt;/span&gt; |&amp;#160; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; %{&lt;span style="color: #2b91af"&gt;dir&lt;/span&gt;&amp;#160;&lt;span style="color: #35687d"&gt;$_&lt;/span&gt; -Recurse
-&lt;span style="color: blue"&gt;Filter&lt;/span&gt;&amp;#160;&lt;span style="color: #35687d"&gt;$file&lt;/span&gt;}
|&amp;#160; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; %{&lt;span style="color: #2b91af"&gt;set-alias&lt;/span&gt;&amp;#160;&lt;span style="color: #35687d"&gt;$alias&lt;/span&gt;&amp;#160;&lt;span style="color: #35687d"&gt;$_&lt;/span&gt;.FullName
-scope Global; &lt;span style="color: blue"&gt;break&lt;/span&gt;} 
&lt;br /&gt;
}
&lt;/div&gt;
&lt;p&gt;
It’s pretty simple to use. You pass in a folder search criteria – it must have a wildcard,
or the function won’t work – the file you’re looking for and the alias you want to
set. The function finds all the folders matching the $foldersearch criteria, then
searches them recursively looking for the $file you specified. Set-alias is called
for the first matching $file found – pipeline processing is halted via the break statement. 
&lt;/p&gt;
&lt;p&gt;
Here are the find-to-set-aliases I have in my profile:
&lt;/p&gt;
&lt;div style="font-family: consolas,lucida console,courier new"&gt;find-to-&lt;span style="color: #2b91af"&gt;set-alias&lt;/span&gt;&amp;#160;&lt;span style="color: maroon"&gt;'c:\program
files*\IronPython*'&lt;/span&gt; ipy.exe ipy 
&lt;br /&gt;
find-to-&lt;span style="color: #2b91af"&gt;set-alias&lt;/span&gt;&amp;#160;&lt;span style="color: maroon"&gt;'c:\program
files*\IronPython*'&lt;/span&gt; chiron.exe chiron 
&lt;br /&gt;
&lt;br /&gt;
find-to-&lt;span style="color: #2b91af"&gt;set-alias&lt;/span&gt;&amp;#160;&lt;span style="color: maroon"&gt;'c:\Python*'&lt;/span&gt; python.exe
cpy 
&lt;br /&gt;
&lt;br /&gt;
find-to-&lt;span style="color: #2b91af"&gt;set-alias&lt;/span&gt;&amp;#160; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: maroon"&gt;'c:\program files*\Microsoft Visual
Studio 9.0\Common7'&lt;/span&gt; devenv.exe vs 
&lt;br /&gt;
find-to-&lt;span style="color: #2b91af"&gt;set-alias&lt;/span&gt;&amp;#160; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: maroon"&gt;'c:\program files*\Microsoft Visual
Studio 9.0\Common7'&lt;/span&gt; tf.exe tf 
&lt;br /&gt;
&lt;br /&gt;
find-to-&lt;span style="color: #2b91af"&gt;set-alias&lt;/span&gt;&amp;#160;&lt;span style="color: maroon"&gt;'c:\program
files*\FSharp*'&lt;/span&gt; fsi.exe fsi 
&lt;br /&gt;
find-to-&lt;span style="color: #2b91af"&gt;set-alias&lt;/span&gt;&amp;#160; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: maroon"&gt;'c:\program files*\Microsoft Repository
SDK*'&lt;/span&gt; ipad.exe ipad 
&lt;br /&gt;
find-to-&lt;span style="color: #2b91af"&gt;set-alias&lt;/span&gt;&amp;#160; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: maroon"&gt;'c:\program files*\Microsoft Virtual
PC*'&lt;/span&gt;&amp;#160;&lt;span style="color: maroon"&gt;'Virtual pc.exe'&lt;/span&gt; vpc 
&lt;/div&gt;
&lt;p&gt;
Python, IronPython and F# aliases, no surprise there. Chiron is the REPL server for
dynamic language Silverlight development. Typically, I use &lt;a href="http://www.tavaresstudios.com/Blog/post/The-last-vsvars32ps1-Ill-ever-need.aspx"&gt;Chris
Tavares’ vsvars script&lt;/a&gt; to configure the command shell for development purposes,
but I find it’s nice to have aliases for TF and DevEnv handy at all times. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=ae593a6d-e9b4-40ad-9a2e-fe46accd5f78" /&gt;</description><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://devhawk.net/Trackback.aspx?guid=ae593a6d-e9b4-40ad-9a2e-fe46accd5f78</trackback:ping><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/pingback.aspx</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/PermaLink,guid,ae593a6d-e9b4-40ad-9a2e-fe46accd5f78.aspx</pingback:target><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/CommentView,guid,ae593a6d-e9b4-40ad-9a2e-fe46accd5f78.aspx</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/SyndicationService.asmx/GetEntryCommentsRss?guid=ae593a6d-e9b4-40ad-9a2e-fe46accd5f78</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">2</slash:comments><feedburner:origLink>http://devhawk.net/2008/12/17/PowerShell+Findtosetalias.aspx</feedburner:origLink></item><item><title>IronPython and LiveFX: Raw HTTP Access</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/487070187/IronPython+And+LiveFX+Raw+HTTP+Access.aspx</link><category>IronPython</category><category>Live Framework</category><category>Windows Live</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Harry Pierson</dc:creator><pubDate>Tue, 16 Dec 2008 17:36:48 -0600</pubDate><guid isPermaLink="false">http://devhawk.net/PermaLink,guid,47b36a30-e4af-42a0-8609-fbc0a83fe083.aspx</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
        <p>
One of the cool things about the Live Framework is that while there’s a <a href="http://msdn.microsoft.com/en-us/library/dd136352.aspx">convenient
.NET library available</a>, you can use the <a href="http://msdn.microsoft.com/en-us/library/dd199240.aspx">raw
HTTP interface</a> from any platform. LiveFX data is served up over HTTP and is available
in ATOM, RSS, JSON or POX formats. As I’ve already shown, you can easily use the .NET
library from IronPython, but I wanted to try working with the raw HTTP interface to
get a feel for that as well.
</p>
        <p>
Unfortunately, it was harder than I expected it to be. The big issue is that the documentation
on how to LiveFX authorization tokens via raw HTTP is fairly sparse and occasionally
contradictory. For example, there’s a whole section on <a href="http://msdn.microsoft.com/en-us/library/dd137185.aspx">Authentication
and Live Framework</a>, but it doesn’t cover this scenario. Luckily, I was able to
figure it out with the help of <a href="http://msdn.microsoft.com/en-us/library/dd135995.aspx">AtomPub
Project Manager LiveFX Sample</a>, a <a href="http://blog.opennetcf.com/afeinman/PermaLink,guid,80ea4a1d-fbc0-485d-a088-fb8f30efb6ab.aspx">post
on Alex Feinman’s blog</a>, a <a href="http://blogs.msdn.com/emesas/archive/2008/02/13/windows-live-id-available-options-part-i.aspx">post
on Emmanuel Mesas’ blog</a> and a little groveling around with Reflector. It does
appear that the auth docs are in flux –Emmanuel refers to <a href="http://msdn.microsoft.com/en-us/library/bb447721.aspx">this
MSDN article</a> as being about RPS Soap requests, but it’s actually about delegated
authority. (Is MSDN reusing URLs? Bad idea.) Also, the sample code has a comment that
reads “to be replaced by delegated authorization” so it looks like changes are coming.
In other words, no promises on how long this code will work!
</p>
        <p>
If you look at the AtomPub Project Manager sample, there’s a WindowsLiveIdentity.cs
file that implements static GetTicket method that looks similar to both the code on
Alex’s blog as well as the implementation of <a href="http://msdn.microsoft.com/en-us/library/dd157462.aspx">GetWindowsLiveAuthenticationToken</a>.
The upshot is that there’s a <a href="http://en.wikipedia.org/wiki/WS-Trust">WS-Trust</a> endpoint
for Windows Live at <a href="https://dev.login.live.com/wstlogin.srf">https://dev.login.live.com/wstlogin.srf</a>.
You send it a RequestSecurityToken (aka RST) message (with a couple of extra WL specific
extensions) and it responds with the security token you’ll need for accessing the
LiveFx HTTP endpoints. 
</p>
        <p>
I ported the GetTicket function over to IronPython. I’m using .NET classes like WebRequest
and XmlReader, but there’s nothing fancy here so I would expect it to be easy enough
to port over to the standard Python library.
</p>
        <div style="font-family: consolas,lucida console,courier new">
          <span style="color: blue">def</span> get_WL_ticket<span style="color: blue">(</span>username,
password, compactTicket<span style="color: blue">)</span><span style="color: blue">:</span><br>
    req = WebRequest<span style="color: blue">.</span>Create<span style="color: blue">(</span>_LoginEndPoint<span style="color: blue">)</span><br>
    req<span style="color: blue">.</span>Method = <span style="color: maroon">"POST"</span><br>
    req<span style="color: blue">.</span>ContentType = <span style="color: maroon">"application/soap+xml;
charset=UTF-8"</span><br>
    req<span style="color: blue">.</span>Timeout = <span style="color: maroon">30</span> * <span style="color: maroon">10000</span><br>
     
<br>
    rst = get_RST_message<span style="color: blue">(</span>username,
password, compactTicket<span style="color: blue">)</span><br>
    rstbytes = Encoding<span style="color: blue">.</span>UTF8<span style="color: blue">.</span>GetBytes<span style="color: blue">(</span>rst<span style="color: blue">)</span><br>
    <span style="color: blue">with</span> req<span style="color: blue">.</span>GetRequestStream<span style="color: blue">(</span><span style="color: blue">)</span> <span style="color: blue">as</span> reqstm<span style="color: blue">:</span><br>
      reqstm<span style="color: blue">.</span>Write<span style="color: blue">(</span>rstbytes, <span style="color: maroon">0</span>,
rstbytes<span style="color: blue">.</span>Length<span style="color: blue">)</span><br>
       
<br>
    <span style="color: blue">with</span> req<span style="color: blue">.</span>GetResponse<span style="color: blue">(</span><span style="color: blue">)</span> <span style="color: blue">as</span> resp<span style="color: blue">:</span><br>
      <span style="color: blue">with</span> resp<span style="color: blue">.</span>GetResponseStream<span style="color: blue">(</span><span style="color: blue">)</span> <span style="color: blue">as</span> respstm<span style="color: blue">:</span><br>
        <span style="color: blue">with</span> XmlReader<span style="color: blue">.</span>Create<span style="color: blue">(</span>respstm<span style="color: blue">)</span> <span style="color: blue">as</span> reader<span style="color: blue">:</span><br>
          <span style="color: blue">if</span> compactTicket<span style="color: blue">:</span><br>
            name = <span style="color: maroon">"BinarySecurityToken"</span><br>
            namespace = <span style="color: maroon">"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"</span><br>
          <span style="color: blue">else</span><span style="color: blue">:</span><br>
            name = <span style="color: maroon">"RequestedSecurityToken"</span><br>
            namespace = <span style="color: maroon">"http://schemas.xmlsoap.org/ws/2005/02/trust"</span><br><br>
          <span style="color: blue">if</span> <span style="color: blue">not</span> reader<span style="color: blue">.</span>ReadToDescendant<span style="color: blue">(</span>name,
namespace<span style="color: blue">)</span><span style="color: blue">:</span><br>
            <span style="color: blue">raise</span> <span style="color: maroon">"couldn't
find security token element"</span><br>
           
<br>
          reader<span style="color: blue">.</span>ReadStartElement<span style="color: blue">(</span>name,
namespace<span style="color: blue">)</span><br>
          token = reader<span style="color: blue">.</span>ReadContentAsString<span style="color: blue">(</span><span style="color: blue">)</span><br>
          reader<span style="color: blue">.</span>ReadEndElement<span style="color: blue">(</span><span style="color: blue">)</span><br>
           
<br>
          <span style="color: blue">return</span> Convert<span style="color: blue">.</span>ToBase64String<span style="color: blue">(</span>Encoding<span style="color: blue">.</span>UTF8<span style="color: blue">.</span>GetBytes<span style="color: blue">(</span>token<span style="color: blue">)</span><span style="color: blue">)</span></div>
        <p>
This code simply uses a WebRequest object to post the RST message to the WS-Trust
enpoint then parses the result to find the token. get_RST_message uses <a href="http://www.python.org/doc/2.5.2/lib/typesseq-strings.html">standard
Python string formatting</a> to generate the RST message that gets posted to the WS-Trust
endpoint. I’m not exactly sure why you need to convert the token value to a byte array
and then Base64 encode it, but that’s what the sample code does so I did it to.
</p>
        <p>
Once you have the authentication ticket, you need to download root service endpoint
document in order to get the base URL and the profiles link. Then you can download
all the profiles or you can download a specific one if you know it’s <a href="http://orand.blogspot.com/2008/11/l1v3-m35h-l337-h4x0rz.html">leet-speak
identifier</a>. LiveFX data can be downloaded in a variety of formats: ATOM, JSON,
RSS or POX. You choose your format by setting the Accept and Content-Type headers. 
</p>
        <p>
I wrote the following functions, the generic boilerplate download function as well
a specific versions for downloading JSON and POX:
</p>
        <div style="font-family: consolas,lucida console,courier new">
          <span style="color: blue">def</span> download<span style="color: blue">(</span>url,
contentType, authToken<span style="color: blue">)</span><span style="color: blue">:</span><br>
  req = WebRequest<span style="color: blue">.</span>Create<span style="color: blue">(</span>url<span style="color: blue">)</span><br>
  req<span style="color: blue">.</span>Accept = contentType 
<br>
  req<span style="color: blue">.</span>ContentType = contentType 
<br>
  req<span style="color: blue">.</span>Headers<span style="color: blue">.</span>Add<span style="color: blue">(</span>HttpRequestHeader<span style="color: blue">.</span>Authorization,
authToken<span style="color: blue">)</span><br>
   
<br>
  <span style="color: blue">return</span> req<span style="color: blue">.</span>GetResponse<span style="color: blue">(</span><span style="color: blue">)</span>  
<br>
   
<br><span style="color: blue">def</span> download_json<span style="color: blue">(</span>url,
authToken<span style="color: blue">)</span><span style="color: blue">:</span><br>
  resp = download<span style="color: blue">(</span>url, <span style="color: maroon">'application/json'</span>,
authToken<span style="color: blue">)</span><br>
  <span style="color: blue">with</span> StreamReader<span style="color: blue">(</span>resp<span style="color: blue">.</span>GetResponseStream<span style="color: blue">(</span><span style="color: blue">)</span><span style="color: blue">)</span> <span style="color: blue">as</span> reader<span style="color: blue">:</span>  
<br>
      data = reader<span style="color: blue">.</span>ReadToEnd<span style="color: blue">(</span><span style="color: blue">)</span><br>
      <span style="color: blue">return</span> eval<span style="color: blue">(</span>data<span style="color: blue">)</span><br><br><span style="color: blue">def</span> download_pox<span style="color: blue">(</span>url,
authToken<span style="color: blue">)</span><span style="color: blue">:</span><br>
  resp = download<span style="color: blue">(</span>url, <span style="color: maroon">'text/xml'</span>,
authToken<span style="color: blue">)</span><br>
  <span style="color: blue">return</span> XmlReader<span style="color: blue">.</span>Create<span style="color: blue">(</span>resp<span style="color: blue">.</span>GetResponseStream<span style="color: blue">(</span><span style="color: blue">)</span><span style="color: blue">)</span><br></div>
        <p>
Using JSON in Python is really easy, since I can simply eval the returned string and
get back Python dictionary objects, similar to what you can do in Javascript. 
</p>
        <p>
Here’s some code that uses the get_WL_ticket and download_json functions above to
retrieve the the user’s Personal Status Message
</p>
        <div style="font-family: consolas,lucida console,courier new">
          <span style="color: green">#Get
user's WL ticket</span>
          <br>
uid = raw_input<span style="color: blue">(</span><span style="color: maroon">"enter
WL ID: "</span><span style="color: blue">)</span>    
<br>
pwd = raw_input<span style="color: blue">(</span><span style="color: maroon">"enter
password: "</span><span style="color: blue">)</span>   
<br><br>
authToken = livefx_http<span style="color: blue">.</span>get_WL_ticket<span style="color: blue">(</span>uid,
pwd, True<span style="color: blue">)</span>   
<br><br><span style="color: green">#download root service document </span><br>
service = livefx_http<span style="color: blue">.</span>download_json<span style="color: blue">(</span>_LiveFxUri,
authToken<span style="color: blue">)</span>   
<br><br><span style="color: green">#download general profile document </span><br>
url = service<span style="color: blue">[</span><span style="color: maroon">'BaseUri'</span><span style="color: blue">]</span> +
service<span style="color: blue">[</span><span style="color: maroon">'ProfilesLink'</span><span style="color: blue">]</span> + <span style="color: maroon">"/G3N3RaL"</span>   
<br><br>
genprofile = livefx_http<span style="color: blue">.</span>download_json<span style="color: blue">(</span>url,
authToken<span style="color: blue">)</span>   
<br><span style="color: blue">print</span> genprofile<span style="color: blue">[</span><span style="color: maroon">'ProfileBase'</span><span style="color: blue">]</span><span style="color: blue">[</span><span style="color: maroon">'PersonalStatusMessage'</span><span style="color: blue">]</span></div>
        <p>
POX is also fairly easy, though a bit more verbose than JSON. The sample code, which
I have <a href="http://cid-0d9bc809858885a4.skydrive.live.com/self.aspx/DevHawk%20Content/IronPython%20Stuff/LiveFxHttp.zip">stuck
on my SkyDrive</a>, includes both POX and JSON code, so you can compare and contrast
the differences. 
</p>
        <img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=47b36a30-e4af-42a0-8609-fbc0a83fe083"></img>
      <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Devhawk?a=9gNf3w.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=9gNf3w.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=7CL2RL.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=7CL2RL.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=w1S3Jv.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=w1S3Jv.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=2t0NDX.p"><img src="http://feeds.feedburner.com/~f/Devhawk?i=2t0NDX.p" border="0"></img></a>
</div>]]></content:encoded><description>&lt;p&gt;
One of the cool things about the Live Framework is that while there’s a &lt;a href="http://msdn.microsoft.com/en-us/library/dd136352.aspx"&gt;convenient
.NET library available&lt;/a&gt;, you can use the &lt;a href="http://msdn.microsoft.com/en-us/library/dd199240.aspx"&gt;raw
HTTP interface&lt;/a&gt; from any platform. LiveFX data is served up over HTTP and is available
in ATOM, RSS, JSON or POX formats. As I’ve already shown, you can easily use the .NET
library from IronPython, but I wanted to try working with the raw HTTP interface to
get a feel for that as well.
&lt;/p&gt;
&lt;p&gt;
Unfortunately, it was harder than I expected it to be. The big issue is that the documentation
on how to LiveFX authorization tokens via raw HTTP is fairly sparse and occasionally
contradictory. For example, there’s a whole section on &lt;a href="http://msdn.microsoft.com/en-us/library/dd137185.aspx"&gt;Authentication
and Live Framework&lt;/a&gt;, but it doesn’t cover this scenario. Luckily, I was able to
figure it out with the help of &lt;a href="http://msdn.microsoft.com/en-us/library/dd135995.aspx"&gt;AtomPub
Project Manager LiveFX Sample&lt;/a&gt;, a &lt;a href="http://blog.opennetcf.com/afeinman/PermaLink,guid,80ea4a1d-fbc0-485d-a088-fb8f30efb6ab.aspx"&gt;post
on Alex Feinman’s blog&lt;/a&gt;, a &lt;a href="http://blogs.msdn.com/emesas/archive/2008/02/13/windows-live-id-available-options-part-i.aspx"&gt;post
on Emmanuel Mesas’ blog&lt;/a&gt; and a little groveling around with Reflector. It does
appear that the auth docs are in flux –Emmanuel refers to &lt;a href="http://msdn.microsoft.com/en-us/library/bb447721.aspx"&gt;this
MSDN article&lt;/a&gt; as being about RPS Soap requests, but it’s actually about delegated
authority. (Is MSDN reusing URLs? Bad idea.) Also, the sample code has a comment that
reads “to be replaced by delegated authorization” so it looks like changes are coming.
In other words, no promises on how long this code will work!
&lt;/p&gt;
&lt;p&gt;
If you look at the AtomPub Project Manager sample, there’s a WindowsLiveIdentity.cs
file that implements static GetTicket method that looks similar to both the code on
Alex’s blog as well as the implementation of &lt;a href="http://msdn.microsoft.com/en-us/library/dd157462.aspx"&gt;GetWindowsLiveAuthenticationToken&lt;/a&gt;.
The upshot is that there’s a &lt;a href="http://en.wikipedia.org/wiki/WS-Trust"&gt;WS-Trust&lt;/a&gt; endpoint
for Windows Live at &lt;a href="https://dev.login.live.com/wstlogin.srf"&gt;https://dev.login.live.com/wstlogin.srf&lt;/a&gt;.
You send it a RequestSecurityToken (aka RST) message (with a couple of extra WL specific
extensions) and it responds with the security token you’ll need for accessing the
LiveFx HTTP endpoints. 
&lt;/p&gt;
&lt;p&gt;
I ported the GetTicket function over to IronPython. I’m using .NET classes like WebRequest
and XmlReader, but there’s nothing fancy here so I would expect it to be easy enough
to port over to the standard Python library.
&lt;/p&gt;
&lt;div style="font-family: consolas,lucida console,courier new"&gt;&lt;span style="color: blue"&gt;def&lt;/span&gt; get_WL_ticket&lt;span style="color: blue"&gt;(&lt;/span&gt;username,
password, compactTicket&lt;span style="color: blue"&gt;)&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; req = WebRequest&lt;span style="color: blue"&gt;.&lt;/span&gt;Create&lt;span style="color: blue"&gt;(&lt;/span&gt;_LoginEndPoint&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; req&lt;span style="color: blue"&gt;.&lt;/span&gt;Method = &lt;span style="color: maroon"&gt;&amp;quot;POST&amp;quot;&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; req&lt;span style="color: blue"&gt;.&lt;/span&gt;ContentType = &lt;span style="color: maroon"&gt;&amp;quot;application/soap+xml;
charset=UTF-8&amp;quot;&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; req&lt;span style="color: blue"&gt;.&lt;/span&gt;Timeout = &lt;span style="color: maroon"&gt;30&lt;/span&gt; * &lt;span style="color: maroon"&gt;10000&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; rst = get_RST_message&lt;span style="color: blue"&gt;(&lt;/span&gt;username,
password, compactTicket&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; rstbytes = Encoding&lt;span style="color: blue"&gt;.&lt;/span&gt;UTF8&lt;span style="color: blue"&gt;.&lt;/span&gt;GetBytes&lt;span style="color: blue"&gt;(&lt;/span&gt;rst&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;with&lt;/span&gt; req&lt;span style="color: blue"&gt;.&lt;/span&gt;GetRequestStream&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;as&lt;/span&gt; reqstm&lt;span style="color: blue"&gt;:&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; reqstm&lt;span style="color: blue"&gt;.&lt;/span&gt;Write&lt;span style="color: blue"&gt;(&lt;/span&gt;rstbytes, &lt;span style="color: maroon"&gt;0&lt;/span&gt;,
rstbytes&lt;span style="color: blue"&gt;.&lt;/span&gt;Length&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;with&lt;/span&gt; req&lt;span style="color: blue"&gt;.&lt;/span&gt;GetResponse&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;as&lt;/span&gt; resp&lt;span style="color: blue"&gt;:&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;with&lt;/span&gt; resp&lt;span style="color: blue"&gt;.&lt;/span&gt;GetResponseStream&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;as&lt;/span&gt; respstm&lt;span style="color: blue"&gt;:&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;with&lt;/span&gt; XmlReader&lt;span style="color: blue"&gt;.&lt;/span&gt;Create&lt;span style="color: blue"&gt;(&lt;/span&gt;respstm&lt;span style="color: blue"&gt;)&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;as&lt;/span&gt; reader&lt;span style="color: blue"&gt;:&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;if&lt;/span&gt; compactTicket&lt;span style="color: blue"&gt;:&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; name = &lt;span style="color: maroon"&gt;&amp;quot;BinarySecurityToken&amp;quot;&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; namespace = &lt;span style="color: maroon"&gt;&amp;quot;http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd&amp;quot;&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;else&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; name = &lt;span style="color: maroon"&gt;&amp;quot;RequestedSecurityToken&amp;quot;&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; namespace = &lt;span style="color: maroon"&gt;&amp;quot;http://schemas.xmlsoap.org/ws/2005/02/trust&amp;quot;&lt;/span&gt; 
&lt;br /&gt;
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;if&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;not&lt;/span&gt; reader&lt;span style="color: blue"&gt;.&lt;/span&gt;ReadToDescendant&lt;span style="color: blue"&gt;(&lt;/span&gt;name,
namespace&lt;span style="color: blue"&gt;)&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;raise&lt;/span&gt;&amp;#160;&lt;span style="color: maroon"&gt;&amp;quot;couldn't
find security token element&amp;quot;&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; reader&lt;span style="color: blue"&gt;.&lt;/span&gt;ReadStartElement&lt;span style="color: blue"&gt;(&lt;/span&gt;name,
namespace&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; token = reader&lt;span style="color: blue"&gt;.&lt;/span&gt;ReadContentAsString&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; reader&lt;span style="color: blue"&gt;.&lt;/span&gt;ReadEndElement&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt; Convert&lt;span style="color: blue"&gt;.&lt;/span&gt;ToBase64String&lt;span style="color: blue"&gt;(&lt;/span&gt;Encoding&lt;span style="color: blue"&gt;.&lt;/span&gt;UTF8&lt;span style="color: blue"&gt;.&lt;/span&gt;GetBytes&lt;span style="color: blue"&gt;(&lt;/span&gt;token&lt;span style="color: blue"&gt;)&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt;
&lt;/div&gt;
&lt;p&gt;
This code simply uses a WebRequest object to post the RST message to the WS-Trust
enpoint then parses the result to find the token. get_RST_message uses &lt;a href="http://www.python.org/doc/2.5.2/lib/typesseq-strings.html"&gt;standard
Python string formatting&lt;/a&gt; to generate the RST message that gets posted to the WS-Trust
endpoint. I’m not exactly sure why you need to convert the token value to a byte array
and then Base64 encode it, but that’s what the sample code does so I did it to.
&lt;/p&gt;
&lt;p&gt;
Once you have the authentication ticket, you need to download root service endpoint
document in order to get the base URL and the profiles link. Then you can download
all the profiles or you can download a specific one if you know it’s &lt;a href="http://orand.blogspot.com/2008/11/l1v3-m35h-l337-h4x0rz.html"&gt;leet-speak
identifier&lt;/a&gt;. LiveFX data can be downloaded in a variety of formats: ATOM, JSON,
RSS or POX. You choose your format by setting the Accept and Content-Type headers. 
&lt;/p&gt;
&lt;p&gt;
I wrote the following functions, the generic boilerplate download function as well
a specific versions for downloading JSON and POX:
&lt;/p&gt;
&lt;div style="font-family: consolas,lucida console,courier new"&gt;&lt;span style="color: blue"&gt;def&lt;/span&gt; download&lt;span style="color: blue"&gt;(&lt;/span&gt;url,
contentType, authToken&lt;span style="color: blue"&gt;)&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt; 
&lt;br /&gt;
&amp;#160; req = WebRequest&lt;span style="color: blue"&gt;.&lt;/span&gt;Create&lt;span style="color: blue"&gt;(&lt;/span&gt;url&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&amp;#160; req&lt;span style="color: blue"&gt;.&lt;/span&gt;Accept = contentType 
&lt;br /&gt;
&amp;#160; req&lt;span style="color: blue"&gt;.&lt;/span&gt;ContentType = contentType 
&lt;br /&gt;
&amp;#160; req&lt;span style="color: blue"&gt;.&lt;/span&gt;Headers&lt;span style="color: blue"&gt;.&lt;/span&gt;Add&lt;span style="color: blue"&gt;(&lt;/span&gt;HttpRequestHeader&lt;span style="color: blue"&gt;.&lt;/span&gt;Authorization,
authToken&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160; 
&lt;br /&gt;
&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt; req&lt;span style="color: blue"&gt;.&lt;/span&gt;GetResponse&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt;&amp;#160; 
&lt;br /&gt;
&amp;#160;&amp;#160; 
&lt;br /&gt;
&lt;span style="color: blue"&gt;def&lt;/span&gt; download_json&lt;span style="color: blue"&gt;(&lt;/span&gt;url,
authToken&lt;span style="color: blue"&gt;)&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt; 
&lt;br /&gt;
&amp;#160; resp = download&lt;span style="color: blue"&gt;(&lt;/span&gt;url, &lt;span style="color: maroon"&gt;'application/json'&lt;/span&gt;,
authToken&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&amp;#160; &lt;span style="color: blue"&gt;with&lt;/span&gt; StreamReader&lt;span style="color: blue"&gt;(&lt;/span&gt;resp&lt;span style="color: blue"&gt;.&lt;/span&gt;GetResponseStream&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt;&amp;#160;&lt;span style="color: blue"&gt;as&lt;/span&gt; reader&lt;span style="color: blue"&gt;:&lt;/span&gt;&amp;#160; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; data = reader&lt;span style="color: blue"&gt;.&lt;/span&gt;ReadToEnd&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt; eval&lt;span style="color: blue"&gt;(&lt;/span&gt;data&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue"&gt;def&lt;/span&gt; download_pox&lt;span style="color: blue"&gt;(&lt;/span&gt;url,
authToken&lt;span style="color: blue"&gt;)&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt; 
&lt;br /&gt;
&amp;#160; resp = download&lt;span style="color: blue"&gt;(&lt;/span&gt;url, &lt;span style="color: maroon"&gt;'text/xml'&lt;/span&gt;,
authToken&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&amp;#160; &lt;span style="color: blue"&gt;return&lt;/span&gt; XmlReader&lt;span style="color: blue"&gt;.&lt;/span&gt;Create&lt;span style="color: blue"&gt;(&lt;/span&gt;resp&lt;span style="color: blue"&gt;.&lt;/span&gt;GetResponseStream&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;
Using JSON in Python is really easy, since I can simply eval the returned string and
get back Python dictionary objects, similar to what you can do in Javascript. 
&lt;/p&gt;
&lt;p&gt;
Here’s some code that uses the get_WL_ticket and download_json functions above to
retrieve the the user’s Personal Status Message
&lt;/p&gt;
&lt;div style="font-family: consolas,lucida console,courier new"&gt;&lt;span style="color: green"&gt;#Get
user's WL ticket&lt;/span&gt; 
&lt;br /&gt;
uid = raw_input&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: maroon"&gt;&amp;quot;enter
WL ID: &amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt;&amp;#160;&amp;#160;&amp;#160; 
&lt;br /&gt;
pwd = raw_input&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: maroon"&gt;&amp;quot;enter
password: &amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt;&amp;#160;&amp;#160; 
&lt;br /&gt;
&lt;br /&gt;
authToken = livefx_http&lt;span style="color: blue"&gt;.&lt;/span&gt;get_WL_ticket&lt;span style="color: blue"&gt;(&lt;/span&gt;uid,
pwd, True&lt;span style="color: blue"&gt;)&lt;/span&gt;&amp;#160;&amp;#160; 
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: green"&gt;#download root service document &lt;/span&gt; 
&lt;br /&gt;
service = livefx_http&lt;span style="color: blue"&gt;.&lt;/span&gt;download_json&lt;span style="color: blue"&gt;(&lt;/span&gt;_LiveFxUri,
authToken&lt;span style="color: blue"&gt;)&lt;/span&gt;&amp;#160;&amp;#160; 
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: green"&gt;#download general profile document &lt;/span&gt; 
&lt;br /&gt;
url = service&lt;span style="color: blue"&gt;[&lt;/span&gt;&lt;span style="color: maroon"&gt;'BaseUri'&lt;/span&gt;&lt;span style="color: blue"&gt;]&lt;/span&gt; +
service&lt;span style="color: blue"&gt;[&lt;/span&gt;&lt;span style="color: maroon"&gt;'ProfilesLink'&lt;/span&gt;&lt;span style="color: blue"&gt;]&lt;/span&gt; + &lt;span style="color: maroon"&gt;&amp;quot;/G3N3RaL&amp;quot;&lt;/span&gt;&amp;#160;&amp;#160; 
&lt;br /&gt;
&lt;br /&gt;
genprofile = livefx_http&lt;span style="color: blue"&gt;.&lt;/span&gt;download_json&lt;span style="color: blue"&gt;(&lt;/span&gt;url,
authToken&lt;span style="color: blue"&gt;)&lt;/span&gt;&amp;#160;&amp;#160; 
&lt;br /&gt;
&lt;span style="color: blue"&gt;print&lt;/span&gt; genprofile&lt;span style="color: blue"&gt;[&lt;/span&gt;&lt;span style="color: maroon"&gt;'ProfileBase'&lt;/span&gt;&lt;span style="color: blue"&gt;]&lt;/span&gt;&lt;span style="color: blue"&gt;[&lt;/span&gt;&lt;span style="color: maroon"&gt;'PersonalStatusMessage'&lt;/span&gt;&lt;span style="color: blue"&gt;]&lt;/span&gt;
&lt;/div&gt;
&lt;p&gt;
POX is also fairly easy, though a bit more verbose than JSON. The sample code, which
I have &lt;a href="http://cid-0d9bc809858885a4.skydrive.live.com/self.aspx/DevHawk%20Content/IronPython%20Stuff/LiveFxHttp.zip"&gt;stuck
on my SkyDrive&lt;/a&gt;, includes both POX and JSON code, so you can compare and contrast
the differences. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=47b36a30-e4af-42a0-8609-fbc0a83fe083" /&gt;</description><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://devhawk.net/Trackback.aspx?guid=47b36a30-e4af-42a0-8609-fbc0a83fe083</trackback:ping><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/pingback.aspx</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/PermaLink,guid,47b36a30-e4af-42a0-8609-fbc0a83fe083.aspx</pingback:target><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/CommentView,guid,47b36a30-e4af-42a0-8609-fbc0a83fe083.aspx</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/SyndicationService.asmx/GetEntryCommentsRss?guid=47b36a30-e4af-42a0-8609-fbc0a83fe083</wfw:commentRss><feedburner:origLink>http://devhawk.net/2008/12/16/IronPython+And+LiveFX+Raw+HTTP+Access.aspx</feedburner:origLink></item><item><title>IronPython and LiveFX: Ori&amp;rsquo;s LiveOE.py</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/486822772/IronPython+And+LiveFX+Orirsquos+LiveOEpy.aspx</link><category>IronPython</category><category>Live Framework</category><category>Windows Live</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Harry Pierson</dc:creator><pubDate>Tue, 16 Dec 2008 12:09:54 -0600</pubDate><guid isPermaLink="false">http://devhawk.net/PermaLink,guid,ae997eb7-047f-4600-8b5d-e0f43c59bddd.aspx</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
        <p>
          <a href="http://blogs.msdn.com/oriamiga/">Ori Amiga</a> is a Group Program Manager
over in the Live Framework team whom you might have seen at PDC08 delivering the <a href="http://channel9.msdn.com/pdc2008/BB04/">Lap
Around LiveFX &amp; Mesh Services</a> and <a href="http://channel9.msdn.com/pdc2008/BB19/">LiveFX
Programming Model Architecture and Insights</a> talks. And apparently, he’s an IronPython
fan as posted a small <a href="http://blogs.msdn.com/oriamiga/archive/2008/11/09/livefx-using-ironpython.aspx">LiveFX
Python module</a> to his blog. It’s pretty simple – it only wraps Connect and ConnectLocal
- but it does cut about ten lines of path appending, reference adding and module importing
code into a single import statement. Here’s the profile access script from <a href="http://devhawk.net/2008/12/13/IronPython+And+LiveFX+Accessing+Profiles.aspx">my
last post</a> rewritten to use Ori’s LiveOE module.
</p>
        <div style="font-family: consolas,lucida console,courier new">
          <span style="color: blue">import</span> LiveOE 
<br><span style="color: blue">from</span> devhawk <span style="color: blue">import</span> linq 
<br><br>
uid = raw_input<span style="color: blue">(</span><span style="color: maroon">"Enter
Windows Live ID: "</span><span style="color: blue">)</span><br>
pwd = raw_input<span style="color: blue">(</span><span style="color: maroon">"Enter
Password: "</span><span style="color: blue">)</span><br><br>
loe = LiveOE<span style="color: blue">.</span>Connect<span style="color: blue">(</span>uid,
pwd<span style="color: blue">)</span><br><br>
general = linq<span style="color: blue">.</span>Single<span style="color: blue">(</span>loe<span style="color: blue">.</span>Profiles<span style="color: blue">.</span>Entries,  
<br>
  <span style="color: blue">lambda</span> e<span style="color: blue">:</span> e<span style="color: blue">.</span>Resource<span style="color: blue">.</span>Type
== LiveOE<span style="color: blue">.</span>ProfileResource<span style="color: blue">.</span>ProfileType<span style="color: blue">.</span>General<span style="color: blue">)</span><br><br><span style="color: blue">print</span> loe<span style="color: blue">.</span>Mesh<span style="color: blue">.</span>ProvisionedUser<span style="color: blue">.</span>Name 
<br><span style="color: blue">print</span> loe<span style="color: blue">.</span>Mesh<span style="color: blue">.</span>ProvisionedUser<span style="color: blue">.</span>Email 
<br><span style="color: blue">print</span> general<span style="color: blue">.</span>Resource<span style="color: blue">.</span>ProfileInfo<span style="color: blue">.</span>PersonalStatusMessage 
<br><span style="color: blue">print</span> linq<span style="color: blue">.</span>Count<span style="color: blue">(</span>loe<span style="color: blue">.</span>Contacts<span style="color: blue">.</span>Entries<span style="color: blue">)</span></div>
        <p>
FYI, make sure you update the sdkLibsPath in LiveOE.py – I’m not sure where Ori has
installed the LiveFX SDK, but it’s *not* in the location suggested by the read me
file.
</p>
        <p>
BTW, it turns out the <a href="http://social.msdn.microsoft.com/Forums/en-US/liveframework/thread/81ab8f62-3244-4ca5-b376-2d5879f47c9f/">WL
Profile information is read only</a> which answers a question I had. However, reading
the thread it sounds like they will eventually get around to making it read-write
at some point. 
</p>
        <img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=ae997eb7-047f-4600-8b5d-e0f43c59bddd"></img>
      <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Devhawk?a=EpsYtQ.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=EpsYtQ.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=pBOp2H.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=pBOp2H.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=TSem4r.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=TSem4r.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=e5W7xI.p"><img src="http://feeds.feedburner.com/~f/Devhawk?i=e5W7xI.p" border="0"></img></a>
</div>]]></content:encoded><description>&lt;p&gt;
&lt;a href="http://blogs.msdn.com/oriamiga/"&gt;Ori Amiga&lt;/a&gt; is a Group Program Manager
over in the Live Framework team whom you might have seen at PDC08 delivering the &lt;a href="http://channel9.msdn.com/pdc2008/BB04/"&gt;Lap
Around LiveFX &amp;amp; Mesh Services&lt;/a&gt; and &lt;a href="http://channel9.msdn.com/pdc2008/BB19/"&gt;LiveFX
Programming Model Architecture and Insights&lt;/a&gt; talks. And apparently, he’s an IronPython
fan as posted a small &lt;a href="http://blogs.msdn.com/oriamiga/archive/2008/11/09/livefx-using-ironpython.aspx"&gt;LiveFX
Python module&lt;/a&gt; to his blog. It’s pretty simple – it only wraps Connect and ConnectLocal
- but it does cut about ten lines of path appending, reference adding and module importing
code into a single import statement. Here’s the profile access script from &lt;a href="http://devhawk.net/2008/12/13/IronPython+And+LiveFX+Accessing+Profiles.aspx"&gt;my
last post&lt;/a&gt; rewritten to use Ori’s LiveOE module.
&lt;/p&gt;
&lt;div style="font-family: consolas,lucida console,courier new"&gt;&lt;span style="color: blue"&gt;import&lt;/span&gt; LiveOE 
&lt;br /&gt;
&lt;span style="color: blue"&gt;from&lt;/span&gt; devhawk &lt;span style="color: blue"&gt;import&lt;/span&gt; linq 
&lt;br /&gt;
&lt;br /&gt;
uid = raw_input&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: maroon"&gt;&amp;quot;Enter
Windows Live ID: &amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
pwd = raw_input&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: maroon"&gt;&amp;quot;Enter
Password: &amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&lt;br /&gt;
loe = LiveOE&lt;span style="color: blue"&gt;.&lt;/span&gt;Connect&lt;span style="color: blue"&gt;(&lt;/span&gt;uid,
pwd&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&lt;br /&gt;
general = linq&lt;span style="color: blue"&gt;.&lt;/span&gt;Single&lt;span style="color: blue"&gt;(&lt;/span&gt;loe&lt;span style="color: blue"&gt;.&lt;/span&gt;Profiles&lt;span style="color: blue"&gt;.&lt;/span&gt;Entries,&amp;#160; 
&lt;br /&gt;
&amp;#160; &lt;span style="color: blue"&gt;lambda&lt;/span&gt; e&lt;span style="color: blue"&gt;:&lt;/span&gt; e&lt;span style="color: blue"&gt;.&lt;/span&gt;Resource&lt;span style="color: blue"&gt;.&lt;/span&gt;Type
== LiveOE&lt;span style="color: blue"&gt;.&lt;/span&gt;ProfileResource&lt;span style="color: blue"&gt;.&lt;/span&gt;ProfileType&lt;span style="color: blue"&gt;.&lt;/span&gt;General&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue"&gt;print&lt;/span&gt; loe&lt;span style="color: blue"&gt;.&lt;/span&gt;Mesh&lt;span style="color: blue"&gt;.&lt;/span&gt;ProvisionedUser&lt;span style="color: blue"&gt;.&lt;/span&gt;Name 
&lt;br /&gt;
&lt;span style="color: blue"&gt;print&lt;/span&gt; loe&lt;span style="color: blue"&gt;.&lt;/span&gt;Mesh&lt;span style="color: blue"&gt;.&lt;/span&gt;ProvisionedUser&lt;span style="color: blue"&gt;.&lt;/span&gt;Email 
&lt;br /&gt;
&lt;span style="color: blue"&gt;print&lt;/span&gt; general&lt;span style="color: blue"&gt;.&lt;/span&gt;Resource&lt;span style="color: blue"&gt;.&lt;/span&gt;ProfileInfo&lt;span style="color: blue"&gt;.&lt;/span&gt;PersonalStatusMessage 
&lt;br /&gt;
&lt;span style="color: blue"&gt;print&lt;/span&gt; linq&lt;span style="color: blue"&gt;.&lt;/span&gt;Count&lt;span style="color: blue"&gt;(&lt;/span&gt;loe&lt;span style="color: blue"&gt;.&lt;/span&gt;Contacts&lt;span style="color: blue"&gt;.&lt;/span&gt;Entries&lt;span style="color: blue"&gt;)&lt;/span&gt;
&lt;/div&gt;
&lt;p&gt;
FYI, make sure you update the sdkLibsPath in LiveOE.py – I’m not sure where Ori has
installed the LiveFX SDK, but it’s *not* in the location suggested by the read me
file.
&lt;/p&gt;
&lt;p&gt;
BTW, it turns out the &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/liveframework/thread/81ab8f62-3244-4ca5-b376-2d5879f47c9f/"&gt;WL
Profile information is read only&lt;/a&gt; which answers a question I had. However, reading
the thread it sounds like they will eventually get around to making it read-write
at some point. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=ae997eb7-047f-4600-8b5d-e0f43c59bddd" /&gt;</description><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://devhawk.net/Trackback.aspx?guid=ae997eb7-047f-4600-8b5d-e0f43c59bddd</trackback:ping><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/pingback.aspx</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/PermaLink,guid,ae997eb7-047f-4600-8b5d-e0f43c59bddd.aspx</pingback:target><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/CommentView,guid,ae997eb7-047f-4600-8b5d-e0f43c59bddd.aspx</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/SyndicationService.asmx/GetEntryCommentsRss?guid=ae997eb7-047f-4600-8b5d-e0f43c59bddd</wfw:commentRss><feedburner:origLink>http://devhawk.net/2008/12/16/IronPython+And+LiveFX+Orirsquos+LiveOEpy.aspx</feedburner:origLink></item><item><title>IronPython and LiveFX: Accessing Profiles</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/483217210/IronPython+And+LiveFX+Accessing+Profiles.aspx</link><category>IronPython</category><category>Live Framework</category><category>Windows Live</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Harry Pierson</dc:creator><pubDate>Fri, 12 Dec 2008 19:50:08 -0600</pubDate><guid isPermaLink="false">http://devhawk.net/PermaLink,guid,95b8da55-983a-4485-ae88-89c0a375e3cb.aspx</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
        <p>
I recently got access to both the <a href="http://www.microsoft.com/azure/windowsazure.mspx">Windows
Azure</a> and <a href="http://dev.live.com/liveframework/">Live Framework</a> CTP
programs. Frankly, I’m very interested in <a href="https://www.mesh.com">Live Mesh</a>,
so I decided to start with a simple LiveFX program. Scott (aka <a href="http://www.liveside.net/members/ScottIsAFool/default.aspx">ScottIsAFool</a>)
at <a href="http://www.liveside.net">LiveSide</a> posted a <a href="http://www.liveside.net/developer/archive/2008/11/10/a-quick-and-dirty-console-application-using-the-livefx.aspx">“quick
and dirty” console app</a> that pulls info from a user’s profile via LiveFx. It’s
not Mesh per se, but it does use the same framework and resource model so I decided
to port it to IronPython. FYI, this app won’t run unless you’ve been received a LiveFx
CTP token and provisioned yourself. 
</p>
        <div style="font-family: consolas,lucida console,courier new">
          <span style="color: blue">#</span>Add
LiveFX References 
<br><span style="color: blue">import</span> sys 
<br>
sys<span style="color: blue">.</span>path<span style="color: blue">.</span>append<span style="color: blue">(</span><span style="color: maroon">'C:\\Program
Files\\Microsoft SDKs\\Live Framework SDK\\v0.9\\Libraries\\.Net Library'</span><span style="color: blue">)</span><br><br><span style="color: blue">import</span> clr 
<br>
clr<span style="color: blue">.</span>AddReference<span style="color: blue">(</span><span style="color: maroon">'Microsoft.LiveFX.Client'</span><span style="color: blue">)</span><br>
clr<span style="color: blue">.</span>AddReference<span style="color: blue">(</span><span style="color: maroon">'Microsoft.LiveFX.ResourceModel'</span><span style="color: blue">)</span><br><br><span style="color: blue">from</span> Microsoft<span style="color: blue">.</span>LiveFX<span style="color: blue">.</span>Client <span style="color: blue">import</span> LiveOperatingEnvironment 
<br><span style="color: blue">from</span> Microsoft<span style="color: blue">.</span>LiveFX<span style="color: blue">.</span>ResourceModel<span style="color: blue">.</span>ProfileResource <span style="color: blue">import</span> ProfileType 
<br><span style="color: blue">from</span> System<span style="color: blue">.</span>Net <span style="color: blue">import</span> NetworkCredential 
<br><br><span style="color: blue">from</span> devhawk <span style="color: blue">import</span> linq 
<br><br><span style="color: blue">#</span>get username <span style="color: blue">and</span> password <span style="color: blue">from</span> the
user 
<br>
uid = raw_input<span style="color: blue">(</span><span style="color: maroon">"Enter
Windows Live ID: "</span><span style="color: blue">)</span><br>
pwd = raw_input<span style="color: blue">(</span><span style="color: maroon">"Enter
Password: "</span><span style="color: blue">)</span><br>
creds = NetworkCredential<span style="color: blue">(</span>uid, pwd, <span style="color: maroon">"https://user-ctp.windows.net"</span><span style="color: blue">)</span><br><br><span style="color: blue">#</span><span style="color: blue">print</span> out user's
info 
<br>
loe = LiveOperatingEnvironment<span style="color: blue">(</span><span style="color: blue">)</span><br>
loe<span style="color: blue">.</span>Connect<span style="color: blue">(</span>creds<span style="color: blue">)</span><br><br>
general = linq<span style="color: blue">.</span>Single<span style="color: blue">(</span>loe<span style="color: blue">.</span>Profiles<span style="color: blue">.</span>Entries,  
<br>
  <span style="color: blue">lambda</span> e<span style="color: blue">:</span> e<span style="color: blue">.</span>Resource<span style="color: blue">.</span>Type
== ProfileType<span style="color: blue">.</span>General<span style="color: blue">)</span><br><br><span style="color: blue">print</span> loe<span style="color: blue">.</span>Mesh<span style="color: blue">.</span>ProvisionedUser<span style="color: blue">.</span>Name 
<br><span style="color: blue">print</span> loe<span style="color: blue">.</span>Mesh<span style="color: blue">.</span>ProvisionedUser<span style="color: blue">.</span>Email 
<br><span style="color: blue">print</span> general<span style="color: blue">.</span>Resource<span style="color: blue">.</span>ProfileInfo<span style="color: blue">.</span>PersonalStatusMessage 
<br><span style="color: blue">print</span> linq<span style="color: blue">.</span>Count<span style="color: blue">(</span>loe<span style="color: blue">.</span>Contacts<span style="color: blue">.</span>Entries<span style="color: blue">)</span></div>
        <p>
I did modify the app slightly, reading the WLID and password off the console – I was
*sure* I would accidently post my personal credentials if I left them embedded in
the app. Otherwise, it’s a straight port. First, I add references the LiveFX dlls.
Since they’re not local to my script, I add the directory where they’re installed
to sys.path, which lets me call clr.AddReference directly. Then I retrieve the user’s
ID and password using raw_input (Python’s equivalent to Console.ReadLine). Finally,
I connect to the user’s LiveOperatingEnvironment and pull their name, email address,
personal status message and the number of contacts they have. 
</p>
        <p>
As per the original app, I use LINQ to find the right profile as well as count the
number of contacts. I was able to reuse the linq.py file I wrote for my <a href="http://devhawk.net/2008/11/27/IronPython+And+Linq+To+XML+Part+2+Screen+Scraping.aspx">Rock
Band song list screen scraper</a> (though I did have to add the Count function since
I hadn’t needed it previously). I’ve posted <a href="http://cid-0d9bc809858885a4.skydrive.live.com/self.aspx/DevHawk%20Content/IronPython%20Stuff/LiveFxPsmDemo.zip">this
script</a> on my SkyDrive, and it includes my most recent linq.py file.
</p>
        <p>
BTW, it doesn’t appear that you can set the PersonalStatusMessage programmatically,
at least not currently. I was thinking it would be cool to build an app that sets
your PSM via Twitter, but the set method of PersonalStatusMessage is marked internal.
In fact, all the set methods of all the profile properties I looked at are marked
internal. If someone knows how to update LiveFX resource objects in the current CTP,
I’d appreciate it if you dropped me a line or left me a comment.
</p>
        <img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=95b8da55-983a-4485-ae88-89c0a375e3cb"></img>
      <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Devhawk?a=xrc7zl.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=xrc7zl.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=lrGVdv.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=lrGVdv.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=TqJQNZ.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=TqJQNZ.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=tIeC9P.p"><img src="http://feeds.feedburner.com/~f/Devhawk?i=tIeC9P.p" border="0"></img></a>
</div>]]></content:encoded><description>&lt;p&gt;
I recently got access to both the &lt;a href="http://www.microsoft.com/azure/windowsazure.mspx"&gt;Windows
Azure&lt;/a&gt; and &lt;a href="http://dev.live.com/liveframework/"&gt;Live Framework&lt;/a&gt; CTP
programs. Frankly, I’m very interested in &lt;a href="https://www.mesh.com"&gt;Live Mesh&lt;/a&gt;,
so I decided to start with a simple LiveFX program. Scott (aka &lt;a href="http://www.liveside.net/members/ScottIsAFool/default.aspx"&gt;ScottIsAFool&lt;/a&gt;)
at &lt;a href="http://www.liveside.net"&gt;LiveSide&lt;/a&gt; posted a &lt;a href="http://www.liveside.net/developer/archive/2008/11/10/a-quick-and-dirty-console-application-using-the-livefx.aspx"&gt;“quick
and dirty” console app&lt;/a&gt; that pulls info from a user’s profile via LiveFx. It’s
not Mesh per se, but it does use the same framework and resource model so I decided
to port it to IronPython. FYI, this app won’t run unless you’ve been received a LiveFx
CTP token and provisioned yourself. 
&lt;/p&gt;
&lt;div style="font-family: consolas,lucida console,courier new"&gt;&lt;span style="color: blue"&gt;#&lt;/span&gt;Add
LiveFX References 
&lt;br /&gt;
&lt;span style="color: blue"&gt;import&lt;/span&gt; sys 
&lt;br /&gt;
sys&lt;span style="color: blue"&gt;.&lt;/span&gt;path&lt;span style="color: blue"&gt;.&lt;/span&gt;append&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: maroon"&gt;'C:\\Program
Files\\Microsoft SDKs\\Live Framework SDK\\v0.9\\Libraries\\.Net Library'&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue"&gt;import&lt;/span&gt; clr 
&lt;br /&gt;
clr&lt;span style="color: blue"&gt;.&lt;/span&gt;AddReference&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: maroon"&gt;'Microsoft.LiveFX.Client'&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
clr&lt;span style="color: blue"&gt;.&lt;/span&gt;AddReference&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: maroon"&gt;'Microsoft.LiveFX.ResourceModel'&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue"&gt;from&lt;/span&gt; Microsoft&lt;span style="color: blue"&gt;.&lt;/span&gt;LiveFX&lt;span style="color: blue"&gt;.&lt;/span&gt;Client &lt;span style="color: blue"&gt;import&lt;/span&gt; LiveOperatingEnvironment 
&lt;br /&gt;
&lt;span style="color: blue"&gt;from&lt;/span&gt; Microsoft&lt;span style="color: blue"&gt;.&lt;/span&gt;LiveFX&lt;span style="color: blue"&gt;.&lt;/span&gt;ResourceModel&lt;span style="color: blue"&gt;.&lt;/span&gt;ProfileResource &lt;span style="color: blue"&gt;import&lt;/span&gt; ProfileType 
&lt;br /&gt;
&lt;span style="color: blue"&gt;from&lt;/span&gt; System&lt;span style="color: blue"&gt;.&lt;/span&gt;Net &lt;span style="color: blue"&gt;import&lt;/span&gt; NetworkCredential 
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue"&gt;from&lt;/span&gt; devhawk &lt;span style="color: blue"&gt;import&lt;/span&gt; linq 
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue"&gt;#&lt;/span&gt;get username &lt;span style="color: blue"&gt;and&lt;/span&gt; password &lt;span style="color: blue"&gt;from&lt;/span&gt; the
user 
&lt;br /&gt;
uid = raw_input&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: maroon"&gt;&amp;quot;Enter
Windows Live ID: &amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
pwd = raw_input&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: maroon"&gt;&amp;quot;Enter
Password: &amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
creds = NetworkCredential&lt;span style="color: blue"&gt;(&lt;/span&gt;uid, pwd, &lt;span style="color: maroon"&gt;&amp;quot;https://user-ctp.windows.net&amp;quot;&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue"&gt;#&lt;/span&gt;&lt;span style="color: blue"&gt;print&lt;/span&gt; out user's
info 
&lt;br /&gt;
loe = LiveOperatingEnvironment&lt;span style="color: blue"&gt;(&lt;/span&gt;&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
loe&lt;span style="color: blue"&gt;.&lt;/span&gt;Connect&lt;span style="color: blue"&gt;(&lt;/span&gt;creds&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&lt;br /&gt;
general = linq&lt;span style="color: blue"&gt;.&lt;/span&gt;Single&lt;span style="color: blue"&gt;(&lt;/span&gt;loe&lt;span style="color: blue"&gt;.&lt;/span&gt;Profiles&lt;span style="color: blue"&gt;.&lt;/span&gt;Entries,&amp;#160; 
&lt;br /&gt;
&amp;#160; &lt;span style="color: blue"&gt;lambda&lt;/span&gt; e&lt;span style="color: blue"&gt;:&lt;/span&gt; e&lt;span style="color: blue"&gt;.&lt;/span&gt;Resource&lt;span style="color: blue"&gt;.&lt;/span&gt;Type
== ProfileType&lt;span style="color: blue"&gt;.&lt;/span&gt;General&lt;span style="color: blue"&gt;)&lt;/span&gt; 
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue"&gt;print&lt;/span&gt; loe&lt;span style="color: blue"&gt;.&lt;/span&gt;Mesh&lt;span style="color: blue"&gt;.&lt;/span&gt;ProvisionedUser&lt;span style="color: blue"&gt;.&lt;/span&gt;Name 
&lt;br /&gt;
&lt;span style="color: blue"&gt;print&lt;/span&gt; loe&lt;span style="color: blue"&gt;.&lt;/span&gt;Mesh&lt;span style="color: blue"&gt;.&lt;/span&gt;ProvisionedUser&lt;span style="color: blue"&gt;.&lt;/span&gt;Email 
&lt;br /&gt;
&lt;span style="color: blue"&gt;print&lt;/span&gt; general&lt;span style="color: blue"&gt;.&lt;/span&gt;Resource&lt;span style="color: blue"&gt;.&lt;/span&gt;ProfileInfo&lt;span style="color: blue"&gt;.&lt;/span&gt;PersonalStatusMessage 
&lt;br /&gt;
&lt;span style="color: blue"&gt;print&lt;/span&gt; linq&lt;span style="color: blue"&gt;.&lt;/span&gt;Count&lt;span style="color: blue"&gt;(&lt;/span&gt;loe&lt;span style="color: blue"&gt;.&lt;/span&gt;Contacts&lt;span style="color: blue"&gt;.&lt;/span&gt;Entries&lt;span style="color: blue"&gt;)&lt;/span&gt;
&lt;/div&gt;
&lt;p&gt;
I did modify the app slightly, reading the WLID and password off the console – I was
*sure* I would accidently post my personal credentials if I left them embedded in
the app. Otherwise, it’s a straight port. First, I add references the LiveFX dlls.
Since they’re not local to my script, I add the directory where they’re installed
to sys.path, which lets me call clr.AddReference directly. Then I retrieve the user’s
ID and password using raw_input (Python’s equivalent to Console.ReadLine). Finally,
I connect to the user’s LiveOperatingEnvironment and pull their name, email address,
personal status message and the number of contacts they have. 
&lt;/p&gt;
&lt;p&gt;
As per the original app, I use LINQ to find the right profile as well as count the
number of contacts. I was able to reuse the linq.py file I wrote for my &lt;a href="http://devhawk.net/2008/11/27/IronPython+And+Linq+To+XML+Part+2+Screen+Scraping.aspx"&gt;Rock
Band song list screen scraper&lt;/a&gt; (though I did have to add the Count function since
I hadn’t needed it previously). I’ve posted &lt;a href="http://cid-0d9bc809858885a4.skydrive.live.com/self.aspx/DevHawk%20Content/IronPython%20Stuff/LiveFxPsmDemo.zip"&gt;this
script&lt;/a&gt; on my SkyDrive, and it includes my most recent linq.py file.
&lt;/p&gt;
&lt;p&gt;
BTW, it doesn’t appear that you can set the PersonalStatusMessage programmatically,
at least not currently. I was thinking it would be cool to build an app that sets
your PSM via Twitter, but the set method of PersonalStatusMessage is marked internal.
In fact, all the set methods of all the profile properties I looked at are marked
internal. If someone knows how to update LiveFX resource objects in the current CTP,
I’d appreciate it if you dropped me a line or left me a comment.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=95b8da55-983a-4485-ae88-89c0a375e3cb" /&gt;</description><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://devhawk.net/Trackback.aspx?guid=95b8da55-983a-4485-ae88-89c0a375e3cb</trackback:ping><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/pingback.aspx</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/PermaLink,guid,95b8da55-983a-4485-ae88-89c0a375e3cb.aspx</pingback:target><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/CommentView,guid,95b8da55-983a-4485-ae88-89c0a375e3cb.aspx</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/SyndicationService.asmx/GetEntryCommentsRss?guid=95b8da55-983a-4485-ae88-89c0a375e3cb</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">2</slash:comments><feedburner:origLink>http://devhawk.net/2008/12/13/IronPython+And+LiveFX+Accessing+Profiles.aspx</feedburner:origLink></item><item><title>IronPython RTM News Gets Around</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/482188129/IronPython+RTM+News+Gets+Around.aspx</link><category>DLR</category><category>IronPython</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Harry Pierson</dc:creator><pubDate>Thu, 11 Dec 2008 18:49:15 -0600</pubDate><guid isPermaLink="false">http://devhawk.net/PermaLink,guid,023449f4-8755-4653-bd04-20ab9f1ef710.aspx</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
        <p>
I just hit the MSDN home page, and what should I see?
</p>
        <p>
          <a href="http://blogs.msdn.com/jasonz/archive/2008/12/11/ironpython-2-0-released.aspx">
            <img title="msdn Home" style="border-right: 0px; border-top: 0px; display: block; float: none; margin: 0px auto 10px; border-left: 0px; border-bottom: 0px" height="124" alt="msdn Home" src="http://devhawk.net/content/binary/WindowsLiveWriter/IronPythonRTMNewsGetsAround_EC8A/msdn%20Home_3.png" width="483" border="0"></img>
          </a>It’s
cool to see JasonZ, aka my group’s general manager, <a href="http://blogs.msdn.com/jasonz/archive/2008/12/11/ironpython-2-0-released.aspx">blogging</a> about
our product. 
</p>
        <p>
I also fired up Visual Studio, and <a href="http://codeplex.com/ironpython">IronPython</a> is
the top headline there too:
</p>
        <p>
          <img title="VS home" style="border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; border-left: 0px; margin-right: auto; border-bottom: 0px" height="457" alt="VS home" src="http://devhawk.net/content/binary/WindowsLiveWriter/IronPythonRTMNewsGetsAround_EC8A/VS%20home_3.png" width="621" border="0"></img>Not
sure why the news is dated September 18th, but hey it’s really cool to see IronPython
(not to mention the <a href="http://www.codeplex.com/dlr">DLR</a>, with the second
headline) getting this kind of visibility. 
</p>
        <img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=023449f4-8755-4653-bd04-20ab9f1ef710"></img>
      <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Devhawk?a=OyvSYq.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=OyvSYq.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=XdHq0s.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=XdHq0s.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=109jod.P"><img src="http://feeds.feedburner.com/~f/Devhawk?i=109jod.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=gNgnu2.p"><img src="http://feeds.feedburner.com/~f/Devhawk?i=gNgnu2.p" border="0"></img></a>
</div>]]></content:encoded><description>&lt;p&gt;
I just hit the MSDN home page, and what should I see?
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.msdn.com/jasonz/archive/2008/12/11/ironpython-2-0-released.aspx"&gt;&lt;img title="msdn Home" style="border-right: 0px; border-top: 0px; display: block; float: none; margin: 0px auto 10px; border-left: 0px; border-bottom: 0px" height="124" alt="msdn Home" src="http://devhawk.net/content/binary/WindowsLiveWriter/IronPythonRTMNewsGetsAround_EC8A/msdn%20Home_3.png" width="483" border="0" /&gt;&lt;/a&gt;It’s
cool to see JasonZ, aka my group’s general manager, &lt;a href="http://blogs.msdn.com/jasonz/archive/2008/12/11/ironpython-2-0-released.aspx"&gt;blogging&lt;/a&gt; about
our product. 
&lt;/p&gt;
&lt;p&gt;
I also fired up Visual Studio, and &lt;a href="http://codeplex.com/ironpython"&gt;IronPython&lt;/a&gt; is
the top headline there too:
&lt;/p&gt;
&lt;p&gt;
&lt;img title="VS home" style="border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; border-left: 0px; margin-right: auto; border-bottom: 0px" height="457" alt="VS home" src="http://devhawk.net/content/binary/WindowsLiveWriter/IronPythonRTMNewsGetsAround_EC8A/VS%20home_3.png" width="621" border="0" /&gt;Not
sure why the news is dated September 18th, but hey it’s really cool to see IronPython
(not to mention the &lt;a href="http://www.codeplex.com/dlr"&gt;DLR&lt;/a&gt;, with the second
headline) getting this kind of visibility. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=023449f4-8755-4653-bd04-20ab9f1ef710" /&gt;</description><trackback:ping xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">http://devhawk.net/Trackback.aspx?guid=023449f4-8755-4653-bd04-20ab9f1ef710</trackback:ping><pingback:server xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/pingback.aspx</pingback:server><pingback:target xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/">http://devhawk.net/PermaLink,guid,023449f4-8755-4653-bd04-20ab9f1ef710.aspx</pingback:target><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/CommentView,guid,023449f4-8755-4653-bd04-20ab9f1ef710.aspx</wfw:comment><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://devhawk.net/SyndicationService.asmx/GetEntryCommentsRss?guid=023449f4-8755-4653-bd04-20ab9f1ef710</wfw:commentRss><feedburner:origLink>http://devhawk.net/2008/12/12/IronPython+RTM+News+Gets+Around.aspx</feedburner:origLink></item><item><title>IPy RTW FTW!</title><link>http://feeds.feedburner.com/~r/Devhawk/~3/481049769/IPy+RTW+FTW.aspx</link><category>IronPython</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Harry Pierson</dc:creator><pubDate>Wed, 10 Dec 2008 16:57:30 -0600</pubDate><guid isPermaLink="false">http://devhawk.net/PermaLink,guid,9d513c68-87c3-4b16-a28f-ece87ad1ef65.aspx</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
        <p>
          <a href="http://www.codeplex.com/IronPython/Release/ProjectReleases.aspx?ReleaseId=8365">
            <img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin: 0px 5px 0px 0px; border-right-width: 0px" height="119" alt="image" src="http://devhawk.net/content/binary/WindowsLiveWriter/IPyRTWFTW_C47D/image_5.png" width="186" align="left" border="0"></img>
          </a>This
is a very pretty sight. It’s a screenshot from the IronPython CodePlex home page showing
that 2.0 is the “current release”. Yes that’s right, dear reader, IronPython 2.0 has
officially been released!
</p>
        <p>
          <a href="http://www.codeplex.com/IronPython/Release/ProjectReleases.aspx?ReleaseId=8365">Get
it now</a>!
</p>
        <p>
This release marks the end of a very busy year for me, nine months to the day since
I accepted the offer to <a href="http://devhawk.net/2008/03/11/Joining+The+Dynamic+Languages+Team.aspx">join
the dynamic languages team</a>. Between helping ship IronPython 2.0 and helping manage
the languages and tools PDC08 track, I’ve been swimming in the deep end of the pool
all year. Feels good to <em>not </em>have any immediate deliverables for the next
month or two.
</p>
        <p>
Major, <em>major</em> props to <a href="http://blogs.msdn.com/dinoviehland">Dino</a>, <a href="http://blogs.msdn.com/curth">IronCurt</a>, <a href="http://knowbody.livejournal.com/">Dave</a> and <a href="http://blogs.msdn.com/srivatsn">Srivatsn</a> who
have done the heavy lifting on the IPy side this release. Also major props to the
DLR team, who are releasing the final 0.9 version of the DLR later today in concert
with IPy 2.0. (Update: the <a href="http://www.codeplex.com/dlr/Release/ProjectReleases.aspx?ReleaseId=20378">DLR
0.9 RTW bits</a> are now available) And of course, HUGE HUGE HUGE thanks to the vibrant
IPy community, many of whom are listed by name in <a href="http://www.codeplex.com/IronPython/Wiki/View.aspx?title=v2.0.0%20Release%20Notes&amp;referringTitle=Home">the
release notes</a>.
</p>
        <p>
Even with 2.0 finally out the door, there’s no rest for the dynamic. As per the release
notes, “we’re planning on releasing IronPython 2.0.1 fairly soon” so keep those bug
reports coming. Going forward, we’ve got big plans for IronPython and we rely heavily
on the continued input from our community, so please keep telling us where we can
improve.
</p>
        <p>
On a personal note, the past nine months have been busy – very busy – but they’ve
also been a blast. Frankly, I was hesitant about joining the product groups for a
long time because I was worried about the grind, the culture, the overall experience.
Turns out my fears were overblown, though I’m thinking that’s at least partially related
to the fact that I work on a “little” project like IronPython rather than a huge project
like Visual Studio. 
</p>
        <img width="0" height="0" src="http://devhawk.net/aggbug.ashx?id=9d513c68-87c3-4b16-a28f-ece87ad1ef65"></img>
      <div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Devhawk?a=T8SbO"><img src="http://feeds.feedburner.com/~f/Devhawk?i=T8SbO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=TMjnO"><img src="http://feeds.feedburner.com/~f/Devhawk?i=TMjnO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=YRLGO"><img src="http://feeds.feedburner.com/~f/Devhawk?i=YRLGO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Devhawk?a=J6jLo"><img src="http://feeds.feedburner.com/~f/Devhawk?i=J6jLo" border="0"></img></a>
</div>]]></content:encoded><description>&lt;p&gt;
&lt;a href="http://www.codeplex.com/IronPython/Release/ProjectReleases.aspx?ReleaseId=8365"&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; margin: 0px 5px 0px 0px; border-right-width: 0px" height="119" alt="image" src="http://devhawk.net/content/binary/WindowsLiveWriter/IPyRTWFTW_C47D/image_5.png" width="186" align="left" border="0" /&gt;&lt;/a&gt;This
is a very pretty sight. It’s a screenshot from the IronPython CodePlex home page showing
that 2.0 is the “current release”. Yes that’s right, dear reader, IronPython 2.0 has
officially been released!
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.codeplex.com/IronPython/Release/ProjectReleases.aspx?ReleaseId=8365"&gt;Get
it now&lt;/a&gt;!
&lt;/p&gt;
&lt;p&gt;
This release marks the end of a very busy year for me, nine months to the day 