<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<feed xmlns="http://www.w3.org/2005/Atom">

	<title>Planet Openbox</title>
	<link rel="self" href="http://planetob.openmonkey.com/atom.xml"/>
	<link href="http://planetob.openmonkey.com"/>
	<id>http://planetob.openmonkey.com/atom.xml</id>
	<updated>2012-02-05T13:30:16+00:00</updated>
	<generator uri="http://www.planetplanet.org/">Planet/2.0 +http://www.planetplanet.org</generator>

	<entry>
		<title type="html">Desligando (ou reiniciando) o computador via SSH (Secure Shell)</title>
		<link href="http://p0ng.com.br/post/16983539494"/>
		<id>http://p0ng.com.br/post/16983539494</id>
		<updated>2012-02-03T18:48:00+00:00</updated>
		<content type="html">&lt;p&gt;&lt;img src=&quot;http://media.tumblr.com/tumblr_lytypvv56c1qzljre.jpg&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Vejo que muitas pessoas acabam entrando no meu site querendo desligar ou reiniciar o computador via &lt;a href=&quot;http://pt.wikipedia.org/wiki/SSH&quot; target=&quot;_blank&quot;&gt;SSH&lt;/a&gt; e acabam indo parar em &lt;a href=&quot;http://p0ng.com.br/post/697986446/desligando-ou-reiniciando-o-computador-via-ts&quot; target=&quot;_blank&quot;&gt;outro post&lt;/a&gt;. Para acabar com as dúvidas, caso queira reiniciar (ou desligar) o computador em uma sessão SSH basta fazer:&lt;/p&gt;
&lt;p&gt;Para reiniciar:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;# reboot &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ou&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;# init 6&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;br /&gt;E para desligar:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;# halt&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ou&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;# init 0&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;br /&gt;É bom dar uma olhada nos comandos &lt;a href=&quot;http://www.ahinc.com/linux101/boot.htm#Shutdown&quot; target=&quot;_blank&quot;&gt;shutdown&lt;/a&gt; e na &lt;a href=&quot;http://www.ahinc.com/linux101/boot.htm#Using%20the%20INIT%20command&quot; target=&quot;_blank&quot;&gt;tabela de códigos do init&lt;/a&gt;.&lt;/p&gt;</content>
		<author>
			<name>Renato Santos</name>
			<uri>http://p0ng.com.br/</uri>
		</author>
		<source>
			<title type="html">site do p0ng</title>
			<link rel="self" href="http://p0ng.com.br/rss"/>
			<id>http://p0ng.com.br/rss</id>
			<updated>2012-02-05T13:30:13+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Watch out, or you'll end up in Pleasant Valley</title>
		<link href="http://shallowsky.com/blog/humor/pleasant-valley.html"/>
		<id>http://shallowsky.com/blog/humor/pleasant-valley.html</id>
		<updated>2012-02-03T01:30:14+00:00</updated>
		<content type="html">&lt;p&gt;
&lt;img src=&quot;http://shallowsky.com/blog/images/humor/pleasant.jpg&quot; align=&quot;right&quot; width=&quot;450&quot; height=&quot;375&quot; alt=&quot;[Pleasant Valley State Prison sign]&quot; /&gt;
I love this sign, along Interstate 5 near Coalinga.
&lt;b&gt;Pleasant Valley State Prison.&lt;/b&gt;
&lt;p&gt;
I guess if you have to be locked away, Pleasant Valley doesn't sound
like the worst place to be.
&lt;p&gt;
Do Pleasant Valley ex-cons have a hard time getting respect when
people find out where they did their hard time?
&lt;p&gt;
I love picturing the local parents trying to strike fear into
their kids' hearts.
&lt;i&gt;&quot;If you don't straighten up, Junior, you're going to end up in ...
PLEASANT VALLEY!&quot;&lt;/i&gt;
&lt;p&gt;
Or the local judges -- &lt;i&gt;&quot;You're not getting off this time. No, I'm
giving you ten years in ... PLEASANT VALLEY!&quot;&lt;/i&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;</content>
		<author>
			<name>Akkana Peck</name>
			<uri>http://shallowsky.com/blog</uri>
		</author>
		<source>
			<title type="html">Shallow Thoughts</title>
			<subtitle type="html">Akkana's Musings on Open Source Computing, Science, and Nature.</subtitle>
			<link rel="self" href="http://shallowsky.com/blog/index.rss"/>
			<id>http://shallowsky.com/blog/index.rss</id>
			<updated>2012-02-03T01:30:14+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Customising ActiveRecord's attribute formatting on inspect</title>
		<link href="http://feedproxy.google.com/~r/BlahBlahWoofWoof/~3/AWzN5OB4Igs/"/>
		<id>http://icelab.com.au/articles/customising-activerecords-attribute-formatting-on-inspect/</id>
		<updated>2012-02-02T13:30:35+00:00</updated>
		<content type="html">&lt;p&gt;We all know that you can change how a Ruby object is represented textually through the &lt;code&gt;inspect&lt;/code&gt; method. &lt;code&gt;ActiveRecord::Base&lt;/code&gt; provides a useful out-of-the-box implementation of &lt;code&gt;inspect&lt;/code&gt; that allows you to see the content of all of a record&amp;rsquo;s attributes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; Gig.last
=&amp;gt; #&amp;lt;Gig id: 123, name: &quot;ICELAB presents Ruby: A Rock Opera in 1.9.3 Thrilli...&quot;, starts_at: &quot;2012-03-03 09:30:00&quot;, capacity: 750, available_ticket_numbers: nil, sold_ticket_numbers: nil, created_at: &quot;2012-01-19 06:47:02&quot;, updated_at: &quot;2012-01-19 06:47:02&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What you might not know is that ActiveRecord provides a hook for you to customise how each of these attributes is formatted in this &lt;code&gt;inspect&lt;/code&gt; output. Let&amp;rsquo;s see how it is used in &lt;code&gt;ActiveRecord::Base#inspect&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Returns the contents of the record as a nicely formatted string.
def inspect
  attributes_as_nice_string = self.class.column_names.collect { |name|
    if has_attribute?(name) || new_record?
      &quot;#{name}: #{attribute_for_inspect(name)}&quot;
    end
  }.compact.join(&quot;, &quot;)
  &quot;#&amp;lt;#{self.class} #{attributes_as_nice_string}&amp;gt;&quot;
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You&amp;rsquo;ll see that it iterates over each of the attributes and passes them through &lt;code&gt;attribute_for_inspect(name)&lt;/code&gt;. This is also a public method that truncates a string if it is longer than 50 characters, shows dates in their DB-native UTC format, the otherwise just calls &lt;code&gt;inspect&lt;/code&gt; on whatever the attribute value is.&lt;/p&gt;

&lt;p&gt;Why would you want to customise this? We have an ActiveRecord with a few columns where we are serializing large arrays to the database&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Gig &amp;lt; ActiveRecord::Base
  serialize :available_ticket_numbers
  serialize :sold_ticket_numbers
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This can lead to some very messy console output:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; Gig.last
=&amp;gt; #&amp;lt;Gig id: 123, name: &quot;ICELAB presents Ruby: A Rock Opera in 1.9.3 Thrilli...&quot;, starts_at: &quot;2012-03-03 09:30:00&quot;, capacity: 750, available_ticket_numbers: nil, sold_ticket_numbers: [&quot;1&quot;, &quot;2&quot;, &quot;3&quot;, &quot;4&quot;, &quot;5&quot;, &quot;6&quot;, &quot;7&quot;, &quot;8&quot;, &quot;9&quot;, &quot;10&quot;, &quot;11&quot;, &quot;12&quot;, &quot;13&quot;, &quot;14&quot;, &quot;15&quot;, &quot;16&quot;, &quot;17&quot;, &quot;18&quot;, &quot;19&quot;, &quot;20&quot;, &quot;21&quot;, &quot;22&quot;, &quot;23&quot;, &quot;24&quot;, &quot;25&quot;, &quot;26&quot;, &quot;27&quot;, &quot;28&quot;, &quot;29&quot;, &quot;30&quot;, &quot;31&quot;, &quot;32&quot;, &quot;33&quot;, &quot;34&quot;, &quot;35&quot;, &quot;36&quot;, &quot;37&quot;, &quot;38&quot;, &quot;39&quot;, &quot;40&quot;, &quot;41&quot;, &quot;42&quot;, &quot;43&quot;, &quot;44&quot;, &quot;45&quot;, &quot;46&quot;, &quot;47&quot;, &quot;48&quot;, &quot;49&quot;, &quot;50&quot;, &quot;51&quot;, &quot;52&quot;, &quot;53&quot;, &quot;54&quot;, &quot;55&quot;, &quot;56&quot;, &quot;57&quot;, &quot;58&quot;, &quot;59&quot;, &quot;60&quot;, &quot;61&quot;, &quot;62&quot;, &quot;63&quot;, &quot;64&quot;, &quot;65&quot;, &quot;66&quot;, &quot;67&quot;, &quot;68&quot;, &quot;69&quot;, &quot;70&quot;, &quot;71&quot;, &quot;72&quot;, &quot;73&quot;, &quot;74&quot;, &quot;75&quot;, &quot;76&quot;, &quot;77&quot;, &quot;78&quot;, &quot;79&quot;, &quot;80&quot;, &quot;81&quot;, &quot;82&quot;, &quot;83&quot;, &quot;84&quot;, &quot;85&quot;, &quot;86&quot;, &quot;87&quot;, &quot;88&quot;, &quot;89&quot;, &quot;90&quot;, &quot;91&quot;, &quot;92&quot;, &quot;93&quot;, &quot;94&quot;, &quot;95&quot;, &quot;96&quot;, &quot;97&quot;, &quot;98&quot;, &quot;99&quot;, &quot;100&quot;, &quot;101&quot;, &quot;102&quot;, &quot;103&quot;, &quot;104&quot;, &quot;105&quot;, &quot;106&quot;, &quot;107&quot;, &quot;108&quot;, &quot;109&quot;, &quot;110&quot;, &quot;111&quot;, &quot;112&quot;, &quot;113&quot;, &quot;114&quot;, &quot;115&quot;, &quot;116&quot;, &quot;117&quot;, &quot;118&quot;, &quot;119&quot;, &quot;120&quot;, &quot;121&quot;, &quot;122&quot;, &quot;123&quot;, &quot;124&quot;, &quot;125&quot;, &quot;126&quot;, &quot;127&quot;, &quot;128&quot;, &quot;129&quot;, &quot;130&quot;, &quot;131&quot;, &quot;132&quot;, &quot;133&quot;, &quot;134&quot;, &quot;135&quot;, &quot;136&quot;, &quot;137&quot;, &quot;138&quot;, &quot;139&quot;, &quot;140&quot;, &quot;141&quot;, &quot;142&quot;, &quot;143&quot;, &quot;144&quot;, &quot;145&quot;, &quot;146&quot;, &quot;147&quot;, &quot;148&quot;, &quot;149&quot;, &quot;150&quot;, &quot;151&quot;, &quot;152&quot;, &quot;153&quot;, &quot;154&quot;, &quot;155&quot;, &quot;156&quot;, &quot;157&quot;, &quot;158&quot;, &quot;159&quot;, &quot;160&quot;, &quot;161&quot;, &quot;162&quot;, &quot;163&quot;, &quot;164&quot;, &quot;165&quot;, &quot;166&quot;, &quot;167&quot;, &quot;168&quot;, &quot;169&quot;, &quot;170&quot;, &quot;171&quot;, &quot;172&quot;, &quot;173&quot;, &quot;174&quot;, &quot;175&quot;, &quot;176&quot;, &quot;177&quot;, &quot;178&quot;, &quot;179&quot;, &quot;180&quot;, &quot;181&quot;, &quot;182&quot;, &quot;183&quot;, &quot;184&quot;, &quot;185&quot;, &quot;186&quot;, &quot;187&quot;, &quot;188&quot;, &quot;189&quot;, &quot;190&quot;, &quot;191&quot;, &quot;192&quot;, &quot;193&quot;, &quot;194&quot;, &quot;195&quot;, &quot;196&quot;, &quot;197&quot;, &quot;198&quot;, &quot;199&quot;, &quot;200&quot;, &quot;201&quot;, &quot;202&quot;, &quot;203&quot;, &quot;204&quot;, &quot;205&quot;, &quot;206&quot;, &quot;207&quot;, &quot;208&quot;, &quot;209&quot;, &quot;210&quot;, &quot;211&quot;, &quot;212&quot;, &quot;213&quot;, &quot;214&quot;, &quot;215&quot;, &quot;216&quot;, &quot;217&quot;, &quot;218&quot;, &quot;219&quot;, &quot;220&quot;, &quot;221&quot;, &quot;222&quot;, &quot;223&quot;, &quot;224&quot;, &quot;225&quot;, &quot;226&quot;, &quot;227&quot;, &quot;228&quot;, &quot;229&quot;, &quot;230&quot;, &quot;231&quot;, &quot;232&quot;, &quot;233&quot;, &quot;234&quot;, &quot;235&quot;, &quot;236&quot;, &quot;237&quot;, &quot;238&quot;, &quot;239&quot;, &quot;240&quot;, &quot;241&quot;, &quot;242&quot;, &quot;243&quot;, &quot;244&quot;, &quot;245&quot;, &quot;246&quot;, &quot;247&quot;, &quot;248&quot;, &quot;249&quot;, &quot;250&quot;, &quot;251&quot;, &quot;252&quot;, &quot;253&quot;, &quot;254&quot;, &quot;255&quot;, &quot;256&quot;, &quot;257&quot;, &quot;258&quot;, &quot;259&quot;, &quot;260&quot;, &quot;261&quot;, &quot;262&quot;, &quot;263&quot;, &quot;264&quot;, &quot;265&quot;, &quot;266&quot;, &quot;267&quot;, &quot;268&quot;, &quot;269&quot;, &quot;270&quot;, &quot;271&quot;, &quot;272&quot;, &quot;273&quot;, &quot;274&quot;, &quot;275&quot;, &quot;276&quot;, &quot;277&quot;, &quot;278&quot;, &quot;279&quot;, &quot;280&quot;, &quot;281&quot;, &quot;282&quot;, &quot;283&quot;, &quot;284&quot;, &quot;285&quot;, &quot;286&quot;, &quot;287&quot;, &quot;288&quot;, &quot;289&quot;, &quot;290&quot;, &quot;291&quot;, &quot;292&quot;, &quot;293&quot;, &quot;294&quot;, &quot;295&quot;, &quot;296&quot;, &quot;297&quot;, &quot;298&quot;, &quot;299&quot;, &quot;300&quot;, &quot;301&quot;, &quot;302&quot;, &quot;303&quot;, &quot;304&quot;, &quot;305&quot;, &quot;306&quot;, &quot;307&quot;, &quot;308&quot;, &quot;309&quot;, &quot;310&quot;, &quot;311&quot;, &quot;312&quot;, &quot;313&quot;, &quot;314&quot;, &quot;315&quot;, &quot;316&quot;, &quot;317&quot;, &quot;318&quot;, &quot;319&quot;, &quot;320&quot;, &quot;321&quot;, &quot;322&quot;, &quot;323&quot;, &quot;324&quot;, &quot;325&quot;, &quot;326&quot;, &quot;327&quot;, &quot;328&quot;, &quot;329&quot;, &quot;330&quot;, &quot;331&quot;, &quot;332&quot;, &quot;333&quot;, &quot;334&quot;, &quot;335&quot;, &quot;336&quot;, &quot;337&quot;, &quot;338&quot;, &quot;339&quot;, &quot;340&quot;, &quot;341&quot;, &quot;342&quot;, &quot;343&quot;, &quot;344&quot;, &quot;345&quot;, &quot;346&quot;, &quot;347&quot;, &quot;348&quot;, &quot;349&quot;, &quot;350&quot;, &quot;351&quot;, &quot;352&quot;, &quot;353&quot;, &quot;354&quot;, &quot;355&quot;, &quot;356&quot;, &quot;357&quot;, &quot;358&quot;, &quot;359&quot;, &quot;360&quot;, &quot;361&quot;, &quot;362&quot;, &quot;363&quot;, &quot;364&quot;, &quot;365&quot;, &quot;366&quot;, &quot;367&quot;, &quot;368&quot;, &quot;369&quot;, &quot;370&quot;, &quot;371&quot;, &quot;372&quot;, &quot;373&quot;, &quot;374&quot;, &quot;375&quot;, &quot;376&quot;, &quot;377&quot;, &quot;378&quot;, &quot;379&quot;, &quot;380&quot;, &quot;381&quot;, &quot;382&quot;, &quot;383&quot;, &quot;384&quot;, &quot;385&quot;, &quot;386&quot;, &quot;387&quot;, &quot;388&quot;, &quot;389&quot;, &quot;390&quot;, &quot;391&quot;, &quot;392&quot;, &quot;393&quot;, &quot;394&quot;, &quot;395&quot;, &quot;396&quot;, &quot;397&quot;, &quot;398&quot;, &quot;399&quot;, &quot;400&quot;, &quot;401&quot;, &quot;402&quot;, &quot;403&quot;, &quot;404&quot;, &quot;405&quot;, &quot;406&quot;, &quot;407&quot;, &quot;408&quot;, &quot;409&quot;, &quot;410&quot;, &quot;411&quot;, &quot;412&quot;, &quot;413&quot;, &quot;414&quot;, &quot;415&quot;, &quot;416&quot;, &quot;417&quot;, &quot;418&quot;, &quot;419&quot;, &quot;420&quot;, &quot;421&quot;, &quot;422&quot;, &quot;423&quot;, &quot;424&quot;, &quot;425&quot;, &quot;426&quot;, &quot;427&quot;, &quot;428&quot;, &quot;429&quot;, &quot;430&quot;, &quot;431&quot;, &quot;432&quot;, &quot;433&quot;, &quot;434&quot;, &quot;435&quot;, &quot;436&quot;, &quot;437&quot;, &quot;438&quot;, &quot;439&quot;, &quot;440&quot;, &quot;441&quot;, &quot;442&quot;, &quot;443&quot;, &quot;444&quot;, &quot;445&quot;, &quot;446&quot;, &quot;447&quot;, &quot;448&quot;, &quot;449&quot;, &quot;450&quot;, &quot;451&quot;, &quot;452&quot;, &quot;453&quot;, &quot;454&quot;, &quot;455&quot;, &quot;456&quot;, &quot;457&quot;, &quot;458&quot;, &quot;459&quot;, &quot;460&quot;, &quot;461&quot;, &quot;462&quot;, &quot;463&quot;, &quot;464&quot;, &quot;465&quot;, &quot;466&quot;, &quot;467&quot;, &quot;468&quot;, &quot;469&quot;, &quot;470&quot;, &quot;471&quot;, &quot;472&quot;, &quot;473&quot;, &quot;474&quot;, &quot;475&quot;, &quot;476&quot;, &quot;477&quot;, &quot;478&quot;, &quot;479&quot;, &quot;480&quot;, &quot;481&quot;, &quot;482&quot;, &quot;483&quot;, &quot;484&quot;, &quot;485&quot;, &quot;486&quot;, &quot;487&quot;, &quot;488&quot;, &quot;489&quot;, &quot;490&quot;, &quot;491&quot;, &quot;492&quot;, &quot;493&quot;, &quot;494&quot;, &quot;495&quot;, &quot;496&quot;, &quot;497&quot;, &quot;498&quot;, &quot;499&quot;, &quot;500&quot;, &quot;501&quot;, &quot;502&quot;, &quot;503&quot;, &quot;504&quot;, &quot;505&quot;, &quot;506&quot;, &quot;507&quot;, &quot;508&quot;, &quot;509&quot;, &quot;510&quot;, &quot;511&quot;, &quot;512&quot;, &quot;513&quot;, &quot;514&quot;, &quot;515&quot;, &quot;516&quot;, &quot;517&quot;, &quot;518&quot;, &quot;519&quot;, &quot;520&quot;, &quot;521&quot;, &quot;522&quot;, &quot;523&quot;, &quot;524&quot;, &quot;525&quot;, &quot;526&quot;, &quot;527&quot;, &quot;528&quot;, &quot;529&quot;, &quot;530&quot;, &quot;531&quot;, &quot;532&quot;, &quot;533&quot;, &quot;534&quot;, &quot;535&quot;, &quot;536&quot;, &quot;537&quot;, &quot;538&quot;, &quot;539&quot;, &quot;540&quot;, &quot;541&quot;, &quot;542&quot;, &quot;543&quot;, &quot;544&quot;, &quot;545&quot;, &quot;546&quot;, &quot;547&quot;, &quot;548&quot;, &quot;549&quot;, &quot;550&quot;, &quot;551&quot;, &quot;552&quot;, &quot;553&quot;, &quot;554&quot;, &quot;555&quot;, &quot;556&quot;, &quot;557&quot;, &quot;558&quot;, &quot;559&quot;, &quot;560&quot;, &quot;561&quot;, &quot;562&quot;, &quot;563&quot;, &quot;564&quot;, &quot;565&quot;, &quot;566&quot;, &quot;567&quot;, &quot;568&quot;, &quot;569&quot;, &quot;570&quot;, &quot;571&quot;, &quot;572&quot;, &quot;573&quot;, &quot;574&quot;, &quot;575&quot;, &quot;576&quot;, &quot;577&quot;, &quot;578&quot;, &quot;579&quot;, &quot;580&quot;, &quot;581&quot;, &quot;582&quot;, &quot;583&quot;, &quot;584&quot;, &quot;585&quot;, &quot;586&quot;, &quot;587&quot;, &quot;588&quot;, &quot;589&quot;, &quot;590&quot;, &quot;591&quot;, &quot;592&quot;, &quot;593&quot;, &quot;594&quot;, &quot;595&quot;, &quot;596&quot;, &quot;597&quot;, &quot;598&quot;, &quot;599&quot;, &quot;600&quot;, &quot;601&quot;, &quot;602&quot;, &quot;603&quot;, &quot;604&quot;, &quot;605&quot;, &quot;606&quot;, &quot;607&quot;, &quot;608&quot;, &quot;609&quot;, &quot;610&quot;, &quot;611&quot;, &quot;612&quot;, &quot;613&quot;, &quot;614&quot;, &quot;615&quot;, &quot;616&quot;, &quot;617&quot;, &quot;618&quot;, &quot;619&quot;, &quot;620&quot;, &quot;621&quot;, &quot;622&quot;, &quot;623&quot;, &quot;624&quot;, &quot;625&quot;, &quot;626&quot;, &quot;627&quot;, &quot;628&quot;, &quot;629&quot;, &quot;630&quot;, &quot;631&quot;, &quot;632&quot;, &quot;633&quot;, &quot;634&quot;, &quot;635&quot;, &quot;636&quot;, &quot;637&quot;, &quot;638&quot;, &quot;639&quot;, &quot;640&quot;, &quot;641&quot;, &quot;642&quot;, &quot;643&quot;, &quot;644&quot;, &quot;645&quot;, &quot;646&quot;, &quot;647&quot;, &quot;648&quot;, &quot;649&quot;, &quot;650&quot;, &quot;651&quot;, &quot;652&quot;, &quot;653&quot;, &quot;654&quot;, &quot;655&quot;, &quot;656&quot;, &quot;657&quot;, &quot;658&quot;, &quot;659&quot;, &quot;660&quot;, &quot;661&quot;, &quot;662&quot;, &quot;663&quot;, &quot;664&quot;, &quot;665&quot;, &quot;666&quot;, &quot;667&quot;, &quot;668&quot;, &quot;669&quot;, &quot;670&quot;, &quot;671&quot;, &quot;672&quot;, &quot;673&quot;, &quot;674&quot;, &quot;675&quot;, &quot;676&quot;, &quot;677&quot;, &quot;678&quot;, &quot;679&quot;, &quot;680&quot;, &quot;681&quot;, &quot;682&quot;, &quot;683&quot;, &quot;684&quot;, &quot;685&quot;, &quot;686&quot;, &quot;687&quot;, &quot;688&quot;, &quot;689&quot;, &quot;690&quot;, &quot;691&quot;, &quot;692&quot;, &quot;693&quot;, &quot;694&quot;, &quot;695&quot;, &quot;696&quot;, &quot;697&quot;, &quot;698&quot;, &quot;699&quot;, &quot;700&quot;, &quot;701&quot;, &quot;702&quot;, &quot;703&quot;, &quot;704&quot;, &quot;705&quot;, &quot;706&quot;, &quot;707&quot;, &quot;708&quot;, &quot;709&quot;, &quot;710&quot;, &quot;711&quot;, &quot;712&quot;, &quot;713&quot;, &quot;714&quot;, &quot;715&quot;, &quot;716&quot;, &quot;717&quot;, &quot;718&quot;, &quot;719&quot;, &quot;720&quot;, &quot;721&quot;, &quot;722&quot;, &quot;723&quot;, &quot;724&quot;, &quot;725&quot;, &quot;726&quot;, &quot;727&quot;, &quot;728&quot;, &quot;729&quot;, &quot;730&quot;, &quot;731&quot;, &quot;732&quot;, &quot;733&quot;, &quot;734&quot;, &quot;735&quot;, &quot;736&quot;, &quot;737&quot;, &quot;738&quot;, &quot;739&quot;, &quot;740&quot;, &quot;741&quot;, &quot;742&quot;, &quot;743&quot;, &quot;744&quot;, &quot;745&quot;, &quot;746&quot;, &quot;747&quot;, &quot;748&quot;, &quot;749&quot;, &quot;750&quot;, created_at: &quot;2012-01-19 06:47:02&quot;, updated_at: &quot;2012-01-19 06:47:02&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That&amp;rsquo;s a lot of noise. Most of the time, it just gets in the way when we&amp;rsquo;re trying to work with our records. If we ever wanted to inspect the content of such an attribute, we could just address it directly.&lt;/p&gt;

