<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" gd:etag="W/&quot;CkUGRH89fCp7ImA9WhFSFEo.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329</id><updated>2013-06-17T14:57:05.164+03:00</updated><category term="logging" /><category term="teamcity" /><category term="dialog" /><category term="tools" /><category term="ironpython" /><category term="path" /><category term="encoding" /><category term="web" /><category term="idcc09" /><category term="boo" /><category term="firebug" /><category term="community" /><category term="syntax" /><category term="nunit" /><category term="experts" /><category term="query" /><category term="validation" /><category term="testoob" /><category term="roadmap" /><category term="c#" /><category term="stackoverflow" /><category term="submit" /><category term="wufoo" /><category term="git" /><category term="punditry" /><category term="rdp" /><category term="jquery ui" /><category term="shortcuts" /><category term="keyboard" /><category term=".net" /><category term="performance" /><category term="israel" /><category term="hg" /><category term="c++" /><category term="asp.net mvc" /><category term="google toolbar" /><category term="resharper" /><category term="ff3" /><category term="lame" /><category term="buttons" /><category term="distributed" /><category term="java" /><category term="ipy" /><category term="bzr" /><category term="ajaxpro" /><category term="typing" /><category term="powerresizer" /><category term="webforms" /><category term="themes" /><category term="intrepid" /><category term="ie8" /><category term="freezing" /><category term="trac" /><category term="groovy" /><category term="digg" /><category term="ie6" /><category term="software" /><category term="html" /><category term="tiddlywiki" /><category term="ie7" /><category term="asp.net" /><category term="regular expressions" /><category term="version control" /><category term="ubuntu" /><category term="testing" /><category term="architecture" /><category term="uri" /><category term="svn" /><category term="ruby" /><category term="brail" /><category term="autoconf" /><category term="milestone" /><category term="javascript" /><category term="eac" /><category term="dynamic" /><category term="iframe" /><category term="8.10" /><category term="conference" /><category term="form" /><category term="idcc" /><category term="qunit" /><category term="alt-net-israel" /><category term="python" /><category term="windows" /><category term="monorail" /><category term="astronauts" /><category term="syntaxhighlighter" /><category term="google-code" /><category term="jqmodal" /><category term="ripping" /><category term="ajax" /><category term="programming" /><category term="silliness" /><category term="hydrogenaudio" /><category term="sorting" /><category term="2.3.5" /><category term="music" /><category term="reddit" /><category term="regex" /><category term="jquery" /><category term="timespan" /><category term="blogger" /><category term="activex" /><category term="namespace" /><category term="particletree" /><category term="zsh" /><category term="tablesorter" /><category term="jquery validation" /><category term="hotkeys" /><category term="mercurial" /><category term="ftp" /><category term="nvelocity" /><title>Cheap Turpentine: Ori Peleg's Blog</title><subtitle type="html">"When art critics get together they talk about Form and Structure and Meaning. When artists get together they talk about where you can buy cheap turpentine." - Pablo Picasso</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://orip.org/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://orip.org/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>53</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/orip" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="orip" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;DEUFSHo-eSp7ImA9WhJRGUU.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-4760382937617932826</id><published>2012-07-22T22:43:00.000+03:00</published><updated>2012-07-22T22:43:39.451+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-07-22T22:43:39.451+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>Python: change and restore the working directory</title><content type="html">&lt;p&gt;
Occasionally a command should be run from a specific directory. Here's a Python helper for this:
&lt;ul&gt;
  &lt;li&gt;&lt;code&gt;try/finally&lt;/code&gt; ensures the original working directory is restored.&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://docs.python.org/library/contextlib.html#contextlib.contextmanager"&gt;contextlib.contextmanager&lt;/a&gt; is a neat way to write things supporting the "with" statement ("Context Managers").&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;script src="https://gist.github.com/3160773.js?file=temp_chdir.py"&gt;&lt;/script&gt;
&lt;noscript&gt;
&lt;code&gt;import os, contextlib

@contextlib.contextmanager
def temp_chdir(path):
    """
    Usage:
    &gt;&gt;&gt; with temp_chdir(gitrepo_path):
    ...   subprocess.call('git status')
    """
    starting_directory = os.getcwd()
    try:
        os.chdir(path)
        yield
    finally:
        os.chdir(starting_directory)&lt;/code&gt;
&lt;/noscript&gt;</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/4760382937617932826/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=4760382937617932826" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/4760382937617932826?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/4760382937617932826?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2012/07/python-change-and-restore-working.html" title="Python: change and restore the working directory" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;D0UMSXYzcCp7ImA9Wx5QEkQ.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-6546244547301621196</id><published>2010-09-01T01:51:00.000+03:00</published><updated>2010-09-01T01:54:48.888+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-01T01:54:48.888+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mercurial" /><category scheme="http://www.blogger.com/atom/ns#" term="version control" /><category scheme="http://www.blogger.com/atom/ns#" term="git" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="hg" /><title>Hg vs. Git in the workplace</title><content type="html">&lt;p&gt;This post is based on the &lt;a href="http://groups.google.com/group/altnetisrael/browse_thread/thread/231c10c8321ff02"&gt;following mail&lt;/a&gt; I sent to the ALT.NET Israel list. I'm discussing a Windows development environment.&lt;/p&gt;

&lt;p&gt;
I'm much better at git than hg, and I use git a lot for real work, and it's great (no ifs or buts).&lt;br/&gt;
I also helped originate the move to git at work, because the transition plan was much better. I evaluated hg first and loved it, but the transition plan wouldn't have been half has smooth (a better hg-svn bridge may have been written since then).
&lt;/p&gt;

