unethical blogger - Mono http://www.unethicalblogger.com/taxonomy/term/1/0 Posts related to the Mono Project en IronWatin; mind the gap http://www.unethicalblogger.com/posts/2009/10/ironwatin_mind_gap <p>Last week <a id="aptureLink_UJbJnwQvgk" href="http://twitter.com/admc">@admc,</a> despite being a big proponent of <a id="aptureLink_mV2RK9dLaN" href="http://twitter.com/windmillproject">Windmill</a>, needed to use WatiN for a change. <a id="aptureLink_sf9oXnu3uF" href="http://watin.sourceforge.net/">WatiN</a> has the distinct capability of being able to work with Internet Explorer's HTTPS support as well as frames, a requirement for the task at hand. As adorable as it was to watch <a id="aptureLink_zccUSsrvlx" href="http://twitter.com/admc">@admc,</a> a child of the dynamic language revolution, struggle with writing in C# with Visual Studio and the daunting "Windows development stack," the prospect of a language shift at Slide towards C# on Windows is almost laughable. Since <a id="aptureLink_oR2hGjfmlx" href="http://www.crunchbase.com/company/slide">Slide</a> is a Python shop, IronPython became the obvious choice.</p> <p>Out of an hour or so of "extreme programming" which mostly entailed Adam watching as I wrote IronPython in his Windows VM, <a href="http://github.com/rtyler/IronWatin"><strong>IronWatin</strong></a> was born. IronWatin itself is a <strong>very</strong> simple test runner that hooks into Python's <a id="aptureLink_SpWkHjDZgq" href="http://en.wikipedia.org/wiki/PyUnit">"unittest"</a> for creating integration tests with WatiN in a familiar environment.</p> <p>I intended IronWatin to be as easy as possible for "native Python" developers, by abstracting out updates to <code>sys.path</code> to include the Python standard lib (adds the standard locations for Python 2.5/2.6 on Windows) as well as adding <code>WatiN.Core.dll</code> via <code>clr.AddReference()</code> so developers can simply <code>import IronWatin; import WatiN.Core</code> and they're ready to start writing integration tests. When using IronWatin, you create test classes that subclass from <code>IronWatin.BrowserTest</code> which takes care of setting up a browser (WatiN.Core.IE/WatiN.Core.FireFox) instance to a specified URL, this leaves your <code>runTest()</code> method to actually execute the core of your test case.</p> <p>Another "feature"/design choice with IronWatin, was to implement a <code>main()</code> method specifically for running the tests on a per-file basis (similar to <code>unittest.main()</code>). This main method allows for passing in an <code>optparse.OptionParser</code> instance to add arguments to the script such as "--server" which are passed into your test classes themselves and exposed as "self.server" (for example). Which leaves you with a fairly straight-forward framework with which to start writing tests for the browser itself:</p> <div class="geshifilter"><pre class="geshifilter-python"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #808080; font-style: italic;">#!/usr/bin/env ipy</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #808080; font-style: italic;"># The import of IronWatin will add a reference to WatiN.Core.dll</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #808080; font-style: italic;"># and update `sys.path` to include C:\Python25\Lib and C:\Python26\Lib</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #808080; font-style: italic;"># so you can import from the Python standard library</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #ff7700;font-weight:bold;">import</span> IronWatin</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #ff7700;font-weight:bold;">import</span> WatiN.<span style="color: black;">Core</span> as Watin</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">optparse</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #ff7700;font-weight:bold;">class</span> OptionTest<span style="color: black;">&#40;</span>IronWatin.<span style="color: black;">BrowserTest</span><span style="color: black;">&#41;</span>:</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> url = <span style="color: #483d8b;">'http://www.github.com'</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #ff7700;font-weight:bold;">def</span> runTest<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #808080; font-style: italic;"># Run some Watin commands</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #ff7700;font-weight:bold;">assert</span> <span style="color: #008000;">self</span>.<span style="color: black;">testval</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> opts = <span style="color: #dc143c;">optparse</span>.<span style="color: black;">OptionParser</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> opts.<span style="color: black;">add_option</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'--testval'</span>, dest=<span style="color: #483d8b;">'testval'</span>, <span style="color: #008000;">help</span>=<span style="color: #483d8b;">'Specify a value'</span><span style="color: black;">&#41;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> IronWatin.<span style="color: black;">main</span><span style="color: black;">&#40;</span>options=opts<span style="color: black;">&#41;</span></div></li></ol></pre></div> <p>Thanks to IronPython, we can make use of our developers' and QA engineers' Python knowledge to get the up and running with writing integration tests using WatiN rapidly instead of trying to overcome the hump of teaching/training with a new language.</p> <p><strong>Deployment Notes:</strong> We're using IronPython 2.6rc1 and building WatiN from trunk in order to take advantage of some recent advances in their Firefox/frame support. We've not tested IronWatin, or WatiN at all for that matter, anywhere other than Windows XP.</p> http://www.unethicalblogger.com/posts/2009/10/ironwatin_mind_gap#comments Hudson Mono Slide Software Development Tue, 13 Oct 2009 21:57:49 +0000 R. Tyler Croy 231 at http://www.unethicalblogger.com Crazysnake; IronPython and Java, just monkeying around http://www.unethicalblogger.com/posts/2009/10/crazysnake_ironpython_and_java_just_monkeying_around <p>This weekend I finally got around to downloading <a id="aptureLink_8B5qEjVCfb" href="http://en.wikipedia.org/wiki/IronPython">IronPython</a> 2.6rc1 to test it against the upcoming builds of <a id="aptureLink_fepi2zTpCR" href="http://en.wikipedia.org/wiki/Mono%20%28software%29">Mono</a> 2.6 preview 1 (the version numbers matched, it felt right). Additionally in the land of Mono, I've been toying around with the IKVM project as of late, as a means of bringing some legacy Java code that I'm familiar with onto the CLR. As I poked in one xterm (urxvt actually) with <a id="aptureLink_myJp30086o" href="http://en.wikipedia.org/wiki/IKVM">IKVM</a> and with IronPython in another, a lightbulb went off. What if I could mix <em>different</em> languages in the <strong>same</strong> runtime; wouldn't that just be cool as a cucumber? Turns out, <strong>it is</strong>.</p> <p>After grabbing a recent release (0.40.0.1) of IKVM, I whipped up a simple Test.java file: <script src="http://gist.github.com/201908.js"><noscript>See <a href="http://gist.github.com/201908">gist #201908</a></noscript></script></p> <p>I compiled Test.java to Test.class then to Test.dll with ikvmc (note: this is using JDK 1.6); in short, Java was compiled to Java bytecode and <em>then</em> to <a id="aptureLink_jrzlVfjMcv" href="http://en.wikipedia.org/wiki/Common%20Intermediate%20Language">CIL</a>:</p> <pre><code>javac Test.java mono ikvm-0.40.0.1/bin/ikvmc.exe -target:library -out:Test.dll Test.class </code></pre> <p>Once you have a DLL, it is fairly simple to import that into an IronPython script thanks to the <code>clr</code> module IronPython provides. It is important to note however, that IKVM generated DLLs <em>will</em> try to load other DLLs at runtime (<code>IKVM.Runtime.dll</code> for example) so these either need to be installed in the <a id="aptureLink_1XlShjCjqK" href="http://en.wikipedia.org/wiki/Global%20Assembly%20Cache">GAC</a> or available in the directory your IronPython script is running in.</p> <p>Here's my sample test IronPython file, using the unittest module to verify that the compiled Java code is doing what I expect it to: <script src="http://gist.github.com/201909.js"><noscript>See <a href="http://gist.github.com/201909">gist #201909</a></noscript></script></p> <p>When I run the IronPython script, everything "just works":</p> <pre><code>% mono IronPython-2.6/ipy.exe IkvmTest.py . ---------------------------------------------------------------------- Ran 1 test in 0.040s OK % </code></pre> <p>While my Test.java is a fairly tame example of what is going on here, the underlying lesson is an important one. Thanks to the Mono project's CLR and the advent of the DLR on top of that we are getting closer to where "language" and "runtime" are separated enough to not be interdependent (as it is with <a id="aptureLink_YUpwTYkk3D" href="http://en.wikipedia.org/wiki/CPython">CPython</a>), allowing me (or you) to compile or otherwise execute code written in multiple languages on a common (language) runtime.</p> <p>That just feels good. <!--break--></p> http://www.unethicalblogger.com/posts/2009/10/crazysnake_ironpython_and_java_just_monkeying_around#comments Miscellaneous Mono Mon, 05 Oct 2009 06:00:59 +0000 R. Tyler Croy 230 at http://www.unethicalblogger.com Toying around with ASP.NET MVC and NAnt http://www.unethicalblogger.com/posts/2009/08/toying_around_aspnet_mvc_and_nant <p>I recently found myself toying around with a number of web frameworks (like <a id="aptureLink_tRFJIRMTMP" href="http://en.wikipedia.org/wiki/Seaside%20%28software%29">Seaside)</a> to get a good read on who's doing what in the web world outside of <a id="aptureLink_ljYLBSCzVn" href="http://en.wikipedia.org/wiki/Python%20%28programming%20language%29">Python</a> and <a id="aptureLink_zIhQ3Jyxp8" href="http://en.wikipedia.org/wiki/Django%20%28web%20framework%29">Django</a>, when I stumbled across the ASP.NET MVC Add-in <a href="http://mjhutchinson.com/journal/2009/04/02/aspnet_mvc_monodevelop_addin_preview">for MonoDevelop</a>. Though the new Vim keybindings are <strong>sweet</strong>, I still can't effectively get work done in MonoDevelop yet. What MonoDevelop <em>does</em> do however is support generating Makefiles for any given project, which allowed me to create some Makefiles for an ASP.NET MVC project I had created in <a id="aptureLink_ZLtfq1CvMX" href="http://en.wikipedia.org/wiki/Monodevelop">MonoDevelop</a>, and port those Makefiles over to fit my NAnt and Vim-based workflow.</p> <p>Along with building the necessary DLLs, I prefer to use my NAnt scripts to fire up the <a id="aptureLink_KlgrO6UVvG" href="http://en.wikipedia.org/wiki/NUnit">NUnit</a> console and fire up a development instance of <a href="http://www.mono-project.com/ASP.NET#ASP.NET_hosting_with_XSP">XSP</a> to test my web applications out. All said and done this fairly basic script does the job; I typically run it with: </p> <pre>nant test run</pre><p> Not much else to say, hope you find it useful.</p> <script src="http://gist.github.com/173708.js"></script> http://www.unethicalblogger.com/posts/2009/08/toying_around_aspnet_mvc_and_nant#comments Miscellaneous Mono Mon, 24 Aug 2009 07:17:12 +0000 R. Tyler Croy 224 at http://www.unethicalblogger.com Lazily loading attributes. http://www.unethicalblogger.com/posts/2008/09/lazily_loading_attributes <p>I found myself talking to <a href="http://jasonrubenstein.blogspot.com/" target="_blank">Jason</a> today about the virtues of <span class="geshifilter"><code class="python geshifilter-python"><span style="color: #008000;">getattr</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></code></span>, <span class="geshifilter"><code class="python geshifilter-python"><span style="color: #008000;">setattr</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></code></span>, and <span class="geshifilter"><code class="python geshifilter-python"><span style="color: #008000;">hasattr</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></code></span> in Python and "abusing" the dynamic nature of the language which reminded me of some lazy-loading code I wrote a while back. In February I found the need to have portions of the logic behind one of our web applications fetch data once per-request. The nature of the web applications we're building on top of the <a href="http://developer.myspace.com/community/" target="_blank">MySpace</a>, <A href="http://developer.hi5.com/" target="_blank">Hi5</a> and <a href="http://developers.facebook.com/" target="_blank">Facebook</a> platforms require some level of network data-access (traditionally via REST-like APIs). This breaks our data access model into the following tiers:<center><img src="http://agentdero.cachefly.net/unethicalblogger.com/images/data_model.png" alt=" Dia FTW "/></center><br /> Working with network-centric data resources is difficult in any scenario (desktop, mobile, web) but the particularly difficult thing about network data access in the mod_python-driven request model is that it will be synchronous (mod_python doesn't support "<a href="http://msdn.microsoft.com/en-us/magazine/cc163725.aspx" target="_blank">asynchronous pages</a>" like ASP.NET does). This means <strong>every</strong> REST call to Facebook, for example, is going to block execution of the request handler until the REST request to Facebook's API tier completes. <div class="geshifilter"><pre class="geshifilter-python"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #ff7700;font-weight:bold;">def</span> request_handler<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kwargs<span style="color: black;">&#41;</span>:</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> fb_uid = kwargs.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'fb_sig_user'</span><span style="color: black;">&#41;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Fetching the name for %s&quot;</span> <span style="color: #66cc66;">%</span> fb_uid</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> name = facebook.<span style="color: black;">users</span>.<span style="color: black;">getInfo</span><span style="color: black;">&#40;</span>uid=fb_uid<span style="color: black;">&#41;</span> </div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #808080; font-style: italic;">### WAIT-WAIT-WAIT-WAIT-WAIT</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> </div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #808080; font-style: italic;">### Continue generating the page...</span></div></li></ol></pre></div>There is also a network hit (albeit minor) for accessing cached data or data stored in databases. The general idea is that we'll need to have some level of data resident in memory through-out a request that can differ widely from request-to-request.</p> <h3>Lazy loading in Python</h3> <p> To help avoid unnecessary database access or network access I wrote a bit of class-sugar to make this a bit easier and more fail-proof:<div class="geshifilter"><pre class="geshifilter-python"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #ff7700;font-weight:bold;">class</span> LazyProgrammer<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #483d8b;">''</span><span style="color: #483d8b;">' </span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #483d8b;"> LazyProgrammer allows for lazily-loaded attributes on the subclasses </span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #483d8b;"> of this object. In order to enable lazily-loaded attributes define</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #483d8b;"> &quot;_X_attr_init()&quot; for the attribute &quot;obj.X&quot;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #483d8b;"> '</span><span style="color: #483d8b;">''</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__getattr__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, name<span style="color: black;">&#41;</span>:</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> rc = <span style="color: #008000;">object</span>.<span style="color: #0000cd;">__getattribute__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #483d8b;">'_%s_attr_init'</span><span style="color: black;">&#41;</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #008000;">setattr</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, name, rc<span style="color: black;">&#41;</span> </div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #ff7700;font-weight:bold;">return</span> rc</div></li></ol></pre></div>This makes developing with network-centric web applications a bit easier, for example, if I have a "friends" lazily-loading attribute off the base "FacebookRequest" class, all developers writing code subclassing FacebookRequest can simply refer to <span class="geshifilter"><code class="python geshifilter-python"><span style="color: #008000;">self</span>.<span style="color: black;">friends</span></code></span> and feel confident they aren't incurring unnecessary bandwidth hits, and the friends-list fetching code is located in once spot. If one-per-request starts to become too resource intensive as well, it'd be trivial to override the <span class="geshifilter"><code class="python geshifilter-python">_friends_attr_init<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></code></span> method to hit a caching server instead of the REST servers first, without needing to change any code "downstream."<br /> <br/></p> <h3>Lazy loading in C#</h3> <p> Since C# is not a dynamically-typed language like Python or JavaScript, you can't implement lazily-loaded attributes in the same fashion (calling something like <span class="geshifilter"><code class="python geshifilter-python"><span style="color: #008000;">setattr</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></code></span>) but you can "abuse" properties in a manner similar to the C# singleton pattern, to get the desired effect:<div class="geshifilter"><pre class="geshifilter-python"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">using System<span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">using System.<span style="color: black;">Collections</span>.<span style="color: black;">Generic</span><span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">public <span style="color: #ff7700;font-weight:bold;">class</span> LazySharp</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: black;">&#123;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #808080; font-style: italic;">#region &quot;Lazy Members&quot;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> private Dictionary<span style="color: #66cc66;">&lt;</span>int, string<span style="color: #66cc66;">&gt;</span> _names = null<span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #808080; font-style: italic;">#endregion</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #808080; font-style: italic;">#region &quot;Lazy Properties&quot;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> public Dictionary<span style="color: #66cc66;">&lt;</span>int, string<span style="color: #66cc66;">&gt;</span> Names</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: black;">&#123;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> get <span style="color: black;">&#123;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#40;</span>this._names == null<span style="color: black;">&#41;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> this._names = this.<span style="color: black;">SomeExpensiveCall</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #ff7700;font-weight:bold;">return</span> this._names<span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: black;">&#125;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: black;">&#125;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #808080; font-style: italic;">#endregion</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: black;">&#125;</span></div></li></ol></pre></div>Admittedly I don't find myself writing Facebook/MySpace/Hi5 applications these days on top of ASP.NET so I cannot say I actually <em>use</em> the class above in production, but conceptually it makes sense.</p> <p>Lazy loading attributes I find useful in the more hodge-podge situations, where code and feature-sets have both grown organically over time, they're not for everybody but I figured I'd share anyways.</p> http://www.unethicalblogger.com/posts/2008/09/lazily_loading_attributes#comments JavaScript Miscellaneous Mono Mon, 15 Sep 2008 07:27:41 +0000 R. Tyler Croy 187 at http://www.unethicalblogger.com Resurgange of the shell. http://www.unethicalblogger.com/posts/2008/09/resurgange_shell <p>Two things happened in such short proximity time-wise that I can't help but thing they're somehow related to the larger shift to <em>interpreters</em>. Earlier this week Miguel introduced <a href="http://tirania.org/blog/archive/2008/Sep-08.html" target="_blank">csharp shell</a> which forced me to dust off my shoddy Mono 1.9 build and rebuild Mono from Subversion just because this is too interesting to pass up on.</p> <p>One of my favorite aspects of using IronPyhton, or Python for that matter is the interpreter which allows for prototyping that doesn't involve creating little test apps that I have to build to prove a point. For example, I can work through fetching a web page in the csharp shell really easily, instead of creating a silly little application, compiling, fixing errors, and recompiling:<br /> <div class="geshifilter"><pre class="geshifilter-bash"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">tyler<span style="color: #000000; font-weight: bold;">@</span>pineapple:~<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">source</span><span style="color: #000000; font-weight: bold;">/</span>mono-project<span style="color: #000000; font-weight: bold;">/</span>mono<span style="color: #000000; font-weight: bold;">&gt;</span> csharp</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">Mono C<span style="color: #808080; font-style: italic;"># Shell, type &quot;help;&quot; for help</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">Enter statements below.</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> using System;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> Console.WriteLine<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;This changes everything.&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">This changes everything.</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> String url = <span style="color: #ff0000;">&quot;http://tycho.usno.navy.mil/cgi-bin/timer.pl&quot;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> using System.Web;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> using System.Net;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> using System.IO;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> using System.Text;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> HttpWebRequest req = HttpWebRequest.Create<span style="color: #7a0874; font-weight: bold;">&#40;</span>url<span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>interactive<span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">1</span>,<span style="color: #000000;">17</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>: error CS0266: Cannot implicitly convert <span style="color: #7a0874; font-weight: bold;">type</span> `System.Net.WebRequest<span style="color: #ff0000;">' to `System.Net.HttpWebRequest'</span>. An explicit conversion exists <span style="color: #7a0874; font-weight: bold;">&#40;</span>are you missing a cast?<span style="color: #7a0874; font-weight: bold;">&#41;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> HttpWebRequest req = HttpWebRequest.Create<span style="color: #7a0874; font-weight: bold;">&#40;</span>url<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #c20cb9; font-weight: bold;">as</span> HttpWebRequest;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> HttpWebResponse response = req.GetResponse<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #c20cb9; font-weight: bold;">as</span> HttpWebResponse;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> StreamReader reader = new StreamReader<span style="color: #7a0874; font-weight: bold;">&#40;</span>req.GetResponseStream<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #c20cb9; font-weight: bold;">as</span> Stream, Encoding.UTF8<span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>interactive<span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">1</span>,<span style="color: #000000;">45</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>: error CS1061: Type `System.Net.HttpWebRequest<span style="color: #ff0000;">' does not contain a definition for `GetResponseStream'</span> and no extension method `GetResponseStream<span style="color: #ff0000;">' of type `System.Net.HttpWebRequest'</span> could be found <span style="color: #7a0874; font-weight: bold;">&#40;</span>are you missing a using directive or an assembly reference?<span style="color: #7a0874; font-weight: bold;">&#41;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> StreamReader reader = new StreamReader<span style="color: #7a0874; font-weight: bold;">&#40;</span>response.GetResponseStream<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #c20cb9; font-weight: bold;">as</span> Stream, Encoding.UTF8<span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> String result = reader.ReadToEnd<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> Console.WriteLine<span style="color: #7a0874; font-weight: bold;">&#40;</span>result<span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;!</span>DOCTYPE HTML PUBLIC <span style="color: #ff0000;">&quot;-//W3C//DTD HTML 3.2 Final&quot;</span><span style="color: #000000; font-weight: bold;">//</span>EN<span style="color: #000000; font-weight: bold;">&gt;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>html<span style="color: #000000; font-weight: bold;">&gt;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>body<span style="color: #000000; font-weight: bold;">&gt;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>TITLE<span style="color: #000000; font-weight: bold;">&gt;</span>What <span style="color: #000000; font-weight: bold;">time</span> is it?<span style="color: #000000; font-weight: bold;">&lt;/</span>TITLE<span style="color: #000000; font-weight: bold;">&gt;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>H2<span style="color: #000000; font-weight: bold;">&gt;</span> US Naval Observatory Master Clock Time<span style="color: #000000; font-weight: bold;">&lt;/</span>H2<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">&lt;</span>H3<span style="color: #000000; font-weight: bold;">&gt;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>BR<span style="color: #000000; font-weight: bold;">&gt;</span>Sep. <span style="color: #000000;">11</span>, <span style="color: #000000;">07</span>:<span style="color: #000000;">29</span>:<span style="color: #000000;">02</span> UTC</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>BR<span style="color: #000000; font-weight: bold;">&gt;</span>Sep. <span style="color: #000000;">11</span>, <span style="color: #000000;">03</span>:<span style="color: #000000;">29</span>:<span style="color: #000000;">02</span> AM EDT</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>BR<span style="color: #000000; font-weight: bold;">&gt;</span>Sep. <span style="color: #000000;">11</span>, <span style="color: #000000;">02</span>:<span style="color: #000000;">29</span>:<span style="color: #000000;">02</span> AM CDT</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>BR<span style="color: #000000; font-weight: bold;">&gt;</span>Sep. <span style="color: #000000;">11</span>, <span style="color: #000000;">01</span>:<span style="color: #000000;">29</span>:<span style="color: #000000;">02</span> AM MDT</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>BR<span style="color: #000000; font-weight: bold;">&gt;</span>Sep. <span style="color: #000000;">11</span>, <span style="color: #000000;">12</span>:<span style="color: #000000;">29</span>:<span style="color: #000000;">02</span> AM PDT</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>BR<span style="color: #000000; font-weight: bold;">&gt;</span>Sep. <span style="color: #000000;">10</span>, <span style="color: #000000;">11</span>:<span style="color: #000000;">29</span>:<span style="color: #000000;">02</span> PM AKDT</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>BR<span style="color: #000000; font-weight: bold;">&gt;</span>Sep. <span style="color: #000000;">10</span>, <span style="color: #000000;">09</span>:<span style="color: #000000;">29</span>:<span style="color: #000000;">02</span> PM HAST</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;/</span>H3<span style="color: #000000; font-weight: bold;">&gt;&lt;</span>P<span style="color: #000000; font-weight: bold;">&gt;&lt;</span>A <span style="color: #007800;">HREF=</span><span style="color: #ff0000;">&quot;http://tycho.usno.navy.mil&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span>Time Service Department, US Naval Observatory<span style="color: #000000; font-weight: bold;">&lt;/</span>A<span style="color: #000000; font-weight: bold;">&gt;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;/</span>body<span style="color: #000000; font-weight: bold;">&gt;&lt;/</span>html<span style="color: #000000; font-weight: bold;">&gt;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> reader.Close<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> response.Close<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> </div></li></ol></pre></div><br /> <!--break--><br /> I really think Miguel and Co. have adding something infinitely more useful in this Hackweek project than anything I've seen come out of recent hackweeks at Novell. The only feature request that I'd add along to the csharp shell would be "recording", i.e.:<br /> <div class="geshifilter"><pre class="geshifilter-bash"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">tyler<span style="color: #000000; font-weight: bold;">@</span>pineapple:~<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">source</span><span style="color: #000000; font-weight: bold;">/</span>mono-project<span style="color: #000000; font-weight: bold;">/</span>mono<span style="color: #000000; font-weight: bold;">&gt;</span> csharp</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">Mono C<span style="color: #808080; font-style: italic;"># Shell, type &quot;help;&quot; for help</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">Enter statements below.</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> Shell.record<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;public void Main(string[] args)&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">recording...</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> using System;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> Console.WriteLien<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;I prototyped this in csharp shell!&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&lt;</span>interactive<span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">1</span>,<span style="color: #000000;">10</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>: error CS0117: `System.Console<span style="color: #ff0000;">' does not contain a definition for `WriteLien'</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>tyler<span style="color: #000000; font-weight: bold;">/</span>basket<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>mono<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2.0</span><span style="color: #000000; font-weight: bold;">/</span>mscorlib.dll <span style="color: #7a0874; font-weight: bold;">&#40;</span>Location of the symbol related to previous error<span style="color: #7a0874; font-weight: bold;">&#41;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> Console.WriteLine<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;I prototyped this in csharp shell!&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">csharp<span style="color: #000000; font-weight: bold;">&gt;</span> Shell.save_record<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;Hello.cs&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">recording saved to <span style="color: #ff0000;">&quot;Hello.cs&quot;</span></div></li></ol></pre></div>Which could conceptually generate the following file:<div class="geshifilter"><pre class="geshifilter-python"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">using System<span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">public <span style="color: #ff7700;font-weight:bold;">class</span> Hello</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: black;">&#123;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> public void Main<span style="color: black;">&#40;</span><span style="color: #dc143c;">string</span><span style="color: black;">&#91;</span><span style="color: black;">&#93;</span> args<span style="color: black;">&#41;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: black;">&#123;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> Console.<span style="color: black;">WriteLine</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;I prototyped this in csharp shell!&quot;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: black;">&#125;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: black;">&#125;</span></div></li></ol></pre></div></p> <h3>JavaScript Shell</h3> <p>In addition to the C# shell, I've been playing with <a href="http://code.google.com/p/v8/" target="_blank">v8</a>, the JavaScript engine that powers Google Chrome. The V8 engine is capable of being embedded easily, or running standalone, one of the examples they ship with is a JavaScript shell. I've created a little wrapper script to give me the ability to load jQuery into the V8 shell to prototype jQuery code without requiring a browser to be up and running:<br /> <div class="geshifilter"><pre class="geshifilter-bash"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">tyler<span style="color: #000000; font-weight: bold;">@</span>pineapple:~<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">source</span><span style="color: #000000; font-weight: bold;">/</span>v8<span style="color: #000000; font-weight: bold;">&gt;</span> .<span style="color: #000000; font-weight: bold;">/</span>shell</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">V8 version <span style="color: #000000;">0.3</span><span style="color: #000000;">.0</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&gt;</span> load<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;window-compat.js&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&gt;</span> load<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;jquery.js&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&gt;</span> $ = window.$</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">function</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>selector,context<span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #7a0874; font-weight: bold;">return</span> new jQuery.fn.init<span style="color: #7a0874; font-weight: bold;">&#40;</span>selector,context<span style="color: #7a0874; font-weight: bold;">&#41;</span>;<span style="color: #7a0874; font-weight: bold;">&#125;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&gt;</span> x = <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">1</span>, <span style="color: #000000;">5</span>, <span style="color: #000000;">6</span>, <span style="color: #000000;">12</span>, <span style="color: #000000;">42</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000;">1</span>,<span style="color: #000000;">5</span>,<span style="color: #000000;">6</span>,<span style="color: #000000;">12</span>,<span style="color: #000000;">42</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&gt;</span> $.each<span style="color: #7a0874; font-weight: bold;">&#40;</span>x, <span style="color: #000000; font-weight: bold;">function</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>index<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span> print<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">&quot;x[&quot;</span> + index + <span style="color: #ff0000;">&quot;] = &quot;</span> + this<span style="color: #7a0874; font-weight: bold;">&#41;</span>; <span style="color: #7a0874; font-weight: bold;">&#125;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">x<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">0</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> = <span style="color: #000000;">1</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">x<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> = <span style="color: #000000;">5</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">x<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">2</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> = <span style="color: #000000;">6</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">x<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">3</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> = <span style="color: #000000;">12</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">x<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">4</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> = <span style="color: #000000;">42</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000;">1</span>,<span style="color: #000000;">5</span>,<span style="color: #000000;">6</span>,<span style="color: #000000;">12</span>,<span style="color: #000000;">42</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">&gt;</span> </div></li></ol></pre></div>The contents of "window-compat.js" being:<br /> <div class="geshifilter"><pre class="geshifilter-javascript"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #009900; font-style: italic;">/*</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #009900; font-style: italic;">&nbsp;* Providing stub &quot;window&quot; objects for jQuery</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #009900; font-style: italic;">&nbsp;*/</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span><span style="color: #66cc66;">&#40;</span>window<span style="color: #66cc66;">&#41;</span> == <span style="color: #3366CC;">'undefined'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> window = <span style="color: #003366; font-weight: bold;">new</span> Object<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> document = window;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> self = window;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> navigator = <span style="color: #003366; font-weight: bold;">new</span> Object<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> navigator.<span style="color: #006600;">userAgent</span> = navigator.<span style="color: #006600;">userAgent</span> <span style="color: #66cc66;">||</span> <span style="color: #3366CC;">'Chrome v8 Shell'</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> location = <span style="color: #003366; font-weight: bold;">new</span> Object<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> location.<span style="color: #006600;">href</span> = <span style="color: #3366CC;">'file:///dev/null'</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> location.<span style="color: #006600;">protocol</span> = <span style="color: #3366CC;">'file:'</span>;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> location.<span style="color: #006600;">host</span> = <span style="color: #3366CC;">''</span>; </div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #66cc66;">&#125;</span>;</div></li></ol></pre></div></p> <p>In general I don't really have anything insightful or especially interesting to add, but I wanted to put out my "+1" in support of both of these projects. Making any language or API more easily accessible through these shells/interpreters can really help developers double-check syntax, expected API behavior etc. Thanks Novell/Google, interpreters rock!</p> http://www.unethicalblogger.com/posts/2008/09/resurgange_shell#comments JavaScript Mono Thu, 11 Sep 2008 07:57:36 +0000 R. Tyler Croy 186 at http://www.unethicalblogger.com NAnt and ASP.NET on Mono http://www.unethicalblogger.com/posts/2008/05/nant_and_aspnet_mono <p>Most of my personal projects are built on top of ASP.NET, <a href="http://www.mono-project.com" target="_blank">Mono</a> and <a href="http://www.lighttpd.net/" target="_blank">Lighttpd</a>. One of the benefits of keeping them all running on the same stack (as opposed to mixing Python, Mono and PHP together) is that I don't need to maintain different infrastructure bits to keep them all up and running. Two key pieces that keep it easy to dive back into the the side-project whenever I have some (spurious) free time are my <a href="http://nant.sourceforge.net/" target="_blank">NAnt</a> scripts and my push scripts.</p> <p><strong><big>NAnt</big></strong><br /> I use my NAnt script for a bit more than just building my web projects, more often than not I use it to build, deploy and test everything related to the site. My projects are typically laid out like: <ul> <li><strong>bin/</strong> Built DLLs, not in Subversion</li> <li><strong>configs/</strong> Web.config files per-development machine</li> <li><strong>libraries/</strong> External libraries, such as Memcached.Client.dll, etc.</li> <li><strong>schemas/</strong> Files containing the SQL for rebuilding my database</li> <li><strong>site/</strong> Fully built web project, including Web.config and .aspx files</li> <li><strong>sources/</strong> Actual code, .aspx.cs and web folder (<em>htdocs/</em> containing styles, javascript, etc)</li> </ul> <p>Executing "<strong>nant run</strong>" will build the entire project and construct the full version of the web application in the <strong>site/</strong> and finally fire up <a href="http://www.mono-project.com/ASP.NET#ASP.NET_hosting_with_XSP" target="_blank">xsp2</a> on localhost for testing. The following NAnt file is what I've been carrying from project to project.<br /> <div class="geshifilter"><pre class="geshifilter-xml"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span><span style="font-weight: bold; color: black;">?&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;project</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;MyProject&quot;</span> <span style="color: #000066;">default</span>=<span style="color: #ff0000;">&quot;library&quot;</span> <span style="color: #000066;">basedir</span>=<span style="color: #ff0000;">&quot;.&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;debug&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">overwrite</span>=<span style="color: #ff0000;">&quot;false&quot;</span> <span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;project.name&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;MyProject&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;project.version&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;1.0.0&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;library&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;MyProject.dll&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;tstamp</span> <span style="color: #000066;">property</span>=<span style="color: #ff0000;">&quot;build.date&quot;</span> <span style="color: #000066;">pattern</span>=<span style="color: #ff0000;">&quot;yyyyMMdd&quot;</span> <span style="color: #000066;">verbose</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="color: #808080; font-style: italic;">&lt;!-- These are being definde for posterity's sake, as they may change in the future --&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;bin_dir&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;bin&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;src_dir&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;sources&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;lib_dir&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;libraries&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;site_dir&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;site&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;deps_dir&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;deps/&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;contrib_dir&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;contrib/&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="color: #808080; font-style: italic;">&lt;!-- xsp specific properties --&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;xsp_port&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;8088&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;xsp_root&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;${site_dir}&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;property</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;xsp_apps&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;/:../${bin_dir}&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="color: #808080; font-style: italic;">&lt;!--// End properties --&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;target</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;library&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Basic MyProject build task&quot;</span> <span style="font-weight: bold; color: black;">&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;echo</span> <span style="color: #000066;">message</span>=<span style="color: #ff0000;">&quot;Building ${project.name}-${project.version}&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span> </div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;csc</span> <span style="color: #000066;">target</span>=<span style="color: #ff0000;">&quot;library&quot;</span> <span style="color: #000066;">output</span>=<span style="color: #ff0000;">&quot;${bin_dir}/${library}&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;sources<span style="font-weight: bold; color: black;">&gt;</span></span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;include</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;${src_dir}/**.cs&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/sources<span style="font-weight: bold; color: black;">&gt;</span></span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;references<span style="font-weight: bold; color: black;">&gt;</span></span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;include</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;Npgsql.dll&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/references<span style="font-weight: bold; color: black;">&gt;</span></span></span> </div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/csc<span style="font-weight: bold; color: black;">&gt;</span></span></span> </div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/target<span style="font-weight: bold; color: black;">&gt;</span></span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;target</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;clean&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Clean up MyProject&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;echo</span> <span style="color: #000066;">message</span>=<span style="color: #ff0000;">&quot;Cleaning ${project.name}&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;delete<span style="font-weight: bold; color: black;">&gt;</span></span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;fileset<span style="font-weight: bold; color: black;">&gt;</span></span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;include</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;${bin_dir}/**.dll&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;include</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;${site_dir}/**.dll&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;include</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;${site_dir}/**.aspx&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/fileset<span style="font-weight: bold; color: black;">&gt;</span></span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/delete<span style="font-weight: bold; color: black;">&gt;</span></span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/target<span style="font-weight: bold; color: black;">&gt;</span></span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;target</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;site&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Populate the site/ directory&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;copy</span> <span style="color: #000066;">todir</span>=<span style="color: #ff0000;">&quot;${site_dir}&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;fileset</span> <span style="color: #000066;">basedir</span>=<span style="color: #ff0000;">&quot;${src_dir}/htdocs&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;include</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;**&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/fileset<span style="font-weight: bold; color: black;">&gt;</span></span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/copy<span style="font-weight: bold; color: black;">&gt;</span></span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;copy</span> <span style="color: #000066;">todir</span>=<span style="color: #ff0000;">&quot;${site_dir}/contrib&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;fileset</span> <span style="color: #000066;">basedir</span>=<span style="color: #ff0000;">&quot;${contrib_dir}&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;include</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;**&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/fileset<span style="font-weight: bold; color: black;">&gt;</span></span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/copy<span style="font-weight: bold; color: black;">&gt;</span></span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;copy</span> <span style="color: #000066;">todir</span>=<span style="color: #ff0000;">&quot;${bin_dir}&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;fileset</span> <span style="color: #000066;">basedir</span>=<span style="color: #ff0000;">&quot;${lib_dir}&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;include</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;*&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/fileset<span style="font-weight: bold; color: black;">&gt;</span></span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/copy<span style="font-weight: bold; color: black;">&gt;</span></span></span> </div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="color: #808080; font-style: italic;">&lt;!-- Copying bin/ into the site/ directory sucks, but xsp2 is buggy</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #808080; font-style: italic;">&nbsp; with the applications parameter</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #808080; font-style: italic;">&nbsp; --&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;copy</span> <span style="color: #000066;">todir</span>=<span style="color: #ff0000;">&quot;${site_dir}&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;fileset<span style="font-weight: bold; color: black;">&gt;</span></span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;include</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;bin/*.dll&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/fileset<span style="font-weight: bold; color: black;">&gt;</span></span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/copy<span style="font-weight: bold; color: black;">&gt;</span></span></span> </div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/target<span style="font-weight: bold; color: black;">&gt;</span></span></span> </div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;target</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;run&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Runs the xsp2 web server on the port cited above&quot;</span> <span style="color: #000066;">depends</span>=<span style="color: #ff0000;">&quot;library, site&quot;</span><span style="font-weight: bold; color: black;">&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;echo</span> <span style="color: #000066;">message</span>=<span style="color: #ff0000;">&quot;Starting the xsp2 web server running on port ${xsp_port}&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;exec</span> <span style="color: #000066;">program</span>=<span style="color: #ff0000;">&quot;xsp2&quot;</span> <span style="color: #000066;">failonerror</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">commandline</span>=<span style="color: #ff0000;">&quot;--port ${xsp_port} --root ${xsp_root}&quot;</span><span style="font-weight: bold; color: black;">/&gt;</span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/target<span style="font-weight: bold; color: black;">&gt;</span></span></span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/project<span style="font-weight: bold; color: black;">&gt;</span></span></span></div></li></ol></pre></div></p> <p><strong><big>The Push Script</big></strong><br /> Since I usually build and deploy on the same machine, I use a simple script called "<strong>push.sh</strong>" to handle rsyncing data from the development part of my machine into the live directories.<br /> <div class="geshifilter"><pre class="geshifilter-bash"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #808080; font-style: italic;">#!/bin/bash</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #808080; font-style: italic;">###############################</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #808080; font-style: italic;">## Push script variables</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">NANT=</span><span style="color: #ff0000;">'/usr/bin/nant'</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">STAGE=</span>`<span style="color: #c20cb9; font-weight: bold;">hostname</span>`</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">SOURCE=</span><span style="color: #ff0000;">'site/'</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">LIVE_TARGET=</span><span style="color: #ff0000;">'/serv/www/domains/myproject.com/htdocs/'</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">BETA_TARGET=</span><span style="color: #ff0000;">'/serv/www/domains/beta.myproject.com/htdocs/'</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">TARGET=</span><span style="color: #007800;">$BETA_TARGET</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #808080; font-style: italic;">###############################</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #808080; font-style: italic;">###############################</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #808080; font-style: italic;">## Internal functions</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">function</span> output <span style="color: #7a0874; font-weight: bold;">&#123;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;===&gt; $1&quot;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #7a0874; font-weight: bold;">&#125;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">function</span> build <span style="color: #7a0874; font-weight: bold;">&#123;</span> </div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #007800;">$<span style="color: #7a0874; font-weight: bold;">&#123;</span>NANT<span style="color: #7a0874; font-weight: bold;">&#125;</span><span style="color: #000000; font-weight: bold;">|</span>> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #007800;">$<span style="color: #7a0874; font-weight: bold;">&#123;</span>NANT<span style="color: #7a0874; font-weight: bold;">&#125;</span><span style="color: #000000; font-weight: bold;">|</span>> site</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #7a0874; font-weight: bold;">&#125;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #808080; font-style: italic;">###############################</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #808080; font-style: italic;">###############################</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #808080; font-style: italic;">## Build the site first</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">output <span style="color: #ff0000;">&quot;Building the site...&quot;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">build</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$?</span> -ne <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> output <span style="color: #ff0000;">&quot;Looks like there was an error building! abort!&quot;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">1</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">fi</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #808080; font-style: italic;">###############################</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #808080; font-style: italic;">## Start actual pushing</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;${1}&quot;</span> = <span style="color: #ff0000;">'live'</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span> </div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> output <span style="color: #ff0000;">&quot; ** PUSHING THE LIVE SITE ***&quot;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> <span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">TARGET=</span><span style="color: #007800;">$LIVE_TARGET</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">else</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> output <span style="color: #ff0000;">&quot;Pushing the beta site&quot;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #000000; font-weight: bold;">fi</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">output <span style="color: #ff0000;">&quot;Using Web.config-${STAGE}&quot;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">output <span style="color: #ff0000;">&quot;Pushing to: ${TARGET}&quot;</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">&nbsp;</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #c20cb9; font-weight: bold;">cp</span> config<span style="color: #000000; font-weight: bold;">/</span>Web.config-<span style="color: #007800;">$<span style="color: #7a0874; font-weight: bold;">&#123;</span>STAGE<span style="color: #7a0874; font-weight: bold;">&#125;</span><span style="color: #000000; font-weight: bold;">|</span>> site<span style="color: #000000; font-weight: bold;">/</span>Web.config</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">rsync --exclude <span style="color: #000000; font-weight: bold;">*</span>.swp --exclude .svn<span style="color: #000000; font-weight: bold;">/</span> -av <span style="color: #007800;">$<span style="color: #7a0874; font-weight: bold;">&#123;</span>SOURCE<span style="color: #7a0874; font-weight: bold;">&#125;</span><span style="color: #000000; font-weight: bold;">|</span>> <span style="color: #007800;">$<span style="color: #7a0874; font-weight: bold;">&#123;</span>TARGET<span style="color: #7a0874; font-weight: bold;">&#125;</span><span style="color: #000000; font-weight: bold;">|</span>></div></li></ol></pre></div></p> <p>Depending on the complexity of the web application I might change the scripts up on a case-by-case basis, but for the most part I have about 5-6 projects out "in the ether" that are built and deployed with a derivative of the NAnt script and push.sh listed above. In general though, they provide a good starting point for the tedious bits of non-Visual Studio-based web development (especially if you're in an entirely Linux-based environment).</p> <p>Hope you find them helpful :)</p> http://www.unethicalblogger.com/posts/2008/05/nant_and_aspnet_mono#comments Miscellaneous Mono Software Development Sun, 04 May 2008 12:26:08 +0000 R. Tyler Croy 181 at http://www.unethicalblogger.com SXSWi and Me http://www.unethicalblogger.com/posts/r_tyler_ballance/sxswi_and_me <p>I spoke with Tammy (our <a href="http://www.slide.com/static/about_press" target="_blank">PR mastermind</a>) about whether or not <A href="http://www.slide.com" target="_blank">Slide</a> was going to let me out of my cage to go to <a href="http://sxsw.com/" target="_blank">South by Southwest Interactive</a> this coming March and it seems like they might actually let me! (I'm just as surprised as you are)</p> <p>Unfortunately things with Facebook were at such a ridiculous pace when SXSWi was accepting <a href="http://2008.sxsw.com/interactive/programming/panels_by_category/" target="_blank">panel submissions</a>, that I never got a chance to submit my panel idea: "Slide is awesome, now let's talk about how great Slide is." This leaves me in a slightly awkward position, I cannot remember the last conference or event that I went to where I wasn't speaking or talking or dancing with a baboon in front of a live studio audience. Even at the last SXSWi I was there for about 36 hours and most of that time was spent setting up and then helping run <a href="http://barcamp.org/BarCampAustinII" target="_blank">BarCamp Austin<sup>2</sup></a>. Ideally I'd like to get on stage with some of the guys from Twitter, Facebook, Bebo, Google and maybe even Myspace to discuss the more open social web that we seem to be moving towards and a bit about how awesome Slide is. It's probably nothing more than a pipe-dream however, since the panels seem to be quite locked down at the moment.</p> <p>Of course, if nobody will have me, then I might be relegated to slumming up and down 6th street in Austin hanging out with the usual drunkards that I know in Austin (you know who you are) and getting into trouble. Mmm, trouble.</p> <p>Regardless, if you're going to be in Austin for SXSWi let me know, I've got a stack of swanky new business cards I want to get rid of :)<br /> <center><a href="http://farm3.static.flickr.com/2388/2127793798_8769341624_o.jpg" rel="lightbox"><img src="http://farm3.static.flickr.com/2388/2127793798_8769341624_o.jpg" width="400"/></a></center></p> http://www.unethicalblogger.com/posts/r_tyler_ballance/sxswi_and_me#comments Facebook Miscellaneous Mono Slide Mon, 31 Dec 2007 13:11:08 +0000 R. Tyler Croy 148 at http://www.unethicalblogger.com Comparing IronPython and CPython http://www.unethicalblogger.com/posts/r_tyler_ballance/comparing_ironpython_and_cpython <p>First a little background to help explain some of the terms, etc. "Python" is a language, similar to how "Java" is a language; unlike Java wherein the language is also relatively synonymous with the actual <em>implementation</em> of that language, Python has multiple implementations. If you've run python(1) from the command line, you're most likely running the CPython implementation of the Python language, in effect, Python implemented in C. Other implementations of Python exist, like <a href="http://www.jython.org/" target="_blank">Jython</a> (implemented on top of the Java virtual machine), <a href="http://codespeak.net/pypy" target="_blank">PyPy</a> (Python implemented in Python), and <a href="http://www.codeplex.com/ironpython" target="_blank">IronPython</a> (Python implemented on top of the .NET CLR).</p> <p>I was talking with some of the guys from the #mono channel on <a href="http://www.gimp.org/irc.html" target="_blank">GIMPNet</a> about IronPython versus CPython as far as performance is concerned and I decided that I would refine my testing (using <a href="http://svn.python.org/projects/python/trunk/Tools/pybench" target="_blank">pybench</a>) for more similar versions of the respective implementations, in as controlled of an environment as possible.</p> <p>I ran pybench.py on a "quiet" (i.e. not-busy) machine sitting in a remote datacenter not too far from Novell, the machine is a Pentium III (i386) based machine running <a href="http://www.opensuse.org" target="_blank">openSUSE</a> 10.3. Since IronPython reports it's "implementation version" as Python 2.4.0, I decided to build and run CPython 2.4 against it. IronPython is running on top of the recently released Mono 1.2.6 which I also built from source (I got IronPython from the IPCE package in YaST however). pybench reported the various implementation details for both as such:</p> <p><strong>CPython</strong></p> <pre style="padding: 3px; border-top: 1px solid #ccc; border-bottom: 1px solid #ccc;"> Implementation: 2.4.4 Executable: /home/tyler/basket/bin/python Version: 2.4.4 Compiler: GCC 4.2.1 (SUSE Linux) Bits: 32bit Build: Dec 18 2007 23:00:48 (#1) Unicode: UCS2 </pre><p> <strong>IronPython</strong></p> <pre style="padding: 3px; border-top: 1px solid #ccc; border-bottom: 1px solid #ccc;"> Implementation: 2.4.0 Executable: /usr/lib/IPCE/ipy.exe Version: 2.4.0 Compiler: .NET 2.0.50727.42 Bits: 32bit Build: (#) Unicode: UCS2 </pre><p> IronPython did <em>alright</em>, but it got pretty thrashed on a lot of the benchmarks. Unfortunately it's hard to tell whether it's Mono getting beaten up, or whether it's IronPython itself that's losing the battle here, running similar tests on the .NET 2.0 CLR would be beneficial but not something I am curious enough to boot a Windows virtual machine for. Regardless, here are the results, I've highlighed the rows where IronPython performs better than CPython.<br /> <!--break--></p> <style type="text/css"> .benchmark td { border-bottom: 1px solid #333; border-right: 1px solid #ccc; border-left: 1px solid #ccc; } </style><table border="0" class="benchmark" cellspacing="0" cellpadding="3"> <tr> <td>Test</td> <td colspan="3">Minimum Run-time</td> <td colspan="3">Average Run-time</td> </tr> <tr> <td> <td>CPython</td> <td bgcolor="#FCDE52">IronPython</td> <td>Diff</td> <td>CPython</td> <td bgcolor="#FCDE52">IronPython</td> <td>Diff</td> </tr> <tr style="background-color: #F9FD85;"> <td>BuiltinFunctionCalls:</td> <td>448ms</td> <td bgcolor="#FCDE52">357ms</td> <td>+25.4%</td> <td>450ms</td> <td bgcolor="#FCDE52">405ms</td> <td>+11.0%</td> </tr> <tr> <td>BuiltinMethodLookup:</td> <td>530ms</td> <td bgcolor="#FCDE52">1329ms</td> <td>-60.1%</td> <td>536ms</td> <td bgcolor="#FCDE52">1390ms</td> <td>-61.4%</td> </tr> <tr style="background-color: #F9FD85;"> <td>CompareFloats:</td> <td>380ms</td> <td bgcolor="#FCDE52">129ms</td> <td>+194.3%</td> <td>381ms</td> <td bgcolor="#FCDE52">132ms</td> <td>+187.7%</td> </tr> <tr style="background-color: #F9FD85;"> <td>CompareFloatsIntegers:</td> <td>377ms</td> <td bgcolor="#FCDE52">93ms</td> <td>+306.1%</td> <td>378ms</td> <td bgcolor="#FCDE52">97ms</td> <td>+291.2%</td> </tr> <tr style="background-color: #F9FD85;"> <td>CompareIntegers:</td> <td>436ms</td> <td bgcolor="#FCDE52">160ms</td> <td>+172.5%</td> <td>437ms</td> <td bgcolor="#FCDE52">161ms</td> <td>+170.6%</td> </tr> <tr> <td>CompareInternedStrings:</td> <td>425ms</td> <td bgcolor="#FCDE52">443ms</td> <td>-4.1%</td> <td>426ms</td> <td bgcolor="#FCDE52">445ms</td> <td>-4.3%</td> </tr> <tr style="background-color: #F9FD85;"> <td>CompareLongs:</td> <td>360ms</td> <td bgcolor="#FCDE52">292ms</td> <td>+23.3%</td> <td>361ms</td> <td bgcolor="#FCDE52">293ms</td> <td>+23.0%</td> </tr> <tr style="background-color: #F9FD85;"> <td>CompareStrings:</td> <td>423ms</td> <td bgcolor="#FCDE52">330ms</td> <td>+28.0%</td> <td>423ms</td> <td bgcolor="#FCDE52">337ms</td> <td>+25.6%</td> </tr> <tr style="background-color: #F9FD85;"> <td>CompareUnicode:</td> <td>377ms</td> <td bgcolor="#FCDE52">243ms</td> <td>+54.7%</td> <td>377ms</td> <td bgcolor="#FCDE52">245ms</td> <td>+54.2%</td> </tr> <tr> <td>ConcatStrings:</td> <td>726ms</td> <td bgcolor="#FCDE52">9452ms</td> <td>-92.3%</td> <td>823ms</td> <td bgcolor="#FCDE52">10071ms</td> <td>-91.8%</td> </tr> <tr> <td>ConcatUnicode:</td> <td>711ms</td> <td bgcolor="#FCDE52">5687ms</td> <td>-87.5%</td> <td>756ms</td> <td bgcolor="#FCDE52">6039ms</td> <td>-87.5%</td> </tr> <tr> <td>CreateInstances:</td> <td>508ms</td> <td bgcolor="#FCDE52">761ms</td> <td>-33.2%</td> <td>518ms</td> <td bgcolor="#FCDE52">815ms</td> <td>-36.4%</td> </tr> <tr> <td>CreateNewInstances:</td> <td>451ms</td> <td bgcolor="#FCDE52">3475ms</td> <td>-87.0%</td> <td>458ms</td> <td bgcolor="#FCDE52">3581ms</td> <td>-87.2%</td> </tr> <tr> <td>CreateStringsWithConcat:</td> <td>473ms</td> <td bgcolor="#FCDE52">2650ms</td> <td>-82.1%</td> <td>475ms</td> <td bgcolor="#FCDE52">2833ms</td> <td>-83.2%</td> </tr> <tr> <td>CreateUnicodeWithConcat:</td> <td>482ms</td> <td bgcolor="#FCDE52">1008ms</td> <td>-52.1%</td> <td>508ms</td> <td bgcolor="#FCDE52">1092ms</td> <td>-53.4%</td> </tr> <tr> <td>DictCreation:</td> <td>405ms</td> <td bgcolor="#FCDE52">2944ms</td> <td>-86.2%</td> <td>407ms</td> <td bgcolor="#FCDE52">3057ms</td> <td>-86.7%</td> </tr> <tr> <td>DictWithFloatKeys:</td> <td>552ms</td> <td bgcolor="#FCDE52">934ms</td> <td>-40.9%</td> <td>553ms</td> <td bgcolor="#FCDE52">944ms</td> <td>-41.5%</td> </tr> <tr> <td>DictWithIntegerKeys:</td> <td>423ms</td> <td bgcolor="#FCDE52">1118ms</td> <td>-62.2%</td> <td>426ms</td> <td bgcolor="#FCDE52">1137ms</td> <td>-62.5%</td> </tr> <tr> <td>DictWithStringKeys:</td> <td>413ms</td> <td bgcolor="#FCDE52">1186ms</td> <td>-65.1%</td> <td>414ms</td> <td bgcolor="#FCDE52">1317ms</td> <td>-68.6%</td> </tr> <tr style="background-color: #F9FD85;"> <td>ForLoops:</td> <td>412ms</td> <td bgcolor="#FCDE52">189ms</td> <td>+118.5%</td> <td>413ms</td> <td bgcolor="#FCDE52">217ms</td> <td>+90.7%</td> </tr> <tr style="background-color: #F9FD85;"> <td>IfThenElse:</td> <td>372ms</td> <td bgcolor="#FCDE52">128ms</td> <td>+191.8%</td> <td>374ms</td> <td bgcolor="#FCDE52">141ms</td> <td>+165.8%</td> </tr> <tr> <td>ListSlicing:</td> <td>311ms</td> <td bgcolor="#FCDE52">4033ms</td> <td>-92.3%</td> <td>315ms</td> <td bgcolor="#FCDE52">4230ms</td> <td>-92.6%</td> </tr> <tr style="background-color: #F9FD85;"> <td>NestedForLoops:</td> <td>488ms</td> <td bgcolor="#FCDE52">349ms</td> <td>+39.7%</td> <td>489ms</td> <td bgcolor="#FCDE52">382ms</td> <td>+28.1%</td> </tr> <tr> <td>NormalClassAttribute:</td> <td>430ms</td> <td bgcolor="#FCDE52">1080ms</td> <td>-60.2%</td> <td>432ms</td> <td bgcolor="#FCDE52">1104ms</td> <td>-60.9%</td> </tr> <tr> <td>NormalInstanceAttribute:</td> <td>401ms</td> <td bgcolor="#FCDE52">427ms</td> <td>-6.1%</td> <td>404ms</td> <td bgcolor="#FCDE52">442ms</td> <td>-8.7%</td> </tr> <tr style="background-color: #F9FD85;"> <td>PythonFunctionCalls:</td> <td>393ms</td> <td bgcolor="#FCDE52">302ms</td> <td>+30.1%</td> <td>402ms</td> <td bgcolor="#FCDE52">352ms</td> <td>+14.3%</td> </tr> <tr> <td>PythonMethodCalls:</td> <td>478ms</td> <td bgcolor="#FCDE52">643ms</td> <td>-25.7%</td> <td>536ms</td> <td bgcolor="#FCDE52">673ms</td> <td>-20.3%</td> </tr> <tr style="background-color: #F9FD85;"> <td>Recursion:</td> <td>547ms</td> <td bgcolor="#FCDE52">158ms</td> <td>+245.9%</td> <td>659ms</td> <td bgcolor="#FCDE52">159ms</td> <td>+313.6%</td> </tr> <tr> <td>SecondImport:</td> <td>476ms</td> <td bgcolor="#FCDE52">1383ms</td> <td>-65.6%</td> <td>481ms</td> <td bgcolor="#FCDE52">1432ms</td> <td>-66.4%</td> </tr> <tr> <td>SecondPackageImport:</td> <td>501ms</td> <td bgcolor="#FCDE52">1425ms</td> <td>-64.8%</td> <td>503ms</td> <td bgcolor="#FCDE52">1482ms</td> <td>-66.1%</td> </tr> <tr> <td>SecondSubmoduleImport:</td> <td>589ms</td> <td bgcolor="#FCDE52">1916ms</td> <td>-69.3%</td> <td>592ms</td> <td bgcolor="#FCDE52">1990ms</td> <td>-70.2%</td> </tr> <tr> <td>SimpleComplexArithmetic:</td> <td>475ms</td> <td bgcolor="#FCDE52">729ms</td> <td>-34.9%</td> <td>476ms</td> <td bgcolor="#FCDE52">758ms</td> <td>-37.3%</td> </tr> <tr> <td>SimpleDictManipulation:</td> <td>424ms</td> <td bgcolor="#FCDE52">1009ms</td> <td>-58.0%</td> <td>427ms</td> <td bgcolor="#FCDE52">1020ms</td> <td>-58.2%</td> </tr> <tr> <td>SimpleFloatArithmetic:</td> <td>416ms</td> <td bgcolor="#FCDE52">455ms</td> <td>-8.7%</td> <td>422ms</td> <td bgcolor="#FCDE52">480ms</td> <td>-12.0%</td> </tr> <tr style="background-color: #F9FD85;"> <td>SimpleIntFloatArithmetic:</td> <td>345ms</td> <td bgcolor="#FCDE52">161ms</td> <td>+113.8%</td> <td>346ms</td> <td bgcolor="#FCDE52">162ms</td> <td>+112.9%</td> </tr> <tr style="background-color: #F9FD85;"> <td>SimpleIntegerArithmetic:</td> <td>345ms</td> <td bgcolor="#FCDE52">161ms</td> <td>+114.7%</td> <td>345ms</td> <td bgcolor="#FCDE52">161ms</td> <td>+113.9%</td> </tr> <tr> <td>SimpleListManipulation:</td> <td>346ms</td> <td bgcolor="#FCDE52">497ms</td> <td>-30.4%</td> <td>350ms</td> <td bgcolor="#FCDE52">501ms</td> <td>-30.1%</td> </tr> <tr> <td>SimpleLongArithmetic:</td> <td>402ms</td> <td bgcolor="#FCDE52">1120ms</td> <td>-64.1%</td> <td>403ms</td> <td bgcolor="#FCDE52">1130ms</td> <td>-64.3%</td> </tr> <tr> <td>SmallLists:</td> <td>417ms</td> <td bgcolor="#FCDE52">1693ms</td> <td>-75.4%</td> <td>421ms</td> <td bgcolor="#FCDE52">1717ms</td> <td>-75.5%</td> </tr> <tr> <td>SmallTuples:</td> <td>450ms</td> <td bgcolor="#FCDE52">3839ms</td> <td>-88.3%</td> <td>453ms</td> <td bgcolor="#FCDE52">3915ms</td> <td>-88.4%</td> </tr> <tr> <td>SpecialClassAttribute:</td> <td>431ms</td> <td bgcolor="#FCDE52">1104ms</td> <td>-60.9%</td> <td>432ms</td> <td bgcolor="#FCDE52">1133ms</td> <td>-61.8%</td> </tr> <tr style="background-color: #F9FD85;"> <td>SpecialInstanceAttribute:</td> <td>608ms</td> <td bgcolor="#FCDE52">423ms</td> <td>+43.8%</td> <td>610ms</td> <td bgcolor="#FCDE52">437ms</td> <td>+39.5%</td> </tr> <tr> <td>StringMappings:</td> <td>443ms</td> <td bgcolor="#FCDE52">2255ms</td> <td>-80.3%</td> <td>448ms</td> <td bgcolor="#FCDE52">2311ms</td> <td>-80.6%</td> </tr> <tr> <td>StringPredicates:</td> <td>503ms</td> <td bgcolor="#FCDE52">1058ms</td> <td>-52.5%</td> <td>504ms</td> <td bgcolor="#FCDE52">1066ms</td> <td>-52.7%</td> </tr> <tr> <td>StringSlicing:</td> <td>527ms</td> <td bgcolor="#FCDE52">2880ms</td> <td>-81.7%</td> <td>562ms</td> <td bgcolor="#FCDE52">3008ms</td> <td>-81.3%</td> </tr> <tr style="background-color: #F9FD85;"> <td>TryExcept:</td> <td>418ms</td> <td bgcolor="#FCDE52">21ms</td> <td>+1905.2%</td> <td>418ms</td> <td bgcolor="#FCDE52">39ms</td> <td>+985.6%</td> </tr> <tr> <td>TryRaiseExcept:</td> <td>587ms</td> <td bgcolor="#FCDE52">6670ms</td> <td>-91.2%</td> <td>591ms</td> <td bgcolor="#FCDE52">6733ms</td> <td>-91.2%</td> </tr> <tr> <td>TupleSlicing:</td> <td>390ms</td> <td bgcolor="#FCDE52">1817ms</td> <td>-78.5%</td> <td>397ms</td> <td bgcolor="#FCDE52">1863ms</td> <td>-78.7%</td> </tr> <tr> <td>UnicodeMappings:</td> <td>362ms</td> <td bgcolor="#FCDE52">1323ms</td> <td>-72.7%</td> <td>365ms</td> <td bgcolor="#FCDE52">1347ms</td> <td>-72.9%</td> </tr> <tr> <td>UnicodePredicates:</td> <td>438ms</td> <td bgcolor="#FCDE52">860ms</td> <td>-49.0%</td> <td>439ms</td> <td bgcolor="#FCDE52">912ms</td> <td>-51.8%</td> </tr> <tr> <td>UnicodeProperties:</td> <td>400ms</td> <td bgcolor="#FCDE52">0ms</td> <td>n/a</td> <td>401ms</td> <td bgcolor="#FCDE52">0ms</td> <td>n/a</td> </tr> <tr> <td>UnicodeSlicing:</td> <td>624ms</td> <td bgcolor="#FCDE52">2491ms</td> <td>-75.0%</td> <td>666ms</td> <td bgcolor="#FCDE52">2638ms</td> <td>-74.7%<br /> </table> <p><br/><br /> The results are disappointing but not all that surprising, especially with regards to string manipulation. I attempted to run the same pybench.py tool on top of Jython but Jython doesn't appear to support the "platform" module, so I don't have a really good baseline for "managed/virtual machine-based Python implementations" right now. However, given the lack of evidence otherwise, I'll just go ahead and assume IronPython blew the doors off of Jython :). In general though this isn't the be-all end-all benchmark for IronPython, especially on Mono, but it does give a nice hint of where some improvements could be made both in the Mono runtime and IronPython. I'll have to run the benchmarks again with the newer versions of both implementations of Python to see where they're improving or degrading but by all means don't let this deter you from checking out IronPython! I'll be writing up a few code samples over the next couple weeks that I hope will be helpful to those "unenlightened" among us; dynamic languages on the CLR, what has the world come to.</p> http://www.unethicalblogger.com/posts/r_tyler_ballance/comparing_ironpython_and_cpython#comments Mono Software Development Wed, 19 Dec 2007 05:44:20 +0000 R. Tyler Croy 146 at http://www.unethicalblogger.com Mono and FastCGI. An awkward relationship. http://www.unethicalblogger.com/posts/r_tyler_ballance/mono_and_fastcgi_an_awkward_relationship <p>I've spent the week tweaking and adjusting my <a href="http://www.lighttpd.net/" target="_blank">lighttpd</a> configuration to where it cooperates better with Mono's <a href="http://www.mono-project.com/FastCGI" target="_blank">FastCGI server</a>, and I finally feel confident enough with the configuration to share. </p> <p>Around thursday morning or so (maybe it was wednesday) the site was spewing so many 500 errors that somebody who I'm not sure I know where I know them from, emailed me saying "dude, site's broke." After checking the error logs, I found a <strong>lot</strong> of errors that were all like this:</p> <pre style="margin-left: 5px; margin-right: 5px; border-top: 1px solid #ccc; border-bottom: 1px solid #ccc; padding: 5px 0px 5px 0px;">fcgi-server re-enabled: 0 /tmp/fastcgi-mono-server backend is overloaded; we'll disable it for 2 seconds and send the request to another backend instead: reconnects: 0 load: 130 fcgi-server re-enabled: 0 /tmp/fastcgi-mono-server backend is overloaded; we'll disable it for 2 seconds and send the request to another backend instead: reconnects: 0 load: 130 </pre><p> After diagnosing the problem and kicking the server again, I decided that a couple of tips on the wiki page for <a href="http://www.mono-project.com/FastCGI_Lighttpd" target="_blank">Mono's FastCGI &amp; Lighttpd</a> had done me in, the first being about the FastCGI handler's <strong>max-procs</strong> configuration variable:<br /> <div style="margin: 8px; padding: 4px; border: 1px solid #CCC; background-color: #efefef;">"max-procs" specifies the maximum number of servers to spawn. Because ASP.NET stores session specific objects, I am unsure of how applications would react if switching from one server to another, or if Lighttpd bonds a single server to a client. As such, I highly recommend keeping this value as "1" to avoid any conflicts.</div> <p>Fortunately <a href="http://urlenco.de" target="_blank">Urlenco.de</a> doesn't really need any session information, so I did what Emeril and Apache admins are both familiar with doing, I kicked it up a notch (to about 10). After kicking the server one more time, this time with <strong>"max-procs" &gt; 10</strong> I watched the load on my little 1U server spike up to 30. While every terminal I had became so sluggish I could barely interact with the machine, I managed to open up "top(1)" and see what processses were royally screwing my machine. Turns out it was 10 instances of Mono, all trying to digest an ASP.NET site at once, all competing for the meager resources available. It seems that the Mono FastCGI server will process and compile your <strong>entire</strong> ASP.NET web application as soon as the FastCGI server is bootstrapped and accepting requests. Fortunately pushing new code to the site gets updated on the next HTTP request, so the number of times you'll have to kick (i.e. restart) the Lighttpd server should be minimal and you won't have to incur the huge performance penalty that often (I've since changed max-procs to 4).<br /> <!--break--><br /> I also went against some of the other advice on the wiki page<br /> <div style="margin: 8px; padding: 4px; border: 1px solid #CCC; background-color: #efefef;">To overcome these problems, the recommended method for processing files is to send all requests directly to the FastCGI Mono Server.</div> <p> By effectively passing <strong>every single request</strong> off to the Mono FastCGI Server you can avoid exposing some internal ASP.NET resources that should be interpreted and not sent over the wire, this seems to be poor practice as far as Lighttpd and FastCGI are concerned. Lighttpd is a very good, high performance HTTP server and should be allowed to do it's job, whereas FastCGI servers merely serve as a means for executing server-side pages, returning markup, etc. To avoid passing every single request off to the FastCGI server, I merely setup the FastCGI handler for <Strong>.aspx</strong> pages and then mapped other ASP.NET extensions to that handler as was appropriate:</p> <pre style="margin-left: 5px; margin-right: 5px; border-top: 1px solid #ccc; border-bottom: 1px solid #ccc; padding: 5px 0px 5px 0px;">fastcgi.map-extensions = ( ".asmx" => ".aspx", ".ashx" => ".aspx", ".asax" => ".aspx", ".ascx" => ".aspx", ".soap" => ".aspx", ".rem" => ".aspx", ".axd" => ".aspx", ".cs" => ".aspx", ".config" => ".aspx", ".dll" => ".aspx" ) </pre><p> The base configuration for one of my virtual hosts (Urlenco.de) turned out something like this:</p> <pre style="margin-left: 5px; margin-right: 5px; border-top: 1px solid #ccc; border-bottom: 1px solid #ccc; padding: 5px 0px 5px 0px;">$HTTP["host"] == "urlenco.de" { fastcgi.server = ( ".aspx" => (( "socket" => "/tmp/fastcgi-mono-server", "bin-path" => "/usr/local/bin/fastcgi-mono-server2", "bin-environment" => ( "MONO_FCGI_APPLICATIONS" => "/:/serv/www/domains/urlenco.de/htdocs", "MONO_FCGI_LOGLEVELS" => "Standard", #All", #Debug", "MONO_FCGI_LOGFILE" => "/var/log/lighttpd/mono.log", ), "max-procs" => 4, "check-local" => "disable" )) ) } </pre><p> Specifying the "application path" is somewhat of a pain, as now I more or less need a separate FastCGI configuration, which means they'll also need separate FastCGI servers, so another virtual host in the configuration (pineapple.monkeypox.org) has the following setup:</p> <pre style="margin-left: 5px; margin-right: 5px; border-top: 1px solid #ccc; border-bottom: 1px solid #ccc; padding: 5px 0px 5px 0px;">$HTTP["host"] == "pineapple.monkeypox.org" { fastcgi.server = ( ".aspx" => (( "socket" => "/tmp/fastcgi-mono-server-pineapple", "bin-path" => "/usr/local/bin/fastcgi-mono-server2", "bin-environment" => ( "MONO_FCGI_APPLICATIONS" => "/:/serv/www/domains/pineapple.monkeypox.org/htdocs", "MONO_FCGI_LOGLEVELS" => "Standard", #All", #Debug", "MONO_FCGI_LOGFILE" => "/var/log/lighttpd/mono.log", ), "max-procs" => 1, "check-local" => "disable" )) ) }</pre><p> Since the virtual host pineapple.monkeypox.org barely runs any ASP.NET code at all, I decided to only give it one Mono FastCGI process. Also of note is that the "socket" is different from the other FastCGI handler, if you try to use the same socket, the first Mono FastCGI process will take it over and both FastCGI handlers will return the same code, returned from the first handler. </p> <p>Feel free to bug me with any questions, this is my first foray into using Lighttpd and I'm already pleased as punch with it (compared to Apache) but there are certainly some caveats and bits of black magic involved with Mono, FastCGI and Lighttpd. That said, it still feels less sticky than running Apache 2 and mod_mono (not that they're not great and all). Hopefully web traffic will increase and give me a good test-bed for figuring out "the right stuff" to scale Mono on Lighttpd.<br /> <br/><br /> Scary thought isn't it? :)</p> http://www.unethicalblogger.com/posts/r_tyler_ballance/mono_and_fastcgi_an_awkward_relationship#comments Miscellaneous Mono Sun, 16 Dec 2007 10:36:10 +0000 R. Tyler Croy 142 at http://www.unethicalblogger.com Urlenco.de: Mono, Lighttpd, and PostgreSQL. http://www.unethicalblogger.com/posts/r_tyler_ballance/urlenco_de_mono_lighttpd_and_postgresql <p>During the nigh 12 hour break I had between <A href="http://www.slide.com">regular work</a> over Thanksgiving, I spent about four hours writing a little utility that I wanted to use instead of <a href="http://tinyurl.com" target="_blank">TinyURL</a>, and found a fantastic domain name for it too: <a href="http://urlenco.de" target="_blank">Urlenco.de</a>. I also wanted to use the opportunity to explore using <a href="http://urlenco.de/rfifrme" target="_blank">Npgsql</a>, the .NET connector for PostgreSQL, which was a very pleasant experience after using the MySQL .NET connector (part of the pleasant experience was using PostgreSQL itself, of course). Another new thing to explore was the <a href="http://urlenco.de/fozefo" target="_blank">FastCGI support for Mono/ASP.NET</a>, I'll be sure to jot down my experiences with Mono's FastCGI support in a later post since my brain is too fried to talk about it coherently in detail.</p> <p>The most important part of the entire project was further refining my rapid-development process for Mono and ASP.NET so I can do quick little projects like this and push them to a live webserver in a matter of hours instead of days (of time I don't have). This mostly consists of boiler-plate project templates for some basic database code, page templates, and a NAnt build script that facilitates the building and testing of the site using xsp2 on localhost. Nothing spectacular, just having a toolkit of necessities to take from one project to the next, especially when time is at such a premium, is a minor but important difference from how I work now as opposed to how I used to work (when I had expendable time).</p> <p>One of my favorite parts of the entire Urlenco.de project was setting up a <a href="http://urlenco.de/Developer.aspx" target="_blank">Urlenco.de API</a> for both encoding (tiny'ing) and decoding (untiny'ing) URLs to and from Urlenco.de, all in under 10 minutes after a suggestion from my friend Dennis at <a href="http://www.palantirtech.com/" target="_blank">Palantir</a>. After another suggestion, I also wrote a <a href="http://urlenco.de/Stats.aspx" target="_blank">Urlenco.de stats page</a> using the <a href="http://code.google.com/apis/chart/">Google Charts API</a> in about 10 minutes as well. </p> <p>Hopefully this weekend I'll be able to write more about Mono and FastCGI (look ma! no apache!) and why it rocks, and why it sucks, etc. But for now I just wanted to point the service out, and hopefully get some more folks banging against it so I can evaluate whether Mono and FastCGI is ready for some larger projects I have coming down the pipe that I want to move away Apache 2.</p> http://www.unethicalblogger.com/posts/r_tyler_ballance/urlenco_de_mono_lighttpd_and_postgresql#comments Miscellaneous Mono Wed, 12 Dec 2007 10:45:39 +0000 R. Tyler Croy 141 at http://www.unethicalblogger.com Missed Spain :( http://www.unethicalblogger.com/posts/r_tyler_ballance/missed_spain <p>I hope everybody enjoyed their stay this past week in Madrid for the <a href="http://mono-project.com/MonoSummit2007">Mono Summit 2007</a>. </p> <p>Unfortunately, it's been too hectic a month to take the week off and go to Madrid, so I'm incredibly jealous of all of you. Grumble.</p> <p><center><a href="http://icanhascheezburger.com/2007/06/06/im-in-ur-office-2/"><img src="http://icanhascheezburger.wordpress.com/files/2007/06/im-in-ur-office-earnin-ur-salry.jpg" alt="I'm in ur office earnin ur salry" /></a></center></p> http://www.unethicalblogger.com/posts/r_tyler_ballance/missed_spain#comments Mono Sat, 01 Dec 2007 20:59:57 +0000 R. Tyler Croy 140 at http://www.unethicalblogger.com "Why are you awesome?" meet Mono http://www.unethicalblogger.com/posts/r_tyler_ballance/why_are_you_awesome_meet_mono <p>When I originally wrote the Facebook demo application "<a href="http://unethicalblogger.com/posts/r_tyler_ballance/introducing_why_are_you_awesome">Why are you awesome?</a>" <img src="http://unethicalblogger.com/files/using-mono.png" align="right"/> I wrote it in PHP4 in about 3 hours and hated myself for every one of those miserable 180 minutes. Since then however, I've been slowly and methodically working on a new, JSON-based, Facebook client library (Mono.Facebook.Platform) specifically to bring together some of the aspects of <a href="http://code.google.com/p/pyfacebook/" target="_blank">pyfacebook</a>, the <a href="http://wiki.developers.facebook.com/index.php/PHP" target="_blank">PHP client</a>, and the <a href="http://www.codeplex.com/FacebookToolkit" target="_blank">Facebook Toolkit</a> that I like (implementation progress can be found in the <a href="http://anonsvn.mono-project.com/viewcvs/*checkout*/trunk/facebook-sharp/src/Mono.Facebook.Platform/NOTES?rev=89668" target="_blank">NOTES</a>). After getting some of the key Facebook calls implemented to support "Why are you awesome?" I figured I might as well give it a whirl and see if a "real" application would work on top of the library (it does).</p> <p>Thus far, all that were needed as far as library calls were: <ul> <li>feed.publishActionOfUser</li> <li>notifications.send</li> <li>fql.query</li> <li>profile.setFBML</li> </ul> <p>A couple of the things I've found thus far in my work have been, that writing a library that you <strong>have</strong> to use forces you to think about what you add and what you remove a lot more and focus on simplicity and extensibility; secondly, JSON is much faster, meaning I can do things with the Mono.Facebook.Platform library that I couldn't with the XML-based PHP4/5 library. Operations like fetching the user IDs of all 700 friends of mine complete in a timely fashion under the JSON library, whereas they typically timeout with the XML-based libraries.<br /> <center><img src="http://unethicalblogger.com/files/awesome_feed.png"/></center></p> <p>The Mono.Facebook.Platform library isn't even alpha, it's in negative greek letters right now, there's not enough of the API implemented, and it doesn't handle errors very well at all, so don't use it. When it's finished however, I intend to support over 90% of the Facebook calls, and offer it up as a faster, viable option, for ASP.NET developers on Windows and on Mono.</p> <p>Of course if you want to check out "Why are you awesome?", head on over to the <a href="http://apps.facebook.com/whyareyouawesome/">application page</a> and install it.<br /> <!--break--></p> http://www.unethicalblogger.com/posts/r_tyler_ballance/why_are_you_awesome_meet_mono#comments Facebook Mono Thu, 15 Nov 2007 13:57:12 +0000 R. Tyler Croy 136 at http://www.unethicalblogger.com Building Mono on Leopard http://www.unethicalblogger.com/posts/r_tyler_ballance/building_mono_on_leopard <p>I figured I'd write up a guide to building Mono from Subversion in preparation of the upcoming 1.2.6 release, on a site I've neglected since I set it up, <a href="http://mononews.org">mononews.org</a> (I hope to get back to writing tutorials and "newsy" stuff with the 1.2.6 release).</p> <p>Anyways, if you've got Leopard installed, Geoff Norton did a great job in helping me track down the remaining Leopard/i386 bugs earlier today, so now you can build and run Mono relatively easily from Subversion on your fancy smancy new OS.</p> <p><center><strong><a href="http://mononews.org/stories/mono-tutorial/building-mono-leopard">Building Mono on Leopard</a></strong></center></p> http://www.unethicalblogger.com/posts/r_tyler_ballance/building_mono_on_leopard#comments Mono Tue, 06 Nov 2007 09:59:40 +0000 R. Tyler Croy 134 at http://www.unethicalblogger.com Any Unemployed .NET Developers in NYC? http://www.unethicalblogger.com/posts/r_tyler_ballance/any_unemployed_net_developers_in_nyc <p>Last week at the <a href="http://widgetsummit.com/" target="_blank">Widget Summit</a> speakers dinner I met an executive from <a href="http://www.doubleclick.com/" target="_blank">DoubleClick</a>, you know, that gigantic ad company that <a href="http://www.businessweek.com/technology/content/apr2007/tc20070414_675511.htm?campaign_id=rss_daily" target="_blank">recently got acquired by Google, Inc.</a> While talking about some of the difficulties in developing scalable web products I brought up some of my history in terms of developing .NET web applications and of course, <a href="http://mono-project.com/" target="_blank">Mono</a> (at least I <em>think</em> that's how we got on the topic).</p> <p>As it turns out, DoubleClick is really pushing to modernize their internal infrastructure on the .NET platform and <strong>really</strong> needs some smart folks either willing to move to New York City, or that already live there. If you're looking, feel free to contact me at <strong>[email protected]</strong> and I'll put you in touch, or hit up their <a href="http://www.doubleclick.com/careers/job_search.aspx">careers page</a>.</p> <p>If you go to work at DoubleClick, I <em>think</em> you can technically get away with saying you work for Google. You'll also be able to say you are working on truly scalable .NET, which is something I really only think Windows Live and Myspace<strong>*</strong> developers can say currently.</p> <p>Of course, if you're on the west-coast or lean more towards Python, <a href="http://www.slide.com/static/jobs">Slide is always hiring</a>. </p> <p><br/><br /> <strong>*</strong> <small>As it turns out, Myspace runs one of the largest .NET sites on the internet, and lays claim to the largest SQL Server installation on the entire planet.</small></p> http://www.unethicalblogger.com/posts/r_tyler_ballance/any_unemployed_net_developers_in_nyc#comments Miscellaneous Mono Software Development Sat, 20 Oct 2007 11:01:11 +0000 R. Tyler Croy 127 at http://www.unethicalblogger.com Remix 07 Boston Wrap-up http://www.unethicalblogger.com/posts/r_tyler_ballance/remix_07_boston_wrap_up <p>Earlier this week, following <a href="http://unethicalblogger.com/posts/r_tyler_ballance/conference_season_communitynext_platform">CommunityNext</a> and <a href="http://unethicalblogger.com/posts/r_tyler_ballance/graphing_social_building_your_first_app_workshop">Graphing Social</a> I was lucky enough to have been asked out to Boston for <a href="http://www.remix07boston.com/">Remix 07 Boston</a>. After receiving the necessary flack from my co-workers at <a href="http://www.slide.com">Slide</a> (primarily a Python/Linux shop), I boarded a plane late Sunday night to arrive <strong>extremely</strong> early on Monday morning (6a.m. isn't my best hour). </p> <p>Upon arrival to the Hyatt Regency Cambridge, I found out that I had access to the Media Room, which allowed me to recharge my laptop and plug into a hard-wired connection such that I was able to write up a <a href="http://unethicalblogger.com/posts/r_tyler_ballance/in_boston_at_remix_phew">few</a> <a href="http://unethicalblogger.com/posts/r_tyler_ballance/miguel_questions_the_manhood_of_400_microsoft_developers_awesome">blog</a> <a href="http://unethicalblogger.com/posts/r_tyler_ballance/miguel_de_icazas_remix_07_boston_keynote_address">posts</a> from the conference itself. Having such access also allowed me to work on some sample Silverlight applications that I'll write up over the weekend covering Silverlight and IronPython. </p> <p>While I enjoyed the sessions, such as Miguel's session on Moonlight and Mono and another session on the DLR and dynamic languages, what I enjoyed most was the ability to pick the brains of some of the folks there. Specifically guys like <a href="http://www.brethorsting.com/">Aaron Brethorst</a>, who works a lot on Microsoft Popfly's interface among other things, who let me question just about everything under the sun with regards to Popfly while still maintaining that I really like the application and its potential.</p> <p>I also really enjoyed meeting up with <a href="http://tirania.org/blog/index.html">Miguel</a> and his crew at Novell (<a href="http://abock.org/">Aaron Bockover</a> and <a href="http://mjhutchinson.com/journal/category/mono/0">Michael Hutchinson</a>) after Miguel was kind enough to take me to a late lunch and then show me around Novell's Boston office. I also think Miguel successfully guilted me into contributing more code that I've been putting off for so long, like my Mono.Nat NAT-PMP code, Mono.Facebook.Platform, and some patches for System.Web.Script.Serialization; all of which I have neglected in the difficult search for a good night's rest, or the perfect ping-pong serve against co-workers.</p> <p>I still look and feel mostly dead from exhaustion, but not dead enough not to continue pounding away on <a href="http://apps.facebook.com/topeight/">everybody's favorite Facebook app</a>, or working on some of the other really cool things that we work on here at Slide (<a href="http://www.slide.com/pic_arrange">bubble text!</a>). In the valley, everybody knows who Slide is now, everybody knows what's going on with Facebook, and an extremely small subset of people that matter know who I am; but on the east coast, far fewer understand what's going on right now on "that college social network, right?"</p> <p>Miguel said he doesn't install Facebook applications citing the near-complete opacity of the security and data-storage policy to the end-user, but maybe now that he's met me, and knows who's behind it, he'll install Top Friends and I'll finally be able to claim that Miguel uses something that I wrote, instead of the usual case of vice versa.</p> <p><strong>Note to self:</strong> Travel back to Boston, soon.</p> http://www.unethicalblogger.com/posts/r_tyler_ballance/remix_07_boston_wrap_up#comments Facebook Miscellaneous Mono Slide Fri, 12 Oct 2007 08:51:28 +0000 R. Tyler Croy 122 at http://www.unethicalblogger.com Miguel de Icaza's Remix 07 Boston Keynote Address http://www.unethicalblogger.com/posts/r_tyler_ballance/miguel_de_icazas_remix_07_boston_keynote_address <p>Before I leave Boston, I had to make sure of one more thing, that my fellow Mono bretheren got to see what I got to see, Miguel's keynote. Thanks to lots of hard encoding and video preparation done by <a href="http://blogs.msdn.com/gduthie/" target="_blank">G. Andrew Duthie</a> and his crew from Microsoft's Media Room at Remix 07 Boston, the videos from the keynote have already been posted in their entirety to <a href="http://channel9.msdn.com" target="_blank">Channel 9</a>.</p> <p>Unfortunately they didn't clip the videos on a per-speaker basis, so you'll probably want to fast-forward in the video to about the 11 minute marker to watch our fearless leader <a href="http://unethicalblogger.com/posts/r_tyler_ballance/miguel_questions_the_manhood_of_400_microsoft_developers_awesome" target="_blank">question the manhood of 400 Microsoft developers</a> as I had previously mentioned. Talking with Miguel after the fact he mentioned that some of his more witty quips were mostly due to him worrying about things breaking on stage and going impromptu with some of the things he was talking about. Overall though I think Miguel did a great job exhibiting Moonlight and the Gnome desktop in general, so I hope you enjoy the video (again, fast-forward to the 11 minute marker).</p> <p><center><strong><a href="http://channel9.msdn.com/Showpost.aspx?postid=346672">Watch Miguel on stage at Remix 07 Boston</a></strong> (<small><a href="http://channel9.msdn.com/Screencasts/346672_RemixMonMornKeynoteP5.wmv">direct link</a></small>)<br/>(<small><a href="http://www.videolan.org/" target="_blank">Download VLC to watch on Linux/Mac OS X</a></small>)</center></p> http://www.unethicalblogger.com/posts/r_tyler_ballance/miguel_de_icazas_remix_07_boston_keynote_address#comments Mono Wed, 10 Oct 2007 04:19:57 +0000 R. Tyler Croy 121 at http://www.unethicalblogger.com Miguel questions the manhood of 400 Microsoft Developers. Awesome. http://www.unethicalblogger.com/posts/r_tyler_ballance/miguel_questions_the_manhood_of_400_microsoft_developers_awesome <p><a href="http://tirania.org/blog/">Miguel de Icaza</a>, one of my own personal geek heroes, just gave his brief "keynote" as part of Microsoft's partner talks component of the overall Remix Boston 07 keynote speech.</p> <p><img src="http://unethicalblogger.com/files/none.png" align="right"/>After previous demos being proudly shown for "working in Safari on Mac OS X, and oh by the way, it's PC compatible too", Miguel showed everybody up by pulling up the still <strong>very</strong> development version of <a href="http://mono-project.com/Moonlight">Moonlight</a> and dazzled a room full of hardened .NET/ASP.NET developers and designers with Mono's progress on the Moonlight project in a scant 4 months since the original "Mix Vegas" conference earlier this year.</p> <p>If you hang around Miguel enough, you'll know how much he loves <a href="http://compiz.org/">Compiz</a>, which he used gratuitously during his demonstrations. The mixture of a good looking Gnome skin and Compiz really helped convey that "yes, Linux is here, Gnome is a fully-featured desktop environment, and check out this <em>AWESOME CUBE EFFECT!</em>" As a developer who's participated in the open source community for almost five years now, it was <em>very</em> inspiring to see a room full of Microsoft's battle-tempered third party developers pine to have some of the cool features that <strong>Linux</strong> has!</p> <p>Some of the Silverlight applications Miguel demonstrated were <a href="http://metaliq.com/portfolio/silverlight.html">Metaliq's Top Banana</a> which ran surprisingly well, then <a href="http://silverlight.net/samples/1.1/chess/run/default.html">Silverlight Chess</a> followed by the <a href="http://halo3.msn.com/">Halo 3 trailer</a> running (not streaming) on Miguel's Linux laptop. To invite further jealousy from the room of developers, Miguel fired up Firefox, running Moonlight, running the Halo 3 Trailer, on the edge of a "cube" workspace (<a href="http://compiz.org/Image:FrontpageImage.jpg">such as this</a>). Applause ensued.</p> <p>Coming back to the topic of developing Silverlight/Moonlight applications on top of Linux, Miguel fired up MonoDevelop claiming that "we have one, I just don't use it; I have an allergy to IDEs." Much to my surprise, he then fired up Emacs to edit his local copy of Silverlight Chess, updating a property such that it returned "Mono" instead of ".NET" in the interface, dropped back into his X terminal and ran "make" like, quote, "<strong>real men do</strong>" (to which some of the crowd applauded and the rest laughed). Miguel then ran the <strike>Silverlight</strike>Moonlight Chess application and closed his keynote speech stating that:</p> <p>"Your designers can use Expression Blend on Windows, but your real developers can use Linux to develop Silverlight."</p> <p>Overall the keynote was very well done but it really seemed like Miguel stole the show after so much emphasis was placed on "Silverlight's portability" by really showing what the Mono Project is capable of, and that while Silverlight may work on Mac and Windows, <strong>Moonlight</strong> runs on the corner of a wicked cool cube.</p> http://www.unethicalblogger.com/posts/r_tyler_ballance/miguel_questions_the_manhood_of_400_microsoft_developers_awesome#comments Mono Mon, 08 Oct 2007 15:07:25 +0000 R. Tyler Croy 119 at http://www.unethicalblogger.com In Boston, At Remix. Phew. http://www.unethicalblogger.com/posts/r_tyler_ballance/in_boston_at_remix_phew <p>After a grueling flight that started with a full-on sprint from the TSA security checkpoint and ended about a quarter mile through the terminal (in socks no less), I have made it across the country to Boston for <a href="http://www.remix07boston.com/">Remix 07 Boston</a>.</p> <p>I'm still anxiously awaiting the keynote, and trying to find the Mono guys that are in attendance to try to learn as much as possible about the development and future of Moonlight, while simultaneously trying to learn as much as possible about how other developers are embracing and using Silverlight too.</p> <p>If you're at Remix, come find me, I'm a San Franciscan in a rainy Boston, and I'm scared ;)</p> <p>I'm this idiot, rocking my "business attire"<br /> <center><img src="http://unethicalblogger.com/files/Photo 29.jpg" height="240" width="320"/></center></p> http://www.unethicalblogger.com/posts/r_tyler_ballance/in_boston_at_remix_phew#comments Miscellaneous Mono Software Development Mon, 08 Oct 2007 11:42:14 +0000 R. Tyler Croy 118 at http://www.unethicalblogger.com Remix 07 Boston, Woohoo! http://www.unethicalblogger.com/posts/r_tyler_ballance/remix_07_boston_woohoo <p><img src="http://unethicalblogger.com/files/remix07.gif" align="right"/><br /> Turns out I'll be attending <a href="http://www.remix07boston.com/" target="_blank">Remix 07 Boston</a> next week but unfortunately my mega-cool-Silverlight hack won't be finished due to some scheduling complexities involved with working 130% of my time at a <a href="http://www.slide.com" target="_blank">start-up in San Francisco</a> (turns out, not too conducive to side-projects). I will be arriving bright and early at 6:30a.m. pounding down a gigantic (and expensive) airport coffee, and then heading to the Hyatt Regency Cambridge, so I apologize in advance if I look exceedingly tired Monday morning.</p> <p>It'll be a great opportunity to get a feel for where Microsoft thinks that Silverlight is going, and how they intend to get there. It's a long hard road to even become <strong>near</strong> where Flash is in terms of market entrenchment, but Microsoft is one of three companies I believe currently capable of acheiving it (the other two being Adobe itself [bought Macromedia, they cheated], and Apple).</p> <p>I would also like to give those <a href="http://unethicalblogger.com/posts/r_tyler_ballance/popfly_how_to_lose_the_buzz" target="_blank">Popfly guys an earful</a> but I may spare them depending on how busy I am trying to find some fellow Facebook developers that live in the Boston area, or <a href="http://tirania.org/blog/" target="_blank">Miguel</a>, who I'm pretty sure doesn't exist, but is merely a robotic creation of some wacky laboratory in Mexico.</p> <p>If you'd like to meetup and have lunch, or a beer in the evening Monday or Tuesday, feel free to send me at email ([email protected]) or track me down during the actual conference (<a href="http://www.flickr.com/photos/agentdero/419361757/" target="_blank">i'm this guy</a>).</p> <p>Special thanks to Anand for what us young-folk call "the hook-ups" and I look forward to seeing both of my blog readers in Boston next week ;)</p> http://www.unethicalblogger.com/posts/r_tyler_ballance/remix_07_boston_woohoo#comments Miscellaneous Mono Wed, 03 Oct 2007 07:01:47 +0000 R. Tyler Croy 112 at http://www.unethicalblogger.com Popfly. How to lose the buzz. http://www.unethicalblogger.com/posts/r_tyler_ballance/popfly_how_to_lose_the_buzz <p>I remember watching a Channel 9 interview about <A href="http://www.popfly.com" target="_blank">Popfly</a> with my coworker and former landlord <a href="http://stuffonfire.com/" target="_blank">David Young</a> just after the original Facebook F8 Platform Launch back in May, laughing hysterically at a user-interface that used <a href="http://unethicalblogger.com/files/grassy_fly.jpg" rel="lightbox">grass as an interface element</a>, but at the same time thinking it was a <strong>very</strong> cool use of Silverlight as an application platform, instead of a Microsoft reply to Flash. Since that fateful day in May when a Microsoft Vice President of Business Development unveiled Popfly (exactly who should be unveiling a developer tool), I've heard close to absolutely nothing about Popfly, but loads about Silverlight. </p> <p>Waiting to build a new version of Mono from trunk, I figured I'd check it out again, hoping their ludicrous "private beta" period would have passed, and I could finally use the technology that was unveiled almost 5 whole months ago. Alas, despite having the Silverlight plugin for Safari, <a href="http://unethicalblogger.com/files/popfly_safari.jpg" rel="lightbox">popfly.com doesn't support Safari</a> (I thought people wrote cross-platform web pages these days). Admitting my defeat, I popped open my VMWare instance of Windows XP, and Internet Exploder 7, only to discover that yes, <a href="http://unethicalblogger.com/files/popfly_ie.jpg" rel="lightbox">Popfly is still invite-only</a> <strong>or</strong> they're having server difficulties? Despite their <a href="http://www.popfly.com/Overview/About.aspx" target="_blank">about page</a> jokingly referring to themselves as the developers behind products like Microsoft Bob, I'm starting to wonder if they weren't joking, as Popfly's introduction at F8 was either woefully premature or Microsoft decided that a developer environment where you draw lasers in-between boxes that <a href="http://unethicalblogger.com/files/boxes_and_such_ib.jpg" rel="lightbox">represent stuff is too silly.</a></p> <p>All my criticisms aside, the product does look interesting enough for me to be excited about the Popfly session at <a href="http://www.remix07boston.com/Agenda.aspx" target="_blank">ReMix Boston '07</a> in October, if for no other reason than to ask for an invite, and maybe even <strong>wtf?</strong> </p> <p>Given the insane amount of buzz around the Facebook Platform, and independent developers struggling to get cool applications into users' hands fast enough, Microsoft screwed up royally on a chance to sow the seeds of the next generation of developers on the web with Microsoft technologies. </p> <p>Dear 800lb Gorilla,<br /> When you announce something at a tech event that could possibly turn out to be industry changing like the Facebook Platform Launch, actually have the product ready for people to start using, otherwise, why bother?</p> http://www.unethicalblogger.com/posts/r_tyler_ballance/popfly_how_to_lose_the_buzz#comments Facebook Mono Opinion Thu, 27 Sep 2007 10:43:54 +0000 R. Tyler Croy 110 at http://www.unethicalblogger.com Contemplating ReMIX 07 in Boston http://www.unethicalblogger.com/posts/2007/09/contemplating_remix_07_boston <p>While catching up on about 2 weeks of Mono Subversion commit emails (about 1000), building Mono, and writing a new Facebook REST client library, I came across <a href="http://www.remix07boston.com/" target="_blank">ReMIX 07 in Boston</a>, which certainly looks interesting. I haven't been to Boston yet, and it'd be nice to at the very least, to try to buy Miguel and some of the Boston-based Mono team a beer, maybe to make up for some of my anger that sometimes blurts out into the IRC channel:</p> <p>05:48 &lt;rtyler&gt; god <strong>[expletive-deleted]</strong> damnit, I'm going to beat somebody up(Which, in all fairness, usually stems from some idiot mistake on my part)</p> <p>The sessions on Silverlight by <a href="http://adamkinney.com/" target="_blank">Adam Kinney</a>, who I did <a href="http://unethicalblogger.com/posts/r_tyler_ballance/channel9_silverlight_interview" target="_blank">this interview</a> with, are definitely looking enticing, as I'm still trying to figure out if it's worth my time and effort, or if Microsoft is going to screw developers <strong>again</strong> (<A href="http://www.mactech.com/articles/mactech/Vol.13/13.06/ActiveXControlsforMac/index.html" target="_blank">ActiveX for Mac OS anybody?</a>). </p> <p>Most of the sessions seem to be targeting web developers, which is a role I find myself increasingly definable by, despite my role being clearly stated on my business card: </p> <p><a href="http://www.flickr.com/photos/agentdero/491860249/" title="Grrrrrrrrrr" target="_blank"><img src="http://farm1.static.flickr.com/206/491860249_9479617d6b_o.jpg" width="250" alt="New Biz Card" /></a></p> <p>Regardless, seeing what developers are doing off in la-la-Microsoft land should be interesting as most of my <a href="http://apps.facebook.com/topeight/" target="_blank">web</a> <a href="http://apps.facebook.com/fortunate" target="_blank">development</a> <a href="http://apps.facebook.com/bugtracker" target="_blank">work</a> is either in Python or ASP.NET(Mono).</p> <p>I am a little disappointed in the lack of sessions on IronPython and where that project is heading; it probably lost out to mega-mind-boggling sessions like "<em>Stop Building PowerPoint Backgrounds &amp; Start Selling High-end Presentations</em>", which means I would have to settle on "<em>Just Glue It! Ruby and the DLR in Silverlight</em>" for my DLR fix.</p> <p>That said, will it be worth a trip across country and a couple of hundred dollars out of pocket? Any couches available in the Boston are? And of course, are Microsoft conferences <strong>that</strong> awesome?</p> Miscellaneous Mono Software Development Sun, 23 Sep 2007 11:34:12 +0000 R. Tyler Croy 109 at http://www.unethicalblogger.com Channel9 Silverlight Interview http://www.unethicalblogger.com/posts/r_tyler_ballance/channel9_silverlight_interview <p><a href="http://channel9.msdn.com/showpost.aspx?postid=342743" target="_blank"><img src="http://unethicalblogger.com/files/my_silverlight_vid.jpg" align="right" width="135"/></a>At the closing of <a href="http://barcamp.org/SilverlightDevCampSF" target="_blank">SilverlightDevCampSF</a> Microsoft Evangelist <a href="http://adamkinney.com/" target="_blank">Adam Kinney</a> did a brief video interview with me about my silly Silverlight hack. I had just started with Silverlight the night before, and didn't even have <a href="http://mono-project.com/Moonlight" target="_blank">Moonlight</a> virtual machine up yet, but I did have a Windows XP vm kicking around. </p> <p>After the, roughly, three hours it took me to get Visual Studio 2008 (Orcas), Expression Blend, and a couple of other tidbits installed on my vm, I finally got to my Silverlight hack. Starting with something I presumed would be exceedingly simply, I created <a href="http://www.slide.com" target="_blank">our</a> "collage" transition in Silverlight (you can find a "sample" <a href="http://monkeypox.org/silverlight/collage/" target="_blank">here</a>).</p> <p>The hack is relatively simple, a new randomly generated storyboard and canvas are created for each image, then added to the root element; after 15 images have been added the canvas is cleared and repeats. I used Silverlight 1.0, since that's all that is released right now, so everything is in Javascript (<a href="http://twitter.com/agentdero/statuses/270270152" target="_blank"><strong>argh!</strong></a>), but I intend on revisiting the hack once Silverlight 1.1 is a bit more stable (and rewrite it in IronPython!).</p> <p>Anyways, <a href="http://channel9.msdn.com/showpost.aspx?postid=342743" target="_blank">here's the interview</a>.</p> http://www.unethicalblogger.com/posts/r_tyler_ballance/channel9_silverlight_interview#comments Miscellaneous Mono Software Development Wed, 19 Sep 2007 12:28:23 +0000 R. Tyler Croy 107 at http://www.unethicalblogger.com SIlverSurfer, Try out Silverlight on Mac OS X http://www.unethicalblogger.com/posts/r_tyler_ballance/silversurfer_try_out_silverlight_on_mac_os_x <p><img src="http://unethicalblogger.com/files/762.jpg" align="right" width="125"/>At the <a href="http://barcamp.org/SilverlightDevCampSF" target="_blank">SilverlightDevCampSF</a> this past couple days, I discovered a couple things while hacking around with both <a href="http://mono-project.com/Moonlight" target="_blank">Moonlight</a>, and <a href="http://silverlight.net/" target="_blank">Silverlight</a>. </p> <p>The first of which was that I don't know nearly enough about Silverlight, XAML, and WPF in general (crap). The second of which, was that with WebKit on Mac OS X, any application that embeds WebViews inherits plugins that are installed on the system. Extending this idea further, WebKit can inherit plugins that are bundled with a Cocoa application (inside Application.app/Contents/PlugIns), woohoo! What this means, outside of a purely Silverlight-related context, is that you could theoretically bundle a WebKit-plugin with a WebKit-based application and just have that plugin purely application specific, or bundle up a WebKit application with different versions of Flash and Silverlight for testing purposes. Unfortunately, there are some issues with clicking through to the Silverlight canvas in an embedded WebKit view, you can still try it out inside an application, without having to install the Silverlight plugin and restart your instance of Safari.</p> <p>That said, are you thinking what I'm thinking? Of course not, you're probably sane, but I'm not, so I'd like to introduce <a href="http://unethicalblogger.com/dist/SilverSurfer.zip" target="_blank">SilverSurfer 1.0</a>, an embedded version of WebKit that loads in the Silverlight 1.0 plugin for Mac OS X. It <strong>doesn't</strong> install anything on your computer, so you don't have to restart Safari, or futz with plug-ins, this is especially useful if you just want to try Silverlight out and see what it's about without installing anything.</p> <h2><small>Running SilverSurfer</small></h2> <p><center><a href="http://unethicalblogger.com/files/silversurfer_google.jpg" rel="lightbox"><img src="http://unethicalblogger.com/files/silversurfer_google.jpg" width="400"/></a></center></p> <h2><small>Visiting a Silverlight page in Safari</small></h2> <p><center><a href="http://unethicalblogger.com/files/silversurfer_safari.jpg" rel="lightbox"><img src="http://unethicalblogger.com/files/silversurfer_safari.jpg" width="400"/></a></center></p> <h2><small>Visiting the same page in SilverSurfer</small></h2> <p><center><a href="http://unethicalblogger.com/files/silversurfer_runningsilverlight.jpg" rel="lightbox"><img src="http://unethicalblogger.com/files/silversurfer_runningsilverlight.jpg" width="400"/></a></center></p> <h2><small>Complex Silverlight in SilverSurfer</small></h2> <p><center><a href="http://unethicalblogger.com/files/silversurfer_virtualearth.jpg" rel="lightbox"><img src="http://unethicalblogger.com/files/silversurfer_virtualearth.jpg" width="400"/></a></center></p> <p>I think it's a neat trick, the only downside is actually having to bundle up the entire Silverlight.plugin bundle with the application bundle to make sure you don't have to install it, but other than that I hope you can find it useful when trying out Silverlight, or just testing it in Safari!</p> http://www.unethicalblogger.com/posts/r_tyler_ballance/silversurfer_try_out_silverlight_on_mac_os_x#comments Mono Software Development Sun, 16 Sep 2007 05:25:48 +0000 R. Tyler Croy 106 at http://www.unethicalblogger.com C'mon down to SilverlightDevCampSF http://www.unethicalblogger.com/posts/r_tyler_ballance/cmon_down_to_silverlightdevcampsf <p>A bit late to bring up, but later today and tomorrow here in San Francisco, "we" (using that term loosely) will be holding <a href="http://barcamp.org/SilverlightDevCampSF" target="_blank">SilverlightDevCampSF</a>, one of the first <a href="http://barcamp.org" target="_blank">BarCamp</a>-styled events that I'll have ever attended where I've not played a part in it's organization. </p> <p>In case you're unfamiliar with BarCamp events, they're loosely organized meetups/conferences to which geeks flock to normally for the booze included, but sometimes for the technical aspects as well.</p> <p>I'm showing up particularly for Kevin Marshall's session on "Silverlight Facebook Apps" for obvious reasons, as well as to try my best to enlighten my fellow developers on the joys of Mono and Moonlight (that last part might not work out, time permitting). Overall it should be fun, and I hope if you're in the bay area you can make it down to 1 Market St! (<small><a href="http://maps.google.com/maps?f=q&amp;hl=en&amp;geocode=&amp;q=1+Market+Street+san+francisco,+ca&amp;sll=37.0625,-95.677068&amp;sspn=51.04407,81.738281&amp;ie=UTF8&amp;z=17&amp;iwloc=addr&amp;om=1" target="_blank">map</a></small>)</p> <p><center>In case you're showing up, here's what I look like:<br/><br /> <img src="http://unethicalblogger.com/files/Photo 6.jpg" height="150"/><br/><strong>I'm with stupid ^</strong></center></p> http://www.unethicalblogger.com/posts/r_tyler_ballance/cmon_down_to_silverlightdevcampsf#comments Mono Software Development Fri, 14 Sep 2007 21:29:20 +0000 R. Tyler Croy 105 at http://www.unethicalblogger.com IronPython for MacPorts http://www.unethicalblogger.com/posts/r_tyler_ballance/ironpython_for_macports <p>What goes better with Sunday evening boredom better than some <a href="http://www.tcl.tk/" target="_blank">Tcl</a> scripting and package management? I know! Nearly nothing, my sentiments exactly. After stumbling across a <a href="http://geeklair.net/new_macports_guide/" target="_blank">guide</a> or <a href="http://www.redhillconsulting.com.au/blogs/simon/archives/000379.html" target="_blank">two</a>, I decided I should give creating an <a href="http://www.codeplex.com/IronPython" target="_blank">IronPython</a> <a href="http://www.macports.org" target="_blank">MacPort</a> a try.</p> <p>I'm not sure on the utility of this minor hack, since the <a href="http://mono-project.com/Downloads" target="_blank">Mono Framework installer</a> includes IronPython 1.1a1. I decided to give it a whirl nonetheless and came up with a pretty simple IronPython Portfile, although there is one thing missing, the IronMath and IronPython DLLs are not properly installed in the GAC. I'm a bit hazy on whether I should be installing the DLLs using <strong>gacutil(1)</strong> or whether I should just copy things over to the <span class="geshifilter"><code class="python geshifilter-python">$<span style="color: black;">&#40;</span>PREFIX<span style="color: black;">&#41;</span>/lib/mono/gac</code></span> and be done with it.. Therefore the crux of my "work" was just creating a <em>sane</em> Makefile, since the IronPython makefile that's distributed on CodePlex uses "csc" and has some pretty nasty syntax. </p> <p>You can check out my Portfile and copy of IronPython 1.1 from anonymous subversion by:</p> <p><strong>Clicking <a href="http://trac.geekisp.com/bleep/browser/trunk/IronPython/Portfile" target="_blank">over here</a></strong><br /> or<br /> <strong>Checking out the code with:<br /> <span class="geshifilter"><code class="python geshifilter-python">svn co svn://svn.<span style="color: black;">geekisp</span>.<span style="color: black;">com</span>/bleep/trunk/IronPython</code></span></strong></p> <p>I'm debating whether or not I should submit the port to MacPorts for inclusion in their next release, mostly because I'm not completely sure if the Mono port includes IronPython or not. If you've got the Mono port installed, feel free to let me know if it installed IronPython, or if you feel like offering up a Makefile.mono patch that properly installs the assemblies into the GAC. I'm a bit new to packaging up open source projects for Mac OS X properly, so any tips would be helpful.</p> http://www.unethicalblogger.com/posts/r_tyler_ballance/ironpython_for_macports#comments Mono Mon, 06 Aug 2007 09:06:12 +0000 R. Tyler Croy 85 at http://www.unethicalblogger.com Hacking with IronPython http://www.unethicalblogger.com/posts/r_tyler_ballance/hacking_with_ironpython <p>I've been wanting to play with <a href="http://www.codeplex.com/IronPython">IronPython</a> for a <strong>very</strong> long time, but never really got around to it since most of my days are either consumed with <a href="http://www.python.org">Python</a> or <a href="http://www.mono-project.com">Mono</a> to some capacity, but never both.</p> <p>Despite my initial instinct to flee in terror after looking over some of the IronPython examples I found on various blogs, I decided it would at the very least be worth an install just to check out the interpreter, and to see how well it performs on top of Mono. <div class="geshifilter"><pre class="geshifilter-python"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">ccnet<span style="color: #66cc66;">%</span> ipy</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">IronPython <span style="color: #ff4500;">1.0</span><span style="color: #ff4500;">.2467</span> on .<span style="color: black;">NET</span> <span style="color: #ff4500;">2.0</span><span style="color: #ff4500;">.50727</span><span style="color: #ff4500;">.42</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">Copyright <span style="color: black;">&#40;</span>c<span style="color: black;">&#41;</span> Microsoft Corporation. <span style="color: black;">All</span> rights reserved.</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #66cc66;">&gt;&gt;&gt;</span> </div></li></ol></pre></div></p> <p><strong>Scary!</strong> But familiar, so I forged ahead undaunted, wanting to start hashing some strings, I figured I'd import the md5 module and get to work.<br /> <div class="geshifilter"><pre class="geshifilter-python"><ol><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">ccnet<span style="color: #66cc66;">%</span> ipy</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">IronPython <span style="color: #ff4500;">1.0</span><span style="color: #ff4500;">.2467</span> on .<span style="color: black;">NET</span> <span style="color: #ff4500;">2.0</span><span style="color: #ff4500;">.50727</span><span style="color: #ff4500;">.42</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">Copyright <span style="color: black;">&#40;</span>c<span style="color: black;">&#41;</span> Microsoft Corporation. <span style="color: black;">All</span> rights reserved.</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">md5</span></div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal">Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> File <span style="color: #dc143c;">md5</span>, line unknown, <span style="color: #ff7700;font-weight:bold;">in</span> Initialize</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> File hashlib, line unknown, <span style="color: #ff7700;font-weight:bold;">in</span> Initialize</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"> File hashlib, line unknown, <span style="color: #ff7700;font-weight:bold;">in</span> __get_builtin_constructor</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #008000;">ImportError</span>: No module named _md5</div></li><li style="font-family: monospace; font-weight: normal;"><div style="font-family: monospace; font-weight: normal; font-style: normal"><span style="color: #66cc66;">&gt;&gt;&gt;</span> </div></li></ol></pre></div></p> <p>Alright, so there are still some holes in the IronPython bridge into Python, but this is fine by me, I can call into .NET code! One other thing that seemed to be missing was the 'select' built-in module, which in turn made my little 'telnetlib' based project fall on it's head. </p> <p>I run an <a href="http://www.icecast.org/">icecast2</a> server on my workstation, so I can just tune in with my MacBook Pro, and get whatever stream is being served up by the server. The source for the icecast2 server is a script using <a href="http://savonet.sourceforge.net/wiki/Liquidsoap">Liquidsoap</a> which allows for shuffling, bumps, and a couple of other things to make my music-listening experience better. One of the nice things about Liquidsoap is that it has a telnet interface, so I can glean meta-data about what's playing, or control the playlist through the telnet interface. With this telnet interface in tow, I set out to hack up a Windows Forms and IronPython-based controller for already scripted radio station. And thus, my little IronRadio Controller was born:<center><a href="http://www.flickr.com/photos/agentdero/953004545/" title="Photo Sharing"><img src="http://farm2.static.flickr.com/1331/953004545_b2e1f6aa41_o.jpg" width="400" alt="IronRadio Controller" /></a></center></p> <p>Unfortunately, I couldn't use Python's native "telnetlib" so I rolled my own IronTelnet class that would permit basic reads and writes to the telnet server, but other than that, the IronRadio Controller is mostly WIndows Forms code and some events cobbled together. The interface is unfortunately poor, as I don't have an <a href="http://developer.apple.com/tools/interfacebuilder.html">Interface Builder</a> for WIndows Forms, let alone IronPython-based Forms (not to mention I could care less about spit-and-polish for anything in X11.app).</p> <p>The source for the script can <a href="http://trac.geekisp.com/bleep/browser/trunk/IronPython/IronRadio.py">be found here</a>, and will require IronPython and Mono to run (or .NET if you're on a Windows machine).</p> <p>I'm still trying to figure out if I can use IronPython with mod_mono to replace fighting with mod_python, but there are no guarantees as to whether that will work or be worth the trouble.</p> http://www.unethicalblogger.com/posts/r_tyler_ballance/hacking_with_ironpython#comments Linux Mono Mon, 30 Jul 2007 13:24:08 +0000 R. Tyler Croy 82 at http://www.unethicalblogger.com IronRu..OOH SHINEY! http://www.unethicalblogger.com/posts/r_tyler_ballance/ironru_ooh_shiney <p>While debating which set of bugs to squash next, I popped open <a href="http://www.opencommunity.co.uk/vienna2.html">Vienna</a> and started catching up on <a href="http://www.go-mono.com/monologue/">monologue</a> and came across Jb Evains' <a href="http://evain.net/blog/articles/2007/07/23/ironruby-first-drops">post regarding IronRuby</a> which <a href="http://www.iunknown.com/2007/07/a-first-look-at.html">John Lam</a> from Microsoft posted as just being "released" (pre-mega-alpha). </p> <p>While I don't use Ruby, or even IronPython on a day to day basis, I have done a lot of work in Cocoa (Objective-C) and to a greater extent, Python. Watching hackers get dynamic languages up and running on top of the CLR is almost like watching Neil Armstrong walk on the moon, you were hoping that it could be done, but up until you actually saw it, you weren't really sure if it could actually be acheived.</p> <p><img src="http://unethicalblogger.com/files/ironruby_interpreter.jpg" width="440"/><br /> Unfortunately, I don't care for Ruby's syntax in comparision to Python's, but that still doesn't mean I can't get excited about dynamic languages on top of the CLR, wahoo!</p> http://www.unethicalblogger.com/posts/r_tyler_ballance/ironru_ooh_shiney#comments Mono Mon, 23 Jul 2007 15:20:42 +0000 R. Tyler Croy 79 at http://www.unethicalblogger.com New Email, etc http://www.unethicalblogger.com/posts/tyler/new_email_etc <p>Digging through my repository of domain names i rent, I finally found one I felt like using for some of my open source hacking; specifically my dealings with <a href="http://mono-project.com">Mono</a>, <a href="http://wiki.openmoko.org">OpenMoko</a> and <a href="http://www.macosforge.org/">Mac OS Forge</a>. I finally setup <a href="http://www.monkeypox.org/">monkeypox.org</a> for both email, general web servitude, and moved most (if not all) of my related mailing list subscriptions over to <a href="mailto:tyler[ZOMGAT]monkeypox[ROFLDOT]org">tyler(at)monkeypox.org</a>.</p> <p>You can find me at that mailing address for all things Mono, and most things non-work related. I'm fine with giving out a few email address @monkeypox.org to some of my Mono compadres, provided they're super-cool and pass a 42km long obstacle course.</p> http://www.unethicalblogger.com/posts/tyler/new_email_etc#comments Mono Sun, 22 Jul 2007 06:52:19 +0000 R. Tyler Croy 78 at http://www.unethicalblogger.com Mono, meet Facebook http://www.unethicalblogger.com/posts/tyler/mono_meet_facebook <p>Recently I've been developing <a href="http://www.facebook.com">Facebook</a> applications on behalf of <a href="http://www.slide.com">Slide</a> (my employer) using our <strong>killer</strong> internal frameworks. While this has resulted in an extremely fast turn around from the whiteboard to release and 8 of the most used applications on Facebook with well over 15 million users, it's all in Python, about 100 miles and a "tabs vs. spaces" flamewar away from what I "used" to do, <a href="http://www.mono-project.com">Mono</a>.</p> <p>Believe it or not, Mono has full ASP.NET 1.1, and a near-complete ASP.NET 2.0 class compatibility (<a href="http://www.mono-project.com/ASP.NET">check it out!</a>). Not only that, there's <strong>two</strong> different ways of hosting a Mono/ASP.NET application, via <a href="http://www.mono-project.com/Xsp#ASP.NET_hosting_with_XSP">xsp2</a> (for development) or with Apache 2 and <a href="http://www.mono-project.com/Xsp#ASP.NET_hosting_with_Apache">mod_mono</a> (for production). The only logical progression for a hacker such as myself, was to write a Mono-based Facebook application, and thus <a href="http://unethicalblogger.com/files/WeatherSharp.png" target="_blank">Weather#</a> was born.<br /> <!--break--><br /> <strong><big>Development</big></strong><br /> Fortunately the pervasiveness of Facebook client libraries is approaching the commonality of Twitter client libraries, mostly because it's a simple REST API, and it's <em>cool</em>. Since somebody already wrote the code, and weaseled it into the <a href="http://www.mono-project.com/AnonSVN">Mono Subversion repository</a> (facebook-sharp) I decided to use it instead of rolling my mini API. The code was a bit old, and obtuse to deal with, so I simply incorporated all of the classes into my project, building everything into my web application. Using one of the many SOAP webservices available on <a href="http://xmethods.net/ve2/ViewListing.po?key=uuid:DC12A48B-1A20-36B1-4AB5-9D7EEF18193E">xmethods.net</a>, I used the wsdl.exe app to generate my SOAP client stubs (which are always subclasses of System.Web.Services.Protocols.SoapHttpClientProtocol), which left me with only about 150 lines of interface and basic glue code to bring these components together such that on page load: <ul> <li>The user location information is fetched from Facebook</li> <li>A SOAP request to the weather web service is made per zip code or city</li> <li>The return data is parsed and fed into the page for display</li> </ul> <p>The entire project was built in <a href="http://www.monodevelop.com/">MonoDevelop</a> which has pre-built ASP.NET templates which include customizable build, run and deploy settings for the MonoDevelop build system. When you click "Run" from inside MonoDevelop IDE, it will rebuld the solution, launch your project inside of xsp2 and then open up a new tab in Firefox to the web application. Building/Testing/Deploying is definitely the easiest part of the road to ASP.NET on Mono.<br /> <center><img src="http://unethicalblogger.com/files/md_building.jpg"/></center><br /> While the <a href="http://www.mono-project.com/ASP.NET_Visual_Designer">ASP.NET Visual Designer</a> is not yet ready for prime time, it's only a minor set back in that you can't drag and drop your web interface together a la Visual Studio .NET, but you have to revert to how most of the web builds their interfaces, with templates and by hand. Given the sheer simplicity of the <a href="http://unethicalblogger.com/files/WeatherSharp.png" target="_blank">Weather# interface</a>, this wasn't a major hurdle to overcome. </p> <p><strong><big>Deployment</big></strong><br /> The only true problem with this near-perfect development setup is the actual public deployment, there are only a <a href="http://www.mono-project.com/FAQ:_ASP.NET#Hosting">few hosts</a> that provide mod_mono hosting as of yet. One of the most beneficial features of Mono however, is the <strong>full</strong> binary compatiblility with .NET, meaning you can develop your entire web application using the free and open source Mono tools, and then deploy your web application to an IIS ASP.NET server (which are very common in the hosting biz). If you have a colocated server, or a virtual private server, it's trivial to setup mod_mono on your Apache 2 web server with most of the mainstream Linux OSes and *bSD's. With ubuntu, in my case, there's only a few packages to install via Synaptic and then move the configuration over in the /etc/apache2/mods-enabled directory and make sure your configuration is correct. That said, if you're the proud owner of a colocated server it should be trivial to configure everything properly.</p> <p><strong><big>Facebook Integration</big></strong><br /> Facebook includes a couple key parameters in their calls into your page to present the user your application, such as the <strong>fb_sig_user</strong> and <strong>fb_sig_session_key</strong>, both of which you can pass into any Facebook client library to start to have your application querying the Facebook Platform. Weather# only makes this call once to <a href="http://developers.facebook.com/documentation.php?v=1.0&amp;method=users.getInfo">users.getInfo</a> to fetch the location information it needs. You can query for a lot more information if necessary, but for the purposes of this example, fetching the location was as basic as was necessary. The most complex part is setting up your Facebook applications settings in "<a href="http://www.facebook.com/developers/apps.php">My Applications</a>", the Weather# information can be found <a href="http://unethicalblogger.com/files/monosample_appsettings.jpg" target="_blank">here</a> (opens in a new window). The most important information is in the screenshot, but if you'll note the callback URL settings. They are set to "iframe" for development purposes (and my desire not to open another port in the firewall to my workstation) and are hitting localhost port 8081, which is the local port I configured my MonoDevelop-deployment xsp2 settings to use. If you switch it over to FBML, you will either have to serve up FBML to the canvas page, or an &lt;fb:iframe/&gt;, but both require Facebook being able to contact your callback URL for proxying purposes.</p> <p><strong><big>&lt;fb:conclusion/&gt;</big></strong><br /> Developing with ASP.NET on Mono is essentially no different than developing with ASP.NET on the stock Microsoft .NET assemblies with the key difference being...no Microsoft .NET assemblies, and no IIS. Meaning, that if you're comfortable with C# or Visual Basic, you can very quickly, and very cheaply develop ASP.NET-based web applications (or web services) and serve them from within your existing <a href="http://en.wikipedia.org/wiki/LAMP_(software_bundle)">LAMP</a> infrastructure. In my opinion, this is one of the best options out right now for current web development, right behind Python; the absolute power of the .NET class libraries is unparalleled, from web controls, to web services, to <a href="http://en.wikipedia.org/wiki/ADO.NET">ADO.NET</a> for data storage, the tools available to the overworked and underpaid developer are worth looking into if you're not already "in the know." mod_mono and xsp2 both run on Mac OS X, Linux, and FreeBSD, and are in the package systems across those platforms (<a href="http://www.macports.org/">MacPorts</a>, <a href="http://en.wikipedia.org/wiki/Advanced_Packaging_Tool">APT</a>, or <a href="http://www.mono-project.com/Mono:FreeBSD">Ports</a>). MonoDevelop works on Linux and FreeBSD, you can get it working on Mac OS X but it's about as painful as a brazilian bikini wax (erm..so I'm told).</p> <p><br/><br /> <strong>Resources</strong> <ul> <li><a href="http://unethicalblogger.com/files/WeatherSharp.png">Weather# screenshot</a></li> <li>Source: <strong>svn co svn://svn.geekisp.com/bleep/trunk/WeatherSharp</strong></li> <li><a href="http://developers.facebook.com/">Facebook Developers Site</a></li> <li><a href="http://www.mono-project.com/Mod_mono">mod_mono</a></li> </ul> http://www.unethicalblogger.com/posts/tyler/mono_meet_facebook#comments Facebook Mono Slide Wed, 04 Jul 2007 17:48:15 +0000 R. Tyler Croy 75 at http://www.unethicalblogger.com Twitterbot Recap http://www.unethicalblogger.com/posts/tyler/twitterbot_recap <p>While trudging through some comment spam, I came across some older comments that I felt needed recapping in <a href="http://unethicalblogger.com/posts/tyler/twitterbot_no_really_i_need_to_be_stopped">this post about my Twitterbot</a>. An anonymous poster had asked about some issues with Mono on Mac OS X returning 401 Unauthorized errors when using HTTP authentication within the <a href="http://trac.geekisp.com/bleep/wiki/Twitterbot">Twitterbot</a>. The issue was fixed relatively quickly after I brought it to the attention of some of the Mono developers, and the fix will be included in <a href="http://mono.ximian.com/monobuild/preview/download-preview/">Mono 1.2.4</a> (preview available). </p> <p>There shouldn't be any more issues with regards to running the Twitterbot on any platform supported by Mono now. In the future I would also like to add better history and duplicate checking by using either a flat-file datasource or one that feeds on a database, but the latter would probably make the program far more complex and difficult to use. Ideas, as usual, are always welcome.</p> http://www.unethicalblogger.com/posts/tyler/twitterbot_recap#comments Mono Tue, 01 May 2007 23:28:56 +0000 R. Tyler Croy 65 at http://www.unethicalblogger.com