&lt;p&gt;To clean this up in one shot across our entire application, we can override &lt;code&gt;attribute_for_inspect&lt;/code&gt;. Put this in a file in &lt;code&gt;lib/&lt;/code&gt; somwhere and require it from your &lt;code&gt;config/application.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module ActiveRecord
  class Base
    alias_method :attribute_for_inspect_before_extension, :attribute_for_inspect
    def attribute_for_inspect(attr_name)
      value = read_attribute(attr_name)

      if value.kind_of?(Array) &amp;amp;&amp;amp; value.length &amp;gt; 4
        (value[0..1] + [&quot;... #{value.length - 4} elements ...&quot;] + value[-2..-1]).inspect
      else
        attribute_for_inspect_before_extension(attr_name)
      end
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This checks for any array attributes and gives them a shortened output if they contain more than five elements:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; Gig.last
=&amp;gt; #&amp;lt;Gig id: 123, name: &quot;ICELAB presents Ruby: A Rock Opera in 1.9.3 Thrilli...&quot;, starts_at: &quot;2012-03-03 09:30:00&quot;, capacity: 750, available_ticket_numbers: nil, sold_ticket_numbers: [&quot;1&quot;, &quot;2&quot;, &quot;... 746 elements ...&quot;, &quot;749&quot;, &quot;750&quot;], created_at: &quot;2012-01-19 06:47:02&quot;, updated_at: &quot;2012-01-19 06:47:02&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Much neater. We get tidier &lt;code&gt;inspect&lt;/code&gt; output without having to override ActiveRecord&amp;rsquo;s otherwise useful &lt;code&gt;inspect&lt;/code&gt; altogether. Depending on your app, I&amp;rsquo;d imagine you could extend it in many different ways to clean up your time on the console.&lt;/p&gt;
&lt;img src=&quot;http://feeds.feedburner.com/~r/BlahBlahWoofWoof/~4/AWzN5OB4Igs&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>Tim Riley</name>
			<uri>http://openmonkey.com/</uri>
		</author>
		<source>
			<title type="html">Tim Riley</title>
			<link rel="self" href="http://feeds.feedburner.com/BlahBlahWoofWoof"/>
			<id>http://openmonkey.com</id>
			<updated>2012-02-02T13:30:35+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Programa do Mução - A laje da casa de Will (30/01/2012)</title>
		<link href="http://p0ng.com.br/post/16778584908"/>
		<id>http://p0ng.com.br/post/16778584908</id>
		<updated>2012-01-30T21:48:00+00:00</updated>
		<content type="html">&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Programa do Mução - A laje da casa de Will (30/01/2012)&lt;/p&gt;</content>
		<author>
			<name>Renato Santos</name>
			<uri>http://p0ng.com.br/</uri>
		</author>
		<source>
			<title type="html">site do p0ng</title>
			<link rel="self" href="http://p0ng.com.br/rss"/>
			<id>http://p0ng.com.br/rss</id>
			<updated>2012-02-05T13:30:13+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Arduino Air Swimmers Shark</title>
		<link href="http://shallowsky.com/blog/hardware/arduino-shark.html"/>
		<id>http://shallowsky.com/blog/hardware/arduino-shark.html</id>
		<updated>2012-01-27T20:30:33+00:00</updated>
		<content type="html">&lt;img src=&quot;http://shallowsky.com/blog/images/arduino/Air-Swimmers-TM-Radio-Controlled-Flying-Shark.jpg&quot; align=&quot;right&quot; width=&quot;250&quot; height=&quot;244&quot; alt=&quot;[Air swimmers shark]&quot; /&gt;
&lt;p&gt;
When SCALE approved my talk proposal,
&lt;a href=&quot;http://www.socallinuxexpo.org/scale10x/presentations/fun-linux-and-devices&quot;&gt;Fun
with Linux and Devices&lt;/a&gt;, I had a challenge: I needed some good,
visual Arduino demos that would work in front of an audience.
&lt;p&gt;
In particular, I wanted something that moved. A little toy truck?
A moving penguin? A rotating sunflower? I fiddled with this and that,
not fully satisfied with anything. And then suddenly I realized what I needed.
Something cool. Something BIG.
Something I'd been wanting an excuse to buy anyway.
&lt;p&gt;
An &lt;a href=&quot;http://www.amazon.com/exec/obidos/ASIN/B005FYEAJ8/shallowsky-20&quot;&gt;Air Swimmers Shark&lt;/a&gt;.
&lt;p&gt;
I'd seen these things on video, but never in person. They're available
all over, even on Amazon, so I put in an order there and got a shark
in a few days.
&lt;p&gt;
These things are ridiculous and cool. It's huge, about 5 feet long,
and filled with helium. It takes maybe half an hour to assemble.
It has a small motor to beat the tail, an infrared transmitter,
and a weighted receiver that moves back and forth on a track to tilt
the fish up or down as it swims.
&lt;p&gt;
Once it's assembled, you can get it filled with helium at a party
store (which costs $3 to $6 depending on where you go).
Once the shark is filled, you add clay as ballast until the shark is
neutrally buoyant, neither rising nor sinking. It's quite sensitive:
you'll find yourself needing to add or remove pea-sized chunks of clay
as the temperature in the room changes, but being a little over- or
under-ballasted doesn't hurt it much.
With its tail beating, the shark really does look like it's swimming
through the air.
&lt;p&gt;
My shark is named Bruce, after the mechanical shark used for the movie
&quot;Jaws&quot;. My Bruce, I'm happy to say, has been much more tractable than
his famously intemperate namesake.
&lt;p&gt;
Okay, now how do we turn this ridiculous-but-cool thing into an Arduino
project?

&lt;h3&gt;Hacking the transmitter&lt;/h3&gt;

&lt;a href=&quot;http://shallowsky.com/arduino/slides/pix/shark/img_5238.jpg&quot;&gt;
&lt;img src=&quot;http://shallowsky.com/blog/images/arduino/img_5238.jpg&quot; align=&quot;right&quot; border=&quot;2&quot; width=&quot;250&quot; height=&quot;192&quot; alt=&quot;[Air Swimmers IR transmitter, front]&quot; /&gt;&lt;/a&gt;
&lt;p&gt;
There were two possible approaches. First, mount an Arduino directly
on the shark, and let it be totally self-directed. Second, patch the
Arduino into the shark's transmitter and control it from Linux.
I chose the second option, for several reasons. First, I was fairly
sure it would be easier, and less invasive (the shark would still be
usable with manual control). I also liked the idea of keeping the
transmitter as a manual override, in case my control program didn't
work right. Finally, I liked the idea of keeping a Linux machine in the
loop -- the shark would actually be controlled by Linux, not just by
the Arduino.
&lt;p&gt;
So the first thing I did was take the transmitter apart (4 Philips screws).
Inside are 4 pushbuttons, for right, left, up, and down, and the circuit
board is nice and simple. Whew -- this might be doable!
&lt;br clear=&quot;all&quot; /&gt;

&lt;a href=&quot;http://shallowsky.com/arduino/slides/pix/shark/img_5245.jpg&quot;&gt;
&lt;img src=&quot;http://shallowsky.com/blog/images/arduino/img_5245.jpg&quot; align=&quot;left&quot; border=&quot;2&quot; width=&quot;250&quot; height=&quot;210&quot; alt=&quot;[Air Swimmers IR transmitter, back]&quot; /&gt;&lt;/a&gt;
&lt;p&gt;
Four more screws and I had access to the back of the board, which was
equally simple.  Now I could get my voltmeter on the contacts while I
pushed buttons. 
&lt;p&gt;
It turned out the contacts (indicated with arrows on the photo) on the
downstream side of each switch were normally high (4.5 volts -- the transmitter
uses 3 AAA batteries). When I pushed the button, the contact went to ground.
Okay, so what I needed was some way for the Arduino to ground those
contacts at will.
&lt;p&gt;
First I needed to solder some wires to the contacts.
(How do you tell which side of the pushbutton is the one you need to solder?
Well, one side changes voltage when you press the button, and the other
side stays constant. The one that changes is the one you need to connect
to the Arduino, so the Arduino can change it too.)
&lt;p&gt;
I figured I needed 6 wires: ground, power, and one for each switch.
(It turned out I didn't need the power wire, but I figured it didn't
hurt to include it just in case.)
I wanted to have a nice small connector on the side of the transmitter,
but I couldn't find any 6-pin connectors that didn't look big and bulky,
so I gave up and decided I'd just let my ribbon cable dangle from the
transmitter. If I got a nice multi-colored one, maybe it would look festive.
&lt;p&gt;
I couldn't find any 6-conductor ribbon cable, so I got a
wider one and separated 6 wires from the rest. Then I soldered the
six wires to the appropriate places (marked by arrows in the photo).
On the other end, I tinned the six wires with solder so I could plug
the stranded wires into my breadboard.

&lt;h3&gt;Simulating button presses&lt;/h3&gt;
&lt;p&gt;
I've done enough reading to know of three ways to simulate a button press.
You can put a relay between the two contacts of the switch; you can do
the same thing, but with an optocoupler (opto-isolator) instead of a relay;
or you can do some magic with a transistor. I was fuzzy on the
transistor magic bit, so a relay sounded easiest. 
&lt;p&gt;
I played around with a relay and a spare switch and convinced myself I
knew how to wire them up. Then it was off to my local parts store to
buy four matched relays small enough to fit on my little mini breadboard.
&lt;p&gt;
There followed a several-day fiasco wherein I bought lots of relays
that turned out not to be suitable, and got increasingly frustrated at
how large and clunky all the available relays were.
There are smaller ones, but I couldn't get them to work.
And I learned that relays mostly come without documentation on which
pin does which, so there's a lot of experimenting with each new type.
&lt;p&gt;
Frustrated, I tried some optocouplers I'd bought on a whim last year.
No dice ... couldn't get them to work either.

&lt;a href=&quot;http://shallowsky.com/arduino/slides/pix/shark/img_5246.jpg&quot;&gt;
&lt;img src=&quot;http://shallowsky.com/blog/images/arduino/img_5246.jpg&quot; align=&quot;right&quot; border=&quot;2&quot; width=&quot;249&quot; height=&quot;194&quot; alt=&quot;[testing my transistor circuit]&quot; /&gt;&lt;/a&gt;
&lt;p&gt;
Desperate, I turned to IRC, #arduino on Freenode. The folks there are
mostly electronics wizards, and I'm sure my questions must have seemed
very dumb, but they were patient with me, and pointed me toward
a very simple circuit,
&lt;a href=&quot;http://www.techshire.com/freebies/LED4dummies_images/LEDNPN.jpg&quot;&gt;LED4dummies&lt;/a&gt;,
that was just what I needed. (They also suggested
&lt;a href=&quot;http://en.wikipedia.org/wiki/Open_collector&quot;&gt;Wikipedia's Open
collector&lt;/a&gt; article, but I found that less clear.) 
&lt;p&gt;
It took me some
experimenting with a transistor, an LED and a couple of resistors
(I blew out a couple of transistors before I realized I had the R2 resistor
in the wrong place) but eventually I got it working, and felt confident
enough to try it with the real shark transmitter. The key was to simplify
the circuit so it had no extra parts, then once it was working, add more
parts to build it up to what I needed.
&lt;br clear=&quot;all&quot; /&gt;

&lt;a href=&quot;http://shallowsky.com/blog/images/arduino/sharkcircuit.svg&quot;&gt;
&lt;img src=&quot;http://shallowsky.com/blog/images/arduino/sharkcircuit.jpg&quot; align=&quot;left&quot; border=&quot;2&quot; width=&quot;250&quot; height=&quot;193&quot; alt=&quot;[Circuit for the Arduino-controlled Air Swimmers Shark]&quot; /&gt;&lt;/a&gt;
&lt;p&gt;
At left, the circuit I ended up with. For each button, I have one
transistor and one resistor (I don't need the second resistor from the
LED4dummies circuit, since that was just to keep the LED from burning out).

&lt;a href=&quot;http://shallowsky.com/arduino/slides/pix/shark/sharkboard.jpg&quot;&gt;
&lt;img src=&quot;http://shallowsky.com/blog/images/arduino/sharkboard.jpg&quot; align=&quot;right&quot; width=&quot;249&quot; height=&quot;191&quot; border=&quot;2&quot; alt=&quot;[testing my transistor circuit]&quot; /&gt;&lt;/a&gt;
&lt;p&gt;
At right is the circuit assembled on a mini-breadboard on top of the 
proto-shield.
Note that the ends of the ribbon cable are plugged in to a spare header I had
lying around; a header makes a passable connector, so I can plug it in
fairly easily right before a talk. The green and blue wires in the back
are going to Arduino digital output pins 3 through 6 (leaving 0 and 1
for serial I/O). The red wires go from the transistors back to the
ribbon cable wires that go to the shark's transmitter buttons.

&lt;h3&gt;The software side&lt;/h3&gt;
&lt;p&gt;
Now I could make the shark think I'd pressed a button on its transmitter.
How do I control that from Linux?
&lt;p&gt;
On the Arduino side, I wrote a simple program that reads and parses
commands coming over the USB cable. So from the computer, I might send
a line like &lt;code&gt;L 300&lt;/code&gt;, and the Arduino would &quot;press&quot; the Left
button for 300 milliseconds. I had already written something like this
for a couple of other Arduino programs. That program is
&lt;a href=&quot;http://shallowsky.com/software/arduino/sharkuino/shark.pde&quot;&gt;shark.pde&lt;/a&gt;.
&lt;p&gt;
On the Linux side, first I needed something that established a serial
connection and sent commands to the Arduino. I wrote a Python class
for that, 
&lt;a href=&quot;http://shallowsky.com/software/arduino/sharkuino/shark.py&quot;&gt;shark.py&lt;/a&gt;.
That let me send commands from the Python console to test the shark.
&lt;p&gt;
Then I needed something more visual, something I could show during a talk.
In particular, the shark doesn't swim unless someone's pressing left,
right, left, right buttons over and over. Of course I wanted the computer
to handle that part.
&lt;p&gt;
So I wrote a little Python-GTK application that keeps the shark swimming,
and lets me drag a mouse around to adjust its left/right up/down direction:
&lt;a href=&quot;http://shallowsky.com/software/arduino/sharkuino/sharkwindow&quot;&gt;sharkwindow&lt;/a&gt;.

&lt;p&gt;
Purely by coincidence, the week before SCALE, Scott Adams introduced a
roboshark character:
&lt;a href=&quot;http://dilbert.com/strips/comic/2012-01-09/&quot;&gt;Dilbert, Jan 11 2012&lt;/a&gt;.
Nice timing for the debut of my own roboshark!

&lt;p&gt;
Sadly, I don't have any photos or video of the shark in action.
But if you're a LWN subscriber, there's an article on my talk
with a couple of great pictures:
&lt;a href=&quot;http://lwn.net/Articles/477030/&quot;&gt;Robots rampage (in a
friendly way) at SCALE 10X&lt;/a&gt;.
And you can see my slides and notes at
&lt;a href=&quot;http://shallowsky.com/arduino/&quot;&gt;Arduino notes&lt;/a&gt;.

&lt;br clear=&quot;all&quot; /&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;</content>
		<author>
			<name>Akkana Peck</name>
			<uri>http://shallowsky.com/blog</uri>
		</author>
		<source>
			<title type="html">Shallow Thoughts</title>
			<subtitle type="html">Akkana's Musings on Open Source Computing, Science, and Nature.</subtitle>
			<link rel="self" href="http://shallowsky.com/blog/index.rss"/>
			<id>http://shallowsky.com/blog/index.rss</id>
			<updated>2012-02-03T01:30:14+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">São Roque, São Roque, São Roque!</title>
		<link href="http://p0ng.com.br/post/16473584753"/>
		<id>http://p0ng.com.br/post/16473584753</id>
		<updated>2012-01-25T18:55:47+00:00</updated>
		<content type="html">&lt;p&gt;&lt;img src=&quot;http://media.tumblr.com/tumblr_lydb7uNl051qzljre.jpg&quot; /&gt;&lt;br /&gt;&lt;br /&gt;Quem tem medo de cachorro vai entender.&lt;/p&gt;</content>
		<author>
			<name>Renato Santos</name>
			<uri>http://p0ng.com.br/</uri>
		</author>
		<source>
			<title type="html">site do p0ng</title>
			<link rel="self" href="http://p0ng.com.br/rss"/>
			<id>http://p0ng.com.br/rss</id>
			<updated>2012-02-05T13:30:13+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Programa do Mução - Carniça fazendo o bordão do Licurgo. Irre!</title>
		<link href="http://p0ng.com.br/post/16426517723"/>
		<id>http://p0ng.com.br/post/16426517723</id>
		<updated>2012-01-24T22:15:11+00:00</updated>
		<content type="html">&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Programa do Mução - Carniça fazendo o bordão do Licurgo. Irre!&lt;/p&gt;</content>
		<author>
			<name>Renato Santos</name>
			<uri>http://p0ng.com.br/</uri>
		</author>
		<source>
			<title type="html">site do p0ng</title>
			<link rel="self" href="http://p0ng.com.br/rss"/>
			<id>http://p0ng.com.br/rss</id>
			<updated>2012-02-05T13:30:13+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Novela “Passeontem”</title>
		<link href="http://p0ng.com.br/post/16425901697"/>
		<id>http://p0ng.com.br/post/16425901697</id>
		<updated>2012-01-24T22:04:45+00:00</updated>
		<content type="html">&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Novela “Passeontem”&lt;/p&gt;</content>
		<author>
			<name>Renato Santos</name>
			<uri>http://p0ng.com.br/</uri>
		</author>
		<source>
			<title type="html">site do p0ng</title>
			<link rel="self" href="http://p0ng.com.br/rss"/>
			<id>http://p0ng.com.br/rss</id>
			<updated>2012-02-05T13:30:13+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Corno, a gente se liga em você!</title>
		<link href="http://p0ng.com.br/post/16425728188"/>
		<id>http://p0ng.com.br/post/16425728188</id>
		<updated>2012-01-24T22:01:47+00:00</updated>
		<content type="html">&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Corno, a gente se liga em você!&lt;/p&gt;</content>
		<author>
			<name>Renato Santos</name>
			<uri>http://p0ng.com.br/</uri>
		</author>
		<source>
			<title type="html">site do p0ng</title>
			<link rel="self" href="http://p0ng.com.br/rss"/>
			<id>http://p0ng.com.br/rss</id>
			<updated>2012-02-05T13:30:13+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Render Single-Line Markdown Text with Redcarpet</title>
		<link href="http://feedproxy.google.com/~r/BlahBlahWoofWoof/~3/Yn5qImDnPKI/"/>
		<id>http://icelab.com.au/articles/render-single-line-markdown-text-with-redcarpet/</id>
		<updated>2012-01-24T00:00:00+00:00</updated>
		<content type="html">&lt;p&gt;At Icelab, we love &lt;a href=&quot;http://daringfireball.net/projects/markdown&quot;&gt;Markdown&lt;/a&gt;. We use it wherever we can for text formatting. In a web app, the obvious place for it is in large text areas, where we can allow complete freedom of formatting. Headers, paragraphs, lists, it&amp;rsquo;s all good.&lt;/p&gt;

&lt;p&gt;What about the formatting of text in single-line text fields? If our form entry is a single line, that&amp;rsquo;s usually how its text will be displayed in our interface. In this case, we probably want to avoid all the block-level elements that Markdown will let the user create.&lt;/p&gt;

&lt;p&gt;This is easy to do using &lt;a href=&quot;http://github.com/tanoku/redcarpet&quot;&gt;Redcarpet&lt;/a&gt;, a fantastic Markdown renderer for Ruby. It is fast and, importantly, it is modular: it allows us to define our own custom renderers. We can use this to create a renderer that ignores all the block-level Markdown elements. Put this somewhere in your Rails app (e.g., &lt;code&gt;lib/redcarpet_renderers.rb&lt;/code&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module Redcarpet
  module Render
    class HTMLWithoutBlockElements &amp;lt; HTML
      include SmartyPants

      def initialize(opts = {})
        opts[:tables] = false
        super(opts)
      end

      # Regular markdown, just ignore all the block-level elements

      def block_code(code, language)
        code
      end

      def block_quote(quote)
        quote
      end

      def block_html(raw_html)
        raw_html
      end

      def header(text, header_level)
        &quot;#{text} &quot;
      end

      def hrule
        &quot; &quot;
      end

      def list(contents, list_type)
        &quot; #{contents}&quot;
      end

      def list_item(text, list_type)
        &quot;* #{text}&quot;
      end

      def paragraph(text)
        text
      end

      # Span-level calls

      def linebreak
        &quot; &quot;
      end

      # Postprocessing: strip the newlines

      def postprocess(document)
        document.gsub(&quot;\n&quot;, ' ').strip
      end
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we can safely render the content from our single-line text fields using markdown. The user can still make things _emphasised_ or **bold** or even [linked](http://icelab.com.au/) and we don&amp;rsquo;t have to worry about unwanted block elements messing up our page layouts.&lt;/p&gt;

&lt;p&gt;To use this renderer, just throw something like the following into your &lt;code&gt;app/helpers/application_helper.rb&lt;/code&gt; file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module ApplicationHelper
  def markdown(text)
    renderer = Redcarpet::Render::HTML.new({
      :filter_html =&amp;gt; true,
      :hard_wrap =&amp;gt; true
    })
    markdown = Redcarpet::Markdown.new(renderer, {
      :autolink =&amp;gt; true,
      :no_intra_emphasis =&amp;gt; true
    })

    markdown.render(text).html_safe
  end

  def markdown_line(text)
    renderer = Redcarpet::Render::HTMLWithoutBlockElements.new({
      :filter_html =&amp;gt; true,
      :hard_wrap =&amp;gt; true
    })
    markdown = Redcarpet::Markdown.new(renderer, {
      :autolink =&amp;gt; true,
      :no_intra_emphasis =&amp;gt; true
    })

    markdown.render(text).html_safe
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And it&amp;rsquo;s now a helper ready for use in our page templates. For example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;item&quot;&amp;gt;
  &amp;lt;h3 class=&quot;name&quot;&amp;gt;&amp;lt;%= markdown_line(item.name) %&amp;gt;&amp;lt;/h3&amp;gt;
  &amp;lt;div class=&quot;description&quot;&amp;gt;
    &amp;lt;%= markdown(item.description) %&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The more Markdown we can use, the happier we are!&lt;/p&gt;
&lt;img src=&quot;http://feeds.feedburner.com/~r/BlahBlahWoofWoof/~4/Yn5qImDnPKI&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>Tim Riley</name>
			<uri>http://openmonkey.com/</uri>
		</author>
		<source>
			<title type="html">Tim Riley</title>
			<link rel="self" href="http://feeds.feedburner.com/BlahBlahWoofWoof"/>
			<id>http://openmonkey.com</id>
			<updated>2012-02-02T13:30:35+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">New Relic, Heroku and Rails Streaming Responses</title>
		<link href="http://feedproxy.google.com/~r/BlahBlahWoofWoof/~3/yez89jZHdzQ/"/>
		<id>http://icelab.com.au/articles/new-relic-heroku-and-rails-streaming-responses/</id>
		<updated>2012-01-20T00:00:00+00:00</updated>
		<content type="html">&lt;p&gt;For &lt;a href=&quot;http://cornerhotel.com/&quot;&gt;Ticketscout&amp;rsquo;s&lt;/a&gt; payment processing, we use a custom Rails action with an HTTP streaming response. It  shows the user a spinner and a &amp;ldquo;please wait&amp;rdquo; message, then periodically sends empty strings to the browser until the credit card transaction is completed. This streaming response keeps the request connection alive longer than the 30 second timeout period that is the default on the &lt;a href=&quot;http://devcenter.heroku.com/articles/request-timeout#cedar&quot;&gt;Heroku Cedar stack&lt;/a&gt;. The technique works well and ensures we don&amp;rsquo;t ever lose track of any slow-to-process credit card payments.&lt;/p&gt;

&lt;p&gt;During development, we found that the streaming responses on Heroku did not work if we had the &lt;a href=&quot;http://addons.heroku.com/newrelic&quot;&gt;New Relic add-on&lt;/a&gt; enabled. Instead of seeing the page content incrementally delivered while the request ran, we&amp;rsquo;d see nothing until the request completed, then all the content delivered at once.&lt;/p&gt;

&lt;p&gt;To deliver the feature on time, we simply disabled the add-on and released. Everything worked smoothly, but it was unnerving to run the app &amp;ldquo;blind&amp;rdquo; without New Relic&amp;rsquo;s useful metrics. This became especially problematic now that we&amp;rsquo;re wanting to pay some more attention to improving the app&amp;rsquo;s performance. I finally contacted New Relic support, and it turns out that a working solution is fairly simple: &lt;a href=&quot;http://newrelic.com/docs/ruby/real-user-monitoring-in-ruby&quot;&gt;disabling the real user monitoring&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Turns out that the real user monitoring is currently incompatible with streaming responses. I disabled the automatic instrumentation in my &lt;code&gt;newrelic.yml&lt;/code&gt; config file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;browser_monitoring:
  auto_instrument: false
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I also switched off the &amp;ldquo;Enable end user monitoring&amp;rdquo; setting in the &amp;ldquo;Settings &gt; Application&amp;rdquo; page. Then, after fresh deploy to Heroku, I re-enabled the add-on and we had both the metrics collection and streaming responses working together!&lt;/p&gt;

&lt;p&gt;Granted, we&amp;rsquo;ve lost access to some useful &lt;a href=&quot;http://newrelic.com/features/real-user-monitoring&quot;&gt;real user metrics&lt;/a&gt; (like network load, page rendering and DOM processing times), but it&amp;rsquo;s better to have some metrics than none at all!&lt;/p&gt;

&lt;p&gt;Down the track, we can probably get the best of both world&amp;rsquo;s by &lt;a href=&quot;http://newrelic.com/docs/ruby/real-user-monitoring-in-ruby&quot;&gt;manually enabling the real user monitoring instrumentation&lt;/a&gt; in all the pages layouts except those used for the streaming responses. Hopefully further down the track, the automatic instrumentation will be compatible with streaming responses out of the box. In the meantime, it&amp;rsquo;s good to have our &lt;a href=&quot;http://www.youtube.com/watch?v=V87I10yMIb4&quot;&gt;charts&lt;/a&gt; back!&lt;/p&gt;
&lt;img src=&quot;http://feeds.feedburner.com/~r/BlahBlahWoofWoof/~4/yez89jZHdzQ&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>Tim Riley</name>
			<uri>http://openmonkey.com/</uri>
		</author>
		<source>
			<title type="html">Tim Riley</title>
			<link rel="self" href="http://feeds.feedburner.com/BlahBlahWoofWoof"/>
			<id>http://openmonkey.com</id>
			<updated>2012-02-02T13:30:35+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Converting HTML pages into PDF</title>
		<link href="http://shallowsky.com/blog/programming/html-slides-to-pdf.html"/>
		<id>http://shallowsky.com/blog/programming/html-slides-to-pdf.html</id>
		<updated>2012-01-17T19:30:11+00:00</updated>
		<content type="html">&lt;p&gt;
I've long wanted a way of converting my HTML presentation slides to PDF.
Mostly because conference organizers tend to freak out at slides in any
format other than Open/Libre Office, Powerpoint or PDF. Too many times,
I've submitted a tarball of my slides and discovered they weren't even
listed on the conference site. (I ask you, in what way is a tarball
more difficult to deal with than an .odp file?) Slide-sharing websites
also have a limited set of formats they'll accept.
&lt;p&gt;
A year or so ago, I added screenshot capability to my webkit-based
 presentation program, 
&lt;a href=&quot;http://shallowsky.com/software/preso/&quot;&gt;Preso&lt;/a&gt;,
do &quot;screenshots&quot;, but I really needed PDF, not images.
&lt;p&gt;
Now, creating PDF from HTML shouldn't be that hard. Every browser has
a print function that can print to a PDF file. So why is it so hard
to create PDF from HTML in any kind of scriptable way?
&lt;p&gt;
After much searching and experimenting,
I finally found a Python code snippet that worked:
&lt;a href=&quot;http://notes.alexdong.com/xhtml-to-pdf-using-pyqt4-webkit-and-headless&quot;&gt;XHTML
to PDF using PyGTK4 Webkit&lt;/a&gt; from Alex Dong. It uses Python-Qt,
not GTK, so I can't integrate it into my Preso app, but that's okay --
a separate tool is just as good.
&lt;p&gt;
(I struggled to write an equivalent in PyGTK, but gave up due to the
complete lack of documentation of Python-Webkit-GTK, and not much
more for gtk.PrintOperation(). QWebView's documentation may not be
as complete as I'd like, but at least there is some.)

&lt;h3&gt;Printing from QtWebView to QPrinter&lt;/h3&gt;
&lt;p&gt;
Here are the important things I learned about QWebView from fiddling
around with Alex's code to adapt it to what I needed, which is
printing a list of pages to sequentially numbered files:
&lt;ul&gt;
&lt;li&gt;To print, you need to wait until the page has finished loading, 
  so connect a function to SIGNAL(&quot;loadFinished(bool)&quot;),
  then load(QUrl(url)).
&lt;li&gt;That loadFinished function remains registered, so as you load new
  pages, it will be called each time. So you can load() the next URL
  as the last step in your loadFinished callback.
&lt;li&gt;If you get confused about callbacks and connect more than one of
  them, bad things happen, and only the last page gets printed, or
  QApplication.exit() doesn't exit at all.
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;
Things I learned about QPrinter():
&lt;ul&gt;
&lt;li&gt;All the examples I found online set the page size with lines like
  QPrinter.setPageSize(QPrinter.A4) or setPaperSize(QPrinter.A4)
  (setPageSize is apparently deprecated in favor of setPaperSize); but
&lt;li&gt;If you want to set a specific size, you can do that with a line like
  &lt;code&gt;QPrinter.setPaperSize(QSizeF(1024, 768), QPrinter.DevicePixel)&lt;/code&gt;
  The second argument (DevicePixel) is a 
  &lt;a href=&quot;http://doc.qt.nokia.com/4.7-snapshot/qprinter.html#Unit-enum&quot;&gt;unit,
  from this list&lt;/a&gt;.
&lt;li&gt;That line gives you the right aspect ratio. But if you think
  &quot;DevicePixels&quot; means the size will correspond to pixels in your browser
  window (just because the documentation says so), you're sadly mistaken.
&lt;li&gt;If you want a PDF page that actually corresponds to the size of your
  browser window, you can get it by calling QWebView.setZoomFactor(z)
  You'll have to experiment to find the right value of z;
  I found I needed about 1.24 if I wanted to capture my
  full 1366x768 slides, or exactly 2.0 if I wanted to restrict the
  saved PDF to only the 1024x758 part that shows up in the projector.
&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;
Anyway, it's a little hacky with that empirical zoom factor ... but it works!
The program is here: 
&lt;a href=&quot;http://shallowsky.com/software/presentation/qhtmlprint&quot;&gt;qhtmlprint:
convert HTML to PDF using Qt Webkit&lt;/a&gt;.
&lt;p&gt;
And it does produce reasonable PDF, with the text properly vectorized,
not just raster screenshots of each page.

&lt;h3&gt;Printing the slides in the right order&lt;/h3&gt;
&lt;p&gt;
Terrific -- now I can feed a list of slides to qhtmlprint and get a
bunch of PDF files back. How do I print the right slides?
&lt;p&gt;
My slides are listed in order in an array inside a Javascript file,
one per line.
If I &lt;code&gt;grep .html navigate.js&lt;/code&gt;, I get a list like this:
&lt;pre&gt;
    &quot;arduino.html&quot;,
    &quot;img.html?pix/arduinos/arduino-clones.jpg&quot;,
    &quot;getting_started.html&quot;,
    &quot;img.html?pix/projects/led.jpg&quot;,
    //&quot;blink.html&quot;,
    &quot;arduino-ide.html&quot;,
&lt;/pre&gt;
&lt;p&gt;
To pass that to qhtmlprint, I only need to remove the commented-out lines
(the ones with //) and strip off the quotes and commas. I can do that
all in one command with a grep and sed pipeline:

&lt;pre&gt;
qhtmlprint ` fgrep .html navigate.js  | grep -v // | sed -e 's/&quot;,/&quot;/' -e 's/&quot;//g' `
&lt;/pre&gt;

&lt;p&gt;
And voia&amp;agrave;! I have a bunch of fileNNN.pdf files.

&lt;h3&gt;Creating a multi-page slide deck&lt;/h3&gt;
&lt;p&gt;
Okay, great! Now how do I stick those files all together into one
slide deck I can submit to conference organizers?

&lt;p&gt;
That part's easy -- Ghostscript can do it.

&lt;pre&gt;
gs -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE=slidedeck.pdf -dBATCH file*.pdf
&lt;/pre&gt;

&lt;p&gt;
And now &lt;i&gt;slidedeck.pdf&lt;/i&gt; contains my whole presentation, ready to go.&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;</content>
		<author>
			<name>Akkana Peck</name>
			<uri>http://shallowsky.com/blog</uri>
		</author>
		<source>
			<title type="html">Shallow Thoughts</title>
			<subtitle type="html">Akkana's Musings on Open Source Computing, Science, and Nature.</subtitle>
			<link rel="self" href="http://shallowsky.com/blog/index.rss"/>
			<id>http://shallowsky.com/blog/index.rss</id>
			<updated>2012-02-03T01:30:14+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Moira para XFCE</title>
		<link href="http://p0ng.com.br/post/15988140981"/>
		<id>http://p0ng.com.br/post/15988140981</id>
		<updated>2012-01-17T03:06:42+00:00</updated>
		<content type="html">&lt;p&gt;&lt;img src=&quot;http://media.tumblr.com/tumblr_lxx9tz1jgV1qzljre.png&quot; /&gt;&lt;br /&gt;&lt;br /&gt;Baseado em um outro tema meu, só que para &lt;a href=&quot;http://p0ngbr.deviantart.com/art/agt-for-Openbox-142241927&quot; target=&quot;_blank&quot;&gt;Openbox&lt;/a&gt;. O nome é inspiração de uma música da banda &lt;a href=&quot;http://www.madamesaatan.com&quot; target=&quot;_blank&quot;&gt;Madame Saatan&lt;/a&gt; (muito boa, por sinal).&lt;br /&gt;&lt;br /&gt;Download @ &lt;a href=&quot;http://p0ngbr.deviantart.com/art/Moira-for-XFCE-279849551&quot; target=&quot;_blank&quot;&gt;deviantART&lt;/a&gt;&lt;/p&gt;</content>
		<author>
			<name>Renato Santos</name>
			<uri>http://p0ng.com.br/</uri>
		</author>
		<source>
			<title type="html">site do p0ng</title>
			<link rel="self" href="http://p0ng.com.br/rss"/>
			<id>http://p0ng.com.br/rss</id>
			<updated>2012-02-05T13:30:13+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Perde quem?</title>
		<link href="http://p0ng.com.br/post/15870045077"/>
		<id>http://p0ng.com.br/post/15870045077</id>
		<updated>2012-01-15T05:11:56+00:00</updated>
		<content type="html">&lt;p&gt;&lt;img src=&quot;http://media.tumblr.com/tumblr_lxtqdmwbAL1qzljre.png&quot; /&gt;&lt;/p&gt;</content>
		<author>
			<name>Renato Santos</name>
			<uri>http://p0ng.com.br/</uri>
		</author>
		<source>
			<title type="html">site do p0ng</title>
			<link rel="self" href="http://p0ng.com.br/rss"/>
			<id>http://p0ng.com.br/rss</id>
			<updated>2012-02-05T13:30:13+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">HTML and Javascript Presentations</title>
		<link href="http://shallowsky.com/blog/speaking/html-preso.html"/>
		<id>http://shallowsky.com/blog/speaking/html-preso.html</id>
		<updated>2012-01-13T04:30:14+00:00</updated>
		<content type="html">&lt;p&gt;
When I give talks that need slides, I've been using my
&lt;a href=&quot;http://shallowsky.com/software/presentation/&quot;&gt;Slide
Presentations in HTML and JavaScript&lt;/a&gt; for many years.
I uploaded it in 2007 -- then left it there, without many updates.
&lt;p&gt;
But meanwhile, I've been giving lots of presentations, tweaking the code,
tweaking the CSS to make it display better. And every now and then I get
reminded that a few other people besides me are using this stuff.
&lt;p&gt;
For instance, around a year ago, I gave a talk where nearly all the
slides were just images. Silly to have to make a separate HTML file
to go with each image. Why not just have one file, img.html, that
can show different images? So I wrote some code that lets you go to
a URL like &lt;b&gt;img.html?pix/whizzyphoto.jpg&lt;/b&gt;, and it will display
it properly, and the Next and Previous slide links will still work.
&lt;p&gt;
Of course, I tweak this software mainly when I have a talk coming up.
I've been working lately on my SCALE talk, coming up on January 22:
&lt;a href=&quot;http://www.socallinuxexpo.org/scale10x/presentations/fun-linux-and-devices&quot;&gt;Fun
with Linux and Devices&lt;/a&gt; (be ready for some fun Arduino demos!)
Sometimes when I overload on talk preparation, I procrastinate
by hacking the software instead of the content of the actual talk.
So I've added some nice changes just in the past few weeks.
&lt;p&gt;
For instance, the speaker notes that remind me of where I am in
the talk and what's coming next. I didn't have any way to add notes on
image slides. But I need them on those slides, too -- so I added that.
&lt;p&gt;
Then I decided it was silly not to have some sort of automatic
reminder of what the next slide was. Why should I have to
put it in the speaker notes by hand? So that went in too.
&lt;p&gt;
And now I've done the less fun part -- collecting it all together and
documenting the new additions. So if you're using my HTML/JS slide
kit -- or if you think you might be interested in something like that
as an alternative to Powerpoint or Libre Office Presenter -- check
out the presentation I have explaining the package, including the
new features.
&lt;p&gt;
You can find it here:
&lt;a href=&quot;http://shallowsky.com/software/presentation/&quot;&gt;Slide
Presentations in HTML and JavaScript&lt;/a&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;</content>
		<author>
			<name>Akkana Peck</name>
			<uri>http://shallowsky.com/blog</uri>
		</author>
		<source>
			<title type="html">Shallow Thoughts</title>
			<subtitle type="html">Akkana's Musings on Open Source Computing, Science, and Nature.</subtitle>
			<link rel="self" href="http://shallowsky.com/blog/index.rss"/>
			<id>http://shallowsky.com/blog/index.rss</id>
			<updated>2012-02-03T01:30:14+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Novas cores no terminal</title>
		<link href="http://p0ng.com.br/post/15728995101"/>
		<id>http://p0ng.com.br/post/15728995101</id>
		<updated>2012-01-12T18:03:00+00:00</updated>
		<content type="html">&lt;p&gt;&lt;img src=&quot;http://media.tumblr.com/tumblr_lxp5avXAyz1qzljre.png&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Text color: #CCCCCC&lt;br /&gt;Bold color: #FFFFFF&lt;br /&gt;Background color: #121212&lt;br /&gt;&lt;br /&gt;#1: #484848&lt;br /&gt;#9: #909090&lt;br /&gt;&lt;br /&gt;#2: #C82727&lt;br /&gt;#10: #ED152A&lt;br /&gt;&lt;br /&gt;#3: #82B414&lt;br /&gt;#11: #B6E354&lt;br /&gt;&lt;br /&gt;#4: #FD971F&lt;br /&gt;#12: #FEED6C&lt;br /&gt;&lt;br /&gt;#5: #5664D6&lt;br /&gt;#13: #8C9EFF&lt;br /&gt;&lt;br /&gt;#6: #AC57B2&lt;br /&gt;#14: #F16FFE&lt;br /&gt;&lt;br /&gt;#7: #009DBF&lt;br /&gt;#15: #8BDAEE&lt;br /&gt;&lt;br /&gt;#8: #E0E0E0&lt;br /&gt;#16: #F8F8F2&lt;/p&gt;
&lt;/blockquote&gt;</content>
		<author>
			<name>Renato Santos</name>
			<uri>http://p0ng.com.br/</uri>
		</author>
		<source>
			<title type="html">site do p0ng</title>
			<link rel="self" href="http://p0ng.com.br/rss"/>
			<id>http://p0ng.com.br/rss</id>
			<updated>2012-02-05T13:30:13+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Scroll do Microsoft Wireless Mouse 5000 muito rápido?</title>
		<link href="http://p0ng.com.br/post/15655693200"/>
		<id>http://p0ng.com.br/post/15655693200</id>
		<updated>2012-01-11T03:58:00+00:00</updated>
		<content type="html">&lt;p&gt;&lt;img height=&quot;310&quot; src=&quot;http://www.microsoft.com/hardware/_base_v1/products/wireless-mouse-5000/mk_wm5000_large.jpg&quot; width=&quot;540&quot; /&gt;&lt;br /&gt;&lt;em&gt;Microsoft Wireless Mouse 5000&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Possui esse mouse e percebe que o &lt;em&gt;scroll&lt;/em&gt; (a rodinha) está mais rápida que o &lt;a href=&quot;http://www.youtube.com/watch?v=xluCL09KG9Y&quot; target=&quot;_blank&quot;&gt;meteóro de Pegasus&lt;/a&gt;? Basta desconectar o &lt;em&gt;transceiver&lt;/em&gt; USB e conectar novamente. Nem precisa reiniciar o PC.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;img src=&quot;http://media.tumblr.com/tumblr_lxm8b2XUo41qzljre.png&quot; /&gt;&lt;br /&gt;&lt;em&gt;Microsoft Wireless Transceiver&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;Algumas pessoas tiveram esse problema no Windows. No meu caso aconteceu no Linux. Acredito que a solução sirva para os dois sistemas. &lt;/p&gt;</content>
		<author>
			<name>Renato Santos</name>
			<uri>http://p0ng.com.br/</uri>
		</author>
		<source>
			<title type="html">site do p0ng</title>
			<link rel="self" href="http://p0ng.com.br/rss"/>
			<id>http://p0ng.com.br/rss</id>
			<updated>2012-02-05T13:30:13+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Parsing HTML in Python</title>
		<link href="http://shallowsky.com/blog/programming/parsing-html-python.html"/>
		<id>http://shallowsky.com/blog/programming/parsing-html-python.html</id>
		<updated>2012-01-08T22:30:12+00:00</updated>
		<content type="html">&lt;p&gt;
I've been having (mis)adventures learning about Python's various
options for parsing HTML.
&lt;p&gt;
Up until now, I've avoided doing any HTMl parsing
in my RSS reader &lt;a href=&quot;http://shallowsky.com/software/feedme/&quot;&gt;FeedMe&lt;/a&gt;.
I use regular expressions to find the places where content starts and
ends, and to screen out content like advertising, and to rewrite links.
Using regexps on HTML is generally considered to be a no-no, but it
didn't seem worth parsing the whole document just for those modest goals.
&lt;p&gt;
But I've long wanted to add support for downloading images, so you
could view the downloaded pages with their embedded images if you so chose.
That means not only identifying img tags and extracting their &lt;code&gt;src&lt;/code&gt;
attributes, but also rewriting the img tag afterward to point to the
locally stored image. It was time to learn how to parse HTML.
&lt;p&gt;
Since I'm forever seeing people flamed on the #python IRC channel for
using regexps on HTML, I figured real HTML parsing must be straightforward.
A quick web search led me to 
&lt;a href=&quot;http://docs.python.org/library/htmlparser.html&quot;&gt;Python's built-in 
HTMLParser class.&lt;/a&gt; It comes with a nice example for how to use it:
define a class that inherits from HTMLParser, then define
some functions it can call for things like handle_starttag and
handle_endtag; then call self.feed(). Something like this:

&lt;pre&gt;
from HTMLParser import HTMLParser

class MyFancyHTMLParser(HTMLParser):
  def fetch_url(self, url) :
    request = urllib2.Request(url)
    response = urllib2.urlopen(request)
    link = response.geturl()
    html = response.read()
    response.close()
    self.feed(html)   # feed() starts the HTMLParser parsing

  def handle_starttag(self, tag, attrs):
    if tag == 'img' :
      # attrs is a list of tuples, (attribute, value)
      srcindex = self.has_attr('src', attrs)
      if srcindex &amp;lt; 0 :
        return   # img with no src tag? skip it
      src = attrs[srcindex][1]
      # Make relative URLs absolute
      src = self.make_absolute(src)
      attrs[srcindex] = (attrs[srcindex][0], src)

    print '&amp;lt;' + tag
    for attr in attrs :
      print ' ' + attr[0]
      if len(attr) &amp;gt; 1 and type(attr[1]) == 'str' :
        # make sure attr[1] doesn't have any embedded double-quotes
        val = attr[1].replace('&quot;', '\&quot;')
        print '=&quot;' + val + '&quot;')
    print '&amp;gt;'

  def handle_endtag(self, tag):
    self.outfile.write('&amp;lt;/' + tag.encode(self.encoding) + '&amp;gt;\n')
&lt;/pre&gt;

&lt;p&gt;
Easy, right? Of course there are a lot more details, but the
basics are simple.
&lt;p&gt;
I coded it up and it didn't take long to get it downloading images
and changing img tags to point to them. Woohoo!
Whee!

&lt;h3&gt;The bad news about HTMLParser&lt;/h3&gt;
&lt;p&gt;
Except ... after using it a few days, I was hitting some weird errors.
In particular, this one:&lt;br /&gt;
&lt;code&gt;
HTMLParser.HTMLParseError: bad end tag: ''
&lt;/code&gt;
&lt;p&gt;
It comes from sites that have illegal content. For instance, stories
on Slate.com include Javascript lines like this one inside
&amp;lt;script&amp;gt;&amp;lt;/script&amp;gt; tags:&lt;br /&gt;
&lt;code&gt;document.write(&quot;&amp;lt;script type='text/javascript' src='whatever'&amp;gt;&amp;lt;/scr&quot; + &quot;ipt&amp;gt;&quot;);&lt;/code&gt;

&lt;p&gt;
This &lt;a href=&quot;http://bytes.com/topic/python/answers/495744-htmlparser-chokes-bad-end-tag-comment&quot;&gt;is
technically illegal html&lt;/a&gt; -- but lots of sites do it, so protesting
that it's technically illegal doesn't help if you're trying to read a 
real-world site.

&lt;p&gt;
Some discussions said setting
&lt;code&gt;self.CDATA_CONTENT_ELEMENTS = ()&lt;/code&gt; would help, but it didn't.
&lt;p&gt;
HTMLParser's code is in Python, not C. So I took a look at where the
errors are generated, thinking maybe I could override them.
It was easy enough to redefine &lt;code&gt;parse_endtag()&lt;/code&gt; to make it not throw
an error (I had to duplicate some internal strings too). But then I
hit another error, so I redefined &lt;code&gt;unknown_decl()&lt;/code&gt; and 
&lt;code&gt;_scan_name()&lt;/code&gt;.
And then I hit another error. I'm sure you see where this was going.
Pretty soon I had over 100 lines of duplicated code, and I was still
getting errors and needed to redefine even more functions.
This clearly wasn't the way to go.

&lt;h3&gt;Using lxml.html&lt;/h3&gt;
&lt;p&gt;
I'd been trying to avoid adding dependencies to additional Python packages,
but if you want to parse real-world HTML, you have to.
There are two main options: Beautiful Soup and lxml.html.
Beautiful Soup is popular for large projects, but the consensus seems
to be that lxml.html is more error-tolerant and lighter weight.
&lt;p&gt;
Indeed, lxml.html is much more forgiving. You can't handle start and
end tags as they pass through, like you can with HTMLParser. Instead
you parse the HTML into an in-memory tree, like this:

&lt;pre&gt;
  tree = lxml.html.fromstring(html)
&lt;/pre&gt;

&lt;p&gt;
How do you iterate over the tree? lxml.html is a good parser, but it
has rather poor documentation, so it took some struggling to figure out
what was inside the tree and how to iterate over it.
&lt;p&gt;
You can visit every element in the tree with
&lt;pre&gt;
for e in tree.iter() :
  print e.tag
&lt;/pre&gt;
&lt;p&gt;
But that's not terribly useful if you need to know which
tags are inside which other tags. Instead, define a function that iterates
over the top level elements and calls itself recursively on each child.
&lt;p&gt;
The top of the tree itself is an element -- typically the
&amp;lt;html&amp;gt;&amp;lt;/html&amp;gt; -- and each element has .tag and .attrib.
If it contains text inside it (like a &amp;lt;p&amp;gt; tag), it also has
.text. So to make something that works similarly to HTMLParser:

&lt;pre&gt;
def crawl_tree(tree) :
  handle_starttag(tree.tag, tree.attrib)
  if tree.text :
    handle_data(tree.text)
  for node in tree :
    crawl_tree(node)
  handle_endtag(tree.tag)
&lt;/pre&gt;

&lt;p&gt;
But wait -- we're not quite all there. You need to handle two
undocumented cases. 
&lt;p&gt;
First, comment tags are special: their &lt;i&gt;tag&lt;/i&gt; attribute, 
instead of being a string, is &amp;lt;built-in function Comment&amp;gt;
so you have to handle that specially and not assume that &lt;i&gt;tag&lt;/i&gt;
is text that you can print or test against.
&lt;p&gt;
Second, what about cases like
&lt;code&gt;&amp;lt;p&amp;gt;Here is some &amp;lt;i&amp;gt;italicised&amp;lt;/i&amp;gt; text.&amp;lt;/p&amp;gt;&lt;/code&gt;
? in this case, you have the &lt;i&gt;p&lt;/i&gt; tag, and its &lt;i&gt;text&lt;/i&gt; is 
&quot;Here is some &quot;.
Then the p has a child, the i tag, with &lt;i&gt;text&lt;/i&gt; of &quot;italicised&quot;.
But what about the rest of the string, &quot; text.&quot;? 
&lt;p&gt;
That's called a tail -- and it's the tail of the adjacent i tag it follows,
not the parent p tag that contains it. Confusing!
&lt;p&gt;
So our function becomes:

&lt;pre&gt;
def crawl_tree(tree) :
  if type(tree.tag) is str :
    handle_starttag(tree.tag, tree.attrib)
    if tree.text :
      handle_data(tree.text)
    for node in tree :
      crawl_tree(node)
    handle_endtag(tree.tag)
  if tree.tail :
    handle_data(tree.tail)
&lt;/pre&gt;

&lt;p&gt;
See how it works? If it's a comment (tree.tag isn't a string),
we'll skip everything -- &lt;i&gt;except&lt;/i&gt; the tail. Even a comment
might have a tail:&lt;br /&gt;
&lt;code&gt;&amp;lt;p&amp;gt;Here is some &amp;lt;!-- this is a comment --&amp;gt; text we want to show.&amp;lt;/p&amp;gt;&lt;/code&gt;
&lt;br /&gt;
so even if we're skipping comment we need its tail.
&lt;p&gt;
I'm sure I'll find other gotchas I've missed, so I'm not releasing
this version of feedme until it's had a lot more testing. But it
looks like lxml.html is a reliable way to parse real-world pages.
It even has a lot of convenience functions like link rewriting
that you can use without iterating the tree at all. Definitely worth
a look!&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;</content>
		<author>
			<name>Akkana Peck</name>
			<uri>http://shallowsky.com/blog</uri>
		</author>
		<source>
			<title type="html">Shallow Thoughts</title>
			<subtitle type="html">Akkana's Musings on Open Source Computing, Science, and Nature.</subtitle>
			<link rel="self" href="http://shallowsky.com/blog/index.rss"/>
			<id>http://shallowsky.com/blog/index.rss</id>
			<updated>2012-02-03T01:30:14+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">OpenSource Enthusiasts Need a Better Clipboard Tool</title>
		<link href="http://www.hilltopyodeler.com/blog/?p=471"/>
		<id>http://www.hilltopyodeler.com/blog/?p=471</id>
		<updated>2012-01-06T01:02:55+00:00</updated>
		<content type="html">&lt;p&gt;Dear LazyWeb,&lt;/p&gt;
&lt;p&gt;From time to time, I am required to use third party tools in my job where I may have to copy a bunch of information (separate fields of data) and paste them one at a time into a web form.  Years ago, while working at a small web design firm, I was introduced to a tool for Windows called &lt;a href=&quot;http://www.thornsoft.com/&quot; target=&quot;_blank&quot;&gt;ClipMate&lt;/a&gt;.  At that point in time, ClipMate proved to be a huge time-saver when copying customer data from our Access database and then pasting it into an online account setup form for a third party web-stats tracking service that we used on client websites.  What sets ClipMate apart from other clipboard tools is that it not only stores a list of your clips (either text or images), but it will allow you to select a clip from where you would like to start pasting from, and then continue pasting down the list, one clip at a time.  In the example that I stated previously, can you imagine going to the database, copying the client&amp;#8217;s name, then pasting the name in the web form, then going back to the database to copy the next required chunk of information, and so forth&amp;#8230;?  Wouldn&amp;#8217;t it be nice to be able to go to the database and copy, copy, copy, copy, copy&amp;#8230;, then go to the web form and paste, paste, paste, paste&amp;#8230;.?  ClipMate allows you to do this.&lt;/p&gt;
&lt;p&gt;There are a handful of clipboard managers/organizers in the world of open source, but I have yet to find one that will do as I have described above.  It has been some years now since I&amp;#8217;ve used ClipMate, but recently, because of some repetitive copying and pasting that I&amp;#8217;ve been doing in my job, I purchased a new license and am again happily plodding along with my friend ClipMate.  However, this requires that I am using a Windows machine.  Fortunately in my job, I have two separate production machines &amp;#8211; on Linux and one Windows, so I am able to pick and choose the tools that work best for the task that I am trying to accomplish.  Below are some screenshots of ClipMate in action:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.hilltopyodeler.com/blog/wp-content/uploads/2012/01/clipmate-01.jpg&quot;&gt;&lt;img class=&quot;alignnone size-medium wp-image-472&quot; src=&quot;http://www.hilltopyodeler.com/blog/wp-content/uploads/2012/01/clipmate-01-300x167.jpg&quot; alt=&quot;&quot; width=&quot;300&quot; height=&quot;167&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.hilltopyodeler.com/blog/wp-content/uploads/2012/01/clipmate-02.jpg&quot;&gt;&lt;img class=&quot;alignnone size-medium wp-image-473&quot; src=&quot;http://www.hilltopyodeler.com/blog/wp-content/uploads/2012/01/clipmate-02-300x166.jpg&quot; alt=&quot;&quot; width=&quot;300&quot; height=&quot;166&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I would like to have a Linux-friendly clipboard tool that will do as I have described &amp;#8211; pasting successively from the list of clipboard elements.  Seeing as how the clipboard tools that I&amp;#8217;ve seen will allow you to select an item from the clipboard list and paste that item, it doesn&amp;#8217;t seem like it would be all that difficult to implement a feature that would allow you to successively paste one item at a time from the list.  I&amp;#8217;m not sure that my programming skills are sharp enough to accomplish this at the moment, nor do I have the time to invest in trying to figure out how to implement such a feature, so I am hoping that some skilled individual will read my plea and decide to do what Open Sourcers do&amp;#8230; grab some fine piece of software that already exists, make it better, and re-release it to the world.&lt;/p&gt;
&lt;p&gt;Incidentally, I&amp;#8217;ve tried running ClipMate under Crossover and Wine, and although the software did run, it somehow did not seem to be able to connect with my clipboard and so it was useless to me.&lt;/p&gt;
&lt;p&gt;Maybe what I am looking for already exists and I just am not aware of it.  Please feel free to comment and let me know if you have found a tool that will work as I have described, or if you have created something that will perform the desired task.  Thank you!&lt;/p&gt;</content>
		<author>
			<name>Darrin Goodman</name>
			<uri>http://www.hilltopyodeler.com/blog</uri>
		</author>
		<source>
			<title type="html">Hilltop Yodeler</title>
			<subtitle type="html">Get your holler on!</subtitle>
			<link rel="self" href="http://www.hilltopyodeler.com/blog/?feed=rss2"/>
			<id>http://www.hilltopyodeler.com/blog/?feed=rss2</id>
			<updated>2012-01-06T05:30:16+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">A geeky HPR New Year's Eve</title>
		<link href="http://corenominal.org/2012/01/05/a-geeky-hpr-new-years-eve"/>
		<id>http://corenominal.org/2012/01/05/a-geeky-hpr-new-years-eve</id>
		<updated>2012-01-05T12:00:35+00:00</updated>
		<content type="html">&lt;p&gt;I am not sure if it is just me, but I have always found New Year&amp;#8217;s Eve to be problematic. Social doctrine dictates that I should probably celebrate the event by socialising in meatspace, which involves getting totally wankered on alcohol, dancing like a complete muppet, and freezing my tits off as I watch a squazillion pounds worth of gunpowder being shot into space. Now, call me a &amp;#8220;boring old fart&amp;#8221;, but personally that sounds like far too much complicated multitasking for one night.&lt;/p&gt;

&lt;p&gt;So, when I read that the Hacker Public Radio crew were planning on holding a special 12 hour &lt;a href=&quot;http://hackerpublicradio.org/eps.php?id=0889&quot; title=&quot;HPR ep0889 :: New Year's Eve Show Announcement&quot;&gt;LIVE New Year&amp;#8217;s Eve event&lt;/a&gt;, I danced with joy (&lt;em&gt;well, not quite, but I was pretty excited.&lt;/em&gt;) I mean, what better way to celebrate the New Year than by joining some like-minded geeks for an open round-table discussion?&lt;/p&gt;

&lt;p&gt;So, both &lt;a href=&quot;http://bobobex.org&quot; title=&quot;@home with bobobex&quot;&gt;Becky&lt;/a&gt; and I joined the event for a few hours and we spent our night chatting about all manner of things. Topics included some chatter about &lt;a href=&quot;http://hackerpublicradio.org/eps.php?id=0893&quot; title=&quot;HPR ep0893 :: Hacker Public Radio New Year's Eve Part 3...&quot;&gt;CrunchBang&lt;/a&gt;, &lt;a href=&quot;http://hackerpublicradio.org/eps.php?id=0894&quot; title=&quot;HPR ep0894 :: Hacker Public Radio New Year's Eve Part 4/8 Mrs Cornominal brings the naughty&quot;&gt;mesh networks, drugs and naughty stuff&lt;/a&gt;, as well as other random subjects.&lt;/p&gt;

&lt;p&gt;It was a fun event and I just wanted thank everybody involved for allowing Becky and I to be a part of it. It was definitely the geekiest New Year&amp;#8217;s Eve that I have ever experienced and I really hope it becomes a regular event!&lt;/p&gt;

&lt;p&gt;P.S. If you missed the event, but would like to listen to the discussions, the whole 12 hour show is being made available from the &lt;a href=&quot;http://hackerpublicradio.org/&quot; title=&quot;Hacker Public Radio&quot;&gt;HPR site&lt;/a&gt;.&lt;/p&gt;
      &lt;p&gt; --&lt;br /&gt;&lt;small&gt;Tagged: &lt;a href=&quot;http://corenominal.org/tags/crunchbang_linux/&quot; title=&quot;Browse all content tagged with &amp;#8220;crunchbang linux&amp;#8221;&quot;&gt;crunchbang linux&lt;/a&gt;, &lt;a href=&quot;http://corenominal.org/tags/hacker_public_radio/&quot; title=&quot;Browse all content tagged with &amp;#8220;hacker public radio&amp;#8221;&quot;&gt;hacker public radio&lt;/a&gt;, &lt;a href=&quot;http://corenominal.org/tags/hpr/&quot; title=&quot;Browse all content tagged with &amp;#8220;hpr&amp;#8221;&quot;&gt;hpr&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;</content>
		<author>
			<name>Philip Newborough</name>
			<uri>http://corenominal.org/</uri>
		</author>
		<source>
			<title type="html">corenominal</title>
			<subtitle type="html">corenominal - RSS feed.</subtitle>
			<link rel="self" href="http://corenominal.org/feed/"/>
			<id>http://corenominal.org/feed/</id>
			<updated>2012-02-05T13:30:13+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Open the X selection in a browser window, from any desktop</title>
		<link href="http://shallowsky.com/blog/linux/open-selection-in-browser.html"/>
		<id>http://shallowsky.com/blog/linux/open-selection-in-browser.html</id>
		<updated>2012-01-04T06:00:17+00:00</updated>
		<content type="html">&lt;p&gt;
Like most Linux users, I use virtual desktops. Normally my browser
window is on a desktop of its own.
&lt;p&gt;
Naturally, it often happens that I encounter a link I'd like to visit
while I'm on a desktop where the browser isn't visible. From some apps,
I can click on the link and have it show up. But sometimes, the link is
just text, and I have to select it, change to the browser desktop,
paste the link into firefox, then change desktops again to do something
else while the link loads.
&lt;p&gt;
So I set up a way to load whatever's in the X selection in firefox no
matter what desktop I'm on.
&lt;p&gt;
In most browsers, including firefox, you can tell your existing
browser window to open a new link from the command line:
&lt;code&gt;firefox http://example.com/&lt;/code&gt; opens that link in your
existing browser window if you already have one up, rather than
starting another browser. So the trick is to get the text you've selected.
&lt;p&gt;
At first, I used a program called xclip. You can run this command:
&lt;code&gt;firefox `xclip -o`&lt;/code&gt; to open the selection. That worked
okay at first -- until I hit my first URL in weechat that was so long
that it was wrapped to the next line. It turns out xclip does odd things
with multi-line output; depending on whether it thinks the output is
a terminal or not, it may replace the newline with a space, or delete
whatever follows the newline. In any case, I couldn't find a way to
make it work reliably when pasted into firefox.
&lt;p&gt;
After futzing with xclip for a little too long, trying to reverse-engineer
its undocumented newline behavior, I decided it would be easier just to
write my own X clipboard app in Python. I already knew how to do that,
and it's super easy once you know the trick:

&lt;pre&gt;
mport gtk
primary = gtk.clipboard_get(gtk.gdk.SELECTION_PRIMARY)
if primary.wait_is_text_available() :
    print primary.wait_for_text()
&lt;/pre&gt;

&lt;p&gt;
That just prints it directly, including any newlines or spaces.
But as long as I was writing my own app, why not handle that too?
&lt;p&gt;
It's not entirely necessary on Firefox: on Linux, Firefox has some
special code to deal with pasting multi-line URLs, so you can copy
a URL that spans multiple lines, middleclick in the content area and
things will work. On other platforms, that's disabled, and some Linux
distros disable it as well; you can enable it by going to
&lt;code&gt;about:config&lt;/code&gt; and searching for &lt;code&gt;single&lt;/code&gt;,
then setting the preference
&lt;i&gt;editor.singlelinepaste.pasteNewlines&lt;/i&gt; to 2.
&lt;p&gt;
However, it was easy enough to make my Python clipboard app do the
right thing so it would work in any browser. I used Python's re
(regular expressions) module:

&lt;pre&gt;
#!/usr/bin/env python

import gtk
import re

primary = gtk.clipboard_get(gtk.gdk.SELECTION_PRIMARY)

if not primary.wait_is_text_available() :
    sys.exit(0)
s = primary.wait_for_text()

# eliminate newlines, and any spaces immediately following a newline:
print re.sub(r'[\r\n]+ *', '', s)
&lt;/pre&gt;

&lt;p&gt;
That seemed to work fine, even on long URLs pasted from weechat
with newlines and spaces, like that looked like
&lt;pre&gt;
http://example.com/long-
    url.html
&lt;/pre&gt;

&lt;p&gt;
All that was left was binding it so I could access it from anywhere.
Of course, that varies depending on your desktop/window manager.
In Openbox, I added two items to my desktop menu in &lt;i&gt;menu.xml&lt;/i&gt;:

&lt;pre&gt;
  &amp;lt;item label=&quot;open selection in Firefox&quot;&amp;gt;
    &amp;lt;action name=&quot;Execute&quot;&amp;gt;&amp;lt;execute&amp;gt;sh -c 'firefox `xclip -o`'&amp;lt;/execute&amp;gt;&amp;lt;/action&amp;gt;
  &amp;lt;/item&amp;gt;
  &amp;lt;item label=&quot;open selection in new tab&quot;&amp;gt;
    &amp;lt;action name=&quot;Execute&quot;&amp;gt;&amp;lt;execute&amp;gt;sh -c 'firefox -new-tab `xclip -o`'&amp;lt;/execute&amp;gt;&amp;lt;/action&amp;gt;
  &amp;lt;/item&amp;gt;
&lt;/pre&gt;

&lt;p&gt;
I also added some code in &lt;i&gt;rc.xml&lt;/i&gt; inside
&amp;lt;context name=&quot;Desktop&quot;&amp;gt;, so I can middle-click
or control-middle-click on the desktop to open a link in the browser:
&lt;pre&gt;
      &amp;lt;mousebind button=&quot;Middle&quot; action=&quot;Press&quot;&amp;gt;
        &amp;lt;action name=&quot;Execute&quot;&amp;gt;
          &amp;lt;execute&amp;gt;sh -c 'firefox `pyclip`'&amp;lt;/execute&amp;gt;
        &amp;lt;/action&amp;gt;
      &amp;lt;/mousebind&amp;gt;
      &amp;lt;mousebind button=&quot;C-Middle&quot; action=&quot;Press&quot;&amp;gt;
        &amp;lt;action name=&quot;Execute&quot;&amp;gt;
          &amp;lt;execute&amp;gt;sh -c -new-tab 'firefox `pyclip`'&amp;lt;/execute&amp;gt;
        &amp;lt;/action&amp;gt;
      &amp;lt;/mousebind&amp;gt;
&lt;/pre&gt;

&lt;p&gt;
I set this up maybe two hours ago and I've probably used it ten or
fifteen times already. This is something I should have done long ago!&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;</content>
		<author>
			<name>Akkana Peck</name>
			<uri>http://shallowsky.com/blog</uri>
		</author>
		<source>
			<title type="html">Shallow Thoughts</title>
			<subtitle type="html">Akkana's Musings on Open Source Computing, Science, and Nature.</subtitle>
			<link rel="self" href="http://shallowsky.com/blog/index.rss"/>
			<id>http://shallowsky.com/blog/index.rss</id>
			<updated>2012-02-03T01:30:14+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">2011 in Review</title>
		<link href="http://feedproxy.google.com/~r/BlahBlahWoofWoof/~3/2rO_bbm6m2Q/"/>
		<id>http://openmonkey.com/2012/01/04/2011-in-review/</id>
		<updated>2012-01-04T00:00:00+00:00</updated>
		<content type="html">&lt;p&gt;Each time I come to these posts, the year just past seems more activity-filled than ever. 2011 has been no exception. Another big year, with quite a few notable firsts for me:&lt;/p&gt;

&lt;h2&gt;A stake&lt;/h2&gt;

&lt;p&gt;In July I became a director and equal partner at &lt;a href=&quot;http://icelab.com.au/&quot;&gt;Icelab&lt;/a&gt;, along with &lt;a href=&quot;http://michaelhoney.com&quot;&gt;Michael&lt;/a&gt; and &lt;a href=&quot;http://makenosound.com/&quot;&gt;Max&lt;/a&gt;. My time working at the lab so far has been immensely satisfying. I am privileged to work with such a &lt;a href=&quot;http://icelab.com.au/about&quot;&gt;great team&lt;/a&gt;, and look forward to having Icelab as the foundation of many exciting future endeavours.&lt;/p&gt;

&lt;h2&gt;An app&lt;/h2&gt;

&lt;p&gt;For years I&amp;rsquo;d toyed with the idea of building an iOS app. It&amp;rsquo;s a platform I love to use, and one that will play an important role in the future of computing, and I wanted to be a part of it. Finally, with my attendance at Swipe Conference &lt;a href=&quot;http://icelab.com.au/articles/decaf-sucks-launch-countdown-starting-again-again/&quot;&gt;as motivation&lt;/a&gt;, I learnt Objective-C and Cocoa, and built and released an app (also thanks to the tireless design work of &lt;a href=&quot;http://makenosound.com/&quot;&gt;Max&lt;/a&gt;). Better still, it was an app for my favorite place on the internet, &lt;a href=&quot;http://decafsucks.com/&quot;&gt;Decaf Sucks&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://farm7.staticflickr.com/6201/6157623285_797469304b_b.jpg&quot; alt=&quot;Decaf Sucks for iPhone&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We released the app in August, just after Decaf Sucks' second birthday. Now, with a few months behind it, it looks like the release has been &lt;a href=&quot;http://icelab.com.au/articles/decaf-sucks-launch-countdown-a-restrospective/&quot;&gt;been quite successful&lt;/a&gt;. Personally, it&amp;rsquo;s found me a bunch of new coffee to try, and helped to take me &lt;a href=&quot;http://decafsucks.com/people/1-timriley&quot;&gt;well past 250 reviews&lt;/a&gt;. I hope it is a positive contribution for the coffee lovers of the world.&lt;/p&gt;

&lt;p&gt;With this big first release under my belt, I feel empowered to create a whole bunch of fun new experiences on iOS. Hopefully there&amp;rsquo;ll be a lot more to share on this front in 2012.&lt;/p&gt;

&lt;h2&gt;A talk&lt;/h2&gt;

&lt;p&gt;In September, the whole Icelab crew travelled up to Sydney for &lt;a href=&quot;http://south11.webdirections.org/&quot;&gt;Web Directions South&lt;/a&gt;, where Michael and I spoke about &lt;a href=&quot;http://south11.webdirections.org/program/big-picture#web-or-native-smart-choices-for-smartphone-apps&quot;&gt;smart choices for smartphone apps&lt;/a&gt; (i.e., &lt;em&gt;web or native, and tell me without the dogma&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://farm7.staticflickr.com/6045/6287098461_ba8087497c_b.jpg&quot; alt=&quot;Presenting at Web Directions South&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This was my first major conference presentation and I was honored to be part of such an inspirational event. I found the whole experience to be really rewarding. I enjoyed the singular focus that it encouraged for a good few weeks of thought, and the extra depths that it encouraged me to plumb in order to give a comprehensive overview of the topic. Its an experience I&amp;rsquo;d definitely like to repeat. Conferences of the world, who would like to have me in 2012? ;&amp;ndash;)&lt;/p&gt;

&lt;h2&gt;A move&lt;/h2&gt;

&lt;p&gt;If all this wasn&amp;rsquo;t enough, my wife and I capped off our year by packing up our lives in Australia and &lt;a href=&quot;http://feeds.feedburner.com/2011/11/03/moving-to-the-philippines/&quot;&gt;moving to the Philippines&lt;/a&gt;! I must say a little more about my &lt;a href=&quot;http://subtletransition.com/&quot;&gt;amazing wife&lt;/a&gt; at this point: not only did she put up with me, look after me and keep me sane throughout my work on all of the above, she also shouldered most of the load for planning this move. I couldn&amp;rsquo;t have done half as much this year without her, and I&amp;rsquo;m lucky to be her husband.&lt;/p&gt;

&lt;p&gt;Anyway, as I write this now, I look out our front window onto the lush green of a small park, surrounded by palm trees, goats grazing, roosters crowing, and the kids of the neighbourhood running around. I&amp;rsquo;m definitely in a whole new place, and I look forward to the many adventures I will have here, away from the computer screen.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://farm8.staticflickr.com/7157/6632120569_90367e3921_b.jpg&quot; alt=&quot;Approaching Sugar Beach, near Sipalay&quot; /&gt;&lt;/p&gt;

&lt;h2&gt;And more&lt;/h2&gt;

&lt;p&gt;In 2011, Icelab grew from three to five people. &lt;a href=&quot;http://hughevans.net/&quot;&gt;Hugh&lt;/a&gt; and &lt;a href=&quot;http://www.andymccray.com/&quot;&gt;Andy&lt;/a&gt; are good humans to see everyday and are invaluable as members of the team. I got to witness &lt;a href=&quot;http://moadoph.gov.au/&quot;&gt;a lot&lt;/a&gt; of &lt;a href=&quot;http://mildenhall.moadoph.gov.au/&quot;&gt;great&lt;/a&gt; &lt;a href=&quot;http://www.nma.gov.au/av/portmacquarie/&quot;&gt;stuff&lt;/a&gt; &lt;a href=&quot;http://www.nma.gov.au/av/flemington/&quot;&gt;come out&lt;/a&gt; &lt;a href=&quot;http://behindthelines.moadoph.gov.au/&quot;&gt;of the lab&lt;/a&gt; this year, much of which I wish I could have worked on myself. I think this is a sign of a good workplace.&lt;/p&gt;

&lt;p&gt;I did get to make one big release. In November we launched the new &lt;a href=&quot;http://cornerhotel.com/&quot;&gt;Corner Hotel&lt;/a&gt; site, along with a completely new ticket sales and box office management system, a Rails app that was practically my sole responsibility for the whole year. It&amp;rsquo;s one of Icelab&amp;rsquo;s biggest projects to date, and happily, everything&amp;rsquo;s gone pretty well since launch.&lt;/p&gt;

&lt;p&gt;Aside from shipping new projects, we also kept-on-shipping with our coffee subscription service, &lt;a href=&quot;http://dispatch.decafsucks.com/&quot;&gt;Dispatch&lt;/a&gt;. It&amp;rsquo;s now &lt;a href=&quot;http://icelab.com.au/articles/dispatchs-first-birthday/&quot;&gt;over a year in the running&lt;/a&gt;, and we&amp;rsquo;ve had a lot of fun sending coffee around the country.&lt;/p&gt;

&lt;p&gt;In the middle of 2012, my wife and I started &lt;a href=&quot;http://www.fitbomb.com/p/why-i-eat-paleo.html&quot;&gt;eating paleo&lt;/a&gt;. It was a terrific decision. I&amp;rsquo;ve never felt healthier in my life, nor eaten better food. While it&amp;rsquo;s harder to follow closely here in the Philippines, we do our best, and I know that it will be an eating habit that I&amp;rsquo;ll keep for the long term.&lt;/p&gt;

&lt;p&gt;And in one final notable event, in April we were lucky to witness the wedding of our good friends Hugh &amp;amp; Tomomi. Since moving to Canberra a few years ago, the friends I&amp;rsquo;ve made there really make it feel like home. We&amp;rsquo;ll be back before too long.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://farm8.staticflickr.com/7016/6632176189_d5824e2ef3_m.jpg&quot; width=&quot;140&quot; height=&quot;140&quot; /&gt; So that&amp;rsquo;s 2011. I finished the year feeling close to burnt out, but I&amp;rsquo;m proud of what I was able to achieve and I&amp;rsquo;ve now learnt the critical (if not already obvious) lesson that it&amp;rsquo;s best not to have many work commitments overlapping with an international house move. Now that we&amp;rsquo;ve settled here and had a short break over Christmas, I&amp;rsquo;m ready to go again and looking forward to a productive &amp;amp; venturesome 2012!&lt;/p&gt;
&lt;img src=&quot;http://feeds.feedburner.com/~r/BlahBlahWoofWoof/~4/2rO_bbm6m2Q&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</content>
		<author>
			<name>Tim Riley</name>
			<uri>http://openmonkey.com/</uri>
		</author>
		<source>
			<title type="html">Tim Riley</title>
			<link rel="self" href="http://feeds.feedburner.com/BlahBlahWoofWoof"/>
			<id>http://openmonkey.com</id>
			<updated>2012-02-02T13:30:35+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Good things</title>
		<link href="http://corenominal.org/2012/01/03/good-things"/>
		<id>http://corenominal.org/2012/01/03/good-things</id>
		<updated>2012-01-03T12:39:41+00:00</updated>
		<content type="html">&lt;p&gt;Just recently, I have received a number of emails from people who have discovered &lt;a href=&quot;http://crunchbang.org/&quot; title=&quot;CrunchBang Linux&quot;&gt;CrunchBang&lt;/a&gt;. The following, by &lt;a href=&quot;http://corvusmarketing.com/&quot; title=&quot;Management Consulting, Business Analysis &amp; Strategic Marketing&quot;&gt;Paul McClellan&lt;/a&gt;, is just one example:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Wanted to tell you that after using linux as a desktop &amp;amp; server for 12+ years, I never found a linux distro that I liked for the packages, the stability &amp;amp; the aesthetics all at once.  At most got two out of three.  Until I found #! - I can&amp;#8217;t tell you what an eerie yet delightful experience it was when I first started it up &amp;amp; found everything just so.&lt;/p&gt;
  
  &lt;p&gt;I hope to see you continue with this distro, while the donation is a tiny pittance, I hope to do more as time goes on &amp;amp; send like-minded folks along to try #!.  I think there are many of us who are like me somewhat technical, yet have a sense of &lt;strong&gt;aesthetics and efficiency&lt;/strong&gt; that recoils at either &amp;#8220;bling&amp;#8221; loaded desktops or worflow-interrupting instability.&lt;/p&gt;
  
  &lt;p&gt;My sincere esteem to you sir for making a Good Thing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, I do not seek out affirmation that CrunchBang is a worthwhile project, but now-and-again it is nice to hear from people who seem to &amp;#8220;get it&amp;#8221;.&lt;/p&gt;

&lt;p&gt;P.S. if anyone is reading this, I wish you a Happy New Year and I hope 2012 sends many good things your way! :)&lt;/p&gt;
      &lt;p&gt; --&lt;br /&gt;&lt;small&gt;Tagged: &lt;a href=&quot;http://corenominal.org/tags/crunchbang_linux/&quot; title=&quot;Browse all content tagged with &amp;#8220;crunchbang linux&amp;#8221;&quot;&gt;crunchbang linux&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;</content>
		<author>
			<name>Philip Newborough</name>
			<uri>http://corenominal.org/</uri>
		</author>
		<source>
			<title type="html">corenominal</title>
			<subtitle type="html">corenominal - RSS feed.</subtitle>
			<link rel="self" href="http://corenominal.org/feed/"/>
			<id>http://corenominal.org/feed/</id>
			<updated>2012-02-05T13:30:13+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">prabhupada01</title>
		<link href="http://urukrama.wordpress.com/2012/01/02/2011-the-year-in-screenshots/"/>
		<id>http://urukrama.wordpress.com/?p=361</id>
		<updated>2012-01-02T19:16:11+00:00</updated>
		<content type="html">&lt;p&gt;About a year ago I retired most of my computers, and am now left with only two: Loka, my old desktop (now with a new 23&amp;#8243; screen), and Savitar, a Thinkpad X41 I bought about 18 months ago.&lt;/p&gt;
&lt;p&gt;Both computers run Debian Testing. My main desktop environments and window managers on Loka have been Xfce with Openbox and WindowMaker, which I rediscovered this year. On Savitar, I used only Openbox and Awesome.&lt;/p&gt;
&lt;h2&gt;Loka&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://urukrama.files.wordpress.com/2011/12/alghattas.jpg&quot;&gt;&lt;img src=&quot;http://urukrama.files.wordpress.com/2011/12/alghattas.jpg?w=300&amp;h=168&quot; alt=&quot;&quot; title=&quot;Alghattas&quot; width=&quot;300&quot; height=&quot;168&quot; class=&quot;aligncenter size-medium wp-image-362&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Xfce 4.6 with Openbox, using the &lt;a href=&quot;http://box-look.org/content/show.php/Alghattas?content=134480&quot;&gt;Alghattas&lt;/a&gt; Openbox and Gtk theme, and the Elementary icons.  I don&amp;#8217;t remember where I found the wallpaper.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://urukrama.files.wordpress.com/2011/12/alghattas_sea.png&quot;&gt;&lt;img src=&quot;http://urukrama.files.wordpress.com/2011/12/alghattas_sea.png?w=300&amp;h=168&quot; alt=&quot;&quot; title=&quot;Alghattas_sea&quot; width=&quot;300&quot; height=&quot;168&quot; class=&quot;aligncenter size-medium wp-image-364&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Xfce 4.6 with Openbox, using the &lt;a href=&quot;http://box-look.org/content/show.php/Alghattas?content=134480&quot;&gt;Alghattas&lt;/a&gt; Openbox and Gtk theme, the Elementary icons, and &lt;a href=&quot;http://interfacelift.com/wallpaper/details/2229/a_moment_of_silence.html&quot;&gt;this wallpaper&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://urukrama.files.wordpress.com/2011/12/j91p4.jpg&quot;&gt;&lt;img src=&quot;http://urukrama.files.wordpress.com/2011/12/j91p4.jpg?w=300&amp;h=168&quot; alt=&quot;&quot; title=&quot;Erthe&quot; width=&quot;300&quot; height=&quot;168&quot; class=&quot;aligncenter size-medium wp-image-365&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Xfce 4.8 with Openbox, using the &lt;a href=&quot;http://box-look.org/content/show.php/Erthe?content=142686&quot;&gt;Erthe Openbox and Gtk theme&lt;/a&gt;, the AnyColorYouLike icons, and part of &lt;a href=&quot;http://www.tarfandestan.com/forum/attachments/94124d1312192448-201109053330-20450.jpg&quot;&gt;this image&lt;/a&gt; as wallpaper.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://urukrama.files.wordpress.com/2011/12/caitanya01.jpg&quot;&gt;&lt;img src=&quot;http://urukrama.files.wordpress.com/2011/12/caitanya01.jpg?w=300&amp;h=168&quot; alt=&quot;&quot; title=&quot;caitanya01&quot; width=&quot;300&quot; height=&quot;168&quot; class=&quot;aligncenter size-medium wp-image-366&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Xfce 4.8 with Openbox, using the &lt;a href=&quot;http://box-look.org/content/show.php/Erthe?content=142686&quot;&gt;Erthe Openbox and Gtk theme&lt;/a&gt;, and the AnyColorYouLike icons. &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://urukrama.files.wordpress.com/2011/12/wmaker02.jpg&quot;&gt;&lt;img src=&quot;http://urukrama.files.wordpress.com/2011/12/wmaker02.jpg?w=300&amp;h=168&quot; alt=&quot;&quot; title=&quot;wmaker02&quot; width=&quot;300&quot; height=&quot;168&quot; class=&quot;aligncenter size-medium wp-image-367&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;WindowMaker, with the &lt;a href=&quot;http://box-look.org/content/show.php/ShikiBlack?content=144353&quot;&gt;ShikiBlack WindowMaker theme&lt;/a&gt;, the &lt;a href=&quot;http://gnome-look.org/content/show.php/Shiki-JetBlack?content=121433&quot;&gt;Shiki-JetBlack Gtk theme&lt;/a&gt;, and the &lt;a href=&quot;http://packages.debian.org/wheezy/moblin-icon-theme&quot;&gt;Moblin icons&lt;/a&gt;. I don&amp;#8217;t remember where I found the wallpaper.&lt;/p&gt;
&lt;h2&gt;Savitar&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://urukrama.files.wordpress.com/2011/12/awesome_coe.jpg&quot;&gt;&lt;img src=&quot;http://urukrama.files.wordpress.com/2011/12/awesome_coe.jpg?w=300&amp;h=225&quot; alt=&quot;&quot; title=&quot;Awesome_coe&quot; width=&quot;300&quot; height=&quot;225&quot; class=&quot;aligncenter size-medium wp-image-370&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Awesome, with the Children of the Earth Awesome theme, Gtk theme, and icons, and Caspar David Friedrich&amp;#8217;s &lt;em&gt;Monk am See&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://urukrama.files.wordpress.com/2011/12/prabhupada01.png&quot;&gt;&lt;img src=&quot;http://urukrama.files.wordpress.com/2011/12/prabhupada01.png?w=300&amp;h=225&quot; alt=&quot;&quot; title=&quot;prabhupada01&quot; width=&quot;300&quot; height=&quot;225&quot; class=&quot;aligncenter size-medium wp-image-374&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Openbox with the &lt;a href=&quot;http://box-look.org/content/show.php/Children+of+the+Earth?content=86011&quot;&gt;Children of the Earth Openbox theme&lt;/a&gt;.&lt;/p&gt;
&lt;br /&gt;  &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/urukrama.wordpress.com/361/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/comments/urukrama.wordpress.com/361/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/urukrama.wordpress.com/361/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/delicious/urukrama.wordpress.com/361/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gofacebook/urukrama.wordpress.com/361/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/facebook/urukrama.wordpress.com/361/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gotwitter/urukrama.wordpress.com/361/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/twitter/urukrama.wordpress.com/361/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/urukrama.wordpress.com/361/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/stumble/urukrama.wordpress.com/361/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/urukrama.wordpress.com/361/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/digg/urukrama.wordpress.com/361/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/urukrama.wordpress.com/361/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/reddit/urukrama.wordpress.com/361/&quot; /&gt;&lt;/a&gt; &lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://stats.wordpress.com/b.gif?host=urukrama.wordpress.com&amp;blog=1573851&amp;post=361&amp;subd=urukrama&amp;ref=&amp;feed=1&quot; width=&quot;1&quot; height=&quot;1&quot; /&gt;</content>
		<author>
			<name>urukrama</name>
			<uri>http://urukrama.wordpress.com</uri>
		</author>
		<source>
			<title type="html">urukrama's weblog</title>
			<link rel="self" href="http://urukrama.wordpress.com/feed/"/>
			<id>http://urukrama.wordpress.com/feed/</id>
			<updated>2012-01-30T23:00:38+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Brume_02</title>
		<link href="http://urukrama.wordpress.com/2012/01/02/2010-the-year-in-screenshots/"/>
		<id>http://urukrama.wordpress.com/?p=285</id>
		<updated>2012-01-02T18:19:46+00:00</updated>
		<content type="html">&lt;p&gt;&lt;em&gt;I had written this a year ago, but somehow forgot to post it. But here are my screenshots from two years ago.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;As I&amp;#8217;ve been doing for a few years now, I am posting screenshots of my desktops of the past year, to amuse you (nearly everyone likes to look at screenshots), to document my changing aesthetics, and to capture my mood of the year as reflected in these images. &lt;/p&gt;
&lt;p&gt;Below are the screenshots of the computers I&amp;#8217;ve used in the past year. Aryaman is a Thinkpad 240 I bought on ebay for £10. I used it particularly when travelling, or when working in a library. I no longer use Mitra (&lt;a href=&quot;http://urukrama.wordpress.com/2008/10/26/giving-new-life-to-an-old-computer/&quot;&gt;my 11 year old Dell Inspiron 2500&lt;/a&gt;) and Yantra (my 10 year old Compaq Presario), but recently gave them away to others who found some good use for them. Loka is my old desktop.&lt;/p&gt;
&lt;h2&gt;Aryaman&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://urukrama.files.wordpress.com/2010/05/heart01.png&quot;&gt;&lt;img src=&quot;http://urukrama.files.wordpress.com/2010/05/heart01.png?w=300&amp;h=225&quot; alt=&quot;&quot; title=&quot;heart01&quot; width=&quot;300&quot; height=&quot;225&quot; class=&quot;aligncenter size-medium wp-image-290&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://urukrama.files.wordpress.com/2010/05/heart02.jpg&quot;&gt;&lt;img src=&quot;http://urukrama.files.wordpress.com/2010/05/heart02.jpg?w=300&amp;h=225&quot; alt=&quot;&quot; title=&quot;heart02&quot; width=&quot;300&quot; height=&quot;225&quot; class=&quot;aligncenter size-medium wp-image-291&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Musca 0.9.24&lt;/p&gt;
&lt;h2&gt;Loka&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://urukrama.files.wordpress.com/2010/05/duke01.jpg&quot;&gt;&lt;img class=&quot;aligncenter size-medium wp-image-286&quot; title=&quot;duke01&quot; src=&quot;http://urukrama.files.wordpress.com/2010/05/duke01.jpg?w=300&amp;h=225&quot; alt=&quot;&quot; width=&quot;300&quot; height=&quot;225&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Openbox 3.4.10 in Xfce 4.6, with the Fearless Openbox theme, the Umbra Gtk theme, and the Iris icon theme.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://urukrama.files.wordpress.com/2010/05/elegance_new01.jpg&quot;&gt;&lt;img src=&quot;http://urukrama.files.wordpress.com/2010/05/elegance_new01.jpg?w=300&amp;h=225&quot; alt=&quot;&quot; title=&quot;elegance_new01&quot; width=&quot;300&quot; height=&quot;225&quot; class=&quot;aligncenter size-medium wp-image-287&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Pekwm 0.1.11, with the Elegance Pekwm and Gtk theme, and the Iris icon theme.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://urukrama.files.wordpress.com/2010/05/groove_stars01.png&quot;&gt;&lt;img src=&quot;http://urukrama.files.wordpress.com/2010/05/groove_stars01.png?w=300&amp;h=225&quot; alt=&quot;&quot; title=&quot;Groove_stars01&quot; width=&quot;300&quot; height=&quot;225&quot; class=&quot;aligncenter size-thumbnail wp-image-289&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Pekwm 0.1.12, with an updated Groove Pekwm and Gtk theme, and the nuoveXT-1.7 icon theme.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://urukrama.files.wordpress.com/2010/05/groove01.jpg&quot;&gt;&lt;img src=&quot;http://urukrama.files.wordpress.com/2010/05/groove01.jpg?w=300&amp;h=225&quot; alt=&quot;&quot; title=&quot;Groove01&quot; width=&quot;300&quot; height=&quot;225&quot; class=&quot;aligncenter size-medium wp-image-288&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Pekwm 0.1.12, with the Groove Pekwm and Gtk theme. The icons are from the Any Colour You Like icon theme.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://urukrama.files.wordpress.com/2010/05/domore_groove01.jpg&quot;&gt;&lt;img src=&quot;http://urukrama.files.wordpress.com/2010/05/domore_groove01.jpg?w=300&amp;h=225&quot; alt=&quot;&quot; title=&quot;domore_groove01&quot; width=&quot;300&quot; height=&quot;225&quot; class=&quot;aligncenter size-medium wp-image-295&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Pekwm 0.1.12, with the Groove Pekwm and Gtk theme. The wallpaper is home made.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://urukrama.files.wordpress.com/2010/06/brume_02.png&quot;&gt;&lt;img src=&quot;http://urukrama.files.wordpress.com/2010/06/brume_02.png?w=300&amp;h=225&quot; alt=&quot;&quot; title=&quot;Brume_02&quot; width=&quot;300&quot; height=&quot;225&quot; class=&quot;aligncenter size-medium wp-image-301&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Openbox 3.4.10, with the Brume Openbox and Gtk theme.&lt;/p&gt;
&lt;br /&gt;  &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gocomments/urukrama.wordpress.com/285/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/comments/urukrama.wordpress.com/285/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godelicious/urukrama.wordpress.com/285/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/delicious/urukrama.wordpress.com/285/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gofacebook/urukrama.wordpress.com/285/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/facebook/urukrama.wordpress.com/285/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gotwitter/urukrama.wordpress.com/285/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/twitter/urukrama.wordpress.com/285/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/gostumble/urukrama.wordpress.com/285/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/stumble/urukrama.wordpress.com/285/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/godigg/urukrama.wordpress.com/285/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/digg/urukrama.wordpress.com/285/&quot; /&gt;&lt;/a&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;http://feeds.wordpress.com/1.0/goreddit/urukrama.wordpress.com/285/&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://feeds.wordpress.com/1.0/reddit/urukrama.wordpress.com/285/&quot; /&gt;&lt;/a&gt; &lt;img alt=&quot;&quot; border=&quot;0&quot; src=&quot;http://stats.wordpress.com/b.gif?host=urukrama.wordpress.com&amp;blog=1573851&amp;post=285&amp;subd=urukrama&amp;ref=&amp;feed=1&quot; width=&quot;1&quot; height=&quot;1&quot; /&gt;</content>
		<author>
			<name>urukrama</name>
			<uri>http://urukrama.wordpress.com</uri>
		</author>
		<source>
			<title type="html">urukrama's weblog</title>
			<link rel="self" href="http://urukrama.wordpress.com/feed/"/>
			<id>http://urukrama.wordpress.com/feed/</id>
			<updated>2012-01-30T23:00:38+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Será, hein?!</title>
		<link href="http://p0ng.com.br/post/15014781781"/>
		<id>http://p0ng.com.br/post/15014781781</id>
		<updated>2011-12-30T06:31:27+00:00</updated>
		<content type="html">&lt;p&gt;&lt;img src=&quot;http://media.tumblr.com/tumblr_lx07fePH2Q1qzljre.jpg&quot; /&gt;&lt;br /&gt;&lt;br /&gt;Tenho lá minhas dúvidas…&lt;/p&gt;</content>
		<author>
			<name>Renato Santos</name>
			<uri>http://p0ng.com.br/</uri>
		</author>
		<source>
			<title type="html">site do p0ng</title>
			<link rel="self" href="http://p0ng.com.br/rss"/>
			<id>http://p0ng.com.br/rss</id>
			<updated>2012-02-05T13:30:13+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Plotting the Analemma</title>
		<link href="http://shallowsky.com/blog/science/astro/plotting-the-analemma.html"/>
		<id>http://shallowsky.com/blog/science/astro/plotting-the-analemma.html</id>
		<updated>2011-12-30T04:00:54+00:00</updated>
		<content type="html">&lt;p&gt;
My SJAA planet-observing column for January is about 
&lt;a href=&quot;http://ephemeris.sjaa.net/1201/c.html&quot;&gt;the Analemma and the
Equation of Time&lt;/a&gt;.
&lt;p&gt;
The analemma is that funny figure-eight you see on world globes in the
middle of the Pacific Ocean. Its shape is the shape traced out by
the sun in the sky, if you mark its position at precisely the same
time of day over the course of an entire year.
&lt;p&gt;
The analemma has two components: the vertical component represents
the sun's declination, how far north or south it is in our sky.
The horizontal component represents the equation of time.
&lt;p&gt;
The equation of time describes how the sun moves relatively faster or
slower at different times of year. It, too, has two components: it's
the sum of two sine waves, one representing how the earth speeds up
and slows down as it moves in its elliptical orbit, the other a
function the tilt (or &quot;obliquity&quot;) of the earth's axis compared to
its orbital plane, the ecliptic.
&lt;p&gt;
&lt;a href=&quot;http://ephemeris.sjaa.net/1201/graph.jpg&quot;&gt;
&lt;img src=&quot;http://ephemeris.sjaa.net/1201/graph.jpg&quot; width=&quot;341&quot; height=&quot;256&quot; align=&quot;right&quot; alt=&quot;[components of the Equation of time]&quot; /&gt;&lt;/a&gt;
The Wikipedia page for
&lt;a href=&quot;http://en.wikipedia.org/wiki/Equation_of_time&quot;&gt;Equation of
time&lt;/a&gt; includes a link to a lovely piece of 
&lt;a href=&quot;http://en.wikipedia.org/wiki/File:Zeitgleichung.png&quot;&gt;R code by
Thomas Steiner showing how the two components relate&lt;/a&gt;. It's labeled
in German, but since the source is included, I was able to add English
labels and use it for my article.
&lt;p&gt;
But if you look at &lt;a href=&quot;http://images.google.com/images?q=analemma&amp;btnG=Search&amp;sout=1&quot;&gt;photos
of real analemmas in the sky&lt;/a&gt;, they're always tilted. Shouldn't they
be vertical? Why are they tilted, and how does the tilt vary with
location? To find out, I wanted a program to calculate the analemma.

&lt;h3&gt;Calculating analemmas in PyEphem&lt;/h3&gt;

&lt;p&gt;
The very useful astronomy Python package 
&lt;a href=&quot;http://rhodesmill.org/pyephem/index.html&quot;&gt;PyEphem&lt;/a&gt;
makes it easy to calculate the position of any astronomical object
for a specific location. Install it with: &lt;code&gt;easy_install pyephem&lt;/code&gt;
for Python 2, or &lt;code&gt;easy_install ephem&lt;/code&gt; for Python 3.
&lt;pre&gt;
import ephem
observer = ephem.city('San Francisco')
sun = ephem.Sun()
sun.compute(observer)
print sun.alt, sun.az
&lt;/pre&gt;
&lt;p&gt;
The alt and az are the altitude and azimuth of the sun right now.
They're printed as strings: &lt;code&gt;25:23:16.6 203:49:35.6&lt;/code&gt;
but they're actually type 'ephem.Angle', so float(sun.alt) will
give you a number in radians that you can use for calculations.
&lt;p&gt;
Of course, you can specify any location, not just major cities.
PyEphem doesn't know San Jose, so here's the approximate location of
Houge Park where the &lt;a href=&quot;http://sjaa.net&quot;&gt;San Jose Astronomical
Association&lt;/a&gt; meets:
&lt;pre&gt;
observer = ephem.Observer()
observer.name = &quot;San Jose&quot;
observer.lon = '-121:56.8'
observer.lat = '37:15.55'
&lt;/pre&gt;
&lt;p&gt;
You can also specify elevation, barometric pressure and other parameters.

&lt;p&gt;
So here's a simple analemma, calculating the sun's position at noon
on the 15th of each month of 2011:
&lt;pre&gt;
    for m in range(1, 13) :
        observer.date('2011/%d/15 12:00' % (m))
        sun.compute(observer)
&lt;/pre&gt;

&lt;p&gt;
I used a simple PyGTK window to plot sun.az and sun.alt, so once
it was initialized, I drew the points like this:

&lt;pre&gt;
    # Y scale is 45 degrees (PI/2), horizon to halfway to zenith:
    y = int(self.height - float(self.sun.alt) * self.height / math.pi)
    # So make X scale 45 degrees too, centered around due south.
    # Want az = PI to come out at x = width/2.
    x = int(float(self.sun.az) * self.width / math.pi / 2)
    # print self.sun.az, float(self.sun.az), float(self.sun.alt), x, y
    self.drawing_area.window.draw_arc(self.xgc, True, x, y, 4, 4, 0, 23040)
&lt;/pre&gt;

&lt;p&gt;
So now you just need to calculate the sun's position at the same time
of day but different dates spread throughout the year.
&lt;p&gt;
&lt;img align=&quot;right&quot; src=&quot;http://shallowsky.com/blog/images/analemma/sj-analemma-clocktimes.jpg&quot; width=&quot;370&quot; height=&quot;220&quot; alt=&quot;[analemma in San Jose at noon clock time]&quot; /&gt;
And my 12-noon analemma came out almost vertical! Maybe the tilt I saw
in analemma photos was just a function of taking the photo early in
the morning or late in the afternoon? To find out, I calculated the
analemma for 7:30am and 4:30pm, and sure enough, those were tilted.
&lt;p&gt;
But wait -- notice my noon analemma was &lt;i&gt;almost&lt;/i&gt; vertical -- but
it wasn't exactly vertical. Why was it skewed at all?

&lt;h3&gt;Time is always a problem&lt;/h3&gt;
&lt;p&gt;
As always with astronomy programs, time zones turned out to be the
hardest part of the project. I tried to add other locations to my
program and immediately ran into a problem.
&lt;p&gt;
The &lt;code&gt;ephem.Date&lt;/code&gt; class always uses UTC, and has no concept
of converting to the observer's timezone. You can convert to the timezone
of the person running the program with &lt;code&gt;localtime&lt;/code&gt;, but
that's not useful when you're trying to plot an analemma at local noon.
&lt;p&gt;
At first, I was only calculating analemmas for my own location.
So I set time to '20:00', that being the UTC for my local noon.
And I got the image at right. It's an analemma, all right, and
it's almost vertical. Almost ... but not quite. What was up?
&lt;p&gt;
Well, I was calculating for 12 noon clock time -- but clock time isn't
the same as mean solar time unless you're right in the middle of your
time zone.
&lt;br clear=&quot;all&quot; /&gt;
&lt;p&gt;
You can calculate what your &lt;i&gt;real&lt;/i&gt; localtime is (regardless of
what politicians say your time zone should be) by using your longitude
rather than your official time zone:
&lt;pre&gt;
    date = '2011/%d/12 12:00' % (m)
    adjtime = ephem.date(ephem.date(date) \
                    - float(self.observer.lon) * 12 / math.pi * ephem.hour)
    observer.date = adjtime
&lt;/pre&gt;

&lt;p&gt;
Maybe that needs a little explaining. I take the initial time string,
like '2011/12/15 12:00', and convert it to an ephem.date.
The number of hours I want to adjust is my longitude (in radians)
times 12 divided by pi -- that's because if you go pi (180) degrees
to the other side of the earth, you'll be 12 hours off.
Finally, I have to multiply that by &lt;code&gt;ephem.hour&lt;/code&gt; because ...
um, because that's the way to add hours in PyEphem and they don't really
document the internals of ephem.Date.
&lt;p&gt;
&lt;img align=&quot;right&quot; src=&quot;http://shallowsky.com/blog/images/analemma/sj-analemma-localtime.jpg&quot; width=&quot;370&quot; height=&quot;220&quot; alt=&quot;[analemma in San Jose at noon clock time]&quot; /&gt;
Set the observer date to this adjusted time before calculating your
analemma, and you get the much more vertical figure you see here.
This also explains why the morning and evening analemmas weren't
symmetrical in the previous run.
&lt;p&gt;
This code is location independent, so now I can run my analemma program
on a city name, or specify longitude and latitude.
&lt;br clear=&quot;all&quot; /&gt;
&lt;p&gt;
PyEphem turned out to be a great tool for exploring analemmas.
But to really understand analemma shapes, I had more exploring to do.
I'll write about that, and post my complete analemma program,
in the next article.
&lt;br clear=&quot;all&quot; /&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;</content>
		<author>
			<name>Akkana Peck</name>
			<uri>http://shallowsky.com/blog</uri>
		</author>
		<source>
			<title type="html">Shallow Thoughts</title>
			<subtitle type="html">Akkana's Musings on Open Source Computing, Science, and Nature.</subtitle>
			<link rel="self" href="http://shallowsky.com/blog/index.rss"/>
			<id>http://shallowsky.com/blog/index.rss</id>
			<updated>2012-02-03T01:30:14+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">MPD on Mac OS X</title>
		<link href="http://www.threadbox.net/2011/12/27/mpd-on-mac-os-x/"/>
		<id>http://www.threadbox.net/?p=3319</id>
		<updated>2011-12-27T19:12:37+00:00</updated>
		<content type="html">&lt;p&gt;&lt;img src=&quot;http://www.threadbox.net/wp-content/uploads/2011/12/ncmpcpp1.png&quot; alt=&quot;&quot; title=&quot;ncmpcpp&quot; width=&quot;312&quot; height=&quot;237&quot; class=&quot;alignright size-full wp-image-3340&quot; /&gt;My story really starts with Trackbox, an experiment of a perl script daemon I wrote long ago that worked like a headless jukebox daemon and allowed a client program to connect to it to provide a user interface to allow the user to browse the collection of music, manage playlists, play, pause, change volume, and all the other things you expect from a media player. It was pretty hacky, but it did the job. When Shank got MPD, the Music Player Daemon, working properly in raw C, though, I retired Trackbox. MPD is very similar to Trackbox: a super lightweight daemon that sits in the background, performing the duties of of music player. If I don&amp;#8217;t need to interact with it, I don&amp;#8217;t even need to have a client running &amp;#8212; like when my linux tower boots and the init script starts it up. MPD resumes playing where it left off before I even launch X. I&amp;#8217;ve obviously been a long time fan of even the idea of MPD.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve been using a Mac increasingly over recent years. It started with a 15&amp;#8243; MacBook Pro for work, and eventually I got a 13&amp;#8243; one for personal use. My current and second Mac is a 13&amp;#8243; 2011 MacBook Air, and I&amp;#8217;ve been frankly thrilled with it. Macs are great, but but I think a lot of folks endure the frustration of hunting for a great music player that simply doesn&amp;#8217;t seem to exist.&lt;/p&gt;
&lt;p&gt;Currawong started &lt;a href=&quot;http://www.head-fi.org/t/539740/mac-os-x-music-players-alternatives-to-itunes&quot;&gt;this excellent thread on head-fi&lt;/a&gt; which gives a really great overview and discussion on the most visible Mac music player options. I&amp;#8217;ve tried most of them, but never really found one to my liking. Each was either buggy, lacking features, stupid expensive, or didn&amp;#8217;t maintain a library, making practical use limited. I have gone back to iTunes every once in a while, and I&amp;#8217;ve always been disappointed with crashing or general bloaty slowness. I finally went as far as to uninstall it from my system entirely, reclaiming hundreds of megabytes. (After removing the iTunes.app, I simply used the Preferences screen of &amp;#8220;Software Update&amp;#8221; to disable future update notifications.) I must say, I don&amp;#8217;t miss it, not one little bit.&lt;/p&gt;
&lt;p&gt;I finally decided to give MPD a go on the Mac. After using it for perhaps about a month now, I can happily say it is absolutely my new favorite. At home, I mount my server&amp;#8217;s RAID array, and at work, I mount my off-site backup, a 3Tb external drive at my desk, so I always have my full collection of mostly lossless music readily at my disposal. I&amp;#8217;ve even found a nice way to start mpd with different config files so I can aim it at the server or the local collection, depending on what I need. Being a global hotkey junkie, I&amp;#8217;ve mapped restarting mpd with each config to a different key.&lt;/p&gt;
&lt;p&gt;MPD is only as nice to use as the client you&amp;#8217;re using. &lt;a href=&quot;http://theremin.sigterm.eu/&quot;&gt;Theremin&lt;/a&gt; is nice native Mac one, but seems fairly unmaintained at this point. It scrobbles and has album art, but its main drawback for me is that it doesn&amp;#8217;t allow browsing the collection by directory structure like most clients. I would recommend giving this one a try; it may fit the bill. There are &lt;a href=&quot;http://mpd.wikia.com/wiki/Clients&quot;&gt;countless others&lt;/a&gt; to choose from, though. I managed to get the excellent, GTK-based &lt;a href=&quot;http://sonata.berlios.de/&quot;&gt;Sonata&lt;/a&gt; client to run under OS X with the help of MacPorts, but it is a bit kludgey. &lt;a href=&quot;http://code.google.com/p/client175/&quot;&gt;Client175&lt;/a&gt; is a very nice, web-based one.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve actually found myself liking the terminal-based &lt;a href=&quot;http://unkart.ovh.org/ncmpcpp/&quot;&gt;ncmpcpp&lt;/a&gt; client best. It is jam-packed with features, remains blazingly quick, and even has the ability to add a random album, artist, or track to the playlist! I can understand why many folks might not like using a console client, but it works really well for me. Bind it to pop up with a global hotkey, and you have a slick, quick-launching client that you don&amp;#8217;t even need running most of the time!&lt;/p&gt;
&lt;p&gt;The other client I use is mpc, the command-line interface client. I barely ever actually use it on the command line, though, but through global hotkeys to toggle (play/pause) and play next track. I&amp;#8217;ve also written a wrapper for mpc that allows me to play (or append to the playlist) random tracks on random albums. The most unique feature of my tool is the ability to specify &amp;#8220;top-level&amp;#8221; directories by a pre-designated &amp;#8220;short code&amp;#8221; and add random tracks or albums only from within one top-level dir at a time. The main directories of my collection are genres, so I can throw on some random ambient music or random drum &amp;#8216;n bass. For example, with my Alfred extension, I do my ⌘+space to open him up, and type, &amp;#8220;rt db&amp;#8221; &amp;#8212; immediately 10 random drum &amp;#8216;n bass tracks are added, and the first one plays.&lt;/p&gt;
&lt;p&gt;Honestly, this has revolutionized how I listen to my music. I often don&amp;#8217;t even have the patience to drill down my folder structure or otherwise hunt for something to listen to. Now I can tell alfred &amp;#8220;rt ch&amp;#8221; and have random chill out beats. If I want to hear the entire album for one of the songs, ⌘⌥5 will play it.&lt;/p&gt;
&lt;p&gt;I use and adore Alfred for many things including setting up these global hotkeys, and I feel it is worth plenty more than what Andrew is asking for it. But if you want something that is free, I recommend &lt;a href=&quot;http://blog.boastr.net/&quot;&gt;BetterTouchTool&lt;/a&gt;. Here is the key configuration I use on my Air:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;⌘⌥1: play/pause toggle&lt;/li&gt;
&lt;li&gt;⌘⌥2: next track&lt;/li&gt;
&lt;li&gt;⌘⌥3: play 10 random tracks from entire collection (hold shift to append)&lt;/li&gt;
&lt;li&gt;⌘⌥4: play 1 random album from entire collection (hold shift to append)&lt;/li&gt;
&lt;li&gt;⌘⌥5: play the album the currently playing song belongs to (hold shift to append)&lt;/li&gt;
&lt;li&gt;or all the above, holding Control as well causes the command to be directed at my server, which drives the living room speakers/headphone system&lt;/li&gt;
&lt;li&gt;Control+⌥+n: launch ncmpcpp under iTerm2&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;(Note: I use Control+⌥+letter to launch / switch focus to my most often used apps. This makes me very efficient and I love it.)&lt;/p&gt;
&lt;p&gt;MPD does the trick for me. It is slim, efficient, and invisible. I can do 90% of everything I need with a simple global hotkey, and Growl gives me feedback. When I actually do want to browse around or manage the playlist, ncmpcpp or other client lets me do that. There are some folks who look for an &amp;#8220;audiophile&amp;#8221; player, but the fact is that if the program can decode the file and feed it to the audio device in a &amp;#8220;bit perfect&amp;#8221; manner, every app should sound the same. I think there are apps that are broken and don&amp;#8217;t do this quite right, and I also think there are people who get fall victim to the placebo effect. I really see no reason to worry about the sound quality of MPD &amp;#8212; I trust it.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve uploaded my &lt;a href=&quot;https://github.com/djthread/mpct&quot;&gt;mpct.php script&lt;/a&gt; to GitHub in case anyone is interested in it. If you use it, I would love to hear about your experience. If you have any questions about any of this, I would really love to hear from you in the comments!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Installing MPD&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Installing MPD on OS X is really easy according to &lt;a href=&quot;http://mpd.wikia.com/wiki/Install&quot;&gt;their instructions&lt;/a&gt;. Simply install homebrew with&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/usr/bin/ruby -e &quot;$(curl -fsSL https://raw.github.com/gist/323731)&quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;then use&lt;/p&gt;
&lt;p&gt;&lt;code&gt;brew install mpd&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;I really like this brew software manager! I can even install packages they don&amp;#8217;t provide with something like&lt;/p&gt;
&lt;p&gt;&lt;code&gt;brew create http://unkart.ovh.org/ncmpcpp/ncmpcpp-0.5.8.tar.bz2&lt;/code&gt;&lt;/p&gt;</content>
		<author>
			<name>Adam Bellinson</name>
			<uri>http://www.threadbox.net</uri>
		</author>
		<source>
			<title type="html">Threadbox.net</title>
			<subtitle type="html">Headphones, Technology, and Stuff</subtitle>
			<link rel="self" href="http://feeds.feedburner.com/threadbox"/>
			<id>http://feeds.feedburner.com/threadbox</id>
			<updated>2012-02-05T12:00:18+00:00</updated>
		</source>
	</entry>

	<entry xml:lang="en">
		<title type="html">Calculating the Solstice and shortest day</title>
		<link href="http://shallowsky.com/blog/science/astro/calculating-solstice.html"/>
		<id>http://shallowsky.com/blog/science/astro/calculating-solstice.html</id>
		<updated>2011-12-22T18:30:18+00:00</updated>
		<content type="html">&lt;p&gt;
&lt;p&gt;
Today is the winter solstice -- the official beginning of winter.
&lt;p&gt;
The solstice is determined by the Earth's tilt on its axis, not
anything to do with the shape of its orbit: the solstice is the point
when the poles come closest to pointing toward or away from the sun.
To us, standing on Earth, that means the winter solstice is the day
when the sun's highest point in the sky is lowest.
&lt;p&gt;
You can calculate the exact time of the equinox using the handy Python
package &lt;a href=&quot;http://rhodesmill.org/pyephem&quot;&gt;PyEphem&lt;/a&gt;.
Install it with: &lt;code&gt;easy_install pyephem&lt;/code&gt;
for Python 2, or &lt;code&gt;easy_install ephem&lt;/code&gt; for Python 3.
Then ask it for the date of the next or previous equinox.
You have to give it a starting date, so I'll pick a date in late summer
that's nowhere near the solstice:
&lt;pre&gt;
&amp;gt;&amp;gt;&amp;gt; ephem.next_solstice('2011/8/1')
2011/12/22 05:29:52
&lt;/pre&gt;
That agrees with my RASC Observer's Handbook: Dec 22, 5:30 UTC. (Whew!)

&lt;p&gt;
PyEphem gives all times in UTC, so, since I'm in California, I subtract
8 hours to find out that the solstice was actually last night at 9:30.
If I'm lazy, I can get PyEphem to do the subtraction for me:
&lt;pre&gt;
ephem.date(ephem.next_solstice('2011/8/1') - 8./24)
2011/12/21 21:29:52
&lt;/pre&gt;
I used 8./24 because PyEphem's dates are in decimal days, so in order
to subtract 8 hours I have to convert that into a fraction of a 24-hour day. 
The decimal point after the 8 is to get Python to do the division in
floating point, otherwise it'll do an integer division and subtract
int(8/24) = 0.

&lt;h3&gt;The shortest day&lt;/h3&gt;
&lt;p&gt;
The winter solstice also pretty much marks the shortest day of the year.
But was the shortest day yesterday, or today?
To check that, set up an &quot;observer&quot; at a specific place on Earth,
since sunrise and sunset times vary depending on where you are.
PyEphem doesn't know about San Jose, so I'll use San Francisco:

&lt;pre&gt;
&amp;gt;&amp;gt;&amp;gt; import ephem
&amp;gt;&amp;gt;&amp;gt; observer = ephem.city(&quot;San Francisco&quot;)
&amp;gt;&amp;gt;&amp;gt; sun = ephem.Sun()
&amp;gt;&amp;gt;&amp;gt; for i in range(20,25) :
...   d = '2011/12/%i 20:00' % i
...   print d, (observer.next_setting(sun, d) - observer.previous_rising(sun, d)) * 24
2011/12/20 20:00 9.56007901422
2011/12/21 20:00 9.55920379754
2011/12/22 20:00 9.55932991847
2011/12/23 20:00 9.56045709446
2011/12/24 20:00 9.56258416496
&lt;/pre&gt;

I'm multiplying by 24 to get hours rather than decimal days.

&lt;p&gt;
So the shortest day, at least here in the bay area, was actually yesterday,
2011/12/21. Not too surprising, since the solstice wasn't that long
after sunset yesterday.

&lt;p&gt;
If you look at the actual sunrise and sunset times, you'll find
that the latest sunrise and earliest sunset don't correspond to the
solstice or the shortest day. But that's all tied up with the equation
of time and the analemma ... and I'll cover that in a separate article.&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;</content>
		<author>
			<name>Akkana Peck</name>
			<uri>http://shallowsky.com/blog</uri>
		</author>
		<source>
			<title type="html">Shallow Thoughts</title>
			<subtitle type="html">Akkana's Musings on Open Source Computing, Science, and Nature.</subtitle>
			<link rel="self" href="http://shallowsky.com/blog/index.rss"/>
			<id>http://shallowsky.com/blog/index.rss</id>
			<updated>2012-02-03T01:30:14+00:00</updated>
		</source>
	</entry>

	<entry>
		<title type="html">Fundamental-Hybrid para XFCE</title>
		<link href="http://p0ng.com.br/post/14438424381"/>
		<id>http://p0ng.com.br/post/14438424381</id>
		<updated>2011-12-19T03:21:00+00:00</updated>
		<content type="html">&lt;p&gt;Tema pedido pelo &lt;a href=&quot;http://netonardin.deviantart.com/&quot; target=&quot;_blank&quot;&gt;netonardin&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://p0ngbr.deviantart.com/art/Fundamental-Hybrid-for-XFCE-274649930&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://media.tumblr.com/tumblr_lwfl9faxkc1qzljre.png&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Download @ &lt;a href=&quot;http://p0ngbr.deviantart.com/art/Fundamental-Hybrid-for-XFCE-274649930&quot; target=&quot;_blank&quot;&gt;deviantART&lt;/a&gt; &lt;/p&gt;</content>
		<author>
			<name>Renato Santos</name>
			<uri>http://p0ng.com.br/</uri>
		</author>
		<source>
			<title type="html">site do p0ng</title>
			<link rel="self" href="http://p0ng.com.br/rss"/>
			<id>http://p0ng.com.br/rss</id>
			<updated>2012-02-05T13:30:13+00:00</updated>
		</source>
	</entry>

</feed>

