<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>jxs.me</title>
  <id>http://jxs.me</id>
  <updated>2010-05-11T00:00:00Z</updated>
  <author>
    <name>Jason Staten</name>
  </author>
  <entry>
    <title>Katas and TDD</title>
    <link href="http://jxs.me/2011/07/09/katas-tdd/" rel="alternate"/>
    <id>http://jxs.me/2011/07/09/katas-tdd/</id>
    <published>2011-07-09T00:00:00Z</published>
    <updated>2011-07-09T00:00:00Z</updated>
    <author>
      <name>Jason Staten</name>
    </author>
    <summary type="html">&lt;p&gt;Not long ago, I picked up Uncle Bob Martin&amp;rsquo;s &lt;a href="http://www.amazon.com/Clean-Coder-Conduct-Professional-Programmers/dp/0137081073"&gt;The Clean Coder&lt;/a&gt; and felt like
I was called out at every angle on places I could improve.  Two areas I&amp;rsquo;ve
severely lacked in are Test Driven Development (TDD) and katas.  I found that
using Ruby&amp;rsquo;s Hoe and Zentest have helped eliminate excuses for me to not
practice.&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;Not long ago, I picked up Uncle Bob Martin&amp;rsquo;s &lt;a href="http://www.amazon.com/Clean-Coder-Conduct-Professional-Programmers/dp/0137081073"&gt;The Clean Coder&lt;/a&gt; and felt like
I was called out at every angle on places I could improve.  Two areas I&amp;rsquo;ve
severely lacked in are Test Driven Development (TDD) and katas.  I found that
using Ruby&amp;rsquo;s Hoe and Zentest have helped eliminate excuses for me to not
practice.&lt;/p&gt;

&lt;h2&gt;Starting Pains&lt;/h2&gt;

&lt;p&gt;One of my biggest deterrents from starting &lt;a href="http://en.wikipedia.org/wiki/Kata_(programming"&gt;katas&lt;/a&gt; is the boilerplate to get
rolling. Being a scripting language, Ruby is helpful for trimming the fat and
only working on the meat. However, there is still the friction of laying out
code properly and setting up testing. It&amp;rsquo;s a minor challenge, but enough to put
off the effort and say, &amp;ldquo;I&amp;rsquo;ll do it later.&amp;rdquo;&lt;/p&gt;

&lt;h2&gt;Breaking Ground&lt;/h2&gt;

&lt;p&gt;Enter &lt;a href="http://seattlerb.rubyforge.org/hoe/"&gt;Hoe&lt;/a&gt;. Hoe is a Ruby gem to help get you rolling quickly. I started
out by calling &lt;code&gt;sow&lt;/code&gt;, which will make a folder in &lt;em&gt;~/.hoe_template/default&lt;/em&gt;, I
copied that folder as as sibling to &lt;em&gt;kata&lt;/em&gt;. I took the time to configure it to
use Minitest instead of Test::Unit.  Now, starting a new kata is as simple as
&lt;code&gt;sow -s kata mynewkata&lt;/code&gt;, and I&amp;rsquo;m good to start working. I now have a predefined
place for source and tests, and also am able to run my tests quickly using
&lt;code&gt;rake test&lt;/code&gt;. I understand that there is some time spent to initially configure
Hoe, but just knowing that won&amp;rsquo;t have to deal with that every time I kata is
makes it worth it.&lt;/p&gt;

&lt;h2&gt;Little Circles&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://rubygems.org/gems/ZenTest"&gt;Zentest&lt;/a&gt; has also been effective in helping me use TDD. It&amp;rsquo;s easy to slip
up and skip running the tests as often as I should. Running &lt;code&gt;autotest&lt;/code&gt;
increases the frequency of of executing tests, by running on every change of
source or test files.  It reduces &amp;ldquo;code, save, run&amp;rdquo;, to simply &amp;ldquo;code, save&amp;rdquo;.
This is great while performing the refactor step of TDD, because you don&amp;rsquo;t have
to switch away from your code unless something breaks.&lt;/p&gt;

&lt;h2&gt;Test Deferred&lt;/h2&gt;

&lt;p&gt;Test Driven Development is not a new topic to me. From the moment I learned of
it, its usefulness has been obvious. Oddly enough, I&amp;rsquo;ve always behaved as if I
was the exception to the rule. I continued writing my code first, and testing
sparsely, &lt;em&gt;even though I knew that TDD was effective&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Assessing myself now, I see that my biggest flaw was only learning theory of TDD
and  not the application of it. I never spent the time to overcome the learning
curve.  At work, I&amp;rsquo;d be starting a new project or feature and wouldn&amp;rsquo;t use TDD
because I thought I didn&amp;rsquo;t have the time to use it. I now recognize two flaws
in this train of thinking.&lt;/p&gt;

&lt;p&gt;First, honing and growing my skills should not be while working on production
code. A baseball pitcher doesn&amp;rsquo;t learn how to throw a curveball during a game.
Rather, he learns it thoroughly during practice time, so that during a game he
can use it effectively. As a parallel, I should be using frequent katas to
broaden and polish my skill set.&lt;/p&gt;

&lt;p&gt;Second, when I think &lt;em&gt;I don&amp;rsquo;t have time&lt;/em&gt;. It&amp;rsquo;s really claiming &lt;em&gt;I dont have
time to learn this technique that would make me a more effective developer&lt;/em&gt;.  I
reflect back to learning Vim. The learning curve is enough to make many shy
away, but the productivity that comes from it is enormous. It took me at least
two months of constant use to be on par with before it. Now, I am frustrated
when I can&amp;rsquo;t use Vim keybindings. Had I excused myself from learning that in
the same way I&amp;rsquo;ve put off TDD, I would be missing one of the most important
tools in my belt.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>What I'm Working On - Fubu New</title>
    <link href="http://jxs.me/2011/06/11/what-im-working-on-fubu-new/" rel="alternate"/>
    <id>http://jxs.me/2011/06/11/what-im-working-on-fubu-new/</id>
    <published>2011-06-11T00:00:00Z</published>
    <updated>2011-06-11T00:00:00Z</updated>
    <author>
      <name>Jason Staten</name>
    </author>
    <summary type="html">&lt;p&gt;A screencast overview of what I&amp;rsquo;m currently working on today&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;A screencast overview of what I&amp;rsquo;m currently working on today.&lt;/p&gt;

&lt;h2&gt;Footage&lt;/h2&gt;

&lt;p&gt;Testing out &lt;a href="http://www.screenr.com/"&gt;screenr&lt;/a&gt; today.&lt;/p&gt;

&lt;div&gt;
&lt;iframe src="http://www.screenr.com/embed/jd8s" width="650" height="396" frameborder="0"&gt;&lt;/iframe&gt;
&lt;/div&gt;


&lt;h2&gt;Fubu New&lt;/h2&gt;