&lt;p&gt;
Still, here are - in order - the reasons I thing hg would fit better at my workplace (and had we found a good transition plan we'd probably be using hg instead of git):
&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
  Friendlier commands and interface. With git I feel like I need to research how to do straightforward things. Git is extremely powerful and I can do anything with it, and I'm strange so I like the arcane, but git requires more of an investment from people to use it effectively when they have other things to do. Some things are arguably easier to understand in git (rebasing, for example, vs. hg's patch queues - although that's debatable) but the whole package leans heavily to hg IMO. This is the least-loved aspect of git among the teams.
  &lt;/li&gt;

  &lt;li&gt;
  In hg, commits remember the named branch they were committed to (see here). I would LOVE to have this in git, but no cigar - we're still playing with different schemes of approximating this.&lt;br/&gt;
With many people working at times on several branches, and with merging done between branches, then given commit XYZ it's nontrivial in git to figure out which branch it belongs to.&lt;br/&gt;
This is especially true in some scenarios we encountered - e.g. human error caused an older release branch to be fast-forwarded to the head of the latest devel branch - few traces are left in the repository itself of the previous state, and we had fun a few times fixing this (can take hours). Now we have a hook to prevent this.&lt;br/&gt;
If we'd have cherry-picked between different branches instead of merged then this would be easy (and this is equivalent to svn's merging, only better), but we like git's merge and we want to use that.
  &lt;/li&gt;

  &lt;li&gt;
  hg has less quirky Windows support. Points to consider:
    &lt;ul&gt;
      &lt;li&gt;
      msysgit gets sporadic releases and is usually months behind the stable git version, the latest hg versions just work.
        &lt;ul&gt;
          &lt;li&gt;This hit us a few times (bug has been fixed but not available in msysgit).&lt;/li&gt;
          &lt;li&gt;Current example: Git 1.7.2 has improved crlf handling but msysgit isn't there.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;
      Being able to "hg serve" your repository is incredibly cool, but "git daemon" doesn't work with msysgit
        &lt;ul&gt;
          &lt;li&gt;
          Think continuous integration that watches your local repository and runs builds with your current code, giving up-to-date feedback
          &lt;/li&gt;
          &lt;li&gt;
          collaborating with someone without pushing a publicly-visible branch (I've actually wanted to do that a few times)
          &lt;/li&gt;
          &lt;li&gt;
          developing and testing on more than 1 machine simultaneously. There are workarounds, but "git daemon" would have been perfect.
          &lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;
        automating hg, including hooks, run in a Windows environment (vs. git where it runs in mingw's MSYS environment)
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

What doesn't bother me much for the long run is tooling. Right now hg seems to have better tools for our scenarios (even including much better Trac support), but I think git's extreme popularity will cause better and better tools to be written. Some people were very sad to let go of their VisualSvn / Ankh plugins, but they manage with Git Extensions (mostly) and occasionally TortoiseGit. I was surprised at how few people use git from the command-line, I can't live without it.</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/6546244547301621196/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=6546244547301621196" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/6546244547301621196?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/6546244547301621196?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2010/08/hg-vs-git-in-workplace.html" title="Hg vs. Git in the workplace" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;CEcGQHwyeCp7ImA9Wx5TEUk.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-3403240442531450772</id><published>2010-06-28T19:34:00.000+03:00</published><updated>2010-07-26T14:00:21.290+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-26T14:00:21.290+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="jquery" /><category scheme="http://www.blogger.com/atom/ns#" term="jquery validation" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>jQuery Validate: Required If Visible</title><content type="html">&lt;p&gt;I needed a generic "required if visible" rule for use with the &lt;a href="http://bassistance.de/jquery-plugins/jquery-plugin-validation/"&gt;jQuery Validation&lt;/a&gt; plugin. This is the result:&lt;/p&gt;&lt;script src="http://gist.github.com/456034.js?file=jQuery.validate.requiredIfVisible.js"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;code style="display:none"&gt;// jQuery.validate.requiredIfVisible.js&lt;br /&gt;
// Copyright (c) 2010 Ori Peleg, http://orip.org, distributed under the MIT license&lt;br /&gt;
(function($) {&lt;br /&gt;
$.validator.addMethod(&lt;br /&gt;
  &amp;quot;requiredIfVisible&amp;quot;,&lt;br /&gt;
  function(value, element, params) {&lt;br /&gt;
    function isVisible(e) {&lt;br /&gt;
    // the element and all of its parents must be :visible&lt;br /&gt;
    // inspiration: http://remysharp.com/2008/10/17/jquery-really-visible/&lt;br /&gt;
    return e.is(&amp;quot;:visible&amp;quot;) &amp;amp;&amp;amp; e.parents(&amp;quot;:not(:visible)&amp;quot;).length == 0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (isVisible($(element))) {&lt;br /&gt;
    // call the &amp;quot;required&amp;quot; method&lt;br /&gt;
    return $.validator.methods.required.call(this, $.trim(element.value), element);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return true;&lt;br /&gt;
  },&lt;br /&gt;
  $.validator.messages.required&lt;br /&gt;
  );&lt;br /&gt;
})(jQuery);&lt;/code&gt;&lt;br /&gt;
&lt;p&gt;Notes:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Using &lt;code&gt;required:"#myinput:visible"&lt;/code&gt; could have worked, but ":visible" doesn't check for hidden parents, and I didn't want to repeat the element selector.&lt;/li&gt;
&lt;li&gt;":hidden" is false for elements with the "visibility:hidden" CSS rule, so I couldn't use ":not(:hidden)" either.&lt;/li&gt;
&lt;li&gt;Technique for checking element visibility from &lt;a href="http://remysharp.com/2008/10/17/jquery-really-visible/"&gt;Remy Sharp's blog&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/3403240442531450772/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=3403240442531450772" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/3403240442531450772?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/3403240442531450772?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2010/06/jquery-validate-required-if-visible.html" title="jQuery Validate: Required If Visible" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;DEEMRnY8fSp7ImA9WxFREUQ.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-5113325432297135300</id><published>2010-04-25T14:58:00.000+03:00</published><updated>2010-04-25T14:58:07.875+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-25T14:58:07.875+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="webforms" /><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="asp.net mvc" /><title>MVC's RenderPartial in a WebForms page</title><content type="html">&lt;p&gt;We have a mixed ASP.NET MVC/WebForms application, slowly transitioning to all-MVC. Obviously, sharing components between MVC and WebForms is important to us.&lt;/p&gt;&lt;p&gt;Using WebForms controls in MVC views is easy enough (minus the postbacks), but when we &lt;a href="http://stackoverflow.com/questions/702746/how-to-include-a-partial-view-inside-a-webform"&gt;rendered partial views in a WebForms page&lt;/a&gt; using &lt;a href="http://bizvprog.blogspot.com/"&gt;Keith Henry&lt;/a&gt;'s code we occasionally got evil "Validation of viewstate MAC failed" errors. Microsoft &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=393619&amp;wa=wsignin1.0"&gt;doesn't think hybrid WebForms / MVC apps are relevant&lt;/a&gt;, but then &lt;a href="http://bugsquash.blogspot.com/2009/02/aspnet-mvc-postback-support.html"&gt;Mauricio Scheffer came to the rescue&lt;/a&gt;. Instead of having the partial views subclass &lt;code&gt;ViewUserControl&lt;/code&gt;, we now subclass Mauricio's &lt;code&gt;ViewUserControlWithoutViewState&lt;/code&gt; - problem solved.&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/5113325432297135300/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=5113325432297135300" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/5113325432297135300?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/5113325432297135300?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2010/04/mvcs-renderpartial-in-webforms-page.html" title="MVC's RenderPartial in a WebForms page" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;DkcMRXo4fip7ImA9WxFSEEo.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-3863495328979871799</id><published>2010-04-12T15:08:00.000+03:00</published><updated>2010-04-12T15:08:04.436+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-12T15:08:04.436+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="teamcity" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>TeamCity 5.0 upgrade - "out of memory" error</title><content type="html">&lt;p&gt;I upgraded &lt;a href="http://www.jetbrains.com/teamcity/"&gt;JetBrains TeamCity&lt;/a&gt; to version 5.0 on Windows (for &lt;a href="http://www.ronnie-midnight-oil.net/2010/04/i-just-uploaded-patch-to-git-plugin-for.html"&gt;Git&lt;/a&gt; support, yay!). The previous version upgrades went smoothly, but this time I got an exception when loading the server:&lt;/p&gt;&lt;pre&gt;java.sql.SQLException: out of memory&lt;/pre&gt;&lt;p&gt;After some googling, I thought I had to:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Run &lt;code&gt;...\TeamCity\bin\tomcat6w.exe //ES//TeamCity&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;In the "Java" tab change the value for "Maximum memory pool"&lt;/li&gt;
&lt;li&gt;Not set it too high&lt;/li&gt;
&lt;/ul&gt;But no cigar. I realized that I probably had a corrupt HSQLDB database, and I ended up reinstalling and copying the config &lt;em&gt;by hand&lt;/em&gt; (which was a little frustrating). I don't think there's a real reason why an embedded SQL database should be less dependable than one with a server (I know that from SQLite), so I'm guessing it's either TeamCity's or HSQLDB's fault. Even so, an "export configuration" button would be nice, and take the pain out of reinstalling TeamCity.&lt;br /&gt;
&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/3863495328979871799/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=3863495328979871799" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/3863495328979871799?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/3863495328979871799?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2010/04/teamcity-50-upgrade-out-of-memory-error.html" title="TeamCity 5.0 upgrade - &quot;out of memory&quot; error" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;AkAHSXkzeyp7ImA9WxBVEUs.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-8948065847507286227</id><published>2010-02-14T19:22:00.000+02:00</published><updated>2010-02-14T19:32:18.783+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-14T19:32:18.783+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ftp" /><category scheme="http://www.blogger.com/atom/ns#" term=".net" /><category scheme="http://www.blogger.com/atom/ns#" term="uri" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="c#" /><title>Encoding usernames and passwords in FTP URIs</title><content type="html">&lt;p&gt;I want to encode the following into a single URI:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Username: 'jane+foo@example.com'&lt;/li&gt;
&lt;li&gt;password: 'my password' (with a space)&lt;/li&gt;
&lt;li&gt;ftp server: 'ftp.example.org'&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The FTP URI that I expect:&lt;/p&gt;
&lt;pre&gt;ftp://jane%2bfoo%40example.com:my%20password@ftp.example.org&lt;/pre&gt;
&lt;p&gt;In .NET, &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.httputility.urlencode.aspx"&gt;HttpUtility.UrlEncode&lt;/a&gt; almost does what I need - it hex-encodes the special chars, but it also converts spaces to "+" which the FTP server interprets as a literal "+".&lt;/p&gt;
&lt;p&gt;Final code that works with my tests using the FileZilla FTP Server:&lt;/p&gt;
&lt;pre&gt;string EncodeFtpUserInfoComponent(string s)
{
  // assume or assert s != null
  return HttpUtility.UrlEncode(s).Replace("+", "%20");
}&lt;/pre&gt;</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/8948065847507286227/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=8948065847507286227" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/8948065847507286227?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/8948065847507286227?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2010/02/encoding-usernames-and-passwords-in-ftp.html" title="Encoding usernames and passwords in FTP URIs" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;DkQCRX4-eip7ImA9WxBWEU4.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-1749797069485104161</id><published>2010-02-02T20:04:00.001+02:00</published><updated>2010-02-02T20:12:44.052+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-02T20:12:44.052+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="powerresizer" /><category scheme="http://www.blogger.com/atom/ns#" term="keyboard" /><category scheme="http://www.blogger.com/atom/ns#" term="shortcuts" /><category scheme="http://www.blogger.com/atom/ns#" term="hotkeys" /><title>PowerResizer Keyboard Shortcuts</title><content type="html">&lt;p&gt;For some reason the keyboard shortcuts / hotkeys for Federico Bastianello's &lt;a href="https://sourceforge.net/projects/powerresizer/"&gt;PowerResizer&lt;/a&gt; aren't on the web, only in the "Readme.txt" installed with it. So, as a public service, here they are (for version 0.95):&lt;/p&gt;
&lt;pre&gt;2.1 - Window Docking Features and Keyboard Shortcuts

 - Move Window + A: dock a window to the left-half of the screen.
 - Move Window + S: dock a window to the right-half of the screen.
 - Move Window + W: dock a window to the top-half of the screen.
 - Move Window + Z: dock a window to the bottom-half of the screen.
 - Move Window + 1: dock a window to the top-left corner of the screen.
 - Move Window + 2: dock a window to the top-right corner of the screen.
 - Move Window + 3: dock a window to the bottom-left corner of the screen.
 - Move Window + 4: dock a window to the bottom-right corner of the screen.
 
When you resize the inner border of those windows you docked to one of the four
corners of the screen or to one of the four screen halves, PowerResizer 
changes the windows' behavior during resize in a way that all docked windows
will follow the new size of their neighboors.
It is possible to mix docked windows in halves of the screen and in corners.

2.2 - Window Moving/Resizing Features and Keyboard Shortcuts

 - Resize Window + CTRL: resize a window mantaining fixed its center point.
 - Resize Window + SHIFT: move a window using its border.
 - Move Window + 5: center a window into the screen (1/16 screen size margin).
 - Move Window + 6: center a window into the screen (1/10 screen size margin).
 - Move Window + 7: center a window into the screen (1/6 screen size margin).
 - Move Window + 8: center a window into the screen (1/4 screen size margin).
 - Move Window + 9: center a window into the screen (1/3 screen size margin).
 - Move Window + 0: maximize a window.
 
2.3 - Screen window reposition Features and Keyboard Shortcuts

 - CTRL + ALT + PAGE UP: Rotate docked windows counter-clockwise.
 - CTRL + ALT + PAGE DOWN: Rotate docked windows clockwise.
 - CTRL + ALT + HOME: Reposition windows.
 
Note: the keyboard shortcuts in that section, are system-wide shortcuts and 
they will work on windows docked on the monitor containing active window.&lt;/pre&gt;</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/1749797069485104161/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=1749797069485104161" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/1749797069485104161?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/1749797069485104161?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2010/02/powerresizer-keyboard-shortcuts.html" title="PowerResizer Keyboard Shortcuts" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CkAHSHk5eCp7ImA9WxNVGE4.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-1824600785165431830</id><published>2009-10-29T17:31:00.000+02:00</published><updated>2009-10-29T17:38:59.720+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-29T17:38:59.720+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term=".net" /><category scheme="http://www.blogger.com/atom/ns#" term="testoob" /><category scheme="http://www.blogger.com/atom/ns#" term="ipy" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="ironpython" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>Console colors on Windows in .NET</title><content type="html">&lt;p&gt;Changing the console output color is easy on *nix terminals with escape sequences, but has a funky API on Windows (see the &lt;a href="http://bazaar.launchpad.net/~testoob-team/testoob/trunk/annotate/head:/src/testoob/reporting/colored.py#L50"&gt;color support code from Testoob&lt;/a&gt; for a Python example with pywin32/ctypes).&lt;/p&gt;
&lt;p&gt;It turns out that there's a very nice .NET API for it, though (there's a nice &lt;a href="http://dotnetperls.com/console-color"&gt;article by Sam Allen&lt;/a&gt; on the Dot Net Perls site). This would be awesome for &lt;a href="http://code.google.com/p/testoob/"&gt;Testoob&lt;/a&gt;'s IronPython support.&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/1824600785165431830/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=1824600785165431830" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/1824600785165431830?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/1824600785165431830?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2009/10/console-colors-on-windows-in-net.html" title="Console colors on Windows in .NET" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;CUQAQHk9cCp7ImA9WxNVFUg.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-4325288404457261639</id><published>2009-10-26T10:47:00.000+02:00</published><updated>2009-10-26T12:35:41.768+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-26T12:35:41.768+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="web" /><title>Include literal file contents in ASP.NET</title><content type="html">&lt;p&gt;I was looking for something similar to &lt;a href="http://velocity.apache.org/"&gt;Velocity&lt;/a&gt;'s &lt;code&gt;#include&lt;/code&gt; for ASP.NET. &lt;code&gt;&amp;lt;% Response.WriteFile([filename]); %&amp;gt;&lt;/code&gt; works well, but a .NET control for this could be nice. Here is my attempt (MIT license):&lt;/p&gt;
&lt;pre&gt;using System.IO;
using System.Web;
using System.Web.UI;

namespace FooControls
{
  public class LiteralContentFromFile : Control
  {
    public string Path { get; set; }

    protected override void Render(HtmlTextWriter writer)
    {
      var server = HttpContext.Current.Server;
      var physicalPath = server.MapPath(Path);
      var fileContents = File.ReadAllText(physicalPath);
      writer.Write(fileContents);
    }
  }
}&lt;/pre&gt;
&lt;p&gt;Usage in an .aspx file (WebForms or ASP.NET MVC):&lt;/p&gt;
&lt;pre&gt;&amp;lt;%@ Register TagPrefix="foo"
  Namespace="FooControls" Assembly="FooControls" %&amp;gt;
...
&amp;lt;foo:LiteralContentFromFile runat="server"
  Path="~/path/to/file" /&amp;gt;&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;Edit:&lt;/b&gt; subclassing &lt;code&gt;System.Web.UI.Control&lt;/code&gt; instead of &lt;code&gt;System.Web.UI.WebControls.WebControl&lt;/code&gt; which added unnecessary and unwanted behavior (for example, wrapped the output with &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt;).&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/4325288404457261639/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=4325288404457261639" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/4325288404457261639?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/4325288404457261639?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2009/10/include-literal-file-contents-in-aspnet.html" title="Include literal file contents in ASP.NET" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;AkADQHc_eSp7ImA9WxNVEUs.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-6949073634015748495</id><published>2009-10-22T01:43:00.000+02:00</published><updated>2009-10-22T01:46:11.941+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-22T01:46:11.941+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="google-code" /><category scheme="http://www.blogger.com/atom/ns#" term="testoob" /><category scheme="http://www.blogger.com/atom/ns#" term="trac" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>Issues API for Google Code Hosting</title><content type="html">&lt;p&gt;Google have recently released an &lt;a href="http://googlecode.blogspot.com/2009/10/issue-tracker-data-api-for-project.html"&gt;issue-management API&lt;/a&gt; for projects hosted on Google Code.&lt;/p&gt;
&lt;p&gt;That's good news for &lt;a href="http://code.google.com/p/testoob/"&gt;Testoob&lt;/a&gt; - I've been wanting to import its old Trac tickets for ages!&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/6949073634015748495/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=6949073634015748495" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/6949073634015748495?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/6949073634015748495?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2009/10/issues-api-for-google-code-hosting.html" title="Issues API for Google Code Hosting" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CEUESH08eyp7ImA9WxNXGUs.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-9058113581135112902</id><published>2009-10-08T02:30:00.001+02:00</published><updated>2009-10-08T02:36:49.373+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-08T02:36:49.373+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="testoob" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>Testoob 1.15 released</title><content type="html">&lt;p&gt;I'm very happy to announce that after nearly 3 years &lt;a href="http://code.google.com/p/testoob"&gt;Testoob&lt;/a&gt; sees another release.&lt;/p&gt;

&lt;p&gt;Testoob is the advanced Python test runner and testing framework that spices up any existing unittest test suite.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Changes:&lt;/strong&gt; Version 1.15 (Oct. 2009) adds better Python 2.6, IronPython, and Jython support, as well as test coverage improvements, better color 
support, and some new options and bugfixes. A full list of changes is available in the &lt;a href="http://groups.google.com/group/testoob/browse_thread/thread/ff2a026433539fb0"&gt;release announcement&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A big shout out to Ronnie van 't Westeinde - without him this version wouldn't have been possible.&lt;/p&gt;

&lt;p&gt;Options to install:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;With easy_install: "&lt;code&gt;easy_install -U testoob&lt;/code&gt;"&lt;/li&gt;
&lt;li&gt;One of the &lt;a href="http://code.google.com/p/testoob/downloads/list"&gt;available packages&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/9058113581135112902/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=9058113581135112902" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/9058113581135112902?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/9058113581135112902?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2009/10/testoob-115-released.html" title="Testoob 1.15 released" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0UBR3o7fCp7ImA9WxNRFU0.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-579694601001836031</id><published>2009-09-09T15:54:00.000+03:00</published><updated>2009-09-09T16:00:56.404+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-09T16:00:56.404+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="idcc09" /><category scheme="http://www.blogger.com/atom/ns#" term="conference" /><category scheme="http://www.blogger.com/atom/ns#" term="community" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="idcc" /><title>IDCC 2009 Registration Is Open</title><content type="html">&lt;p&gt;The response for the &lt;a href="http://orip.org/2009/07/idcc-2009-call-for-content.html"&gt;call for content&lt;/a&gt; for &lt;a href="http://idcc.co.il/"&gt;IDCC 2009&lt;/a&gt; has been impressive, and now &lt;a href="http://weblogs.asp.net/israelio/archive/2009/09/09/idcc-new-agenda-we-added-another-track.aspx"&gt;two tracks are open&lt;/a&gt; with great talks.&lt;/p&gt;
&lt;p&gt;Hurry up and &lt;a href="http://idcc.co.il/register"&gt;register&lt;/a&gt;!&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/579694601001836031/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=579694601001836031" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/579694601001836031?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/579694601001836031?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2009/09/idcc-2009-registration-is-open.html" title="IDCC 2009 Registration Is Open" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CEcGRXw4fCp7ImA9WxNRE04.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-2580614422333419399</id><published>2009-09-07T16:43:00.000+03:00</published><updated>2009-09-07T17:00:24.234+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-07T17:00:24.234+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><category scheme="http://www.blogger.com/atom/ns#" term="form" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="html" /><title>"Enter" submits my ASP.NET form!</title><content type="html">&lt;p&gt;ASP.NET encourages web pages to be written as one big &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt;, and every interaction with it to be a POST to the server ("Postback" in ASP.NET). This means pages often have multiple auto-generated &lt;code&gt;&amp;lt;input type="submit"&amp;gt;&lt;/code&gt; elements.&lt;/p&gt;
&lt;p&gt;On some browsers, pressing &lt;kbd&gt;Enter&lt;/kbd&gt; causes the first submit button to be "clicked". In pages with many such buttons, that's usually not what you want. As a hack to make "Enter" do nothing on an already-built page, I added the following before any other submit button:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;div style="visibility:hidden;height:0;"&amp;gt;
  &amp;lt;input type="submit" value="Dummy" onclick="return false;" /&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Now this do-nothing, invisible submit button "catches" the Enter and prevents the next button from being "clicked". This requires JavaScript turned on, but ASP.NET's "Postbacks" require them anyway, so no big loss.&lt;/p&gt;
&lt;p&gt;Implementation note: using '&lt;code&gt;display:none;&lt;/code&gt;' caused the browser to ignore it, so I had to resort to '&lt;code&gt;visibility:hidden;&lt;/code&gt;' and then '&lt;code&gt;height:0;&lt;/code&gt;' to impact the layout as little as I could. There could be cross-browser styling issues here, my specific case didn't need anything special.&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/2580614422333419399/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=2580614422333419399" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/2580614422333419399?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/2580614422333419399?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2009/09/enter-submits-my-aspnet-form.html" title="&quot;Enter&quot; submits my ASP.NET form!" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;AkECQHc7cSp7ImA9WxNSEUw.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-3633422731443414049</id><published>2009-08-24T15:54:00.001+03:00</published><updated>2009-08-24T15:57:41.909+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-24T15:57:41.909+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="windows" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="path" /><title>Python: checking if an executable exists in the path</title><content type="html">I wanted to do this on Windows. Based on &lt;a href="http://stackoverflow.com/questions/775351/os-path-exists-for-files-in-your-path/1322060"&gt;this StackOverflow question&lt;/a&gt; and on Trey Stout's and Carl Meyer's responses I made the following snippet:
&lt;pre&gt;
def exists_in_path(cmd):
  # can't search the path if a directory is specified
  assert not os.path.dirname(cmd)

  extensions = os.environ.get("PATHEXT", "").split(os.pathsep)
  for directory in os.environ.get("PATH", "").split(os.pathsep):
    base = os.path.join(directory, cmd)
    options = [base] + [(base + ext) for ext in extensions]
    for filename in options:
      if os.path.exists(filename):
        return True
  return False
&lt;/pre&gt;</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/3633422731443414049/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=3633422731443414049" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/3633422731443414049?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/3633422731443414049?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2009/08/python-checking-if-executable-exists-in.html" title="Python: checking if an executable exists in the path" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>4</thr:total></entry><entry gd:etag="W/&quot;C0cFRnk4cCp7ImA9WxJbE04.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-3238309650456563507</id><published>2009-07-22T21:43:00.000+03:00</published><updated>2009-07-23T09:36:57.738+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-23T09:36:57.738+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="namespace" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>JavaScript Namespaces</title><content type="html">&lt;p&gt;It's important to &lt;a href="http://yuiblog.com./blog/2006/06/01/global-domination/"&gt;namespace your JavaScript code&lt;/a&gt;. I want one "master" namespace, and everything else under it (like &lt;a href="http://developer.yahoo.com/yui/"&gt;YUI&lt;/a&gt;'s namespacing approach). I fell into some potholes of browser compatibility on the way (with &lt;code&gt;var foo; if (!foo) foo = {};&lt;/code&gt;), but here's what I ended up with:&lt;/p&gt;
&lt;pre&gt;
// define master namespace
if (typeof foo === "undefined") var foo = {};

(function(){ // lexical scoping, allows "private" variables and functions

// define sub-namespace
if (!foo.bar) foo.bar = {};

// these don't leak outside
function helper() { /* ... */ } // "private" function
var counter = 0;                // "private" variable

// this function shows up globally under namespace foo.bar
foo.bar.func1 = function(x) { /* ... */ };

// not just functions
foo.bar.constant1 = 12;
foo.bar.shared_data = [];

})(); // end of lexical scoping
&lt;/pre&gt;
&lt;p&gt;This way all the JS files can use the same namespace hierarchy, and can still be defined separately. No JS library necessary.&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/3238309650456563507/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=3238309650456563507" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/3238309650456563507?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/3238309650456563507?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2009/07/javascript-namespaces.html" title="JavaScript Namespaces" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DEYGRXk-cSp7ImA9WxJUFkg.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-7915311900970252994</id><published>2009-07-15T11:31:00.000+03:00</published><updated>2009-07-15T14:08:44.759+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-15T14:08:44.759+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="idcc09" /><category scheme="http://www.blogger.com/atom/ns#" term="israel" /><category scheme="http://www.blogger.com/atom/ns#" term="community" /><category scheme="http://www.blogger.com/atom/ns#" term=".net" /><category scheme="http://www.blogger.com/atom/ns#" term="idcc" /><title>IDCC 2009, call for content</title><content type="html">&lt;p&gt;&lt;a href="http://www.idcc.co.il/"&gt;The Israeli Developers Community Conference 2009&lt;/a&gt; has started its call for content. It's a community conference centered on the .NET world.&lt;/p&gt;

&lt;p&gt;If you have a &lt;a href="http://www.idcc.co.il/sessions/submit"&gt;session to propose&lt;/a&gt;, please do! The community will vote on the proposals, and the conference will conform to the participants - not the other way around.&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/7915311900970252994/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=7915311900970252994" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/7915311900970252994?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/7915311900970252994?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2009/07/idcc-2009-call-for-content.html" title="IDCC 2009, call for content" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0MDQ3c7eSp7ImA9WxJXEkw.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-7774384928332126408</id><published>2009-06-05T17:17:00.001+03:00</published><updated>2009-06-05T17:17:52.901+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-05T17:17:52.901+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="testoob" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>Fresh instances in Python with lazy evaluation</title><content type="html">&lt;p&gt;Testoob's &lt;code&gt;--capture&lt;/code&gt; feature (written by &lt;a href="http://code.google.com/u/misha.seltzer/"&gt;Misha&lt;/a&gt;) replaces &lt;code&gt;sys.stdout&lt;/code&gt; and &lt;code&gt;sys.stderr&lt;/code&gt; for each test being run, and displays the output only if the test fails.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://code.google.com/u/leeor.aharon/"&gt;Leeor Aharon&lt;/a&gt;, of &lt;a href="http://code.google.com/p/ff-activex-host/"&gt;ff-activex-host&lt;/a&gt; fame, wanted to use it with Python's &lt;a href="http://docs.python.org/library/logging.html"&gt;logging module&lt;/a&gt;, but the &lt;code&gt;StreamHandler&lt;/code&gt; class stores a reference to the output stream on initialization - it already has a reference to sys.stdout, so replacing it won't affect it.&lt;/p&gt;
&lt;p&gt;We originally thought of sublcassing &lt;code&gt;StreamHandler&lt;/code&gt; and making retrieve the logger from a property, but we came up with this elegant code instead:&lt;/p&gt;
&lt;pre class="code-py"&gt; 
class LazyEvaluator(object):
    def __init__(self, factory):
        self.__factory = factory
    def __getattr__(self, name):
        return getattr(self.__factory(), name)

lazy_stdout = LazyEvaluator(lambda:sys.stdout)
handler = StreamHandler(strm=lazy_stdout)
&lt;/pre&gt;
&lt;p&gt;The "lazy evaluator" is initialized with a factory callable, and every time it tries to access an attribute or method the object will be re-created by the factory. No changes necessary for &lt;code&gt;StreamHandler&lt;/code&gt;, and &lt;code&gt;./alltests.py --capture&lt;/code&gt; works like a charm.&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/7774384928332126408/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=7774384928332126408" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/7774384928332126408?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/7774384928332126408?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2009/06/fresh-instances-in-python-with-lazy.html" title="Fresh instances in Python with lazy evaluation" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>3</thr:total></entry><entry gd:etag="W/&quot;C04NRXg6fCp7ImA9WxJQFEw.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-4840477894520565671</id><published>2009-05-27T10:47:00.001+03:00</published><updated>2009-05-27T11:13:14.614+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-27T11:13:14.614+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="jquery" /><category scheme="http://www.blogger.com/atom/ns#" term="themes" /><category scheme="http://www.blogger.com/atom/ns#" term="jquery ui" /><category scheme="http://www.blogger.com/atom/ns#" term="dialog" /><title>jQuery UI scoped themes and the Dialog widget</title><content type="html">&lt;p&gt;There's a problem using scoped themes with jQuery UI's Dialog widget in the 1.6 and 1.7 releases (and possibly 1.7.1 as well).&lt;/p&gt;
&lt;p&gt;Christoph Herold &lt;a href="http://groups.google.com/group/jquery-ui-dev/browse_thread/thread/264dce061c54e0ae
"&gt;mentioned his workaround&lt;/a&gt; - wrapping the dialog's DOM with a scoping div (with the scoped theme's class name). I wrote a small jQuery plugin that does this and works fine so far:&lt;/p&gt;
&lt;pre class="code-js"&gt;
// Wraps the dialog in a div with the scoping class on
// dialog open, removes the scoping class on dialog close
$.fn.dialogScopingWorkaround = function(scopingClass) {
  this.bind('dialogopen', function(event, ui) {
    $(this).parents(".ui-dialog").wrap(
      '&amp;lt;div class="dialogScopingWrapper '
      + scopingClass
      + '"&gt;&amp;lt;/div&gt;'
    );
  });
  this.bind('dialogclose', function(event, ui) {
    var wrapper = $(this).parents(".dialogScopingWrapper");
    wrapper.replaceWith(wrapper.children());
  });
  return this;
};&lt;/pre&gt;
&lt;p&gt;Example with the "smoothness" theme scoped with class "theme-smoothness":&lt;/p&gt;
&lt;pre class="code-js"&gt;$('#dialog').dialogScopingWorkaround("theme-smoothness").dialog();

// Must call the workaround before opening the dialog
// so the 'dialogopen' event is bound.&lt;/pre&gt;</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/4840477894520565671/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=4840477894520565671" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/4840477894520565671?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/4840477894520565671?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2009/05/jquery-ui-scoped-themes-and-dialog.html" title="jQuery UI scoped themes and the Dialog widget" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A0MGSX84eyp7ImA9WxJRFUs.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-7093108671803916287</id><published>2009-05-17T17:05:00.000+03:00</published><updated>2009-05-17T17:10:28.133+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-17T17:10:28.133+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ie8" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="ie7" /><title>IE7 compatibility image wants to install IE8</title><content type="html">I use Microsoft's &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=21EABB90-958F-4B64-B5F1-73D0A413C8EF&amp;displaylang=en"&gt;IE Application Compatibility&lt;/a&gt; virtual machine images to test web sites with IE6 and IE7.

Well, today my IE7 virtual machine wanted to &lt;a href="http://blogs.msdn.com/ie/archive/2009/04/10/prepare-for-automatic-update-distribution-of-ie8.aspx"&gt;automatically update to IE8&lt;/a&gt;. Great for the web, funny for an IE7 compatibility test image :)</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/7093108671803916287/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=7093108671803916287" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/7093108671803916287?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/7093108671803916287?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2009/05/ie7-compatibility-image-wants-to.html" title="IE7 compatibility image wants to install IE8" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0EEQXo7fCp7ImA9WxJRE04.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-2280687188851089366</id><published>2009-05-14T22:38:00.001+03:00</published><updated>2009-05-14T23:06:40.404+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-14T23:06:40.404+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="jquery" /><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><category scheme="http://www.blogger.com/atom/ns#" term="ajax" /><category scheme="http://www.blogger.com/atom/ns#" term="ajaxpro" /><title>Ajax.NET Professional "onTimeout" exception</title><content type="html">&lt;p&gt;We just upgraded to &lt;a href="http://codeplex.com/AjaxPro"&gt;Ajax.NET Professional&lt;/a&gt; 9.2.17.1 and started seeing these JavaScript exceptions in file "core.ashx":&lt;/p&gt;
&lt;blockquote&gt;
this.onTimeout is not a function
&lt;/blockquote&gt;
&lt;p&gt;It turns out this is a &lt;a href="http://ajaxpro.codeplex.com/WorkItem/View.aspx?WorkItemId=21433&amp;ProjectName=AjaxPro"&gt;known issue&lt;/a&gt; with synchronous calls done with AjaxPro's client-side JS. We should probably have ditched it and used regular jQuery AJAX calls on the client side (like &lt;a href="http://weblogs.asp.net/mschwarz/archive/2007/04/10/jquery-and-ajax-net-professional-ajaxpro.aspx"&gt;here&lt;/a&gt; and &lt;a href="http://weblogs.asp.net/mschwarz/archive/2007/04/15/download-ajaxpro-beta-with-jquery-support.aspx"&gt;here&lt;/a&gt;) but we haven't gotten around to that yet.&lt;/p&gt;

&lt;p&gt;Our workaround was easy - we were making a "fire and forget" call, so it didn't need to be synchronous (we added an empty callback handler to the arg list). We could have also patched the JS ourselves and:
&lt;ul&gt;
&lt;li&gt;rebuilt AjaxPro with the patched version&lt;/li&gt;
&lt;li&gt;&lt;a href="http://weblogs.asp.net/mschwarz/archive/2005/11/24/431450.aspx"&gt;made AjaxPro load the patched version&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;not used RegisterTypeForAjax and &lt;a href="http://my6solutions.com/post/2009/03/09/Running-AjaxNET-Professional-under-ASP-NET-MVC.aspx"&gt;added the script references ourselves&lt;/a&gt; - pointing to the patched version, and possibly taking the opportunity to combine and minify AjaxPro's JS files.&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/2280687188851089366/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=2280687188851089366" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/2280687188851089366?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/2280687188851089366?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2009/05/ajaxnet-professional-ontimeout.html" title="Ajax.NET Professional &quot;onTimeout&quot; exception" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0AESHkyeip7ImA9WxVUEkg.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-4024052193538554791</id><published>2009-03-17T02:31:00.000+02:00</published><updated>2009-03-17T03:01:49.792+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-17T03:01:49.792+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="blogger" /><category scheme="http://www.blogger.com/atom/ns#" term="reddit" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="digg" /><title>Reddit and Digg icons on Blogger without external scripts</title><content type="html">&lt;p&gt;It took me a while to be able to add reddit and Digg icons that didn't load external scripts - Blogger's templating language had me stumped. I used &lt;a href="http://www.reddit.com/buttons/"&gt;reddit&lt;/a&gt;'s, &lt;a href="http://digg.com/tools/integrate"&gt;Digg&lt;/a&gt;'s, and &lt;a href="http://help.blogger.com/bin/answer.py?answer=47270"&gt;Blogger&lt;/a&gt;'s documentation, but I would never have gotten the "onclick" escaping right without &lt;a href="http://www.consumingexperience.com/2007/01/new-blogger-expr-how-to-convert.html"&gt;this post&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&amp;lt;!-- reddit button --&gt;
&amp;lt;a expr:href='"http://www.reddit.com/submit?url=" + data:post.url' expr:onclick='"window.location = \"http://www.reddit.com/submit?url=\" + encodeURIComponent(\"" + data:post.url + "\"); return false"'&gt; &amp;lt;img src="http://www.reddit.com/static/spreddit1.gif" title="submit to reddit" alt="submit to reddit" border="0" /&gt; &amp;lt;/a&gt;
&amp;lt;!-- digg button --&gt;
&amp;lt;a expr:href='"http://digg.com/submit?url=" + data:post.url' expr:onclick='"window.location = \"http://digg.com/submit?url=\" + encodeURIComponent(\"" + data:post.url + "\"); return false"'&gt; &amp;lt;img style="background:white;" width="16" height="16" alt="Submit Story to Digg" title="Submit Story to Digg" src="http://digg.com/img/digg-guy-icon.gif"/&gt;&amp;lt;/a&gt;&lt;/pre&gt;
&lt;p&gt;P.S. - if you can't find the "data:post.body" element to add the buttons after, like I couldn't, see if you forgot to check the "Expand Widget Templates" checkbox under "Layout -&gt; Edit HTML".&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/4024052193538554791/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=4024052193538554791" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/4024052193538554791?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/4024052193538554791?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2009/03/reddit-and-digg-icons-on-blogger.html" title="Reddit and Digg icons on Blogger without external scripts" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;D08EQ3s9eyp7ImA9WxVUEU0.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-8108445976391569111</id><published>2009-03-13T00:21:00.000+02:00</published><updated>2009-03-15T10:30:02.563+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-15T10:30:02.563+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="jquery" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>Prefetching JavaScript (or anything) with jQuery</title><content type="html">&lt;p&gt;While users are logging into a web site, I thought why not prefetch some JavaScript files they'll be needing on the next page?&lt;/p&gt;

&lt;p&gt;I could load them with Ajax and this will be invisible to users (see the &lt;a href="http://sites.google.com/site/io/even-faster-web-sites"&gt;Even Faster Web Sites&lt;/a&gt; talk by Steven Souders, and his discussion of browser busy indicators).&lt;/p&gt;

&lt;p&gt;The following seems to work, prefetching 2 files in parallel:&lt;/p&gt;
&lt;pre&gt;
(function($) {
 $.ajax({ url:"/js/file1.js", cache:true, dataType:"text" });
 $.ajax({ url:"/js/file2.js", cache:true, dataType:"text" });
})(jQuery);
&lt;/pre&gt;

&lt;p&gt;The 'text' dataType means jQuery won't try to evaluate the JavaScript it fetches. The 'cache' parameter defaults to 'true', but I prefer adding it.&lt;/p&gt;

&lt;p&gt;I tested several browsers with a &lt;a href="http://www.charlesproxy.com/"&gt;proxy&lt;/a&gt;, and the JavaScript files are cached - cool! I presume this technique would work with any resource, not just JS.&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/8108445976391569111/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=8108445976391569111" title="14 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/8108445976391569111?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/8108445976391569111?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2009/03/prefetching-javascript-or-anything-with.html" title="Prefetching JavaScript (or anything) with jQuery" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>14</thr:total></entry><entry gd:etag="W/&quot;D0QGRX4zfSp7ImA9WxNTEko.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-3690829227677156411</id><published>2009-03-08T23:56:00.001+02:00</published><updated>2009-08-14T21:42:04.085+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-14T21:42:04.085+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="bzr" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="svn" /><title>bzr svn: 'unsupported protocol'</title><content type="html">&lt;p&gt;&lt;b&gt;Update (Aug 2009):&lt;/b&gt; this is a workaround for a bug that's been fixed for a while in the stable bzr versions.&lt;/p&gt;
&lt;p&gt;This is something I've banged my head against for a nontrivial while when working with bzr and a subversion repository requiring authentication:&lt;/p&gt;
&lt;pre&gt;
&amp;gt; bzr push http://svnrepos.example.net/trunk
bzr: ERROR: Invalid http response for http://.../.bzr/branch-format: Unable to handle http code 401: Authorization Required
&lt;/pre&gt;
&lt;p&gt;Hard-coding 'http+svn' used to work (and give a warning), but it doesn't in &lt;a href="https://launchpad.net/bzr/+download"&gt;the latest versions&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;
&amp;gt; bzr push http+svn://svnrepos.example.net/trunk
bzr: ERROR: Unsupported protocol for url "http+svn://..."
&lt;/pre&gt;
&lt;p&gt;There's a &lt;a href="https://bugs.launchpad.net/bzr/+bug/256612"&gt;ticket in progress&lt;/a&gt; about this issue, but there's a simple workaround: specify the username in the URL with &lt;b&gt;http://username@host&lt;/b&gt;:&lt;/p&gt;
&lt;pre&gt;
&amp;gt; bzr push http://username@svnrepos.example.net/trunk
&lt;/pre&gt;
&lt;p&gt;Success!&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/3690829227677156411/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=3690829227677156411" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/3690829227677156411?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/3690829227677156411?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2009/03/bzr-svn-unsupported-protocol.html" title="bzr svn: 'unsupported protocol'" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;A0QBRno9eSp7ImA9WxVTFkk.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-755044140144551233</id><published>2008-12-30T17:01:00.000+02:00</published><updated>2008-12-30T17:02:37.461+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-30T17:02:37.461+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="resharper" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>Resharper 4.5 Nightlies Available</title><content type="html">JetBrains started &lt;a href="http://www.jetbrains.net/confluence/display/ReSharper/ReSharper+4.5+Nightly+Builds"&gt;releasing nightlies&lt;/a&gt; on Dec. 26, hooray :)</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/755044140144551233/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=755044140144551233" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/755044140144551233?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/755044140144551233?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2008/12/resharper-45-nightlies-available.html" title="Resharper 4.5 Nightlies Available" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;D0UERHsyeyp7ImA9WxRUGUQ.&quot;"><id>tag:blogger.com,1999:blog-7694153150954292329.post-1873834137859381690</id><published>2008-11-29T23:19:00.000+02:00</published><updated>2008-11-29T23:46:45.593+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-11-29T23:46:45.593+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>Using Python for Serious Development</title><content type="html">&lt;p&gt;Some time ago an &lt;a href="http://ronnie-midnight-oil.net/"&gt;old friend&lt;/a&gt; asked a question on the Python-IL mailing list, wondering what we thought of using Python for serious development. I think &lt;a href="http://www.mail-archive.com/python@linux.org.il/msg00536.html"&gt;my response&lt;/a&gt; back then was pretty interesting, so I'm reproducing it here (edited cosmetically only). Today I would've probably put it differently, but the essence would be the same.&lt;/p&gt;

&lt;pre style="margin: 0em;"&gt;From: Ori Peleg
Mon, 16 Apr 2007 23:17:55 -0700

Yes, you should program in Python! (or a similar agile
language) :-)

