<?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:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CkcARH0_eyp7ImA9WhRRFEk.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310</id><updated>2011-11-28T01:27:25.343+01:00</updated><category term="mobile" /><category term="firefox" /><category term="trac" /><category term="pyqt" /><category term="git" /><category term="python" /><category term="books" /><category term="buildbot" /><category term="kanban" /><category term="windows" /><category term="qt" /><category term="lavalamp" /><category term="django" /><category term="mercurial" /><category term="c++" /><category term="misc" /><title>Macke's Blog</title><subtitle type="html">Random tidbits related to software development...</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://mackeblog.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>40</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/blogspot/FdDGt" /><feedburner:info uri="blogspot/fddgt" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;CUYFQHs6fSp7ImA9WhdUFko.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-1543362117787473437</id><published>2011-09-30T11:11:00.005+02:00</published><updated>2011-10-03T22:18:31.515+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T22:18:31.515+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="kanban" /><category scheme="http://www.blogger.com/atom/ns#" term="trac" /><title>Trac and Kanban - Redux</title><content type="html">Hello there!&lt;br /&gt;
&lt;br /&gt;
Since my last post before summer, the number of total visits has gone from 2000 to over 7000! One of the reasons for this was the &amp;nbsp;&lt;a href="http://mackeblog.blogspot.com/2011/01/trac-and-kanban.html"&gt;Trac and Kanban&lt;/a&gt;&amp;nbsp;post, where I breifly describe how to use a Trac wiki page as a basic kanban board. (The main reason is&lt;a href="http://stackoverflow.com/q/1791474/72312"&gt; this Stack Overflow question&lt;/a&gt;&amp;nbsp;which asks for a bit more, such as drag-n-drop and the like.)&lt;br /&gt;
&lt;br /&gt;
We'we worked with this for half a year now, and it still feels like a good thing. So good, actually, that I simply had to improve it a bit.&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: large;"&gt;Trac and Kanban, v2.0&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Mainly I now use the "format=table" option to get a table, which means we get color for the priority, we can show who is owning the item and what resolution it had (duplicate/invalid/worksforme/wontfix, etc) where suitable.&lt;br /&gt;
&lt;br /&gt;
It looks like this (with no one working on anything at the moment, but you get the idea):&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-H7gT4_DCWEI/ToWD3eodeMI/AAAAAAAAAGo/DobE0ZwJi94/s1600/orzone_trac_kanban_dashboard.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://2.bp.blogspot.com/-H7gT4_DCWEI/ToWD3eodeMI/AAAAAAAAAGo/DobE0ZwJi94/s640/orzone_trac_kanban_dashboard.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
This could be even better if Trac supported sorting on several ticket fields, but that is not possible with 0.12. There is a &lt;a href="http://trac.edgewall.org/ticket/10178"&gt;ticket and patch&lt;/a&gt;&amp;nbsp;available on the Trac home site, but I haven't tried it ... yet.&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: large;"&gt;Code review&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
For the confused, note that I still use two custom fields for post-commit code review "reviewed_by" and "has_review_issues".&lt;br /&gt;
&lt;br /&gt;
I will probably change the boolean review_issues to a checkbox that better handles the states and workflow for code review:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;not_reviewed&lt;/li&gt;
&lt;li&gt;reviewed_with_issues&lt;/li&gt;
&lt;li&gt;review_issues_fixed&lt;/li&gt;
&lt;li&gt;reviewed_and_approved&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
A custom TicketChangeListener could then manage the has_issues to issues_fixed transition, so that it's automatically visible that the code has changed.&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: large;"&gt;Automatic subpage/dashboard lists&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The second new thing I've discovered and deployed is the &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;TitleIndex &lt;/span&gt;macro, to simply list show all sub pages for a single wiki page. Since we have all the dashboards under Dashboard/ProductNameX.Y pages, it's easy to list them all using&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; [[TitleIndex(Dashboard/ProductName,hideprefix)]] &lt;/span&gt;on a product's "home" wiki page.&lt;br /&gt;
&lt;br /&gt;
Old/completed milestones could then be moved to DashboardOld container so that they're still there, but does not clutter the "current and upcoming milestones/sprints" list.&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: large;"&gt;Wiki code&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The wiki page above was generated from the following code:&lt;br /&gt;
&lt;code style="font-size: small;"&gt;&lt;br /&gt;
This is the ticket dashboard for **[milestone:"Orsync 1.0"]**&lt;br /&gt;
([/query?milestone=Orsync+1.0&amp;amp;status=new&amp;amp;status=reopened&amp;amp;status=testable&amp;amp;status=accepted&amp;amp;order=priority&amp;amp;col=id&amp;amp;col=summary&amp;amp;col=status&amp;amp;col=type&amp;amp;col=priority&amp;amp;col=milestone&amp;amp;col=component open tickets])&lt;br /&gt;
-- [wiki:Orcamp/FeatureList current feature list]&lt;br /&gt;
&lt;br /&gt;
Create new&lt;br /&gt;
[/newticket?milestone=Orsync+1.0&amp;amp;component=Apps/Orsync&amp;amp;type=defect defect],&lt;br /&gt;
[/newticket?milestone=Orsync+1.0&amp;amp;component=Apps/Orsync&amp;amp;type=enhancement enhancement],&lt;br /&gt;
[/newticket?milestone=Orsync+1.0&amp;amp;component=Apps/Orsync&amp;amp;type=suggestion suggestion],&lt;br /&gt;
[/newticket?milestone=Orsync+1.0&amp;amp;component=Apps/Orsync&amp;amp;type=change change],&lt;br /&gt;
[/newticket?milestone=Orsync+1.0&amp;amp;component=Apps/Orsync&amp;amp;type=task task],&lt;br /&gt;
[/newticket?milestone=Orsync+1.0&amp;amp;component=Apps/Orsync&amp;amp;type=demo demo] or&lt;br /&gt;
[/newticket?milestone=Orsync+1.0&amp;amp;component=Apps/Orsync generic] ticket.&lt;br /&gt;
&lt;br /&gt;
{{{&lt;br /&gt;
#!div style="float:left; margin-right:1em; width:30%"&lt;br /&gt;
&lt;br /&gt;
= Open Tickets = &lt;br /&gt;
&lt;br /&gt;
Total: [[TicketQuery(status=new|reopened,type!=suggestion,milestone=Orsync 1.0,format=count)]] &lt;br /&gt;
([[TicketQuery(status=new|reopened,type=suggestion,milestone=Orsync 1.0,format=count)]])&lt;br /&gt;
&lt;br /&gt;
== New &amp;amp; Reopened ==&lt;br /&gt;
&lt;br /&gt;
[[TicketQuery(format=table,col=summary|type,status=reopened|new,type!=suggestion,milestone=Orsync 1.0,group=priority,order=type)]]&lt;br /&gt;
&lt;br /&gt;
== Suggestions == &lt;br /&gt;
&lt;br /&gt;
[[TicketQuery(group=priority,status=new|reopened,type=suggestion,milestone=Orsync 1.0)]]&lt;br /&gt;
&lt;br /&gt;
}}}&lt;br /&gt;
{{{&lt;br /&gt;
#!div style="float:left; margin-right:1em; width:30%" &lt;br /&gt;
&lt;br /&gt;
= Work In Progress =&lt;br /&gt;
&lt;br /&gt;
Total: &lt;br /&gt;
[[TicketQuery(status=accepted,order=priority,group=owner,milestone=Orsync 1.0,format=count)]]&lt;br /&gt;
([[TicketQuery(status=accepted|testable,milestone=Orsync 1.0,format=count)]])&lt;br /&gt;
&lt;br /&gt;
== Started ==&lt;br /&gt;
&lt;br /&gt;
[[TicketQuery(status=accepted,group=owner,order=priority,format=table,col=summary|type|owner,milestone=Orsync 1.0)]]&lt;br /&gt;
&lt;br /&gt;
== Unreviewed tickets == &lt;br /&gt;
&lt;br /&gt;
[[TicketQuery(review_issues!=1,reviewed=,status=testable,group=owner,order=priority,format=table,col=summary|type|owner,milestone=Orsync 1.0)]]&lt;br /&gt;
&lt;br /&gt;
== Reviewed tickets with issues ==&lt;br /&gt;
&lt;br /&gt;
[[TicketQuery(review_issues=1,status=testable,group=owner,order=priority,format=table,col=summary|type|owner,milestone=Orsync 1.0)]]&lt;br /&gt;
&lt;br /&gt;
== Ready for Test ==&lt;br /&gt;
&lt;br /&gt;
[[TicketQuery(review_issues=1,status=testable,group=developertest,order=priority,format=table,col=summary|type,milestone=Orsync 1.0)]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}}}&lt;br /&gt;
{{{&lt;br /&gt;
#!div style="float:left; margin-right:1em; width:30%" &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Closed Tickets = &lt;br /&gt;
&lt;br /&gt;
Total: [[TicketQuery(status=closed,resolution=fixed,milestone=Orsync 1.0,format=count)]] ([[TicketQuery(status=closed,resolution!=fixed,milestone=Orsync 1.0,format=count)]])&lt;br /&gt;
&lt;br /&gt;
== Fixed tickets ==&lt;br /&gt;
&lt;br /&gt;
[[TicketQuery(status=closed,format=table,col=summary|type,resolution=fixed,order=priority,desc=1,milestone=Orsync 1.0)]]&lt;br /&gt;
&lt;br /&gt;
== Denied tickets ==&lt;br /&gt;
&lt;br /&gt;
[[TicketQuery(status=closed,resolution=wontfix|worksforme,format=table,col=summary|type|resolution,order=priority,desc=1,milestone=Orsync 1.0)]]&lt;br /&gt;
&lt;br /&gt;
== Invalid/duplicate/other ==&lt;br /&gt;
&lt;br /&gt;
[[TicketQuery(status=closed,resolution!=fixed|wontfix|worksforme,format=table,col=summary|type|resolution,order=priority,desc=1,milestone=Orsync 1.0)]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}}}&lt;br /&gt;
&lt;br /&gt;
{{{&lt;br /&gt;
#!div style="clear:both"&lt;br /&gt;
}}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
There you go. Hope it helps!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-1543362117787473437?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/id_SpKn7tPC-6j8hcukHoxt6vms/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/id_SpKn7tPC-6j8hcukHoxt6vms/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/id_SpKn7tPC-6j8hcukHoxt6vms/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/id_SpKn7tPC-6j8hcukHoxt6vms/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/_ko5rrsQPNc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/1543362117787473437/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=1543362117787473437" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/1543362117787473437?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/1543362117787473437?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/_ko5rrsQPNc/trac-and-kanban-redux.html" title="Trac and Kanban - Redux" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-H7gT4_DCWEI/ToWD3eodeMI/AAAAAAAAAGo/DobE0ZwJi94/s72-c/orzone_trac_kanban_dashboard.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2011/09/trac-and-kanban-redux.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcESHo-cSp7ImA9WhZSE0Q.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-7247377895367619030</id><published>2011-03-29T13:26:00.001+02:00</published><updated>2011-03-29T13:26:49.459+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-29T13:26:49.459+02:00</app:edited><title>Process spawned successfully</title><content type="html">Our daughter arrived on March 19th, hence the lack of updates lately.&lt;br /&gt;
&lt;br /&gt;
Normal service may resume in the future, but expect shorter posts in the near time.&lt;br /&gt;
&lt;br /&gt;
P.S. I'm considering applying as a GSoC mentor for Buildbot, guiding the Javascript UI project together with a few other Buildbot developers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-7247377895367619030?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/K_UvHbJq0DRtGuFdhs9IaneiI48/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/K_UvHbJq0DRtGuFdhs9IaneiI48/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/K_UvHbJq0DRtGuFdhs9IaneiI48/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/K_UvHbJq0DRtGuFdhs9IaneiI48/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/WkaEg5ExGAM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/7247377895367619030/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=7247377895367619030" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/7247377895367619030?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/7247377895367619030?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/WkaEg5ExGAM/process-spawned-successfully.html" title="Process spawned successfully" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2011/03/process-spawned-successfully.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMHQXo4cSp7ImA9WhZUFEk.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-1535838878611612597</id><published>2011-02-26T22:13:00.005+01:00</published><updated>2011-06-07T11:53:50.439+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-07T11:53:50.439+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="books" /><title>Book Review - What Technology Wants by Kevin Kelly</title><content type="html">I decided to order a few non-fiction book from Amazon a few months ago, as a change from the reality-escaping high-fantasy, grand space opera or hard sci-fi that I usually churn through. I suppose it's got something to do with &lt;s&gt;growing up&lt;/s&gt;&amp;nbsp;getting older.&lt;br /&gt;
&lt;br /&gt;
Included in the package was:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;i&gt;Managing Humans&lt;/i&gt; by &lt;i&gt;Michael Lopp&lt;/i&gt; (has a very neat 'geek &amp;amp; manager' blog at&amp;nbsp;&lt;a href="http://randsinrepose.com/"&gt;randsinrepose.com&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Linchpin &lt;/i&gt;by &lt;i&gt;Seth Godin&lt;/i&gt; (has a pretty unique 'be awesome now' blog at &lt;a href="http://sethgodin.com/"&gt;sethgodin.com&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Guns, Germs and Steel &lt;/i&gt;by &lt;i&gt;Jared Diamond&lt;/i&gt; (the book won the Pulitzer Prize)&lt;/li&gt;
&lt;li&gt;&lt;i&gt;Crossing the Chasm: Marketing and Selling High-Tech Products to Mainstream Customer &lt;/i&gt;by &lt;i&gt;Geoffery A. Moore &lt;/i&gt;(was recommended due to the other books I've ordered)&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;And, the reason for this post:&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;What Technology Wants &lt;/i&gt;by Kevin Kelly (former Wired editor, etc. Website at &lt;a href="http://kk.org/"&gt;kk.org&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;Apart from the last one, I've also finished the two first and heartily recommend them. &amp;nbsp;I might review them too, but if you can't wait for that, I'm fairly certain you won't regret spending some time with them. Also, I'm currently a third of the way into&amp;nbsp;&lt;i&gt;Guns, Germs and Steel&lt;/i&gt;&amp;nbsp;and it has not disappointed the slightest yet.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Anyway, withour further ado, here comes my short and humble review of:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;i&gt;What Technology Wants &lt;/i&gt;by &lt;i&gt;Kevin Kelly&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;&lt;i&gt;(This review is also posted on &lt;a href="http://www.amazon.com/review/R3G9G1SSSH3YI3/ref=cm_cr_rdp_perm"&gt;Amazon.com&lt;/a&gt;)&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;What Technology Wants is a slightly puzzling title which poked my interest. Can technology actually "want" something? What does that phrase mean? Does it attempt to imply that technology has a will of its own, is it is a "force of nature", or just something inevitable built in the rules of the universe?&lt;br /&gt;
&lt;br /&gt;
These questions might sound a bit like "hippy-talk" (for lack of a better term) and while reading the first chapters of the book, which try to grasp this rather evasive concept, it felt rather hard to follow out where the author tries to lead. Solid lines of reasoning do emerge eventually, so if the narrative feels a bit vague in the beginning, one should not give up. Getting the grips on the driving force behind all the technology that most of us humans has ready access to, and what this actually means, is to say the least a rather daunting task. Also, I suppose the book tries to cater for many readers, not just the tech-savvy, so it attempts to gather everyone and provide a foundation on which the ideas and theories of subsequent chapters can build on.&lt;br /&gt;
&lt;br /&gt;
The amount of background research made for the book is phenomenal. He devotes a large part of the book on the Amish, being that they are a successful group that chooses to live outside the "normal" western civilization, actively choosing to abstain from much of today's technology. However, he notes, crucially in my (and his) opinion, that the&amp;nbsp;Amish&amp;nbsp;would not be able to function without the rest of the society, and that they continually lag about 50 years behind.&lt;br /&gt;
&lt;br /&gt;
This choosing of technology is not specific to&amp;nbsp;Amish&amp;nbsp;though. Everyone is doing it, one way or the other. Often, we are not very consistent in our choices. I.e. we may be on the cutting edge on one part, but several generations back on another, just because we want to.&lt;br /&gt;
&lt;br /&gt;
Kelly relates this to the fact that&amp;nbsp;Amish&amp;nbsp;seem to live a pretty happy and unstressful life, at least in comparison to many of the rest of us. They perform their honest work and labor with the tools they have, being fairly content with the situation. They choose their tools by waiting for the rest of society (and select individuals of their own) to try out technologies before choosing that which is good and not disruptive to their way of living. This of course relies on the fact to the rest of us continues to provide spare parts for old tech, as well as continuously producing new technology.&lt;br /&gt;
&lt;br /&gt;
An interesting side-fact (related to the issue of spare parts above) that is stated is that, apparently, no technology ever dies. You can find somewhere to buy a piece of flint and steel, an axe, an abacus, vacuum tubes (for your "this-goes-to-eleven" guitar amp), a vinyl player, etc. It don't doubt it at all, and it does help to choose between various technologies.&lt;br /&gt;
&lt;br /&gt;
The book also contains a treatise on the unabomber. Being Swedish (and rather young at the time of the event), I knew very little about him before reading this book. There are some excerpts of the unabombers manifesto included (and discussed) in the book, which make the case that technology is inevitable and people cannot escape it. From this, IIRC, the unabomber draws the conclusion that since it's forced upon people by the system, so the system (and/or civilization) such as it is must be destroyed completely for the people to be free. &amp;nbsp;Most of us agree with the first part, but our rejection of the latter conclusion probably separates civilization from apocalypse. (Also, even the unabomber tried to reject civilization and technology for several years, but could not do so completely, since he needed bullets for his rifle, rope for his traps and gasoline for the car to be able to travel to trade these things.)&lt;br /&gt;
&lt;br /&gt;
Kelly proffers the same statement here, which is that technology in something inevitable, in the same sense that the universe has given us &amp;nbsp;DNA, multi-cellular organisms, mammals, humans and civilization (for better or worse). One simply cannot prevent technology from appearing, given how far everything have gone already, and from where it actually started (i.e. the primordial soup). Complexity, and the perpetual increase thereof, is inherent in the foundations of the universe. We've had natural evolution for almost four billion years, and for the last ten to twenty thousand years (give or take a few), mankind (a product of the above) has been selecting, domesticating, refining and reworking different parts of nature to its liking. Now, we're selecting technology instead, and technology is undergoing evolution under the same criteria that (probably) made us domesticate the wolf rather than the hyena. (It's more beautiful, more intelligent, more adaptable, etc etc.)&lt;br /&gt;
&lt;br /&gt;
This strive towards beauty, complexity, adaptability, etc etc is going on with technology today. Personally, I see this in the world of computer components, libraries, frameworks, utilities, etc. The open-source ecosystem a good example of this evolutionary process, as &amp;nbsp;libraries come, evolve and leave. Some evolve quickly then stagnate when there is no opposition, then either gets wiped out when a new, better toolkit appear, or they attract sufficient interest (from it's users and developers) to catch up. The book's final chapters summarizes a number of criteria that are selected for in the evolutionary process, that will continue to be the driving force of change as technology evolves into more diverse, specialized, complex, interlinked, adaptable and beautiful manifestations..&lt;br /&gt;
&lt;br /&gt;
Kelly, rather early, names the entire technological sphere the Technium. In the end, he concludes that what it wants is just to live and prosper, just like any other self-evolvable entity. The difference is that the Technium can evolve a thousand or a million times faster, and that it this speed is because it does not evolve by chance (i.e. mutation), but rather the fact that it is actively driven (you could say developed) towards improvement with every generation. Also, since it's so interlinked, and has perfect memory (i.e. the Internet, more or less), it will build upon itself much faster than evolution (wherein for instance the eye evolved independently eight times) and even faster than human civilization (which could not communicate ideas and inventions especially fast until we had the Internet).&lt;br /&gt;
&lt;br /&gt;
I think this book is awesome in several ways. The question it attempts to both define, investigate and answer is immense. It is also a most relevant question, as I (and I suspect a few more) wonder where we are heading with all this technology, how it will shape us and what we can do, if anything, to guide it during its evolution. And since it actually manages to pull it off, I cannot by heartily recommend it to anyone that has some kind of interest in the field.&lt;br /&gt;
&lt;br /&gt;
Having left me me with a sense that there is really no difference between the big bang and the forming solar systems, life and evolution, humans and civilization and finally technology (and thus the Technium, as Kelly names it), I feel that I'm standing slightly more on firmer ground, while the world around us spins ever faster.&lt;br /&gt;
&lt;br /&gt;
Or maybe, I'm just getting older. ;)&lt;br /&gt;
&lt;div style="font-style: italic;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-1535838878611612597?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/8_g5T_yiIiILbSC69pap1cYBm7U/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8_g5T_yiIiILbSC69pap1cYBm7U/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/8_g5T_yiIiILbSC69pap1cYBm7U/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8_g5T_yiIiILbSC69pap1cYBm7U/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/IdA-QgjhBys" height="1" width="1"/&gt;</content><link rel="related" href="http://www.kk.org/books/what-technology-wants.php" title="Book Review - What Technology Wants by Kevin Kelly" /><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/1535838878611612597/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=1535838878611612597" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/1535838878611612597?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/1535838878611612597?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/IdA-QgjhBys/book-review-what-technology-wants-by.html" title="Book Review - What Technology Wants by Kevin Kelly" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2011/02/book-review-what-technology-wants-by.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkEMQ3Y6eip7ImA9Wx9WEkU.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-3104691647946733569</id><published>2011-01-17T17:11:00.000+01:00</published><updated>2011-01-17T17:11:22.812+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-17T17:11:22.812+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="pyqt" /><title>Configuring PyQt across unit-tests</title><content type="html">We had some &lt;span class="Apple-style-span" style="font-family: inherit;"&gt;problems &lt;/span&gt;with configuring the PyQt API version across unit-tests. The problems arise because several modules try to call sip.setapi, which you can only do once (even if you call it with the same args, which ought to be idempotent, you'd think.)&lt;br /&gt;
&lt;br /&gt;
Anyway, what I did was to create a module called 'pyqtconfig' with the following contents:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;import sip&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;sip.setapi('QString', 2)&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;sip.setapi('QVariant', 2)&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;sip.setapi('QTextStream', 2)&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;import PyQt4.Qt&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Qt = PyQt4.Qt&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Then I simply do 'from pyqtconfig import Qt' in each module. Works like a charm.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;i&gt;(If you want to import each module separately, you need to adapt the above code somewhat. I'll leave that as an exercise for the reader. :)&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-3104691647946733569?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/kO9L4aSXHPEd4aKyQDL66jSEdxw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kO9L4aSXHPEd4aKyQDL66jSEdxw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/kO9L4aSXHPEd4aKyQDL66jSEdxw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kO9L4aSXHPEd4aKyQDL66jSEdxw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/voAG_cNB6uo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/3104691647946733569/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=3104691647946733569" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/3104691647946733569?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/3104691647946733569?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/voAG_cNB6uo/configuring-pyqt-across-unit-tests.html" title="Configuring PyQt across unit-tests" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2011/01/configuring-pyqt-across-unit-tests.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkcAQHk6fCp7ImA9WhdUE0o.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-3266571510391042553</id><published>2011-01-17T12:51:00.006+01:00</published><updated>2011-09-30T11:14:01.714+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-30T11:14:01.714+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="kanban" /><category scheme="http://www.blogger.com/atom/ns#" term="trac" /><title>Trac and Kanban</title><content type="html">&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;(Don't miss my update &lt;a href="http://mackeblog.blogspot.com/2011/09/trac-and-kanban-redux.html"&gt;Trac and Kanban Redux&lt;/a&gt;)&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;We use a Trac wiki page as a simple kanban board. It's pretty neat, especially when put on a 42" LCD TV in the project room.&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Here's how it looks in the browser:&lt;/span&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_tlUbUg_x1Rk/TTQtJ8EDJkI/AAAAAAAAADo/V6jIXwiZ52I/s1600/trac.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" src="http://2.bp.blogspot.com/_tlUbUg_x1Rk/TTQtJ8EDJkI/AAAAAAAAADo/V6jIXwiZ52I/s400/trac.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
And here's the wiki code, all built using TickeyQuery-macros, both for counting (to keep an eye on the WIP-limit) and listing the tickets themselves. It's pretty basic, but it works well &amp;nbsp;for our small team and it's easy to understand and maintain.&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;pre style="font-size: 50%;"&gt;This is the ticket dashboard for Orcamp for [milestone:"Orcamp 1.0"] ([/query?milestone=2010+M11&amp;amp;order=priority&amp;amp;col=id&amp;amp;col=summary&amp;amp;col=status&amp;amp;col=type&amp;amp;col=priority&amp;amp;col=milestone&amp;amp;col=component tickets])  -- [wiki:Orcamp/FeatureList current feature list]

{{{
#!div style="float:left; margin-right:1em; width:30%"

= Open Tickets = 

Total: [[TicketQuery(status=new|reopened,milestone=Orcamp 1.0,format=count)]] 

[[TicketQuery(group=priority,status=new|reopened,milestone=Orcamp 1.0)]]

}}}
{{{
#!div style="float:left; margin-right:1em; width:30%" 

= Work In Progress =

Total: [[TicketQuery(status=accepted|testable,milestone=Orcamp 1.0,format=count)]] 

== Started ==

[[TicketQuery(status=accepted,order=priority,group=owner,milestone=Orcamp 1.0)]]

== Ready for Test ==

[[TicketQuery(status=testable&amp;amp;review_issues=0&amp;amp;reviewed!=,group=developertest,milestone=Orcamp 1.0)]]

== Reviewed tickets with issues ==

[[TicketQuery(review_issues=1,group=owner,status=testable|closed,resolution=fixed,milestone=Orcamp 1.0)]]

== Unreviewed tickets == 

[[TicketQuery(review_issues!=1,status=closed|testable,group=status,resolution=fixed,reviewed=,milestone=Orcamp 1.0)]]


}}}
{{{
#!div style="float:left; margin-right:1em; width:30%" 


= Closed Tickets = 

Total fixed: [[TicketQuery(status=closed,milestone=Orcamp 1.0,resolution=fixed,format=count)]] 
Other: [[TicketQuery(status=closed,milestone=Orcamp 1.0,resolution!=fixed,format=count)]] 

== Fixed tickets ==

[[TicketQuery(status=closed,group=type,resolution=fixed,milestone=Orcamp 1.0)]]

== Other resolutions ==

[[TicketQuery(status=closed,group=resolution,resolution!=fixed,milestone=Orcamp 1.0)]]


}}}

{{{
#!div style="clear:both"
}}}

&lt;/pre&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Note that the above wiki code contains some references to custom fields (notably review_issues) that we use to manage code reviews on a ticket-by-ticket basis. In our small team, we've decided to allow commits of unreviewed code, but require code to be reviewed before it's cleared for testing.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
As always, you should adapt to local conditions. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-3266571510391042553?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Wh-Es3JnmTNQ87HMl67u71XB-4Q/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Wh-Es3JnmTNQ87HMl67u71XB-4Q/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Wh-Es3JnmTNQ87HMl67u71XB-4Q/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Wh-Es3JnmTNQ87HMl67u71XB-4Q/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/9ycyG51Nylo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/3266571510391042553/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=3266571510391042553" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/3266571510391042553?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/3266571510391042553?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/9ycyG51Nylo/trac-and-kanban.html" title="Trac and Kanban" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_tlUbUg_x1Rk/TTQtJ8EDJkI/AAAAAAAAADo/V6jIXwiZ52I/s72-c/trac.png" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2011/01/trac-and-kanban.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0cCQnk-cSp7ImA9Wx9XFUQ.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-8781368938790084627</id><published>2011-01-09T18:43:00.001+01:00</published><updated>2011-01-09T18:44:23.759+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-09T18:44:23.759+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="buildbot" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><title>BuildBotIcon - Python Style (and it's got tests this time!)</title><content type="html">If you've read earlier posts here, you might know that I'm behind &lt;a href="https://bitbucket.org/marcusl/buildboticon/wiki/Home"&gt;BuildBotIcon&lt;/a&gt;, a small Java application that sits in the system tray, polling one or more &lt;a href="http://buildbot.net/"&gt;BuildBot&lt;/a&gt; servers and reports any changes. It also plays sounds and turns lava lamps on or off.&lt;br /&gt;
&lt;br /&gt;
I've decided to do a version in Python using PyQt instead. It's mostly as a fun exercise swim in the ecosystem of python (setuptools, unittest, mocking, coverage, yaml, etc) but it might come out better than the original.&lt;br /&gt;
&lt;br /&gt;
PyQs nice, and the new-style signals-slots makes it a breeze to do what you want if, assuming you know your way around Qt. (Not that it's hard to learn, I just knew Qt pretty well before embarking on this project.)&lt;br /&gt;
&lt;br /&gt;
Writing unittests are a breeze, and I think that it sure helps knowing that the code works, instead of knowing it only compiles. Coming from C++ this is actually pretty nice change. However, you should write with testing from the beginning. Grafting unit-testing later on is difficult and might not be a net win for all components, especially in C++ . (Mostly since you've run them for a while and the obvious (and thus easy-to-test-for) bugs have already been ironed out.)&lt;br /&gt;
&lt;br /&gt;
However, the greatest fun so far has been using &lt;a href="http://pypi.python.org/pypi/mock/"&gt;Mock&lt;/a&gt;, yet another mock object module for python that takes a nice and intuitive approach to mocking, IMHO. Instead of record/replay, or setup/run/verify, it's more like mock/run/assert. Read &lt;a href="http://www.voidspace.org.uk/python/articles/mocking.shtml"&gt;Mocking, Patching, Stubbing: all that Stuff&lt;/a&gt;&amp;nbsp;(and it's link to &lt;a href="http://martinfowler.com/articles/mocksArentStubs.html"&gt;Mocks aren't Stubs&lt;/a&gt;)&amp;nbsp;for more information on this.&lt;br /&gt;
&lt;br /&gt;
The ability of substituting &lt;b&gt;any &lt;/b&gt;function or object in the APIs you're running makes unittesting immensely powerful and thorough. If you trust the framework (Qt in my case) it's very easy to verify that play() is called on the right QSound (without making noises) or that get() is run with the right URL to access the network.&lt;br /&gt;
Of course, more complex behaviours are trickier to mock properly, so it helps to refactor your app into testable parts (which you should do anyway).&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Also, I've used &lt;a href="http://yaml.org/"&gt;YAML &lt;/a&gt;for the settings file this time (using &lt;a href="http://pyyaml.org/"&gt;PyYAML&lt;/a&gt;). All is good and well, except that it turns out that writing the settings file first and implementing the app second had probably been a better idea. TDD again.&lt;/div&gt;&lt;br /&gt;
It has all fallen out pretty nicely so far, except that, similar to the Java version, I've bungled together the backend that does networking and parsing with the UI. Since I currently have three ways to show build state (tray icon, sound and lava lamps) I should really had put a Listener interface in there. Fixing that now means refactoring the unit tests too, which is less fun. :-|&lt;br /&gt;
&lt;br /&gt;
Nevertheless, all of this is experience is bound to pay back in my ThrustRacer-project (should I get it off the ground) or at work, where we're about to embark on a year of much Python coding. I don't expect either to get it right from the start, one never does. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-8781368938790084627?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Krs6IfYOtYhKGznkoISPM5vkBcQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Krs6IfYOtYhKGznkoISPM5vkBcQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Krs6IfYOtYhKGznkoISPM5vkBcQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Krs6IfYOtYhKGznkoISPM5vkBcQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/3L1BROx6Lg0" height="1" width="1"/&gt;</content><link rel="related" href="https://bitbucket.org/marcusl/buildboticon/wiki/Home" title="BuildBotIcon - Python Style (and it's got tests this time!)" /><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/8781368938790084627/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=8781368938790084627" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/8781368938790084627?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/8781368938790084627?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/3L1BROx6Lg0/buildboticon-python-style-and-its-got.html" title="BuildBotIcon - Python Style (and it's got tests this time!)" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2011/01/buildboticon-python-style-and-its-got.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0AMRH05cCp7ImA9Wx9QF00.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-9111097368302480509</id><published>2010-12-30T01:31:00.003+01:00</published><updated>2010-12-30T11:43:05.328+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-30T11:43:05.328+01:00</app:edited><title>ThrustRacer (working title)</title><content type="html">I just got the idea to re-create the old &lt;a href="http://www.bluemoon.ee/history/roketz/index.html"&gt;Roketz&lt;/a&gt; game on more modern hardware, notably using OpenGL GPUs and getting the stuff to run on both my PC and my HTC Desire Android device. (B.t.w, the PC version of Roketz is fully runnable on modern operating systems if you install &lt;a href="http://www.dosbox.com/"&gt;DosBox&lt;/a&gt;, but the &lt;a href="http://androiddosbox.appspot.com/"&gt;Android DosBox&lt;/a&gt;&amp;nbsp;project claims that performance is a bit low still. So it won't do for an action game..)&lt;br /&gt;
&lt;br /&gt;
There is already someone trying to do a version called &lt;a href="http://openroketz.sourceforge.net/"&gt;OpenRoketz&lt;/a&gt; but that seems to be in 2D using &lt;a href="http://www.libsdl.org/"&gt;SDL &lt;/a&gt;(which isn't available pre-compiled for VS2008 ... and it didn't compile out-of-the box either). Anyway I sort-o- planned the thing as a neat side-project to try proper OpenGL ES 2 (as opposed to vanilla OpenGL with all the fixed function stuff, which is what I learnt 12 years ago just after doing some 3DFX-Glide stuff, just after writing my own triangle rasterizers and whatnot).&lt;br /&gt;
&lt;br /&gt;
I'd also like to try and attempt to create a small community with high-scores on the web, network play and user-creatable maps. Web servers are pretty cheap nowadays and &lt;a href="http://djangoproject.org/"&gt;Django&lt;/a&gt; is always fun to muck about with. (The editor will probably be in &lt;a href="http://www.python.org/"&gt;Python&lt;/a&gt; and &lt;a href="http://qt.nokia.com/"&gt;Qt&lt;/a&gt;).&lt;br /&gt;
&lt;br /&gt;
It'll probably not amount to much, but what the heck. :)&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-9111097368302480509?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/7LR7YFcUtJjNXGMXbe1PRWvg7nU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7LR7YFcUtJjNXGMXbe1PRWvg7nU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/7LR7YFcUtJjNXGMXbe1PRWvg7nU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7LR7YFcUtJjNXGMXbe1PRWvg7nU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/K_x_iMGgtGI" height="1" width="1"/&gt;</content><link rel="related" href="https://bitbucket.org/marcusl/thrustracer/" title="ThrustRacer (working title)" /><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/9111097368302480509/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=9111097368302480509" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/9111097368302480509?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/9111097368302480509?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/K_x_iMGgtGI/thrustracer-working-title.html" title="ThrustRacer (working title)" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><thr:total>3</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2010/12/thrustracer-working-title.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEAFRnk4fyp7ImA9Wx9TGEg.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-6769282223559226742</id><published>2010-11-27T12:18:00.000+01:00</published><updated>2010-11-27T12:18:37.737+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-27T12:18:37.737+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mercurial" /><title>Mercurial rebase/merge musings part 2</title><content type="html">In a&amp;nbsp;&lt;a href="http://mackeblog.blogspot.com/2010/11/mercurial-rebasemerge-musings.html"&gt;previous post&lt;/a&gt;&amp;nbsp;I wrote about how nice it'd be if &lt;a href="http://mercurial.selenic.com/"&gt;Mercurial&lt;/a&gt; automatically could choose rebase or merge depending on whether there are conflicts that need manual resolution.&lt;br /&gt;
&lt;br /&gt;
So, "yesternight", after finishing the &lt;a href="http://mercurial.selenic.com/wiki/CheckFilesExtension"&gt;checkfiles extension&lt;/a&gt;&amp;nbsp;I wrote about recently I couldn't go back to sleep (despite it being 2:30 AM). So, I got back up and hacked together the&amp;nbsp;&lt;a href="http://mercurial.selenic.com/wiki/RebaseIfExtension"&gt;rebaseif extension&lt;/a&gt; that adds a command and an option to pull that does exactly that. It turns out it wasn't that hard,&amp;nbsp;although&amp;nbsp;the process could probably be optimized slightly as it currently attempts a rebase, aborts on conflicts and then does a merge. (The better way would be to detect which operation would succeed and perform that.)&lt;br /&gt;
&lt;br /&gt;
Now, some support for that in &lt;a href="http://tortoisehg.bitbucket.org/"&gt;TortoiseHg&lt;/a&gt;&amp;nbsp;and we're all set. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-6769282223559226742?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/rKCQ3edPxn_3BDzmg_E1E9O36uM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rKCQ3edPxn_3BDzmg_E1E9O36uM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/rKCQ3edPxn_3BDzmg_E1E9O36uM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rKCQ3edPxn_3BDzmg_E1E9O36uM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/eEhpFhIdhxo" height="1" width="1"/&gt;</content><link rel="related" href="http://mercurial.selenic.com/wiki/RebaseIfExtension" title="Mercurial rebase/merge musings part 2" /><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/6769282223559226742/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=6769282223559226742" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/6769282223559226742?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/6769282223559226742?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/eEhpFhIdhxo/mercurial-rebasemerge-musings-part-2.html" title="Mercurial rebase/merge musings part 2" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2010/11/mercurial-rebasemerge-musings-part-2.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUCSH0-eSp7ImA9Wx9TGEg.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-8651092987414067548</id><published>2010-11-27T00:52:00.003+01:00</published><updated>2010-11-27T12:27:49.351+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-27T12:27:49.351+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mercurial" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><title>Mercurial extension writing</title><content type="html">I just spent the better part of the evening and early night to hack together a &lt;a href="http://mercurial.selenic.com/"&gt;Mercurial &lt;/a&gt;extension to check for and fix tabs and trailing whitespace in files to be committed.&lt;br /&gt;
&lt;br /&gt;
Diving into a (relatively) poorly documented Python API is not easy. My previous attempts with Django (extremely good docs) and BuildBot (perfectly acceptable docs) went much better in terms of tackling the early learning curve.&lt;br /&gt;
&lt;br /&gt;
As an example, I have not yet managed to figure out how to get the added diff lines of the working directory, or the files included in an upcoming commit (this are slightly different). The MercurialAPI wiki page only gives a brief overview, after that you're on your own and have to use the source. This is pretty fine, except that dynamic languages need more written docs if the source is to be understood better.&lt;br /&gt;
&lt;br /&gt;
Anyway, the extension works pretty nicely as I decided to check the _entire_ file instead of just the changed lines. Shouldn't make a big difference performance wise, and it will allow a code base to go from mixes-tabs to spaces-only much faster. I can always revisit that part later if the need arises.&lt;br /&gt;
&lt;br /&gt;
The next part in the plan is to write a small script that auto-injects this into each developers hgrc file on checkout. (I have a script that one must run, more or less, to deploy/unzip third-party libraries and set up environment variable, so it can just as well edit the hgrc file too.) I'm not worried about the security implications currently, as we're four developers on a corporate network, so everyone should play nicely at the moment, and secondly, I can always safeguard the paths to the extension (or put in in a subrepo) to which no-one but a select few, including myself, have commit/push rights (in case of a rogue developer).&lt;br /&gt;
&lt;br /&gt;
The next little script I write will probably be something like that, to allow deployment of local extensions. I'll also add some extra meta-data to a commit and a central-repo hook to check for that, so that one can't push without the meta-data (ensuring that everyone starts using the hook ASAP) and also run the same checks there (in case someone decides to override the hook).&lt;br /&gt;
&lt;br /&gt;
Hacking should not happen out of pure malice, but I've had developers disabling the global warnings-in-log-at-exit popup just because they where annoyed by them. (The best way would've been to fix the warnings inside the app, or at least have a chat with me on which log messages are warnings and if it's worthwhile to add a feature where said developer may disable the popup for a few hours.) Since the popup was disabled, many others in the team missed warnings or errors in the log and subsequently the CI build failed with warnings after commit. Sadly quite contraproductive and against the spirit of early-warnings.&lt;br /&gt;
&lt;br /&gt;
Summing it up, I really enjoy hacking together small things in Python, but for larger projects it seems to become pretty unbearable and you really want to know the types of the variables. I really wish C# and WPF was available on more than one platform, so that we could go with that instead of C++/Python on Qt. It does seem to be a nicer road to walk.&lt;br /&gt;
&lt;br /&gt;
(Yes, I've thought about Java, and I've worked with it for a few years. And no, I don't really like it, but I suppose SWT is at leats a bearable GUI-API (i.e. better than Swing), but lately with the Oracle takeover I'm very wary of betting on Java going anywhere but down the drain for non-enterprise projects.)&lt;br /&gt;
&lt;br /&gt;
Obligatory links:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="https://bitbucket.org/marcusl/ml-hgext/src/tip/checkfiles.py"&gt;checkfiles.py&lt;/a&gt;&amp;nbsp;on BitBucket.org.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://mercurial.selenic.com/wiki/CheckFilesExtension"&gt;CheckFilesExtension&lt;/a&gt;&amp;nbsp;on the Mercurial Wiki.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ohloh.net/p/ml-hgext"&gt;ml-hgext&lt;/a&gt; project on Ohloh.net&lt;/li&gt;
&lt;li&gt;&lt;a href="http://open.spotify.com/artist/0Iv00ucAIqr5KVS7bXGFa9"&gt;Ozric Tentacles&lt;/a&gt;&amp;nbsp;on Spotify, great background coding music (instrumental progressive/trance crossover)&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-8651092987414067548?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/GH2vC3yG0NteZLagBZnaW7BrFyM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GH2vC3yG0NteZLagBZnaW7BrFyM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/GH2vC3yG0NteZLagBZnaW7BrFyM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GH2vC3yG0NteZLagBZnaW7BrFyM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/Agz13t3UMco" height="1" width="1"/&gt;</content><link rel="related" href="https://bitbucket.org/marcusl/ml-hgext/src" title="Mercurial extension writing" /><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/8651092987414067548/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=8651092987414067548" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/8651092987414067548?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/8651092987414067548?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/Agz13t3UMco/mercural-extension-writing.html" title="Mercurial extension writing" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2010/11/mercural-extension-writing.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkICSXk4cCp7ImA9Wx5aE04.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-4735606049141891389</id><published>2010-11-09T22:36:00.000+01:00</published><updated>2010-11-09T22:36:08.738+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-09T22:36:08.738+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mobile" /><title>New toy!</title><content type="html">Also, I got a HTC Desire a few weeks ago. Love it!&lt;br /&gt;
&lt;br /&gt;
It's really becoming the multi-purpose do-it-all device that we all need to make our life a non-stop information gathering/processing journey from the cradle to the grave. :-P&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-4735606049141891389?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/TpDifaPecj4EEtMl9-CSr2CqmPk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TpDifaPecj4EEtMl9-CSr2CqmPk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/TpDifaPecj4EEtMl9-CSr2CqmPk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TpDifaPecj4EEtMl9-CSr2CqmPk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/-iF7xb47kkI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/4735606049141891389/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=4735606049141891389" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/4735606049141891389?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/4735606049141891389?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/-iF7xb47kkI/new-toy.html" title="New toy!" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2010/11/new-toy.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak4HSHo8cCp7ImA9Wx5aE04.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-3896886213718465693</id><published>2010-11-09T22:33:00.001+01:00</published><updated>2010-11-09T22:42:19.478+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-09T22:42:19.478+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="buildbot" /><category scheme="http://www.blogger.com/atom/ns#" term="qt" /><title>More on HTML &amp; JavaScript Client Apps</title><content type="html">In a&amp;nbsp;&lt;a href="http://mackeblog.blogspot.com/2010/11/logwindow-20.html#links"&gt;recent post&lt;/a&gt;&amp;nbsp;I wrote about the new log window for our Qt apps at work. Essentially, it delivers the log via AJAX to a web browser, with the html &amp;amp; javascript embedded in and served statically by the app. Works well enough.&lt;br /&gt;
&lt;br /&gt;
However, there are two more ships on the horizon flying similar flags. &lt;br /&gt;
&lt;br /&gt;
The first is my (secret) plan to build a debugger for a State Machine for a few years. Since Qt now has a state machine as of 4.6, and it seems both solid, well documented and behaves mostly correct (observing that we've yet to learn all ins and outs of a full state chart machine) is seems a good target for this. I've already written a QStateMachine to GraphViz translator, which outputs an SVG which can (with some good faith and heavy squinting)&amp;nbsp;be interpreted as a UML state chart (cough cough).&lt;br /&gt;
&lt;br /&gt;
Now, SVG is an XML document which has a DOM, which you can manipulate with Javascript in most modern browsers. Yay! However, &amp;nbsp;this did not, at the time of having the idea, include Google Chrome (my favorite), since &lt;a href="http://code.google.com/p/chromium/issues/detail?id=61412"&gt;SVG-DOM updates didn't redraw the image immediately&lt;/a&gt;.... They have fixed it since, but I am pretty busy with other things so this small show stopper held me up. I hit a bump, I move in another direction, especially when I'm just going somewhere to see where I end up. Will have to get back on this one ... :)&lt;br /&gt;
&lt;br /&gt;
Anyway, for the final product, I think a nice event log and some dynamic colouring/resizes of states and transitions would work wonders for debugging the app. Breakpoints via mouse-click events in the graph is then the second step. Then there are some question marks, but the last step is, as always, profit. ;)&lt;br /&gt;
&lt;br /&gt;
The problem is always to package it so that other people can re-use it. I have to try to get better at that, but it's sadly not on top of the priority pile when working at a startup.&lt;br /&gt;
&lt;br /&gt;
Secondly, it seems as the &lt;a href="http://www.buildbot.net/"&gt;BuildBot&lt;/a&gt;&amp;nbsp;project is planning to boot my &lt;a href="http://buildbot.net/trac/wiki/JinjaBranch"&gt;Jinja webstatus implementation&lt;/a&gt;&amp;nbsp;that replaced the html-string-pasting in python. (I never blogged about that.. oh well.. fun times it was anyway) Anyways, sad as that can be, the new plan is for... a html/javascript-only client! The content can then be served statically (via twisted or your local "real" webserver, for more oomph) and the webpage then communicates with the buildmaster using relatively small AJAX requests.&lt;br /&gt;
&lt;br /&gt;
I think the idea is pretty neat, and has much in common with the things above, so I might go ahead and tackle that as well. Or procastrinate until someone else does it and steal^h^h^hborrow ideas from that place. Anyways, the jinja-rewrite made it much easier to see the actual HTML, so the new javascript (preferrably using jQuery) client could build on top of the existing layout.&lt;br /&gt;
&lt;br /&gt;
Small steps in the right direction makes the world a better place. :)&lt;br /&gt;
&lt;br /&gt;
Also, some day in March, if things go as they should, the household will gain a new member. One very small and in need of almost-constant care. I estimate I will not be able to contribute to open source for a few years starting then. Best do what I can before that. ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-3896886213718465693?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/lwmmsx9QEnu0PAGJyQOPJWaFODM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/lwmmsx9QEnu0PAGJyQOPJWaFODM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/lwmmsx9QEnu0PAGJyQOPJWaFODM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/lwmmsx9QEnu0PAGJyQOPJWaFODM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/XTc99YEDEJE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/3896886213718465693/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=3896886213718465693" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/3896886213718465693?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/3896886213718465693?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/XTc99YEDEJE/more-on-html-javascript-client-apps.html" title="More on HTML &amp; JavaScript Client Apps" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2010/11/more-on-html-javascript-client-apps.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE8BSX87eyp7ImA9Wx9TGEg.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-1898978358041159928</id><published>2010-11-04T17:40:00.003+01:00</published><updated>2010-11-27T12:20:58.103+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-27T12:20:58.103+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mercurial" /><title>Mercurial rebase/merge musings</title><content type="html">I asked about &lt;a href="http://stackoverflow.com/questions/4086724/how-do-i-check-for-potential-merge-rebase-conflicts-in-mercurial"&gt;how-to-check-for-potential-merge-rebase-conflicts-in-mercurial&lt;/a&gt; on &lt;a href="http://stackoverflow.com/"&gt;StackOverflow&lt;/a&gt; yesterday and got a few interesting responses.&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;I think I'm going to write a small plugin that rebases if there are no file conflicts, and merges otherwise. This is what I want myself and everyone else to do, as it helps with clearing up bad merges afterwards, and avoid "'rebase broke the build and my life sucks" situtations.&lt;br /&gt;
&lt;br /&gt;
Update 2010-11-27: I've written an extension for this, see &lt;a href="http://mackeblog.blogspot.com/2010/11/mercurial-rebasemerge-musings-part-2.html"&gt;this post&lt;/a&gt; for details and links.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-1898978358041159928?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/C3eGG1wgBZBvRzaeJRFU014Dvww/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/C3eGG1wgBZBvRzaeJRFU014Dvww/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/C3eGG1wgBZBvRzaeJRFU014Dvww/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/C3eGG1wgBZBvRzaeJRFU014Dvww/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/rTQY0csw-BI" height="1" width="1"/&gt;</content><link rel="related" href="http://stackoverflow.com/questions/4086724/how-do-i-check-for-potential-merge-rebase-conflicts-in-mercurial" title="Mercurial rebase/merge musings" /><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/1898978358041159928/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=1898978358041159928" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/1898978358041159928?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/1898978358041159928?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/rTQY0csw-BI/mercurial-rebasemerge-musings.html" title="Mercurial rebase/merge musings" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2010/11/mercurial-rebasemerge-musings.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMEQ3k8fyp7ImA9Wx5bGEU.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-3209031374227433156</id><published>2010-11-04T16:50:00.006+01:00</published><updated>2010-11-04T17:00:02.777+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-04T17:00:02.777+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="qt" /><title>LogWindow 2.0 using LibQxt</title><content type="html">I just implemented a small web server for our Qt apps that use LibQxt's QxtWeb  classes to serve the application log over HTML.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Static files are served from QResources and log events are fetched by AJAX/jQuery, using a small javascript code to format them into a table in the web server.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Next on the todo-list is to add a dynamic filter by severity/thread/location. Should be pretty easy to get going.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We used an in-application LogWindow before, but that sucks performance wise and it doesn't redraw when debugging the GUI-thread, obviously. This is also way easier than creating and managing an logging application as an entirely different process.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The most recent LibQxt even has a JSONRPCService, which might've been useful. We're using a slightly older one so I manually implemented a WebService which serves JSON or html/css/js.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Anyway, this ought to be cleaned up a bit and contributed back to LibQxt.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-3209031374227433156?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/23EQcW2O8Entex95PCfMgXXrbak/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/23EQcW2O8Entex95PCfMgXXrbak/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/23EQcW2O8Entex95PCfMgXXrbak/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/23EQcW2O8Entex95PCfMgXXrbak/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/mrBKfrz3lNc" height="1" width="1"/&gt;</content><link rel="related" href="http://doc.libqxt.org/tip/qxtweb.html" title="LogWindow 2.0 using LibQxt" /><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/3209031374227433156/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=3209031374227433156" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/3209031374227433156?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/3209031374227433156?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/mrBKfrz3lNc/logwindow-20.html" title="LogWindow 2.0 using LibQxt" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2010/11/logwindow-20.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEANQn8zfip7ImA9Wx9bF0s.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-1009235735624057982</id><published>2010-01-22T19:51:00.008+01:00</published><updated>2011-02-27T00:26:33.186+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-27T00:26:33.186+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="python" /><title>Validating DTDs in python with lxml</title><content type="html">&lt;div&gt;After replacing the string-pasting in Buildbot's web-backend with proper html-templates (using Jinja), I decided to write a unit-test that follows all links on all pages and make sure they validate and don't contain stale links.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;lxml seemed like a nice tool for that, but our XHTML starts with a reference to w3.org's DTD I got this straight away:&lt;/div&gt;&lt;pre&gt;failed to load HTTP resource&lt;/pre&gt;Googling found me the &lt;a href="http://www.hoboes.com/Mimsy/hacks/caching-dtds-using-lxml-and-etree/"&gt;Caching DTDs using lxml and etree&lt;/a&gt; article by Jimmy Stratton. He had ran into the same problem last fall, dug around for a while (against the forces of nature, in this case represented by authors and documentation for lxml and python), and was nice enough to post his solution on the web.&lt;br /&gt;
&lt;br /&gt;
The resolver works flawlessly. Thanks Jimmy! I owe you one.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Update:&lt;/b&gt;&amp;nbsp;Since this is a reasonably popular post, here's the &lt;a href="https://github.com/buildbot/buildbot/blob/a1e99533057f3fd56496c26b42f0e0ba9e774b08/buildbot/test/runs/test_webparts.py"&gt;unit test&lt;/a&gt; for BuildBot, which applies this using the Twisted framework to validate all linked-to pages on the website. (It's was lost from the source tree in one of the many refactorings and cleanups of BuildBot's test suite. Also, it added some troublesome dependencies for the many builds slaves, and was too broad in scope. It should be re-cast as unit-tests for each page's possible states.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-1009235735624057982?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/zLGnNtDOiYrbnFd3RtalfkHnkSc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zLGnNtDOiYrbnFd3RtalfkHnkSc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/zLGnNtDOiYrbnFd3RtalfkHnkSc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zLGnNtDOiYrbnFd3RtalfkHnkSc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/1rrcqVULqD0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/1009235735624057982/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=1009235735624057982" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/1009235735624057982?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/1009235735624057982?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/1rrcqVULqD0/validating-dtds-in-python-with-lxml.html" title="Validating DTDs in python with lxml" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2010/01/validating-dtds-in-python-with-lxml.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUAMSXgyeCp7ImA9WxNSF04.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-2322232116250775305</id><published>2009-08-31T18:55:00.002+02:00</published><updated>2009-08-31T18:56:28.690+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-31T18:56:28.690+02:00</app:edited><title>Dirty coding tricks</title><content type="html">If you've gotta ship, you've gotta ship.&lt;br /&gt;&lt;br /&gt;See &lt;a href="http://www.gamasutra.com/view/feature/4111/dirty_coding_tricks.php"&gt;this Gamasutra article&lt;/a&gt; for some funny stories. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-2322232116250775305?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/jSCBNu04iNOaddzjBUfE87aJl9I/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/jSCBNu04iNOaddzjBUfE87aJl9I/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/jSCBNu04iNOaddzjBUfE87aJl9I/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/jSCBNu04iNOaddzjBUfE87aJl9I/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/x_qcKDj_lbU" height="1" width="1"/&gt;</content><link rel="related" href="http://www.gamasutra.com/view/feature/4111/dirty_coding_tricks.php" title="Dirty coding tricks" /><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/2322232116250775305/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=2322232116250775305" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/2322232116250775305?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/2322232116250775305?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/x_qcKDj_lbU/dirty-coding-tricks.html" title="Dirty coding tricks" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2009/08/dirty-coding-tricks.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEAHR3Y5fSp7ImA9WxJUEUg.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-4943898598235998513</id><published>2009-07-09T18:12:00.005+02:00</published><updated>2009-07-09T18:25:36.825+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-09T18:25:36.825+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="buildbot" /><category scheme="http://www.blogger.com/atom/ns#" term="lavalamp" /><title>Teh build is fail!</title><content type="html">Just to complete the gallery:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_tlUbUg_x1Rk/SlYXB98fdII/AAAAAAAAACI/7puznKg9NkA/s1600-h/lavalamp-megared.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 192px; height: 320px;" src="http://3.bp.blogspot.com/_tlUbUg_x1Rk/SlYXB98fdII/AAAAAAAAACI/7puznKg9NkA/s320/lavalamp-megared.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5356494129379374210" /&gt;&lt;/a&gt;&lt;br /&gt;The responsible one has left the building but it's been pretty effective so far in getting people to fix the build a.s.a.p. :)&lt;br /&gt;&lt;br /&gt;Also, the latest version of &lt;a href="http://bitbucket.org/marcusl/buildboticon"&gt;BuildBotIcon&lt;/a&gt; has optional sound, and currently we have Homer Simpson going 'DOH!' or 'Woohoo!' (rather loud). This makes everyone aware of it instantly.&lt;br /&gt;&lt;br /&gt;(And yes, I've been reading &lt;a href="http://icanhascheezburger.com"&gt;lolcats&lt;/a&gt; too much lately..)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-4943898598235998513?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/CSvgIPQmaar590WmINsVg9toLc0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CSvgIPQmaar590WmINsVg9toLc0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/CSvgIPQmaar590WmINsVg9toLc0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CSvgIPQmaar590WmINsVg9toLc0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/ZCTCTs6ubH0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/4943898598235998513/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=4943898598235998513" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/4943898598235998513?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/4943898598235998513?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/ZCTCTs6ubH0/teh-build-is-fail.html" title="Teh build is fail!" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_tlUbUg_x1Rk/SlYXB98fdII/AAAAAAAAACI/7puznKg9NkA/s72-c/lavalamp-megared.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2009/07/teh-build-is-fail.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak4GRn07eSp7ImA9WxJVE0o.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-3338476827918471741</id><published>2009-06-30T18:20:00.002+02:00</published><updated>2009-06-30T18:22:07.301+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-30T18:22:07.301+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="lavalamp" /><title>Oh noes, the red light is on!</title><content type="html">This is how it looks before things get really bad. The build was fixed before the lamp was running at full speed though. :)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_tlUbUg_x1Rk/Sko7gBs2xQI/AAAAAAAAACA/PXM6hgi0DLo/s1600-h/lavalamp-red.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 192px; height: 320px;" src="http://3.bp.blogspot.com/_tlUbUg_x1Rk/Sko7gBs2xQI/AAAAAAAAACA/PXM6hgi0DLo/s320/lavalamp-red.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5353156528481682690" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-3338476827918471741?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/m3v8buGAI3tfYoRYWIFle27iXoc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/m3v8buGAI3tfYoRYWIFle27iXoc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/m3v8buGAI3tfYoRYWIFle27iXoc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/m3v8buGAI3tfYoRYWIFle27iXoc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/gzmzKbYESdA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/3338476827918471741/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=3338476827918471741" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/3338476827918471741?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/3338476827918471741?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/gzmzKbYESdA/oh-noes-red-light-is-on.html" title="Oh noes, the red light is on!" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_tlUbUg_x1Rk/Sko7gBs2xQI/AAAAAAAAACA/PXM6hgi0DLo/s72-c/lavalamp-red.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2009/06/oh-noes-red-light-is-on.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkEBQHs-eSp7ImA9WxJVE0k.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-1531229131214993729</id><published>2009-06-24T17:25:00.005+02:00</published><updated>2009-06-30T09:57:31.551+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-30T09:57:31.551+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="buildbot" /><category scheme="http://www.blogger.com/atom/ns#" term="lavalamp" /><title>Lava lamps - up and running!</title><content type="html">One picture, 1k words, etc:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_tlUbUg_x1Rk/SkJFpBnawZI/AAAAAAAAAB4/l4Bt7uT1vG4/s1600-h/lavalamps.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 192px; height: 320px;" src="http://3.bp.blogspot.com/_tlUbUg_x1Rk/SkJFpBnawZI/AAAAAAAAAB4/l4Bt7uT1vG4/s320/lavalamps.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5350915878380290450" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We've also added a timer to turn them off during the night, along with the status monitor (which you can't see), to be nice to the environment.&lt;br /&gt;&lt;br /&gt;Again, the USB board can be bought from &lt;a href="http://www.active-robots.com/products/phidgets/phidgets-interface.shtml"&gt;Active Robots&lt;/a&gt; who were very friendly and helpful shipping the package to me, in spite of the efforts of our local post office. ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-1531229131214993729?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/hq0LD_TmzI9Jb_HBcK5sPt3mdzY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hq0LD_TmzI9Jb_HBcK5sPt3mdzY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/hq0LD_TmzI9Jb_HBcK5sPt3mdzY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hq0LD_TmzI9Jb_HBcK5sPt3mdzY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/W-DuP5L1GIk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/1531229131214993729/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=1531229131214993729" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/1531229131214993729?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/1531229131214993729?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/W-DuP5L1GIk/lavalamps-up-and-running.html" title="Lava lamps - up and running!" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_tlUbUg_x1Rk/SkJFpBnawZI/AAAAAAAAAB4/l4Bt7uT1vG4/s72-c/lavalamps.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2009/06/lavalamps-up-and-running.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0cFQHkzfCp7ImA9WxJWF00.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-8715298374718489928</id><published>2009-06-22T21:19:00.011+02:00</published><updated>2009-06-22T22:03:31.784+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-22T22:03:31.784+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="buildbot" /><category scheme="http://www.blogger.com/atom/ns#" term="lavalamp" /><title>Lava lamp USB board assembly pictures</title><content type="html">Here's some pictures of the assembly process. It went reasonably well, but making sure you have big enough drills beforehand helps a bit. :)&lt;br /&gt;&lt;br /&gt;Here's how the board looks before assembly:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bitbucket.org/marcusl/buildboticon/wiki/phidget_board.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 400px; height: 261px;" src="http://bitbucket.org/marcusl/buildboticon/wiki/phidget_board.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;First, check that the circuit board fix in plastic box. Tight fit. :)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_tlUbUg_x1Rk/Sj_aULUyZhI/AAAAAAAAABI/wOhuMZbC_jE/s1600-h/tightfit.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 199px;" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/Sj_aULUyZhI/AAAAAAAAABI/wOhuMZbC_jE/s320/tightfit.jpg" alt="" id="BLOGGER_PHOTO_ID_5350234922511656466" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Drill holes for 230V mains (in/out) and USB cable: (Had to use a knife to make the hole for the USB-B connector fit, as it is slightly asymmetric. Luckily, the plastic was very easy to work with.)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_tlUbUg_x1Rk/Sj_bHD7uoKI/AAAAAAAAABQ/yoPfp2KZ2ck/s1600-h/cableholes.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 192px;" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/Sj_bHD7uoKI/AAAAAAAAABQ/yoPfp2KZ2ck/s320/cableholes.jpg" alt="" id="BLOGGER_PHOTO_ID_5350235796700831906" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Drilled for circuit board with USB connector in place (avoids misalignment):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_tlUbUg_x1Rk/Sj_ZlvOMXeI/AAAAAAAAABA/xobNLIu64zY/s1600-h/boardholes.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 192px;" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/Sj_ZlvOMXeI/AAAAAAAAABA/xobNLIu64zY/s320/boardholes.jpg" alt="" id="BLOGGER_PHOTO_ID_5350234124693822946" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Prepare cables:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_tlUbUg_x1Rk/Sj_dS_O9J-I/AAAAAAAAABY/-wVGp9kBhEM/s1600-h/cable.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 134px;" src="http://2.bp.blogspot.com/_tlUbUg_x1Rk/Sj_dS_O9J-I/AAAAAAAAABY/-wVGp9kBhEM/s320/cable.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5350238200620984290" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Do the wiring (and remember to pull the cables through the holes in the box first):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_tlUbUg_x1Rk/Sj_dkt9kGSI/AAAAAAAAABg/vRKsHOm1eQA/s1600-h/wiring.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 219px;" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/Sj_dkt9kGSI/AAAAAAAAABg/vRKsHOm1eQA/s320/wiring.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5350238505222281506" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Fit the wired circuit board in the box, make sure all cables go inside and put tie-wraps on the cables to secure against mechanical stress:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_tlUbUg_x1Rk/Sj_dzdPVWvI/AAAAAAAAABo/8tih0PiNcd0/s1600-h/finalwiring.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 192px;" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/Sj_dzdPVWvI/AAAAAAAAABo/8tih0PiNcd0/s320/finalwiring.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5350238758431447794" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here's the box with the lid on:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_tlUbUg_x1Rk/Sj_et57M3SI/AAAAAAAAABw/Eq9MmmrwlIo/s1600-h/finalbox3.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 156px;" src="http://1.bp.blogspot.com/_tlUbUg_x1Rk/Sj_et57M3SI/AAAAAAAAABw/Eq9MmmrwlIo/s320/finalbox3.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5350239762564046114" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Ta-daaa. :)&lt;br /&gt;&lt;br /&gt;As you can see, I currently only use one relay. It's of course possible to use all four, but that requires more drilling and wiring, and more lava lamp shelf space. :)&lt;br /&gt;&lt;br /&gt;Always leave room for upgrades, I say. ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-8715298374718489928?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/nrEK9MNaTxVQq5r8IaJ7EEttsWA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nrEK9MNaTxVQq5r8IaJ7EEttsWA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/nrEK9MNaTxVQq5r8IaJ7EEttsWA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nrEK9MNaTxVQq5r8IaJ7EEttsWA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/w49Q9EiuUHk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/8715298374718489928/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=8715298374718489928" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/8715298374718489928?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/8715298374718489928?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/w49Q9EiuUHk/lava-lamp-usb-board-assembly-pictures.html" title="Lava lamp USB board assembly pictures" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_tlUbUg_x1Rk/Sj_aULUyZhI/AAAAAAAAABI/wOhuMZbC_jE/s72-c/tightfit.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2009/06/lava-lamp-usb-board-assembly-pictures.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkUGRno_eSp7ImA9WxJWEkk.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-5591212639158810048</id><published>2009-06-17T16:08:00.005+02:00</published><updated>2009-06-17T16:17:07.441+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-17T16:17:07.441+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="buildbot" /><category scheme="http://www.blogger.com/atom/ns#" term="lavalamp" /><title>Lava lamp - 99.5%</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_tlUbUg_x1Rk/Sjj6dLDZsqI/AAAAAAAAAA4/N-kVoxdrP8I/s1600-h/lavalamp-box.jpg"&gt;&lt;img style="float:none; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 320px; height: 192px;" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/Sjj6dLDZsqI/AAAAAAAAAA4/N-kVoxdrP8I/s320/lavalamp-box.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5348299936592671394" /&gt;&lt;/a&gt;&lt;br /&gt;Here's a tech-porn picture. :)&lt;br /&gt;&lt;br /&gt;It's connected at office and it works, but I didn't have time for lavalamps.&lt;br /&gt;&lt;br /&gt;Instead, I connected it to my office stereo system and set the computer to constantly play something from &lt;a href="http://open.spotify.com/album/1HVTBlr88ojRIUUdFd2psL"&gt;Tribute to Vengaboys&lt;/a&gt; when the build has failed.&lt;br /&gt;&lt;br /&gt;Forget the carrot, it's all about the stick. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-5591212639158810048?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/q__xtBRNYn6bhyBpAiwQkkB7fBE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/q__xtBRNYn6bhyBpAiwQkkB7fBE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/q__xtBRNYn6bhyBpAiwQkkB7fBE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/q__xtBRNYn6bhyBpAiwQkkB7fBE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/aT7NyRpVj_o" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/5591212639158810048/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=5591212639158810048" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/5591212639158810048?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/5591212639158810048?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/aT7NyRpVj_o/lava-lamp-995.html" title="Lava lamp - 99.5%" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_tlUbUg_x1Rk/Sjj6dLDZsqI/AAAAAAAAAA4/N-kVoxdrP8I/s72-c/lavalamp-box.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2009/06/lava-lamp-995.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU4EQX89eSp7ImA9WxJWEUU.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-956731024967204662</id><published>2009-06-16T23:29:00.003+02:00</published><updated>2009-06-16T23:31:40.161+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-16T23:31:40.161+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="buildbot" /><category scheme="http://www.blogger.com/atom/ns#" term="lavalamp" /><title>Lava lamps - 99% there</title><content type="html">The usb-board and wiring is finally connected and safely encased inside in a box!&lt;br /&gt;&lt;br /&gt;I'll go shop for lamps tomorrow and have pics up in a week or so. (Got much to do this weekend, as it's Midsummer holiday in Sweden.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-956731024967204662?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/4yP5UlGEu16WbwqWFy3084iggug/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4yP5UlGEu16WbwqWFy3084iggug/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/4yP5UlGEu16WbwqWFy3084iggug/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4yP5UlGEu16WbwqWFy3084iggug/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/QwVoKDEYVhI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/956731024967204662/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=956731024967204662" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/956731024967204662?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/956731024967204662?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/QwVoKDEYVhI/lava-lamps-99-there.html" title="Lava lamps - 99% there" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2009/06/lava-lamps-99-there.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU4HSXo8fip7ImA9WxJWEUU.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-2329370802832565140</id><published>2009-05-17T18:13:00.005+02:00</published><updated>2009-06-16T23:32:18.476+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-06-16T23:32:18.476+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="buildbot" /><category scheme="http://www.blogger.com/atom/ns#" term="lavalamp" /><title>Lava lamps - soon</title><content type="html">I just added Lava Lamp support to &lt;a href="http://bitbucket.org/marcusl/buildboticon"&gt;BuildbotIcon&lt;/a&gt; using the &lt;a href="http://www.phidgets.com/products.php?category=1&amp;amp;product_id=1014"&gt;Phidgets&lt;/a&gt; USB interface kit. (Bought from &lt;a href="http://www.active-robots.com/products/phidgets/phidgets-interface.shtml"&gt;Active-Robots UK&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;Can't wait to have it going in the office. I've got the code running, but I need some casing and wiring for it to be safe to connect to the 220V outlet.&lt;br /&gt;&lt;br /&gt;If you like it, click here:&lt;br /&gt;&lt;br /&gt;&lt;script type="text/javascript" src="http://www.ohloh.net/p/318990/widgets/project_users.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Of course, it's nothing compared to &lt;a href="http://blog.last.fm/2008/08/01/quality-control"&gt;Last.FM's setup&lt;/a&gt; but you have to start somewhere. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-2329370802832565140?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/CbnovmLi5unL12Dnpw2r3ZXOSRs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CbnovmLi5unL12Dnpw2r3ZXOSRs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/CbnovmLi5unL12Dnpw2r3ZXOSRs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CbnovmLi5unL12Dnpw2r3ZXOSRs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/BHACb347MFE" height="1" width="1"/&gt;</content><link rel="related" href="http://bitbucket.org/marcusl/buildboticon" title="Lava lamps - soon" /><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/2329370802832565140/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=2329370802832565140" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/2329370802832565140?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/2329370802832565140?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/BHACb347MFE/lava-lamps-soon.html" title="Lava lamps - soon" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2009/05/lava-lamps-soon.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcDSHY9cSp7ImA9Wx9TGEg.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-5409471059181994935</id><published>2009-04-01T00:38:00.005+02:00</published><updated>2010-11-27T12:24:39.869+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-27T12:24:39.869+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mobile" /><title>Smartphone retro gaming!</title><content type="html">Wohoo! Smartphones with touchscreen can run games properly!&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.spicypixel.com/web/page/morphgear/Home.aspx"&gt;Morphgear&lt;/a&gt; is an emulator platform for (amongst other) Windows Mobile. There are modules for NES, SNES and more available. You'll have to pay for it to play more than five minutes, but hey, it works and with &lt;a href="http://forum.xda-developers.com/showthread.php?t=489147"&gt;this amazing skin&lt;/a&gt; I've got myself a little gameboy thingy.&lt;br /&gt;
&lt;br /&gt;
And ROMs are amazingly small. (Super Mario Bros is 40 kb! I can add 200 000 of those on one SD card). The music brings me back.&lt;br /&gt;
&lt;br /&gt;
Woot woot. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-5409471059181994935?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/CfGQmlHVOt-QFbJQFc9hljGW6-M/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CfGQmlHVOt-QFbJQFc9hljGW6-M/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/CfGQmlHVOt-QFbJQFc9hljGW6-M/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CfGQmlHVOt-QFbJQFc9hljGW6-M/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/I_PhqhoUSWw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/5409471059181994935/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=5409471059181994935" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/5409471059181994935?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/5409471059181994935?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/I_PhqhoUSWw/smartphone-retro-gaming.html" title="Smartphone retro gaming!" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2009/04/smartphone-retro-gaming.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcCRXY_eCp7ImA9Wx9TGEg.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-3326490304982357079</id><published>2009-03-31T23:36:00.004+02:00</published><updated>2010-11-27T12:24:24.840+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-27T12:24:24.840+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="misc" /><title>Two good links</title><content type="html">Just for fun, but you really ought to read &lt;a href="http://www.sinfest.net/"&gt;SinFest&lt;/a&gt;. My favourite webcomic keeps getting better and better. New comic &lt;span style="font-style: italic;"&gt;every day&lt;/span&gt; since the start.&lt;br /&gt;
&lt;br /&gt;
Also, &lt;a href="http://www.brokenpicturetelephone.com/"&gt;Broken Picture Telephone&lt;/a&gt; is a very fun take on the old whispering game of miscommunication. Describe a picture, draw the description, repeat until satsified. See results. (The site has some problems, so you can't even connect to donate some times. Best to try it when the US is sleeping. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-3326490304982357079?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/XOp6IlU1LhqFHO5TGQnYnOr1LR0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/XOp6IlU1LhqFHO5TGQnYnOr1LR0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/XOp6IlU1LhqFHO5TGQnYnOr1LR0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/XOp6IlU1LhqFHO5TGQnYnOr1LR0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/CemTzl6FQwg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/3326490304982357079/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=3326490304982357079" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/3326490304982357079?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/3326490304982357079?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/CemTzl6FQwg/two-good-links.html" title="Two good links" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2009/03/two-good-links.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcNRno_fyp7ImA9Wx9TGEg.&quot;"><id>tag:blogger.com,1999:blog-4343580553277118310.post-4478724185498587483</id><published>2009-03-31T23:14:00.004+02:00</published><updated>2010-11-27T12:24:57.447+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-27T12:24:57.447+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mobile" /><category scheme="http://www.blogger.com/atom/ns#" term="windows" /><title>Making the smartphone smart, only €19.99</title><content type="html">My HTC Touch HD (a.k.a. Blackstone to you guys across the pond) is my first "Smartphone", and was reputedly an iPhone killer.&lt;br /&gt;
&lt;br /&gt;
It hasn't lived up to that. Not that I've owned an iPhone.. yet.. but it feels a bit clanky to use. And no games has worked well yet. Bah!&lt;br /&gt;
&lt;br /&gt;
But, since it's got 0.5 GHz, ~300 mb ram and 8 gb flash, it ought to be good at something. And I just found out that with &lt;a href="http://global.wmwifirouter.com/"&gt;WMWifiRouter&lt;/a&gt; it becomes an excellent 3g modem + wireless router (that can also play youtube videos in 800x480 :).&lt;br /&gt;
&lt;br /&gt;
This is an excellent piece of software. It installs smoothly, asks for some options, then gives me 6 buttons to start mapping between wifi, 3g, bluetooth and usb whichever way makes sense.&lt;br /&gt;
&lt;br /&gt;
It also monitors the battery's temp in case it overheats... Oookay. I suppose it's a good thing that it does, but it's like having a warning light + engine shutdown in your car in case the rear wheel nut is coming loose.&lt;br /&gt;
&lt;br /&gt;
Can't blame the program for that, though.&lt;br /&gt;
&lt;br /&gt;
I ended up with this because Vista fails to reco'nize my HTC as a PAN supporting bluetooth device. Pfft! My old GSM-only Nokia worked amazingly well (connect to network - bluetooth pan - presto), although it was hideously slow. Well, since it worked for the Nokia, I'll blame HTC this time around.&lt;br /&gt;
&lt;br /&gt;
Anyway, I'm glad that I can now access the net from my laptop _anywhere_. Very nice when on some trains that don't yet offer WiFi. (Most budget trains don't, and the only ones running to my parent's part of the country don't either... although they do have power outlets.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4343580553277118310-4478724185498587483?l=mackeblog.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/NvU0zfjrR5DO4oPX0EEE4pQnIy8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NvU0zfjrR5DO4oPX0EEE4pQnIy8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/NvU0zfjrR5DO4oPX0EEE4pQnIy8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NvU0zfjrR5DO4oPX0EEE4pQnIy8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/FdDGt/~4/seYIN7YSv-o" height="1" width="1"/&gt;</content><link rel="related" href="http://global.wmwifirouter.com/" title="Making the smartphone smart, only €19.99" /><link rel="replies" type="application/atom+xml" href="http://mackeblog.blogspot.com/feeds/4478724185498587483/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4343580553277118310&amp;postID=4478724185498587483" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/4478724185498587483?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4343580553277118310/posts/default/4478724185498587483?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/FdDGt/~3/seYIN7YSv-o/making-smartphone-smart-only-1999.html" title="Making the smartphone smart, only €19.99" /><author><name>Macke</name><uri>http://www.blogger.com/profile/06392128938508053935</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://4.bp.blogspot.com/_tlUbUg_x1Rk/TSUDFx-lD0I/AAAAAAAAADI/Y23nbBB9-Qw/S220/goomba_small.jpeg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mackeblog.blogspot.com/2009/03/making-smartphone-smart-only-1999.html</feedburner:origLink></entry></feed>