&lt;p&gt;I&amp;rsquo;m currently working on the &lt;code&gt;fubu new&lt;/code&gt; command. It&amp;rsquo;s a command line utility for
generating a working &lt;a href="http://fubumvc.com/"&gt;FubuMVC&lt;/a&gt; project. Yesterday, I spent Open Source
Friday working with &lt;a href="https://twitter.com/smerrell"&gt;Sam Merrell&lt;/a&gt; on determining a strategy for replacing
placeholders in a template project. Sam has done some work with T4, and also
threw around the idea of writing a basic templating engine. However, both seem
a bit overkill for what&amp;rsquo;s actually necessary. &lt;code&gt;String.Replace()&lt;/code&gt; makes the cut.&lt;/p&gt;

&lt;p&gt;At the moment, &lt;code&gt;fubu new&lt;/code&gt; only works against a directory. However, adding a
default template and simplifying distribution of 3rd party templates (zip, git,
etc), is planned.&lt;/p&gt;

&lt;h2&gt;Spark&lt;/h2&gt;

&lt;p&gt;As for the issue with Spark, I&amp;rsquo;ll be diving into that as well.
&lt;code&gt;Spark.Parser.ViewLoader&lt;/code&gt; is spitting out null for one of its values.&lt;/p&gt;

&lt;h2&gt;Fubu on Mono&lt;/h2&gt;

&lt;p&gt;Not covered in the screencast, but also an effort I&amp;rsquo;ve put forth this morning
is attempting to build FubuMVC on mono. It was working at one point and now is
failing on FubuMVC.Deployers&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;FubuBottleDestination.cs(49,75): error CS0584: Internal compiler error: Method not found: 'Bottles.Deployers.Iis.ServerManagerExtensions.CreateSite'.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When that method does, in fact, &lt;a href="https://github.com/DarthFubuMVC/bottles/blob/37d123113c158cc5dc095624e48fa04017741009/src/Bottles.Deployers.Iis/ServerManagerExtensions.cs"&gt;exist&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>C# Websockets with Fleck</title>
    <link href="http://jxs.me/2011/05/28/csharp-websockets-with-fleck/" rel="alternate"/>
    <id>http://jxs.me/2011/05/28/csharp-websockets-with-fleck/</id>
    <published>2011-05-28T00:00:00Z</published>
    <updated>2011-05-28T00:00:00Z</updated>
    <author>
      <name>Jason Staten</name>
    </author>
    <summary type="html">&lt;p&gt;In honor of Fleck, a C# websocket library, becoming Mono compatible, I&amp;rsquo;m
finally giving it some exposure&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;In honor of Fleck, a C# websocket library, becoming Mono compatible, I&amp;rsquo;m
finally giving it some exposure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/statianzo/Fleck"&gt;Fleck&lt;/a&gt; was written in response to a lack of lightweight websockets support in
C#. It was forked from the &lt;a href="http://nugget.codeplex.com/"&gt;Nugget&lt;/a&gt; project, and stripped down to the core.
The result is an API similar to &lt;a href="http://github.com/igrigorik/em-websocket"&gt;em-websockets&lt;/a&gt; that stays out of your way.&lt;/p&gt;

&lt;h2&gt;Look familiar?&lt;/h2&gt;

&lt;div id="alphabet"&gt;&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;If you&amp;rsquo;re in a browser that supports WebSockets&lt;/strong&gt; (Chrome, Safari, Firefox
trunk), go ahead and type a bit. Your keystrokes will be captured, and
broadcasted to any other users on the page. If this page is lonely, you can
open a second browser window to test it out.&lt;/p&gt;

&lt;h2&gt;Fleck in Action&lt;/h2&gt;

&lt;p&gt;Get rolling with Fleck by creating a new &lt;code&gt;WebSocketServer&lt;/code&gt; with the address to
bind.  Call &lt;code&gt;Start()&lt;/code&gt; to start the server and configure callbacks for &lt;code&gt;OnOpen&lt;/code&gt;,
&lt;code&gt;OnClose&lt;/code&gt;, and &lt;code&gt;OnMessage&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var allSockets = new List&amp;lt;IWebSocketConnection&amp;gt; ();
var server = new WebSocketServer ("ws://localhost:8081");
server.Start (socket =&amp;gt;
{
  socket.OnOpen = () =&amp;gt; allSockets.Add (socket);
  socket.OnClose = () =&amp;gt; allSockets.Remove (socket);
  socket.OnMessage = message =&amp;gt;
  {
    foreach (var s in allSockets.ToList())
      s.Send (message);
  };
});
var input = Console.ReadLine ();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the example, connected sockets are added to an array and broadcasted to when
&lt;code&gt;OnMessage&lt;/code&gt; is triggered.&lt;/p&gt;

&lt;h2&gt;Client Side&lt;/h2&gt;

&lt;p&gt;The client side script listens for keypresses and sends them to the websocket.
On receiving a message, which is just a single letter in this case, the
corresponding letter will be lit up.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var socket;
var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

function animateCharacter(letter)
{
  var upper = letter.toUpperCase();
  $('#character_' + upper)
    .stop(true,true)
    .animate({ opacity: 1}, 100)
    .animate({ opacity: .2}, 100);
}

function setup()
{
  var target = $('#alphabet');
  for(var i = 0; i &amp;lt;=alphabet.length; i++)
  {
    var char = alphabet.charAt(i);
    target.append('&amp;lt;span id="character_' + char +'"&amp;gt;' + char + '&amp;lt;/span');
  }
  connect();

  $(document).keypress(function(e){
    var char = String.fromCharCode(e.keyCode);
    socket.send(char);
  });
};

function connect(){
  socket = new WebSocket('ws://localhost:8081');
  socket.onmessage = function(mess) {
    animateCharacter(mess.data);
  };

};

window.onload += setup();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With it all put together, WebSockets makes for a simple way to connect users
together through the browser without plugins, polling, or other ugly frameworks.&lt;/p&gt;

&lt;script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"&gt;&lt;/script&gt; 


&lt;script src="/js/fleck-websocket-example.js"&gt;&lt;/script&gt;

</content>
  </entry>
  <entry>
    <title>Logging to CouchDB from C#</title>
    <link href="http://jxs.me/2011/05/14/logging-to-couchdb-from-c/" rel="alternate"/>
    <id>http://jxs.me/2011/05/14/logging-to-couchdb-from-c/</id>
    <published>2011-05-14T00:00:00Z</published>
    <updated>2011-05-14T00:00:00Z</updated>
    <author>
      <name>Jason Staten</name>
    </author>
    <summary type="html">&lt;p&gt;Setting up a centralized form of logging can be a pain. CouchDB can help make it easy&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;Setting up a centralized form of logging can be a pain. CouchDB can help make it easy.&lt;/p&gt;

&lt;h2&gt;Prerequisites&lt;/h2&gt;

&lt;p&gt;First, grab the &lt;a href="http://logging.apache.org/log4net/index.html"&gt;log4net&lt;/a&gt; library. It&amp;rsquo;s common, proven, and makes logging
straightforward.&lt;/p&gt;