My main points:

 - Python is excellent for refactoring (beats C++ and, yes,
   Java too)
 - Don't move an inch with unit and system tests
 - These tests are much easier to write in Python
 - Compiler-checked interfaces aren't that important
 - After a few serious successes, Python is a very serious
   contender in my company.

Now to our application's story:
We ported a large application core to Python (original was in
C++ - we wrote it too).
Our motivation was maintainability - we were sure we could
reduce that hulking core to a smaller and simpler creature.
This really did happen, to the point that the project never
went into maintenance mode - it suddenly became useful for
things we didn't predict :)

We got performance benefits as well (yes, we were surprised).
The reasons were straightforward - we had many more options
when refactoring the code, and separated a lot of logic
neatly (for example extracted DB caching to a decorator -
"AOP" in a language that needs a new term :-)

The gains we ended up getting could have been achieved in
C++, obviously, but they only became apparent after
refactoring with Python.

We also wrote a quick sample client/server application with
Twisted, which was later modified in 2 weeks by someone
different and transformed into an excellent production
application, that's still working flawlessly after 6 months
with no maintenance. All this with about 300 lines of simple,
practically stupid, "I understand this code the first time I
see it" code (actually, this is probably the reason for the
quality).

Now, every time someone says "client/server" people think
about Python and Twisted, and even a large legacy network
client is being replaced with a small Twisted client soon.

