<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>true false maybe &#187; Uncategorized</title>
	<atom:link href="http://truefalsemaybe.com/category/uncategorized/feed/" rel="self" type="application/rss+xml" />
	<link>http://truefalsemaybe.com</link>
	<description>tom longson's blog on software, design, and user experience</description>
	<lastBuildDate>Sun, 07 Aug 2011 15:57:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Baby Real World Achievements?</title>
		<link>http://truefalsemaybe.com/2011/08/baby-real-world-achievements/</link>
		<comments>http://truefalsemaybe.com/2011/08/baby-real-world-achievements/#comments</comments>
		<pubDate>Sun, 07 Aug 2011 15:56:48 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://truefalsemaybe.com/?p=219</guid>
		<description><![CDATA[As you might know I&#8217;m a designer and developer, and for the first time in my life i&#8217;m thinking about kids. Partly because I&#8217;m on the cusp of turning 30, and in a stable relationship, but also because right now I&#8217;m babysitting a toddler. He&#8217;s really cool, and extremely curious. In exploring his environment around [...]]]></description>
			<content:encoded><![CDATA[<p>As you might know I&#8217;m a designer and developer, and for the first time in my life i&#8217;m thinking about kids. Partly because I&#8217;m on the cusp of turning 30, and in a stable relationship, but also because right now I&#8217;m babysitting a toddler. He&#8217;s really cool, and extremely curious.</p>
<p>In exploring his environment around the home where he lives, there are places and things he manages to get to that are clearly new for him. I had the idea of turning one of those push lights into something more interesting, like make it light up and make a noise, and put them all over your house, encouraging exploration, but in the *right* places. At least, I would since I grew up being uncoordinated, and I&#8217;d want my kid to be able to literally be able to crawl up the walls.</p>
<p>What do you think?</p>
]]></content:encoded>
			<wfw:commentRss>http://truefalsemaybe.com/2011/08/baby-real-world-achievements/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Running your OS X Locker</title>
		<link>http://truefalsemaybe.com/2011/05/running-your-os-x-locker/</link>
		<comments>http://truefalsemaybe.com/2011/05/running-your-os-x-locker/#comments</comments>
		<pubDate>Mon, 16 May 2011 07:55:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://truefalsemaybe.com/?p=192</guid>
		<description><![CDATA[So installing Locker can be a bit of a bear, so I put together this howto since my laptop got stolen last week, and I had a brand spanking new macbook pro to try out locker from the very start. With this guide, using OSX, you could install Locker for yourself at this very early [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://truefalsemaybe.com/wp-content/uploads/2011/05/locker.png" alt="The Locker Project" title="The Locker Project" width="200" height="200" class="alignleft size-full wp-image-204" style="float: right;"/>So installing <a href="http://gigaom.com/2011/02/04/the-locker-project-why-leave-data-tracking-to-others-do-it-yourself/">Locker</a> can be a bit of a bear, so I put together this howto since my laptop got stolen last week, and I had a brand spanking new macbook pro to try out locker from the very start. With this guide, using OSX, you could install Locker for yourself at this very early stage to try it out. </p>
<p><strong>Start by getting Git<br />
</strong><br />
Git is used to get Locker. It&#8217;s also used to contribute to locker. Git is great. Go get git.</p>
<p>http://code.google.com/p/git-osx-installer/downloads/list?can=3&#038;q=&#038;sort=-uploaded&#038;colspec=Filename+Summary+Uploaded+Size+DownloadCount</p>
<p><strong>Get XCode (Developer Tools)<br />
</strong><br />
Go to the Apple Store, search for &#8220;Xcode&#8221;, download. This is needed for compiling Node.js. It was $5.00. I remember this being free before the App Store&#8230;. >:(</p>
<p><strong>Download Node.js</strong></p>
<p>http://nodejs.org/#download</p>
<p>I grabbed the tgz.</p>
<p><code>curl -o node.tgz http://nodejs.org/dist/node-v0.4.7.tar.gz</code></p>
<p><code>cd node-v0.4.7/</code></p>
<p>So I read README.md. Looks like the usual drill of ./configure; make; make install.</p>
<p><code><br />
./configure<br />
make<br />
</code></p>
<p>Some warnings about directory not found for option &#8216;-Lusr/local/lib&#8217;. Hopefully that won&#8217;t stop me.</p>
<p>Going to try make test to test to see if it works as the node guys expect node to. </p>
<p><code>make test</code></p>
<p>Crap, one of the test failed&#8230; &#8220;simple/test-http-dns-fail&#8221; <strong>my node</strong> doesn&#8217;t ever fail, so this will be irrelevant (j/k).</p>
<p><code><br />
make install<br />
</code></p>
<p><strong>Eep</strong><br />
<code><br />
Cannot create folder<br />
'/usr/local/include/node/' (original error: [Errno 13] Permission denied: '/usr/local/include')<br />
</code></p>
<p>Lets do that with sudo, if it works for sandwiches&#8230;</p>
<p>Yay! &#8216;install&#8217; finished successfully (0.256s)</p>
<p><strong>Ok, NPM now.</strong></p>
<p>This is for node packages. Yummy yummy nodey packages.<br />
<code><br />
curl -o install_npm.sh http://npmjs.org/install.sh<br />
sudo sh install_npm.sh<br />
</code></p>
<p><strong><br />
Okay, now we can install Locker!</strong><br />
<code></p>
<p>git clone https://github.com/LockerProject/Locker.git<br />
cd Locker<br />
</code></p>
<p>Yay, downloaded (cloned) it directly from github.com. Now I have my own personal Locker platform to run with.</p>
<p>We need to set it up though&#8230;<br />
<code><br />
npm install<br />
python setupEnv.py<br />
</code></p>
<p>Okay, nothing fishy there&#8230;</p>
<p><code><br />
node lockerd.js<br />
</code></p>
<p>Hot damn, it&#8217;s up! Now to go to http://localhost:8042 to access it with Chrome.</p>
<p>Here&#8217;s a picture of a kitty to show you how I feel:</p>
<p><img src="http://truefalsemaybe.com/wp-content/uploads/2011/05/kitteh.jpg" alt="kitteh" title="kitteh" width="500" height="334" class="alignnone size-full wp-image-210" /></p>
]]></content:encoded>
			<wfw:commentRss>http://truefalsemaybe.com/2011/05/running-your-os-x-locker/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>iPhone app for finding vineyards</title>
		<link>http://truefalsemaybe.com/2010/12/iphone-app-for-finding-vineyards/</link>
		<comments>http://truefalsemaybe.com/2010/12/iphone-app-for-finding-vineyards/#comments</comments>
		<pubDate>Sat, 25 Dec 2010 04:57:25 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://truefalsemaybe.com/?p=177</guid>
		<description><![CDATA[I&#8217;m really pleased to announce that Andrew, Anna, and my iPhone Wine App, Fine Local Wine is live on the app store. It&#8217;s my first push into real mobile development, and I&#8217;m really proud of what we&#8217;ve accomplished. This app uses Fine Local Wine&#8216;s website as the backend, and reuses much of Gaia iPhone GPS&#8216;s [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://truefalsemaybe.com/wp-content/uploads/2010/12/Screen-shot-2010-12-24-at-8.52.40-PM.png" alt="iphone wine app" title="iphone wine app" width="652" height="494" class="alignnone size-full wp-image-178" /></p>
<p>I&#8217;m really pleased to announce that Andrew, Anna, and my <a href="http://itunes.apple.com/us/app/fine-local-wine/id411402645?mt=8">iPhone Wine App</a>, Fine Local Wine is live on the app store. It&#8217;s my first push into real mobile development, and I&#8217;m really proud of what we&#8217;ve accomplished. This app uses <a href="http://finelocalwine.com/">Fine Local Wine</a>&#8216;s website as the backend, and reuses much of Gaia <a href="http://www.gaiagps.com/">iPhone GPS</a>&#8216;s framework on the mobile frontend. </p>
<p>My aim is to do more development, and rebuild the backend with Pinax to allow more user input into what wineries are in our database, and allow people to rate and review the ones that are.</p>
<p>Would love to hear your feedback. If you leave me a comment I&#8217;ll give you a promo code so you can try the app out yourself for free <img src='http://truefalsemaybe.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://truefalsemaybe.com/2010/12/iphone-app-for-finding-vineyards/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>JavaScript Book Recommendations</title>
		<link>http://truefalsemaybe.com/2010/06/javascript-book-recommendations/</link>
		<comments>http://truefalsemaybe.com/2010/06/javascript-book-recommendations/#comments</comments>
		<pubDate>Tue, 08 Jun 2010 22:00:31 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://truefalsemaybe.com/?p=150</guid>
		<description><![CDATA[I&#8217;ve been expanding my library recently, and I wanted to share a list of some advanced JavaScript books I&#8217;ve picked up: JavaScript: The Good Parts by Papa Crock High Performance Web Sites by Steve Souders Even Faster Web Sites by Steve Souders High Performance JavaScript by Nicholas C. Zakas Professional JavaScript for Web Developers by [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been expanding my library recently, and I wanted to share a list of some advanced JavaScript books I&#8217;ve picked up:</p>
<ul>
<li><a href="http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1276033931&amp;sr=1-1">JavaScript: The Good Parts</a> by Papa Crock</li>
<li><a href="http://www.amazon.com/High-Performance-Web-Sites-Essential/dp/0596529309">High Performance Web Sites</a> by Steve Souders</li>
<li><a href="http://www.amazon.com/Even-Faster-Web-Sites-Performance/dp/0596522304/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1276033969&amp;sr=1-1">Even Faster Web Sites</a> by Steve Souders</li>
<li><a href="http://www.amazon.com/Performance-JavaScript-Faster-Application-Interfaces/dp/059680279X/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1276034070&amp;sr=1-1">High Performance JavaScript</a> by Nicholas C. Zakas</li>
<li><a href="http://www.amazon.com/Professional-JavaScript-Developers-Wrox-Programmer/dp/047022780X/">Professional JavaScript for Web Developers</a> by Nicholas C. Zakas</li>
<li><a href="http://www.amazon.com/Pro-JavaScript-Techniques-John-Resig/dp/1590597273/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1276034136&amp;sr=1-1-spell">Pro Javascript Techniques</a> by John Resig</li>
<li><a href="http://www.manning.com/resig/">Secrets of the JavaScript Ninja</a> by John Resig</li>
</ul>
<p>If you&#8217;re totally new, these probably aren&#8217;t the best books to dive into, but I still recommend picking up JavaScript: The Good Parts. It&#8217;s amazing reading, really gave me a much better understanding of the language, and incredibly dense.</p>
]]></content:encoded>
			<wfw:commentRss>http://truefalsemaybe.com/2010/06/javascript-book-recommendations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DataTable in yer DataTable</title>
		<link>http://truefalsemaybe.com/2010/03/datatable-in-yer-datatable/</link>
		<comments>http://truefalsemaybe.com/2010/03/datatable-in-yer-datatable/#comments</comments>
		<pubDate>Sat, 20 Mar 2010 00:24:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[yahoo]]></category>
		<category><![CDATA[yui]]></category>
		<category><![CDATA[yuiblog]]></category>

		<guid isPermaLink="false">http://truefalsemaybe.com/2010/03/datatable-in-yer-datatable/</guid>
		<description><![CDATA[This is in response to Daniel Barreiro&#8217;s post on putting DataTables in DataTables: http://www.yuiblog.com/blog/2010/03/17/using-nested-datatables-for-row-expansion/ Credit: my coworker Jason R. Smith.]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone size-full wp-image-117" title="yodawg" src="http://truefalsemaybe.com/wp-content/uploads/2010/03/yodawg.jpg" alt="yodawg" width="595" height="576" /></p>
<p>This is in response to Daniel Barreiro&#8217;s post on putting DataTables in DataTables:</p>
<p><a href="http://www.yuiblog.com/blog/2010/03/17/using-nested-datatables-for-row-expansion/">http://www.yuiblog.com/blog/2010/03/17/using-nested-datatables-for-row-expansion/</a></p>
<p>Credit: my coworker Jason R. Smith.</p>
]]></content:encoded>
			<wfw:commentRss>http://truefalsemaybe.com/2010/03/datatable-in-yer-datatable/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What is JSONPX?</title>
		<link>http://truefalsemaybe.com/2009/10/what-is-jsonpx/</link>
		<comments>http://truefalsemaybe.com/2009/10/what-is-jsonpx/#comments</comments>
		<pubDate>Wed, 28 Oct 2009 19:19:34 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[javascript jsonp jsonpx templating xml]]></category>

		<guid isPermaLink="false">http://truefalsemaybe.com/?p=112</guid>
		<description><![CDATA[I saw a message on twitter about something called JSONPX, and did some research to try to find out what it was. According to Wait till I come this is a new way to provide XML with a callback. Essentially this is a format to provide markup Yahoo&#8217;s API with a callback and metadata describing [...]]]></description>
			<content:encoded><![CDATA[<p>I saw a message on twitter about something called JSONPX, and did some research to try to find out what it was. According to <a href="http://www.wait-till-i.com/2009/07/09/another-interesting-yql-feature-xml-with-callback-json-p-x/">Wait till I come</a> this is a new way to provide XML with a callback. Essentially this is a format to provide markup Yahoo&#8217;s API with a callback and metadata describing the query.</p>
<p>Pretty slick, if you ask me. Normally I&#8217;d take the JSONP results and have a JavaScript templating engine like <a href="http://ejohn.org/blog/javascript-micro-templating/">John Resig&#8217;s Micro-Templating</a>. If you use Yahoo&#8217;s <a href="http://developer.yahoo.com/yql/guide/sorting.html">sanitize</a> function, you can even make the HTML safe to insert via innerHTML, even though <a href="http://erik.eae.net/archives/2005/04/08/18.13.31/">innerHTML is evil</a>.</p>
<p>As it gets easier to do HTML layout without markup hacks, I see this approach becoming more common. Get the markup you want, with the metadata you need.</p>
]]></content:encoded>
			<wfw:commentRss>http://truefalsemaybe.com/2009/10/what-is-jsonpx/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Be Cool</title>
		<link>http://truefalsemaybe.com/2009/05/be-cool/</link>
		<comments>http://truefalsemaybe.com/2009/05/be-cool/#comments</comments>
		<pubDate>Mon, 04 May 2009 05:42:18 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://truefalsemaybe.com/2009/05/be-cool/</guid>
		<description><![CDATA[Andrew says to his kids &#8220;What&#8217;s the rule?&#8221;]]></description>
			<content:encoded><![CDATA[<p>Andrew says to his kids &#8220;What&#8217;s the rule?&#8221;</p>
<p><img class="alignnone size-full wp-image-108" title="becool" src="http://truefalsemaybe.com/wp-content/uploads/2009/05/becool.jpg" alt="becool" width="600" height="450" /></p>
]]></content:encoded>
			<wfw:commentRss>http://truefalsemaybe.com/2009/05/be-cool/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tagging with SQLAlchemy</title>
		<link>http://truefalsemaybe.com/2009/04/100/</link>
		<comments>http://truefalsemaybe.com/2009/04/100/#comments</comments>
		<pubDate>Wed, 08 Apr 2009 20:47:03 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://truefalsemaybe.com/?p=100</guid>
		<description><![CDATA[I wanted to use tags with SQLAlchemy, so I looked up previous examples and found Wayne&#8217;s post on how he did it. I adapted his code into a single file example so you can see better how it works. For any given page, there can be any number of tags .appended to it. For any [...]]]></description>
			<content:encoded><![CDATA[<p>I wanted to use tags with SQLAlchemy, so I looked up previous examples and found Wayne&#8217;s post on how he did it. I adapted his code into a single file example so you can see better how it works. For any given page, there can be any number of tags .appended to it. For any given tag, you can .append it to any number of pages.</p>
<p>For example:</p>
<pre lang="python">page = Page(u"Example Page")
page.append(Tag(u"examples"))</pre>
<pre lang="python">from sqlalchemy import *
from sqlalchemy.orm import *
engine = create_engine('sqlite://')
metadata = MetaData(engine)

#engine.echo =True 

page_table = Table("page", metadata,
    Column("id", Integer, Sequence('page_seq_id', optional=True), primary_key=True),
    Column("name", Unicode(100), nullable=False),
)

tag_table = Table("tag", metadata,
    Column("id", Integer, Sequence('taq_seq_id', optional=True), primary_key=True),
    Column("name", Unicode(50), nullable=False, unique=True),
)

pagetag_table = Table("pagetag", metadata,
    Column("id", Integer, Sequence('pagetag_seq_id', optional=True), primary_key=True),
    Column("pageid", Integer, ForeignKey('page.id')),
    Column("tagid", Integer, ForeignKey('tag.id')),
)

class Tag(object):
    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "Tag(\"%s\")" % self.name

class Page(object):
    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return "Page(\"%s\")" % self.name

mapper(Tag, tag_table)
mapper(Page, page_table, properties = {
    'tags':relation(Tag, secondary=pagetag_table, cascade="all"),
    #    'tags':relation(Tag, secondary=pagetag_table, cascade="all,delete-orphans"),
})

metadata.create_all()

sess = create_session()

page = Page(u"Tags with SQLAlchemy Example")
page2 = Page(u"Hot New Video Game Consists Solely Of Shooting People Point-Blank In The Face")
page3 = Page(u"Congressman's War Hero Son Would Have Wanted Highway Bill Passed")

tag = Tag(u"examples")
tag2 = Tag(u"onion")

page.tags.append(tag)
page2.tags.append(tag2)
page3.tags.append(tag2)

sess.add(page)
sess.add(page2)
sess.add(page3)
sess.flush()

tag_q = sess.query(Tag)
tags = tag_q.all()
print "Number of tags:", len(tags)

# filter pages by tag(s)
page_q = sess.query(Page)
pages = page_q.join('tags').filter_by(name=u"tag").all()

print
print "First Page"
print page_q.first()
print page_q.first().tags

print
print "Second Page"
print page_q.all()[1]
print page_q.all()[1].tags

print
print "Third Page"
print page_q.all()[2]
print page_q.all()[2].tags

# delete-orphans does the work for us here...
#sess.delete(pages[0]
#sess.flush()

print
print "All tags"
tags = tag_q.all()
print tags, "Count:", len(tags)

print
print "Tag cloud anyone?"
# see the source code linked below for a properly weighted tag cloud.
tag_q = sess.query(func.count("*").label(u"tagcount"), Tag)
tag_r = tag_q.filter(Tag.id==pagetag_table.c.tagid).group_by(Tag.id).all()
#print tag_q
print tag_r

# what about pages with related tags?
page_q = sess.query(Page)

taglist = [u"tag1", u"tag2"]
tagcount = len(taglist)
page_q.join(Page.tags).filter(Tag.name.in_(taglist)).\
group_by(Page.id).having(func.count(Page.id) == tagcount).all()</pre>
<p>I know tag clouds are passe, but I still think from an information architecture perspective, tags still better than categories.</p>
]]></content:encoded>
			<wfw:commentRss>http://truefalsemaybe.com/2009/04/100/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Giving up Reddit for Lent</title>
		<link>http://truefalsemaybe.com/2009/02/giving-up-reddit-for-lent/</link>
		<comments>http://truefalsemaybe.com/2009/02/giving-up-reddit-for-lent/#comments</comments>
		<pubDate>Tue, 24 Feb 2009 18:05:46 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[productivity]]></category>

		<guid isPermaLink="false">http://truefalsemaybe.com/?p=95</guid>
		<description><![CDATA[I&#8217;m not religious but I like the idea of Lent because it fits into the idea of changing our habits, which is hard to do and potentially has dramatic long standing effects on how we live. I for one love reading Reddit and sometimes Digg, but I find it to be somewhat a sinkhole. Sure [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m not religious but I like the idea of Lent because it fits into the idea of changing our habits, which is hard to do and potentially has dramatic long standing effects on how we live.</p>
<p>I for one love reading <a href="http://reddit.com">Reddit</a> and sometimes <a href="http://digg.com">Digg</a>, but I find it to be somewhat a sinkhole. Sure it&#8217;s funny to read about how someone destroyed their finger with magnets or see a cute picture of a coyote on the BART, but from a learning perspective, I&#8217;d be better off spending my time on <a href="http://news.ycombinator.com/">hacker news</a>.</p>
<p>So to that end, I&#8217;m modifying my host file to give up reddit for lent. Who knows, maybe instead of removing the entry after lent, I&#8217;ll add more instead.</p>
<p>Here&#8217;s how you can do it too:<br />
<a href="http://www.allthingsmarked.com/2006/08/28/howto-block-websites-using-the-hosts-file/">Windows</a> | <a href="http://osxdaily.com/2007/03/19/block-access-to-specified-sites-by-modifying-etchosts/">OSX</a> | <a href="http://tugalinux.wordpress.com/2009/01/15/blocking-websites-using-the-hosts-file/">Linux</a></p>
]]></content:encoded>
			<wfw:commentRss>http://truefalsemaybe.com/2009/02/giving-up-reddit-for-lent/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Profiling SQL in Pylons with Dozer</title>
		<link>http://truefalsemaybe.com/2008/11/profiling-sql-in-pylons-with-dozer/</link>
		<comments>http://truefalsemaybe.com/2008/11/profiling-sql-in-pylons-with-dozer/#comments</comments>
		<pubDate>Fri, 14 Nov 2008 18:32:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Pylons]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://truefalsemaybe.com/?p=68</guid>
		<description><![CDATA[So you want to find out why your Pylons app is running slowly? Well most likely it has to do with your SQL queries, and the best way to see what&#8217;s going on and how long each request is taking is to install Dozer (by benbangert of Pylons), and load it up with a TimerProxy [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://truefalsemaybe.com/wp-content/uploads/2008/11/picture-141.png"><img src="http://truefalsemaybe.com/wp-content/uploads/2008/11/picture-141.png" alt="" title="Pylons with Dozer" width="500" height="309" class="alignnone size-full wp-image-78" /></a></p>
<p>So you want to find out why your Pylons app is running slowly? Well most likely it has to do with your SQL queries, and the best way to see what&#8217;s going on and how long each request is taking is to install Dozer (by benbangert of Pylons), and load it up with a TimerProxy (by zzzeek of SQLAlchemy).</p>
<p>Sound like fun? Well, here&#8217;s how to do it.</p>
<p>Install Dozer:</p>
<pre>sudo easy_install -U http://www.bitbucket.org/bbangert/dozer/get/b748d3e1cc87.gz</pre>
<p>Add this to your middleware:</p>
<pre>
# Add this to your middleware.py, right before return app
    if asbool(config['debug']):
        from dozer import Logview
        app = Logview(app, config)
</pre>
<p>Add this to your development.ini</p>
<pre>
# Add to development.ini
logview.sqlalchemy = #faa
logview.pylons.templating = #bfb
</pre>
<p>(you can customize the colors here)</p>
<p>Next, modify your configuration ini as well as you like to configure what shows up in the log. Note that I have root set to INFO which will squelch a lot of messages. Change this to DEBUG to see more of what&#8217;s going on in each request.</p>
<pre>
# Logging configuration
[loggers]
keys = root, YOURPROJ

[handlers]
keys = console

[formatters]
keys = generic

[logger_root]
level = INFO
handlers = console

[logger_YOURPROJ]
level = DEBUG
handlers =
qualname = YOURPROJ.lib

[logger_sqlalchemy]
level = INFO
handlers =
qualname = sqlalchemy.engine

[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic

[formatter_generic]
format = %(asctime)s,%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S
</pre>
<p>Add this file to /lib/</p>
<p>querytimer.py</p>
<pre lang="python">from sqlalchemy.interfaces import ConnectionProxy
import time

import logging
log = logging.getLogger(__name__)

class TimerProxy(ConnectionProxy):
    def cursor_execute(self, execute, cursor, statement, parameters, context, executemany):
        now = time.time()
        try:
            return execute(cursor, statement, parameters, context)
        finally:
            total = time.time() - now
            log.debug("Query: %s" % statement)
            log.debug("Total Time: %f" % total)
</pre>
<p>Okay, one last thing, modify your SQLAlchemy engine in environment.py to this:</p>
<pre lang="python">engine = engine_from_config(config, 'sqlalchemy.', proxy=TimerProxy())</pre>
<p>and add an import at the top:</p>
<pre lang="python">from YOURPROJ.lib.querytimer import TimerProxy</pre>
<p>So that&#8217;s it! Restart paster, and load up a request in your web browser. There will now be a bar at the top that you can click on and see all the requests.</p>
<p>If you want to run TimerProxy on it&#8217;s own (that is without Pylons and Dozer, see zzzeek&#8217;s post on &#8220;<a href="http://techspot.zzzeek.org/?p=31">Timing All Queries</a>&#8220;.</p>
]]></content:encoded>
			<wfw:commentRss>http://truefalsemaybe.com/2008/11/profiling-sql-in-pylons-with-dozer/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