&lt;p&gt;Second, pull down &lt;a href="https://github.com/statianzo/PostLog"&gt;PostLog&lt;/a&gt; from github and build&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git clone https://statianzo@github.com/statianzo/PostLog.git
$ cd PostLog
$ msbuild PostLog.sln
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;PostLog is an HttpAppender for log4net. It will make an HTTP request for logging events.&lt;/p&gt;

&lt;p&gt;Finally, with an instance of &lt;a href="http://couchdb.apache.org/"&gt;CouchDB&lt;/a&gt; running, create a database for logging against.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ curl -X PUT http://localhost:5984/testlog
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Use log4net like normal&lt;/h2&gt;

&lt;p&gt;If your project currently uses, you&amp;rsquo;re in business.
If not, take the following example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;using System;
using log4net.Config;
using log4net;

namespace CouchDBAppenderExample
{
  class MainClass
  {
    public static void Main (string[] args)
    {
      XmlConfigurator.Configure();
      ILog logger = LogManager.GetLogger(typeof(MainClass));
      Console.WriteLine ("Press enter to do it");
      Console.ReadLine();
      try {
        throw new InvalidOperationException("Don't do that!");
      }
      catch(InvalidOperationException e) {
        logger.Error("It blew up", e);
      }
      Console.WriteLine("Done");
      Console.ReadLine();
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A typical log4net usage. An exception occurs and it gets logged.&lt;/p&gt;

&lt;h2&gt;Configure log4net&lt;/h2&gt;

&lt;p&gt;PostLog&amp;rsquo;s &lt;code&gt;HttpAppender&lt;/code&gt; is configured in the &lt;code&gt;log4net&lt;/code&gt; app.config section.
Several options are available.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;uri&lt;/code&gt; The location to send the HTTP Request&lt;/li&gt;
&lt;li&gt;&lt;code&gt;method&lt;/code&gt; The HTTP method to be used (defaults to POST)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;useragent&lt;/code&gt; The value of the useragent header&lt;/li&gt;
&lt;li&gt;&lt;code&gt;format&lt;/code&gt; The format to serialize the log data. Options are &lt;em&gt;form&lt;/em&gt;, &lt;em&gt;json&lt;/em&gt;, and &lt;em&gt;xml&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;xmlrootname&lt;/code&gt; root element tag for xml&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;A sample configuration is as follows:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version="1.0"?&amp;gt;
&amp;lt;configuration&amp;gt;
  &amp;lt;configSections&amp;gt;
    &amp;lt;section name="log4net"
             type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" /&amp;gt;
  &amp;lt;/configSections&amp;gt;

  &amp;lt;log4net&amp;gt;
    &amp;lt;appender name="HttpAppender" type="PostLog.HttpAppender, PostLog"&amp;gt;
      &amp;lt;uri value="http://localhost:5984/testlog" /&amp;gt;
      &amp;lt;formatterType value="PostLog.JsonBodyFormatter, PostLog" /&amp;gt;
      &amp;lt;parameter&amp;gt;
        &amp;lt;name value="date" /&amp;gt;
        &amp;lt;layout type="log4net.Layout.RawTimeStampLayout" /&amp;gt;
      &amp;lt;/parameter&amp;gt;
      &amp;lt;parameter&amp;gt;
        &amp;lt;name value="level" /&amp;gt;
        &amp;lt;layout type="log4net.Layout.PatternLayout"&amp;gt;
          &amp;lt;conversionPattern value="%level" /&amp;gt;
        &amp;lt;/layout&amp;gt;
      &amp;lt;/parameter&amp;gt;
      &amp;lt;parameter&amp;gt;
        &amp;lt;name value="message" /&amp;gt;
        &amp;lt;layout type="log4net.Layout.PatternLayout"&amp;gt;
          &amp;lt;conversionPattern value="%message" /&amp;gt;
        &amp;lt;/layout&amp;gt;
      &amp;lt;/parameter&amp;gt;
      &amp;lt;parameter&amp;gt;
        &amp;lt;name value="exception" /&amp;gt;
        &amp;lt;layout type="log4net.Layout.ExceptionLayout" /&amp;gt;
      &amp;lt;/parameter&amp;gt;
    &amp;lt;/appender&amp;gt;
    &amp;lt;root&amp;gt;
      &amp;lt;level value="DEBUG" /&amp;gt;
      &amp;lt;appender-ref ref="HttpAppender" /&amp;gt;
    &amp;lt;/root&amp;gt;
  &amp;lt;/log4net&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With the new appender in place, your log statements should start hitting CouchDB.&lt;/p&gt;

&lt;h2&gt;Views&lt;/h2&gt;

&lt;p&gt;Now that your log statements are in Couch, you probably want to look at them.&lt;/p&gt;

&lt;p&gt;Let&amp;rsquo;s create a file named logging.json. The file has a view to see all error log statements.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  "_id":"_design/logging",
  "language": "javascript",
  "views":
  {
    "error": {
      "map": "function(doc) { if (doc.level === 'ERROR')  emit(doc.date, doc) }"
    },
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Send it to Couch with curl:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ curl -T - http://localhost:5984/testlog/_design/logging &amp;lt; logging.json
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we can view all error statements by calling&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ curl http://localhost:5984/testlog/_design/logging/_view/error
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Example&lt;/h2&gt;

&lt;p&gt;An example project is available on github at:
https://github.com/statianzo/CouchDBAppenderExample&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Drag and Drop with jQuery</title>
    <link href="http://jxs.me/2010/09/20/drag-and-drop-with-jquery/" rel="alternate"/>
    <id>http://jxs.me/2010/09/20/drag-and-drop-with-jquery/</id>
    <published>2010-09-20T00:00:00Z</published>
    <updated>2010-09-20T00:00:00Z</updated>
    <author>
      <name>Jason Staten</name>
    </author>
    <summary type="html">&lt;p&gt;The past week, I&amp;rsquo;ve been testing out the drag and drop APIs provided by Firefox
and Chrome. It&amp;rsquo;s relatively simple to add a desktop feel to your web apps just
by hooking in&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;The past week, I&amp;rsquo;ve been testing out the drag and drop APIs provided by Firefox
and Chrome. It&amp;rsquo;s relatively simple to add a desktop feel to your web apps just
by hooking in.&lt;/p&gt;

&lt;h2&gt;Handling the Drag&lt;/h2&gt;

&lt;p&gt;Think about what happens you drag and drop a file onto your browser window. Your
browser will take the file and attempt to open it. To perform a custom behavior
for a drag and drop on
a web page, you need to tell the browser, &amp;ldquo;No thanks. I&amp;rsquo;ll take it from here.&amp;rdquo;
To do that in Javascript terms there are two calls to make on the event object:
&lt;code&gt;stopPropegation()&lt;/code&gt; and &lt;code&gt;preventDefault()&lt;/code&gt;. The former will stop the event flow
to other handlers, and the latter stops the browser from performing the default
behavior, opening the file.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function ignoreDrag(e) {
  e.originalEvent.stopPropagation();
  e.originalEvent.preventDefault();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the case that you&amp;rsquo;re using jQuery, calling the attribute &lt;code&gt;originalEvent&lt;/code&gt; is necessary to
access &lt;code&gt;stopPropegation()&lt;/code&gt; and &lt;code&gt;preventDefault()&lt;/code&gt;. You&amp;rsquo;ll want to bind the
&lt;code&gt;ignoreDrag&lt;/code&gt; function the &lt;em&gt;dragenter&lt;/em&gt; and &lt;em&gt;dragover&lt;/em&gt; events of the target.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$('#target')
.bind('dragenter', ignoreDrag)
.bind('dragover', ignoreDrag);
.bind('drop', drop);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can use these events to style your target as well, to give visual
confirmation that a file is able to be dropped on that element.&lt;/p&gt;

&lt;h2&gt;Using the Drop&lt;/h2&gt;

&lt;p&gt;Now that you&amp;rsquo;ve stopped the normal behavior for the drag, you need to do some
behavior when a file is dropped. The event argument of the &lt;em&gt;drop&lt;/em&gt; event has an
attribute called &lt;code&gt;dataTransfer&lt;/code&gt; which contains information about what was
dropped. For accessing data like text or urls, invoke &lt;code&gt;getData()&lt;/code&gt; passing one of
the types given in &lt;code&gt;types&lt;/code&gt;. For file access use the &lt;code&gt;files&lt;/code&gt; attribute to
retreive an array of &lt;em&gt;File&lt;/em&gt; objects.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function drop(e) {
  ignoreDrag(e);
  var dt = e.originalEvent.dataTransfer;
  var files = dt.files;

  if(dt.files.length &amp;gt; 0){
    var file = dt.files[0];
    alert(file.name);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;div id='alerter' style='background:#6666FF;'&gt;Drop File Here&lt;/div&gt;


&lt;p&gt;&lt;em&gt;File&lt;/em&gt; objects contain information about the name and size of the file. Also,
they can be passed to an &lt;em&gt;XmlHttpRequest&lt;/em&gt; and sent as a blob of data. That&amp;rsquo;s
useful for doing an upload of drag and dropped files. &lt;a href="http://webreflection.blogspot.com"&gt;Andrea Giammarchi&lt;/a&gt;
wrote a small library called &lt;a href="http://www.3site.eu/jstests/upload/sendFile.js"&gt;sendfile&lt;/a&gt; for uploading an array of
&lt;em&gt;File&lt;/em&gt; objects. It could be used as follows:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function drop(e) {
  ignoreDrag(e);
  var dt = e.originalEvent.dataTransfer;
  var droppedFiles = dt.files;

  if(dt.files.length &amp;gt; 0){
    sendMultipleFiles({
      files: droppedFiles,
      url: 'http://mywebsite.com/upload',
      onload: function (){ alert('Done'); }
    });
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Client Side File Reading in Firefox&lt;/h2&gt;

&lt;p&gt;Firefox allows you to read from a &lt;em&gt;File&lt;/em&gt; object through three different methods:
&lt;code&gt;getAsBinary()&lt;/code&gt;, &lt;code&gt;getAsDataURL()&lt;/code&gt;, and &lt;code&gt;getAsText(encoding)&lt;/code&gt;. The first will
provide raw binary data. &lt;code&gt;getAsDataURL&lt;/code&gt; will provide a base-64 formatted
string. Finally &lt;code&gt;getAsText&lt;/code&gt; will return a string from the encoding provided.&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;getAsDataURL&lt;/code&gt; will allow you to populate the &lt;em&gt;src&lt;/em&gt; attribute of an &lt;em&gt;img&lt;/em&gt;
tag with a &lt;em&gt;data&lt;/em&gt; string.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function drop(e) {
  ignoreDrag(e);
  var dt = e.originalEvent.dataTransfer;
  var files = dt.files;

  if(dt.files.length &amp;gt; 0){
    $(this).attr('src', files[0].getAsDataURL());
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you&amp;rsquo;re using Firefox (3.6+), drag an image over the image below. The image
will be replaced by the image you drop. No need to send data round trip!&lt;/p&gt;

&lt;p&gt;&lt;img id="droppedPic" style="width:500px; height:300px; border: 1px solid black" src="http://img651.imageshack.us/img651/6028/80099190727442.jpg" /&gt;&lt;/p&gt;

&lt;script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"&gt;&lt;/script&gt;


&lt;script src="/js/dragndrop.js"&gt;&lt;/script&gt;


&lt;script language="javascript" type="text/javascript"&gt;
    function ignoreDrag(e) {
      e.originalEvent.stopPropagation();
      e.originalEvent.preventDefault();
    }
    function drop(e) {
      ignoreDrag(e);
      var dt = e.originalEvent.dataTransfer;
      var files = dt.files;

      if(dt.files.length &gt; 0){
        var file = dt.files[0];
        alert(file.name);
      }
    }

    $('#alerter')
    .bind('dragenter', ignoreDrag)
    .bind('dragover', ignoreDrag)
    .bind('drop', drop);
&lt;/script&gt;

</content>
  </entry>
  <entry>
    <title>GitHub Live via Eventmachine Websockets</title>
    <link href="http://jxs.me/2010/09/07/github-live-via-eventmachine-websockets/" rel="alternate"/>
    <id>http://jxs.me/2010/09/07/github-live-via-eventmachine-websockets/</id>
    <published>2010-09-07T00:00:00Z</published>
    <updated>2010-09-07T00:00:00Z</updated>
    <author>
      <name>Jason Staten</name>
    </author>
    <summary type="html">&lt;p&gt;Keeping track of commits that have been pushed to GitHub can wind up in many
wasteful F5 keystrokes or polling scheme. Using the Post-Receive hook that
GitHub provides can turn the tables having it notify us when a change is made.
Adding on Websockets can create a browser based display for calls to that hook&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;Keeping track of commits that have been pushed to GitHub can wind up in many
wasteful F5 keystrokes or polling scheme. Using the Post-Receive hook that
GitHub provides can turn the tables having it notify us when a change is made.
Adding on Websockets can create a browser based display for calls to that hook.&lt;/p&gt;

&lt;h2&gt;The Hook&lt;/h2&gt;

&lt;p&gt;Setting up the hook is simple after glancing at &lt;a href="http://help.github.com/post-receive-hooks/"&gt;post-receive docs&lt;/a&gt;.
Simply enter the &lt;em&gt;Admin&lt;/em&gt; section of your own personal GitHub repository and set
up the required service hook. Point it at a url of a web server you own.&lt;/p&gt;

&lt;h2&gt;Ruby Side&lt;/h2&gt;

&lt;p&gt;For this, I went with &lt;a href="http://www.sinatrarb.com/"&gt;Sinatra&lt;/a&gt; because it&amp;rsquo;s simple to get rolling. Also, I use
the &lt;a href="http://github.com/igrigorik/em-websocket"&gt;em-websockets&lt;/a&gt; gem for the purpose of simple web sockets. For further
reference on usage see my &lt;a href="http://jxs.me/2010/08/20/websockets-using-ruby-eventmachine/"&gt;previous post&lt;/a&gt; about them.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'bundler'
Bundler.setup
require 'sinatra/base'
require 'yaml'
require 'em-websocket'
require 'open-uri'

GITHUB_URI = 'http://github.com/api/v2/yaml/commits/list/statianzo/emptyrepo/master
SOCKETS = []
EventMachine.run do

  class LivePush &amp;lt; Sinatra::Base
    set :public, File.dirname(__FILE__) + '/public'
    get '/' do
     open(GITHUB_URI) {|s| @commits = YAML::load(s.read)['commits']} unless @commit
     erb :show
    end

    post '/receive' do
      puts "incoming!!"
      if params[:payload]
        @commits = nil
        SOCKETS.each {|s| s.send params[:payload]}
      end
      'Thanks'
    end
  end

  EventMachine::WebSocket.start(:host =&amp;gt; '0.0.0.0', :port =&amp;gt; 8080) do |ws|
    ws.onopen do
      puts "hello!"
      SOCKETS &amp;lt;&amp;lt; ws
    end
    ws.onclose { SOCKETS.delete ws}
  end

  LivePush.run!({:port =&amp;gt; 8081})
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The Sinatra app provides routes for &lt;em&gt;/&lt;/em&gt; and &lt;em&gt;/receive&lt;/em&gt;. The first is for
displaying of the commits and the second takes the content GitHub sends and
broadcasts it to all sockets connected.&lt;/p&gt;

&lt;h2&gt;Javascript Side&lt;/h2&gt;

&lt;p&gt;The javascript is all about parsing the data and slapping it on the page to make
it visible. Using the json parser from [json.org][json] makes this painless.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  function connect(){
    var socket = new WebSocket('ws://yourserver.com:8080');
    socket.onmessage = function(mess) {
      if(mess &amp;amp;&amp;amp; mess.data){
        var table = $('#commits');
        var result = JSON.parse(mess.data);
        for(var i = 0; i &amp;lt; result.commits.length; i++){
          var commit = result.commits[i];
          table.append('&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;'+ commit.id + '&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;'+
              commit.author.name + '&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;' + commit.message + '&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;')
        }
      }
    };
  };
  $(function(){
      connect();
    });
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In this example, the results are appended to a &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt; on the current page.
Very basic, but you can get as fancy as you&amp;rsquo;d like and pull any of the data that
the &lt;a href="http://help.github.com/post-receive-hooks/"&gt;post-receive&lt;/a&gt; hook provides.&lt;/p&gt;

&lt;p&gt;And that&amp;rsquo;s it. Instant feedback about what&amp;rsquo;s getting pushed to your GitHub
repository. I&amp;rsquo;ll have a demo and the source up soon.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>NHibernate in Memory Database Testing with SQLite</title>
    <link href="http://jxs.me/2010/08/30/nhibernate-in-memory-database-testing-with-sqlite/" rel="alternate"/>
    <id>http://jxs.me/2010/08/30/nhibernate-in-memory-database-testing-with-sqlite/</id>
    <published>2010-08-30T00:00:00Z</published>
    <updated>2010-08-30T00:00:00Z</updated>
    <author>
      <name>Jason Staten</name>
    </author>
    <summary type="html">&lt;p&gt;One of the pain points that can come along with most tests that hit a database
is possibility for inconsistent results. &amp;ldquo;Just run it again&amp;rdquo; is not the best
mentality to have about it. For example, when someone is running tests locally
at the same time your continuous integration is running. The CI fails and you&amp;rsquo;re
faced with the task of figuring out what&amp;rsquo;s wrong, when it&amp;rsquo;s really nothing.&lt;/p&gt;

&lt;p&gt;We&amp;rsquo;ve got an ORM to abstract the database from our app. Why not put it to use?&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;One of the pain points that can come along with most tests that hit a database
is possibility for inconsistent results. &amp;ldquo;Just run it again&amp;rdquo; is not the best
mentality to have about it. For example, when someone is running tests locally
at the same time your continuous integration is running. The CI fails and you&amp;rsquo;re
faced with the task of figuring out what&amp;rsquo;s wrong, when it&amp;rsquo;s really nothing.&lt;/p&gt;

&lt;p&gt;We&amp;rsquo;ve got an ORM to abstract the database from our app. Why not put it to use?&lt;/p&gt;

&lt;h2&gt;SQLite&lt;/h2&gt;

&lt;p&gt;Enter SQLite. &lt;a href="http://www.sqlite.org/"&gt;SQLite&lt;/a&gt; is a basic, lightweight SQL database wrapped
into a single library. A benefit of its use is that SQLite can create an
in-memory database that cleans up after all connections are closed. Its
excellent for testing. Starting with a clean slate each test run can provide
for consistent, reproducible results.&lt;/p&gt;

&lt;h2&gt;Prerequisites&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://nhforge.org/"&gt;NHibernate&lt;/a&gt; comes with support for SQLite from the
&lt;em&gt;NHibernate.Driver.SQLite20Driver&lt;/em&gt; class.  However, you must provide two other
files for it to work. First, &lt;a href="http://www.sqlite.org/download.html"&gt;sqlite3.dll&lt;/a&gt;, the SQLite unmanaged
library; include it in your test project and ensure &amp;ldquo;copy to output directory&amp;rdquo;
is marked.  Second, &lt;a href="http://sqlite.phxsoftware.com/"&gt;System.Data.SQLite&lt;/a&gt; a managed library that
allows ADO.NET to interact with SQLite; include this as a reference in your test
project.&lt;/p&gt;

&lt;h2&gt;A Base Class&lt;/h2&gt;

&lt;p&gt;The following is a basic example of how to set up a base class for in memory
database testing. Any tests that require database interaction should inherit
from this class and will have the Session object available. Sessions last as
long as each test fixture. Also, &lt;code&gt;typeof(Plan)&lt;/code&gt; refers to the type of any of
your domain classes.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class InMemoryDatabaseTest
{
  private static Configuration _configuration;
  protected readonly ISession Session;
  private readonly object _baton = new object();

  private readonly ISessionFactory
    _sessionFactory;

  public InMemoryDatabaseTest()
  {
    if (_configuration == null)
      lock (_baton)
        if (_configuration == null)
        {
          _configuration = new Configuration()
            .SetProperty(Environment.ReleaseConnections, "on_close")
            .SetProperty(Environment.ProxyFactoryFactoryClass,
                         "NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle")
            .SetProperty(Environment.CacheProvider,
                         "NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache")
            .SetProperty(Environment.ConnectionDriver, typeof (SQLite20Driver).AssemblyQualifiedName)
            .SetProperty(Environment.ConnectionProvider,
                         "NHibernate.Connection.DriverConnectionProvider")
            .SetProperty(Environment.Isolation, "ReadCommitted")
            .SetProperty(Environment.ConnectionString, "Data Source=:memory:;Version=3;New=True;")
            .SetProperty(Environment.ShowSql, "True")
            .SetProperty(Environment.Dialect, typeof (SQLiteDialect).AssemblyQualifiedName)
            .AddAssembly(Assembly.GetAssembly(typeof(YourDomainObject)));

    _sessionFactory = _configuration.BuildSessionFactory();
    Session = _sessionFactory.OpenSession();
    var schemaExport = new SchemaExport(_configuration);
    schemaExport.Execute(false, true, false, Session.Connection, null);
  }

  public void Dispose()
  {
    Session.Dispose();
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Support for Schemas&lt;/h2&gt;

&lt;p&gt;SQLite doesn&amp;rsquo;t provide native support for schemas. We use SQL Server, and this
led to a problem when any of our mappings pointed to tables in anything other
than the &lt;em&gt;dbo&lt;/em&gt; schema. A simple fix to this is to replace all periods with
underscores prior to creating your session factory. This gives the desired
behavior without requiring any modification to your mapping files.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;if (_configuration == null) {
  _configuration = new Configuration()
  //Configuation...
  foreach (PersistentClass classMapping in _configuration.ClassMappings)
  {
    if (classMapping.Table.Name.Contains("."))
      classMapping.Table.Name = classMapping.Table.Name.Replace(".", "_");
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Working with AutoMockContainer&lt;/h2&gt;

&lt;p&gt;If you&amp;rsquo;re a user of &lt;a href="http://code.google.com/p/moq-contrib/"&gt;Moq-Contrib&amp;rsquo;s AutoMockContainer&lt;/a&gt;, you can
register the Session object into the container to have it provided instead of a
mocked session. It&amp;rsquo;s as simple as adding the following after creating your
session object.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;MockContainer.Register(Session); 
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Testing with NHProf&lt;/h2&gt;

&lt;p&gt;If you use NHibernate Profiler (if you don&amp;rsquo;t, you should be), your SQLite
database interaction can be monitored using that as well. Add an
AssemblyInitialize (or your testing framework&amp;rsquo;s variant) to your
InMemoryDatabaseTest class and all interactions will be profiled.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[AssemblyInitialize]
public static void AssemblyInit(TestContext testContext)
{
  NHibernateProfiler.Initialize(); 
} 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Having trustworthy results is essential in any test driven development.  Using
SQLite for testing can help testing scenarios that have consistent results
each time.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Websockets using Ruby Eventmachine</title>
    <link href="http://jxs.me/2010/08/20/websockets-using-ruby-eventmachine/" rel="alternate"/>
    <id>http://jxs.me/2010/08/20/websockets-using-ruby-eventmachine/</id>
    <published>2010-08-20T00:00:00Z</published>
    <updated>2010-08-20T00:00:00Z</updated>
    <author>
      <name>Jason Staten</name>
    </author>
    <summary type="html">&lt;p&gt;HTML5 is loaded with a lot of features that will make the lives of developers
much easier and the experience for end users more pleasant as well. Lets take a
look one of the new features: WebSockets. We&amp;rsquo;ll make the magic happen with
Ruby&amp;rsquo;s EventMachine gem&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;HTML5 is loaded with a lot of features that will make the lives of developers
much easier and the experience for end users more pleasant as well. Lets take a
look one of the new features: WebSockets. We&amp;rsquo;ll make the magic happen with
Ruby&amp;rsquo;s EventMachine gem.&lt;/p&gt;

&lt;h2&gt;Mash Some Keys!&lt;/h2&gt;

&lt;div id="alphabet"&gt;&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;If you&amp;rsquo;re in a browser that supports WebSockets&lt;/strong&gt; (Chrome, Safari, Firefox
trunk), go ahead and type a bit. Your keystrokes will be captured, and
broadcasted to any other users on the page. If this page is lonely, you can
open a second browser window to test it out.&lt;/p&gt;

&lt;h2&gt;Setting Up EventMachine&lt;/h2&gt;

&lt;p&gt;Using &lt;a href="http://rubyeventmachine.com/"&gt;EventMachine&lt;/a&gt; for WebSockets is simple with the
&lt;a href="http://github.com/igrigorik/em-websocket"&gt;em-websockets&lt;/a&gt; gem. Start an &lt;code&gt;EventMachine.run&lt;/code&gt; block and
&lt;code&gt;EventMachine::WebSocket.start&lt;/code&gt; will do the rest. It provides a socket object
that resembles the javascript WebSocket spec with callbacks for &lt;em&gt;onopen&lt;/em&gt;, &lt;em&gt;onmessage&lt;/em&gt;,
and &lt;em&gt;onclose&lt;/em&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require 'eventmachine'
require 'em-websocket'

@sockets = []
EventMachine.run do
  EventMachine::WebSocket.start(:host =&amp;gt; '0.0.0.0', :port =&amp;gt; 8080) do |socket|
    socket.onopen do
      @sockets &amp;lt;&amp;lt; socket
    end
    socket.onmessage do |mess|
      @sockets.each {|s| s.send mess}
    end
    socket.onclose do
      @sockets.delete socket
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the example, connected sockets are added to an array and broadcasted to when
&lt;em&gt;onmessage&lt;/em&gt; is triggered.&lt;/p&gt;

&lt;h2&gt;Client Side&lt;/h2&gt;

&lt;p&gt;The client side script listens for keypresses and sends them to the websocket.
On receiving a message, which is just a single letter in this case, the
corresponding letter will be lit up.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var socket;
var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

function animateCharacter(letter)
{
  var upper = letter.toUpperCase();
  $('#character_' + upper)
    .stop(true,true)
    .animate({ opacity: 1}, 100)
    .animate({ opacity: .2}, 100);
}

function setup()
{
  var target = $('#alphabet');
  for(var i = 0; i &amp;lt;=alphabet.length; i++)
  {
    var char = alphabet.charAt(i);
    target.append('&amp;lt;span id="character_' + char +'"&amp;gt;' + char + '&amp;lt;/span');
  }
  connect();

  $(document).keypress(function(e){
    var char = String.fromCharCode(e.keyCode);
    socket.send(char);
  });
};

function connect(){
  socket = new WebSocket('ws://h.jxs.me:8080');
  socket.onmessage = function(mess) {
    animateCharacter(mess.data);
  };

};

window.onload += setup();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;With it all put together, WebSockets makes for a simple way to connect users
together through the browser without plugins, polling, or other ugly frameworks.&lt;/p&gt;

&lt;script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"&gt;&lt;/script&gt; 


&lt;script src="/js/websocket-example.js"&gt;&lt;/script&gt;

</content>
  </entry>
  <entry>
    <title>ActionContainer: a Dynamic C# Service Agent</title>
    <link href="http://jxs.me/2010/08/13/actioncontainer-a-dynamic-c-service-agent/" rel="alternate"/>
    <id>http://jxs.me/2010/08/13/actioncontainer-a-dynamic-c-service-agent/</id>
    <published>2010-08-13T00:00:00Z</published>
    <updated>2010-08-13T00:00:00Z</updated>
    <author>
      <name>Jason Staten</name>
    </author>
    <summary type="html">&lt;p&gt;ActionContainer is an implementation of the Service Agent pattern in
written in C#. It takes advantage of the C# 4.0 &lt;em&gt;dynamic&lt;/em&gt; feature to eliminate
cluttering your code with empty message classes and also manipulate calls at
runtime&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;ActionContainer is an implementation of the Service Agent pattern in
written in C#. It takes advantage of the C# 4.0 &lt;em&gt;dynamic&lt;/em&gt; feature to eliminate
cluttering your code with empty message classes and also manipulate calls at
runtime.&lt;/p&gt;

&lt;h2&gt;Usage&lt;/h2&gt;

&lt;p&gt;Usage of ActionContainer is straight forward. Start by creating a class that
implements the empty &lt;code&gt;IActionProvider&lt;/code&gt; interface with public methods.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class SimpleProvider : IActionProvider
{
  public void SayHello(string name)
  {
    Console.WriteLine("Hello, {0}", name);
  }

  public string GeneratePassword()
  {
    return "RaNdOmPaSsWoRd";
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Inject an instance of the ServiceAgent class, and make calls to the registered methods
through the &lt;code&gt;ServiceAgent&lt;/code&gt; object.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class Needy : IDependOnSomething
{
    public dynamic ServiceAgent { get; set; }

    public void DoSomething()
    {
        ServiceAgent.SayHello("Buddy");
        string password = ServiceAgent.GeneratePassword();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Calling &lt;code&gt;SayHello&lt;/code&gt; with a string, will look up a registered method with the name
&lt;em&gt;SayHello&lt;/em&gt;, takes a string argument, and has a void return type. Same behavior
goes for &lt;code&gt;GeneratePassword&lt;/code&gt;, except it returns a string.&lt;/p&gt;

&lt;p&gt;Looking up methods by name and parameters doesn&amp;rsquo;t require creating a
class (think &lt;em&gt;SayHelloRequest&lt;/em&gt;) for each registered action.&lt;/p&gt;

&lt;p&gt;The ServiceAgent is also return type aware. In the call &lt;code&gt;string password =
ServiceAgent.GeneratePassword();&lt;/code&gt;, a search is done for the GeneratePassword
that returns string. In this case, the &lt;code&gt;SimpleProvider&lt;/code&gt; has the only registered
GeneratePassword. Lets say we added another provider, the &lt;code&gt;NumericProvider&lt;/code&gt; as
follows:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class NumericProvider: IActionProvider
{
  public int GeneratePassword()
  {
    return 42;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now calls to &lt;code&gt;ServiceAgent.GeneratePassword();&lt;/code&gt; can handle both int and string
return types with no special &lt;em&gt;PasswordResponse&lt;/em&gt; or &lt;em&gt;NumericPasswordResponse&lt;/em&gt;
wrapper classes.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;string strpwd = ServiceAgent.GeneratePassword(); //returns "RaNdOmPaSsWoRd"
int numpwd = ServiceAgent.GeneratePassword(); //returns 42
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Additional Behavior&lt;/h2&gt;

&lt;p&gt;The default method lookup ability of ActionContainer is just that: the default.
ActionContainer provides a hook into its resolving process simply by creating
implementations of the &lt;code&gt;IActionListener&lt;/code&gt; interface.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public interface IActionListener
{
  bool CanHandle(ActionCallInfo callInfo);
  bool Handle(ActionListenerContext context);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;CanHandle&lt;/code&gt; method returns &lt;em&gt;true&lt;/em&gt; if it has an opinion on the return value
of a call. If &lt;code&gt;CanHandle&lt;/code&gt; is true, &lt;code&gt;Handle&lt;/code&gt; allows the object to manipulate the
return value a value.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ActionCallInfo&lt;/code&gt; includes the method name, named parameters, unnamed
parameters, and expected return type.&lt;/p&gt;

&lt;p&gt;Using this information you could add helpful hooks such as a &lt;code&gt;LogListener&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class LogListener : IActionListener
{
  public bool CanHandle(ActionCallInfo callInfo)
  {
    var arg = callInfo
      .NamedArguments
      .FirstOrDefault(
          x =&amp;gt; x.Item1.Equals("log", StringComparison.OrdinalIgnoreCase)
      );
    if (arg == null || !(arg.Item2 is bool) || !(bool)arg.Item2)
      return false;
    var unnamed = callInfo.UnnamedArguments;
    Console.Write("Calling {0}({1}) - Args: ", callInfo.MethodName, callInfo.ReturnType);
    for (int i = 0; i &amp;lt; unnamed.Count; i++)
    {
      var val = unnamed[i];
      Console.Write("input{0}= {1} ", i, val);
    }
    Console.WriteLine();
    return false;

  }

  public bool Handle(ActionListenerContext context)
  {
    return false;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;LogListener&lt;/code&gt; will watch for an argument named &lt;em&gt;log&lt;/em&gt; with the value of
true. It will then write to the console the name of the call, return type, and
arguments.  To put it to use, just use the ServiceAgent as follows:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ServiceAgent.SayHello("Buddy", log: true);
//Output:
//Calling SayHello() - Args: input0= Buddy
//Hello, Buddy
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Because the ServiceAgent is a dynamic object, any number of named arguments can
be passed to its method calls.&lt;/p&gt;

&lt;p&gt;Another possible hook would be a &lt;code&gt;StringTrimListener&lt;/code&gt;. Any arguments that are strings
can be trimmed before getting passed to the handling method.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public class StringTrimListener : IActionListener
{
  public bool CanHandle(ActionCallInfo callInfo)
  {
    var unnamed = callInfo.UnnamedArguments;
    for (int i =0; i &amp;lt; unnamed.Count; i++)
    {
      var val = unnamed[i] as string;
      if (val != null)
        unnamed[i] = val.Trim();
    }
    return false;
  }

  public bool Handle(ActionListenerContext context)
  {
    return false;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;No change in code is needed to have calls to the ServiceAgent start using the
&lt;code&gt;StringTrimListener&lt;/code&gt;. Just make a call on something with a string with hanging
spaces.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ServiceAgent.SayHello("       Friend     ", log: true);
//Output:
//Hello, Friend
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Things To Keep In Mind&lt;/h2&gt;

&lt;p&gt;ActionContainer has some requirements that you must keep in mind while using it.
Most deal with determining types.&lt;/p&gt;

&lt;p&gt;First, when doing variable assignment you must explicitly provide the type when
returning values. Using &lt;code&gt;var&lt;/code&gt; will result in unfriendly behavior.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var result = ServiceAgent.GeneratePassword(); //BAD!
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Second, passing null values as parameters limits lookup. This has to do with
null not carrying any type information other than &lt;em&gt;object&lt;/em&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;string name = null;
ServiceAgent.SayHello(name); //Less than favorable
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Finally, ActionContainer is slow (~10x) compared to direct method calls. Using
it in a long running loop will have noticeable performance hits. However, in
response to user actions, incoming web request, etc, the difference is negligible.&lt;/p&gt;

&lt;h2&gt;Getting ActionContainer&lt;/h2&gt;

&lt;p&gt;It&amp;rsquo;s on &lt;a href="http://github.com/statianzo/ActionContainer"&gt;Github&lt;/a&gt;. Go and grab it with Git.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git clone git://github.com/statianzo/ActionContainer.git
&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  <entry>
    <title>Yellowbrick: an email blogging example</title>
    <link href="http://jxs.me/2010/08/06/yellowbrick-an-email-blogging-example/" rel="alternate"/>
    <id>http://jxs.me/2010/08/06/yellowbrick-an-email-blogging-example/</id>
    <published>2010-08-06T00:00:00Z</published>
    <updated>2010-08-06T00:00:00Z</updated>
    <author>
      <name>Jason Staten</name>
    </author>
    <summary type="html">&lt;p&gt;Yellowbrick is a small sinatra blog designed to run on Heroku. It combines
several of Heroku&amp;rsquo;s addons such as MongoHQ and Sendgrid. Using the skeleton&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;Yellowbrick is a small sinatra blog designed to run on Heroku. It combines
several of Heroku&amp;rsquo;s addons such as MongoHQ and Sendgrid. Using the skeleton
Git repository, you can be up and rolling with your own blog similar to that of
Tumblr, but configurable down to the last snippet of code.&lt;/p&gt;

&lt;h2&gt;Why?&lt;/h2&gt;

&lt;p&gt;Simple: learning. Yellowbrick is an easy way to help get a grasp of
programatically dealing with incoming emails. Also, there&amp;rsquo;s some definite cool
factor to running your own custom blog over taking the de facto. Finally, it&amp;rsquo;s
extensible; there&amp;rsquo;s no limit as to what you can create when the source is yours.&lt;/p&gt;

&lt;h2&gt;Prerequisites&lt;/h2&gt;

&lt;p&gt;First of all, Yellowbrick requires that you own a domain and have control over
its DNS settings. If you don&amp;rsquo;t have a Heroku account, Git, and Ruby go grab
those now too.&lt;/p&gt;

&lt;p&gt;Also, you need the &lt;em&gt;bundler&lt;/em&gt;, &lt;em&gt;heroku&lt;/em&gt;, and &lt;em&gt;thin&lt;/em&gt; gems installed.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ sudo gem install bundler heroku thin
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Getting Some Source&lt;/h2&gt;

&lt;p&gt;Pull down a copy of the skeleton from Github and enter the directory&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git clone git://github.com/statianzo/yellowbrick.git
$ cd yellowbrick
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Yellowbrick consist of a relatively simple structure. &lt;em&gt;yellowbrick.rb&lt;/em&gt; is the
core of the app, handling incoming requests. &lt;em&gt;boot.rb&lt;/em&gt; loads dependencies and
sets up the database. &lt;em&gt;config.ru&lt;/em&gt; prepares the app to be run on Heroku.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;models&lt;/em&gt; and &lt;em&gt;views&lt;/em&gt; directories contain the models and views for the app,
respectively.&lt;/p&gt;

&lt;h2&gt;Running Locally&lt;/h2&gt;

&lt;p&gt;To start up Yellowbrick locally, you first need to install the Gemfile&amp;rsquo;s gems&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ bundle install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Second, you need to have the environment variable &lt;em&gt;MONGOHQ_URL&lt;/em&gt; pointed to an
instance of MongoDB. For a local instance you could use the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ export MONGOHQ_URL='mongodb://localhost/yellowbrick'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And finally, start the &lt;em&gt;thin&lt;/em&gt; webserver&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ thin start
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you browse to &lt;code&gt;localhost:3000&lt;/code&gt; you should be met with an empty Yellowbrick
blog. To send a sample post, use &lt;em&gt;curl&lt;/em&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ curl -d "subject=MyPost&amp;amp;text=Body+Goes+Here" http://localhost:3000/receive
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Refreshing will show your post&lt;/p&gt;

&lt;h2&gt;Preparing Heroku&lt;/h2&gt;

&lt;p&gt;Running locally and posting via command line is not too exciting. Blogs are all
about web presence. Let&amp;rsquo;s get some.&lt;/p&gt;

&lt;p&gt;Create a new Heroku app using the &lt;em&gt;heroku&lt;/em&gt; command line tool. Set up the
Sendgrid and MongoHQ addons. Push to the heroku remote repository.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ heroku create &amp;lt;app_name_here&amp;gt;
$ heroku addons:add mongohq:free
$ heroku addons:add sendgrid:free
$ git push heroku master
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Your site should now be usable the same as your local instance. Heroku&amp;rsquo;s MongoHQ
addon automatically sets up the &lt;em&gt;MONGOHQ_URL&lt;/em&gt;, and will point to the correct
location.&lt;/p&gt;

&lt;h2&gt;Set Up Sendgrid&lt;/h2&gt;

&lt;p&gt;Yellowbrick is functional now. However, to have the ability to receive and
handle emails, Sendgrid must be configured. Sendgrid provides a feature to parse
an email sent to a doma and POST it to a specified url.&lt;/p&gt;

&lt;p&gt;If your domain&amp;rsquo;s DNS settings are controlled by your domain provider, go to
their site, and add an additional &lt;em&gt;mx record&lt;/em&gt; that points to &lt;em&gt;mx.sendgrid.net&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Retrieve your Sendgrid credentials from Heroku&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ heroku config
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Log into the Sendgrid website, enter the Developers &amp;ndash; Parse Incoming section
where you can set up a hostname to receive emails at
(&lt;em&gt;watch.yourdomain.com&lt;/em&gt;) and the url to hit when an email arrives,
&lt;em&gt;yourapp.heroku.com/receive&lt;/em&gt;. It may take up to a half hour while your mx
record is getting set up.&lt;/p&gt;

&lt;p&gt;Send an email with a subject and body to &lt;em&gt;anything@watch.yourdomain.com&lt;/em&gt;, and in
moments, the contents should be displayed on your heroku site.&lt;/p&gt;

&lt;h2&gt;Extending Yellowbrick&lt;/h2&gt;

&lt;p&gt;As is, Yellowbrick is raw and not secure against anyone else getting their hands
on the email address to post to your blog. An initial enhancement could be to
add additional restrictions and preventing senders who are not your email using
the &lt;code&gt;params[:to]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Read more about what parameters are sent in Sendgrid&amp;rsquo;s API documentation.&lt;/p&gt;
</content>
  </entry>
</feed>