How come Python is so amazing for refactoring?
First, you need really good tests. I don't miss the compiler
when I have really good tests.
The good side is that to develop at good quality and speed
you need really good tests in any language, so you're not
losing anything.  These tests are also so much easier to
write in Python - we get more and better tests, and spend
less time writing them. (Whatever language you use for the
system, you should probably test in a language like Python).

Once these tests are in place, refactoring in Python with a
good text editor and some basic tools is so much smoother
than C++ or Java, even with Eclipse's really cool 'Refactor'
menu.
Those actions that are trivial in Eclipse ( e.g. 'Rename
Method') are a little more complicated in Python, but not by
much (remember the good tests).
On the other hand, anything that isn't in Eclipse's context
menu is absolutely horrible to do in Java, to the point that
I've met many good Java developers that don't think anything
else exists at all :) In Python, I've found it to be a snap.
And when you add all the more and less dynamic tools that can
be put to good use, I'm one happy refactorer. Decorators,
bound methods, generator expressions, and the like give me
many ways to make the code simpler that aren't nearly as
accessible in Java (or barely possible in C++).

Why aren't interfaces that important? The reason I like
interfaces is as documentation that the compiler happens to
check. It's convenient, but I don't terribly miss it in the
presence of (a) good documentation, and (b), you guessed it,
good tests :-D
I don't have much experience with zope.interface, so I don't
know how easy it is to use or how much of the benefit from
interfaces you get.
I must say about this point that I'm comparing a full
static-typing approach (e.g. Java) to a full dynamic-typing
approach (e.g. Python) - give me dynamic typing any day. A
hybrid statically- and dynamically-typed language like Groovy
could work better, I don't have the experience to say.

orip.
&lt;/pre&gt;</content><link rel="replies" type="application/atom+xml" href="http://orip.org/feeds/1873834137859381690/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7694153150954292329&amp;postID=1873834137859381690" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/1873834137859381690?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7694153150954292329/posts/default/1873834137859381690?v=2" /><link rel="alternate" type="text/html" href="http://orip.org/2008/11/using-python-for-serious-development.html" title="Using Python for Serious Development" /><author><name>Ori Peleg</name><uri>https://plus.google.com/106709595689600504649</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh3.googleusercontent.com/-rkNKN1ix2XE/AAAAAAAAAAI/AAAAAAAAKs4/HuUm3WyiPv0/s512-c/photo.jpg" /></author><thr:total>0</thr:total></entry></feed>
