<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>voidynullness</title><link href="http://www.voidynullness.net/" rel="alternate"></link><link href="http://www.voidynullness.net/feeds/all.atom.xml" rel="self"></link><id>http://www.voidynullness.net/</id><updated>2019-05-15T20:32:00+10:00</updated><entry><title>The Terrible Turnbull and LNP NBN legacy</title><link href="http://www.voidynullness.net/blog/2019/05/15/malcolm-turnbull-terrible-nbn-legacy/" rel="alternate"></link><published>2019-05-15T20:32:00+10:00</published><updated>2019-05-15T20:32:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2019-05-15:/blog/2019/05/15/malcolm-turnbull-terrible-nbn-legacy/</id><summary type="html">&lt;p&gt;Hey remember Malcolm Turnbull?  Remember that guy?  Remember him?  He was the Prime Minister until not too long ago, wasn&amp;#8217;t he?  He was the also guy largely responsible for screwing up the &lt;span class="caps"&gt;NBN&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Remember the &lt;span class="caps"&gt;NBN&lt;/span&gt;?  That huge national infrastructure project that would have brought great benefits to the nation &amp;#8212; if Malcolm and the &lt;span class="caps"&gt;LNP&lt;/span&gt; Coalition government hadn&amp;#8217;t screwed it&amp;nbsp;up.&lt;/p&gt;
&lt;p&gt;Malcolm Turnbull might not be dead yet, but his political career is, and its ghost will &lt;a href="https://www.lifehacker.com.au/2019/05/q-how-borked-is-the-nbn-a-pretty-borked/"&gt;haunt …&lt;/a&gt;&lt;/p&gt;</summary><content type="html">&lt;p&gt;Hey remember Malcolm Turnbull?  Remember that guy?  Remember him?  He was the Prime Minister until not too long ago, wasn&amp;#8217;t he?  He was the also guy largely responsible for screwing up the &lt;span class="caps"&gt;NBN&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Remember the &lt;span class="caps"&gt;NBN&lt;/span&gt;?  That huge national infrastructure project that would have brought great benefits to the nation &amp;#8212; if Malcolm and the &lt;span class="caps"&gt;LNP&lt;/span&gt; Coalition government hadn&amp;#8217;t screwed it&amp;nbsp;up.&lt;/p&gt;
&lt;p&gt;Malcolm Turnbull might not be dead yet, but his political career is, and its ghost will &lt;a href="https://www.lifehacker.com.au/2019/05/q-how-borked-is-the-nbn-a-pretty-borked/"&gt;haunt the &lt;span class="caps"&gt;NBN&lt;/span&gt; for years to come.&lt;/a&gt;  The &lt;span class="caps"&gt;NBN&lt;/span&gt; as envisioned by Labor is dead, but what remains is a zombiefied mess that will terrorise anyone expecting decent broadband in this&amp;nbsp;country.&lt;/p&gt;
&lt;p&gt;As this election campaign grinds into its last week, and draws to a merciful end, the Coalition is asking Australian voters to re-elect the same old government with new leader in Scott Morrison.  It might be instructive to take a little walk down memory lane and look back on the largely lamentable legacy of its previous leader.  The one who destroyed the &lt;span class="caps"&gt;NBN&lt;/span&gt; &amp;#8212; a fact that seems to have been largely&amp;nbsp;forgotten.&lt;/p&gt;
&lt;p&gt;While not necessarily surprising, I do feel it&amp;#8217;s certainly dispiriting how little the &lt;span class="caps"&gt;NBN&lt;/span&gt; has been mentioned during this election campaign.  It&amp;#8217;s not a surprise because technology issues rarely make it into the mainstream political discourse &amp;#8212; there just aren&amp;#8217;t enough votes there to matter, it seems.  And computer nerds aren&amp;#8217;t very good at organising collectively in a way that makes the powers-that-be take&amp;nbsp;notice.&lt;/p&gt;
&lt;p&gt;The &lt;span class="caps"&gt;NBN&lt;/span&gt;, despite being a relatively dull tech issue at its core, had a moment of mainstream political fame years ago, because of the costs involved, and because the Coalition sensed there was some cheap political points to be scored there &amp;#8212; at the expense of the&amp;nbsp;nation.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve been trying to avoid writing (or thinking) about the &lt;span class="caps"&gt;NBN&lt;/span&gt;, because what&amp;#8217;s the point anyway?  Most people in the tech industry are well aware of the issues involved, and the deficiencies in Malcolm&amp;#8217;s &lt;a href="https://www.itwire.com/open-sauce/84182-turnbull-s-tech-legacy-the-mtm-malcolm-technology-mix-nbn.html"&gt;multi-technology mix version of the &lt;span class="caps"&gt;NBN&lt;/span&gt;.&lt;/a&gt;  It&amp;#8217;s a bit hard not to, when a crucial piece of infrastructure we rely on day to day to make a living doesn&amp;#8217;t work reliably.  Political point scoring is one thing, but some of us need a reliable and fast internet connect to do actual work, and every dropout is a testament to the failure of Malcolm Turnbull, as former Communications Minister in charge of the &lt;span class="caps"&gt;NBN&lt;/span&gt;, and more broadly as a failed politician.  Seems people outside the tech industry generally don&amp;#8217;t care enough to make a difference.  And computer nerds generally aren&amp;#8217;t very good at explaining to the masses why certain tech issues are&amp;nbsp;important.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s all just screaming into the void.  Same with all the other technology-related failures of the &lt;span class="caps"&gt;LNP&lt;/span&gt; government &amp;#8212; the failed census, robodebt, the terrible metadata retention scheme, the even worse &lt;span class="caps"&gt;AA&lt;/span&gt; Bill, MyHealthRecord&amp;#8230;the list goes on.  This government cannot&amp;nbsp;computer.&lt;/p&gt;
&lt;p&gt;A lot of this seems to have been forgotten, as the media focuses elsewhere, and the news cycle inevitably moves&amp;nbsp;on.&lt;/p&gt;
&lt;p&gt;But if we don&amp;#8217;t look back at the past, we will never learn from it, and risk repeating the same&amp;nbsp;mistakes.&lt;/p&gt;
&lt;p&gt;Malcolm Turnbull might be gone from politics, but the forces in place that led to his failures, and to his undermining of the &lt;span class="caps"&gt;NBN&lt;/span&gt;, are still there.  The hostility towards technology, and ill-informed policy resulting from this, is still there within the Coalition, ready to undermine other industries, like renewable&amp;nbsp;energy.&lt;/p&gt;
&lt;p&gt;Of course, the state of the &lt;span class="caps"&gt;NBN&lt;/span&gt; is a result of many factors going back decades.  As is always the case with politics, shitfuckery abounds, on both sides.  The fact the Coalition even got elected in 2013 under the leadership of Tony Abbott was the result of the Labor party imploding.  Labor is responsible for an otherwise unelectable Tony Abbott managing to actually win an election, and set the stage for Turnbull to undermine the &lt;span class="caps"&gt;NBN&lt;/span&gt; as Communication minister.  But the Coalition shitfuckery in this area was generally worse than Labor&amp;#8217;s when it comes to Australia&amp;#8217;s broadband infrastructure &amp;#8212; from John Howard&amp;#8217;s fateful decision to privatise Telstra without structural separation, a series of incredibly incompetent Communications and Information Technology ministers (remember &lt;a href="https://www.theregister.co.uk/2003/09/29/worlds_biggest_luddite_to_retire/"&gt;international laughing stock Richard Alston&lt;/a&gt;?), George Brandis introducing Metadata retention then spectacularly failing to explain metadata in a &lt;span class="caps"&gt;TV&lt;/span&gt; interview, and a series of draconian surveillance and anti-encryption laws mis-characterised as &amp;#8220;national&amp;nbsp;security&amp;#8221;.&lt;/p&gt;
&lt;p&gt;So while the state of the &lt;span class="caps"&gt;NBN&lt;/span&gt; might not be entirely Turnbull&amp;#8217;s fault, he had a huge influence with his terrible decision to abandon Labor&amp;#8217;s plan of universal optic fibre and change to a ridiculous &amp;#8220;multi-technology mix&amp;#8221; relying on archaic copper&amp;nbsp;cables.&lt;/p&gt;
&lt;p&gt;The resulting problems caused by this decision is essentially Malcolm Turnbull&amp;#8217;s main legacy.  We should remember this fuck up, and apportion blame for it to Turnbull, in the hope that future politicians in similar position of power would be more likely to make better&amp;nbsp;decisions.&lt;/p&gt;
&lt;p&gt;But what really annoys me about the whole thing is how predictable it was.  Every single knowledgeable telecommunications expert at the time was of the opinion that Turnbull&amp;#8217;s multi-technology mix &lt;span class="caps"&gt;NBN&lt;/span&gt; was various combinations of inferior, stupid and insane.  Of course, there were numerous clueless partisans commentators willing to defend the coalitions&amp;#8217;s flawed broadband policy.  And these people&amp;#8217;s clearly wrong opinions were taken seriously by a credible media wanting to &amp;#8220;both sides&amp;#8221; the&amp;nbsp;issue.&lt;/p&gt;
&lt;p&gt;I have never understood the contortions journalists make in the pursuit of some misguided ideal of &amp;#8220;objectivity&amp;#8221;.  The problems with this are manifest in a world where Donald Trump is president.  But the problems have been there for a long time, and have consequences.  We&amp;#8217;ve seen climate change sceptics with no expertise or qualifications put up again qualified climate scientists to debate climate change.  We get the views anti-vaccination crackpots with no credible evidence presented along with the advice from qualified medical professionals and&amp;nbsp;scientists.&lt;/p&gt;
&lt;p&gt;The last decade or so of Australian (and international) politics has exposed the flaws of this kind of media reporting.  There seems to be a desperate need by political journalists for narrative &amp;#8212; and to believe that the people they are reporting on in positions of power have character, intelligence, gravitas.  Surely the vagaries of our elected political leaders should have dispelled this myth by now?  Our politicians are mostly power hungry grifters driven by a desire for fame, power, self aggrandisement and self enrichment, rather than any real desire for public&amp;nbsp;service.&lt;/p&gt;
&lt;p&gt;The political careers of both Malcolm Turnbull, and his predecessors as Prime Minister, Tony Abbott, benefited greatly from a credulous media.  I&amp;#8217;m not really talking about the right wing propaganda machine of New Corp, which is a whole other shitshow.  People fed a diet of Murdoch bullshit are obviously going to be&amp;nbsp;ill-informed.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s annoying that even more credible media outlets largely recycle press releases, or just uncritically report the utterances of politicians as news, even if it is plainly untrue or non-sensical.  There was a hell of a lot of that going around at the time regarding the &lt;span class="caps"&gt;NBN&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Looking back to 2013, it&amp;#8217;s clear now the &lt;span class="caps"&gt;LNP&lt;/span&gt; under Tony Abbott had no credible plan for a decent broadband network.  &amp;#8220;Better, faster, sooner&amp;#8221; my ass.  They wanted to do what they could to undermine the &lt;span class="caps"&gt;NBN&lt;/span&gt; &amp;#8212; their &lt;span class="caps"&gt;NBN&lt;/span&gt; policy was just a weak exercise in plausible&amp;nbsp;deniability.  &lt;/p&gt;
&lt;p&gt;Yet, it was reported in the media as if it was a credible communications policy, and after the election, Malcolm Turnbull was taken seriously as communications&amp;nbsp;minister.&lt;/p&gt;
&lt;p&gt;I think there was a sense at the time that after the Labor party imploded while in office, it kind of ruined the usual subtext of political reporting that these were the great men and women of history, and made it look more like high school bickering.  So there was a desperate need amongst reporters to present the Coalition a sensible and responsible alternative.  But Tony Abbott was opposition leader at the time, and he was neither.  We certainly didn&amp;#8217;t get sensible or responsible government with Abbott as Prime Minister.  We got knights and dames, knighthoods for Prince Phillip, raw onion eating, and lots of other weirdness, but no sign of good&amp;nbsp;government.&lt;/p&gt;
&lt;p&gt;The entire country breathed a great sigh of relief when Abbott was deposed by Turnbull.  The weirdness and delusion was gone, but more importantly, here, finally, was a Prime Minister that looked and acted the part.  Turnbull looked like a Prime Minister.  He spoke like a Prime Minister.  His background make it seem that, on paper at least, he would make a good Prime Minister.  And he enjoyed some initial popularity.  That soon faded, however, as it became increasingly apparent he didn&amp;#8217;t have much more idea of what he was doing than his&amp;nbsp;predecessors.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s deeply weird to me that even when a politician conclusively demonstrates they have no idea what they&amp;#8217;re talking about, not idea what they&amp;#8217;re doing, and no ideas in general, they are still taken seriously by political&amp;nbsp;journalists.&lt;/p&gt;
&lt;p&gt;I think Turnbull was particularly interesting in this regard, because he looked and sounded the part so well.  He was the ultimate cosplay as Prime Minister of Australia.  And before that, he got to cosplay as Communications minister.  Unfortunately, the media mistook his pathetic cosplay broadband policy as something that made sense, when every expert in the country was screaming that it did&amp;nbsp;not.&lt;/p&gt;
&lt;p&gt;Politicians are human beings after all.  Being elected doesn&amp;#8217;t automatically give them new skills or talents.  Most at some point in their lives were second rate suburban accountants and lawyers.  They&amp;#8217;re all essentially cosplaying as politicians.  (Except for Barnaby Joyce, who cosplays as a farmer.  One of the more amusing owns of Barnaby Joyce I&amp;#8217;ve seen on Twitter involve references to him being a suburban accountant before entering politics.  But he wears Akubra hats and R.M Williams boots whenever there&amp;#8217;s cameras likely to be around, trying to look rural.  Seems to work though.  Especially on gullible&amp;nbsp;journalists.)&lt;/p&gt;
&lt;p&gt;Obviously, looking like a Prime Minister does not guarantee success as one.  Neither does being an investment banker or lawyer.  On paper, Turnbull&amp;#8217;s background makes it seem like he might actually make a good Prime Minister.  In reality, it did not.  Success in one field does not guarantee success in another.  Donald Trump is another obvious example of that.  Although it increasingly seems like Trump&amp;#8217;s business success was largely a fiction of his own creation.  I wonder how much of Turnbull&amp;#8217;s business success is due to skill and talent, and how much to white male privilege and dumb luck?  His supposed business acumen didn&amp;#8217;t help when it came to building a world class broadband network.  And it certainly didn&amp;#8217;t help him handle the ideological and personal divisions within his own party that ultimately cost him his job as &lt;span class="caps"&gt;PM&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;span class="caps"&gt;NBN&lt;/span&gt; rollout is entering its last stages.  Regardless of who wins the election, it&amp;#8217;s unlikely it will get better any time soon.  Turnbull&amp;#8217;s terrible switch from fibre to a multi-technology mix have crippled it for years to come, without a great upgrade path.  Eventually there will be no choice but to replace the remaining copper-based parts of the network with optic fibre, at great expense, but we&amp;#8217;re stuck with what we&amp;#8217;ve got for&amp;nbsp;now.&lt;/p&gt;
&lt;p&gt;So Malcolm Turnbull looked the part, sounded the part, and had a background that suggested he might be good as both Communications Minister, and then Prime Minister.  But he wasn&amp;#8217;t.  He was terrible at both.  The resulting &lt;span class="caps"&gt;NBN&lt;/span&gt; is a mess.  And his political career ended with an incredibly messy coup by Peter Dutton (of all&amp;nbsp;&amp;#8220;people&amp;#8221;!).&lt;/p&gt;
&lt;p&gt;Turnbull&amp;#8217;s career, and the &lt;span class="caps"&gt;NBN&lt;/span&gt;, provide an instructive look at what what promised, and what was eventually delivered.  Neither was successful.  Signs of problems with both were there from the start.  (Problems that weren&amp;#8217;t particularly prominently address by political journalists at the&amp;nbsp;time.)&lt;/p&gt;
&lt;p&gt;The &lt;span class="caps"&gt;LNP&lt;/span&gt; promised an &lt;span class="caps"&gt;NBN&lt;/span&gt; that would be fast, affordable, sooner.  It&amp;#8217;s none of that.  Outside of the fibre parts of the network, it&amp;#8217;s slow and prone to dropouts.  As the &lt;span class="caps"&gt;NBN&lt;/span&gt; rollout finishes up, Australia continues to drop in global speed ranking &amp;#8212; &lt;a href="https://www.lifehacker.com.au/2019/04/australias-internet-speeds-are-getting-faster-slower-than-everyone-else/"&gt;down from 50th to&amp;nbsp;62nd.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;None of that has featured in this election campaign.  As far as the &lt;span class="caps"&gt;NBN&lt;/span&gt; goes, the fact the coalition made a mess of it seems to have been&amp;nbsp;forgotten.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s as if the &lt;span class="caps"&gt;NBN&lt;/span&gt; issue has been neutralised now that Turnbull is gone.  But while Scott Morrison might not have had much direct involvement in screwing up the &lt;span class="caps"&gt;NBN&lt;/span&gt; (he was busy being cruel to asylum seekers) the same political forces are still there, and we shouldn&amp;#8217;t forget Morrison is now leading the government responsible for screwing up the &lt;span class="caps"&gt;NBN&lt;/span&gt;.  Since he&amp;#8217;s only been &lt;span class="caps"&gt;PM&lt;/span&gt; for 8 months, he doesn&amp;#8217;t have much of a record to run on, going into this election.  But the political coalition he is notionally leading has been in government for 6 years, and in that time they have achieved little &amp;#8212; apart from screwing up the &lt;span class="caps"&gt;NBN&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;The government is asking to be re-elected but not providing much in policies.  Morrison is running essentially on a platform that he is not Bill Shorten, nor is he Malcolm Turnbull.  Or Tony&amp;nbsp;Abbott.&lt;/p&gt;
&lt;p&gt;Meanwhile, the climate is changing, and we&amp;#8217;ve had six years of inaction, while the Coalition government worked to undermine renewable energy the same way they&amp;#8217;ve undermined the &lt;span class="caps"&gt;NBN&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Remember, every time your internet connection craps out, that&amp;#8217;s the legacy of Malcolm&amp;nbsp;Turnbull.&lt;/p&gt;
&lt;p&gt;With that ranting out of my system, I should now post this thing before my internet connection craps out.&amp;nbsp;Again.&lt;/p&gt;</content><category term="NBN"></category><category term="Broadband"></category><category term="Ranting"></category></entry><entry><title>Wayward Windows</title><link href="http://www.voidynullness.net/blog/2018/12/18/wayward-windows/" rel="alternate"></link><published>2018-12-18T00:00:00+11:00</published><updated>2018-12-18T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2018-12-18:/blog/2018/12/18/wayward-windows/</id><summary type="html">&lt;p class="first last"&gt;Some thoughts about my experiences using Windows on old&amp;nbsp;hardware.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;In some occasional but disturbing fever dreams I consider buying
another Windows&amp;nbsp;device.&lt;/p&gt;
&lt;p&gt;Then I power up one of my old Windows laptops and any such desire
rapidly&amp;nbsp;fades.&lt;/p&gt;
&lt;p&gt;Waiting for an old Windows machine to boot up has a way of focusing the
mind on the deficiencies of Windows as an operating system.  And the
ever-increasing boot times provide more and more time to contemplate the
many and varied ways in which Windows disappoints and&amp;nbsp;annoys.&lt;/p&gt;
&lt;p&gt;One possible way to prevent oneself from impulse buying anything online is
to try and do it on an old, underpowered Windows machine.  By the time it
boots, you&amp;#8217;d have forgotten what you were going to buy.  By the time a a
browser loads (and then probably updates itself) you&amp;#8217;ve most likely gone
away to do something else, and forgotten why you powered the thing on in the
first&amp;nbsp;place.&lt;/p&gt;
&lt;p&gt;I don&amp;#8217;t use Windows much anymore &amp;#8212; my development work these days is done
mostly on Linux, sometimes a&amp;nbsp;Mac.&lt;/p&gt;
&lt;p&gt;So booting up one of my old Windows machines is inevitably an exercise in
frustration. The frustration of the long boot up time, the endless hard
drive thrashing before being presented with a useable desktop.  Then
there&amp;#8217;s Windows Update.  The slowdown to the point of being unusable, as
Windows installs updates in the &amp;#8220;background&amp;#8221;.  Windows Update increasingly
seems like punishment for using Windows sparingly &amp;#8212; the less you use the
device in questions, the longer the wait for it to update, and the less
useable the device is in the meantime.  Yes, I get that security is
important, but all this is hardly conductive to getting anything useful&amp;nbsp;accomplished.&lt;/p&gt;
&lt;p&gt;Of course, the two ageing Windows laptops I have are hardly representative
of modern Windows machines &amp;#8212; one a Windows 7 era machine, the other
Windows 8, both with mechanical hard drives, and both now running
Windows 10.  But they were both powerfull machines for their time &amp;#8212; both
Core i7 processors (albeit many generations old), with plenty of &lt;span class="caps"&gt;RAM&lt;/span&gt;.  It&amp;#8217;s
most likely the mechanical hard drives that are the main performance drag &amp;#8212;
it really is astonishing the difference solid state drives make to&amp;nbsp;performance.&lt;/p&gt;
&lt;p&gt;Though I do still wonder if the performance has to be this bad on older
hardware?  I wonder if any developer in any position to influence any
operating system development still encounters machines with mechanical hard
drives?  Probably not, so either through unconscious bias or intentional
design, &lt;span class="caps"&gt;OS&lt;/span&gt; development now assumes &lt;span class="caps"&gt;SSD&lt;/span&gt; hardware, and therefore modern
operating systems run far more crappier than they should on older&amp;nbsp;hardware.&lt;/p&gt;
&lt;p&gt;Either way, the crappiness of Windows running on old hardware really
doesn&amp;#8217;t inspire confidence at best, and moreover acts as a deterrent to
buying any new hardware with the intention of running Windows on it.
Especially pricier, upper end hardware like Surface devices.  Sure, they&amp;#8217;ll
probably be nice and performative initially.  But how long before the usual
Windows software rots sets in?  How long before the shiny new device of
desire becomes another laggy&amp;nbsp;mess?&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related&amp;nbsp;Posts:&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/06/12/initial-windows-8-development-machine-setup/"&gt;How to turn a Windows box into a development&amp;nbsp;machine&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="Ranting"></category><category term="Attempted Humour"></category></entry><entry><title>Nexus redux</title><link href="http://www.voidynullness.net/blog/2018/07/24/nexus-redux/" rel="alternate"></link><published>2018-07-24T00:00:00+10:00</published><updated>2018-07-24T00:00:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2018-07-24:/blog/2018/07/24/nexus-redux/</id><summary type="html">&lt;p class="first last"&gt;Banished&amp;nbsp;bootloop.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;span class="caps"&gt;OK&lt;/span&gt;, so my phone actually got fixed. Finally.  And somewhat&amp;nbsp;surprisingly.&lt;/p&gt;
&lt;p&gt;My Nexus 5x phone developed a defect a few months ago &amp;#8212; the dreaded, and apparantly common, bootloop issue.  It suddenly started rebooting, repeatedly and constantly, to the point it became unusable.  &lt;span class="caps"&gt;LG&lt;/span&gt; Australia initially rejected my warranty claim.  Their opening gambit was to try and fob me off by telling me my phone was an overseas model or grey import.  It&amp;#8217;s not.  It is an Australian model purhased outright at a local &lt;span class="caps"&gt;JB&lt;/span&gt; Hi Fi&amp;nbsp;store.&lt;/p&gt;
&lt;p&gt;Finally, after repeated warranty claims, and uploading multiple copies of my receipt, they agreed to repair the phone.  But I wasn&amp;#8217;t expecting much when I posted the phone to their repair&amp;nbsp;centre.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;d come across a number of forums on whirlpool with horror stories of &lt;span class="caps"&gt;LG&lt;/span&gt; warranty issues, and some reports of &lt;span class="caps"&gt;LG&lt;/span&gt; refusing to repair bootlooping Nexus 5X devices.  Excuses like falsely claiming water damage seemed common.  My phone was otherwise in great condition, certainly no water damage &amp;#8212; not even a scratch on the&amp;nbsp;screen.&lt;/p&gt;
&lt;p&gt;Perhaps this was why I did end up with a functional and repaired phone.  They finally honored their warranty&amp;nbsp;obligations.&lt;/p&gt;
&lt;p&gt;Which is great, but because the whole thing dragged out for so long, I had to get a replacement phone anyway.  And I&amp;#8217;m not sure I trust the Nexus 5X anymore as my main&amp;nbsp;phone.&lt;/p&gt;
&lt;p&gt;The replacement phone I settled on was a Moto G5&amp;nbsp;plus.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s a mid-range phone, but does what I need it&amp;nbsp;to.&lt;/p&gt;
&lt;p&gt;I actually like it better than the Nexus.  I think it&amp;#8217;s an objectively better&amp;nbsp;phone.&lt;/p&gt;
&lt;p&gt;They&amp;#8217;re both midrange phones with fairly stock&amp;nbsp;Android.&lt;/p&gt;
&lt;p&gt;But I think there&amp;#8217;s more attention to detail with the Moto.  It feels a little bit more refined.  There are some small changes to the standard Android &lt;span class="caps"&gt;OS&lt;/span&gt;, and for the most part they are worthwhile changes.  In particular, the notificaitions and home screen are really well thought out on the&amp;nbsp;Moto.&lt;/p&gt;
&lt;p&gt;I prefered the location of the fingerprint sensor on the Nexus &amp;#8212; it perfectly located on the back.  But this is a minor thing.  The front sensor on the Moto is&amp;nbsp;fine.&lt;/p&gt;
&lt;p&gt;My main annoyances with the Nexus were the buttons.  Clearly some corners were cut (hence the common bootloop issues).  In particular, the power and volume buttons felt cheap and spongy.  They were also overly sensitive, which was particular annoying in combination with the fact they were still functional even with the device &amp;#8220;locked&amp;#8221;.  So often just picking up the phone meant an unwanted volume&amp;nbsp;adjustment.&lt;/p&gt;
&lt;p&gt;The vibration and synaptics were also felt weak and&amp;nbsp;insubstantial.&lt;/p&gt;
&lt;p&gt;All in all, the Moto feels like a more solid and well made phone, so I&amp;#8217;m sticking with it.  The repaired Nexus will be my backup/dev device.  Assuming it doesn&amp;#8217;t start bootlooping&amp;nbsp;again.&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related&amp;nbsp;Posts:&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2017/12/23/nexus-5x-bootloop-lg-refuses-to-honour-warranty/"&gt;&lt;span class="caps"&gt;LG&lt;/span&gt; refuses to honour warranty after my Nexus 5X develops bootloop&amp;nbsp;issue&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2017/12/21/lg-nexus-5x-bootloop-death/"&gt;Death by bootloop of my Nexus&amp;nbsp;5X&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/03/17/android-nexus-7-slow-sluggish-laggy-after-lollipop-update/"&gt;Laggy&amp;nbsp;Lollipop&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="Android Nexus"></category></entry><entry><title>LG refuses to honour warranty after my Nexus 5X develops bootloop issue</title><link href="http://www.voidynullness.net/blog/2017/12/23/nexus-5x-bootloop-lg-refuses-to-honour-warranty/" rel="alternate"></link><published>2017-12-23T00:00:00+11:00</published><updated>2017-12-23T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2017-12-23:/blog/2017/12/23/nexus-5x-bootloop-lg-refuses-to-honour-warranty/</id><summary type="html">&lt;p class="first last"&gt;My initial attempt to get &lt;span class="caps"&gt;LG&lt;/span&gt; Australia to honour its&amp;nbsp;warranty.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;This is the story of the unexpected death of my Nexus 5X &amp;#8212; a phone taken
too early by &lt;span class="caps"&gt;LG&lt;/span&gt;&amp;#8217;s dodgy manufacturing and the inexorable march of planned&amp;nbsp;obsolescence.&lt;/p&gt;
&lt;p&gt;After my phone started randomly rebooting itself one night, I did some
googling.  Turns out this is not an unusual issue with the Nexus 5X model,
which is made by &lt;span class="caps"&gt;LG&lt;/span&gt;.  It is often referred to as the &amp;#8220;bootloop&amp;#8221; issue.
What&amp;#8217;s more, this is not the only model with this problem &amp;#8212; it also
affected some previous &lt;span class="caps"&gt;LG&lt;/span&gt; phones.  There was even a class action lawsuit in
the &lt;span class="caps"&gt;US&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;While apparently &lt;span class="caps"&gt;LG&lt;/span&gt; has never officially stated what the root cause of this
issue is, online speculation points towards either a flaw with the &lt;span class="caps"&gt;CPU&lt;/span&gt;
design, or bad &lt;span class="caps"&gt;CPU&lt;/span&gt; soldering&amp;nbsp;work.&lt;/p&gt;
&lt;p&gt;Design flaw or manufacturing flaw, either way, seems like something that
should be covered by some combination of either manufacturer&amp;#8217;s warranty or
Australian consumer&amp;nbsp;law.&lt;/p&gt;
&lt;p&gt;The phone was 15 months old and in good condition appearance-wise &amp;#8212; no
drops, dents, scratches or water damage.  While 15 months isn&amp;#8217;t exactly a
short time to own a phone these days, there seems to be a general consensus
that a phone should last at least two years.  According the &lt;span class="caps"&gt;LG&lt;/span&gt; website,
this phone comes with a 24 months&amp;nbsp;warranty.&lt;/p&gt;
&lt;p&gt;I still had the receipt (and original packaging) so I took it back to the
&lt;span class="caps"&gt;JB&lt;/span&gt; Hi-Fi store I&amp;#8217;d bought it from, but they weren&amp;#8217;t much&amp;nbsp;help.&lt;/p&gt;
&lt;p&gt;So I lodged a warranty repair request through the &lt;span class="caps"&gt;LG&lt;/span&gt; Australia website.
After a few days I received an email saying my device was an overseas
model so &lt;span class="caps"&gt;LG&lt;/span&gt; Australia didn&amp;#8217;t want to have anything to do with&amp;nbsp;it.&lt;/p&gt;
&lt;p&gt;This made me so&amp;nbsp;angry.&lt;/p&gt;
&lt;p&gt;I had purchased the phone in-store at &lt;span class="caps"&gt;JB&lt;/span&gt; Hi-Fi.  My understanding was that
&lt;span class="caps"&gt;JB&lt;/span&gt; only sold Australian stock.  I went to a store and asked a salesperson,
who confirmed that &lt;span class="caps"&gt;JB&lt;/span&gt; only sold Australian stock.  So some corporation here
are being cunts about this.  Either &lt;span class="caps"&gt;JB&lt;/span&gt; are selling overseas or grey import
stock and claiming it&amp;#8217;s Australian stock, or &lt;span class="caps"&gt;LG&lt;/span&gt; are full of&amp;nbsp;shit.&lt;/p&gt;
&lt;p&gt;I suspect the latter is more&amp;nbsp;likely.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m assuming that this is essentially an opening gambit on the part of &lt;span class="caps"&gt;LG&lt;/span&gt;,
who are trying to weasel their way out of their warranty obligations, as
well as their obligations under Australian consumer&amp;nbsp;law.&lt;/p&gt;
&lt;p&gt;Well, even though this meant I had to buy a new phone, I&amp;#8217;m not ready to
give up just yet.  There is now a principle at stake.  &lt;span class="caps"&gt;LG&lt;/span&gt; sold me a dodgy
phone, so they should at least fix&amp;nbsp;it.&lt;/p&gt;
&lt;p&gt;To be&amp;nbsp;continued&amp;#8230;&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related&amp;nbsp;Posts:&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2017/12/21/lg-nexus-5x-bootloop-death/"&gt;Death by bootloop of my Nexus&amp;nbsp;5X&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/03/17/android-nexus-7-slow-sluggish-laggy-after-lollipop-update/"&gt;Laggy&amp;nbsp;Lollipop&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="Android Nexus"></category></entry><entry><title>Death by bootloop of my Nexus 5X</title><link href="http://www.voidynullness.net/blog/2017/12/21/lg-nexus-5x-bootloop-death/" rel="alternate"></link><published>2017-12-21T00:00:00+11:00</published><updated>2017-12-21T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2017-12-21:/blog/2017/12/21/lg-nexus-5x-bootloop-death/</id><summary type="html">&lt;p class="first last"&gt;An obituary for my Nexus 5X &amp;#8212; taken too early by the&amp;nbsp;bootloop.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;span class="dquo"&gt;&amp;#8220;&lt;/span&gt;I was talking to my sister today, and guess what she said to&amp;nbsp;me&amp;#8230;&amp;#8221;&lt;/p&gt;
&lt;p&gt;Then silence, as my girlfriend paused for dramatic effect.  At least that&amp;#8217;s
what I thought it&amp;nbsp;was.&lt;/p&gt;
&lt;p&gt;I was on the phone to my girlfriend.  At least I thought I&amp;nbsp;was.&lt;/p&gt;
&lt;p&gt;I looked at my phone.  The screen was off, and the phone didn&amp;#8217;t respond to
touches or key presses.  Hmmm&amp;#8230;couldn&amp;#8217;t be the battery, I had just taken it
off the charger.  I held down the power key.  It started to&amp;nbsp;reboot.&lt;/p&gt;
&lt;p&gt;I called her&amp;nbsp;back.&lt;/p&gt;
&lt;p&gt;My girlfriend once again started to regale me with the latest installment
of interpersonal drama between herself and one of her sisters.  Then the
phone went dead again.  I looked at the screen.  It was rebooting again.
Hmmm&amp;#8230;had I inadvertently held down the power key, while steeling myself
to hear about the latest installment of interpersonal drama between my
girlfriend and one of her sisters?  Possibly, but I didn&amp;#8217;t think&amp;nbsp;so.&lt;/p&gt;
&lt;p&gt;Had my Nexus 5X become self-aware enough to know it no longer wanted to
hear about my girlfriend&amp;#8217;s interpersonal drama with her sisters?
Possibly, who knows what Google&amp;#8217;s machine learning algorithms are capable
of, but I didn&amp;#8217;t think&amp;nbsp;so.&lt;/p&gt;
&lt;p&gt;A third attempt at a phone conversation was also rudely interrupted by a
spontaneous reboot, at which point it was clear something was going on with
my phone.  Had the force of my girlfriend&amp;#8217;s sibling-induced rage remotely
fried my phone?  Possibly, but I didn&amp;#8217;t think&amp;nbsp;so.&lt;/p&gt;
&lt;p&gt;We gave up on having a phone conversation that night, and I never got to
find out what her sister had said to get her so riled up that day &amp;#8212; by the
time we next spoke she had moved on to another drama with another&amp;nbsp;sister.&lt;/p&gt;
&lt;p&gt;I didn&amp;#8217;t try to make any more calls that night, but soon noticed that even
when I put my phone down and didn&amp;#8217;t use it, after a while it would still
spontaneously reboot.  And I began to get the impression the time between
reboots was getting shorter and&amp;nbsp;shorter.&lt;/p&gt;
&lt;p&gt;At that point it was clear there was something wrong with my phone.  I then
realised that I didn&amp;#8217;t have the photos on the phone backed up.  I&amp;#8217;d had the
phone for around 15 months.  Any other data of any importance would be
synced to a cloud account, but I had deliberately turned off all cloud sync
on my photos.  So I had over a year&amp;#8217;s worth of photos on a phone that was
malfunctioning.  Nothing earthshatteringly important, but still, stuff I&amp;#8217;d
like to&amp;nbsp;retain.&lt;/p&gt;
&lt;p&gt;I found a &lt;span class="caps"&gt;USB&lt;/span&gt;-C cable, then spent the rest of the night copying photos from
the phone to my laptop &amp;#8212; in batches, in between reboots.  (I have never
been more grateful for &lt;span class="caps"&gt;USB&lt;/span&gt; 3 transfer&amp;nbsp;speeds!)&lt;/p&gt;
&lt;p&gt;It was a good thing I did too.  By the next day, the phone wouldn&amp;#8217;t even
boot up at all.  It would reboot itself constantly, before it had even
finished booting up.  Pretty soon it was rebooting at the splash&amp;nbsp;screen.&lt;/p&gt;
&lt;p&gt;Great, so my phone was fucked.  After just over a year.  Planned
obsolescence strikes again.  It&amp;#8217;s also the second Nexus branded device I
have owned that failed after a relatively short&amp;nbsp;time.&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related&amp;nbsp;Posts:&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/03/17/android-nexus-7-slow-sluggish-laggy-after-lollipop-update/"&gt;Laggy&amp;nbsp;Lollipop&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="Android Nexus"></category></entry><entry><title>VoidyBootstrap version 2.1 released</title><link href="http://www.voidynullness.net/blog/2017/01/31/voidy-bootstrap-2-1-release/" rel="alternate"></link><published>2017-01-31T00:00:00+11:00</published><updated>2017-01-31T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2017-01-31:/blog/2017/01/31/voidy-bootstrap-2-1-release/</id><summary type="html">&lt;p&gt;&lt;a class="reference external" href="http://www.voidynullness.net/page/voidy-bootstrap-pelican-theme/"&gt;VoidyBootstrap&lt;/a&gt; is a &lt;a class="reference external" href="http://getpelican.com/"&gt;Pelican&lt;/a&gt; theme based on Bootstrap 3 that I hacked together
when I first started using Pelican, and have been all too sporadically
updating&amp;nbsp;since.&lt;/p&gt;
&lt;p&gt;Version 2.1 has now been&amp;nbsp;released.&lt;/p&gt;
&lt;p&gt;This release is mostly just updates to dependencies (Bootstrap, Font
Awesome, etc) and some various minor fixes and&amp;nbsp;tweaks.&lt;/p&gt;
&lt;p&gt;The most significant changes are for compatibility with Pelican 3.7 (and&amp;nbsp;3.6).&lt;/p&gt;
&lt;p&gt;I don&amp;#8217;t believe any of the changes in this release break backward …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a class="reference external" href="http://www.voidynullness.net/page/voidy-bootstrap-pelican-theme/"&gt;VoidyBootstrap&lt;/a&gt; is a &lt;a class="reference external" href="http://getpelican.com/"&gt;Pelican&lt;/a&gt; theme based on Bootstrap 3 that I hacked together
when I first started using Pelican, and have been all too sporadically
updating&amp;nbsp;since.&lt;/p&gt;
&lt;p&gt;Version 2.1 has now been&amp;nbsp;released.&lt;/p&gt;
&lt;p&gt;This release is mostly just updates to dependencies (Bootstrap, Font
Awesome, etc) and some various minor fixes and&amp;nbsp;tweaks.&lt;/p&gt;
&lt;p&gt;The most significant changes are for compatibility with Pelican 3.7 (and&amp;nbsp;3.6).&lt;/p&gt;
&lt;p&gt;I don&amp;#8217;t believe any of the changes in this release break backward
compatibility, except for a few things related to the default sidebar&amp;nbsp;implementation.&lt;/p&gt;
&lt;p&gt;In VoidyBootstrap, the sidebar is optional, and the default is single
column mode.  The theme allows for an optional sidebar to be configured by
using the &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;SIDEBAR&lt;/span&gt;&lt;/tt&gt; option to specify the filename of a Jinja template
that will constitute the sidebar contents.  A basic sidebar template is
included as a starting point, but a custom template can be created and used&amp;nbsp;instead.&lt;/p&gt;
&lt;p&gt;For those using the built-in default sidebar, there&amp;#8217;s a few things to be
aware of if upgrading from version 2.0 to&amp;nbsp;2.1.&lt;/p&gt;
&lt;p&gt;Firstly, there is no longer a tag cloud by default.  This is because tag
cloud support has been moved from Pelican itself to a plugin in Pelican
3.7.  It therefore seemed the most logical option for the theme was to
remove the tag cloud, and provide an option to enable it for those who want
to configure the tag_cloud plugin.  You can of course roll your own tag
cloud template and incorporate that into the sidebar (or elsewhere).  I&amp;#8217;ve
provided a tag cloud template in &lt;tt class="docutils literal"&gt;sb_tagcloud.html&lt;/tt&gt;, which can be
incorporated into the default sidebar using the following setting in
&lt;tt class="docutils literal"&gt;pelicanconf.py&lt;/tt&gt;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
CUSTOM_SIDEBAR_MIDDLES = (&amp;quot;sb_links.html&amp;quot;, &amp;quot;sb_taglist.html&amp;quot;, )
&lt;/pre&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;sb_links.html&lt;/tt&gt; template fragment is only required if the &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;LINKS&lt;/span&gt;&lt;/tt&gt;
setting is being used.  Which is the other breaking change in this release:
the &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;LINKS&lt;/span&gt;&lt;/tt&gt; setting is now also disabled by default, and can be enabled
by incorporating &lt;tt class="docutils literal"&gt;sb_links.html&lt;/tt&gt; as shown&amp;nbsp;above.&lt;/p&gt;
&lt;p&gt;Thanks to everyone who contributed pull&amp;nbsp;requests.&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related&amp;nbsp;Posts:&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/06/01/voidy-bootstrap-pelican-theme-version-2/"&gt;What&amp;#8217;s new in VoidyBootstrap version&amp;nbsp;2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="Pelican"></category><category term="Python"></category><category term="VoidyBootstrap"></category></entry><entry><title>Upgrading to Pelican 3.7</title><link href="http://www.voidynullness.net/blog/2017/01/16/upgrading-pelican-3-7/" rel="alternate"></link><published>2017-01-16T00:00:00+11:00</published><updated>2017-01-16T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2017-01-16:/blog/2017/01/16/upgrading-pelican-3-7/</id><summary type="html">&lt;p class="first last"&gt;Some notes on upgrading an existing website to Pelican&amp;nbsp;3.7&lt;/p&gt;
</summary><content type="html">&lt;p&gt;The new year brings with it a new release of &lt;a class="reference external" href="http://getpelican.com/"&gt;Pelican&lt;/a&gt;.  Well, actually, &lt;a class="reference external" href="https://blog.getpelican.com/category/news.html"&gt;Pelican 3.7 was released&lt;/a&gt; last month, but it&amp;#8217;s in
these first few weeks of the new year that I find myself with some spare
moments to devote to trying out the latest version &amp;#8212; a task somewhat
overdue, having paid little attention to Pelican since version 3.5.  So in
this post I&amp;#8217;m going to have a look at changes in Pelican since version 3.5
that might be relevant when upgrading an existing&amp;nbsp;website.&lt;/p&gt;
&lt;div class="section" id="pelican-changes"&gt;
&lt;h2&gt;Pelican&amp;nbsp;changes&lt;/h2&gt;
&lt;p&gt;In general Pelican itself tends to be fairly backwards compatible, so often
all that&amp;#8217;s required is to upgrade the Pelican version in whatever virtual
Python environment you might be using.  However, there are often
interactions between themes and plugins that might break things when&amp;nbsp;upgrading.&lt;/p&gt;
&lt;p&gt;There were a few things that affected me and the combination of theme and
plugins that I was using after upgrading to Pelican&amp;nbsp;3.7.&lt;/p&gt;
&lt;p&gt;One is that the uppercase &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;PAGES&lt;/span&gt;&lt;/tt&gt; context variable available to themes &lt;a class="reference external" href="https://github.com/getpelican/pelican/pull/1767"&gt;has been
removed&lt;/a&gt;
in favour of the lowercase &lt;tt class="docutils literal"&gt;pages&lt;/tt&gt;.  Unfortuantely, many themes use the
uppercase version and therefore &lt;a class="reference external" href="https://github.com/getpelican/pelican-themes/issues/437"&gt;need to be updated&lt;/a&gt;
before they will work properly with Pelican&amp;nbsp;3.7.&lt;/p&gt;
&lt;p&gt;Another is that &lt;a class="reference external" href="https://github.com/getpelican/pelican/pull/1703"&gt;tag cloud support has been removed from Pelican itself&lt;/a&gt;
and moved to the &lt;a class="reference external" href="https://github.com/getpelican/pelican-plugins/tree/master/tag_cloud"&gt;tag_cloud plugin.&lt;/a&gt;
So if your site has a tag cloud, you&amp;#8217;ll now need to configure the&amp;nbsp;plugin.&lt;/p&gt;
&lt;p&gt;On a side note, I just recently noticed the &lt;a class="reference external" href="https://github.com/getpelican/pelican-plugins/tree/master/sitemap"&gt;sitemap plugin&lt;/a&gt;
now supports excluding URLs from the sitemap via regular expressions, which
I find incredibly useful, since I don&amp;#8217;t want tag or category pages in my&amp;nbsp;sitemaps.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="pelican-site-configuration"&gt;
&lt;h2&gt;Pelican site&amp;nbsp;configuration&lt;/h2&gt;
&lt;p&gt;While there&amp;#8217;s a variety of possible workflows with Pelican (it being a
command line tool after all) I assume it&amp;#8217;s fairly typical to have static
sites originally created using the &lt;a class="reference external" href="http://docs.getpelican.com/en/latest/quickstart.html"&gt;Pelican quickstart script.&lt;/a&gt;  This means
there&amp;#8217;s a Makefile (or Fabfile) that was created with a previous version of
Pelican that won&amp;#8217;t have enhancements or features present in recent&amp;nbsp;versions.&lt;/p&gt;
&lt;p&gt;So as I usually do when undertaking a Pelican upgrade (because I&amp;#8217;m kind of
anal retentive about such things), I ran quickstart to create a dummy
skeleton site, then compared it with previous versions, to see if there is
anything significant enough to incorporate into my site&amp;#8217;s existing&amp;nbsp;configuration.&lt;/p&gt;
&lt;p&gt;Only the Makefile had any differences of&amp;nbsp;note.&lt;/p&gt;
&lt;p&gt;A diff between a version 3.5 and 3.6 Makefile gives (abridged, differences
in echo output&amp;nbsp;ommitted):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;34a35,39
&amp;gt; RELATIVE ?= 0
&amp;gt; ifeq ($(RELATIVE), 1)
&amp;gt;     PELICANOPTS += --relative-urls
&amp;gt; endif

...

72a80,87
&amp;gt; serve-global:
&amp;gt; ifdef SERVER
&amp;gt;     cd $(OUTPUTDIR) &amp;amp;&amp;amp; $(PY) -m pelican.server 80 $(SERVER)
&amp;gt; else
&amp;gt;     cd $(OUTPUTDIR) &amp;amp;&amp;amp; $(PY) -m pelican.server 80 0.0.0.0
&amp;gt; endif
&amp;gt;
&amp;gt;
81,82c96
&amp;lt;     kill -9 `cat pelican.pid`
&amp;lt;     kill -9 `cat srv.pid`
&lt;span class="gd"&gt;---&lt;/span&gt;
&amp;gt;     $(BASEDIR)/develop_server.sh stop
110c124
&amp;lt; .PHONY: html help clean regenerate serve devserver publish ssh_upload rsync_upload dropbox_upload ftp_upload s3_upload cf_upload github
&lt;span class="gd"&gt;---&lt;/span&gt;
&amp;gt; .PHONY: html help clean regenerate serve serve-global devserver publish ssh_upload rsync_upload dropbox_upload ftp_upload s3_upload cf_upload github
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So the main changes are support of the new &lt;a class="reference external" href="https://github.com/getpelican/pelican/pull/1592"&gt;relative URLs option&lt;/a&gt;, along with some
changes to running the development&amp;nbsp;server.&lt;/p&gt;
&lt;p&gt;A diff of the version 3.6 and 3.7 Makefiles&amp;nbsp;gives:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;115c115
&amp;lt;     s3cmd sync $(OUTPUTDIR)/ s3://$(S3_BUCKET) --acl-public --delete-removed --guess-mime-type
&lt;span class="gd"&gt;---&lt;/span&gt;
&amp;gt;     s3cmd sync $(OUTPUTDIR)/ s3://$(S3_BUCKET) --acl-public --delete-removed --guess-mime-type --no-mime-magic --no-preserve
124c124
&amp;lt; .PHONY: html help clean regenerate serve serve-global devserver publish ssh_upload rsync_upload dropbox_upload ftp_upload s3_upload cf_upload github
&lt;span class="gd"&gt;---&lt;/span&gt;
&amp;gt; .PHONY: html help clean regenerate serve serve-global devserver stopserver publish ssh_upload rsync_upload dropbox_upload ftp_upload s3_upload cf_upload github
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There was also a tweak to &lt;tt class="docutils literal"&gt;develop_server.sh&lt;/tt&gt; in version&amp;nbsp;3.7:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;69c69
&amp;lt;   cd $OUTPUTDIR
&lt;span class="gd"&gt;---&lt;/span&gt;
&amp;gt;   mkdir -p $OUTPUTDIR &amp;amp;&amp;amp; cd $OUTPUTDIR
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h3&gt;Related&amp;nbsp;Posts:&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/30/upgrading-pelican-3-5/"&gt;Upgrading to Pelican&amp;nbsp;3.5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/01/23/upgrading-pelican-3-3/"&gt;Upgrading to Pelican&amp;nbsp;3.3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/06/01/voidy-bootstrap-pelican-theme-version-2/"&gt;What&amp;#8217;s New In VoidyBootstrap Version&amp;nbsp;2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="Pelican"></category><category term="Python"></category></entry><entry><title>Android Tabs: How to use TabLayout</title><link href="http://www.voidynullness.net/blog/2015/08/16/android-tablayout-design-support-library-tutorial/" rel="alternate"></link><published>2015-08-16T00:00:00+10:00</published><updated>2015-08-16T00:00:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2015-08-16:/blog/2015/08/16/android-tablayout-design-support-library-tutorial/</id><summary type="html">&lt;p class="first last"&gt;Android Tabs (part 2): Android tabs example using&amp;nbsp;TabLayout.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;This post presents a simple example of using &lt;a class="reference external" href="http://developer.android.com/reference/android/support/design/widget/TabLayout.html"&gt;TabLayout&lt;/a&gt;
from the Android &lt;a class="reference external" href="http://android-developers.blogspot.com.au/2015/05/android-design-support-library.html"&gt;Design Support Library&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s the second part in a series about implementing tabs on Android without
using any APIs deprecated in &lt;span class="caps"&gt;API&lt;/span&gt; level 21.  In the &lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/08/12/android-pagertabstrip-with-viewpager-and-appcompatactivity/"&gt;previous post&lt;/a&gt; I looked at
&lt;a class="reference external" href="http://developer.android.com/reference/android/support/v4/view/PagerTabStrip.html"&gt;PagerTabStrip&lt;/a&gt;,
which works well enough.  However, &lt;tt class="docutils literal"&gt;TabLayout&lt;/tt&gt; provides a look and feel
more in keeping with Material Design conventions.  In this post
we&amp;#8217;ll convert the example from the previous post to use &lt;tt class="docutils literal"&gt;TabLayout&lt;/tt&gt;
instead of &lt;tt class="docutils literal"&gt;PagerTabStrip&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;The first thing we need to do is include the Design Support Library in the
&lt;tt class="docutils literal"&gt;dependencies&lt;/tt&gt; of the app&amp;#8217;s &lt;tt class="docutils literal"&gt;build.gradle&lt;/tt&gt; file:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
compile 'com.android.support:design:22.2.0'
&lt;/pre&gt;
&lt;p&gt;In the activity layout (&lt;tt class="docutils literal"&gt;activity_tab_layout.xml&lt;/tt&gt;) we place a &lt;tt class="docutils literal"&gt;TabLayout&lt;/tt&gt;
widget and a &lt;tt class="docutils literal"&gt;ViewPager&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;LinearLayout&lt;/span&gt; &lt;span class="na"&gt;xmlns:android=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://schemas.android.com/apk/res/android&amp;quot;&lt;/span&gt;
    &lt;span class="na"&gt;xmlns:app=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://schemas.android.com/apk/res-auto&amp;quot;&lt;/span&gt;
    &lt;span class="na"&gt;android:orientation=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;vertical&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;android:padding=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;4dip&amp;quot;&lt;/span&gt;
    &lt;span class="na"&gt;android:gravity=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;center_horizontal&amp;quot;&lt;/span&gt;
    &lt;span class="na"&gt;android:layout_width=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;match_parent&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;android:layout_height=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;match_parent&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;android.support.design.widget.TabLayout&lt;/span&gt;
        &lt;span class="na"&gt;android:id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;@+id/tabs&amp;quot;&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_width=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;match_parent&amp;quot;&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_height=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;wrap_content&amp;quot;&lt;/span&gt;
        &lt;span class="na"&gt;app:tabMode=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;fixed&amp;quot;&lt;/span&gt;
        &lt;span class="na"&gt;app:tabGravity=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;fill&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;android.support.v4.view.ViewPager&lt;/span&gt; &lt;span class="na"&gt;xmlns:android=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://schemas.android.com/apk/res/android&amp;quot;&lt;/span&gt;
        &lt;span class="na"&gt;xmlns:tools=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://schemas.android.com/tools&amp;quot;&lt;/span&gt;
        &lt;span class="na"&gt;android:id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;@+id/pager&amp;quot;&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_width=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;match_parent&amp;quot;&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_height=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;match_parent&amp;quot;&lt;/span&gt;
        &lt;span class="na"&gt;tools:context=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;net.voidynullness.android.tabitytabs.TabLayoutActivity&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;/android.support.v4.view.ViewPager&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/LinearLayout&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There&amp;#8217;s a number of useful attributes for &lt;tt class="docutils literal"&gt;TabLayout&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Above, we set &lt;tt class="docutils literal"&gt;tabMode&lt;/tt&gt; to &lt;tt class="docutils literal"&gt;fixed&lt;/tt&gt; to show all tabs.  The other alternative is
&lt;tt class="docutils literal"&gt;scrollable&lt;/tt&gt;, where the tabs can be scrolled (similar to&amp;nbsp;PagerTabStrip).&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;tabGravity&lt;/tt&gt; determines alignment of tabs.  It can be set to &lt;tt class="docutils literal"&gt;fill&lt;/tt&gt; to
space out tabs to fill available space, or &lt;tt class="docutils literal"&gt;centre&lt;/tt&gt; to cluster the tabs
in the middle of the &lt;tt class="docutils literal"&gt;TabLayout&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;If we wanted to we could programmatically add tabs using the &lt;tt class="docutils literal"&gt;addTab()&lt;/tt&gt;
and &lt;tt class="docutils literal"&gt;setText()&lt;/tt&gt; methods:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;tabLayout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TabLayout&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;findViewById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tabs&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;tabLayout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addTab&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tabLayout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newTab&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;setText&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Tab 1&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;tabLayout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addTab&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tabLayout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newTab&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;setText&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Tab 2&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;tabLayout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addTab&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tabLayout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newTab&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;setText&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Tab 3&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But we&amp;#8217;re not going to do things that way for this&amp;nbsp;example.&lt;/p&gt;
&lt;p&gt;Instead, we will create a hosting activity (that subclasses &lt;a class="reference external" href="https://developer.android.com/reference/android/support/v7/app/AppCompatActivity.html"&gt;AppCompatActivity&lt;/a&gt;)
which will use the above layout, and wire up the &lt;tt class="docutils literal"&gt;ViewPager&lt;/tt&gt; to the
&lt;tt class="docutils literal"&gt;TabLayout&lt;/tt&gt;.  The &lt;tt class="docutils literal"&gt;ViewPager&lt;/tt&gt; will take care of fragment switching for
us (&lt;tt class="docutils literal"&gt;TabLayoutActivity.java&lt;/tt&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;net.voidynullness.android.tabitytabs&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.os.Bundle&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.support.design.widget.TabLayout&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.support.v4.view.ViewPager&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.support.v7.app.AppCompatActivity&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;


&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TabLayoutActivity&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;AppCompatActivity&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Bundle&lt;/span&gt; &lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onCreate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;setContentView&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;activity_tab_layout&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;TabLayout&lt;/span&gt; &lt;span class="n"&gt;tabs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TabLayout&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;findViewById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;tabs&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;ViewPager&lt;/span&gt; &lt;span class="n"&gt;pager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ViewPager&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;findViewById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;pager&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;TabsPagerAdapter&lt;/span&gt; &lt;span class="n"&gt;adapter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;TabsPagerAdapter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getSupportFragmentManager&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

        &lt;span class="n"&gt;pager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setAdapter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;adapter&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;tabs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setupWithViewPager&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pager&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;No changes are required to our &lt;a class="reference external" href="http://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter.html"&gt;FragmentPagerAdapter&lt;/a&gt;
(&lt;tt class="docutils literal"&gt;TabsPagerAdapter&lt;/tt&gt;) or sample fragment class (&lt;tt class="docutils literal"&gt;PageFragment&lt;/tt&gt;) from the
previous post, so we can reuse those without changes.  (See the
&lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/08/12/android-pagertabstrip-with-viewpager-and-appcompatactivity/"&gt;previous post for details and implementation&lt;/a&gt; of these two&amp;nbsp;classes).&lt;/p&gt;
&lt;p&gt;The above activity&amp;#8217;s &lt;tt class="docutils literal"&gt;onCreate()&lt;/tt&gt; instantiates a new
&lt;tt class="docutils literal"&gt;TabsPagerAdapter&lt;/tt&gt;, which is our subclass of &lt;tt class="docutils literal"&gt;FragmentPagerAdapter&lt;/tt&gt;, and
passes it to the &lt;tt class="docutils literal"&gt;ViewPager&lt;/tt&gt;, which handles most of the work of
switching between tabs and fragments.  To configure the &lt;tt class="docutils literal"&gt;TabLayout&lt;/tt&gt; we just
need to call &lt;tt class="docutils literal"&gt;setupWithViewPager()&lt;/tt&gt; and pass in the &lt;tt class="docutils literal"&gt;ViewPager&lt;/tt&gt; we just
configured.  &lt;a class="reference external" href="http://developer.android.com/reference/android/support/design/widget/TabLayout.html#setupWithViewPager%28android.support.v4.view.ViewPager%29"&gt;setupWithViewPager()&lt;/a&gt;
is a convenience method that sets
things up for the common use case of letting a PagerAdapter configure the
tabs.  (The PagerAdapter in this case being &lt;tt class="docutils literal"&gt;TabsPagerAdapter&lt;/tt&gt;.)&lt;/p&gt;
&lt;p&gt;The result is a tabbed layout with a reasonably Material Design compliant&amp;nbsp;look:&lt;/p&gt;
&lt;img alt="TabLayout screenshot" class="center-block" src="http://www.voidynullness.net/images/android-tabs-tablayout.png" /&gt;
&lt;p&gt;The &lt;a class="reference external" href="https://bitbucket.org/robulouski/androidtabitytabs/src"&gt;complete source code is on&amp;nbsp;BitBucket.&lt;/a&gt;&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related&amp;nbsp;Posts:&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/08/12/android-pagertabstrip-with-viewpager-and-appcompatactivity/"&gt;Using PagerTabStrip with&amp;nbsp;ViewPager&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="Android"></category></entry><entry><title>Android Tabs: Using PagerTabStrip with ViewPager</title><link href="http://www.voidynullness.net/blog/2015/08/12/android-pagertabstrip-with-viewpager-and-appcompatactivity/" rel="alternate"></link><published>2015-08-12T00:00:00+10:00</published><updated>2015-08-12T00:00:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2015-08-12:/blog/2015/08/12/android-pagertabstrip-with-viewpager-and-appcompatactivity/</id><summary type="html">&lt;p class="first last"&gt;Android Tabs (part 1): Android tabs example using&amp;nbsp;PagerTabStrip.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;The release of Android &lt;span class="caps"&gt;API&lt;/span&gt; level 21 (Lollipop) deprecated a number of APIs
&amp;#8212; in particular, anything to do with ActionBar&amp;nbsp;tabs.&lt;/p&gt;
&lt;p&gt;This means a common way of implementing tabbed navigation is now
discouraged, but things have not been particularly clear as to what
replaces these deprecated APIs.  Of course, deprecated doesn&amp;#8217;t mean
unusable.  Deprecated though they are, ActionBar tabs will still&amp;nbsp;work.&lt;/p&gt;
&lt;p&gt;But anyone starting a new long term Android project might reasonably baulk
at firing up the Android Studio &amp;#8220;New Project&amp;#8221; code wizard only to be
greeted with a whole lot of deprecation warnings in the generated code for
anything with tabs.  Even if the resulting code does actually work.  For&amp;nbsp;now.&lt;/p&gt;
&lt;p&gt;So what are our options if we want tabs, but don&amp;#8217;t want to use any of these
deprecated&amp;nbsp;APIs?&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://plus.google.com/+KirillGrouchnikov/posts/Cwk7joBV3AC"&gt;Roll your own tabs implementation&lt;/a&gt;
(Obviously not helpful to any developers dealing with onerous&amp;nbsp;deadlines.)&lt;/li&gt;
&lt;li&gt;Use a third party&amp;nbsp;implementation.&lt;/li&gt;
&lt;li&gt;Incorporate or adapt the implementation of tabs in either the Android &lt;span class="caps"&gt;SDK&lt;/span&gt;
&lt;a class="reference external" href="https://developer.android.com/samples/SlidingTabsBasic/project.html"&gt;Sliding Tabs sample&lt;/a&gt; or
the Google &lt;a class="reference external" href="https://github.com/google/iosched"&gt;iosched&lt;/a&gt;&amp;nbsp;app.&lt;/li&gt;
&lt;li&gt;Use the venerable &lt;a class="reference external" href="http://developer.android.com/reference/android/support/v4/view/PagerTabStrip.html"&gt;PagerTabStrip&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Use &lt;a class="reference external" href="http://developer.android.com/reference/android/support/design/widget/TabLayout.html"&gt;TabLayout&lt;/a&gt;
from Google&amp;#8217;s newish &lt;a class="reference external" href="http://android-developers.blogspot.com.au/2015/05/android-design-support-library.html"&gt;Android Design Support Library&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;#8217;ll explore the last two options in this tutorial.  In this post I&amp;#8217;ll show
a simple implementation of tabs using &lt;tt class="docutils literal"&gt;PagerTabStrip&lt;/tt&gt;.  In the next post I&amp;#8217;ll
look at &lt;tt class="docutils literal"&gt;TabLayout&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;PagerTabStrip works in conjunction with &lt;a class="reference external" href="http://developer.android.com/reference/android/support/v4/view/ViewPager.html"&gt;ViewPager&lt;/a&gt;,
and plays well with &lt;a class="reference external" href="https://developer.android.com/reference/android/support/v7/app/AppCompatActivity.html"&gt;AppCompatActivity&lt;/a&gt;
(although the results aren&amp;#8217;t exactly Material Design&amp;nbsp;friendly).&lt;/p&gt;
&lt;p&gt;For this example project we&amp;#8217;ll use &lt;tt class="docutils literal"&gt;AppCompatActivity&lt;/tt&gt; as our Activity class,
and &lt;tt class="docutils literal"&gt;Theme.AppCompat.Light.DarkActionBar&lt;/tt&gt; as the application&amp;nbsp;theme.&lt;/p&gt;
&lt;p&gt;We&amp;#8217;ll start with the layout for our activity
(&lt;tt class="docutils literal"&gt;activity_pager_tab_strip.xml&lt;/tt&gt;), which in this case will just be a
&lt;tt class="docutils literal"&gt;ViewPager&lt;/tt&gt; containing a &lt;tt class="docutils literal"&gt;PagerTabStrip&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;android.support.v4.view.ViewPager&lt;/span&gt; &lt;span class="na"&gt;xmlns:android=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://schemas.android.com/apk/res/android&amp;quot;&lt;/span&gt;
    &lt;span class="na"&gt;xmlns:tools=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://schemas.android.com/tools&amp;quot;&lt;/span&gt;
    &lt;span class="na"&gt;android:id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;@+id/pager&amp;quot;&lt;/span&gt;
    &lt;span class="na"&gt;android:layout_width=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;match_parent&amp;quot;&lt;/span&gt;
    &lt;span class="na"&gt;android:layout_height=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;match_parent&amp;quot;&lt;/span&gt;
    &lt;span class="na"&gt;tools:context=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;net.voidynullness.android.tabitytabs.PagerTabStripActivity&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;android.support.v4.view.PagerTabStrip&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_width=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;match_parent&amp;quot;&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_height=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;wrap_content&amp;quot;&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_gravity=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;top&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/android.support.v4.view.ViewPager&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;layout_gravity&lt;/tt&gt; is set to &amp;#8220;top&amp;#8221; so that the tabs are displayed at the top of
the &lt;tt class="docutils literal"&gt;ViewPager&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;The activity code (&lt;tt class="docutils literal"&gt;PagerTabStripActivity.java&lt;/tt&gt;) is fairly&amp;nbsp;straightforward:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;net.voidynullness.android.tabitytabs&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.os.Bundle&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.support.v4.view.ViewPager&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.support.v7.app.AppCompatActivity&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PagerTabStripActivity&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;AppCompatActivity&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Bundle&lt;/span&gt; &lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onCreate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;setContentView&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;activity_pager_tab_strip&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;TabsPagerAdapter&lt;/span&gt; &lt;span class="n"&gt;adapter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;TabsPagerAdapter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getSupportFragmentManager&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="n"&gt;ViewPager&lt;/span&gt; &lt;span class="n"&gt;pager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ViewPager&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;findViewById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;pager&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;pager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setAdapter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;adapter&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There&amp;#8217;s not much going on in the Activity &amp;#8212; it&amp;#8217;s basically just
configuring the &lt;tt class="docutils literal"&gt;ViewPager&lt;/tt&gt; by giving it a suitable adapter object.  In
this case the adapter class is &lt;tt class="docutils literal"&gt;TabsPagerAdapter&lt;/tt&gt;, which is our subclass of
&lt;a class="reference external" href="http://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter.html"&gt;FragmentPagerAdapter&lt;/a&gt;
(see below).  Notice that we need to pass a &lt;tt class="docutils literal"&gt;FragmentManager&lt;/tt&gt; to the
adapter, and here we&amp;#8217;re passing the support library fragment manager, since
we&amp;#8217;re using &lt;tt class="docutils literal"&gt;AppCompatActivity&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;TabsPagerAdapter&lt;/tt&gt; is a subclass of &lt;tt class="docutils literal"&gt;FragmentPagerAdapter&lt;/tt&gt;, and it&amp;#8217;s
here that the fragments corresponding to each tab page are instantiated,
and tab title text is defined (&lt;tt class="docutils literal"&gt;TabsPagerAdapter.java&lt;/tt&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;net.voidynullness.android.tabitytabs&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.support.v4.app.Fragment&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.support.v4.app.FragmentManager&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.support.v4.app.FragmentPagerAdapter&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;


&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TabsPagerAdapter&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;FragmentPagerAdapter&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;TabsPagerAdapter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FragmentManager&lt;/span&gt; &lt;span class="n"&gt;fm&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fm&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Fragment&lt;/span&gt; &lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;PageFragment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;getCount&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;CharSequence&lt;/span&gt; &lt;span class="nf"&gt;getPageTitle&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;TAB &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It&amp;#8217;s about as minimal as a &lt;tt class="docutils literal"&gt;FragmentPagerAdapter&lt;/tt&gt; can be.  At the very
least, subclasses of &lt;tt class="docutils literal"&gt;FragmentPagerAdapter&lt;/tt&gt; must implement &lt;tt class="docutils literal"&gt;getItem()&lt;/tt&gt;
and &lt;tt class="docutils literal"&gt;getCount()&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;getItem()&lt;/tt&gt; is expected to return the fragment for the specified
position.  &lt;a class="reference external" href="http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/support/v4/app/FragmentPagerAdapter.java#FragmentPagerAdapter.instantiateItem%28android.view.ViewGroup%2Cint%29"&gt;Internally,&lt;/a&gt;
&lt;tt class="docutils literal"&gt;FragmentPagerAdapter&lt;/tt&gt; calls &lt;tt class="docutils literal"&gt;getItem()&lt;/tt&gt; to instantiate
fragments, and uses the &lt;tt class="docutils literal"&gt;FragmentManager&lt;/tt&gt; passed into the constructor to
manage these&amp;nbsp;fragments.&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;getCount()&lt;/tt&gt; should return the total number of&amp;nbsp;fragments.&lt;/p&gt;
&lt;p&gt;We&amp;#8217;re also overriding &lt;tt class="docutils literal"&gt;getPageTitle()&lt;/tt&gt;, which is used to set the text for
each tab&amp;nbsp;position.&lt;/p&gt;
&lt;p&gt;So we have our &lt;tt class="docutils literal"&gt;ViewPager&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;FragmentPagerAdapter&lt;/tt&gt;, now we need a
fragment to actually display something.  We&amp;#8217;ll call our simple placeholder
fragment class &lt;tt class="docutils literal"&gt;PageFragment&lt;/tt&gt;.  It will just display a text string on
the screen to indicate which fragment &amp;#8220;page&amp;#8221; is currently selected
(&lt;tt class="docutils literal"&gt;PageFragment.java&lt;/tt&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;net.voidynullness.android.tabitytabs&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.support.v4.app.Fragment&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.os.Bundle&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.view.LayoutInflater&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.view.View&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.view.ViewGroup&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.widget.TextView&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;


&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PageFragment&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;Fragment&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;ARG_PAGE_NUMBER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;page_number&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;PageFragment&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;PageFragment&lt;/span&gt; &lt;span class="nf"&gt;newInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;PageFragment&lt;/span&gt; &lt;span class="n"&gt;fragment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;PageFragment&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;Bundle&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Bundle&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;putInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ARG_PAGE_NUMBER&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;fragment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setArguments&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fragment&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;View&lt;/span&gt; &lt;span class="nf"&gt;onCreateView&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LayoutInflater&lt;/span&gt; &lt;span class="n"&gt;inflater&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ViewGroup&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
                             &lt;span class="n"&gt;Bundle&lt;/span&gt; &lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;View&lt;/span&gt; &lt;span class="n"&gt;rootView&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;inflater&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;inflate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fragment_page_layout&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;TextView&lt;/span&gt; &lt;span class="n"&gt;txt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TextView&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;rootView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findViewById&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;page_number_label&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getArguments&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ARG_PAGE_NUMBER&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;txt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setText&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Page %d&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;rootView&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;a class="reference external" href="http://www.androiddesignpatterns.com/2012/05/using-newinstance-to-instantiate.html"&gt;newInstance() idiom&lt;/a&gt;
of a static factory method is used to create and initialise new&amp;nbsp;fragments.&lt;/p&gt;
&lt;p&gt;As shown above, our fragment adapter (&lt;tt class="docutils literal"&gt;TabsPagerAdapter&lt;/tt&gt;) creates
&lt;tt class="docutils literal"&gt;PageFragment&lt;/tt&gt; fragments by calling the static &lt;tt class="docutils literal"&gt;newInstance()&lt;/tt&gt; method
and passing in the page/tab number of that particular instance.
Inside &lt;tt class="docutils literal"&gt;newInstance()&lt;/tt&gt;, the page number is saved as an argument&amp;nbsp;bundle.&lt;/p&gt;
&lt;p&gt;In &lt;tt class="docutils literal"&gt;onCreateView()&lt;/tt&gt;, the &lt;tt class="docutils literal"&gt;TextView&lt;/tt&gt; contents are updated to display the
page number, which is retrieved from the&amp;nbsp;arguments.&lt;/p&gt;
&lt;p&gt;The corresponding layout file for our &lt;tt class="docutils literal"&gt;PageFragment&lt;/tt&gt; class simply
contains a single &lt;tt class="docutils literal"&gt;TextView&lt;/tt&gt; to display the page number
(&lt;tt class="docutils literal"&gt;fragment_page_layout.xml&lt;/tt&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;RelativeLayout&lt;/span&gt; &lt;span class="na"&gt;xmlns:android=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://schemas.android.com/apk/res/android&amp;quot;&lt;/span&gt;
    &lt;span class="na"&gt;xmlns:tools=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://schemas.android.com/tools&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;android:layout_width=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;match_parent&amp;quot;&lt;/span&gt;
    &lt;span class="na"&gt;android:layout_height=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;match_parent&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;android:paddingLeft=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;@dimen/activity_horizontal_margin&amp;quot;&lt;/span&gt;
    &lt;span class="na"&gt;android:paddingRight=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;@dimen/activity_horizontal_margin&amp;quot;&lt;/span&gt;
    &lt;span class="na"&gt;android:paddingTop=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;@dimen/activity_vertical_margin&amp;quot;&lt;/span&gt;
    &lt;span class="na"&gt;android:paddingBottom=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;@dimen/activity_vertical_margin&amp;quot;&lt;/span&gt;
    &lt;span class="na"&gt;tools:context=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;net.voidynullness.android.tabitytabs.PageFragment&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;TextView&lt;/span&gt; &lt;span class="na"&gt;android:id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;@+id/page_number_label&amp;quot;&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_width=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;match_parent&amp;quot;&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_height=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;wrap_content&amp;quot;&lt;/span&gt;
        &lt;span class="na"&gt;android:textAppearance=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;@android:style/TextAppearance.Large&amp;quot;&lt;/span&gt;
        &lt;span class="na"&gt;android:gravity=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;center&amp;quot;&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_centerVertical=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;true&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/RelativeLayout&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The result is three fragments, that can be switched by swiping or selecting the
appropriate&amp;nbsp;tab:&lt;/p&gt;
&lt;img alt="PagerTabStrip screenshot" class="center-block" src="http://www.voidynullness.net/images/android-tabs-pagertabstrip.png" /&gt;
&lt;p&gt;The &lt;a class="reference external" href="https://bitbucket.org/robulouski/androidtabitytabs/src"&gt;complete source code for this example is on&amp;nbsp;BitBucket.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In &lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/08/16/android-tablayout-design-support-library-tutorial/"&gt;the next post&lt;/a&gt;,
I&amp;#8217;ll take a look at an alternative to &lt;tt class="docutils literal"&gt;PagerTabStrip&lt;/tt&gt; &amp;#8212; &lt;tt class="docutils literal"&gt;TabLayout&lt;/tt&gt;
from the Android Design Support Library &amp;#8212; which provides similar
functionality but is more in keeping with Material Design&amp;nbsp;conventions.&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related&amp;nbsp;Posts:&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/08/16/android-tablayout-design-support-library-tutorial/"&gt;How to use&amp;nbsp;TabLayout&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="Android"></category></entry><entry><title>Big Government Puppies</title><link href="http://www.voidynullness.net/blog/2015/08/02/big-government-puppies/" rel="alternate"></link><published>2015-08-02T00:00:00+10:00</published><updated>2015-08-02T00:00:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2015-08-02:/blog/2015/08/02/big-government-puppies/</id><summary type="html">&lt;p class="first last"&gt;Telecommunications and other things Attorney-General George Brandis knows nothing&amp;nbsp;about.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;When training puppies, apparently consistency is really&amp;nbsp;important.&lt;/p&gt;
&lt;p&gt;If you want your puppy to stay off the furniture, then they should never be
allowed on the furniture.  Ever.  Mixed messages don&amp;#8217;t work.  Puppies
cannot understand nuance.  (Come to think of it, neither can
politicians, it seems.)  If the puppy ever jumps on the furniture, they
should be gently but firmly removed.  Every time.  So that they eventually
realise they are not allowed on the&amp;nbsp;furniture.&lt;/p&gt;
&lt;p&gt;If, in moments of weakness, they puppy is ever allowed on the furniture, it
undermines the message &amp;#8212; and the owner&amp;#8217;s authority.  The dog will
eventually realise its owner is weak, and can be exploited.  They are then
more likely to keep pushing their luck, constantly jumping on the couch in
the hope they may be allowed to remain there.  They might even get the idea
the furniture is their territory, and get aggressive if anyone tries to
move&amp;nbsp;them.&lt;/p&gt;
&lt;p&gt;Being more of a cat person, I have no idea if this is&amp;nbsp;true.&lt;/p&gt;
&lt;p&gt;But in any case, it strikes me that this is a weirdly apt analogy for the
relationship between us, and the politicians who supposedly represent our&amp;nbsp;interests.&lt;/p&gt;
&lt;p&gt;Politicians, much like mischievous puppies, will always try to push their
luck.  They will try to get away with as much as they can.  Much like we
shouldn&amp;#8217;t allow our pets to shit on the carpet and have free reign over our
furniture, we shouldn&amp;#8217;t allow our politicians to blithely expand their
powers, remove prudent oversight, or eschew&amp;nbsp;accountability.&lt;/p&gt;
&lt;p&gt;For an example of what happens when we do, we just need to take a look at
what&amp;#8217;s been happening in the Australian telecommunications industry,
especially since the Abbott government was&amp;nbsp;elected.&lt;/p&gt;
&lt;p&gt;First, this government destroyed all that was good about the
&lt;span class="caps"&gt;NBN&lt;/span&gt;.  While we can speculate about why exactly they might have wanted
to do this (was it &lt;a class="reference external" href="https://theconversation.com/news-corp-australia-vs-the-nbn-is-it-really-all-about-foxtel-16768"&gt;for the benefit of Rupert Murdoch&amp;#8217;s media empire?&lt;/a&gt;),
I suspect they did it partly out of ignorance &amp;#8212; not understanding the
social and economic benefits a universal fibre network would bring &amp;#8212; but
mostly just because they could.  They burned the &lt;span class="caps"&gt;NBN&lt;/span&gt; and scorched the earth
afterwards, just to see if they could get away with it.  And they did get
away with it.  Because we didn&amp;#8217;t push back strongly&amp;nbsp;enough.&lt;/p&gt;
&lt;p&gt;Of course, anyone thinking that was the end of the Coalition&amp;#8217;s interest in
screwing up the tech industry would have been profoundly naive.  Especially
with an Attorney-General like George Brandis, whose ego and sense of
infallibility is matched only by his complete ignorance of the
telecommunications industry and anything&amp;nbsp;technical.&lt;/p&gt;
&lt;p&gt;It was only the&amp;nbsp;beginning.&lt;/p&gt;
&lt;p&gt;After a hobbled &lt;span class="caps"&gt;NBN&lt;/span&gt;, we got the controversial mandatory data
retention.  There is no evidence that data retention is effective in
reducing crime or terrorism, it possibly makes us &lt;a class="reference external" href="http://www.theregister.co.uk/2015/07/13/attorneygeneral_wont_rule_out_metadata_stored_on_usb_drive_in_a_shed/"&gt;less safe&lt;/a&gt;
because our metadata will be an irresistible target for hackers and
identity thieves, and it will be &lt;a class="reference external" href="http://www.theregister.co.uk/2015/05/17/your_metadata_and_the_cost_of_collecting_it_belongs_on_your_phone_and_internet_bill/"&gt;really expensive.&lt;/a&gt;
Not to mention the burden and red tape it imposes on the telcos,
and the inevitable &lt;a class="reference external" href="http://www.theregister.co.uk/2015/05/14/ludlam_bells_data_retention_cat_border_force_wants_access_too/"&gt;scope&amp;nbsp;creep&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;But this government didn&amp;#8217;t stop there.  After that was the
&lt;a class="reference external" href="http://visibly-banned.tumblr.com/"&gt;website blocking laws,&lt;/a&gt;
presumably to appease large corporate donors to the
Liberal party, like Village Roadshow.  Once again, despite no evidence
website blocking will be effective at its supposed purpose of
preventing illegal downloading &amp;#8212; and considerable international
evidence that it won&amp;#8217;t.  And once again adding costs and red tape for
the&amp;nbsp;telcos.&lt;/p&gt;
&lt;p&gt;They came for our &lt;span class="caps"&gt;NBN&lt;/span&gt;, and we did nothing that stopped them, so we
missed out on fast fibre broadband.  Then they came for our privacy,
and we did nothing that stopped them, so we got data retention.  Then
they came for our websites, and we did nothing that stopped them, so we got
website blocking and internet&amp;nbsp;censorship.&lt;/p&gt;
&lt;p&gt;Now, Brandis is once again meddling in areas outside both his
portfolio and expertise &amp;#8212; with predictably dire&amp;nbsp;results.&lt;/p&gt;
&lt;p&gt;The Attorney-General&amp;#8217;s Department is planning to introduce more stupid
national security legislation targeting telecommunications companies (&lt;em&gt;The
Telecommunications and Other Legislation Amendment Bill 2015&lt;/em&gt;) and the
telcos are &lt;a class="reference external" href="http://www.abc.net.au/news/2015-07-22/telcos-draw-the-line-at-governments-latest-security-laws/6638464"&gt;really unhappy&lt;/a&gt;.
If these laws pass, we will have a guy who doesn&amp;#8217;t know what metadata
means, and who is confused about even the most basic technical details of
the internet &amp;#8212; like the &lt;a class="reference external" href="http://www.zdnet.com/article/brandis-ditches-conference-after-disastrous-data-retention-interview/"&gt;difference between &lt;span class="caps"&gt;DNS&lt;/span&gt; and &lt;span class="caps"&gt;IP&lt;/span&gt; addresses&lt;/a&gt; &amp;#8212; being
able to dictate to ISPs what kind of technology they are allowed to use,
and to interfere at will with the day to day operations of telcos by
requesting arbitrary documents and&amp;nbsp;information.&lt;/p&gt;
&lt;p&gt;The proposed legislation exhibits all the typical problems of government
overreach.  These laws are intrusive and will be expensive to implement.
The legislation is vague and there is no justification for these new
government powers &amp;#8212; it&amp;#8217;s unclear what
&lt;a class="reference external" href="http://www.theregister.co.uk/2015/07/22/oz_carriers_try_to_head_off_government_telco_security_bill/"&gt;problems these laws are trying to solve.&lt;/a&gt;
There has also been &lt;a class="reference external" href="http://www.michellerowland.com.au/transcript_fairfax_breaking_politics_22_july_2015"&gt;too little consultation with the&amp;nbsp;industry&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Even at the best of times, politicians and government seem to act on the
mistaken belief that there is no problem that can&amp;#8217;t be solved with
legislation &amp;#8212; and without unintentional consequences.  &lt;span class="caps"&gt;IT&lt;/span&gt; security is a
difficult problem, but it&amp;#8217;s not one that gets any easier with the
Attorney-General&amp;#8217;s department breathing down the neck of the entire
industry.  &lt;span class="caps"&gt;IT&lt;/span&gt; security certainly doesn&amp;#8217;t get any easier with technically
clueless government bureaucrats trying to dictate technology choices.  And
even when governments act with the best of intentions &amp;#8212; which is not the
case here &amp;#8212; there is always the risk they will make something worse.
Which is why we must be vigilant (and suspicious) of all attempts at
governments expanding their powers, and curtailing&amp;nbsp;ours.&lt;/p&gt;
&lt;p&gt;If politicians are not put in their place by the electorate, they end up
making stupid laws like this.  We end up with a situation where politicians
end up thinking they are better placed to dictate security than computer
security&amp;nbsp;experts.&lt;/p&gt;
&lt;p&gt;The telcos are now &lt;a class="reference external" href="http://www.zdnet.com/article/australian-telcos-face-more-national-security-regulation/"&gt;pushing back,&lt;/a&gt;
but I suspect &lt;a class="reference external" href="http://www.zdnet.com/article/telcos-hit-back-against-national-security-law-proposal/"&gt;their protests&lt;/a&gt;
are a case of too little too&amp;nbsp;late.&lt;/p&gt;
&lt;p&gt;Like a puppy who was constantly allowed to sleep on the couch, and so
grows up to be a dog expecting that privilege, they government now knows
it can get away with messing with the telecommunications industry in
whatever way it sees fit &amp;#8212; and it&amp;#8217;s not going to give up that privilege
without a fight.  It&amp;#8217;s certainly not just going to back down at the
first sign of&amp;nbsp;resistance.&lt;/p&gt;
&lt;p&gt;A dog owner who never properly trained his puppy to stay off
the couch &amp;#8212; who perhaps only meekly objected when the puppy jumped on
the couch  &amp;#8212; has only themselves to blame if the puppy grew up into a
dog that refuses to get off the&amp;nbsp;furniture.&lt;/p&gt;
&lt;p&gt;So we &amp;#8212; as the consumers who will end up paying for all of this &amp;#8212; along
with the telcos, have only have ourselves to blame.  Because we didn&amp;#8217;t
fight back strongly&amp;nbsp;enough.&lt;/p&gt;
&lt;p&gt;With the possibly exception of iiNet, the telcos put up weak
resistance to the data retention and website blocking laws, which gave
the government more confidence in introducing further intrusion into
their&amp;nbsp;operations.&lt;/p&gt;
&lt;p&gt;It seems when it comes to combating government overreach, we can&amp;#8217;t afford
to sit back, and pick and chose our battles.  We need to fight constantly
and consistently.  If we want our puppies to stay off the couch, we need to
be consistently firm with keeping them off the couch.  So with our
meddlesome politicians, we need to constantly fight them off from taking
away our freedoms, civil liberties and digital rights.  We can&amp;#8217;t just
think, &amp;#8220;I have nothing to hide, so I don&amp;#8217;t care about data retention&amp;#8221;.
Because as we have just seen, things like that tend to be the thin edge of
the wedge.  There is always much worse to&amp;nbsp;come.&lt;/p&gt;
&lt;p&gt;Attorney-General George Brandis is drunk on power, bloated of ego,
and oblivious to his own ignorance.  And he&amp;#8217;s coming for the tech&amp;nbsp;industry.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s time for all of us to stand up, menacingly brandish a rolled up
newspaper in front of his face, and firmly and loudly say: &amp;#8220;&lt;span class="caps"&gt;DOWN&lt;/span&gt;!&amp;#8221;&lt;/p&gt;
&lt;p&gt;&lt;span class="dquo"&gt;&amp;#8220;&lt;/span&gt;Bad dog, George.  Bad.  Get down!  And stay&amp;nbsp;down&amp;#8221;&lt;/p&gt;
&lt;p&gt;And if he doesn&amp;#8217;t obey our wishes, he deserves a whack on the&amp;nbsp;nose.&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related&amp;nbsp;Posts:&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/07/14/mandatory-protocol-analysis-to-the-node/"&gt;Mandatory protocol analysis to the&amp;nbsp;node&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/02/28/mandatory-data-retention-futile-and-dangerous/"&gt;Mandatory data retention: futile and&amp;nbsp;dangerous&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/02/23/who-cares-about-data-retention-anyway/"&gt;Who cares about data retention&amp;nbsp;anyway?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/28/metadata-karma/"&gt;Metadata&amp;nbsp;karma&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/22/they-are-coming-for-us-and-our-metadata/"&gt;They&amp;#8217;re coming for us and our&amp;nbsp;metadata&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/25/we-all-have-something-to-hide-from-mandatory-meta-data-retention/"&gt;We all have something to&amp;nbsp;hide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="privacy"></category><category term="data retention"></category><category term="metadata"></category><category term="politics"></category><category term="surveillance"></category></entry><entry><title>Mandatory protocol analysis to the node</title><link href="http://www.voidynullness.net/blog/2015/07/14/mandatory-protocol-analysis-to-the-node/" rel="alternate"></link><published>2015-07-14T00:00:00+10:00</published><updated>2015-07-14T00:00:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2015-07-14:/blog/2015/07/14/mandatory-protocol-analysis-to-the-node/</id><summary type="html">&lt;p class="first last"&gt;A recent job ad seems to suggest that&amp;#8217;s exactly what his department is&amp;nbsp;doing.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Gather round all ye geeks, wonks, activists, civil libertarians, conspiracy
theorists &amp;#8212; and let us all read between the lines of a job ad that was
posted on Seek&amp;nbsp;recently.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s read between the lines of this job ad as we play everyone&amp;#8217;s least
favourite game of &amp;#8220;guess which particular civil liberties and digital rights
are under attack from the Australian government this&amp;nbsp;month&amp;#8221;?&lt;/p&gt;
&lt;p&gt;The ad is titled &amp;#8220;Software Developer - Protocol Analysis&amp;#8221; and was posted
(via a recruitment agency) on 12 June 2015.  It&amp;#8217;s a reasonably high paid
role, located in &amp;#8220;Central Melbourne&amp;#8221;, for a &amp;#8220;Federal Government&amp;nbsp;Department&amp;#8221;.&lt;/p&gt;
&lt;p&gt;Turns out the Federal Government Department in question is the
Attorney-General&amp;#8217;s&amp;nbsp;Department.&lt;/p&gt;
&lt;img alt="Seek job ad screenshot" class="pull-right" src="http://www.voidynullness.net/images/software-developer-protocol-analysis.png" /&gt;
&lt;p&gt;That would be Attorney-General George Brandis.  Remember him?  He&amp;#8217;s the
guy who &lt;a class="reference external" href="http://www.smh.com.au/digital-life/consumer-security/george-brandis-still-struggling-with-metadata-20150112-12miwj.html"&gt;really, really wants our metadata,&lt;/a&gt;
without a warrant, and
&lt;a class="reference external" href="http://www.smh.com.au/digital-life/digital-life-news/george-brandis-in-car-crash-interview-over-controversial-data-retention-regime-20140806-101849.html"&gt;without knowing what metadata actually&amp;nbsp;means.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;His department is responsible not just for the
&lt;a class="reference external" href="http://www.smh.com.au/federal-politics/political-news/senate-passes-controversial-metadata-laws-20150327-1m8q3v.html"&gt;undemocratic and misguided data retention laws,&lt;/a&gt;
but also the laws threatening to put investigative journalists in
jail for 10 years for doing their&amp;nbsp;job.&lt;/p&gt;
&lt;p&gt;Then there&amp;#8217;s the government&amp;#8217;s recently introduced &lt;a class="reference external" href="http://www.abc.net.au/news/2015-06-22/governments-bill-to-block-foreign-piracy-websites-passes-senate/6565098"&gt;website&lt;/a&gt;
&lt;a class="reference external" href="https://pirateparty.org.au/2015/06/23/copyright-industry-buys-its-very-own-censorship-regime/"&gt;blocking&lt;/a&gt;
laws, probably designed to &lt;a class="reference external" href="http://www.itnews.com.au/News/399933,village-roadshow-boosts-donations-amidst-copyright-crackdown.aspx"&gt;appease their corporate&amp;nbsp;donors.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With all that in mind, let&amp;#8217;s take a look at some of the specific skills the
Attorney General&amp;#8217;s department is looking&amp;nbsp;for.&lt;/p&gt;
&lt;blockquote&gt;
Protocol analysis of &lt;span class="caps"&gt;IP&lt;/span&gt; network applications and services. This includes
aspects such as reverse engineering of network protocols and traffic
analysis&lt;/blockquote&gt;
&lt;p&gt;For those less technically inclined, a protocol is an agreed set of
rules that networked devices use to communicate with each other.  Think of
it as a particular language computers use to talk to each&amp;nbsp;other.&lt;/p&gt;
&lt;p&gt;For example, BitTorrent is a protocol for peer-to-peer file sharing.  Could
it be this protocol that the Attorney-General&amp;#8217;s department is most
interested in&amp;nbsp;analysing?&lt;/p&gt;
&lt;blockquote&gt;
Demonstrated understanding of &lt;span class="caps"&gt;IP&lt;/span&gt; networks and protocols&lt;/blockquote&gt;
&lt;p&gt;They&amp;#8217;re looking for a software developer with specific knowledge of
networking protocols.  And also experience with spying on network&amp;nbsp;traffic:&lt;/p&gt;
&lt;blockquote&gt;
Experience with network protocol analysis tools such as Wireshark, TCPDump etc&lt;/blockquote&gt;
&lt;p&gt;Both Wireshark and tcpdump are what&amp;#8217;s known as &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Packet_analyzer"&gt;packet
analysers.&lt;/a&gt; They&amp;#8217;re used
to capture, store, and analyse network traffic.  They basically a way of
&amp;#8220;spying&amp;#8221; on network communication &amp;#8212; not necessarily in a sinister way, but
of course they can be used for devious&amp;nbsp;purposes.&lt;/p&gt;
&lt;p&gt;Packet analysers are essentially a diagnostic tool.  I&amp;#8217;ve used tcpdump
occasionally in the past, when debugging low level networking code.
Still, it&amp;#8217;s a bit unusual to see it explicitly mentioned in a software
development job ad.  It&amp;#8217;s more likely something an networking/security
engineer might&amp;nbsp;use.&lt;/p&gt;
&lt;p&gt;Putting it all together, it paints a kind of sinister picture.
Especially given the way the Abbott Government has been &lt;a class="reference external" href="http://www.crikey.com.au/2014/12/11/governments-full-blown-war-on-the-internet-is-here-at-last/"&gt;waging war on the
internet&lt;/a&gt;.
First data retention, then website blocking, now this.  What the hell is
this ridiculous government up to&amp;nbsp;now?&lt;/p&gt;
&lt;p&gt;Why does the Attorney-General&amp;#8217;s department want a software developer with
network spying skills?  Come to think of it, why does the
Attorney-General&amp;#8217;s department even need a software developer at&amp;nbsp;all?&lt;/p&gt;
&lt;p&gt;To &lt;a class="reference external" href="https://www.youtube.com/watch?v=E-iENCZKFzk"&gt;paraphrase Tom Waits:&lt;/a&gt;
What&amp;#8217;s George Brandis building in&amp;nbsp;there?&lt;/p&gt;
&lt;p&gt;&lt;span class="caps"&gt;OK&lt;/span&gt;, so maybe it&amp;#8217;s nothing.  Maybe it is all completely innocuous.  Maybe
there&amp;#8217;s a legitimate reason George Brandis&amp;#8217;s department needs a software&amp;nbsp;developer.&lt;/p&gt;
&lt;p&gt;Maybe the Attorney-General&amp;#8217;s department just want a technical person on
staff to repeatedly explain metadata to&amp;nbsp;Brandis?&lt;/p&gt;
&lt;p&gt;Or maybe George Brandis is now overcompensating for that &lt;a class="reference external" href="http://www.news.com.au/technology/online/george-brandis-metadata-interview-fails-spectacularly-internet-reacts/story-fnjwnhzf-1227016188974"&gt;embarrassing Sky
news interview&lt;/a&gt;
where he &lt;a class="reference external" href="http://www.abc.net.au/insiders/content/2014/s4064410.htm"&gt;badly fumbled&lt;/a&gt; his
explanation of metadata.  So maybe now he&amp;#8217;s constantly dropping the term
&amp;#8220;metadata&amp;#8221; into conversation, in an effort to prove he&amp;#8217;s finally learned
what it means.  But apart from coming across as awkward and try-hard, he&amp;#8217;s
still getting the context wrong, and thereby demonstrating that he still
has no idea what it really means.  Maybe Brandis is doing things like
coming back from lunch and loudly proclaiming he enjoyed his hot-dog with
added metadata.  And maybe his staff are tired of explaining: &amp;#8220;That&amp;#8217;s not
metadata, George, it&amp;#8217;s mustard.&amp;#8221;  Maybe there is no one on his staff who
can adequately explain to Brandis that mustard is a condiment, while
metadata retention is an invasion of privacy.  That mustard is delicious,
while data retention tastes of government overreach, with a bitter
aftertaste of privacy violation &amp;#8212; and possible side effects of widespread
identity&amp;nbsp;theft.&lt;/p&gt;
&lt;p&gt;Maybe it&amp;#8217;s all mundane and innocent and there&amp;#8217;s no agenda.  But probably&amp;nbsp;not.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s most likely this job has something to do with either mandatory data
retention, the new website blocking laws, or possibly some new scheme
attempting to combat illegal&amp;nbsp;downloading.&lt;/p&gt;
&lt;p&gt;Or maybe all of the&amp;nbsp;above.&lt;/p&gt;
&lt;p&gt;I can&amp;#8217;t imagine any scenario where a role like this in the
Attorney-General&amp;#8217;s department won&amp;#8217;t result in some combination of
curtailing civil liberties and government overreach.  But then maybe I&amp;#8217;m
just not as imaginative as the Abbott&amp;nbsp;government.&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related&amp;nbsp;Posts:&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/02/28/mandatory-data-retention-futile-and-dangerous/"&gt;Mandatory data retention: futile and&amp;nbsp;dangerous&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/02/23/who-cares-about-data-retention-anyway/"&gt;Who cares about data retention&amp;nbsp;anyway?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/28/metadata-karma/"&gt;Metadata&amp;nbsp;karma&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/22/they-are-coming-for-us-and-our-metadata/"&gt;They&amp;#8217;re coming for us and our&amp;nbsp;metadata&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/25/we-all-have-something-to-hide-from-mandatory-meta-data-retention/"&gt;We all have something to&amp;nbsp;hide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="privacy"></category><category term="data retention"></category><category term="metadata"></category><category term="politics"></category><category term="surveillance"></category></entry><entry><title>How to add a list of recent posts to a Pelican blog</title><link href="http://www.voidynullness.net/blog/2015/06/25/add-recent-posts-list-to-pelican-blog/" rel="alternate"></link><published>2015-06-25T00:00:00+10:00</published><updated>2015-06-25T00:00:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2015-06-25:/blog/2015/06/25/add-recent-posts-list-to-pelican-blog/</id><summary type="html">&lt;p class="first last"&gt;Adding recent posts list to a Pelican blog, and using&amp;nbsp;TEMPLATE_PAGES.&lt;/p&gt;
</summary><content type="html">&lt;div class="section" id="list-of-recent-posts"&gt;
&lt;h2&gt;List of Recent&amp;nbsp;Posts&lt;/h2&gt;
&lt;p&gt;If you&amp;#8217;re a blogger, and if your blogging platform of choice is &lt;a class="reference external" href="http://getpelican.com"&gt;Pelican&lt;/a&gt; (And if not why not? Pelican really is quite
nice!), and if you&amp;#8217;d like to have a list of recent posts somewhere in the
page layout, but the Pelican theme you&amp;#8217;re using doesn&amp;#8217;t have built in
support for this, it&amp;#8217;s not too difficult to add, as long as you&amp;#8217;re
comfortable messing about with the Jinja templates of the theme in&amp;nbsp;question.&lt;/p&gt;
&lt;p&gt;The Jinja template code to accomplish this is reasonably straightforward,
although you need to take into account that the &lt;tt class="docutils literal"&gt;articles&lt;/tt&gt; variable
&lt;a class="reference external" href="http://docs.getpelican.com/en/latest/themes.html#common-variables"&gt;means something different&lt;/a&gt;
depending on which index page is being rendered.  In &lt;tt class="docutils literal"&gt;index.html&lt;/tt&gt;,
&lt;tt class="docutils literal"&gt;articles&lt;/tt&gt; is a list of all articles.  In all other index pages
(i.e. author, category, tag), it&amp;#8217;s only a subset relevant to that index &amp;#8212;
the list of &lt;em&gt;all articles&lt;/em&gt; is instead available as a variable called
&lt;tt class="docutils literal"&gt;all_articles&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Here is an example that will render the 6 most recent posts as an unordered&amp;nbsp;list.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h4&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;RECENT POSTS&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h4&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nv"&gt;recent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;articles&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="nv"&gt;all_articles&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nv"&gt;all_articles&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;recent-posts&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;recent&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;
  &lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;loop&lt;/span&gt;&lt;span class="nv"&gt;.index&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;6&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;SITEURL&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;a.url&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;a.title&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;endif&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;
&lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;endfor&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Place the above snippet in an appropriate place in your theme&amp;#8217;s Jinja
templates and style to&amp;nbsp;taste.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="now-with-added-json"&gt;
&lt;h2&gt;Now With Added &lt;span class="caps"&gt;JSON&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;But what if &amp;#8212; maybe, for some reason &amp;#8212; you&amp;#8217;d like to get details of recent
posts in &lt;span class="caps"&gt;JSON&lt;/span&gt; format instead?  Why would anyone want to do that, you&amp;nbsp;ask?&lt;/p&gt;
&lt;p&gt;Well, to provide a contrived example of using Pelican&amp;#8217;s Template Pages
functionality, for one&amp;nbsp;thing.&lt;/p&gt;
&lt;p&gt;I recently discovered the &lt;tt class="docutils literal"&gt;TEMPLATE_PAGES&lt;/tt&gt; setting, and have been
exploring its possibilities.  It&amp;#8217;s quite nifty.  Yes, I used the word
&amp;#8220;nifty&amp;#8221;.  Yes, I probably need to get out&amp;nbsp;more.&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;TEMPLATE_PAGES&lt;/tt&gt; is also somewhat &lt;a class="reference external" href="http://docs.getpelican.com/en/latest/settings.html#template-pages"&gt;vaguely documented&lt;/a&gt;.
It&amp;#8217;s purpose is to basically enable creation of any kind of other custom
content, besides articles and pages.  The idea is you can add a template, which
can have any kind of arbitrary content (and need not inherit from the
theme&amp;#8217;s &lt;tt class="docutils literal"&gt;base.html&lt;/tt&gt;), and specify where the output should&amp;nbsp;go.&lt;/p&gt;
&lt;p&gt;Since the template can be pretty much anything, it doesn&amp;#8217;t have to be
&lt;span class="caps"&gt;HTML&lt;/span&gt;.  We can generate &lt;span class="caps"&gt;JSON&lt;/span&gt; output, if we so&amp;nbsp;desire.&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s say we were to create a file called &lt;tt class="docutils literal"&gt;recent.json&lt;/tt&gt; in our theme&amp;#8217;s
&lt;tt class="docutils literal"&gt;templates&lt;/tt&gt; directory, with the following&amp;nbsp;contents:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;&amp;quot;recent&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nv"&gt;recent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;articles&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="nv"&gt;all_articles&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nv"&gt;all_articles&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;
      &lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nv"&gt;a&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;recent&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;
        &lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;loop&lt;/span&gt;&lt;span class="nv"&gt;.index&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;6&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;url&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;SITEURL&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;a.url&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="cp"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;a.title&lt;/span&gt; &lt;span class="cp"&gt;}}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;loop&lt;/span&gt;&lt;span class="nv"&gt;.last&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="nb"&gt;loop&lt;/span&gt;&lt;span class="nv"&gt;.index&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;6&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;endif&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;
        &lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;endif&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;
      &lt;span class="cp"&gt;{%&lt;/span&gt; &lt;span class="k"&gt;endfor&lt;/span&gt; &lt;span class="cp"&gt;%}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then we add this to our &lt;tt class="docutils literal"&gt;pelicanconf.py&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;TEMPLATE_PAGES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;recent.json&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;api/recent.json&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;TEMPLATE_PAGES&lt;/tt&gt; is a dictionary mapping template to output.  So in the
above example, we&amp;#8217;re telling Pelican to render the
&lt;tt class="docutils literal"&gt;templates/recent.json&lt;/tt&gt; template and place the output into
&lt;tt class="docutils literal"&gt;output/api/recent.json&lt;/tt&gt; (assuming the Pelican output directory is
configured to be &amp;#8220;output&amp;#8221;).  That file is now accessible on the
&lt;tt class="docutils literal"&gt;/api/recent.json&lt;/tt&gt; &lt;span class="caps"&gt;URL&lt;/span&gt; path in the usual way, and available for all sorts
of &lt;span class="caps"&gt;AJAX&lt;/span&gt;&amp;nbsp;mischief.&lt;/p&gt;
&lt;p&gt;As an example, here&amp;#8217;s some jQuery that consumes the above &lt;span class="caps"&gt;JSON&lt;/span&gt; output to
render a list of recent posts&amp;nbsp;dynamically:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;#payload&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;lt;p&amp;gt;...loading...&amp;lt;/p&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getJSON&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/api/recent.json&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
                &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;recent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;quot;&amp;gt;&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;});&lt;/span&gt;
                &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;newhtml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;lt;ul id=&amp;quot;recent-posts&amp;quot;&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="nx"&gt;newhtml&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="nx"&gt;newhtml&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;lt;/ul&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;#payload&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newhtml&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Not that I&amp;#8217;m in any way suggesting this method of generating a list of
recent posts is preferable to the previous method (static generation via
Jinja template).  It is merely an example of what&amp;#8217;s possible.  Sensible use
cases are left as an exercise for the reader&amp;#8230;and possibly future blog&amp;nbsp;posts.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="fail-faster"&gt;
&lt;h2&gt;Fail&amp;nbsp;Faster&lt;/h2&gt;
&lt;p&gt;Another &lt;a class="reference external" href="http://docs.getpelican.com/en/latest/settings.html#writing-only-selected-content"&gt;occasionally useful but vaguely documented&lt;/a&gt;
Pelican setting is
&lt;tt class="docutils literal"&gt;WRITE_SELECTED&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;If you have a blog with a considerable amount of content, you may notice it
takes entire &lt;em&gt;seconds&lt;/em&gt; to generate your static site.  Probably many, many
seconds.  Especially if Typogrify is turned on, which tends to slow things
down a bit.  If there&amp;#8217;s really lots of content and/or you&amp;#8217;re running on a
really slow (virtual) machine, it might even take a &lt;em&gt;minute&lt;/em&gt; or more to
regenerate your&amp;nbsp;site.&lt;/p&gt;
&lt;p&gt;And the more content you write, the slower things will only&amp;nbsp;get.&lt;/p&gt;
&lt;p&gt;Seconds.  Maybe a minute.  In this world of instant gratification, who&amp;#8217;s
got time to wait &lt;em&gt;seconds&lt;/em&gt; for a&amp;nbsp;build?&lt;/p&gt;
&lt;p&gt;Those seconds really add up when doing theme tweaks, or working on getting
an article&amp;#8217;s markup just&amp;nbsp;right.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re anything like me, you want The Machine to pass judgement on your
substandard markup and declare it to be unparsable garbage as soon as&amp;nbsp;possible.&lt;/p&gt;
&lt;p&gt;Thankfully, Pelican has got you covered.  If you&amp;#8217;re just tweaking a page or
two, you can temporarily use the &lt;tt class="docutils literal"&gt;WRITE_SELECTED&lt;/tt&gt; setting in your
&lt;tt class="docutils literal"&gt;pelicanconf.py&lt;/tt&gt; to only output the page or pages you&amp;#8217;re currently&amp;nbsp;editing:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;WRITE_SELECTED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;output/blog/2015/01/01/path-to-blog-post/index.html&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s1"&gt;&amp;#39;output/blog/pages/stuff/index.html&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                 &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The slightly tricky thing is that &lt;tt class="docutils literal"&gt;WRITE_SELECTED&lt;/tt&gt; apparently needs to be
set to a list of full paths the the output files, including output
directory.  These will obviously depend on your URLs settings and
output directory&amp;nbsp;configuration.&lt;/p&gt;
&lt;p&gt;With &lt;tt class="docutils literal"&gt;WRITE_SELECTED&lt;/tt&gt; set only those files listed will be regenerated, which
should make things substantially&amp;nbsp;faster.&lt;/p&gt;
&lt;p&gt;Just remember to remove the &lt;tt class="docutils literal"&gt;WRITE_SELECTED&lt;/tt&gt; setting before publishing
and uploading the final finished results, to make sure everything gets
refreshed&amp;nbsp;properly.&lt;/p&gt;
&lt;/div&gt;
</content><category term="Pelican"></category><category term="Python"></category></entry><entry><title>What’s New In VoidyBootstrap Version 2</title><link href="http://www.voidynullness.net/blog/2015/06/01/voidy-bootstrap-pelican-theme-version-2/" rel="alternate"></link><published>2015-06-01T00:00:00+10:00</published><updated>2015-06-01T00:00:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2015-06-01:/blog/2015/06/01/voidy-bootstrap-pelican-theme-version-2/</id><summary type="html">&lt;p class="first last"&gt;VoidyBootstrap has undergone some refinement under the hood, with many new customisation features&amp;nbsp;added.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;VoidyBootstrap is a theme for the &lt;a class="reference external" href="http://getpelican.com"&gt;Pelican static site&amp;nbsp;generator.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This post is a summary of the main changes introduced in Version 2 of&amp;nbsp;VoidyBootstrap.&lt;/p&gt;
&lt;p&gt;As far as blog themes go, VoidyBootstrap is deliberately minimal in terms
of design.  It&amp;#8217;s based on &lt;a class="reference external" href="http://getbootstrap.com/"&gt;Bootstrap&lt;/a&gt;, and by
default it just provides a standard Bootstrap look and feel.  Nothing much
has changed in this&amp;nbsp;regard.&lt;/p&gt;
&lt;p&gt;However, its main reason for existing is flexibility and customisation, and
it&amp;#8217;s here where I&amp;#8217;ve made significant changes, some of which break
backwards compatibility with previous versions.  This is something I wanted
to avoid, ideally, but in the end I decided it was justified.  With these
changes the result is a Pelican theme that is now even more flexible and
customisable, with a more consistent naming convention for its many
configuration&amp;nbsp;options.&lt;/p&gt;
&lt;p&gt;I never actually intended to undertake such an extensive update.  When I
started working on what would eventually become version 2, I just planned
to update dependencies (Bootstrap, FontAwesome, etc) to the latest
versions, and make a few other tweaks.  But as often happens with these
things, what started as a few small tweaks quickly escalated to into weeks
of large scale hacking and refactoring.  I ended up adding and changing so
many things I felt I should call this release &amp;#8220;version 2&amp;#8221;.  (For what it&amp;#8217;s
worth though, I don&amp;#8217;t intend on making any more large scale changes like
this.  The version 2 series should be just small incremental updates &amp;#8212;
hopefully &amp;#8212; but we&amp;#8217;ll&amp;nbsp;see&amp;#8230;)&lt;/p&gt;
&lt;div class="section" id="overview"&gt;
&lt;h2&gt;Overview&lt;/h2&gt;
&lt;p&gt;VoidyBootstrap started off as a custom theme for this blog, then gradually
evolved into a stand-alone open source theme.  Unsurprisingly, therefore, it
reflects my requirements and is geared towards my Pelican workflow.
VoidyBootstrap is admittedly a somewhat idiosyncratic Pelican theme, but it
works for me, although of course your mileage may&amp;nbsp;vary.&lt;/p&gt;
&lt;p&gt;VoidyBootstrap came about out of my desire for a simple Bootstrap-based
Pelican theme that was easy to customise.  There are 3 main overriding
goals I had with&amp;nbsp;VoidyBootstrap:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;It had to be flexible and&amp;nbsp;customisable.&lt;/li&gt;
&lt;li&gt;Despite its focus on customisation, it should be easy to set up.  It
should &amp;#8220;Just Work&amp;#8221; out of the box, with sensible defaults, and good&amp;nbsp;documentation.&lt;/li&gt;
&lt;li&gt;Customisation workflows should play nice with version control, making it
possible to isolate changes and easily merge in upstream changes in the
base&amp;nbsp;theme.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Much of the changes in version 2 have been motivated by that last point,
even though it may not be immediately obvious that&amp;#8217;s the&amp;nbsp;case.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="sidebar-changes"&gt;
&lt;h2&gt;Sidebar&amp;nbsp;Changes&lt;/h2&gt;
&lt;p&gt;The most visible change in VoidyBootstrap version 2 is the sidebar &amp;#8212; in
that by default, there now isn&amp;#8217;t&amp;nbsp;one!&lt;/p&gt;
&lt;p&gt;The sidebar is now optional, so VoidyBootstrap can now be used in either
single column or 2 column&amp;nbsp;mode.&lt;/p&gt;
&lt;p&gt;For implementation reasons, the default is now single column without a
sidebar.  To enable the standard sidebar, add the following line to your
&lt;tt class="docutils literal"&gt;pelicanconf.py&lt;/tt&gt;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
SIDEBAR = &amp;quot;sidebar.html&amp;quot;
&lt;/pre&gt;
&lt;p&gt;As always, you&amp;#8217;re not limited to the standard sidebar implementation, and
you can use your own custom sidebar template if you&amp;nbsp;prefer:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
SIDEBAR = &amp;quot;custom_sidebar_template_name_here.html&amp;quot;
&lt;/pre&gt;
&lt;p&gt;Also, the relative width of the sidebar can now be changed using the
&lt;tt class="docutils literal"&gt;SIDEBAR_SIZE&lt;/tt&gt; setting.  By default, if the sidebar is enabled it spans 3
columns in the &lt;a class="reference external" href="http://getbootstrap.com/css/#grid"&gt;responsive Bootstrap grid.&lt;/a&gt;
The main content column takes up the rest.  The value of &lt;tt class="docutils literal"&gt;SIDEBAR_SIZE&lt;/tt&gt;
can be set higher than 3 (but less than 12) to make the sidebar wider and
content column narrower.  For example, to make the sidebar and content
columns the same size, set &lt;tt class="docutils literal"&gt;SIDEBAR_SIZE&lt;/tt&gt; to 6 in your&amp;nbsp;pelicanconf.py:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
SIDEBAR_SIZE = 6
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="custom-css-and-javascript"&gt;
&lt;h2&gt;Custom &lt;span class="caps"&gt;CSS&lt;/span&gt; and&amp;nbsp;Javascript&lt;/h2&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;STYLESHEET_FILES&lt;/tt&gt; setting replaces &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;STYLESHEETS&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;MAIN_LOCAL_STYLESHEET&lt;/tt&gt; setting has been renamed to
&lt;tt class="docutils literal"&gt;BOOTSTRAP_STYLESHEET&lt;/tt&gt;.  This option allows an alternative (customised)
Bootstrap &lt;span class="caps"&gt;CSS&lt;/span&gt; file to be used in stead of the standard&amp;nbsp;one.&lt;/p&gt;
&lt;p&gt;As before, if &lt;tt class="docutils literal"&gt;BOOTSTRAP_STYLESHEET&lt;/tt&gt; is not set, the standard
Bootstrap &lt;span class="caps"&gt;CSS&lt;/span&gt; file is used via a &lt;span class="caps"&gt;CDN&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;The above settings represent the primary means of incorporating custom &lt;span class="caps"&gt;CSS&lt;/span&gt;
files, but in version 2, there are now even more options when it comes to
configuring &lt;span class="caps"&gt;CSS&lt;/span&gt; and JavaScript&amp;nbsp;files.&lt;/p&gt;
&lt;p&gt;The new &lt;tt class="docutils literal"&gt;STYLESHEET_URLS&lt;/tt&gt; setting allows additional style sheets to be
linked in from arbitrary &lt;span class="caps"&gt;URLS&lt;/span&gt; (e.g. from a &lt;span class="caps"&gt;CDN&lt;/span&gt;).  Once possible use case
for this setting is to incorporate the Bootstrap theme &lt;span class="caps"&gt;CSS&lt;/span&gt; file from &lt;span class="caps"&gt;CDN&lt;/span&gt;,
like&amp;nbsp;so:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
STYLESHEET_URLS = (&amp;quot;https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap-theme.min.css&amp;quot;, )
&lt;/pre&gt;
&lt;p&gt;Similarly, &lt;tt class="docutils literal"&gt;JAVASCRIPT_URLS&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;JAVASCRIPT_FILES&lt;/tt&gt; settings have been
added to make it easier to incorporate custom, site-wide JavaScript&amp;nbsp;files.&lt;/p&gt;
&lt;p&gt;For those who, for whatever reason, might not want to use any &lt;span class="caps"&gt;CDN&lt;/span&gt; files, it&amp;#8217;s
now possible to configure VoidyBootstrap without any dependencies on
external CDNs.  Doing this requires using the new &lt;tt class="docutils literal"&gt;SKIP_DEFAULT_CSS&lt;/tt&gt; and
&lt;tt class="docutils literal"&gt;SKIP_DEFAULT_JS&lt;/tt&gt; settings, and then manually configuring all the theme&amp;#8217;s
dependencies (Bootstrap &lt;span class="caps"&gt;CSS&lt;/span&gt; and JavaScript, Font Awesome, jQuery) using the
above&amp;nbsp;settings:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
SKIP_DEFAULT_CSS = True
SKIP_DEFAULT_JS = True
BOOTSTRAP_STYLESHEET = &amp;quot;bootstrap.min.css&amp;quot;
STYLESHEET_FILES = (&amp;quot;font-awesome.min.css&amp;quot;, &amp;quot;pygment.css&amp;quot;,)
JAVASCRIPT_FILES = (&amp;quot;jquery.min.js&amp;quot;, &amp;quot;bootstrap.min.js&amp;quot;,)
&lt;/pre&gt;
&lt;p&gt;Note that if you go this way, it&amp;#8217;s entirely up to you to download all those
files and put them in the correct directories.  (The theme is designed to
use CDNs by default, and does not ship with any vendor&amp;nbsp;files.)&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="optional-templates-removed"&gt;
&lt;h2&gt;Optional Templates&amp;nbsp;removed&lt;/h2&gt;
&lt;p&gt;A core idea behind VoidyBootstrap is that most &amp;#8220;blog&amp;#8221; type websites have
certain similarities in layout and overall structures, and therefore there
are certain semantic content blocks that are likely to appear in most blogs
(e.g. navigation, footer, author bio,&amp;nbsp;etc).&lt;/p&gt;
&lt;p&gt;Wherever practical, VoidyBootstrap will leave these content blocks blank and
provide ways to theme users to add their own content.  Or alternatively,
provide a default implementation, but let theme users override this with
their own, if they prefer (for example, like with the sidebar, as discussed&amp;nbsp;above).&lt;/p&gt;
&lt;p&gt;Version 1 of VoidyBootstrap had two ways to customise these &amp;#8220;content blocks&amp;#8221;:
&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/03/30/introducing-voidy-bootstrap-pelican-theme/#adding-custom-content"&gt;&amp;#8220;Optional Templates&amp;#8221;&lt;/a&gt;
and &lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/03/30/introducing-voidy-bootstrap-pelican-theme/#overriding-existing-content"&gt;&amp;#8220;Custom&amp;nbsp;Includes&amp;#8221;.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Optional Templates have now been removed in favour of Custom Includes.
Everything that was possible with Optional Templates in earlier versions
can now be accomplished with Custom&amp;nbsp;Includes.&lt;/p&gt;
&lt;p&gt;Optional Templates seemed like a good idea at the time, but in practice I
found them unwieldy.  And it seems kind of redundant &amp;#8212; not to mention
potentially confusing to new users &amp;#8212; to have two arbitrarily different
mechanisms for essentially accomplishing the same thing.  So Optional
Templates are gone (vestiges may remain in the code, but these will
eventually be removed &amp;#8212; do not rely on them), and new Custom Includes have
been added in their place (see&amp;nbsp;below).&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="new-custom-includes"&gt;
&lt;h2&gt;New Custom&amp;nbsp;Includes&lt;/h2&gt;
&lt;p&gt;&lt;span class="dquo"&gt;&amp;#8220;&lt;/span&gt;Custom Includes&amp;#8221;, for want of a better term, is a method VoidyBootstrap
provides for customising content blocks.  Custom Includes are settings
beginning with the prefix &lt;tt class="docutils literal"&gt;CUSTOM_&lt;/tt&gt;.  They are all optional, but if used,
must be set in &lt;tt class="docutils literal"&gt;pelicanconf.py&lt;/tt&gt; to the filename of a Jinja template
filename (or a list/tuple of filenames for some) which will then be added
to the appropriate place in the website layout (via a Jinja &lt;tt class="docutils literal"&gt;include&lt;/tt&gt;
directive).&lt;/p&gt;
&lt;p&gt;Lots of stuff has been changed when it comes to &amp;#8220;Custom&amp;nbsp;Includes&amp;#8221;.&lt;/p&gt;
&lt;p&gt;Some configuration setting were renamed, some were removed, and a whole
bunch were&amp;nbsp;added.&lt;/p&gt;
&lt;p&gt;With the new &amp;#8220;Custom Includes&amp;#8221; settings, there is now far more fine
grained control when it comes to adding blocks of custom&amp;nbsp;content.&lt;/p&gt;
&lt;p&gt;In many cases, it&amp;#8217;s now possible to provided different
templates for different page types (&lt;span class="caps"&gt;INDEX&lt;/span&gt;, &lt;span class="caps"&gt;ARTICLE&lt;/span&gt;, &lt;span class="caps"&gt;PAGE&lt;/span&gt;, &lt;span class="caps"&gt;CATEGORY&lt;/span&gt;, &lt;span class="caps"&gt;TAG&lt;/span&gt;,&amp;nbsp;etc).&lt;/p&gt;
&lt;p&gt;There are options for adding content outside of the main Bootstrap
container used to wrap the 2 columns (&lt;tt class="docutils literal"&gt;CUSTOM_HEADER_*&lt;/tt&gt;).&lt;/p&gt;
&lt;p&gt;There are options for adding content inside the main Bootstrap
container but above/below the columns, so in 2 column mode content will span
above or below the 2 columns (&lt;tt class="docutils literal"&gt;CUSTOM_CONTAINER_TOP_*&lt;/tt&gt; and
&lt;tt class="docutils literal"&gt;CUSTOM_CONTENT_BOTTOM_*&lt;/tt&gt;).&lt;/p&gt;
&lt;p&gt;The settings &lt;tt class="docutils literal"&gt;CUSTOM_CONTENT_TOP_*&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;CUSTOM_CONTENT_BOTTOM_*&lt;/tt&gt; are
now the ones used for adding arbitrary content to the top or bottom of the
content&amp;nbsp;column.&lt;/p&gt;
&lt;p&gt;Note that some of the new Custom Includes settings are lists:
&lt;tt class="docutils literal"&gt;CUSTOM_SITE_HEADERS&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;CUSTOM_ARTICLE_HEADERS&lt;/tt&gt;,
&lt;tt class="docutils literal"&gt;CUSTOM_INDEX_ARTICLE_HEADERS&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;CUSTOM_ARTICLE_FOOTERS&lt;/tt&gt; and
&lt;tt class="docutils literal"&gt;CUSTOM_PAGE_FOOTERS&lt;/tt&gt;.  I realise this might be potentially confusing to
new users of the theme.  But I found with these settings in particular, it
was often useful to be able to specify multiple templates.  It makes it
easier to split template fragments into smaller chunks, which could then be
reused (&lt;span class="caps"&gt;DRY&lt;/span&gt; and all&amp;nbsp;that).&lt;/p&gt;
&lt;p&gt;For more details about the new Custom Includes see the
&amp;#8220;Custom Includes&amp;#8221; section in the &lt;a class="reference external" href="https://github.com/robulouski/voidy-bootstrap/blob/master/README.rst"&gt;&lt;span class="caps"&gt;README&lt;/span&gt;&lt;/a&gt;,
as well as &lt;a class="reference external" href="https://github.com/robulouski/voidy-bootstrap/blob/master/CHANGES.rst"&gt;the changelog&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The above is by no means a complete list of changes.  Just the main
ones (the ones most likely to affect anyone attempting to upgrade their
installation from an earlier version).  There have been other bits and
pieces added or changed along the way.  I &lt;em&gt;think&lt;/em&gt; everything that deserves
documenting has been documented in both &lt;a class="reference external" href="https://github.com/robulouski/voidy-bootstrap/blob/master/CHANGES.rst"&gt;the changelog&lt;/a&gt;
and &lt;a class="reference external" href="https://github.com/robulouski/voidy-bootstrap/blob/master/README.rst"&gt;the &lt;span class="caps"&gt;README&lt;/span&gt;&lt;/a&gt;,
although I might have possibly missed&amp;nbsp;something.&lt;/p&gt;
&lt;p&gt;If you do find anything I might have missed, let me know in the&amp;nbsp;comments.&lt;/p&gt;
&lt;div class="section" id="see-also"&gt;
&lt;h3&gt;See&amp;nbsp;Also:&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/page/voidy-bootstrap-pelican-theme/"&gt;VoidyBootstrap project&amp;nbsp;page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/robulouski/voidy-bootstrap"&gt;VoidyBootstrap on&amp;nbsp;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h3&gt;Related&amp;nbsp;Posts:&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/03/30/introducing-voidy-bootstrap-pelican-theme/"&gt;Introducing VoidyBootstrap: A theme for&amp;nbsp;Pelican&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/03/19/voidy-bootstrap-prologue/"&gt;The winding road to a workable writing&amp;nbsp;workflow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="Pelican"></category><category term="Python"></category><category term="VoidyBootstrap"></category></entry><entry><title>Smooth scrolling using jQuery</title><link href="http://www.voidynullness.net/blog/2015/05/29/jquery-smooth-scrolling-floating-scroll-to-top-button/" rel="alternate"></link><published>2015-05-29T00:00:00+10:00</published><updated>2015-05-29T00:00:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2015-05-29:/blog/2015/05/29/jquery-smooth-scrolling-floating-scroll-to-top-button/</id><summary type="html">&lt;p class="first last"&gt;An example of implementing smooth page scrolling using jQuery, and a floating scroll-to-top&amp;nbsp;button.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Just leaving this here so I don&amp;#8217;t have to keep looking it&amp;nbsp;up&amp;#8230;&lt;/p&gt;
&lt;p&gt;Smooth scrolling is a common embellishment for web pages, and it&amp;#8217;s possible
to implement with surprisingly little code thanks to&amp;nbsp;jQuery.&lt;/p&gt;
&lt;p&gt;Creating a link that returns to the top of the current page can be done
using an anchor with a &lt;a class="reference external" href="https://html.spec.whatwg.org/multipage/browsers.html#scroll-to-fragid"&gt;&lt;span class="caps"&gt;URL&lt;/span&gt; fragment of &amp;#8220;top&amp;#8221;&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;#top&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Return to top&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Thanks to &lt;a class="reference external" href="https://api.jquery.com/category/selectors/attribute-selectors/"&gt;jQuery&amp;#8217;s equivalents&lt;/a&gt;
of &lt;a class="reference external" href="https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors"&gt;&lt;span class="caps"&gt;CSS&lt;/span&gt; attribute selectors&lt;/a&gt;,
we can easily add a click handler to all anchor elements on the page that implements
smooth scrolling using the &lt;a class="reference external" href="http://api.jquery.com/animate/"&gt;jQuery animate() function&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;a[href=&amp;#39;#top&amp;#39;]&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;html, body&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;animate&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;scrollTop&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;slow&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="section" id="floating-scroll-to-top-button"&gt;
&lt;h2&gt;Floating scroll to top&amp;nbsp;button&lt;/h2&gt;
&lt;p&gt;A more advanced embellishment is to add a floating button (often fixed in
the bottom right corner of the page) that will return to the top.  To
implement this, first we need an appropriate anchor element somewhere on
the web page.  Here&amp;#8217;s an example using Font Awesome for the up arrow&amp;nbsp;icon:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;#top&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;btn-scroll-to-top&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Top of page&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;i&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;fa fa-arrow-circle-up fa-fw fa-lg&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;i&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then we style it appropriately with &lt;span class="caps"&gt;CSS&lt;/span&gt; and fix it&amp;#8217;s&amp;nbsp;position:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nc"&gt;.btn-scroll-to-top&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;background-color&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;transparent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nb"&gt;display&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nb"&gt;position&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nb"&gt;bottom&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nb"&gt;right&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nb"&gt;padding&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nb"&gt;font-size&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;36px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nb"&gt;font-weight&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nb"&gt;text-align&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nb"&gt;text-decoration&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.btn-scroll-to-top&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;text-decoration&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That by itself should do the trick (if we were to omit the &lt;tt class="docutils literal"&gt;display:
none&lt;/tt&gt; line).  But we can take things a step further, and make the button
fade in once the user starts to scroll down the page.  Putting it
all together with the smooth scrolling, the JavaScript would look something
like&amp;nbsp;this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;a[href=&amp;#39;#top&amp;#39;]&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;html, body&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;animate&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;scrollTop&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;slow&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;scroll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
         &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;scrollTop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;.btn-scroll-to-top&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;fadeIn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
         &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;.btn-scroll-to-top&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;fadeOut&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
         &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here we&amp;#8217;re using the &lt;a class="reference external" href="http://api.jquery.com/scrollTop/"&gt;jQuery scrollTop() function&lt;/a&gt; to determine how far the page has been
scrolled, and toggling the button visibility as&amp;nbsp;appropriate.&lt;/p&gt;
&lt;/div&gt;
</content><category term="jQuery"></category></entry><entry><title>Laggy Lollipop: How to clear the cache partition on an Android Nexus 7</title><link href="http://www.voidynullness.net/blog/2015/03/17/android-nexus-7-slow-sluggish-laggy-after-lollipop-update/" rel="alternate"></link><published>2015-03-17T00:00:00+11:00</published><updated>2015-03-17T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2015-03-17:/blog/2015/03/17/android-nexus-7-slow-sluggish-laggy-after-lollipop-update/</id><summary type="html">&lt;p class="first last"&gt;How to fix an Android Nexus 7 that&amp;#8217;s become slow and sluggish after an update to&amp;nbsp;Lollipop.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;I usually approach any software update with a sense of mixed feeling.
Especially operating system updates.  The promise of new features or better
performance is offset by the trepidation that the new version might be
substantially worse than what came before.  (Yes, I&amp;#8217;m looking at you
Windows&amp;nbsp;8!)&lt;/p&gt;
&lt;p&gt;My fears were realised when my Nexus 7 tablet, which had been happily
running KitKat, received the Android 5.0 &amp;#8220;Lollipop&amp;#8221;&amp;nbsp;update.&lt;/p&gt;
&lt;p&gt;Things were definitely not right after that.  My Nexus became slow.  Really,
incredibly slow and sluggish and laggy.  With frequent &lt;a class="reference external" href="http://developer.android.com/training/articles/perf-anr.html"&gt;&lt;span class="caps"&gt;ANR&lt;/span&gt;&amp;nbsp;dialogs.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After the Lollipop update, my Nexus 7 was so sluggish it was close to
unusable.  After some googling it was clear I wasn&amp;#8217;t the only one
experiencing this&amp;nbsp;problem.&lt;/p&gt;
&lt;p&gt;I tried clearing the cache partition, and found that this helped improve
performance somewhat.  My Nexus is still performing much worse under
Lollipop, but it has at least gone from &amp;#8220;unusable&amp;#8221; to &amp;#8220;barely&amp;nbsp;usable&amp;#8221;.&lt;/p&gt;
&lt;p&gt;The steps to do this are as&amp;nbsp;follows.&lt;/p&gt;
&lt;div class="section" id="how-to-wipe-the-cache-partition"&gt;
&lt;h2&gt;How to wipe the cache&amp;nbsp;partition&lt;/h2&gt;
&lt;p&gt;Start with the tablet turned&amp;nbsp;off.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Press and hold the &lt;strong&gt;volume down&lt;/strong&gt; and &lt;strong&gt;power&lt;/strong&gt; buttons until a screen
appears with a large arrow at the top (kind of pointing towards the
power button at the top right corner of the&amp;nbsp;device).&lt;/li&gt;
&lt;li&gt;Press the &lt;strong&gt;volume down&lt;/strong&gt; button a few times until an arrow with &amp;#8220;Recovery&amp;#8221;&amp;nbsp;appears.&lt;/li&gt;
&lt;li&gt;Press the &lt;strong&gt;power&lt;/strong&gt; button to select Recovery&amp;nbsp;Mode.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;An Android logo with an exclamation mark should now appear (with &amp;#8220;no command&amp;#8221;&amp;nbsp;text).&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Hold down the &lt;strong&gt;power&lt;/strong&gt; button, press and release &lt;strong&gt;volume up&lt;/strong&gt; once,
then release &lt;strong&gt;power&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You should now see a text based screen with a list of&amp;nbsp;options.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Use the &lt;strong&gt;volume down&lt;/strong&gt; button to move the selection to the &amp;#8220;wipe cache
partition&amp;#8221; option. &lt;em&gt;Double check to make sure you have selected &amp;#8220;erase or
wipe cache partition&amp;#8221;.  &lt;span class="caps"&gt;DO&lt;/span&gt; &lt;span class="caps"&gt;NOT&lt;/span&gt; select &amp;#8220;wipe data/factory reset&amp;#8221; by&amp;nbsp;mistake!&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Press the &lt;strong&gt;power&lt;/strong&gt; button once to select the &amp;#8220;wipe cache&amp;#8221;&amp;nbsp;option.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The process of clearing the cache should now begin, and will probably take a
few seconds.  Once it&amp;#8217;s done, you should be back at the same&amp;nbsp;menu.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;If necessary use the volume buttons to highlight the &amp;#8220;reboot system now&amp;#8221;&amp;nbsp;option.&lt;/li&gt;
&lt;li&gt;Press the &lt;strong&gt;power&lt;/strong&gt; button to reboot your&amp;nbsp;device.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once your Nexus finishes rebooting, it should hopefully be at least a
little more responsive and usable.  Whether the improvement lasts remains
to be&amp;nbsp;seen.&lt;/p&gt;
&lt;/div&gt;
</content><category term="Android Nexus"></category></entry><entry><title>The Definition of Metadata</title><link href="http://www.voidynullness.net/blog/2015/03/03/definition-of-metadata-mass-surveillance/" rel="alternate"></link><published>2015-03-03T00:00:00+11:00</published><updated>2015-03-03T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2015-03-03:/blog/2015/03/03/definition-of-metadata-mass-surveillance/</id><summary type="html">&lt;p&gt;Metadata used to be such an innocuous, mundane, technical&amp;nbsp;term.&lt;/p&gt;
&lt;p&gt;Until Big Government got hold of&amp;nbsp;it.&lt;/p&gt;
&lt;p&gt;And appropriated it for its own Orwellian&amp;nbsp;purposes.&lt;/p&gt;
&lt;p&gt;In technical circles, metadata is an abstract term.  It means nothing in
itself.  What the word &amp;#8220;metadata&amp;#8221; refers to is entirely dependent on&amp;nbsp;context.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re talking about databases, metadata might information about the
structure of the database &amp;#8212; how the data is&amp;nbsp;stored.&lt;/p&gt;
&lt;p&gt;But you&amp;#8217;re talking about photo files, it might be things …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Metadata used to be such an innocuous, mundane, technical&amp;nbsp;term.&lt;/p&gt;
&lt;p&gt;Until Big Government got hold of&amp;nbsp;it.&lt;/p&gt;
&lt;p&gt;And appropriated it for its own Orwellian&amp;nbsp;purposes.&lt;/p&gt;
&lt;p&gt;In technical circles, metadata is an abstract term.  It means nothing in
itself.  What the word &amp;#8220;metadata&amp;#8221; refers to is entirely dependent on&amp;nbsp;context.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re talking about databases, metadata might information about the
structure of the database &amp;#8212; how the data is&amp;nbsp;stored.&lt;/p&gt;
&lt;p&gt;But you&amp;#8217;re talking about photo files, it might be things like when the
photo was taken, the location where the photo was taken, the device used to
take the photo, the camera settings used to take the photo (exposure, white
balance, shutter speed),&amp;nbsp;etc.&lt;/p&gt;
&lt;p&gt;It might be.  But it depends.  It&amp;#8217;s an abstract&amp;nbsp;term.&lt;/p&gt;
&lt;p&gt;And it really, really depends on&amp;nbsp;context.&lt;/p&gt;
&lt;p&gt;Partly because it varies depending on context.  The &amp;#8220;metadata&amp;#8221; of a photo
sharing website is likely to be different to the &amp;#8220;metadata&amp;#8221; of an
accounting application, for&amp;nbsp;example.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s kind of like the word &amp;#8220;religion&amp;#8221;.  It means different things,
depending on which religion &amp;#8212; or groups of religions &amp;#8212; you might be
referring&amp;nbsp;to.&lt;/p&gt;
&lt;p&gt;You might use the word &amp;#8220;religion&amp;#8221; in an abstract way, perhaps if talking
about a group of religions in a general sense.  But the word &amp;#8220;religion&amp;#8221; in
itself doesn&amp;#8217;t provide specifics &amp;#8212; it wouldn&amp;#8217;t be particularly
enlightening to proudly proclaim a new found faith by saying you have
decided to &amp;#8220;convert to religion&amp;#8221;.  Which religion?  It doesn&amp;#8217;t make sense
to get into specifics without providing at least some context about which
religion you may be referring&amp;nbsp;to.&lt;/p&gt;
&lt;p&gt;Similarly, in the context of mass surveillance, talking about metadata
without specifying the exact metadata doesn&amp;#8217;t make much&amp;nbsp;sense.&lt;/p&gt;
&lt;p&gt;Yet, this is what the proposed mandatory metadata retention laws are doing
&amp;#8212; the legislation doesn&amp;#8217;t even define the &amp;#8220;metadata&amp;#8221; that service
providers are supposed to&amp;nbsp;retain.&lt;/p&gt;
&lt;p&gt;This is like saying religion is important and we must believe &amp;#8212; without
specifying which religion, or what we are to&amp;nbsp;believe.&lt;/p&gt;
&lt;p&gt;The Australian Government&amp;#8217;s proposed data retention legislation takes its
&lt;a class="reference external" href="http://survivelaw.com/index.php/blogs/procrastination/1349-life-lessons-from-the-castle"&gt;legal cues from The Castle&lt;/a&gt;
&amp;#8212; it&amp;#8217;s all about &amp;#8220;the vibe&amp;#8221; of the metadata thing.  The government is
arguing these data retention laws are really important for national
security, but apparently not important enough for&amp;nbsp;specifics.&lt;/p&gt;
&lt;p&gt;Which is kind of like arguing that all monotheistic Abrahamic faiths are
basically the same and any distinction is not worth bothering with.  Sure,
you could try and argue that, but you&amp;#8217;re likely to get some pretty strong
push back in certain religious circles.  I&amp;#8217;d be willing to bet a lifetime
supply of contraception on&amp;nbsp;that.&lt;/p&gt;
&lt;p&gt;With metadata as with religion, the devil is in the&amp;nbsp;details.&lt;/p&gt;
&lt;p&gt;And much like religion, the very notion of mass surveillance by the state
requires a huge leap of&amp;nbsp;faith.&lt;/p&gt;
&lt;p&gt;Faith that data retention will be effect in catching criminals and
preventing terrorism (despite evidence that it&amp;#8217;s&amp;nbsp;not).&lt;/p&gt;
&lt;p&gt;Faith that the government and its agencies will not abuse the data it
collects on its citizens (other governments&amp;nbsp;have).&lt;/p&gt;
&lt;p&gt;Faith that the metadata will be stored securely and won&amp;#8217;t be hacked&amp;nbsp;(unlikely/impossible).&lt;/p&gt;
&lt;p&gt;Faith that it will not stifle freedom of speech and freedom of the press
(it will by&amp;nbsp;definition).&lt;/p&gt;
&lt;p&gt;Faith despite evidence
&lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/02/28/mandatory-data-retention-futile-and-dangerous/"&gt;nothing the government says about data retention is&amp;nbsp;true.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And it&amp;#8217;s really hard to have faith in data retention when the argument for
it has been so poorly articulated. The subtleties of metadata as an
abstract term were obviously lost on Attorney General George Brandis when
he tried to explain it in that now
&lt;a class="reference external" href="http://www.smh.com.au/digital-life/digital-life-news/george-brandis-in-car-crash-interview-over-controversial-data-retention-regime-20140806-101849.html"&gt;infamous interview on Sky News,&lt;/a&gt;.
It&amp;#8217;s hard to have faith in our elected leaders when they are making draconian
laws about &lt;a class="reference external" href="http://www.abc.net.au/news/2014-08-08/pesce-when-it-comes-to-metadata-numbers-can-mislead/5658070"&gt;technology they clearly don&amp;#8217;t&amp;nbsp;understand.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After Brandis&amp;#8217;s trainwreck of an explanation, we now have politicians
glibly reciting the minimal route definition of metadata &amp;#8212; that it&amp;#8217;s &amp;#8220;data
about data&amp;#8221;.  While that might be the technical definition, it doesn&amp;#8217;t
really apply in the context of mandatory data retention.  Like many terms
used by politicians, &amp;#8220;metadata&amp;#8221; has been appropriated as a weasel word
designed to&amp;nbsp;deceive.&lt;/p&gt;
&lt;p&gt;The term &amp;#8220;metadata&amp;#8221; is now part of the government&amp;#8217;s attempt to make data
retention seem benign &amp;#8212; by making it sound technical; by implying metadata
is somehow not actually data; by downplaying the privacy implications while
exaggerating the distinction between &amp;#8220;data&amp;#8221; and&amp;nbsp;&amp;#8220;metadata&amp;#8221;.&lt;/p&gt;
&lt;p&gt;Anachronistic analogies describing metadata as &amp;#8220;the
&lt;a class="reference external" href="http://www.abc.net.au/news/2014-08-06/security-laws-abbott-browsing-history-not-collected/5652364"&gt;material on the front of the envelope,&lt;/a&gt;
not the contents inside the envelope&amp;#8221; are misleading and&amp;nbsp;inaccurate.&lt;/p&gt;
&lt;p&gt;Metadata is a lot more than the address on the front of an envelope.
Metadata is more like everything on the front and back of the envelope &amp;#8212;
including addresses, stamp, postmark and fingerprints &amp;#8212; along with details
of the pen used to write the address, where you bought the pen, where you
bought the stamp, where you were when you wrote the address, who you were
with, what you were wearing, what you had for breakfast that day, the date
you posted the envelope, the postbox location where you posted the
envelope, along with all your movements on the day you posted that&amp;nbsp;envelope.&lt;/p&gt;
&lt;p&gt;Ultimately, &amp;#8220;metadata&amp;#8221; is vague and abstract enough that in the hands of
politicians it can mean whatever they want it to mean.  This makes the
technical definition irrelevant &amp;#8212; any information that&amp;#8217;s collected about
us and our internet usage and communication is data.  Don&amp;#8217;t be fooled by
false distinctions and technical connotations.  The distinction between
&amp;#8220;metadata&amp;#8221; and &amp;#8220;data&amp;#8221; is an arbitrary one, and in this case a misleading
one.  It&amp;#8217;s all data, and it&amp;#8217;s all private &amp;#8212;
&lt;a class="reference external" href="http://theconversation.com/how-will-data-retention-laws-cope-with-the-internet-of-things-36885"&gt;even if it&amp;#8217;s not considered equally&amp;nbsp;private.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sure, content of communication is considered more &amp;#8220;private&amp;#8221; than the
&amp;#8220;metadata&amp;#8221; around that content (the contents of an email is considered very
private, the time it was sent less so, for&amp;nbsp;example).&lt;/p&gt;
&lt;p&gt;But any consideration of the privacy of metadata is misleading if we only
look at a single communication in isolation.  Keep in mind that data
retention is about our communication patterns in aggregate.  It&amp;#8217;s not just
&lt;em&gt;one&lt;/em&gt; envelope, it&amp;#8217;s &lt;em&gt;all&lt;/em&gt; the envelopes, and a whole lot more besides.
Data retention is about gathering a large amount of data about &lt;em&gt;all&lt;/em&gt; our
digital communication and online activities, so that things can be inferred
from sequences and patterns.  Information that&amp;#8217;s innocuous in isolation can
become
&lt;a class="reference external" href="https://www.eff.org/deeplinks/2013/06/why-metadata-matters"&gt;ominous in aggregate.&lt;/a&gt;
Knowing an individual called a local doctor&amp;#8217;s clinic might not reveal much.
But knowing that call was followed by a numerous calls to abortion clinics
possibly&amp;nbsp;does.&lt;/p&gt;
&lt;p&gt;The problem is with enough data, &lt;em&gt;everything&lt;/em&gt; looks ominous in aggregate.
Patterns truly innocent but seemingly nefarious will inevitably
&lt;a class="reference external" href="http://www.counterpunch.org/2006/05/24/why-does-the-nsa-engage-in-mass-surveillance-of-americans-when-it-s-statistically-impossible-for-such-spying-to-detect-terrorists/"&gt;emerge due to randomness.&lt;/a&gt;
The web browsing history of a chemistry student might, at times, look very
similar to the web browsing history of a potential bomb maker.
Journalists, activists, whistleblowers and researchers often have
legitimate reasons for visiting dubious corners of the internet and perhaps
communicating with individuals of dubious character &amp;#8212; and doing so in
private.  But metadata by definition means no context or nuance.  Metadata
means &lt;a class="reference external" href="http://www.badscience.net/2009/02/datamining-would-be-lovely-if-it-worked/"&gt;everyone looks guilty.&lt;/a&gt;
Metadata is an overbearing and constantly critical parent, always assuming
the&amp;nbsp;worst.&lt;/p&gt;
&lt;p&gt;Just like we leave our scent behind as we move through the real world, in a
constantly connected online world, we inevitably leave traces of our
activities behind.  Whether it&amp;#8217;s an entry in a log file on an obscure
server that will never examined, or an entry in a massive social media
database that will be extensively data mined, it will still be there.  Even
if we don&amp;#8217;t realise.  We almost certainly cannot realise just what our
digital metadata trail might imply.  Things we would consider completely
innocuous can appear suspicious taken out of&amp;nbsp;context.&lt;/p&gt;
&lt;p&gt;Like a sniffer dog tracking a scent, the government wants to be able to
sniff out our online activities based on our digital data trail.  But
unlike a sniffer dog, the government has no leash, and no idea what it&amp;#8217;s
doing or what it&amp;#8217;s looking for.  Data retention gives government
authorities the ability to look at patterns in our internet usage and
communication, but no way to determine whether those patterns mean anything
significant, or whether they&amp;#8217;re just statistical noise.  This means that
when it comes to data retention, the government is a rabid, anxious,
agitated beast ready to tear the throat out of anyone that smells a bit&amp;nbsp;funny.&lt;/p&gt;
&lt;p&gt;Data retention gives the government and its agencies too much power over us
with too little oversight, for very little&amp;nbsp;gain.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s also given &amp;#8220;metadata&amp;#8221; a new meaning:
&amp;#8220;metadata&amp;#8221; is now a euphemism for government sanctioned&amp;nbsp;spying.&lt;/p&gt;
&lt;p&gt;Metadata means the government spying on all of us &amp;#8212; but mostly the
innocent &amp;#8212; without a&amp;nbsp;warrant.&lt;/p&gt;
&lt;p&gt;Metadata means many false positives, which in turn means innocent people
are be more likely to be charged and possibly convicted of things they
didn&amp;#8217;t&amp;nbsp;do.&lt;/p&gt;
&lt;p&gt;It means our phones become tracking devices for the&amp;nbsp;government.&lt;/p&gt;
&lt;p&gt;It means ISPs become agents of the state, gathering information about our
online&amp;nbsp;activities.&lt;/p&gt;
&lt;p&gt;It means the government will know who we communicate with, and when, and
how&amp;nbsp;often.&lt;/p&gt;
&lt;p&gt;It means whistleblowers will find it much harder to expose government and
corporate&amp;nbsp;corruption.&lt;/p&gt;
&lt;p&gt;It means hackers will have an irresistible honeypot of data they will try
and get their hands&amp;nbsp;on.&lt;/p&gt;
&lt;p&gt;It means the risk of identity theft will&amp;nbsp;increase.&lt;/p&gt;
&lt;p&gt;It means we have a government trying to implementing policy they
&lt;a class="reference external" href="http://www.sbs.com.au/news/article/2015/02/20/loopholes-leave-current-metadata-system-open-abuse-police-insider-reveals"&gt;don&amp;#8217;t understand and can barely&amp;nbsp;articulate.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It means wasting millions of taxpayer dollars on something that
is &lt;a class="reference external" href="http://www.pbs.org/newshour/rundown/nsa-surveillance-doesnt-stop-terrorism-report-claims/"&gt;known to be ineffective&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It means we get poorly drafted national security legislation based on fear
rather than sensible, evidence-based&amp;nbsp;policy.&lt;/p&gt;
&lt;p&gt;It means online anonymity will be&amp;nbsp;impossible.&lt;/p&gt;
&lt;p&gt;It means invasion of our&amp;nbsp;privacy.&lt;/p&gt;
&lt;p&gt;It means undermining Australia&amp;#8217;s&amp;nbsp;democracy.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://theconversation.com/what-politicians-say-about-metadata-bad-metaphors-and-a-bad-idea-30247"&gt;Misleading metaphors&lt;/a&gt;
about envelopes don&amp;#8217;t even begin to explain the &lt;a class="reference external" href="http://www.theguardian.com/world/2007/apr/24/usa.comment"&gt;deleterious effect&lt;/a&gt;
mandatory data retention will have on our&amp;nbsp;democracy.&lt;/p&gt;
&lt;p&gt;Data retention is to democracy what a gatecrashing Satanist noisily
sacrificing a goat is to a quiet christening&amp;#8212; a disturbing and completely
unwelcome&amp;nbsp;intrusion.&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related&amp;nbsp;Posts:&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/02/28/mandatory-data-retention-futile-and-dangerous/"&gt;Mandatory data retention: futile and&amp;nbsp;dangerous&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/02/23/who-cares-about-data-retention-anyway/"&gt;Who cares about data retention&amp;nbsp;anyway?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/28/metadata-karma/"&gt;Metadata&amp;nbsp;karma&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/22/they-are-coming-for-us-and-our-metadata/"&gt;They&amp;#8217;re coming for us and our&amp;nbsp;metadata&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/25/we-all-have-something-to-hide-from-mandatory-meta-data-retention/"&gt;We all have something to&amp;nbsp;hide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="privacy"></category><category term="data retention"></category><category term="metadata"></category><category term="politics"></category><category term="surveillance"></category></entry><entry><title>Mandatory data retention: futile and dangerous</title><link href="http://www.voidynullness.net/blog/2015/02/28/mandatory-data-retention-futile-and-dangerous/" rel="alternate"></link><published>2015-02-28T00:00:00+11:00</published><updated>2015-02-28T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2015-02-28:/blog/2015/02/28/mandatory-data-retention-futile-and-dangerous/</id><summary type="html">&lt;p&gt;They say the definition of madness is doing the same thing over and over again and expecting different results.  So what, then, are we to make of the Australian Government&amp;#8217;s fervour for data retention?  Is it not the  government taking something other countries have done and found to be ineffective, doing it anyway, yet expecting different&amp;nbsp;results?&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.smh.com.au/it-pro/metadata-retention-laws-will-pass-as-labor-folds-20150227-13qd4m.html"&gt;Mandatory data retention is in the news again&lt;/a&gt;
in Australia, as an incredibly unpopular and incompetent Prime Minister scrambles back to his …&lt;/p&gt;</summary><content type="html">&lt;p&gt;They say the definition of madness is doing the same thing over and over again and expecting different results.  So what, then, are we to make of the Australian Government&amp;#8217;s fervour for data retention?  Is it not the  government taking something other countries have done and found to be ineffective, doing it anyway, yet expecting different&amp;nbsp;results?&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.smh.com.au/it-pro/metadata-retention-laws-will-pass-as-labor-folds-20150227-13qd4m.html"&gt;Mandatory data retention is in the news again&lt;/a&gt;
in Australia, as an incredibly unpopular and incompetent Prime Minister scrambles back to his comfort zone of national security, and attempts to scare us into forgetting about his failings as a leader.  So once again, Tony Abbott and his ministers are in the media saying silly things about technology they don&amp;#8217;t understand, in an attempt to sell us the complete falsehood that data retention is required to fight crime and prevent&amp;nbsp;terrorism.&lt;/p&gt;
&lt;p&gt;Which is not to say terrorism is not a problem.  It might not be as big a threat as the government and media make it out to be, but it is a threat.  Which is why it requires sensible, evidence based approaches.  As opposed to data retention, which represents an anecdotal, fear based&amp;nbsp;approach.&lt;/p&gt;
&lt;p&gt;Australia is not the first country to try mass surveillance of its citizens in an attempt to combat crime.  Others countries have had data retention in place for a number of years already, which means we can learn from their experience.  The evidence is fairly damning.  The international experience shows quite conclusively that &lt;a class="reference external" href="http://www.newscientist.com/article/dn26801-mass-surveillance-not-effective-for-finding-terrorists.html"&gt;data retention doesn&amp;#8217;t work.&lt;/a&gt;
Not only is it completely ineffective, but it&amp;#8217;s incredibly expensive, undemocratic, and open to abuse.  It&amp;#8217;s for those reasons many countries that have adopted data retention measures are now abolishing&amp;nbsp;them.&lt;/p&gt;
&lt;p&gt;But Australian authorities are determined to learn nothing from this, and are persisting in their misguided quest to spy on all of&amp;nbsp;us.&lt;/p&gt;
&lt;p&gt;While there&amp;#8217;s been a backlash on social media to the data retention proposal, &lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/02/23/who-cares-about-data-retention-anyway/"&gt;out in the real world people don&amp;#8217;t really care,&lt;/a&gt;&amp;nbsp;unfortunately.&lt;/p&gt;
&lt;p&gt;For a country that&amp;#8217;s somewhat cynical towards its politicians, we&amp;#8217;re still remarkably willing to give government the benefit of the doubt.  We&amp;nbsp;shouldn&amp;#8217;t.&lt;/p&gt;
&lt;p&gt;Perhaps part of the apathy also comes from living in a world where organisations collecting data about us has become somewhat normalised.  Whether it&amp;#8217;s government or business, we know our actions are being tracked and stored.  We know that social media companies track and store a huge amount of data about our online activities.  We know that retail companies track our shopping habits through reward card&amp;nbsp;programs.&lt;/p&gt;
&lt;p&gt;But it&amp;#8217;s worth noting there&amp;#8217;s a big difference in the potential downside of a private company collecting data on users, and a government collecting data on its&amp;nbsp;citizens.&lt;/p&gt;
&lt;p&gt;For starters we have a choice whether to use the services of a private company, so we can always opt out.  But if we do decided to &amp;#8220;opt in&amp;#8221; to a business and use its services, it becomes a value proposition.  We accept that a social media website will track our usage, in exchange for the (free) service that social media website provides.  We accept the retailer tracking our purchases, in exchange for whatever perceived benefit we may get (whether real or illusory) from the rewards program.  If we decide the value provided by the service is no longer worthwhile, or the company displeases us enough in some way, we have the option of no longer doing business with&amp;nbsp;them.&lt;/p&gt;
&lt;p&gt;And usually the worst thing a private company can (legally) do is try to sell you something.  Or sell data about you to some other company that tries to sell you&amp;nbsp;something.&lt;/p&gt;
&lt;p&gt;In contrast, the worst thing a government can do is &lt;a class="reference external" href="http://au.pcmag.com/internet-products/26446/news/megauploads-kim-dotcom-is-broke"&gt;take all your money&lt;/a&gt;
and put you in jail for something you didn&amp;#8217;t do &amp;#8212; and maybe even execute&amp;nbsp;you.&lt;/p&gt;
&lt;p&gt;While the worst thing that can happen when Google&amp;#8217;s advertising algorithm goes wrong is you will see an ad that has zero relevance to you.  The worst thing that can happen if the government&amp;#8217;s data retention goes wrong is you end up in jail for the rest of your life even if you didn&amp;#8217;t do anything wrong.  Or &lt;a class="reference external" href="http://thenextweb.com/au/2012/07/26/anonymous-hacks-australian-isp-aapt-to-demonstrate-data-retention-problems/"&gt;hackers get hold of your metadata&lt;/a&gt;
and use it to steal your identity.  Or you end up stalked by horny &lt;span class="caps"&gt;ASIO&lt;/span&gt; agents who have been illicitly reading your emails and looking at your private photos in the cloud.  The possibilities for abuse are endless, but the benefits&amp;nbsp;nonexistent.&lt;/p&gt;
&lt;p&gt;There is no opt out from government mass surveillance, and no value proposition.  What do we as citizens get out of it?  Apart from a completely false sense of security?  Apart from the illusion of government doing &lt;em&gt;something&lt;/em&gt; about crime?  Data retention has never worked to prevent crime or terrorism anywhere in the world where it&amp;#8217;s been tried, so any perceived value is a&amp;nbsp;mirage.&lt;/p&gt;
&lt;p&gt;The benefits of data retention are illusory, but the &lt;a class="reference external" href="http://theconversation.com/nine-reasons-you-should-care-about-nsas-prism-surveillance-15075"&gt;downside is huge,&lt;/a&gt;
especially considering the &lt;a class="reference external" href="http://www.badscience.net/2009/02/datamining-would-be-lovely-if-it-worked/"&gt;false positives problem.&lt;/a&gt;
Terrorism is subject to the same principles of randomness and probability as everything else, and the false positives problem is the statistical reason &lt;a class="reference external" href="http://www.counterpunch.org/2006/05/24/why-does-the-nsa-engage-in-mass-surveillance-of-americans-when-it-s-statistically-impossible-for-such-spying-to-detect-terrorists/"&gt;data retention is ineffective in catching or preventing&amp;nbsp;criminals.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With any kind of data analysis, the larger and broader the dataset, the more statistical noise, and the harder it is to analyse the data to find rare patterns or occurrences.  When you have a large &lt;em&gt;untargeted&lt;/em&gt; dataset, of the sort generated by mandatory data retention, meaningless patterns will occur out of sheer randomness.  Just like when tossing a coin, it&amp;#8217;s not unusual to get series of heads or tails in a row, but those consecutive heads or tails runs are just random noise and don&amp;#8217;t tell us anything about the long term probabilities of the coin toss.  This kind of randomness makes
using a huge collection of data to find a very small number of criminals or terrorists pretty much impossible.  Of particular concern is that any kind of analysis will generate a huge number of false positives &amp;#8212; totally innocent people the algorithm has flagged due to randomness.  No matter how good the algorithms may be, not matter how advanced the analysis, there will still be a huge number of false positives, because that&amp;#8217;s how the probabilities play&amp;nbsp;out.&lt;/p&gt;
&lt;p&gt;Given that the worst thing a government can do if it&amp;#8217;s wrong about an individual is take away everything they own and deprive them of their freedom for the rest of their life, mandatory data retention should be of concern to everyone.  Especially &lt;a class="reference external" href="http://www.crikey.com.au/2015/02/06/data-retention-will-hurt-you-not-criminals-heres-how/"&gt;innocent, law-abiding citizens.&lt;/a&gt;
Those thinking they have &lt;a class="reference external" href="http://chronicle.com/article/Why-Privacy-Matters-Even-if/127461/"&gt;nothing to hide&lt;/a&gt;
because they haven&amp;#8217;t done anything wrong are in for a rude awakening if they&amp;#8217;re unlucky enough to end up being one of false&amp;nbsp;positives.&lt;/p&gt;
&lt;p&gt;Mandatory data retention will increase the chances of innocent people being convicted of crimes they didn&amp;#8217;t commit, all the while diverting police resources from pursuing actual guilty&amp;nbsp;criminals.&lt;/p&gt;
&lt;p&gt;Any kind of analysis on the metadata database will flag so many genuinely innocent people as potential criminals worthy of investigation, it will be impossible to sift through them all to find the truly guilty.  Police and intelligence resources will be wasted on wild metadata driven goose chases, trying to establish that innocent people are actually innocent.  Or worse, prosecuting the&amp;nbsp;innocent.&lt;/p&gt;
&lt;p&gt;Authorities already have considerable powers for targeted data collection on specific suspects.  It is extreme overkill, not to mention extremely expensive and counterproductive, to use mass  surveillance to collect data on everyone.  Especially the&amp;nbsp;innocent.&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related&amp;nbsp;Posts:&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/02/23/who-cares-about-data-retention-anyway/"&gt;Who cares about data retention&amp;nbsp;anyway?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/28/metadata-karma/"&gt;Metadata&amp;nbsp;karma&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/22/they-are-coming-for-us-and-our-metadata/"&gt;They&amp;#8217;re coming for us and our&amp;nbsp;metadata&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/25/we-all-have-something-to-hide-from-mandatory-meta-data-retention/"&gt;We all have something to&amp;nbsp;hide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="privacy"></category><category term="data retention"></category><category term="metadata"></category><category term="politics"></category><category term="surveillance"></category></entry><entry><title>Who cares about data retention anyway?</title><link href="http://www.voidynullness.net/blog/2015/02/23/who-cares-about-data-retention-anyway/" rel="alternate"></link><published>2015-02-23T00:00:00+11:00</published><updated>2015-02-23T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2015-02-23:/blog/2015/02/23/who-cares-about-data-retention-anyway/</id><summary type="html">&lt;p class="standfirst"&gt;There&amp;#8217;s a whole world of apathy out&amp;nbsp;there&amp;#8230;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span class="dquo"&gt;&amp;#8220;&lt;/span&gt;The Australian people are being sleep walked into a system the
Attorney-General cannot even&amp;nbsp;articulate.&amp;#8221;&lt;/p&gt;
&lt;p class="attribution"&gt;&amp;mdash;&lt;a class="reference external" href="http://www.sbs.com.au/news/article/2015/02/20/loopholes-leave-current-metadata-system-open-abuse-police-insider-reveals"&gt;Police insider speaking to &lt;span class="caps"&gt;ABC&lt;/span&gt;&amp;nbsp;Radio&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Over the weekend I caught up with a couple friends I hadn&amp;#8217;t seen for a
while.  Friends outside of the &lt;span class="caps"&gt;IT&lt;/span&gt;&amp;nbsp;industry.&lt;/p&gt;
&lt;p&gt;At one point, when the conversation turned towards politics, I asked if
they had heard about the government&amp;#8217;s proposed mandatory data retention
plan.  Neither&amp;nbsp;had.&lt;/p&gt;
&lt;p&gt;&lt;span class="dquo"&gt;&amp;#8220;&lt;/span&gt;Don …&lt;/p&gt;</summary><content type="html">&lt;p class="standfirst"&gt;There&amp;#8217;s a whole world of apathy out&amp;nbsp;there&amp;#8230;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span class="dquo"&gt;&amp;#8220;&lt;/span&gt;The Australian people are being sleep walked into a system the
Attorney-General cannot even&amp;nbsp;articulate.&amp;#8221;&lt;/p&gt;
&lt;p class="attribution"&gt;&amp;mdash;&lt;a class="reference external" href="http://www.sbs.com.au/news/article/2015/02/20/loopholes-leave-current-metadata-system-open-abuse-police-insider-reveals"&gt;Police insider speaking to &lt;span class="caps"&gt;ABC&lt;/span&gt;&amp;nbsp;Radio&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Over the weekend I caught up with a couple friends I hadn&amp;#8217;t seen for a
while.  Friends outside of the &lt;span class="caps"&gt;IT&lt;/span&gt;&amp;nbsp;industry.&lt;/p&gt;
&lt;p&gt;At one point, when the conversation turned towards politics, I asked if
they had heard about the government&amp;#8217;s proposed mandatory data retention
plan.  Neither&amp;nbsp;had.&lt;/p&gt;
&lt;p&gt;&lt;span class="dquo"&gt;&amp;#8220;&lt;/span&gt;Don&amp;#8217;t get him started,&amp;#8221; said my girlfriend, as I launched into a variation
of a rant she&amp;#8217;d probably heard&amp;nbsp;before.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m not sure if I should give her points for putting up with my
political/geeky rants, or question our relationship given her disturbing
lack of feels about privacy and democratic freedoms?  (Maybe she&amp;#8217;s
an &lt;span class="caps"&gt;ASIO&lt;/span&gt;&amp;nbsp;spy?!)&lt;/p&gt;
&lt;p&gt;These two friends were reasonably active on Facebook (not so much Twitter),
and lately the only thing I&amp;#8217;ve been doing on Facebook (and Twitter) is
sharing articles about data retention (&lt;a class="reference external" href="https://twitter.com/robulouski"&gt;I am really fun on social media&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Which raises the question of whether these (supposed) friends were ignoring
my Facebook posts from lack of interest, or if Facebook&amp;#8217;s algorithm
didn&amp;#8217;t bother showing my activity in their&amp;nbsp;feeds?&lt;/p&gt;
&lt;p&gt;It would not surprise me if it was the former.  Not everyone amongst my
friends and family shares my zeal for technology and politics issues.
Actually, few do, even those more technically&amp;nbsp;inclined.&lt;/p&gt;
&lt;p&gt;My brother, for one, is usually quite blunt about his lack of interest in
most things I deem worthy of sharing on Facebook.  We might share &lt;span class="caps"&gt;DNA&lt;/span&gt;, but
he shares little of my computer geek interests.  He has no qualms about
telling me that even though he sees most of my status updates in his
Facebook feed, he ignores almost all of them because they are of no
interest to him.  And because any articles I share usually require too much&amp;nbsp;reading.&lt;/p&gt;
&lt;p&gt;Surrounded by such indifference, I have resigned myself to the fact that
I am merely shouting into the void on social media (and this&amp;nbsp;blog).&lt;/p&gt;
&lt;p&gt;Still, while not necessarily surprising, it&amp;#8217;s still somewhat disconcerting
that others can be so oblivious to an issue that has had reasonable media
coverage, and quite a lot of traction on social&amp;nbsp;media.&lt;/p&gt;
&lt;p&gt;But by its personalised nature, everyone&amp;#8217;s experience on social media will
reflect their interests.  Especially in the echo chamber of&amp;nbsp;Twitter.&lt;/p&gt;
&lt;p&gt;While my Twitter feed is a constant stream of anti-data-retention vitriol,
that&amp;#8217;s unlikely to be everyone else&amp;#8217;s&amp;nbsp;experience.&lt;/p&gt;
&lt;p&gt;Even amongst &amp;#8220;friends&amp;#8221; on Facebook, an item shared is not necessarily an
item that anyone else payed any attention to whatsoever.  Especially if it
was about something as &amp;#8220;niche&amp;#8221; as data&amp;nbsp;retention.&lt;/p&gt;
&lt;p&gt;While I, and many others, obviously have some strong opinions about data
retention and privacy issues, and have expended considerable effort trying
to spread the word online, that doesn&amp;#8217;t mean it has grabbed the attention
of the&amp;nbsp;masses.&lt;/p&gt;
&lt;p&gt;Things are very different in the real world, outside of Twitter and the &lt;span class="caps"&gt;IT&lt;/span&gt;
industry and geeky social circles.  Sometimes social media makes it easy to
forget&amp;nbsp;that.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;d bet most people are largely indifferent to the issue of mandatory data&amp;nbsp;retention.&lt;/p&gt;
&lt;p&gt;Out in the suburban mainstream, many people haven&amp;#8217;t heard of data
retention.  And even if they have, they don&amp;#8217;t really care.  It doesn&amp;#8217;t seem
like something that should  matter to them, with their McMansions and their
weekend sportsball.  Even though it&amp;nbsp;does.&lt;/p&gt;
&lt;p&gt;Which once again confirms my belief that social media might have its uses,
but it&amp;#8217;s not a particularly effective tool for activism.  Few people have
changed their minds because of a pithy tweet or dank meme.  Social media
tends towards preaching to the converted.  Communicating to the apathetic
masses through social media doesn&amp;#8217;t work for seemingly dry tech issues like
data retention, even though the privacy implications are wide ranging and
will affect &lt;em&gt;everyone&lt;/em&gt; using the&amp;nbsp;internet.&lt;/p&gt;
&lt;p&gt;In my &lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/02/18/electronic-graffiti/"&gt;previous post&lt;/a&gt; I
pondered politicians not taking social media criticism seriously.  This
is another reason why they won&amp;#8217;t.  I suspect they realise the repercussions
of social media are relatively benign.  At most, a social media backlash
might get generate a few fleeting minutes of coverage within the 24 hour
news cycle, in between the real money shots of news &amp;#8212; celebrity gossip and&amp;nbsp;sport.&lt;/p&gt;
&lt;p&gt;This is why, despite all the angry tweets about data retention, despite
the shared links to articles pointing out the flaws in the concept, our
politicians will ultimately get their way.  Our politicians will succeed
at undermining our democracy and eroding our&amp;nbsp;privacy.&lt;/p&gt;
&lt;p&gt;Because most people just don&amp;#8217;t&amp;nbsp;care.&lt;/p&gt;
&lt;p&gt;And those that do are just shouting into the&amp;nbsp;void.&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related&amp;nbsp;Posts:&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/02/18/electronic-graffiti/"&gt;Electronic&amp;nbsp;Graffiti&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="privacy"></category><category term="data retention"></category><category term="metadata"></category><category term="politics"></category></entry><entry><title>Electronic Graffiti</title><link href="http://www.voidynullness.net/blog/2015/02/18/electronic-graffiti/" rel="alternate"></link><published>2015-02-18T00:00:00+11:00</published><updated>2015-02-18T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2015-02-18:/blog/2015/02/18/electronic-graffiti/</id><summary type="html">&lt;p&gt;Australian politics is weird at the moment.  More so than&amp;nbsp;usual.&lt;/p&gt;
&lt;p&gt;We have a conservative Prime Minister so incompetent and unpopular that
even conservatives are having some pretty intense buyers&amp;#8217;&amp;nbsp;remorse.&lt;/p&gt;
&lt;p&gt;His own &lt;a class="reference external" href="http://www.theage.com.au/federal-politics/political-news/liberal-mp-dennis-jensen-calls-on-tony-abbott-to-resign-20150203-1358jm.html"&gt;backbenchers even tried to get rid of him.&lt;/a&gt;
&lt;a class="reference external" href="http://www.news.com.au/national/tony-abbott-faces-liberal-leadership-spill-motion/story-fncynjr2-1227212587207"&gt;But he survived,&lt;/a&gt;
so the country is still stuck with Tony Abbott as &lt;span class="caps"&gt;PM&lt;/span&gt;.  For&amp;nbsp;now.&lt;/p&gt;
&lt;p&gt;Tony Abbott survives to gaffe another day, and if past performance is any
indicator of future performance, there will be more gaffes to …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Australian politics is weird at the moment.  More so than&amp;nbsp;usual.&lt;/p&gt;
&lt;p&gt;We have a conservative Prime Minister so incompetent and unpopular that
even conservatives are having some pretty intense buyers&amp;#8217;&amp;nbsp;remorse.&lt;/p&gt;
&lt;p&gt;His own &lt;a class="reference external" href="http://www.theage.com.au/federal-politics/political-news/liberal-mp-dennis-jensen-calls-on-tony-abbott-to-resign-20150203-1358jm.html"&gt;backbenchers even tried to get rid of him.&lt;/a&gt;
&lt;a class="reference external" href="http://www.news.com.au/national/tony-abbott-faces-liberal-leadership-spill-motion/story-fncynjr2-1227212587207"&gt;But he survived,&lt;/a&gt;
so the country is still stuck with Tony Abbott as &lt;span class="caps"&gt;PM&lt;/span&gt;.  For&amp;nbsp;now.&lt;/p&gt;
&lt;p&gt;Tony Abbott survives to gaffe another day, and if past performance is any
indicator of future performance, there will be more gaffes to come.  Many,
many&amp;nbsp;more.&lt;/p&gt;
&lt;p&gt;Abbott just stumbles from one gaffe to another.  We barely have time to
laugh, scoff, scorn, shake our heads and wonder in disbelief at what Abbott
was thinking when he said that &amp;#8212; before he goes and says or does something
else even more astonishingly&amp;nbsp;stupid.&lt;/p&gt;
&lt;p&gt;Or &lt;a class="reference external" href="http://www.theguardian.com/tv-and-radio/australia-culture-blog/2014/aug/11/eric-abetz-and-george-brandis-give-the-bachelor-a-run-for-idiocy"&gt;one of his ministers&amp;nbsp;obliges.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;When Attorney General George Brandis hilariously bungled an attempt to
&lt;a class="reference external" href="http://www.smh.com.au/digital-life/digital-life-news/george-brandis-in-car-crash-interview-over-controversial-data-retention-regime-20140806-101849.html"&gt;explain metadata on Sky News,&lt;/a&gt;
it quite rightly made him an object of ridicule.  But not for long enough,
in my opinion.  I felt this particular fuckup was so bad yet so easily
preventable (do some research Brandis, it&amp;#8217;s your job!), that the public
deserved to dine out on it for much longer.  Despite the ridicule he got,
Brandis deserved a lot more, since he clearly did not have any
understanding of laws he was proposing.  It got a bit of media attention,
then the media focus quickly moved on to other senior government
ministers embarrassing themselves, so I think we got a bit short
changed.  Brandis&amp;#8217;s self-inflicted metadata mess was soon overshadowed by
other government ministers saying stupid shit &amp;#8212; Treasurer Joe Hockey
saying poor people don&amp;#8217;t drive cars, and Senator Eric Abetz claiming
abortion causes breast&amp;nbsp;cancer.&lt;/p&gt;
&lt;p&gt;Stupidity must be contagious in the Liberal&amp;nbsp;Party.&lt;/p&gt;
&lt;p&gt;But seems even the Liberal Party must draw a line somewhere.  And looks
like Abbott crossed that line by
&lt;a class="reference external" href="http://www.news.com.au/entertainment/celebrity-life/tony-abbotts-knightmare-could-be-fatal-if-his-government-fails-to-change-tack/story-fnisprwn-1227197985652"&gt;giving a knighthood to British royalty.&lt;/a&gt;
On Australia&amp;nbsp;Day.&lt;/p&gt;
&lt;p&gt;Yes, the
&lt;a class="reference external" href="http://www.theguardian.com/australia-news/2015/jan/26/tony-abbott-acknowledges-internal-critics-but-dismisses-electronic"&gt;Prime Minister of Australia
bestowed a knighthood on Prince Philip,&lt;/a&gt;
the Queen&amp;#8217;s husband.  On a day when the country celebrates the achievements of great
Australians, Tony Abbott decided to honour British royalty&amp;nbsp;instead.&lt;/p&gt;
&lt;p&gt;Obviously, a lot of people thought this was really stupid.  It was
another episode in his sitcom of a government; another moment when the nation
collectively asked: &amp;#8220;What the hell was Abbott thinking?  Didn&amp;#8217;t he run that
idea by anyone first?  Doesn&amp;#8217;t he have&amp;nbsp;advisers?&amp;#8221;&lt;/p&gt;
&lt;p&gt;Quite predictably, social media had a field day with this.  Especially on&amp;nbsp;Twitter.&lt;/p&gt;
&lt;p&gt;But Abbott dismissed the outpouring of scorn on social media as
&lt;a class="reference external" href="http://www.gizmodo.com.au/2015/01/aussie-pm-tony-abbott-thinks-that-social-media-is-electronic-graffiti/"&gt;electronic graffiti.&lt;/a&gt;  His exact words&amp;nbsp;were:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Social media is kind of like electronic graffiti and I think that in
the media, you make a big mistake to pay too much attention to social&amp;nbsp;media.&lt;/p&gt;
&lt;p&gt;You wouldn’t report what’s sprayed up on the walls of buildings and
look, as I said, social media has its place, but it’s anonymous. It’s
often very abusive and, in a sense, it has about as much authority and
credibility as graffiti that happens to be put forward by means of &lt;span class="caps"&gt;IT&lt;/span&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Predictably, this didn&amp;#8217;t help his cause much, and it definitely didn&amp;#8217;t
make him seem any less out of&amp;nbsp;touch.&lt;/p&gt;
&lt;p&gt;But while the &amp;#8220;electronic graffiti&amp;#8221; line will no doubt live on as an ironic Twitter
hashtag for a while yet, once again mainstream media coverage (and derision) was
disappointingly brief, as leadership speculation and the subsequent &lt;a class="reference external" href="http://www.sbs.com.au/news/article/2015/02/06/spill-motion-be-moved-against-tony-abbott"&gt;spill motion&lt;/a&gt;
became the&amp;nbsp;story.&lt;/p&gt;
&lt;p&gt;So I want to pause for a moment, and ponder the
&lt;a class="reference external" href="http://theconversation.com/no-tony-abbott-you-cant-dismiss-social-media-as-electronic-graffiti-36819"&gt;electronic graffiti&lt;/a&gt;
comment a&amp;nbsp;bit.&lt;/p&gt;
&lt;p&gt;Sure, it&amp;#8217;s a another sign that Tony Abbott knows little about technology,
and certainly doesn&amp;#8217;t &amp;#8220;get&amp;#8221; social media.  Dismissing what has become a
mainstream communication and entertainment medium in this way is just&amp;nbsp;weird.&lt;/p&gt;
&lt;p&gt;But treating this as another example of Abbott being out of touch and
technologically illiterate is far too simplistic.  Maybe even far too
generous.  I think it goes far deeper than his apathy &amp;#8212; and sometimes
outright disdain &amp;#8212; for science and&amp;nbsp;technology.&lt;/p&gt;
&lt;p&gt;Abbott&amp;#8217;s &amp;#8220;electronic graffiti&amp;#8221; comment is nothing less than a sign of his
utter contempt for voters combined with an unbounded ego.  The subtext
behind it isn&amp;#8217;t just that things people say on social media don&amp;#8217;t matter &amp;#8212;
it&amp;#8217;s that things people say in general don&amp;#8217;t matter.  Abbott simply does
not care about other people, their opinions, or criticisms.  His overblown
ego doesn&amp;#8217;t allow it.  Hence his many silly &amp;#8220;captain&amp;#8217;s picks&amp;#8221;, made with
little consultation, and probably with the firm belief he was making
great&amp;nbsp;decisions.&lt;/p&gt;
&lt;p&gt;Tony Abbott has a weirdly inflated view of his own superiority and
infallibility.  Even his own backbenchers are not worth listening to, it
seems.  The recent spill motion was initiated by backbenchers who felt
their views and need were being ignored.  If Abbott doesn&amp;#8217;t care what his
ministers or backbenchers think, he sure as hell won&amp;#8217;t care what randoms on
Twitter think of&amp;nbsp;him.&lt;/p&gt;
&lt;p&gt;Another manifestation of this mindset was demonstrated during &lt;a class="reference external" href="http://www.abc.net.au/news/2015-02-02/crabb-pm-fights-for-survival-in-hunger-games-speech/6063782"&gt;his National Press Club speech,&lt;/a&gt;
when Abbott insulted voters and disparaged democracy by saying people elect Labor
governments in &lt;a class="reference external" href="http://www.smh.com.au/federal-politics/political-opinion/tony-abbotts-threats-scare-tactics-only-dig-him-a-deeper-hole-20150202-1349o4.html"&gt;a fit of absent-mindedness.&lt;/a&gt;
Tact and subtlety are not exactly hallmarks of
&lt;a class="reference external" href="http://www.sbs.com.au/news/article/2015/02/13/comment-page-intentionally-left-blank?cid=trending"&gt;Abbott&amp;#8217;s communication
skills.&lt;/a&gt;
Neither is any awareness of irony &amp;#8212; someone as famously gaffe prone as
Abbott really isn&amp;#8217;t in any position to be calling anyone else &amp;#8220;absent
minded&amp;#8221;, and certainly not millions of&amp;nbsp;voters!&lt;/p&gt;
&lt;p&gt;Of course, an egotistical and arrogant politician is hardly a rarity.  It&amp;#8217;s
more like a prerequisite for the job.  But it helps if there is a vision
and intelligence &amp;#8212; there&amp;#8217;s little evidence Abbott possesses either &amp;#8212; to
back up the attitude.  Abbott&amp;#8217;s confidence is based purely on his own&amp;nbsp;delusions.&lt;/p&gt;
&lt;p&gt;All of this has some potentially profound implications for those contemplating
any kind of political&amp;nbsp;activism.&lt;/p&gt;
&lt;p&gt;Some people use social media with an determined earnestness, labouring
under a false belief that their social media sharing and posting might
make a difference, somehow.  That their Facebook posts, tweets, and blog
posts actually&amp;nbsp;matter.&lt;/p&gt;
&lt;p&gt;I doubt it.  The idea that social media makes a difference is just as
delusional as Abbott&amp;#8217;s belief in his own&amp;nbsp;superiority.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve always been sceptical of the effectiveness of online activism of any
kind.  Whether it&amp;#8217;s the slacktivism of online petitions, the clicktivism of
groups like GetUp, or the various combinations of blog posts, memes,
Facebook status updates and tweets &amp;#8212; mostly it&amp;#8217;s just shouting into the
digital&amp;nbsp;void.&lt;/p&gt;
&lt;p&gt;Proof of this abundant, if we look at the many cases where online activism
failed.  Especially in technology-related issues, which are more likely to
provoke online&amp;nbsp;angst.&lt;/p&gt;
&lt;p&gt;Take the National Broadband Network, for example.  Few people within the &lt;span class="caps"&gt;IT&lt;/span&gt;
industry thought the Coalition&amp;#8217;s alternative to the &lt;span class="caps"&gt;NBN&lt;/span&gt; was a good idea.
Pretty much nobody on Twitter thought it was a good idea.  But online
petitions and widespread derision on Twitter didn&amp;#8217;t stop the Coalition from
destroying the &lt;span class="caps"&gt;NBN&lt;/span&gt;.  What we&amp;#8217;re getting now cannot even be accurately as
either &amp;#8220;national&amp;#8221; or &amp;#8220;broadband&amp;#8221;, and it&amp;#8217;s barely even a &amp;#8220;network&amp;#8221;.
Labor&amp;#8217;s vision for universal fibre is pretty much dead.  All the online
outrage and well reasoned articles and blog posts didn&amp;#8217;t save the &lt;span class="caps"&gt;NBN&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Then there&amp;#8217;s the new National Security laws, many of which are designed to
restrict online freedoms.  The first two tranches of National Security laws
were unnecessary, un-democratic, and deeply flawed.  Reaction on social
media (and also mainstream media outside of Murdoch publications) was
mostly negative.  Yet, the legislation passed.  And there&amp;#8217;s more to come
with the third tranche of laws &amp;#8212; for mandatory data retention &amp;#8212; still
before the&amp;nbsp;parliament.&lt;/p&gt;
&lt;p&gt;The battle over mandatory data retention is still being fought, but like
the other battles between the technology industry and the government, it&amp;#8217;s
one were the government will probably win.  The government will win because
people outside the tech industry don&amp;#8217;t care, and those within it who do
care are wasting time online instead of taking the fight to politicians
offline.  Despite widespread criticism on social media and opposition from
the telecommunications industry, mandatory data retention is likely to be
implemented.  The government will succeed at forcing the telecommunications
industry to implement ineffective, expensive and misguided&amp;nbsp;policy.&lt;/p&gt;
&lt;p&gt;Of course, few would have realistically expected much from this government
in terms of science and technology.  Though many might be surprised by the
level of hostility towards issues in these areas &amp;#8212; not to mention abject
incompetence.  From broadband to climate change, this &lt;span class="caps"&gt;LNP&lt;/span&gt; government seemingly
prides itself on being behind the times.  Australia currently has a government
suspicious of any technology that&amp;#8217;s not directly &lt;a class="reference external" href="http://www.smh.com.au/federal-politics/political-news/coal-is-good-for-humanity-says-tony-abbott-at-mine-opening-20141013-115bgs.html"&gt;coal-related.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We can certainly forget about any prospect of sensible technology policy
from this government.  Not while we have a Prime Minister who thinks the
internet is &lt;a class="reference external" href="http://www.computerworld.com.au/article/525840/his_own_words_tony_abbott_nbn/"&gt;&amp;#8220;essentially a video entertainment&amp;nbsp;system&amp;#8221;.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The best we can hope to achieve is to stop these idiots messing things up
too badly &amp;#8212; stop them implementing bad laws and  bad policy based on
outdated beliefs and flawed ideology.  Our chances don&amp;#8217;t look good based on
past performance.  Especially if we&amp;#8217;re going to rely on social media as our
main strategy.  (Thank God for a hostile&amp;nbsp;Senate!)&lt;/p&gt;
&lt;p&gt;Tony Abbott&amp;#8217;s view of social media as &amp;#8220;electronic graffiti&amp;#8221; is further
evidence of the impotence of social media in influencing the political
process.  I suspect it&amp;#8217;s more than just another of his weird-ass,
brain-fart soundbites.  In this case, it&amp;#8217;s a reflection of his true beliefs
&amp;#8212; and from his position of power and privilege, those beliefs become self
fulfilling prophecy.  By believing social media is not worthy of his
attention, Abbott will happily ignore it, as will his ministers and his&amp;nbsp;government.&lt;/p&gt;
&lt;p&gt;Another reason I think social media matters little to politicians is that
they&amp;#8217;ve made little attempt to regulate it.  Politicians love to regulate
stuff.  It&amp;#8217;s kind of why they exist.  They regulate things even if there&amp;#8217;s
no sensible reason to regulate it (the data retention thing is an example
of that).  I suspect the reason that they&amp;#8217;ve largely left social media
alone is partly because they don&amp;#8217;t really understand it (even though
they&amp;#8217;re &lt;a class="reference external" href="http://www.smh.com.au/federal-politics/political-news/abbott-government-spends-up-big-on-media-monitoring-20150104-12hj88.html"&gt;spending a lot of money monitoring it&lt;/a&gt;), but mostly because they
realise it&amp;#8217;s an excellent (and low cost) marketing tool for their own
purposes.  Which is essentially the whole point of social media.  Some
users might think they&amp;#8217;re being subversive by posting political content,
but it&amp;#8217;s all part of the plan.  Social media is mostly a platform for
advertising and marketing.  It is just entertainment for the masses.  In
the bread and circuses of politics, social media is just another&amp;nbsp;circus.&lt;/p&gt;
&lt;p&gt;Maybe one day social media will have real influence in the political
process, but I suspect that day is at least a generation away.  Maybe when
the current generation that has grown up with social media is in power,
they will be more inclined to pay attention to the vitriolic rantings of
the Twitter hoards.  Although by then social media will probably have
morphed into a different (more corporatised?  more regulated?) beast than
what it is&amp;nbsp;today.&lt;/p&gt;
&lt;p&gt;Or maybe social media will remain mostly a distraction for the masses, and
mostly useless for political activism.  While online activism may
occasionally have a win with little issues, it rarely has much effect when
it comes to big political issues &amp;#8212; especially issues driven by corporate
interests with lots of money on their&amp;nbsp;side.&lt;/p&gt;
&lt;p&gt;In a way, the current Coalition government is a case study in the
ineffectiveness of online activism.  Just about everything they&amp;#8217;ve done &amp;#8212;
from border protection and asylum seekers to national security &amp;#8212; has been
met with widespread criticism on social media.  As a government, they are
incompetent and clueless, and about as unpopular as it&amp;#8217;s possible to be in
Australian politics.  Yet, they&amp;#8217;ve been remarkably successful at
implementing bad laws and making bad decisions, particularly on issues
affecting technology users and the technology industry, where the online
backlash has been especially&amp;nbsp;harsh.&lt;/p&gt;
&lt;p&gt;Despite this, they&amp;nbsp;won.&lt;/p&gt;
&lt;p&gt;They won because governments don&amp;#8217;t care about criticism on social media.
They won because there aren&amp;#8217;t enough votes or campaign donations in
technology issues for it to matter that a bunch of nerds on Twitter are
angry at&amp;nbsp;them.&lt;/p&gt;
&lt;p&gt;We&amp;#8217;re going to need a lot more than dank memes to make a dent in the
entrenched &lt;span class="caps"&gt;LNP&lt;/span&gt; apathy to technology&amp;nbsp;issues.&lt;/p&gt;
&lt;p&gt;By all means use social media to&amp;nbsp;vent.&lt;/p&gt;
&lt;p&gt;Just don&amp;#8217;t do so thinking it will achieve anything.  Because if past
performance is any indicator, &lt;a class="reference external" href="http://www.suck.com/daily/2000/09/08/"&gt;it&amp;nbsp;won&amp;#8217;t.&lt;/a&gt;&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related&amp;nbsp;Posts:&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/04/14/go-work-down-the-mines-liberal-nbn-broadband-policy/"&gt;The Liberal Party&amp;#8217;s broadband policy&amp;nbsp;explained&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/01/05/screwed-to-the-node/"&gt;Screwed To The&amp;nbsp;Node&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="politics"></category><category term="data retention"></category><category term="metadata"></category></entry><entry><title>The Who Hacked Sony Story</title><link href="http://www.voidynullness.net/blog/2015/02/02/the-who-hacked-sony-story/" rel="alternate"></link><published>2015-02-02T00:00:00+11:00</published><updated>2015-02-02T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2015-02-02:/blog/2015/02/02/the-who-hacked-sony-story/</id><summary type="html">&lt;p&gt;The recent &lt;a class="reference external" href="http://www.vox.com/2014/12/14/7387945/sony-hack-explained"&gt;Sony hack&lt;/a&gt;
was notable for many reasons, not least of which is how
&lt;a class="reference external" href="http://www.wired.com/2014/12/sony-hack-what-we-know/"&gt;devastatingly successful&lt;/a&gt;
it was &amp;#8212; hackers managed to get hold of huge amounts of sensitive&amp;nbsp;data.&lt;/p&gt;
&lt;p&gt;But one aspect that intrigued me in particular was the way it was reported,
and how different angles of the story were emphasised (or de-emphasised)
by different media&amp;nbsp;outlets.&lt;/p&gt;
&lt;p&gt;Obviously this story would be of some interest to those technically
inclined, especially those working in areas of technology or cybersecurity …&lt;/p&gt;</summary><content type="html">&lt;p&gt;The recent &lt;a class="reference external" href="http://www.vox.com/2014/12/14/7387945/sony-hack-explained"&gt;Sony hack&lt;/a&gt;
was notable for many reasons, not least of which is how
&lt;a class="reference external" href="http://www.wired.com/2014/12/sony-hack-what-we-know/"&gt;devastatingly successful&lt;/a&gt;
it was &amp;#8212; hackers managed to get hold of huge amounts of sensitive&amp;nbsp;data.&lt;/p&gt;
&lt;p&gt;But one aspect that intrigued me in particular was the way it was reported,
and how different angles of the story were emphasised (or de-emphasised)
by different media&amp;nbsp;outlets.&lt;/p&gt;
&lt;p&gt;Obviously this story would be of some interest to those technically
inclined, especially those working in areas of technology or cybersecurity.  As
such, there are some complex technical aspects, which might be of interest
to a certain tech savvy demographic, but perhaps not so much to a more
general mainstream audience.  But while it&amp;#8217;s one thing to tailor the amount
technical detail in reporting to the level of your target audience, it&amp;#8217;s
another thing entirely to just regurgitate government propaganda without
any attempt at providing&amp;nbsp;context.&lt;/p&gt;
&lt;p&gt;Yet, that increasingly became the nature of the reporting, especially in
the weeks after the story first broke, as more details were made public.
In a way, the more information that emerged, the more distorted that
information&amp;nbsp;became.&lt;/p&gt;
&lt;p&gt;Pretty soon, the &amp;#8220;official&amp;#8221; narrative became that the North Korean
government was responsible for hacking Sony.  After that most major
&amp;#8220;mainstream&amp;#8221; news sources just reported this as if it was a proven fact,
without any attempt at context or&amp;nbsp;nuance.&lt;/p&gt;
&lt;p&gt;Anyone with just a passing interest in the story, who was getting their
news only from popular mainstream news websites, would be left convinced
that hacking Sony was all part of a cyberwar North Korea was waging on its
perceived enemies in the&amp;nbsp;West.&lt;/p&gt;
&lt;p&gt;This is in stark contrast to the way this story was reported on technical
news sites, and the way knowledgeable bloggers wrote about&amp;nbsp;it.&lt;/p&gt;
&lt;p&gt;The North Korea cyberwar narrative might make for a better story, and a
more dramatic story, but it there&amp;#8217;s a lot more going on than&amp;nbsp;that.&lt;/p&gt;
&lt;p&gt;Right from the start, many security experts considered it unlikely North
Korea were the perpetrators.  With these kinds of hacking attacks,
&lt;a class="reference external" href="http://www.theatlantic.com/international/archive/2015/01/we-still-dont-know-who-hacked-sony-north-korea/384198/"&gt;attribution is notoriously difficult.&lt;/a&gt;
So far, all the evidence linking it to North Korea is circumstantial at
best.  Sony is also a strange and rather low value target for a
nation state.  The case that Sony was targeted because of &amp;#8220;The Interview&amp;#8221;
movie is weakened by the fact the attackers only mentioned the movie after
the media started speculating about this possiblity.  Surely these points
are worth noting, if only in passing, in any objective reporting of the
story?  Even one aimed at a non-technical&amp;nbsp;audience?&lt;/p&gt;
&lt;p&gt;While it&amp;#8217;s hardly surprising to see tech news reported badly or
innacurately, it was still dissapointing &amp;#8212; and disturbing &amp;#8212; to see how
pervasive the official government line became, that North Korea was&amp;nbsp;responsible.&lt;/p&gt;
&lt;p&gt;Especially considering the &lt;a class="reference external" href="https://securityledger.com/2014/12/new-clues-in-sony-hack-point-to-insiders-away-from-dprk/"&gt;increasingly likely theory&lt;/a&gt;
that the Sony hack was actually the work
of &lt;a class="reference external" href="http://www.theguardian.com/film/2014/dec/30/sony-hack-researchers-claim-sacked-employees-could-be-to-blame"&gt;disgruntled former employees,&lt;/a&gt;
who may have planted malware software from the inside, stolen data, and
handed over crucial details of Sony&amp;#8217;s internal network to&amp;nbsp;hackers.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m no security expert, but this seems like a far more likely scenario.
The hackers were so successful that it seems inconceivable they could have
achieved as much as they did without help from the inside.  It&amp;#8217;s
astonishing that hackers might have managed to transfer so much data out
Sony&amp;#8217;s network without anyone noticing.  If that is what happened, then
Sony had some seriously inadequate network monitoring in place.  Even so,
isn&amp;#8217;t it far more likely that some disgruntled employees copied huge amount
of sensitive corporate data onto external &lt;span class="caps"&gt;USB&lt;/span&gt; drives, then just walked out
the door with&amp;nbsp;them?&lt;/p&gt;
&lt;p&gt;Of course, the &lt;span class="caps"&gt;US&lt;/span&gt; government has officially blamed North Korea for the cyber
attack on Sony.  Which doesn&amp;#8217;t mean it&amp;#8217;s necessarily true.
Sure, with all they spying the &lt;span class="caps"&gt;NSA&lt;/span&gt; is doing (along with other government
agencies) it&amp;#8217;s certainly likely that the
&lt;a class="reference external" href="https://firstlook.org/theintercept/2015/01/09/nsa-played-key-role-linking-north-korea-sony-h/"&gt;&lt;span class="caps"&gt;US&lt;/span&gt; government knows a lot more&lt;/a&gt;
than they are publicly revealing.  But blaming North Korea is awfully
convenient, considering we may never know for sure who is&amp;nbsp;responsible.&lt;/p&gt;
&lt;p&gt;After all, what&amp;#8217;s more likely: That a secretive, poor,
communist country with little internet infrastructure launched a
phenomenally successful cyber attack against Sony because they were about
to release a crappy Seth Rogen movie?  Or that disgruntled employees
planted malware, then handed over the details to some hacker group?  My
money is on the&amp;nbsp;latter.&lt;/p&gt;
&lt;p&gt;But most of the media went with the official government&amp;nbsp;line.&lt;/p&gt;
&lt;p&gt;So much for the internet setting truth&amp;nbsp;free.&lt;/p&gt;
&lt;p&gt;Anyone else remember when the internet first started to become mainstream?
Remember the hype of the dot-com boom?  We were entering a new age, we were
told.  Old media was now obsolete.  The internet would obliterate all
the old publishing empires, and bring in a glorios new age of self
publishing.  No more would media moguls and governments control the flow of
information.  Because information wanted to be free!  The truth is out&amp;nbsp;there!&lt;/p&gt;
&lt;p&gt;Didn&amp;#8217;t really turn out that way, did it?  Maybe kinda sorta, if you squint
real hard, and lower your expectations.  There are still book publishers,
record labels, newspaper companies.  Sure, many of them struggling for
profitability or relevance, but they&amp;#8217;re still there.  More importantly, a
lot of the &lt;a class="reference external" href="http://newscorp.com/"&gt;old media empires&lt;/a&gt; are still around,
and still have substantial power and&amp;nbsp;influence.&lt;/p&gt;
&lt;p&gt;Even the advent of social media hasn&amp;#8217;t really made it easier to find the
facts.  If anything, it&amp;#8217;s made
things worse.  Social media provides just another outlet for governments
and corporations to get their message out.  We have access to far more
media than ever before.  But not necessarily more facts.  It&amp;#8217;s probably no
coincidence that the more media there is, the more mis-information is out
there.  Who needs to censor the media, when you can just bury inconvenient
truths in amongst a sea of mis-information and&amp;nbsp;spin?&lt;/p&gt;
&lt;p&gt;Which I think is the ultimate irony of the Sony hacking.  Despite little
evidence, large swathes of the media are happily reporting the official &lt;span class="caps"&gt;US&lt;/span&gt;
government line that North Korea is responsible for the cyber attack
on&amp;nbsp;Sony.&lt;/p&gt;
&lt;p&gt;North Korea, one of the last die hard vestiges of communism, is a country
where few people have internet access, and the media is mostly government
propaganda designed to keep its population&amp;nbsp;misinformed.&lt;/p&gt;
&lt;p&gt;By contrast, the supposedly democratic Western world enjoys a mind-boggling
array of media options, from traditional news sources, to obscure news
websites and blogs, to social media.  Yet, ironically, this doesn&amp;#8217;t always
mean we are told the truth.  Are the people in the western world any
less&amp;nbsp;mis-informed?&lt;/p&gt;
&lt;p&gt;We might get more news, but it&amp;#8217;s still filtered through layers of
government spin, corporate &lt;span class="caps"&gt;PR&lt;/span&gt;, and news media bias.  As much as the
internet might hold potential to speak truch to power, it&amp;#8217;s more often a
vehicle for conspiracy theories, and &lt;a class="reference external" href="http://rationalwiki.org/wiki/Anti-vaccination_movement"&gt;outright mis-information&lt;/a&gt;.
Not to mention cat&amp;nbsp;pics.&lt;/p&gt;
&lt;p&gt;The truth might be out there, online.  But we usually have to wade through
a big pile of shit to find&amp;nbsp;it.&lt;/p&gt;
</content></entry><entry><title>Hello 2015, and goodbye online freedom and privacy</title><link href="http://www.voidynullness.net/blog/2015/01/12/hello-2015-goodbye-freedom-and-privacy/" rel="alternate"></link><published>2015-01-12T00:00:00+11:00</published><updated>2015-01-12T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2015-01-12:/blog/2015/01/12/hello-2015-goodbye-freedom-and-privacy/</id><summary type="html">&lt;p&gt;It&amp;#8217;s that time, as the new year gets underway, and memories of New Year&amp;#8217;s
hangovers recede, where many a second-rate writer wastes many words
attempting to predict what&amp;#8217;s ahead for the new&amp;nbsp;year.&lt;/p&gt;
&lt;p&gt;Since describing my blogging attempts as &amp;#8220;second-rate&amp;#8221; would be
exceedingly generous &amp;#8212; and with slim chance my online ramblings will have
anyone of sane disposition mistake me for a writer &amp;#8212; I feel I have little
credibility to lose by throwing my contribution into the&amp;nbsp;mix …&lt;/p&gt;</summary><content type="html">&lt;p&gt;It&amp;#8217;s that time, as the new year gets underway, and memories of New Year&amp;#8217;s
hangovers recede, where many a second-rate writer wastes many words
attempting to predict what&amp;#8217;s ahead for the new&amp;nbsp;year.&lt;/p&gt;
&lt;p&gt;Since describing my blogging attempts as &amp;#8220;second-rate&amp;#8221; would be
exceedingly generous &amp;#8212; and with slim chance my online ramblings will have
anyone of sane disposition mistake me for a writer &amp;#8212; I feel I have little
credibility to lose by throwing my contribution into the&amp;nbsp;mix.&lt;/p&gt;
&lt;p&gt;In 2015, the disturbing trends of recent years will no doubt continue &amp;#8212;
mass surveillance by governments, erosion of digital rights, widespread
invasion of privacy, stupid software patents, and Luddite legislators
enacting stupid laws affecting the tech&amp;nbsp;industry.&lt;/p&gt;
&lt;p&gt;This year will be more of the same.  It&amp;#8217;s a war, against us, and our
freedom.  We, the users and developers of technology,
&lt;a class="reference external" href="http://dcinno.streetwise.co/2014/05/22/tech-titans-furious-over-patent-law-failure/"&gt;will&lt;/a&gt;
&lt;a class="reference external" href="http://www.usnews.com/news/articles/2014/09/16/how-the-tech-lobby-got-beat"&gt;lose.&lt;/a&gt;
Politicians and large corporations will win.
&lt;a class="reference external" href="http://techcrunch.com/2014/11/19/tech-reacts-to-the-demise-of-partial-nsa-reform-in-the-senate/"&gt;Again.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This will likely be the year the Trans-Pacific Partnership will be
finalised.  The &lt;span class="caps"&gt;TPP&lt;/span&gt; means more power for large corporations, and less for
consumers and governments.  It means consumers will pay more for everything
from movies to medication.  It means governments will become more
vulnerable to lawsuits from multinational corporations.  It means countries
will be forced to introduce draconian copyright provisions that criminalise
infringement and significantly curb online&amp;nbsp;freedom.&lt;/p&gt;
&lt;p&gt;In the &lt;span class="caps"&gt;US&lt;/span&gt;, this will probably be the year that the battle for
&lt;a class="reference external" href="https://www.eff.org/issues/net-neutrality"&gt;net neutrality&lt;/a&gt;
will be lost, setting a disturbing precedent for the &lt;a class="reference external" href="http://www.businessspectator.com.au/article/2014/11/14/technology/nbn-and-net-neutrality-what-it-means-australian-consumers"&gt;rest of the world&lt;/a&gt;.
For those unsure about the implications of net neutrality, is was nicely
summed up by John Oliver on &lt;em&gt;Last Week Tonight&lt;/em&gt; as &amp;#8220;cable company fuckery&amp;#8230;
because that is what it&amp;nbsp;is.&amp;#8221;&lt;/p&gt;
&lt;p&gt;Is there anything more disturbing than the prospect of cable companies
becoming &lt;em&gt;more&lt;/em&gt;&amp;nbsp;powerful?&lt;/p&gt;
&lt;p&gt;2015 will be a year of even more mass surveillance by governments.  In the
&lt;span class="caps"&gt;US&lt;/span&gt; there&amp;#8217;s already a staggering amount of mass surveillance being
undertaken by the &lt;span class="caps"&gt;NSA&lt;/span&gt; and other government agencies, and this will no doubt
keep&amp;nbsp;increasing.&lt;/p&gt;
&lt;p&gt;Other countries also have data retention regimes in place to routinely spy
on their own citizens, and more are likely to join the mass surveillance
circle jerk, despite little evidence it helps in combating crime or
preventing&amp;nbsp;terrorism.&lt;/p&gt;
&lt;p&gt;Never one to let evidence get in the way of bad policy, in 2015 the
Australian government will introduce its own flawed mandatory data
retention scheme, conveniently ignoring evidence showing similar schemes in
other countries have failed to provide any&amp;nbsp;benefit.&lt;/p&gt;
&lt;p&gt;Last year, the Australian government successfully introduced legislation
that undermined basic democratic rights of free speech, freedom of the
press, freedom of association, and the right to be considered innocent until
proven guilty.  This year, they will continue their attack on democracy
by eliminating our right to privacy through mandatory data retention.  And
possibly restrict our internet access by &lt;a class="reference external" href="http://www.abc.net.au/news/2014-09-09/kirkland-the-lunacy-of-trying-to-stop-piracy-at-any-cost/5731414"&gt;introducing a filtering&amp;nbsp;scheme.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Throughout all this, I&amp;#8217;m sure many technology literate people will respond
with much anger and vitriol on social media, along with the occasional well
reasoned blog post or article.  But as in previous years, none of that
which will achieve anything.  We will lose.  Because this is a war against
us, but it&amp;#8217;s not a war where facts or logic matter.  It&amp;#8217;s a war where
money, spin, corporations, and political lobbying decide the&amp;nbsp;outcomes.&lt;/p&gt;
&lt;p&gt;In 2015, as in years before, the politicians and their corporate masters
will get their&amp;nbsp;way.&lt;/p&gt;
&lt;p&gt;Happy new&amp;nbsp;year!&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related&amp;nbsp;Posts:&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/28/metadata-karma/"&gt;Metadata&amp;nbsp;karma&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/22/they-are-coming-for-us-and-our-metadata/"&gt;They&amp;#8217;re coming for us and our&amp;nbsp;metadata&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/25/we-all-have-something-to-hide-from-mandatory-meta-data-retention/"&gt;We all have something to&amp;nbsp;hide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="privacy"></category><category term="metadata"></category><category term="politics"></category><category term="surveillance"></category><category term="TPP"></category></entry><entry><title>Upgrading to pelican 3.5</title><link href="http://www.voidynullness.net/blog/2014/11/30/upgrading-pelican-3-5/" rel="alternate"></link><published>2014-11-30T00:00:00+11:00</published><updated>2014-11-30T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2014-11-30:/blog/2014/11/30/upgrading-pelican-3-5/</id><summary type="html">&lt;p&gt;I recently updated my Pelican blog setup, going from Pelican 3.3 to Pelican
3.5.  I skipped Pelican 3.4, mostly by circumstance rather than intention
&amp;#8212; by the time I got around to upgrading, Pelican 3.5 had been&amp;nbsp;released!&lt;/p&gt;
&lt;p&gt;Although I wasn&amp;#8217;t in any great rush to upgrade anyway, as I was rather
diligently procrastinating the task of reinstalling the Linux box I&amp;#8217;d been
using for my Pelican work, and this is something I wanted to …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I recently updated my Pelican blog setup, going from Pelican 3.3 to Pelican
3.5.  I skipped Pelican 3.4, mostly by circumstance rather than intention
&amp;#8212; by the time I got around to upgrading, Pelican 3.5 had been&amp;nbsp;released!&lt;/p&gt;
&lt;p&gt;Although I wasn&amp;#8217;t in any great rush to upgrade anyway, as I was rather
diligently procrastinating the task of reinstalling the Linux box I&amp;#8217;d been
using for my Pelican work, and this is something I wanted to do first.
But by the time I had overcome my procrastination (not to mention general
reluctance to mess with Things That Are Working), I&amp;#8217;d discovered that
Pelican 3.5 was out.  So perhaps in a way my procrastination resulted in
some fortuitous&amp;nbsp;timing.&lt;/p&gt;
&lt;p&gt;For the most part things went surprisingly&amp;nbsp;smoothly.&lt;/p&gt;
&lt;p&gt;Since I was essentially reinstalling (and reconfiguring) things from
scratch on a new Linux installation (Mint 17), I decided to have a go at
using Python 3, as up until now I&amp;#8217;d only ever used Pelican with Python 2.7.
I used the system&amp;#8217;s Python 3.4 (and &amp;#8220;pip3&amp;#8221; via the system&amp;#8217;s package&amp;nbsp;manager).&lt;/p&gt;
&lt;p&gt;Not being sure if virtualenv/virtualenvwrapper played nice with Python 3, I
thought I&amp;#8217;d try the native virtual environment support in Python 3:
&lt;a class="reference external" href="https://docs.python.org/3/library/venv.html"&gt;venv.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here, I ran into a bit of a problem.  When trying to create a new virtual
environment I&amp;#8217;d get an error like&amp;nbsp;this:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Error: Command '['/home/rob/python/newenv/bin/python3.4', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 1
&lt;/pre&gt;
&lt;p&gt;This appears to be caused by an issue in Python 3.4 (affecting Debian and
derivatives, at&amp;nbsp;least).&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://community.linuxmint.com/tutorial/view/1804"&gt;The solution here&lt;/a&gt;
fixed the&amp;nbsp;problem.&lt;/p&gt;
&lt;p&gt;After that I was able to create a new virtual environment for Pelican with&amp;nbsp;pyvenv:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;mkdir venv
&lt;span class="nb"&gt;cd&lt;/span&gt; venv
pyvenv-3.4 pel
&lt;span class="nb"&gt;source&lt;/span&gt; pel/bin/activate
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;From this point on things were fairly straightforward.  I didn&amp;#8217;t encounter
any issues with using Python 3 instead of Python 2 to install and configure&amp;nbsp;Pelican:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;pip3 install pelican markdown
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The above command installed Pelican 3.5.  With that done, I did a dummy run
of &lt;a class="reference external" href="http://docs.getpelican.com/en/3.5.0/quickstart.html"&gt;pelican-quickstart&lt;/a&gt;,
then compared the various generated files to that of version 3.3, to get an
idea if any important differences needed to be&amp;nbsp;addressed.&lt;/p&gt;
&lt;p&gt;There wasn&amp;#8217;t much.  Here is a diff of the&amp;nbsp;Makefiles:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;1,2c1,2
&amp;lt; PY=python
&amp;lt; PELICAN=pelican
&lt;span class="gd"&gt;---&lt;/span&gt;
&amp;gt; PY?=python3
&amp;gt; PELICAN?=pelican
27a28,29
&amp;gt; GITHUB_PAGES_BRANCH=gh-pages
&amp;gt;
90c92
&amp;lt;     rsync -e &amp;quot;ssh -p $(SSH_PORT)&amp;quot; -P -rvz --delete $(OUTPUTDIR)/ $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR) --cvs-exclude
&lt;span class="gd"&gt;---&lt;/span&gt;
&amp;gt;     rsync -e &amp;quot;ssh -p $(SSH_PORT)&amp;quot; -P -rvzc --delete $(OUTPUTDIR)/ $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR) --cvs-exclude
99c101
&amp;lt;     s3cmd sync $(OUTPUTDIR)/ s3://$(S3_BUCKET) --acl-public --delete-removed
&lt;span class="gd"&gt;---&lt;/span&gt;
&amp;gt;     s3cmd sync $(OUTPUTDIR)/ s3://$(S3_BUCKET) --acl-public --delete-removed --guess-mime-type
105,106c107,108
&amp;lt;     ghp-import $(OUTPUTDIR)
&amp;lt;     git push origin gh-pages
&lt;span class="gd"&gt;---&lt;/span&gt;
&amp;gt;     ghp-import -m &amp;quot;Generate Pelican site&amp;quot; -b $(GITHUB_PAGES_BRANCH) $(OUTPUTDIR)
&amp;gt;     git push origin $(GITHUB_PAGES_BRANCH)
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(Note that a Python 2 environment was used to generate the Pelican 3.3
files, while Python 3 was used for Pelican 3.5.  I&amp;#8217;m not sure if that&amp;#8217;s
significant, I don&amp;#8217;t think it&amp;nbsp;was.)&lt;/p&gt;
&lt;p&gt;There appear to be only minor changes to the deployment targets.  The only
one of note being the addition of the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-c&lt;/span&gt;&lt;/tt&gt; option to the &lt;tt class="docutils literal"&gt;rsync&lt;/tt&gt; command.&lt;/p&gt;
&lt;p&gt;Here is a diff of &lt;tt class="docutils literal"&gt;pelicanconf.py&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;8a9,10
&amp;gt; PATH = &amp;#39;content&amp;#39;
&amp;gt;
11c13
&amp;lt; DEFAULT_LANG = u&amp;#39;en&amp;#39;
&lt;span class="gd"&gt;---&lt;/span&gt;
&amp;gt; DEFAULT_LANG = &amp;#39;en&amp;#39;
16a19,20
&amp;gt; AUTHOR_FEED_ATOM = None
&amp;gt; AUTHOR_FEED_RSS = None
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So pretty much the only change I had to make was disable author feeds,
which I had no use&amp;nbsp;for.&lt;/p&gt;
&lt;p&gt;Both &lt;tt class="docutils literal"&gt;publishconf.py&lt;/tt&gt; were&amp;nbsp;identical.&lt;/p&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;develop_server.sh&lt;/tt&gt; script had many minor changes &amp;#8212; almost all of
them to the wording of text in echo statements.  I just copied over my old
version with the&amp;nbsp;latest.&lt;/p&gt;
&lt;p&gt;There was only one problem I ran into during the upgrade, and it&amp;#8217;s actually
a problem I first noticed after &lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/01/23/upgrading-pelican-3-3/"&gt;I upgraded to Pelican 3.3&lt;/a&gt;, which changed the way
static files were handled and introduced the &lt;tt class="docutils literal"&gt;EXTRA_PATH_METADATA&lt;/tt&gt;
setting.  I had a file with a &lt;span class="caps"&gt;HTML&lt;/span&gt; extension that I simply wanted copied
into the root directory of my generated website, without being processed in
any way.  The file wasn&amp;#8217;t actually a valid &lt;span class="caps"&gt;HTML&lt;/span&gt; file though.  It was just
an arbitrary text file, however it was generated by an external tool, so I
couldn&amp;#8217;t change the contents of the file, or its file extension.  My
initial attempt to configure this resulted in something like this in my
&lt;tt class="docutils literal"&gt;pelicanconf.py&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;STATIC_PATHS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;images&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;&amp;#39;other/robots.txt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;&amp;#39;other/favicon.ico&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;&amp;#39;other/arbitrary.html&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;EXTRA_PATH_METADATA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;&amp;#39;other/robots.txt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;path&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;robots.txt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s1"&gt;&amp;#39;other/favicon.ico&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;path&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;favicon.ico&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s1"&gt;&amp;#39;other/arbitrary.html&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;path&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;arbitrary.html&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That worked for the first two files, which were copied across correctly to
the root directory of the generated website.  But the file with the &lt;span class="caps"&gt;HTML&lt;/span&gt;
extension wasn&amp;#8217;t copied, and Pelican output this error&amp;nbsp;message:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;ERROR: Skipping other/arbitrary.html: could not find information about &amp;#39;title&amp;#39;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;My initial attempts at finding a solution had been unsuccessful, so I had
been ignoring this error for a while.  But I eventually noticed this file
not being copied to the right place was causing some issues, which
motivated me to once again try and find a&amp;nbsp;solution.&lt;/p&gt;
&lt;p&gt;I came across some discussions of this problem in
&lt;a class="reference external" href="https://github.com/getpelican/pelican/issues/1157"&gt;these&lt;/a&gt;
&lt;a class="reference external" href="https://github.com/getpelican/pelican/issues/1046"&gt;two&lt;/a&gt;
issues on&amp;nbsp;GitHub.&lt;/p&gt;
&lt;p&gt;Turns out that Pelican accepts &lt;span class="caps"&gt;HTML&lt;/span&gt; files as source input, just like
Markdown and reStructuredText, which is probably why it was attempting to
process my arbitrary (non) &lt;span class="caps"&gt;HTML&lt;/span&gt; input file, and complaining about a missing
title.  This is all well and good, but I can imagine many valid use cases
where it might be desirable to have &lt;span class="caps"&gt;HTML&lt;/span&gt; content just copied over as part
of site generation without any processing (like content generated by tools
external to Pelican).  Fortunately, Pelican provides a way to skip
processing of all &lt;span class="caps"&gt;HTML&lt;/span&gt; files via the &lt;a class="reference external" href="http://docs.getpelican.com/en/latest/settings.html#basic-settings"&gt;&lt;span class="caps"&gt;READERS&lt;/span&gt;&lt;/a&gt;&amp;nbsp;setting:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;READERS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;html&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This solved the problem and got rid of that error message.  After adding
the above line to my &lt;tt class="docutils literal"&gt;pelicanconf.py&lt;/tt&gt; all my external, non-generated
files ended up where I wanted them in the output directory, and I finally
had a &amp;#8220;neat&amp;#8221; build without any mysterious warning or&amp;nbsp;errors.&lt;/p&gt;
&lt;p&gt;Overall, the upgrade went fairly&amp;nbsp;smoothly.&lt;/p&gt;
&lt;p&gt;I didn&amp;#8217;t encounter any backward compatibility issues with Pelican 3.5.
Apart from the minor tweaks above to &lt;tt class="docutils literal"&gt;Makefile&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;pelicanconf.py&lt;/tt&gt;,
there were no significant changes required to either my configuration or
(custom)&amp;nbsp;theme.&lt;/p&gt;
&lt;p&gt;I did, however, encounter a minor glitch, which I think had something to do
with&amp;nbsp;caching.&lt;/p&gt;
&lt;p&gt;Pelican 3.5 features caching to speed up site generation, which is nice and
usually works quite well.  It doesn&amp;#8217;t appear to be perfect, though.  At one
point, while messing around with theme modifications, I noticed that some
parts of my website were not being generated properly.  In particular,
there were internal links that were pointing to wrong (non-existent)
URLs.  At first I thought I had introduced some weird theme issue, but that
didn&amp;#8217;t appear to be the&amp;nbsp;case.&lt;/p&gt;
&lt;p&gt;I deleted the &lt;tt class="docutils literal"&gt;cache&lt;/tt&gt; directory.  Then I did a &lt;tt class="docutils literal"&gt;make clean&lt;/tt&gt; followed by
a &lt;tt class="docutils literal"&gt;make html&lt;/tt&gt; That fixed the problem &amp;#8212; the regenerated website was fine.
I&amp;#8217;m therefore assuming it had something to do with the caching.  I wasn&amp;#8217;t
able to reproduce the problem though, so for now it remains a vague
observation that the caching can sometimes cause&amp;nbsp;issues.&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related&amp;nbsp;Posts:&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/01/23/upgrading-pelican-3-3/"&gt;Upgrading to Pelican&amp;nbsp;3.3&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="Pelican"></category><category term="Python"></category></entry><entry><title>Metadata karma</title><link href="http://www.voidynullness.net/blog/2014/11/28/metadata-karma/" rel="alternate"></link><published>2014-11-28T00:00:00+11:00</published><updated>2014-11-28T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2014-11-28:/blog/2014/11/28/metadata-karma/</id><summary type="html">&lt;p&gt;The government did a couple things I found really disturbing&amp;nbsp;recently.&lt;/p&gt;
&lt;p&gt;Well, actually, that seems like a ludicrous understatement given recent
events in Australian&amp;nbsp;politics.&lt;/p&gt;
&lt;p&gt;Recently, &lt;em&gt;everything&lt;/em&gt; this government has done has been disturbing on some&amp;nbsp;level.&lt;/p&gt;
&lt;p&gt;For the sake of brevity however, if nothing else, let&amp;#8217;s consider just two
for now: the mandatory data legislation introduced in recent months; and
the prosecution of 21 year old student Freya Newman for uncovering evidence
of a secret scholarship awarded to …&lt;/p&gt;</summary><content type="html">&lt;p&gt;The government did a couple things I found really disturbing&amp;nbsp;recently.&lt;/p&gt;
&lt;p&gt;Well, actually, that seems like a ludicrous understatement given recent
events in Australian&amp;nbsp;politics.&lt;/p&gt;
&lt;p&gt;Recently, &lt;em&gt;everything&lt;/em&gt; this government has done has been disturbing on some&amp;nbsp;level.&lt;/p&gt;
&lt;p&gt;For the sake of brevity however, if nothing else, let&amp;#8217;s consider just two
for now: the mandatory data legislation introduced in recent months; and
the prosecution of 21 year old student Freya Newman for uncovering evidence
of a secret scholarship awarded to the daughter of the Prime&amp;nbsp;Minister.&lt;/p&gt;
&lt;p&gt;The latter has recently concluded, with Freya Newman being sentenced to a 2
year good behaviour bond earlier this week.  The former will drag on into
next year, the government&amp;#8217;s attempt to ram the legislation through like the
first two tranches of new national security laws having thankfully&amp;nbsp;failed.&lt;/p&gt;
&lt;p&gt;While not directly related, apart from the fact I consider both to be quite
shitty things for a government to do, I think it&amp;#8217;s interesting that the
debates surrounding both played out around the same&amp;nbsp;time.&lt;/p&gt;
&lt;p&gt;They&amp;#8217;re both issues that you can slice and dice in different ways, and look
at from different angles.  Generally, I suspect one&amp;#8217;s interpretation of
both to be colored by how much one trusts the motives of government in
general, and this government in&amp;nbsp;particular.&lt;/p&gt;
&lt;p&gt;Personally, I have little benefit of the doubt left to give.  I have little
trust in any government generally, abject apprehension of our current one,
and nothing but outrage and dismay at both the prospect of metadata
retention and the way Freya Newman was&amp;nbsp;treated.&lt;/p&gt;
&lt;p&gt;On both issues I think government motives are far from&amp;nbsp;pure.&lt;/p&gt;
&lt;p&gt;For mine, there is little ambiguity: mandatory data retention is an
invasion of privacy and represents massive government overreach; Freya
Newman might have technically broken the law (possibly a stupid law), but
she did nothing wrong, and the information she revealed was definitely in
the public&amp;nbsp;interest.&lt;/p&gt;
&lt;p&gt;As &lt;a class="reference external" href="http://www.abc.net.au/news/2014-11-19/leyonhjelm-metadata-and-the-law-of-unintended-consequences/5901958"&gt;Senator David Leyonhjelm says&lt;/a&gt;,
&amp;#8220;We should be watching the Government, not the other way&amp;nbsp;around.&amp;#8221;&lt;/p&gt;
&lt;p&gt;Which is why Freya Newman&amp;#8217;s actions were in the public interest.  As
voters, we have a right to know that a private design school &amp;#8212; which stood
to benefit from an Abbott government&amp;#8217;s policies &amp;#8212; had given Frances Abbott
a secret scholarship.  Not to mention the hypocrisy of the Prime Minister&amp;#8217;s
daughter given a free ride after all the &amp;#8220;lifters and leaners&amp;#8221; rhetoric by
this government.  Probably why the Prime Minister hadn&amp;#8217;t publicly declared
the scholarship.  It was an embarrassing revelation for the Prime&amp;nbsp;Minister.&lt;/p&gt;
&lt;p&gt;But while the public has a right to know what our politicians are up to,
supposedly on our behalf, the government has no right to invade the privacy
of law abiding citizens.  Spying on the innocent with mass surveillance is
going to far.  It will not make us safer from terrorist.  But it will
undermine our democracy, and our&amp;nbsp;privacy.&lt;/p&gt;
&lt;p&gt;Amongst other things, data retention is &lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/25/we-all-have-something-to-hide-from-mandatory-meta-data-retention/"&gt;a deterrent to whistleblowers&lt;/a&gt; coming forward
to expose government (or corporate) corruption.  Which is another aspect
the data retention laws have in common with Freya Newman&amp;#8217;s prosecution &amp;#8212;
the intention of both is to discourage whistleblowers.  Well, whether it&amp;#8217;s
an intention or a side effect is debatable, but it will be the result
nonetheless.  A result that&amp;#8217;s beneficial to government, but detrimental to&amp;nbsp;democracy.&lt;/p&gt;
&lt;p&gt;Freya Newman was prosecuted to send a message to anyone else who might
consider revealing information that proves inconvenient to the government.
As her lenient sentence demonstrated, her &amp;#8220;offence&amp;#8221; was a minor one at
most.  What she did wouldn&amp;#8217;t even have been illegal if it involved a public
university, as opposed to a private&amp;nbsp;school.&lt;/p&gt;
&lt;p&gt;The authorities have discretion about what they do or don&amp;#8217;t prosecute, and
it&amp;#8217;s likely Freya Newman was only prosecuted as punishment because she
revealed information embarrassing to the current Prime Minister.  It&amp;#8217;s
unlikely she would have been charged if the scholarship in question had
involved someone less high profile than a sitting Prime Minister&amp;#8217;s
daughter.  It was a vindictive use of the legal system to
punish a past whisteblower and discourage future&amp;nbsp;ones.&lt;/p&gt;
&lt;p&gt;With the prosecution of Freya Newman, this government has shown it doesn&amp;#8217;t
take kindly to whistleblowers, and is willing to abuse the legal system to
punish them.  Even if they&amp;#8217;re just a 21 year old university student.  This
is a reason in itself to be suspicious of government motives when it comes
to data retention.  While the government might say it&amp;#8217;s all in the
interests of national security, their real agenda likely involves some
combination of whistleblowers, activists, and &lt;a class="reference external" href="http://www.afr.com/p/technology/illegal_downloaders_could_be_targeted_817APwVoupGe8nI7g9lXTO"&gt;illegal&amp;nbsp;downloaders.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;However, there might actually be a small upside to all this.  The
government has shown itself to be way out of its depths on the technical
issues surrounding metadata retention.  Or even &lt;a class="reference external" href="http://www.news.com.au/technology/online/george-brandis-metadata-interview-fails-spectacularly-internet-reacts/story-fnjwnhzf-1227016188974"&gt;definitions of&amp;nbsp;metadata.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Politicians also have a remarkable ability to either ignore or
underestimate side effects of their laws, in their misguided belief
there is no problem that can&amp;#8217;t be legislated&amp;nbsp;away.&lt;/p&gt;
&lt;p&gt;These two factors could combine to produce some entertainingly ironic&amp;nbsp;results.&lt;/p&gt;
&lt;p&gt;While metadata retention will likely result in less whistleblowers coming
forward, it creates the all too likely possibility that the retained
metadata will be hacked and leaked.  Any hacked metadata will likely
contain metadata on politician, their families, business associates,
mistresses, etc.  This leaked metadata could be mined to expose information
embarrassing or damaging to the government.  So when one door closes,
another&amp;nbsp;opens.&lt;/p&gt;
&lt;p&gt;Because if and when mandatory data retention is introduced &amp;#8212; and it
probably will be, eventually &amp;#8212; I can&amp;#8217;t imagine any scenario where ISPs are
forced to store so much data unnecessary to their core business, and manage
to do so&amp;nbsp;securely.&lt;/p&gt;
&lt;p&gt;The metadata will inevitably be hacked.  It will be hacked because data
retention will be really expensive, and &lt;span class="caps"&gt;IT&lt;/span&gt; security is complicated and
difficult at the best of times.  Already there is squabbling about who will
pay for it.  Which means it&amp;#8217;s likely to be us, the consumers.  And when
time or money constraints impact any &lt;span class="caps"&gt;IT&lt;/span&gt; project, security is the first
thing to&amp;nbsp;suffer.&lt;/p&gt;
&lt;p&gt;So the one possible bright side from the government introducing a misguided
mandatory data retention regime, possibly in an attempt to discourage
whistleblowers revealing government secrets, is that it will lead to
hackers getting at the metadata of politicians and revealing government&amp;nbsp;secrets.&lt;/p&gt;
&lt;p&gt;The results should be entertaining, and the schadenfreude will be exquisite,
as hopefully those politicians who voted for stupid metadata laws will have
their careers embarrassingly destroyed by an unnecessary metadata regime they&amp;nbsp;introduced.&lt;/p&gt;
&lt;p&gt;It will be karma through metadata.&amp;nbsp;Hopefully.&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related&amp;nbsp;Posts:&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/22/they-are-coming-for-us-and-our-metadata/"&gt;They&amp;#8217;re coming for us and our&amp;nbsp;metadata&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/25/we-all-have-something-to-hide-from-mandatory-meta-data-retention/"&gt;We all have something to&amp;nbsp;hide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="privacy"></category><category term="metadata"></category><category term="politics"></category><category term="surveillance"></category></entry><entry><title>We all have something to hide</title><link href="http://www.voidynullness.net/blog/2014/11/25/we-all-have-something-to-hide-from-mandatory-meta-data-retention/" rel="alternate"></link><published>2014-11-25T00:00:00+11:00</published><updated>2014-11-25T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2014-11-25:/blog/2014/11/25/we-all-have-something-to-hide-from-mandatory-meta-data-retention/</id><summary type="html">&lt;p&gt;The Australian government recently &lt;a class="reference external" href="http://www.zdnet.com/au/mandatory-data-retention-legislation-hits-the-australian-parliament-7000035221/"&gt;introduced mandatory data retention&lt;/a&gt;
legislation, and in the debate that followed, I heard a radio talkback host
admit he wasn&amp;#8217;t overly concerned by the prospect, on the grounds that if
you don&amp;#8217;t do anything wrong you have nothing to&amp;nbsp;hide.&lt;/p&gt;
&lt;p&gt;He couldn&amp;#8217;t be &lt;a class="reference external" href="http://www.wired.com/2013/06/why-i-have-nothing-to-hide-is-the-wrong-way-to-think-about-surveillance/"&gt;more&amp;nbsp;wrong.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Thinking &amp;#8220;I have nothing to hide&amp;#8221; is naive when it comes to mandatory
data retention, and represents a failure to fully &lt;a class="reference external" href="https://www.citizensnotsuspects.org.au/nine-reasons-2/"&gt;understand the&amp;nbsp;implications.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Data retention is usually …&lt;/p&gt;</summary><content type="html">&lt;p&gt;The Australian government recently &lt;a class="reference external" href="http://www.zdnet.com/au/mandatory-data-retention-legislation-hits-the-australian-parliament-7000035221/"&gt;introduced mandatory data retention&lt;/a&gt;
legislation, and in the debate that followed, I heard a radio talkback host
admit he wasn&amp;#8217;t overly concerned by the prospect, on the grounds that if
you don&amp;#8217;t do anything wrong you have nothing to&amp;nbsp;hide.&lt;/p&gt;
&lt;p&gt;He couldn&amp;#8217;t be &lt;a class="reference external" href="http://www.wired.com/2013/06/why-i-have-nothing-to-hide-is-the-wrong-way-to-think-about-surveillance/"&gt;more&amp;nbsp;wrong.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Thinking &amp;#8220;I have nothing to hide&amp;#8221; is naive when it comes to mandatory
data retention, and represents a failure to fully &lt;a class="reference external" href="https://www.citizensnotsuspects.org.au/nine-reasons-2/"&gt;understand the&amp;nbsp;implications.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Data retention is usually thought of as a technical issue, but that is a
far too simplistic way of looking at it.  Mandatory data retention has
&lt;a class="reference external" href="http://www.abc.net.au/technology/articles/2012/09/28/3599864.htm"&gt;profound implications&lt;/a&gt; for
privacy, the media, and basic democratic&amp;nbsp;rights.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s not an abstract thing &amp;#8212; data retention is every much an invasion of
privacy as would be Tony Abbott standing behind you and watching while you
masturbate to internet&amp;nbsp;porn.&lt;/p&gt;
&lt;p&gt;But the implications go far beyond an individual&amp;#8217;s personal porn
predilections, or even rights to&amp;nbsp;privacy.&lt;/p&gt;
&lt;p&gt;Just because you might think you have nothing to hide, doesn&amp;#8217;t mean the
same applies to everyone else.  There are people out there with legitimate
reasons not to want their metadata tracked by the government.  Like, for
example, a government employee who stumbles across proof of government
corruption as part of their job.  Data retention makes it less likely a
person in this situation would come forward, knowing their phone records
and internet usage are constantly being monitored by the government, and
that there are likely to be unpleasant personal&amp;nbsp;consequences.&lt;/p&gt;
&lt;p&gt;A strong democracy sometimes needs whisteblowers to uncover corruption or
other inappropriate behavior by those in positions of power.  Sometimes it
is in the best interests of the whistleblower to remain anonymous, and for
journalists to protect their sources.  This becomes much more difficult, if
not impossible, when mass government surveillance is in place.  Which is
probably the whole point.  The government is far more interested is using
data retention as a deterrent to whistleblowers (not to mention illegal
downloaders) than&amp;nbsp;terrorists.&lt;/p&gt;
&lt;p&gt;Then there is plain old government stupidity.  Believing you have nothing
to hide if you haven&amp;#8217;t done anything wrong is somewhat predicated in the
false believe that governments &amp;#8212; and all their employees and associated
actors &amp;#8212; are always sensible and rational and act intelligently.  And most
importantly, always make sensible&amp;nbsp;laws.&lt;/p&gt;
&lt;p&gt;This is hardly ever the&amp;nbsp;case.&lt;/p&gt;
&lt;p&gt;There are lots of laws, for starter.  More than any one person can keep in
their head, which is why we have specialist lawyers.  How can you be sure
you haven&amp;#8217;t broken some law, if you&amp;#8217;re not aware of every single&amp;nbsp;law?&lt;/p&gt;
&lt;p&gt;Everyone is guilty of something, no matter how trivial &amp;#8212; or&amp;nbsp;stupid.&lt;/p&gt;
&lt;p&gt;And there are lots of &lt;a class="reference external" href="http://www.stupidlaws.com/laws/countries/australia/"&gt;stupid laws&lt;/a&gt;.  For example, &lt;a class="reference external" href="http://www.au.timeout.com/melbourne/aroundtown/features/2423/breaking-the-law"&gt;in Victoria&lt;/a&gt;:
it&amp;#8217;s illegal to be near or inside a house that is used regularly by thieves;
only licensed electricians are allowed to change a light bulb; you can&amp;#8217;t
fly kites or play games in public which annoy people; you&amp;#8217;re breaking the
law if you have an article of disguise without a lawful excuse; you&amp;#8217;re not
allowed to sing an obscene song, tune or ballad within earshot of&amp;nbsp;someone.&lt;/p&gt;
&lt;p&gt;Who hasn&amp;#8217;t been guilty of some or all of those things at some&amp;nbsp;point?&lt;/p&gt;
&lt;p&gt;Metadata retention is another stupid law, and gives more power to other
laws, stupid and otherwise.  Having a database of metadata gives
authorities the possibly irresistible temptation to abuse their power in
all kinds of creative ways.  If a government agency decides to go after an
individual &amp;#8212; either vindictively, as in the case of a whistleblower, or
simply because they mistakenly suspect an individual is guilty but don&amp;#8217;t
have proof &amp;#8212; stupid laws and legal technicalities provide other means to
hound that innocent&amp;nbsp;person.&lt;/p&gt;
&lt;p&gt;Having a database of metadata on everyone means the government will be able
to arbitrarily find something to pin on just about anyone.  If they desire
to punish someone, the government will be able to trawl the metadata
database in search of a crime or broken law that&amp;nbsp;fits.&lt;/p&gt;
&lt;p&gt;Just look at what happened to Freya Newman, the whistleblower who provided
evidence that Prime Minister Tony Abbott&amp;#8217;s daughter &lt;a class="reference external" href="https://newmatilda.com/2014/05/21/leaked-documents-cast-doubt-abbotts-60k-scholarship-claims"&gt;received a secret
scholarship at a private design school.&lt;/a&gt;
Abbott was opposition leader at the time, and his daughter, Frances Abbott,
was his dependant.  He did not disclose this scholarship, worth about
$60000, and still hasn&amp;#8217;t, despite disclosing far more trivial items.  It
appears the scholarship wasn&amp;#8217;t advertised, hasn&amp;#8217;t been offered since, and
Frances Abbott received the scholarship after only a &lt;a class="reference external" href="https://newmatilda.com/2014/05/21/leaked-documents-cast-doubt-abbotts-60k-scholarship-claims"&gt;single&amp;nbsp;meeting.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Regardless of the legality or propriety of it all, at the very least,
&lt;a class="reference external" href="http://au.ibtimes.com/articles/570576/20141024/doesn-t-pay-whistleblower-australia-especially-subject.htm"&gt;the whole thing smells.&lt;/a&gt;
The scholarship should have been public knowledge before the election.  The
Prime Minister should have disclosed it. The fact he didn&amp;#8217;t makes it look
even more suspicious.  Especially since the private school in questions
stood to benefit financially from the Liberal government&amp;#8217;s education&amp;nbsp;policies.&lt;/p&gt;
&lt;p&gt;Despite this, Freya Newman was &lt;a class="reference external" href="https://newmatilda.com/2014/09/18/freya-newman-pleads-guilty-over-frances-abbotts-60k-secret-scholarship-leak"&gt;charged and found guilty.&lt;/a&gt;
This is a &lt;a class="reference external" href="http://www.theguardian.com/commentisfree/2014/sep/22/freya-newman-the-whistleblower-behind-frances-abbotts-scholarship-should-be-thanked-not-punished"&gt;disgraceful way to treat a whistleblower&lt;/a&gt;
who disclosed information &lt;a class="reference external" href="http://www.crikey.com.au/2014/10/23/crikey-says-we-stand-with-freya/"&gt;clearly in the public interest.&lt;/a&gt;
Thankfully, a small measure of sanity prevailed, and today a Magistrate
&lt;a class="reference external" href="https://newmatilda.com/2014/11/25/freya-newman-escapes-conviction-exposing-secret-frances-abbott-scholarship"&gt;sentenced Freya Newman&lt;/a&gt;
to a two-year good behaviour bond, with no conviction&amp;nbsp;recorded.&lt;/p&gt;
&lt;p&gt;What Freya Newman did might be technically illegal but it wasn&amp;#8217;t wrong.
She broke a stupid law, and for good reason.  She did something even many
legal experts didn&amp;#8217;t realise was illegal to reveal private information the
public had a right to&amp;nbsp;know.&lt;/p&gt;
&lt;p&gt;The legal system was then used to vindictively punish Freya Newman for
revealing information that was inconvenient to the Prime&amp;nbsp;Minister.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s an example of existing stupid laws being used for dubious intention by
the&amp;nbsp;state.&lt;/p&gt;
&lt;p&gt;Mandatory data retention will give the government phenomenally more power
and scope to do this.  And not just the current government, but any future&amp;nbsp;government.&lt;/p&gt;
&lt;p&gt;Imagine the kind of thing a vindictive government could do with years
of phone and internet records of an individual who does something that
displeases them?  Even if the individual&amp;#8217;s actions are&amp;nbsp;justified?&lt;/p&gt;
&lt;p&gt;Mandatory data retention is a serious concern to whistleblowers, activists
and journalists.  But in an online, social-media-connected world, where
it&amp;#8217;s becoming almost impossible to use the internet without breaking some
law, it should be a concern to all internet&amp;nbsp;users.&lt;/p&gt;
&lt;p&gt;With the government demonstrating they can and will use the legal system to
punish the innocent, and the prospect of government agencies watching your
every online move, do you really reckon you have nothing to&amp;nbsp;hide?&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related&amp;nbsp;Posts:&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/22/they-are-coming-for-us-and-our-metadata/"&gt;They&amp;#8217;re coming for us and our&amp;nbsp;metadata&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/28/metadata-karma/"&gt;Metadata&amp;nbsp;karma&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="privacy"></category><category term="metadata"></category><category term="politics"></category><category term="surveillance"></category></entry><entry><title>They’re coming for us and our metadata</title><link href="http://www.voidynullness.net/blog/2014/11/22/they-are-coming-for-us-and-our-metadata/" rel="alternate"></link><published>2014-11-22T00:00:00+11:00</published><updated>2014-11-22T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2014-11-22:/blog/2014/11/22/they-are-coming-for-us-and-our-metadata/</id><summary type="html">&lt;p&gt;They&amp;#8217;re coming for&amp;nbsp;us.&lt;/p&gt;
&lt;p&gt;Them &amp;#8212; the politicians, bureaucrats,&amp;nbsp;lawyers.&lt;/p&gt;
&lt;p&gt;They coming for us &amp;#8212; programmer, developers, designers, scientists, engineers.  Us&amp;nbsp;geeks.&lt;/p&gt;
&lt;p&gt;They’re coming for us, for our freedoms, and for our privacy, and they&amp;#8217;re calling this &amp;#8220;mandatory data retention&amp;#8221;.  Or metadata.  Or &amp;#8220;national security&amp;#8221;.  But regardless of what they call it, it is in fact just an outright attack on our democratic rights and&amp;nbsp;freedoms.&lt;/p&gt;
&lt;p&gt;They&amp;#8217;re coming for us.  To maintain their power and influence.  And stifle …&lt;/p&gt;</summary><content type="html">&lt;p&gt;They&amp;#8217;re coming for&amp;nbsp;us.&lt;/p&gt;
&lt;p&gt;Them &amp;#8212; the politicians, bureaucrats,&amp;nbsp;lawyers.&lt;/p&gt;
&lt;p&gt;They coming for us &amp;#8212; programmer, developers, designers, scientists, engineers.  Us&amp;nbsp;geeks.&lt;/p&gt;
&lt;p&gt;They’re coming for us, for our freedoms, and for our privacy, and they&amp;#8217;re calling this &amp;#8220;mandatory data retention&amp;#8221;.  Or metadata.  Or &amp;#8220;national security&amp;#8221;.  But regardless of what they call it, it is in fact just an outright attack on our democratic rights and&amp;nbsp;freedoms.&lt;/p&gt;
&lt;p&gt;They&amp;#8217;re coming for us.  To maintain their power and influence.  And stifle&amp;nbsp;ours.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s a war.  Which They are winning.  And we are losing quite&amp;nbsp;badly.&lt;/p&gt;
&lt;p&gt;Especially in&amp;nbsp;Australia.&lt;/p&gt;
&lt;p&gt;The Abbott government has managed to successfully screw us out of a decent Fibre-based broadband network (the only thing the previous government got right).  They screwed up the &lt;span class="caps"&gt;NBN&lt;/span&gt;, so now they&amp;#8217;ve got their sights set on screwing up the technology industry in other&amp;nbsp;ways.&lt;/p&gt;
&lt;p&gt;They&amp;#8217;re doing this under the pretext of reforming &amp;#8220;national security&amp;#8221; legislation, but calling it that gives it credibility is doesn&amp;#8217;t deserve, because it will do little to combat the risk of terrorism.  (A real risk, but realistically small in Australia, certainly not high enough for draconian legislation that takes away democratic freedoms.)  It&amp;#8217;s far more accurate to call it &amp;#8220;anti-democracy&amp;#8221;&amp;nbsp;legislation.&lt;/p&gt;
&lt;p&gt;The &lt;a class="reference external" href="http://www.smh.com.au/digital-life/consumer-security/terror-laws-clear-senate-enabling-entire-australian-web-to-be-monitored-and-whistleblowers-to-be-jailed-20140925-10m8ih.html"&gt;first tranche&lt;/a&gt; &lt;a class="reference external" href="http://www.smh.com.au/federal-politics/political-news/australias-new-security-laws-explained-20140926-10mh6d.html"&gt;of legislation&lt;/a&gt; was an attack on freedom of the press.  It threatens anyone who says or writes anything about an &lt;span class="caps"&gt;ASIO&lt;/span&gt; special operation &amp;#8212; journalist, blogger or social media user &amp;#8212; with up to 10 years in jail.  And anything can be deemed an &lt;span class="caps"&gt;ASIO&lt;/span&gt; special operation.  It also gives &lt;span class="caps"&gt;ASIO&lt;/span&gt; the power to spy on the entire internet with a single warrant, and to plant spyware on people&amp;#8217;s&amp;nbsp;computers.&lt;/p&gt;
&lt;p&gt;The &lt;a class="reference external" href="http://theconversation.com/bill-targets-foreign-fighters-before-departure-and-after-return-30095"&gt;second tranche&lt;/a&gt;  further restricts freedom of speech, and sets a disturbing precedent for essentially treating people as guilty unless they can prove they are&amp;nbsp;innocent.&lt;/p&gt;
&lt;p&gt;The third batch of regulation has the technical community in its sights.  It is a full on attack on the internet, and it users.  On&amp;nbsp;us.&lt;/p&gt;
&lt;p&gt;The government wants to force ISPs to retain customer “metadata” &amp;#8212; to &lt;a class="reference external" href="http://www.smh.com.au/federal-politics/political-news/malcolm-turnbull-introduces-legislation-for-metadata-retention-scheme-20141030-11e101.html"&gt;store phone and internet usage data on all their customers.&lt;/a&gt;  They want ISPs to &lt;a class="reference external" href="http://www.abc.net.au/news/2014-10-30/turnbull-introduces-data-retention-bill-to-parliament/5853156"&gt;spy on us on behalf of the government.&lt;/a&gt; Spy on our phone calls, and on our internet&amp;nbsp;usage.&lt;/p&gt;
&lt;p&gt;Apart from being creepy, there are many reasons this is a bad&amp;nbsp;idea.&lt;/p&gt;
&lt;p&gt;It will be expensive, and the cost will inevitably be passed on to us.  This will essentially be an “internet tax”, in that it will make internet access more expensive in Australia.  And Australia already has expensive yet crappy&amp;nbsp;internet.&lt;/p&gt;
&lt;p&gt;It is a gross invasion of privacy.  And it isn’t even clear who will end up having access to this metadata.  It seems likely that it will be used as evidence to prosecute online piracy, as well as being used in all kinds of civil&amp;nbsp;lawsuits.&lt;/p&gt;
&lt;p&gt;But most disturbingly, it will have the opposite effect to that intended.  It will actually make us all less safe.  This stored metadata will be an irresistible honeypot for hackers the world over.  It means hackers will inevitably get access to all sorts of sensitive metadata, of both individuals and government employees.  Best case scenario this hacked metadata is used to embarrass the politicians who voted for it.  Worst case is it’s used to blackmail people in positions of&amp;nbsp;power.&lt;/p&gt;
&lt;p&gt;Mandatory data retention will do little to make us safer, but it will make the internet more expensive, slower, less secure, and less private.  It&amp;#8217;s win for government, but a loss for everyone&amp;nbsp;else.&lt;/p&gt;
&lt;p&gt;We are basically losing a war against politicians trying to take away our freedoms, making things more difficult for us, and generally meddling in an industry they don’t&amp;nbsp;understand.&lt;/p&gt;
&lt;p&gt;They&amp;#8217;re&amp;nbsp;winning.&lt;/p&gt;
&lt;p&gt;What&amp;#8217;s worse is not just that they&amp;#8217;re winning, but that they are clearly idiots with delusions of competence.   The worst thing is that we are losing to a bunch of out of touch and ill-informed&amp;nbsp;idiots.&lt;/p&gt;
&lt;p&gt;This has been obvious in the past few&amp;nbsp;months.&lt;/p&gt;
&lt;p&gt;Attorney-General George Brandis threw the first turd in the metadata shitfight when he did an &lt;a class="reference external" href="https://www.youtube.com/watch?v=EbtgULCY5zk"&gt;interview on Sky News&lt;/a&gt; to announce the government’s intention to introduce mandatory data&amp;nbsp;retention.&lt;/p&gt;
&lt;p&gt;During this interview, Brandis was &lt;a class="reference external" href="http://www.abc.net.au/insiders/content/2014/s4064410.htm"&gt;unable to explain what metadata actually is&lt;/a&gt;.  He clearly &lt;a class="reference external" href="http://www.news.com.au/technology/online/george-brandis-metadata-interview-fails-spectacularly-internet-reacts/story-fnjwnhzf-1227016188974"&gt;had no idea.&lt;/a&gt;  This is the guy who spend thousands of dollars of taxpayer money to build fancy bookcases for his office.  It seems none of those of those books had a serviceable definition of&amp;nbsp;metadata.&lt;/p&gt;
&lt;p&gt;As funny as that trainwreck of an interview is (and it is funny), it’s also depressing because of what it implies.  There is no positive way of looking at it.  It’s disturbing no matter which angle you&amp;nbsp;take.&lt;/p&gt;
&lt;p&gt;The most charitable interpretation is that George Brandis is simply an idiot.  But if the George Brandis is a simpleton theory is too simplistic, then it implies that he didn’t care enough about the issues to do even some basic research into the topic before going on &lt;span class="caps"&gt;TV&lt;/span&gt; to talk about it.  There he was, talking about introducing draconian legislation likely to severely impact millions of people, not to mention introduce huge costs to many businesses, and not across any of the issues.  Not even on a really basic level.  (If he’d at least said something like “source &lt;span class="caps"&gt;IP&lt;/span&gt; address” or “&lt;span class="caps"&gt;DHCP&lt;/span&gt; logs”, even if somewhat out of context so it was obvious he didn’t really understand the specifics, it would have at least shown he had made some effort to understand the technical details.  It would have at least shown he was professional enough to do some fucking research.  But all he could manage was to incoherently mumble about “web addresses”, which means nothing, and shows how little he cares about doing his job&amp;nbsp;properly.)&lt;/p&gt;
&lt;p&gt;If the Attorney General can’t be bothered doing even some basic research on technical terminology, it’s probably an indication of how little everyone else in the government really cares about the subtleties of this anti-democracy legislation they’re planning.  And of how little this government care about technology industries in&amp;nbsp;general.&lt;/p&gt;
&lt;p&gt;The government would like nothing better than to ram all this legislation through parliament with little debate, and even less thought about the consequences.  They are meddling in an area they don’t understand.  And they clearly don’t&amp;nbsp;care.&lt;/p&gt;
&lt;p&gt;Obviously there aren’t enough votes in this for them to&amp;nbsp;care.&lt;/p&gt;
&lt;p&gt;Which I guess is why it’s important for us, those of us who do care about such thing, to spread the word about how terrible the decisions our political masters are&amp;nbsp;making.&lt;/p&gt;
&lt;p&gt;I would have thought Brandis’s disastrous metadata interview would have had some consequences, possibly derailed the government’s plans a bit.  But it didn’t seem to, because shortly after followed a &lt;a class="reference external" href="http://www.theguardian.com/tv-and-radio/australia-culture-blog/2014/aug/11/eric-abetz-and-george-brandis-give-the-bachelor-a-run-for-idiocy"&gt;unbelievable sequence of stupidity&lt;/a&gt; from senior government&amp;nbsp;ministers:&lt;/p&gt;
&lt;p&gt;Treasurer Joe Hockey revealed he thinks &lt;a class="reference external" href="http://www.smh.com.au/federal-politics/political-news/critics-attack-joe-hockeys-claim-poorest-dont-drive-cars-as-completely-fallacious-20140813-3dmrj.html"&gt;poor people don&amp;#8217;t drive&amp;nbsp;cars.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Senator Eric Abetz revealed he thinks &lt;a class="reference external" href="http://www.smh.com.au/federal-politics/political-news/eric-abetz-draws-link-between-abortion-and-breast-cancer-before-world-congress-of-families-20140807-101p60.html"&gt;abortion causes breast cancer.&lt;/a&gt; (Based on research from the 1950’s, apparently, which makes one wonder what decade he thinks we’re in&amp;nbsp;now?)&lt;/p&gt;
&lt;p&gt;The metadata stupidity was lost in the mix. It’s as if we have a government governing through abject stupidity and constant fuck ups.  As First Dog on the Moon so aptly put it, it’s &lt;a class="reference external" href="http://www.theguardian.com/commentisfree/cartoon/2014/aug/25/firstdog-cartoon-budgetrepair"&gt;Operation Ongoing Enormous Clusterfuck Is The New&amp;nbsp;Normal.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The weird thing is, it seems to be working.  They’re winning.  The government managed to ram through the first two tranches of anti-democracy legislation quickly and with little debate.  They tried to do the same with the metadata legislation, but thankfully failed, which is one small, tiny win for us.  But it looks likely to get passed early next&amp;nbsp;year.&lt;/p&gt;
&lt;p&gt;The idiots are going to&amp;nbsp;win.&lt;/p&gt;
&lt;p&gt;Unless we can make the mainstream see what a terrible idea it is.  Unless we can convince enough voters (or enough voters in marginal electorates) that there will be a tangible downside of having the government constantly spying on them, and turning ISPs into tools of state&amp;nbsp;surveillance.&lt;/p&gt;
&lt;p&gt;Unless we can make the government care by making sure they lose votes because of this, and possibly make sure their campaign donors lose out in some way.  It’s going to take a lot more than just tweets and bitching about it on social media, or making &lt;a class="reference external" href="http://www.cnet.com/au/news/senator-ludlam-calls-for-meme-protest-to-block-data-retention-laws/"&gt;clever&amp;nbsp;memes.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;What are the chances we can pull that&amp;nbsp;off?&lt;/p&gt;
&lt;p&gt;We’re screwed.  The idiots are going to win&amp;nbsp;again.&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related&amp;nbsp;Posts:&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/25/we-all-have-something-to-hide-from-mandatory-meta-data-retention/"&gt;We all have something to&amp;nbsp;hide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/28/metadata-karma/"&gt;Metadata&amp;nbsp;karma&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/04/14/go-work-down-the-mines-liberal-nbn-broadband-policy/"&gt;The Liberal Party&amp;#8217;s broadband policy&amp;nbsp;explained&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/02/national-broadband-cyber-futility/"&gt;National Broadband&amp;nbsp;Cyber-Futility&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/30/deviant-luddites-screwing-us/"&gt;The Deviant Luddites Screwing&amp;nbsp;Us&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/01/05/screwed-to-the-node/"&gt;Screwed To The&amp;nbsp;Node&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/01/06/booze-to-the-node/"&gt;Booze To The&amp;nbsp;Node&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="privacy"></category><category term="metadata"></category><category term="politics"></category><category term="surveillance"></category></entry><entry><title>To An Australia That Cares</title><link href="http://www.voidynullness.net/blog/2014/08/31/to-an-australia-that-cares-about-problems-of-the-rich/" rel="alternate"></link><published>2014-08-31T00:00:00+10:00</published><updated>2014-08-31T00:00:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2014-08-31:/blog/2014/08/31/to-an-australia-that-cares-about-problems-of-the-rich/</id><summary type="html">&lt;p class="first last"&gt;Read why a rich guy who&amp;#8217;s running a movie company into the ground wants you to feel really sorry for him and the industry he&amp;#8217;s&amp;nbsp;destroying.&lt;/p&gt;
</summary><content type="html">&lt;p class="introblock"&gt;We interrupt our usual technical trivialities to bring you an
&lt;a class="reference external" href="https://twitter.com/bengrubb/status/503033345089867778"&gt;important open letter&lt;/a&gt;
from &lt;strong&gt;Rich Corporate Douche&lt;/strong&gt;, &lt;span class="caps"&gt;CEO&lt;/span&gt; and Chairman of &lt;strong&gt;Corporate Douche
Multiplex Cinemas Ltd&lt;/strong&gt;, who wants you to &lt;a class="reference external" href="http://www.gizmodo.com.au/2014/08/rantmodo-village-roadshows-open-letter-doctor-whos-open-showing-and-closed-doors-for-fast-movie-pirates/"&gt;feel really sorry for him&lt;/a&gt;
and his
&lt;a class="reference external" href="http://www.televisedrevolution.com/features/village-roadshow-takes-piracy-war-print/"&gt;important rich person&amp;nbsp;problems.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;From the desk of Rich Corporate&amp;nbsp;Douche:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Dear Pirating&amp;nbsp;Plebs,&lt;/p&gt;
&lt;p&gt;A young man born in the Sydney suburb of Douchetown, I have become one of the world&amp;#8217;s finest crony capitalists.  Along with my fellow corporate cronies, and with the assistance of compliant governments, we have conspired to eliminate major competitors in the Australian movie business and build a cosy entertainment oligopoly.  Our extraordinary efforts at subverting free market forces have earned us&amp;nbsp;millions.&lt;/p&gt;
&lt;p&gt;With little real consumer choice in the market, this has allowed us to build a profitable business model based around treating our customers with contempt.  We can charge them whatever we want for movie ticket prices and food.  We can make them wait months, if not years, to see movies already released overseas.  Even if a movie happens to be made in Australia, overseas audiences will see it long before it&amp;#8217;s released locally.  They are all shining examples of how easy it is to exploit the Australian creative&amp;nbsp;industry.&lt;/p&gt;
&lt;p&gt;We love technology when it increases our profit margins, because those profits can be used to fund expensive personal drug habits.  For example, technology advancements allowed us to automate many aspects of our cinema business and thereby reduce staff.  Less money spent on staff means more profits, and more profits means more drugs for us, so it&amp;#8217;s a win-win situation.  Unless you&amp;#8217;re a customer watching a movie and a technical glitch causes the sound to drop out at a crucial point in the movie, and there is no staff member to complain to, yet alone fix the problem.  But we don&amp;#8217;t care about any of that as long as we get our drugs.  It&amp;#8217;s this focus on profits over the customer experience which I&amp;#8217;m sure will make you proud of the Australian&amp;nbsp;industry.&lt;/p&gt;
&lt;p&gt;All this wonderful Australian creativity and excellence in profitably screwing our customers is in real jeopardy of being lost if the problems the internet poses to our business isn&amp;#8217;t solved.  We hate technology when it creates competition for our lazy and outdated business models, because it&amp;#8217;s really hard to innovate and compete with expensive personal drug habits to maintain.  It&amp;#8217;s &lt;span class="caps"&gt;OK&lt;/span&gt; when we used technology to cut costs and increase profits, but it&amp;#8217;s evil and illegal when consumers use technology to bypass our cynical and inept business practices.  After decades of treating customers with contempt, how dare those customers bypass our oligopolies &amp;#8212; how dare they consume media online instead of going to our cinemas and buying ridiculously overpriced&amp;nbsp;popcorn!&lt;/p&gt;
&lt;p&gt;As rich people who have made lots of money and monopolized an industry for a really long time now, we feel entitled to continue to make money and monopolize the industry in perpetuity.  We are entitled to our profits.  But this is the good kind of entitlement &amp;#8212; rich people entitlement.  The Government have rightly moved to end the age of entitlement, but that only applies to poor people.  We&amp;#8217;re rich white men with political connections, so it&amp;#8217;s different.  We are entitled to our profits, and neither the free market nor technology changes will stand in our way when we can use our money and power to make politicians skew the playing field in our&amp;nbsp;favour.&lt;/p&gt;
&lt;p&gt;Adjusting business models for changing technological landscapes and adapting to profound cultural shifts in the way people consume media content is just not the way things are done in Australian business. Especially when it&amp;#8217;s so much easier to bribe politicians to regulate away competitive threats to our monopolistic market&amp;nbsp;share.&lt;/p&gt;
&lt;p&gt;Online content consumption, even the legal kind, is a threat to our increasingly outdated business model, and therefore by extension, a threat to our shareholders, trophy wives, mistresses, kids, and personal drug habits.  Especially personal drug habits.  Because our position on piracy issues is clearly the result of overindulging in illicit&amp;nbsp;substances.&lt;/p&gt;
&lt;p&gt;Being rich has many advantages, including being able to afford some really great drugs.  While &lt;a class="reference external" href="http://www.cnet.com/au/news/village-roadshow-says-iinet-is-complicit-in-piracy/"&gt;under the influence of those drugs&lt;/a&gt;
we came up with a potential solution to the problems online piracy poses to our business.
After lots of &lt;a class="reference external" href="http://www.theaustralian.com.au/media/how-village-keeps-show-on-the-road/story-e6frg996-1111112896849"&gt;smoking funny stuff&lt;/a&gt;, the solution became so obvious we were surprised no one had seriously proposed it&amp;nbsp;before:&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s make the internet&amp;nbsp;illegal.&lt;/p&gt;
&lt;p&gt;The Government, through Attorney General George Brandis and Minister for Communications Malcolm Turnbull, have moved positively to address this crucial issue.  But they haven&amp;#8217;t done anywhere near enough.  We still don&amp;#8217;t feel we&amp;#8217;ve got value for money with regards to our many
&lt;a class="reference external" href="http://www.crikey.com.au/2007/01/31/village-roadshow-still-a-shocker/"&gt;corporate donations to the Liberal Party.&lt;/a&gt;  The Liberal Party still owes us, so we want The Liberal Party to take immediate steps to &lt;a class="reference external" href="http://www.smh.com.au/comment/end-internet-piracy-and-bring-google-to-heel-20140616-zs8l8.html"&gt;make the internet illegal&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Those calling for a nuanced, &lt;a class="reference external" href="http://games.on.net/2014/06/whats-the-issue-with-piracy-in-australia/"&gt;common sense approach&lt;/a&gt;
to online piracy are &lt;a class="reference external" href="http://games.on.net/2014/08/village-roadshow-wont-attend-a-forum-on-piracy-because-crazies-will-be-there/"&gt;clearly crazies&lt;/a&gt;
&lt;a class="reference external" href="http://www.zdnet.com/au/village-roadshow-no-show-for-online-piracy-forum-7000032773/"&gt;whose hidden agenda is theft of movies.&lt;/a&gt; Those who insist on trying to explain matters regarding science or technology to &lt;a class="reference external" href="http://www.abc.net.au/news/2014-08-08/eric-abetz-discusses-link-between-abortion-and-breast-cancer/5657130"&gt;senior ministers&lt;/a&gt;
in this government are even crazier.
And anyone who thinks we&amp;#8217;re going to get any decent technology related policy out of this government is downright&amp;nbsp;delusional.&lt;/p&gt;
&lt;p&gt;Given than both Prime Minister Tony Abbott and Attorney General George Brandis have demonstrated they
&lt;a class="reference external" href="http://www.dailylife.com.au/news-and-views/news-features/george-brandis-stars-in-the-most-embarrassing-interview-youll-ever-be-likely-to-see-20140807-3d95s.html"&gt;know nothing about the internet,&lt;/a&gt;
it will be much simpler to convince them to ban the internet entirely, rather than trying to explain it to&amp;nbsp;them.&lt;/p&gt;
&lt;p&gt;We believe that Australia cares and it is a choice between a tiny group of out of touch rich white men unable to adapt to the digital age, and the rights and freedoms of millions of Australian internet users.  I&amp;#8217;m sure the Australian people understand the needs of rich people should come first.  After all, the jobs of &lt;a class="reference external" href="http://dailyreview.crikey.com.au/game-of-thrones-panic-a-skeleton-army-to-fight-piracy"&gt;900,000 people and economic value to our economy of $90 billion annually&lt;/a&gt; depend on us.  And that&amp;#8217;s just our mistresses and drug dealers.  Tragically, it could also mean the next generation growing up without knowing what it&amp;#8217;s like to pay a week&amp;#8217;s wages for a small popcorn and&amp;nbsp;coke.&lt;/p&gt;
&lt;p&gt;This won&amp;#8217;t happen.  We care.  Mostly about our profits.  And expensive drug habits.  And also shareholders.  But mostly the&amp;nbsp;drugs.&lt;/p&gt;
&lt;p&gt;Which is why, after making the internet illegal, we want the government to make computer games illegal too.  Because computer games compete with movies for people&amp;#8217;s attention and entertainment dollar.  And we really hate competition.  We also want to outlaw YouTube cat videos too, while we&amp;#8217;re at it.  Can&amp;#8217;t have people staying at home and watching cat videos on the internet for free instead of going to our cinemas.  Internet cat videos are just as bad as piracy, they are stealing our potential&amp;nbsp;income.&lt;/p&gt;
&lt;p&gt;Also, in addition to making unemployed people apply for 40 jobs a month, we think the government should force every unemployed person to go see 40 movies a month at our cinemas too.  That extra profit for us would be good for the economy, and great for our drug habits.  (Exactly how unemployed people on the dole who have to apply for 40 jobs a month are going to find the time or money to go see 40 movies a month is an implementation detail for a lower pay grade, and not something for us rich elite to worry&amp;nbsp;about.)&lt;/p&gt;
&lt;p&gt;See?  We&amp;#8217;re just full of great ideas in the movie distribution&amp;nbsp;business!&lt;/p&gt;
&lt;p&gt;Like our exciting new joint venture with a rather mysterious but strangely compelling group calling themselves &lt;span class="caps"&gt;SATAN&lt;/span&gt;, or something like that.  Their representatives are very keen to be working with us to capture the immortal soul of every patron to enter our cinemas.  The details and business case are still being worked out, but we&amp;#8217;re told we can buy lots of really great drugs with immortal souls, so needless to say we are very&amp;nbsp;excited.&lt;/p&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;Sincerely,&lt;/div&gt;
&lt;div class="line"&gt;&lt;br /&gt;&lt;/div&gt;
&lt;div class="line"&gt;Rich Corporate Douche&lt;/div&gt;
&lt;div class="line"&gt;Chairman and Chief Executive Officer&lt;/div&gt;
&lt;div class="line"&gt;Corporate Douche Multiplex Cinemas Limited&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related&amp;nbsp;Posts:&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/08/26/piracy-propaganda/"&gt;Piracy&amp;nbsp;Propaganda&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/04/14/go-work-down-the-mines-liberal-nbn-broadband-policy/"&gt;The Liberal Party&amp;#8217;s broadband policy&amp;nbsp;explained&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="Piracy"></category><category term="Ranting"></category><category term="Attempted Humour"></category><category term="Politics"></category></entry><entry><title>Piracy Propaganda</title><link href="http://www.voidynullness.net/blog/2014/08/26/piracy-propaganda/" rel="alternate"></link><published>2014-08-26T00:00:00+10:00</published><updated>2014-08-26T00:00:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2014-08-26:/blog/2014/08/26/piracy-propaganda/</id><summary type="html">&lt;p&gt;Village Roadshow &lt;a class="reference external" href="https://twitter.com/bengrubb/status/503033345089867778"&gt;ran ads in newspapers&lt;/a&gt;
over the weekend
&lt;a class="reference external" href="http://www.gizmodo.com.au/2014/08/rantmodo-village-roadshows-open-letter-doctor-whos-open-showing-and-closed-doors-for-fast-movie-pirates/"&gt;consisting of an open letter&lt;/a&gt;
from its CEOs &lt;a class="reference external" href="http://www.televisedrevolution.com/features/village-roadshow-takes-piracy-war-print/"&gt;expressing much butthurt over piracy&lt;/a&gt;
and &amp;#8220;copyright&amp;nbsp;theft&amp;#8221;.&lt;/p&gt;
&lt;p&gt;I really wish the language surrounding allegedly &amp;#8220;illegal&amp;#8221; downloading
would change.  It doesn&amp;#8217;t really make much sense to talk about digital
&lt;em&gt;copies&lt;/em&gt; being &amp;#8220;theft&amp;#8221;.  And from a legal perspective, there is actually no
such thing as &amp;#8220;copyright theft&amp;#8221; &amp;#8212; only copyright&amp;nbsp;infringement.&lt;/p&gt;
&lt;p&gt;But then, hyperbolic rhetoric is one of the tools the movie industry like …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Village Roadshow &lt;a class="reference external" href="https://twitter.com/bengrubb/status/503033345089867778"&gt;ran ads in newspapers&lt;/a&gt;
over the weekend
&lt;a class="reference external" href="http://www.gizmodo.com.au/2014/08/rantmodo-village-roadshows-open-letter-doctor-whos-open-showing-and-closed-doors-for-fast-movie-pirates/"&gt;consisting of an open letter&lt;/a&gt;
from its CEOs &lt;a class="reference external" href="http://www.televisedrevolution.com/features/village-roadshow-takes-piracy-war-print/"&gt;expressing much butthurt over piracy&lt;/a&gt;
and &amp;#8220;copyright&amp;nbsp;theft&amp;#8221;.&lt;/p&gt;
&lt;p&gt;I really wish the language surrounding allegedly &amp;#8220;illegal&amp;#8221; downloading
would change.  It doesn&amp;#8217;t really make much sense to talk about digital
&lt;em&gt;copies&lt;/em&gt; being &amp;#8220;theft&amp;#8221;.  And from a legal perspective, there is actually no
such thing as &amp;#8220;copyright theft&amp;#8221; &amp;#8212; only copyright&amp;nbsp;infringement.&lt;/p&gt;
&lt;p&gt;But then, hyperbolic rhetoric is one of the tools the movie industry like
to use against the competitive threat the online world&amp;nbsp;represents.&lt;/p&gt;
&lt;p&gt;Of course, the irony here is that regardless of terminology or language
used, none of these nefarious &amp;#8220;pirates&amp;#8221; doing the dastardly digital deeds
of &amp;#8220;stealing&amp;#8221; by making &lt;em&gt;copies&lt;/em&gt; are likely to be reading a weekend
&lt;em&gt;newspaper&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Not to mention the hypocrisy of Village calling copyright infringement
&amp;#8220;theft&amp;#8221; when their movie ticket and popcorn prices amount to highway&amp;nbsp;robbery.&lt;/p&gt;
&lt;p&gt;But, obviously, the purpose of the ad was less about preventing illegal
downloading, and more an attempt to reframe the debate in a way that
benefits them, while doubling as a promotion for an upcoming movie&amp;nbsp;release.&lt;/p&gt;
&lt;p&gt;The ad is all the more pathetic for being such obvious propaganda from an
industry struggling to find relevance in the digital age.  Village Roadshow
is doing what crony capitalists usually do when faced with a problem of
consumer choice or the free market reducing their profit margins &amp;#8212; running
to the government to help them out by further restricting consumer choice
and market&amp;nbsp;competition.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s regulation over innovation.  The Australian way, when it comes to&amp;nbsp;business.&lt;/p&gt;
&lt;p&gt;So we have an emotive plea for the government to restrict the rights of
internet users, under the pretext of saving movie companies from the
scourge of people infringing their intellectual&amp;nbsp;property.&lt;/p&gt;
&lt;p&gt;Which, if you think about it, is a weird thing to complain about, and even
weirder to spend thousands of dollars for the privilege of complaining
about it in newspaper&amp;nbsp;advertising.&lt;/p&gt;
&lt;p&gt;They&amp;#8217;re essentially complaining about the price signals the market is
providing them.  Illegal downloads are an indication that while some people
might want their product, they&amp;#8217;re not willing to pay the prices being
asked.  Or they want the product via a more convenient distribution model
&amp;#8212; digital download, or online streaming, perhaps viewed on a mobile&amp;nbsp;device.&lt;/p&gt;
&lt;p&gt;You would think if the movie industry had any idea about the basics of
running a business, they&amp;#8217;d spend more time working out how to best monetize
these new consumer trends towards online content consumption, and less
time lobbying governments to further skew they playing field in
their favour.  Or running newspaper ads claiming the sky is&amp;nbsp;falling.&lt;/p&gt;
&lt;p&gt;In a way, the movie companies are also complaining that many people are
keen to consume the products they produce.  A problem many industries would
dearly like to have.  It&amp;#8217;s a sign the movie industry is doing something
right.  Or at least a sign their marketing departments are doing something
right &amp;#8212; doing an excellent job of convincing people they should consume
their formulaic, cliched&amp;nbsp;crap.&lt;/p&gt;
&lt;p&gt;All of which suggest the real problem faced by the movie industry is not
&amp;#8220;piracy&amp;#8221;, but changing consumer habits and preferences, driven partly by
changes in technology.  This would suggest the solution lies more in
working out how to effectively monetize the trend to online consumption,
rather than restricting the online rights and digital freedoms of the&amp;nbsp;masses.&lt;/p&gt;
&lt;p&gt;But that would be entirely too sensible for an industry too lazy to
innovate.  An an industry that has spent so much money on political
donations, they&amp;#8217;re determined to get their money&amp;#8217;s&amp;nbsp;worth.&lt;/p&gt;
&lt;p&gt;Of course, those complaining the loudest about illegal downloads are movie
&lt;em&gt;distribution&lt;/em&gt; companies.  They feel threatened not just by the very small
percentage of their movies that are pirated online, but by the very
internet itself.  As more and more content moves to an online distribution
model, their business model becomes increasingly&amp;nbsp;obsolete.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s difficult to feel sorry for them though.  They&amp;#8217;ve had things pretty
good for a long time, with their government sanctioned oligopolies.  Now
that the internet is undermining their monopolistic ways, they go running
back to the government to protect their artificially inflated profit
margins.  They want the government to put as many artificial restrictions
on the internet as possible, just so they can artificially prolong their
profit margins in the face of changing technology and consumer&amp;nbsp;behavior.&lt;/p&gt;
&lt;p&gt;After decades of treating their customers with contempt (through high
prices, poor customer service, releasing movies much later in Australia
than other countries, etc) Village Roadshow are trying to portray
themselves as the victim of the illegally downloading hordes, now that
technology allows consumers the choice of bypassing their crappy business&amp;nbsp;practices.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s weird and completely disingenuous for a such a soulless corporate
entity as Village Roadshow to try and elicit sympathy out of this.  After
all, it&amp;#8217;s not as if they&amp;#8217;ve made much of a contribution to the movie going
experience.  Theirs is the mainstream multiplex experience that focuses on
quantity rather than quality.  Along with price&amp;nbsp;gouging.&lt;/p&gt;
&lt;p&gt;Compare and contrast this to a place like the &lt;a class="reference external" href="http://www.astortheatre.net.au/"&gt;The Astor Theatre&lt;/a&gt;, which provides a more &amp;#8220;authentic&amp;#8221;
movie going experience, and one that many people actually care about.  The
two exist on opposite ends of a spectrum in many ways, and there&amp;#8217;s a kind
of weird irony that this ad ran on the same weekend that The Astor
announced it &lt;a class="reference external" href="http://astortheatreblog.wordpress.com/2014/08/23/astor-theatre-1982-2015/"&gt;will close in early&amp;nbsp;2015.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There were a lot of genuinely disappointed people after The Astor announced
it would be closing.  The emotion didn&amp;#8217;t have to be forced or manipulated
through full page newspaper ads.  Can&amp;#8217;t imagine anyone would really care if
any individual Village cinema shut down.  Or even the whole&amp;nbsp;company.&lt;/p&gt;
&lt;p&gt;I suspect on some level, Village Roadshow might be  aware of&amp;nbsp;this.&lt;/p&gt;
&lt;p&gt;The emotional language of the ad also seems to reflect either a delusion
about their importance to the local movie industry, or a weird insecurity
about their place in&amp;nbsp;it.&lt;/p&gt;
&lt;p&gt;If Village Roadshow were to disappear, maybe the Australian movie industry
would too.  Or at least part of it.  But I doubt it.  If there is any money
to be made, another company would step in to make it.  Or to create a
business model that works in a new, online era.  It&amp;#8217;s quite arrogant of
Village Roadshow to think just because they can&amp;#8217;t make money making
Australian movies, then no one else&amp;nbsp;can.&lt;/p&gt;
&lt;p&gt;The fact that independent cinemas like The Astor have existed so long &amp;#8212;
especially given the many market forces working against them, not to
mention competition from the likes of Village &amp;#8212; suggests there does exist
an audience passionate about films and the cinema&amp;nbsp;experience.&lt;/p&gt;
&lt;p&gt;Australia does&amp;nbsp;care.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s just that Australia doesn&amp;#8217;t care about the corporate tools at Village&amp;nbsp;Roadshow.&lt;/p&gt;
</content><category term="Piracy"></category><category term="Ranting"></category></entry><entry><title>How to install a Python development environment on Windows</title><link href="http://www.voidynullness.net/blog/2014/06/19/install-python-setuptools-pip-virtualenvwrapper-for-powershell-pyside-on-windows/" rel="alternate"></link><published>2014-06-19T00:00:00+10:00</published><updated>2014-06-19T00:00:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2014-06-19:/blog/2014/06/19/install-python-setuptools-pip-virtualenvwrapper-for-powershell-pyside-on-windows/</id><summary type="html">&lt;p class="first last"&gt;For those times you wanna do some Python coding but all you got is a Windows&amp;nbsp;machine.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;This is a brief outline of the process I used recently for setting up a
Python development environment on a new Windows 8.1 machine.  (Based mostly
on information in &lt;a class="reference external" href="http://www.tylerbutler.com/2012/05/how-to-install-python-pip-and-virtualenv-on-windows-with-powershell/"&gt;these&lt;/a&gt;
&lt;a class="reference external" href="http://docs.python-guide.org/en/latest/starting/install/win/"&gt;posts&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Installing Python itself on Windows &amp;#8212; just to run Python scripts &amp;#8212; is
fairly straightforward: &lt;a class="reference external" href="https://www.python.org/download/"&gt;pick a Python implementation&lt;/a&gt;
(CPython or one of the alternatives) download and run the
installer, and you should be good to&amp;nbsp;go.&lt;/p&gt;
&lt;p&gt;But to do any kind of non-trivial development, you&amp;#8217;re probably going to
want a few more tools available &amp;#8212; at the very least things like pip and&amp;nbsp;virtualenv.&lt;/p&gt;
&lt;p&gt;Since there is a really nice PowerShell implementation of
virtualenvwrapper, I like to set things up so I can work from a PowerShell
command&amp;nbsp;line.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s what I installed, in the order I installed it, to get a reasonably
useable Python development environment on&amp;nbsp;Windows.&lt;/p&gt;
&lt;div class="section" id="python"&gt;
&lt;h2&gt;Python&lt;/h2&gt;
&lt;p&gt;First step is to &lt;a class="reference external" href="https://www.python.org/download/"&gt;download and install Python&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I went with what I suppose is the conservative approach: 32-bit CPython
2.7.  (Yeah, I&amp;nbsp;know&amp;#8230;)&lt;/p&gt;
&lt;p&gt;After installing Python, make sure running scripts is enabled in&amp;nbsp;PowerShell:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Set-ExecutionPolicy RemoteSigned
&lt;/pre&gt;
&lt;p&gt;If the Python installer didn&amp;#8217;t add the location of Python to the system
path, you will need to do that yourself.  I did that by creating file called
&lt;tt class="docutils literal"&gt;profile.ps1&lt;/tt&gt; in &lt;tt class="docutils literal"&gt;~/Documents/WindowsPowerShell&lt;/tt&gt; and added the
Python install path to &lt;tt class="docutils literal"&gt;$env:Path&lt;/tt&gt;.  My &lt;tt class="docutils literal"&gt;profile.ps1&lt;/tt&gt; looks like&amp;nbsp;this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nv"&gt;$env:Path&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;;C:\Python27;C:\Python27\Scripts&amp;quot;&lt;/span&gt;
&lt;span class="nb"&gt;Import-Module&lt;/span&gt; &lt;span class="n"&gt;virtualenvwrapper&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Modify the path as necessary for your&amp;nbsp;system.&lt;/p&gt;
&lt;p&gt;The second line, importing virtualenvwrapper, is explained&amp;nbsp;below.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="setuptools"&gt;
&lt;h2&gt;Setuptools&lt;/h2&gt;
&lt;p&gt;Next install &lt;a class="reference external" href="https://pythonhosted.org/setuptools/setuptools.html"&gt;Setuptools&lt;/a&gt;, a tool for
building and distributing Python packages.  It&amp;#8217;s required by pip (see
below).  In the past we might have installed &lt;a class="reference external" href="https://pythonhosted.org/distribute/"&gt;Distribute&lt;/a&gt; instead, but apparently Distribute
has been merged into Setuptools, so now Setuptools is the way to&amp;nbsp;go.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://bitbucket.org/pypa/setuptools#rst-header-windows-8-powershell"&gt;Download ez_setup.py&lt;/a&gt;
and run it in an administrator PowerShell&amp;nbsp;console.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="pip"&gt;
&lt;h2&gt;pip&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://pip.pypa.io/en/latest/index.html"&gt;pip&lt;/a&gt; is a tool for installing
and managing Python packages.  It automates and simplifies the process of
downloading and installing packages from online repositories (usually &lt;a class="reference external" href="https://pypi.python.org/pypi"&gt;PyPI&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;To &lt;a class="reference external" href="http://www.pip-installer.org/en/latest/installing.html#using-the-installer"&gt;install pip&lt;/a&gt;,
download &lt;a class="reference external" href="https://raw.github.com/pypa/pip/master/contrib/get-pip.py"&gt;get-pip.py&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Then run it in an (administrator) PowerShell&amp;nbsp;console:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
python .\get-pip.py
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="virtualenv-and-virtualenvwrapper"&gt;
&lt;h2&gt;virtualenv and&amp;nbsp;virtualenvwrapper&lt;/h2&gt;
&lt;p&gt;Different Python project are likely to require different collections of
packages.  It&amp;#8217;s common practice to avoid installing packages into the
system Python installation, and instead use virtualenv to create isolated
Python environments.  virtualenvwrapper simplifies the use of virtualenv
for common tasks, and there is a PowerShell port that works really well on&amp;nbsp;Windows.&lt;/p&gt;
&lt;p&gt;With setuptools and pip installed, we can now install virtualenv
and virtualenvwrapper by using the following commands at a PowerShell&amp;nbsp;prompt:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
pip install virtualenv
pip install virtualenvwrapper-powershell
mkdir ~/.virtualenvs
&lt;/pre&gt;
&lt;p&gt;To check if everything installed&amp;nbsp;correctly:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
Import-Module virtualenvwrapper
Get-Command *virtualenv*
&lt;/pre&gt;
&lt;p&gt;This should produce a list of available virtualenv&amp;nbsp;commands.&lt;/p&gt;
&lt;p&gt;You should now be able to use virtualenvwrapper in pretty much the same way
as on Linux (but there&amp;#8217;s also PowerShell style cmdlets as&amp;nbsp;alternatives).&lt;/p&gt;
&lt;p&gt;To avoid having to type &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Import-Module&lt;/span&gt; virtualenvwrapper&lt;/tt&gt; every time you
open a new PowerShell window, it&amp;#8217;s a good idea to add it to your profile,
as shown in the earlier&amp;nbsp;example.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="qt-and-pyside"&gt;
&lt;h2&gt;Qt and&amp;nbsp;PySide&lt;/h2&gt;
&lt;p&gt;My reasons for even bothering to install a Python development environment
on a Windows machine usually have something to do with Qt based
development.  I use the PySide bindings, which on Windows can be &lt;a class="reference external" href="http://qt-project.org/wiki/PySide_Binaries_Windows"&gt;installed
in a virtualenv&lt;/a&gt; like&amp;nbsp;so:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
New-VirtualEnvironment pyside
easy_install -U PySide
&lt;/pre&gt;
&lt;p&gt;The first line creates a virtualenv called &amp;#8220;pyside&amp;#8221;, and the second line
installs the PySide&amp;nbsp;bindings.&lt;/p&gt;
&lt;p&gt;(The &lt;tt class="docutils literal"&gt;easy_install&lt;/tt&gt; command didn&amp;#8217;t work first time I tried it, not sure
why.  But it ran fine when I tried it again, after a&amp;nbsp;reboot.)&lt;/p&gt;
&lt;/div&gt;
</content><category term="Python"></category><category term="PowerShell"></category></entry><entry><title>How to turn a Windows box into a development machine</title><link href="http://www.voidynullness.net/blog/2014/06/12/initial-windows-8-development-machine-setup/" rel="alternate"></link><published>2014-06-12T00:00:00+10:00</published><updated>2014-06-12T00:00:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2014-06-12:/blog/2014/06/12/initial-windows-8-development-machine-setup/</id><summary type="html">&lt;p class="first last"&gt;For those times when there isn&amp;#8217;t a Linux box handy&amp;#8230;and you must write&amp;nbsp;code&amp;#8230;&lt;/p&gt;
</summary><content type="html">&lt;p&gt;One of the problems with a new Windows machine (or a clean install of an
old one), apart from the fact it is a Windows machine, is the time that
will inevitably be spent looking at progress bars while the many, many
pieces of software a Windows &lt;span class="caps"&gt;PC&lt;/span&gt; needs to be usable as a development
machine (or anything else more productive than web browsing device) are
downloaded and&amp;nbsp;installed.&lt;/p&gt;
&lt;p&gt;The following are the things I installed recently on a new Windows 8.1
machine to suitably geekify it for my coding purposes, in approximate order
of geekiness &amp;#8212; from least technical (things all Windows machine will
probably need to have installed, like browsers, document viewers, etc) to
the most technical (IDEs and development&amp;nbsp;tools).&lt;/p&gt;
&lt;p&gt;Given a choice, I generally prefer to do development work on a Linux
box.  But sometimes having a Windows machine handy is a necessary&amp;nbsp;evil.&lt;/p&gt;
&lt;p&gt;This was actually my first experience with the much maligned Windows 8 &lt;span class="caps"&gt;UI&lt;/span&gt;.
But I will reserve judgment until I&amp;#8217;ve have a chance to use it for a
while.  My initial reaction so far is pretty much what I expected &amp;#8212; Metro
on a desktop is somewhat clunky and horrible, but nowhere near as bad as
it&amp;#8217;s been made out to&amp;nbsp;be.&lt;/p&gt;
&lt;div class="section" id="browsers"&gt;
&lt;h2&gt;Browsers&lt;/h2&gt;
&lt;p&gt;Obvious first step is to avoid having anything to do with Internet&amp;nbsp;Explorer.&lt;/p&gt;
&lt;p&gt;So goodbye &lt;span class="caps"&gt;IE&lt;/span&gt;, hello &lt;a class="reference external" href="https://www.google.com/chrome/browser/"&gt;Chrome&lt;/a&gt; and &lt;a class="reference external" href="http://www.mozilla.org/en-US/firefox/new/"&gt;Firefox.&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="document-viewers"&gt;
&lt;h2&gt;Document&amp;nbsp;Viewers&lt;/h2&gt;
&lt;p&gt;Kindle for &lt;span class="caps"&gt;PC&lt;/span&gt; &amp;#8212; for reading&amp;nbsp;eBooks.&lt;/p&gt;
&lt;p&gt;Adobe Reader for viewing &lt;span class="caps"&gt;PDF&lt;/span&gt; files &amp;#8212;  be sure to deselect any options for
McAfee&amp;nbsp;crapware.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="dropbox"&gt;
&lt;h2&gt;Dropbox&lt;/h2&gt;
&lt;p&gt;You&amp;#8217;re probably gonna want the desktop client from the
&lt;a class="reference external" href="https://www.dropbox.com/"&gt;Dropbox website&lt;/a&gt;,
not the Metro&amp;nbsp;app.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="backup"&gt;
&lt;h2&gt;Backup&lt;/h2&gt;
&lt;p&gt;At this point I installed backup software and did an image of the hard
drive, so that I&amp;#8217;d have a clean and minimal image I could revert to if&amp;nbsp;necessary.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="emacs"&gt;
&lt;h2&gt;Emacs&lt;/h2&gt;
&lt;p&gt;I&amp;#8217;m an Emacs kinda guy, so even on Windows some kind of Emacs is&amp;nbsp;compulsory.&lt;/p&gt;
&lt;p&gt;After trying other variations, I inevitably seem to go back to the standard
&lt;span class="caps"&gt;GNU&lt;/span&gt;&amp;nbsp;build.&lt;/p&gt;
&lt;p&gt;This time, I looked around for alternatives, and came across
&lt;a class="reference external" href="http://ergoemacs.org/"&gt;ErgoEmacs.&lt;/a&gt; I hadn&amp;#8217;t heard of this variant
before, but it wasn&amp;#8217;t the &amp;#8220;ergonomics&amp;#8221; aspect that interested me &amp;#8212; it was
the fact it comes packaged with Windows ports of many common Unix commands,
along with other configuration niceties.  So I thought I&amp;#8217;d give it a&amp;nbsp;go.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="notepad"&gt;
&lt;h2&gt;Notepad++&lt;/h2&gt;
&lt;p&gt;Despite having Emacs on my Windows machines, I also like to have a more
typical Windows text editor available, for those times I might want to just
view&amp;nbsp;files.&lt;/p&gt;
&lt;p&gt;I find &lt;a class="reference external" href="http://notepad-plus-plus.org/"&gt;Notepad++&lt;/a&gt; fills this need&amp;nbsp;nicely.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="office"&gt;
&lt;h2&gt;Office&lt;/h2&gt;
&lt;p&gt;Despite being primarily a development machine, having an office suite
installed can come in surprisingly handy, even if it&amp;#8217;s just to
view/manipulate &lt;span class="caps"&gt;CSV&lt;/span&gt; files in a&amp;nbsp;spreadsheet.&lt;/p&gt;
&lt;p&gt;Libre Office will usually do for those not wanting to go down the
Microsoft Office&amp;nbsp;route.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="python"&gt;
&lt;h2&gt;Python&lt;/h2&gt;
&lt;p&gt;A machine without Python is just not a development machine, as far as I&amp;#8217;m
concerned.  But I will save the gory details of my &lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/06/19/install-python-setuptools-pip-virtualenvwrapper-for-powershell-pyside-on-windows/"&gt;Windows Python setup
for it&amp;#8217;s own&amp;nbsp;post.&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="java"&gt;
&lt;h2&gt;Java&lt;/h2&gt;
&lt;p&gt;Even if you have no intention of actually developing in &lt;a class="reference external" href="http://www.oracle.com/technetwork/java/javase/downloads/index.html"&gt;Java&lt;/a&gt;
at some point you&amp;#8217;re likely to need at least the runtime, if not the
&lt;a class="reference external" href="http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html"&gt;whole &lt;span class="caps"&gt;SDK&lt;/span&gt;.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Be sure to opt out of any crapware options included in the&amp;nbsp;installer.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="development-tools"&gt;
&lt;h2&gt;Development&amp;nbsp;Tools&lt;/h2&gt;
&lt;p&gt;So with the main preliminaries out of the way, it should now be safe to
install actual development&amp;nbsp;tools.&lt;/p&gt;
&lt;p&gt;To each their own, but my Windows development needs at the moment revolve
around a combination of Android and&amp;nbsp;Qt.&lt;/p&gt;
&lt;p&gt;For &lt;a class="reference external" href="https://developer.android.com/sdk/index.html"&gt;Android development&lt;/a&gt;
there&amp;#8217;s the choice of &lt;a class="reference external" href="http://developer.android.com/tools/studio/index.html"&gt;Android Studio&lt;/a&gt; or Eclipse with &lt;span class="caps"&gt;ADT&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;These appears to work fine with Java &lt;span class="caps"&gt;SE&lt;/span&gt; Development Kit 7, even though
Android is (currently) limited to the Java 6 &lt;span class="caps"&gt;API&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;For any desktop &lt;span class="caps"&gt;UI&lt;/span&gt; work &lt;a class="reference external" href="http://qt-project.org/"&gt;Qt&lt;/a&gt; is currently my
preferred framework (usually via Python bindings).  When I tried to install
Qt Creator using the &lt;a class="reference external" href="http://qt-project.org/downloads"&gt;online
installer.&lt;/a&gt;,
it got stuck while downloading files the first time round.  But I ran it again
and it worked.  Go&amp;nbsp;figure.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="linux"&gt;
&lt;h2&gt;Linux!&lt;/h2&gt;
&lt;p&gt;Finally, because all too often on Windows I want to do something that is
just much easier/faster/better done on Linux, I installed &lt;a class="reference external" href="https://www.virtualbox.org/"&gt;VirtualBox&lt;/a&gt;, then created a &lt;a class="reference external" href="http://www.linuxmint.com/"&gt;Linux Mint&lt;/a&gt; virtual&amp;nbsp;machine.&lt;/p&gt;
&lt;/div&gt;
</content></entry><entry><title>How to make a Samsung Galaxy S3 play nice with Eclipse on Windows</title><link href="http://www.voidynullness.net/blog/2014/05/01/how-to-debug-run-android-app-samsung-galaxy-s3-device-eclipse-windows/" rel="alternate"></link><published>2014-05-01T00:00:00+10:00</published><updated>2014-05-01T00:00:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2014-05-01:/blog/2014/05/01/how-to-debug-run-android-app-samsung-galaxy-s3-device-eclipse-windows/</id><summary type="html">&lt;p&gt;Using Eclipse on a Windows development machine, I&amp;#8217;d managed to get &lt;span class="caps"&gt;USB&lt;/span&gt;
debugging working on various Android devices with various versions of
Android without too much drama.  But I ran into some difficulties when I
tried to debug an app on a Samsung Galaxy S3 (&lt;span class="caps"&gt;GT&lt;/span&gt;-&lt;span class="caps"&gt;I9300T&lt;/span&gt; with Android&amp;nbsp;4.3).&lt;/p&gt;
&lt;p&gt;I think I&amp;#8217;m beginning to detect a pattern emerging &amp;#8212; the more recent the
Android version, the more (unnecessary?) development hoops to jump through.
(Because Security!&amp;nbsp;Apparently.)&lt;/p&gt;
&lt;p&gt;So …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Using Eclipse on a Windows development machine, I&amp;#8217;d managed to get &lt;span class="caps"&gt;USB&lt;/span&gt;
debugging working on various Android devices with various versions of
Android without too much drama.  But I ran into some difficulties when I
tried to debug an app on a Samsung Galaxy S3 (&lt;span class="caps"&gt;GT&lt;/span&gt;-&lt;span class="caps"&gt;I9300T&lt;/span&gt; with Android&amp;nbsp;4.3).&lt;/p&gt;
&lt;p&gt;I think I&amp;#8217;m beginning to detect a pattern emerging &amp;#8212; the more recent the
Android version, the more (unnecessary?) development hoops to jump through.
(Because Security!&amp;nbsp;Apparently.)&lt;/p&gt;
&lt;p&gt;So here&amp;#8217;s the full process I ended up going through to make everything
work.  The following worked for me on both a Windows 7 machine, and a
Windows 8.1 laptop.  (But as always, &lt;span class="caps"&gt;YMMV&lt;/span&gt;.)  I suspect the process would
be the same for the Galaxy S4 and S5, as well as other recent Android 4
devices, with the only difference being the &lt;span class="caps"&gt;USB&lt;/span&gt; driver&amp;nbsp;required.&lt;/p&gt;
&lt;p&gt;First thing, as usual, is to enable &lt;span class="caps"&gt;USB&lt;/span&gt; debugging on the&amp;nbsp;device:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Open &lt;strong&gt;Settings&lt;/strong&gt;, go to the &lt;strong&gt;More&lt;/strong&gt; tab and select &lt;strong&gt;Developer
options&lt;/strong&gt;.  If you don&amp;#8217;t have any &lt;strong&gt;Developer Options&lt;/strong&gt; then:&lt;ul&gt;
&lt;li&gt;Scroll down and Select &lt;strong&gt;About device&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Scroll down to reveal &lt;strong&gt;Build number&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Tap &lt;strong&gt;Build number&lt;/strong&gt; seven&amp;nbsp;times.&lt;/li&gt;
&lt;li&gt;Navigate back to the previous screen, and you should now find a selection
for &lt;strong&gt;Developer options&lt;/strong&gt; has magically appeared.  Select&amp;nbsp;it.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Enable the &lt;strong&gt;&lt;span class="caps"&gt;USB&lt;/span&gt; Debugging&lt;/strong&gt;&amp;nbsp;option.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When developing on Windows, an &lt;span class="caps"&gt;OEM&lt;/span&gt; &lt;span class="caps"&gt;USB&lt;/span&gt; driver is required.
I installed the &lt;a class="reference external" href="http://developer.samsung.com/android/tools-sdks/Samsung-Andorid-USB-Driver-for-Windows"&gt;Windows &lt;span class="caps"&gt;USB&lt;/span&gt; driver from the Samsung&amp;nbsp;website.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You may need to reboot at this point, especially if it&amp;#8217;s a Windows 7
machine you&amp;#8217;re&amp;nbsp;using.&lt;/p&gt;
&lt;p&gt;This next step is surprisingly significant.  Before connecting the Galaxy S3
to the &lt;span class="caps"&gt;PC&lt;/span&gt; via &lt;span class="caps"&gt;USB&lt;/span&gt;, turn on the device and &lt;strong&gt;unlock the screen&lt;/strong&gt;.  Do whatever you
need to do to prevent the phone from turning off/sleeping/locking until
you&amp;#8217;ve got Eclipse to recognise&amp;nbsp;it.&lt;/p&gt;
&lt;p&gt;With the phone on and the screen unlocked, connect it to the development
machine with a &lt;span class="caps"&gt;USB&lt;/span&gt;&amp;nbsp;cable.&lt;/p&gt;
&lt;p&gt;Windows will then hopefully detect the device and do some driver
installation.  Wait for it to finish.  But watch the screen on the&amp;nbsp;phone.&lt;/p&gt;
&lt;p&gt;At some point you should see a dialog pop up asking if you want to &amp;#8220;Allow
&lt;span class="caps"&gt;USB&lt;/span&gt;  debugging&amp;#8221; from this&amp;nbsp;computer.&lt;/p&gt;
&lt;img alt="Samsung Galaxy S3 Allow USB Debugging screenshot" src="http://www.voidynullness.net/images/galaxy_s3_allow_usb_debug.png" /&gt;
&lt;p&gt;Select &lt;span class="caps"&gt;OK&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Eclipse (and &lt;tt class="docutils literal"&gt;adb&lt;/tt&gt;) should now be able to connect to the Galaxy S3.  If
you look in the &lt;strong&gt;Devices&lt;/strong&gt; tab in the &lt;span class="caps"&gt;DDMS&lt;/span&gt; perspective, you should see the
device listed as&amp;nbsp;&amp;#8220;Online&amp;#8221;:&lt;/p&gt;
&lt;img alt="Eclipse Devices Samsung Galaxy S3 online screenshot" src="http://www.voidynullness.net/images/eclipse_galaxy_s3_online.png" /&gt;
&lt;p&gt;If so, you should now be able to use Eclipse to run apps on the device in
the usual way (Run as Android&amp;nbsp;Application).&lt;/p&gt;
&lt;p&gt;If not (if the phone comes up as &amp;#8220;unauthorized&amp;#8221; or &amp;#8220;offline&amp;#8221;), try
switching the &lt;span class="caps"&gt;USB&lt;/span&gt; connection option on the phone from &lt;span class="caps"&gt;MTP&lt;/span&gt; mode to &lt;span class="caps"&gt;PTP&lt;/span&gt;, then
back again.  This should make Windows reload the drivers, and then the
&amp;#8220;Allow &lt;span class="caps"&gt;USB&lt;/span&gt; debugging&amp;#8221; should&amp;nbsp;appear.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s possibly worth pointing out at this point, if you find nothing works,
try a different &lt;span class="caps"&gt;USB&lt;/span&gt; cable.  In particular, keep the cable that came with
the device handy (and labeled, if necessary!).  I once wasted a lot of time
trying to get Eclipse to connect to my S3 using a &lt;span class="caps"&gt;USB&lt;/span&gt; cable that just
happened to by lying on my desk at the time, all to no avail.  It would
charge, but not do anything else.  Turns out that one particular cable, for
some reason, just doesn&amp;#8217;t work.  Switching to a different cable did the&amp;nbsp;trick.&lt;/p&gt;
</content><category term="Eclipse"></category><category term="ADT"></category><category term="Android"></category></entry><entry><title>The Liberal Party’s broadband policy explained</title><link href="http://www.voidynullness.net/blog/2014/04/14/go-work-down-the-mines-liberal-nbn-broadband-policy/" rel="alternate"></link><published>2014-04-14T00:00:00+10:00</published><updated>2014-04-14T00:00:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2014-04-14:/blog/2014/04/14/go-work-down-the-mines-liberal-nbn-broadband-policy/</id><summary type="html">&lt;p class="first last"&gt;The Minister for Mis-communication explains his vision for crappy internet infrastructure in&amp;nbsp;Australia.&lt;/p&gt;
</summary><content type="html">&lt;p class="introblock"&gt;We interrupt our usual random technical trivialities to bring you an important announcement from the Minister for Mis-communication, Malcolm something-or-other, we&amp;#8217;re not sure, we&amp;#8217;d look it up, but our &lt;span class="caps"&gt;ADSL&lt;/span&gt; has dropped out again, and as usual Telstra refuses to fix it.  Anyway, apparently this is what you need to know about the current state of broadband in Australia, and the Liberal Party&amp;#8217;s grand technological vision for the&amp;nbsp;country&amp;#8230;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;From the desk of The Minister for&amp;nbsp;Mis-communication:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Dear nerds, journalists and welfare&amp;nbsp;bludgers,&lt;/p&gt;
&lt;p&gt;It appears once again my &lt;a class="reference external" href="http://www.minister.communications.gov.au/malcolm_turnbull/speeches/commsday"&gt;intentions&lt;/a&gt;
are being &lt;a class="reference external" href="http://www.zdnet.com/turnbull-walks-away-from-nbn-high-ground-claims-7000028267/"&gt;misunderstood.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Once again allegations of &lt;a class="reference external" href="http://www.abc.net.au/news/2014-04-14/braue-nbn-hypocrisy-confirms-contempt-for-process/5384464"&gt;hypocrisy&lt;/a&gt;
and &lt;a class="reference external" href="http://www.sortius-is-a-geek.com/off-with-their-heads/"&gt;lying&lt;/a&gt;
are being &lt;a class="reference external" href="http://www.theaustralian.com.au/media/opinion/turnbull-too-quick-to-abandon-faster-smarter-broadband-service/story-e6frg9tf-1226883007979#"&gt;unfairly&lt;/a&gt;
leveled against me,
just because in opposition I consistently criticized the Labor government
for proceeding with a Fibre To The Premises National Broadband Network
without a cost-benefit analysis, and now in government I&amp;#8217;m doing the same
thing, and proceeding with my alternative &lt;a class="reference external" href="http://www.crikey.com.au/2014/04/10/turnbull-pulls-the-plug-on-fttp-so-were-back-to-the-drawing-board/"&gt;Fibre To Nowhere&lt;/a&gt;
&lt;a class="reference external" href="https://newmatilda.com/2014/04/10/nbn-not-national-not-broadband-not-network"&gt;Hodgepodge Broadband Network&lt;/a&gt;
without a cost-benefit&amp;nbsp;analysis.&lt;/p&gt;
&lt;p&gt;I think there may be some &lt;a class="reference external" href="http://delimiter.com.au/2014/04/10/dont-know-cover-nbn-anymore/"&gt;confusion&lt;/a&gt;
out there on where the Liberal Party of
Australia &amp;#8212; a division of News Corp (&lt;span class="caps"&gt;NASDAQ&lt;/span&gt;: &lt;span class="caps"&gt;NWS&lt;/span&gt;) &amp;#8212; actually stands on
broadband and technology issues.  So let me try and clear things up for all
you computer nerds and clueless tech&amp;nbsp;journalists.&lt;/p&gt;
&lt;p&gt;The &lt;a class="reference external" href="http://www.jasonclare.com.au/media/portfolio-releases/1846-one-year-since-liberal-lie-on-nbn.html"&gt;Coalition&amp;#8217;s Plan&lt;/a&gt;
for &lt;a class="reference external" href="http://www.michellerowland.com.au/malcolms-multi-mix-an-upload-of-rubbish/"&gt;better broadband&lt;/a&gt;
is basically this:
go work down the&amp;nbsp;mines.&lt;/p&gt;
&lt;p&gt;Forget about the internet, and just go work down the&amp;nbsp;mines.&lt;/p&gt;
&lt;p&gt;All you geeks and porn addicts and journalists &amp;#8212; all of you put away your
computers and phones and tablets, and go get a real job down the&amp;nbsp;mines.&lt;/p&gt;
&lt;p&gt;Because the only thing Australia is good for is mining.  Just mining.
That&amp;#8217;s all our current and future prosperity should be linked to.  We as a
country should just focus on&amp;nbsp;mining.&lt;/p&gt;
&lt;p&gt;Because if there&amp;#8217;s one thing the Global Financial Crisis taught us, is that
there is no need to diversify or hedge risk if you&amp;#8217;re onto a sure thing,
and mining is as sure as houses and mortgage backed securities.  And
anyway, if something does go wrong, we now know any economic problem can be
solved with clever financial engineering and endless money&amp;nbsp;printing.&lt;/p&gt;
&lt;p&gt;Because what could possibly go wrong anyway?  After all, we are in a
commodity super cycle that will never end.  Australia can dig stuff out of
the ground and sell it to the highest bidder&amp;nbsp;forever.&lt;/p&gt;
&lt;p&gt;Because we have so much stuff in the ground to dig up that we will never
run out, and we will always have willing&amp;nbsp;buyers.&lt;/p&gt;
&lt;p&gt;So all of you geeks and bloggers and journalists &amp;#8212; stop whining and go
work down the&amp;nbsp;mines&lt;/p&gt;
&lt;p&gt;Australia is a mining country.  We have no need for a modern broadband
network, or a technology industry, or even technology.  Australia needs
fast and reliable broadband infrastructure about as much as it needs a car
industry.  Or an&amp;nbsp;environment.&lt;/p&gt;
&lt;p&gt;So the official position of The Liberal Party on broadband is that you
should all go work down the&amp;nbsp;mines.&lt;/p&gt;
&lt;p&gt;Forget about the internet.  Australia is a technological backwater and
that&amp;#8217;s the way it should&amp;nbsp;be.&lt;/p&gt;
&lt;p&gt;All we&amp;#8217;re good for is digging stuff out of the ground and selling it to
China, so that&amp;#8217;s all we&amp;#8217;re going to&amp;nbsp;do.&lt;/p&gt;
&lt;p&gt;That&amp;#8217;s why we&amp;#8217;re so keen to repeal the mining tax and the carbon tax &amp;#8212;
because all we care about is helping mining companies make as much money as
possible.  We don&amp;#8217;t don&amp;#8217;t care about other industries, especially not the
technology industry.  As if there&amp;#8217;s money to be made in technology anyway.
That&amp;#8217;s why we have no interest in building a modern broadband network that
would be a huge benefit to both consumers and businesses &amp;#8212; because that
would be a waste of&amp;nbsp;money.&lt;/p&gt;
&lt;p&gt;Those of you with ideas involving computers and the internet and technology
startups &amp;#8212; you&amp;#8217;re all in the wrong country.  We don&amp;#8217;t need any of that,
because we&amp;#8217;ve got mining!  Technology is what other countries do.  We just
do mining.  Australia just digs stuff out of the ground.  Then sells it to
other&amp;nbsp;countries.&lt;/p&gt;
&lt;p&gt;Now I realise some of you may be slightly confused, because this might seem
a bit different to what we in the Liberal Party promised before the
election.   We&amp;#8217;re sorry you misunderstood us, but you can&amp;#8217;t really blame us
for your ignorance and lack of cognitive ability.  After all, not everyone
can be as smart as the Liberal&amp;nbsp;Party.&lt;/p&gt;
&lt;p&gt;Before the election, when the Liberal Party promised Australia would get a
&amp;#8220;fast&amp;#8221; and &amp;#8220;affordable&amp;#8221; National Broadband Network &amp;#8220;sooner&amp;#8221;, what we really
meant was: &amp;#8220;fuck you, go work down the&amp;nbsp;mines&amp;#8221;.&lt;/p&gt;
&lt;p&gt;I don&amp;#8217;t know how the Australian public could have misinterpreted&amp;nbsp;that.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re confused, blame the liberal elite media.  I know I&amp;nbsp;do.&lt;/p&gt;
&lt;p&gt;It was their fault, all those stupid tech journalists, falsely getting your
hopes up by misrepresenting Liberal Party policies &amp;#8212; mainly by reporting
the Liberal Party actually had serious policies.  It should be pretty
obvious to everyone by now that we don&amp;#8217;t, and never did.  I&amp;#8217;m sure those
journalists won&amp;#8217;t make the same mistake&amp;nbsp;again.&lt;/p&gt;
&lt;p&gt;Those critics accusing me of hypocrisy and dishonesty just can&amp;#8217;t see the
big picture.  Our broadband policy is entirely consistent with our policy
framework in other areas.  For example, our policy for employment, which
forces the unemployed to go work down the mines.  And similarly the Liberal
Party&amp;#8217;s version of the National Disability Insurance Scheme (&lt;span class="caps"&gt;NDIS&lt;/span&gt;), which
will force disabled people to go work down the&amp;nbsp;mines.&lt;/p&gt;
&lt;p&gt;Then there&amp;#8217;s our education policy.  I know what you&amp;#8217;re probably thinking &amp;#8212;
that we&amp;#8217;re going to force children to go work down the mines.  Don&amp;#8217;t be
silly.  That would be cruel and uncaring.  The Australian Liberal Party is
all about kindness and goodwill.  That&amp;#8217;s why as part of our new education
policy, we will force children to work as Dickensian chimney sweeps.  That
will prepare them to go work down the mines when they grow up.  It&amp;#8217;s this
kind of forward thinking that distinguishes the Liberal Party from all that
profligate Labor scum.  Everyone in the Liberal Party should get
knighthoods for coming up with such progressive policies and being so in
touch with the&amp;nbsp;times.&lt;/p&gt;
&lt;p&gt;So with everyone busy working down the mines, it should be obvious to all
but the most obstinate nerds that no one will have time for the internet,
thereby making a modern broadband network completely&amp;nbsp;redundant.&lt;/p&gt;
&lt;p&gt;Not to mention that we will introduce all manner of draconian legislation
to severely restrict the digital rights and online freedoms of all
Australians, so that using the internet essentially becomes illegal.  Now
there&amp;#8217;s obviously no point investing billions of dollars to provide
everyone in the country with a universally fast and reliable internet
connection, if using the internet is against the law.  Because it soon will
be, now that the Liberal Party are in&amp;nbsp;power.&lt;/p&gt;
&lt;p&gt;So any Australians clamouring to &lt;a class="reference external" href="http://www.abc.net.au/technology/articles/2014/04/08/3980980.htm"&gt;download Game of Thrones&lt;/a&gt;
&amp;#8212; fuck off and go work down the mines.  There shall be no popular &lt;span class="caps"&gt;TV&lt;/span&gt; show
downloads for you while there&amp;#8217;s important mining work to be&amp;nbsp;done.&lt;/p&gt;
&lt;p&gt;I know that some of you who voted for us might think it somewhat harsh and
unfair that we&amp;#8217;re forcing &lt;em&gt;everyone&lt;/em&gt; to go work down the mines.  But what
you must understand is now that we have been elected by the people of
Australia, we have a mandate to do whatever the hell we want, regardless of
what we said before the election, and regardless of what you the people of
Australia actually want us to do.  That&amp;#8217;s how democracy&amp;nbsp;works.&lt;/p&gt;
&lt;p&gt;Don&amp;#8217;t bother reading the pointless ramblings of uninformed journalists and
bloggers.  Just accept the fact you elected us and now we will make you all
go work down the&amp;nbsp;mines.&lt;/p&gt;
&lt;p&gt;The sooner all these stupid journalists in the liberal media get on board
with my broadband plan &amp;#8212; and go work down the mines instead of writing
uninformed drivel &amp;#8212; the better it will be for all concerned.  After all,
they seem quite worked up about how badly I&amp;#8217;m screwing up broadband in this
country.  I honestly think they will be happier to forget about the whole
broadband thing and just go work down the&amp;nbsp;mines.&lt;/p&gt;
&lt;p&gt;I hope that clears things&amp;nbsp;up.&lt;/p&gt;
&lt;p&gt;Now stop reading this shit and go work down the&amp;nbsp;mines.&lt;/p&gt;
&lt;p&gt;Vote Liberal&amp;nbsp;bitches.&lt;/p&gt;
&lt;p&gt;Sincerely,&lt;/p&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;Sir Malcolm&lt;/div&gt;
&lt;div class="line"&gt;Duke of Wentworth&lt;/div&gt;
&lt;div class="line"&gt;Minister for Mis-communication&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related&amp;nbsp;Posts:&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/01/06/booze-to-the-node/"&gt;Booze To The&amp;nbsp;Node&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/02/national-broadband-cyber-futility/"&gt;National Broadband&amp;nbsp;Cyber-Futility&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/08/31/to-an-australia-that-cares-about-problems-of-the-rich/"&gt;To An Australia That&amp;nbsp;Cares&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="NBN"></category><category term="Broadband"></category><category term="Ranting"></category><category term="Attempted Humour"></category><category term="Politics"></category></entry><entry><title>Introducing VoidyBootstrap: A theme for Pelican</title><link href="http://www.voidynullness.net/blog/2014/03/30/introducing-voidy-bootstrap-pelican-theme/" rel="alternate"></link><published>2014-03-30T00:00:00+11:00</published><updated>2014-03-30T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2014-03-30:/blog/2014/03/30/introducing-voidy-bootstrap-pelican-theme/</id><summary type="html">&lt;p class="first last"&gt;A guide to using and customising the VoidyBootstrap&amp;nbsp;theme.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;So I kind of accidentally made a &lt;a class="reference external" href="http://getpelican.com"&gt;Pelican&lt;/a&gt;&amp;nbsp;theme.&lt;/p&gt;
&lt;p&gt;Didn’t mean to.  Really I&amp;nbsp;didn’t.&lt;/p&gt;
&lt;p&gt;At least, I honestly had no intention of &lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/03/19/voidy-bootstrap-prologue/"&gt;engaging in this kind of geekiness&lt;/a&gt;
when I started this&amp;nbsp;blog.&lt;/p&gt;
&lt;p&gt;I just wanted to write a blog.  A geek blog.  I set out with every
intention of ignoring the blogging technology and resisting any urges to
tinker with themes (or anything else) and just&amp;nbsp;write.&lt;/p&gt;
&lt;p&gt;I&amp;nbsp;failed.&lt;/p&gt;
&lt;p&gt;I just couldn’t&amp;nbsp;resist.&lt;/p&gt;
&lt;p&gt;A little change here.  Then a little change there.  And pretty soon I had
this monstrosity of a Bootstrap based Pelican theme on my&amp;nbsp;hands.&lt;/p&gt;
&lt;p&gt;Yes, another Bootstrap theme.  Because what the world really needs is more
websites with the now ubiquitous Bootstrap look.  But in my defence I have
tried to make this theme as easily customisable as possible.  Which is the
purpose of this blog post: to justify the existence of yet another
Bootstrap blog theme, by demonstrating how (hopefully) easy it is to use
the VoidyBootstrap theme to make a website with Pelican that doesn’t
obviously look like a Bootstrap&amp;nbsp;website.&lt;/p&gt;
&lt;p&gt;I feel I can&amp;#8217;t just unleash this (somewhat idiosyncratic) theme without at
least attempting to justify its existence (and idiosyncrasies).  So here&amp;nbsp;goes.&lt;/p&gt;
&lt;p&gt;When I started using &lt;a class="reference external" href="http://getpelican.com"&gt;Pelican&lt;/a&gt;
for this blog, despite my limited design skills, I managed to hack together
a custom theme that made use of Bootstrap 2 and Font Awesome 3.  When I
decided the time had come to upgrade the theme for Bootstrap 3 and Font
Awesome 4, I took a step back first to evaluate how I wanted to&amp;nbsp;proceed.&lt;/p&gt;
&lt;p&gt;I used the break of backward compatibility that Bootstrap 3 presented as an
opportunity to rethink my design and approach.  (And I use the word
&amp;#8220;design&amp;#8221; in this context very loosely.)  Upgrading the theme for Bootstrap
3 necessitated somewhat of a redesign (or at least a bit of work), so I
decided if I&amp;#8217;m going to do this, I only want to do have to do it&amp;nbsp;once.&lt;/p&gt;
&lt;p&gt;If I were to use the combination of Pelican and Bootstrap to create other
websites, I didn&amp;#8217;t want to have to start from&amp;nbsp;scratch.&lt;/p&gt;
&lt;p&gt;Of course, there&amp;#8217;s always the option of doing what seems be the standard
practice for creating a custom website with Pelican: looking through the
&lt;a class="reference external" href="https://github.com/getpelican/pelican-themes"&gt;official themes repository&lt;/a&gt;, selecting a theme with a
design that&amp;#8217;s closest to what you want to achieve, then hacking away with
wild abandon at the theme&amp;#8217;s &lt;a class="reference external" href="http://jinja.pocoo.org/"&gt;Jinja&lt;/a&gt;
templates and &lt;span class="caps"&gt;CSS&lt;/span&gt; to implement the desired&amp;nbsp;results.&lt;/p&gt;
&lt;p&gt;Which is all well and good: Pelican is a technical tool for a technical
audience who often have the skill and desire to do just that.  But while
there are a lot more themes available now than when I started playing with
Pelican, few seem to be designed with customisation in&amp;nbsp;mind.&lt;/p&gt;
&lt;p&gt;I thought it might be worthwhile to create a very basic Bootstrap theme,
with minimal additional styling, that would act as a reasonable starting
point for a Bootstrap website with Pelican that could be easily customised
&amp;#8212; so that it doesn&amp;#8217;t obviously look like a Bootstrap&amp;nbsp;website!&lt;/p&gt;
&lt;p&gt;The result is &lt;a class="reference external" href="http://www.voidynullness.net/page/voidy-bootstrap-pelican-theme/"&gt;VoidyBootstrap&lt;/a&gt;.
It&amp;#8217;s intended more as a &amp;#8220;meta-theme&amp;#8221; than a stand alone theme (although it
can certainly be used as a stand alone theme, and should work fine without
any customising).  It&amp;#8217;s a basic blog theme based on Bootstrap &amp;#8212; but one
that (hopefully) facilitates customisation as painlessly as&amp;nbsp;possible.&lt;/p&gt;
&lt;p class="introblock"&gt;&lt;strong&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt;, November 2014:&lt;/strong&gt; This post is about &lt;a class="reference external" href="https://github.com/robulouski/voidy-bootstrap/tree/v1.0"&gt;version 1&lt;/a&gt; of the
&lt;a class="reference external" href="http://www.voidynullness.net/page/voidy-bootstrap-pelican-theme/"&gt;VoidyBootstrap theme.&lt;/a&gt;
It&amp;#8217;s been reworked a bit since then, and many of the configuration settings
changed.  See the theme&amp;#8217;s
&lt;a class="reference external" href="https://github.com/robulouski/voidy-bootstrap/blob/master/README.rst"&gt;latest &lt;span class="caps"&gt;README&lt;/span&gt; file&lt;/a&gt; and
&lt;a class="reference external" href="https://github.com/robulouski/voidy-bootstrap/blob/master/CHANGES.rst"&gt;changelog&lt;/a&gt;
for&amp;nbsp;details.&lt;/p&gt;
&lt;p class="introblock"&gt;&lt;strong&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt;, June 2015:&lt;/strong&gt; While the concepts in the following sections are
still mostly relevant, the details have changed.  In version 2 of
VoidyBootstrap, many of the configuration
settings described below have been renamed.  There is a
&lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/06/01/voidy-bootstrap-pelican-theme-version-2/"&gt;summary of the major changes in this&amp;nbsp;post.&lt;/a&gt;&lt;/p&gt;
&lt;div class="section" id="voidybootstrap-quickstart"&gt;
&lt;h2&gt;VoidyBootstrap&amp;nbsp;Quickstart&lt;/h2&gt;
&lt;p&gt;While the main goal of VoidyBootstrap is easy customisation, I also wanted
to make things as easy as possible for those who just want a simple blog
theme and don&amp;#8217;t want to mess around with theme modifications.  So for
anyone happy with a fairly stock standard default Bootstrap look (at least
initially), the VoidyBootstrap theme gives you that with a minimum of
effort&amp;nbsp;(hopefully).&lt;/p&gt;
&lt;p&gt;The theme should work without any theme-specific options configured (I
think).  But as a bare minimum, you&amp;#8217;d probably want to configure the
following theme-specific settings in your &lt;tt class="docutils literal"&gt;pelicanconf.py&lt;/tt&gt;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
SITENAME = 'mywebsitename'
SITESUBTITLE = 'Sub-title that goes underneath site name in jumbotron.'

# Extra stylesheets, for bootstrap overrides or additional styling.
STYLESHEETS = (&amp;quot;pygment.css&amp;quot;, &amp;quot;voidybootstrap.css&amp;quot;,)

# Use the default sharing button implementation.
CUSTOM_ARTICLE_SHARING = &amp;quot;sharing.html&amp;quot;
CUSTOM_ARTICLE_SCRIPTS = &amp;quot;sharing_scripts.html&amp;quot;
&lt;/pre&gt;
&lt;p&gt;The following settings from the default Pelican theme are&amp;nbsp;supported:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;SITEURL&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;FEED_DOMAIN&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;FEED_ALL_ATOM&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;FEED_ALL_RSS&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;DISQUS_SITENAME&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;GOOGLE_ANALYTICS&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Configure those that you require (usually in &lt;tt class="docutils literal"&gt;publishconf.py&lt;/tt&gt;).&lt;/p&gt;
&lt;p&gt;(See &lt;a class="reference external" href="https://github.com/robulouski/voidy-bootstrap/blob/v1.0/README.rst"&gt;the theme&amp;#8217;s &lt;span class="caps"&gt;README&lt;/span&gt;&lt;/a&gt;
for a more detailed configuration&amp;nbsp;example.)&lt;/p&gt;
&lt;p&gt;And that&amp;#8217;s pretty much it.  With that you get a blog layout that looks
something like&amp;nbsp;this:&lt;/p&gt;
&lt;img alt="Default VoidyBootstrap screenshot" src="http://www.voidynullness.net/images/voidybootstrap_default.png" /&gt;
&lt;p&gt;What&amp;#8217;s provided by default is a responsive 2 column layout that stacks
vertically on small screens.  There is a navbar and Jumbotron at the top,
and the sidebar contains category links and a tag&amp;nbsp;cloud.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="customising-styles"&gt;
&lt;h2&gt;Customising&amp;nbsp;Styles&lt;/h2&gt;
&lt;p&gt;You may notice the theme&amp;#8217;s &lt;tt class="docutils literal"&gt;static/css&lt;/tt&gt; directory is relatively bare.
This is intentional.  By default, all the &lt;span class="caps"&gt;CSS&lt;/span&gt; and Javascript files required by
the theme (Bootstrap, Font Awesome, JQuery, etc) are downloaded from&amp;nbsp;CDNs.&lt;/p&gt;
&lt;p&gt;So by default the only styling provided by this theme is from a standard
&lt;tt class="docutils literal"&gt;bootstrap.min.css&lt;/tt&gt; downloaded via a &lt;span class="caps"&gt;CDN&lt;/span&gt;.  And nothing else &amp;#8212; no &lt;span class="caps"&gt;CSS&lt;/span&gt;
files from the theme&amp;#8217;s &lt;tt class="docutils literal"&gt;static/css&lt;/tt&gt; directory are used, unless configured
otherwise (which I&amp;#8217;ll explain in a&amp;nbsp;moment).&lt;/p&gt;
&lt;p&gt;VoidyBootstrap provides two ways to customise the theme&amp;#8217;s unashamedly
default Bootstrap look (without having to resort to hacking at the supplied
templates or &lt;span class="caps"&gt;CSS&lt;/span&gt; files).  These methods can be used individually or in
conjunction with each&amp;nbsp;other.&lt;/p&gt;
&lt;p&gt;The first is the &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;STYLESHEETS&lt;/span&gt;&lt;/tt&gt; setting.  This is an array for specifying
any additional stylesheet files.  As mentioned above, by default the theme
grabs what it need from CDNs and doesn&amp;#8217;t reference any &lt;span class="caps"&gt;CSS&lt;/span&gt; files in
&lt;tt class="docutils literal"&gt;static/css&lt;/tt&gt;.  The &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;STYLESHEETS&lt;/span&gt;&lt;/tt&gt; setting is provided to enable any
additional (local) &lt;span class="caps"&gt;CSS&lt;/span&gt; files to be explicitly configured.  It should be set to a
list of &lt;span class="caps"&gt;CSS&lt;/span&gt; files present in the theme&amp;#8217;s &lt;tt class="docutils literal"&gt;static/css&lt;/tt&gt; directory.&lt;/p&gt;
&lt;p&gt;All the &lt;span class="caps"&gt;CSS&lt;/span&gt; files in the &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;STYLESHEETS&lt;/span&gt;&lt;/tt&gt; array will be referenced by the
theme&amp;#8217;s &lt;tt class="docutils literal"&gt;base.html&lt;/tt&gt; template after the main Bootstrap &lt;span class="caps"&gt;CSS&lt;/span&gt; file, so this
provides a way to override the default Bootstrap styles.  Therefore a
simple way to provide your own styling on top of this theme is to add your
own &lt;span class="caps"&gt;CSS&lt;/span&gt; files to the &lt;tt class="docutils literal"&gt;static/css&lt;/tt&gt; directory, and add their filenames to
the &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;STYLESHEETS&lt;/span&gt;&lt;/tt&gt; array in &lt;tt class="docutils literal"&gt;pelicanconf.py&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;The theme&amp;#8217;s &lt;tt class="docutils literal"&gt;static/css&lt;/tt&gt; directory contains a sample &lt;span class="caps"&gt;CSS&lt;/span&gt; file
(&lt;tt class="docutils literal"&gt;voidybootstrap.css&lt;/tt&gt;), which can be used as a starting point.  It
provides a minimal set of styling (mostly just spacing and whitespace&amp;nbsp;changes).&lt;/p&gt;
&lt;p&gt;Of course, because &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;STYLESHEETS&lt;/span&gt;&lt;/tt&gt; is an array, any number of &lt;span class="caps"&gt;CSS&lt;/span&gt; files can
be included, and it can be used to bring in any additional custom styling
(not just Bootstrap&amp;nbsp;overrides).&lt;/p&gt;
&lt;p&gt;The second method of customising the theme&amp;#8217;s default look is the
&lt;tt class="docutils literal"&gt;MAIN_LOCAL_STYLESHEET&lt;/tt&gt; setting.  This configuration option allows the
standard Bootstrap &lt;span class="caps"&gt;CSS&lt;/span&gt; file to be replaced with a customised one.  It&amp;#8217;s
provided to make it easy to do things like integrate a customised
Bootstrap file generated by the &lt;a class="reference external" href="http://getbootstrap.com/customize/"&gt;Bootstrap customizer&lt;/a&gt;, or one built using an
&lt;a class="reference external" href="http://www.helloerik.com/bootstrap-3-less-workflow-tutorial"&gt;advanced Less workflow&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Simply place the customised Bootstrap &lt;span class="caps"&gt;CSS&lt;/span&gt; file in the theme&amp;#8217;s
&lt;tt class="docutils literal"&gt;static/css&lt;/tt&gt; directory, and in &lt;tt class="docutils literal"&gt;pelicanconf.py&lt;/tt&gt; set
&lt;tt class="docutils literal"&gt;MAIN_LOCAL_STYLESHEET&lt;/tt&gt; to the&amp;nbsp;filename.&lt;/p&gt;
&lt;p&gt;(If the &lt;tt class="docutils literal"&gt;MAIN_LOCAL_STYLESHEET&lt;/tt&gt; option is not set, the standard
&lt;tt class="docutils literal"&gt;bootstrap.min.css&lt;/tt&gt; will be used &amp;#8212; from a &lt;span class="caps"&gt;CDN&lt;/span&gt; &amp;#8212; as described&amp;nbsp;above.)&lt;/p&gt;
&lt;p&gt;With the combination of &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;STYLESHEETS&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;MAIN_LOCAL_STYLESHEET&lt;/tt&gt;
settings, there&amp;#8217;s the flexibility to accommodate different degrees of
customisation and various Bootstrap workflows.  For example, to incorporate
&lt;span class="caps"&gt;CSS&lt;/span&gt; from one of the &lt;a class="reference external" href="http://bootswatch.com/"&gt;Bootswatch&lt;/a&gt; themes, it
should be a relatively straightforward matter of downloading the &lt;span class="caps"&gt;CSS&lt;/span&gt; files,
placing them in &lt;tt class="docutils literal"&gt;static/css&lt;/tt&gt; and configuring the &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;STYLESHEETS&lt;/span&gt;&lt;/tt&gt; and
&lt;tt class="docutils literal"&gt;MAIN_LOCAL_STYLESHEET&lt;/tt&gt; settings in &lt;tt class="docutils literal"&gt;pelicanconf.py&lt;/tt&gt; as&amp;nbsp;appropriate.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="adding-custom-content"&gt;
&lt;h2&gt;Adding Custom&amp;nbsp;Content&lt;/h2&gt;
&lt;p&gt;Conceptually, Pelican themes are quite simple (although as is often the
case, the devil is in the&amp;nbsp;details).&lt;/p&gt;
&lt;p&gt;A Pelican theme usually has two directories: &lt;tt class="docutils literal"&gt;static&lt;/tt&gt; and
&lt;tt class="docutils literal"&gt;templates&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;static&lt;/tt&gt; directory is where any &lt;span class="caps"&gt;CSS&lt;/span&gt; or image files required by the
theme will go (along with any other static&amp;nbsp;assets).&lt;/p&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;templates&lt;/tt&gt; directory will usually contain &lt;span class="caps"&gt;HTML&lt;/span&gt; files, which are
actually &lt;a class="reference external" href="http://jinja.pocoo.org/"&gt;Jinja2&lt;/a&gt;&amp;nbsp;templates.&lt;/p&gt;
&lt;p&gt;Pelican requires &lt;a class="reference external" href="http://docs.getpelican.com/en/latest/themes.html"&gt;certain templates that must be present&lt;/a&gt;.
These in turn can include other templates.  To help keep things organised,
VoidyBootstrap has all templates included from the core templates in an
&lt;tt class="docutils literal"&gt;includes&lt;/tt&gt; subdirectory.&lt;/p&gt;
&lt;p&gt;Like with any other Pelican theme, you are of course free to modify any of
the theme&amp;#8217;s templates to implement a different layout and add custom
content.  But if you&amp;#8217;re happy to work with the layout the theme provides,
and all you want to do is add a few sections of custom content here and
there, then VoidyBootstrap provides a potentially easier/neater way to do&amp;nbsp;this.&lt;/p&gt;
&lt;p&gt;VoidyBootstrap takes advantage of the Jinja &amp;#8220;include&amp;#8221; statement with the
&amp;#8220;ignore missing&amp;#8221; option.  At strategic points in the theme&amp;#8217;s layout, it
attempts to include &amp;#8220;optional&amp;#8221; template fragments (i.e. templates which are
used if they are there, but the theme works fine without them, and they are
not supplied by default).  Therefore it&amp;#8217;s possible to add chunks of
arbitrary custom content by simply creating these optional template files
in the theme&amp;#8217;s &lt;tt class="docutils literal"&gt;templates/includes&lt;/tt&gt; directory.&lt;/p&gt;
&lt;p&gt;This is all in an attempt to cater for some common customisation needs.  Of
course, no one theme can anticipate every design need.  So for things like
extensive layout changes, modifying the templates is the only option.  But I
wanted to provide a middle ground &amp;#8212; I wanted VoidyBootstrap to provide
ways to make simple customisations to content and appearance without having
to delve too deep into Pelican&amp;#8217;s theme template&amp;nbsp;system.&lt;/p&gt;
&lt;p&gt;The diagram below gives an overview of the the templates used to render an
article page.  The dashed boxes represent these optional&amp;nbsp;templates.&lt;/p&gt;
&lt;img alt="Outline of the VoidyBootstrap layout" src="http://www.voidynullness.net/images/voidybootstrap_layout.png" /&gt;
&lt;p&gt;For example, let&amp;#8217;s say that at the top of the sidebar of your website you&amp;#8217;d
like to have an &amp;#8220;About&amp;#8221; section.  You could of course just edit
&lt;tt class="docutils literal"&gt;sidebar.html&lt;/tt&gt;.  But adding custom content to the sidebar would be a
fairly common requirement when creating a website, so VoidyBootstrap
provides some &amp;#8220;hooks&amp;#8221; to make this a bit easier (not just easier to
implement, but also easier to keep your customisations separate from the
theme&amp;#8217;s templates, for those that might care about&amp;nbsp;that).&lt;/p&gt;
&lt;p&gt;Notice in the above diagram that &lt;tt class="docutils literal"&gt;sidebar.html&lt;/tt&gt; provides two optional
templates: &lt;tt class="docutils literal"&gt;sidebar_top.html&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;sidebar_bottom.html&lt;/tt&gt;.  To have your
custom content appear at the top of the sidebar, create a template with the
required content in the &lt;tt class="docutils literal"&gt;includes&lt;/tt&gt; directory called &lt;tt class="docutils literal"&gt;sidebar_top.html&lt;/tt&gt;.
The contents of that template fragment will then appear at the top of the&amp;nbsp;sidebar.&lt;/p&gt;
&lt;p&gt;As another example, if you decide you&amp;#8217;d like a navigation element at the
top of article pages, you could place the &lt;span class="caps"&gt;HTML&lt;/span&gt; for this navigation element
in a template called &lt;tt class="docutils literal"&gt;article_top.html&lt;/tt&gt;.  Want to add a copyright message
to the footer?  Just put it in a template called &lt;tt class="docutils literal"&gt;footer.html&lt;/tt&gt; and it&amp;#8217;ll
be automatically&amp;nbsp;included.&lt;/p&gt;
&lt;p&gt;See the &amp;#8220;Optional Templates&amp;#8221; section in the &lt;a class="reference external" href="https://github.com/robulouski/voidy-bootstrap/blob/master/README.rst"&gt;&lt;span class="caps"&gt;README&lt;/span&gt;&lt;/a&gt;
for a list of all the available optional&amp;nbsp;templates.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="overriding-existing-content"&gt;
&lt;h2&gt;Overriding Existing&amp;nbsp;Content&lt;/h2&gt;
&lt;p&gt;In addition to being able to add new content, the VoidyBootstrap theme also
allows some existing sections of content to be swapped out by a custom
implementation.  It&amp;#8217;s an attempt to cater for the case where the theme
satisfies most design needs&amp;#8230;except for that one&amp;nbsp;thing&amp;#8230;&lt;/p&gt;
&lt;p&gt;As an example, let&amp;#8217;s once again consider what would be a fairly common
requirement: customising the sidebar.  The default sidebar provided by the
theme displays social links (if configured), categories and a tag cloud.
The previous section described a way of adding custom sidebar content in
addition to what&amp;#8217;s there by default.  But what if you don&amp;#8217;t want categories
and a tag cloud in the sidebar?  What if you decide that&amp;#8217;s completely
inappropriate for your website?  What if instead you want to have a sidebar
full of cat pictures?  Well the VoidyBootstrap theme has got you covered.
It won&amp;#8217;t judge you for what you decide to put in your website&amp;#8217;s sidebar,
and in fact will gladly facilitate a completely customised sidebar.  Simply
create your glorious feline sidebar template and put it in the theme&amp;#8217;s
&lt;tt class="docutils literal"&gt;templates/includes&lt;/tt&gt; directory (or subdirectory thereof).  You can call
it whatever you want (as long it doesn&amp;#8217;t conflict with anything already
there, or the name of an optional template).  Let&amp;#8217;s say you&amp;#8217;ve called the
new template &lt;tt class="docutils literal"&gt;cats_sidebar.html&lt;/tt&gt;, and placed it in a subdirectory called
&lt;tt class="docutils literal"&gt;custom&lt;/tt&gt;.  To enable your custom cat pic sidebar, in your
&lt;tt class="docutils literal"&gt;pelicanconf.py&lt;/tt&gt; file add the following&amp;nbsp;line:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
CUSTOM_SIDEBAR = &amp;quot;custom/cats_sidebar.html&amp;quot;
&lt;/pre&gt;
&lt;p&gt;This will result in the theme&amp;#8217;s implementation of the sidebar being
completely replaced with whatever is in &lt;tt class="docutils literal"&gt;cats_sidebar.html&lt;/tt&gt;.  (Goodbye
tag cloud, hello&amp;nbsp;kitties!)&lt;/p&gt;
&lt;p&gt;VoidyBootstrap provides a number of these &amp;#8220;Custom Includes&amp;#8221; that allow parts of
the theme to be overridden by an alternative implementation.  (See the
&amp;#8220;Custom Includes&amp;#8221; section in the &lt;a class="reference external" href="https://github.com/robulouski/voidy-bootstrap/blob/master/README.rst"&gt;&lt;span class="caps"&gt;README&lt;/span&gt;&lt;/a&gt;
for&amp;nbsp;details.)&lt;/p&gt;
&lt;p&gt;As another example, if you think the theme&amp;#8217;s article headings are an
abomination against all that is good and holy in web design, you&amp;#8217;re able to
supply your own.  Not only that, if you want you can supply different
article heading templates for index pages and article pages, thereby
allowing for differentiation in layout and style.  Simply create templates
for custom article headings that please your aesthetic sensibilities, then
set the &lt;tt class="docutils literal"&gt;CUSTOM_ARTICLE_HEADER&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;CUSTOM_ARTICLE_HEADER_INDEX&lt;/tt&gt;
settings appropriately in &lt;tt class="docutils literal"&gt;pelicanconf.py&lt;/tt&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;There&amp;#8217;s more to the VoidyBootstrap theme than what&amp;#8217;s been mentioned here.
While being a deliberately minimal theme as far as design goes, it aims to
be fairly feature complete in every other respect.  It&amp;#8217;s a modern Pelican
blog theme, with hopefully all the features you&amp;#8217;d expect in a modern blog
theme, and even some surprisingly nice features you might not expect (like
custom metadata tags, &amp;#8220;featured images&amp;#8221;, Open Graph, Twitter Summary Card
metadata, and&amp;nbsp;more!).&lt;/p&gt;
&lt;p&gt;But it&amp;#8217;s main reason for existing are the customisation features discussed
in this post.  It&amp;#8217;s a Pelican theme based on Bootstrap that&amp;#8217;s designed to
be customised.  To that extent, it tries to anticipate and facilitate a
range of customisation needs.  How appropriate the theme is for your needs
will most likely depend on how you feel about usefulness of these
customisation abilities.  (Or how much you like the default Bootstrap&amp;nbsp;look.)&lt;/p&gt;
&lt;div class="section" id="see-also"&gt;
&lt;h3&gt;See&amp;nbsp;Also:&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/page/voidy-bootstrap-pelican-theme/"&gt;VoidyBootstrap project&amp;nbsp;page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/robulouski/voidy-bootstrap"&gt;VoidyBootstrap on&amp;nbsp;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h3&gt;Related&amp;nbsp;Posts:&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/06/01/voidy-bootstrap-pelican-theme-version-2/"&gt;What&amp;#8217;s new in VoidyBootstrap version&amp;nbsp;2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/03/19/voidy-bootstrap-prologue/"&gt;The winding road to a workable writing&amp;nbsp;workflow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="Pelican"></category><category term="Python"></category><category term="VoidyBootstrap"></category></entry><entry><title>The winding road to a workable writing workflow</title><link href="http://www.voidynullness.net/blog/2014/03/19/voidy-bootstrap-prologue/" rel="alternate"></link><published>2014-03-19T00:00:00+11:00</published><updated>2014-03-19T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2014-03-19:/blog/2014/03/19/voidy-bootstrap-prologue/</id><summary type="html">&lt;p&gt;It&amp;#8217;s hard to imagine now that early incarnations of this blog started as a
Wordpress&amp;nbsp;site.&lt;/p&gt;
&lt;p&gt;Not that I have anything against Wordpress itself, as such.  It&amp;#8217;s just that
I&amp;#8217;ve developed a deep dislike for &lt;span class="caps"&gt;PHP&lt;/span&gt; (the underlying technology used to
develop Wordpress).
&lt;a class="reference external" href="https://wiki.theory.org/YourLanguageSucks#PHP_sucks_because"&gt;And&lt;/a&gt;
&lt;a class="reference external" href="http://www.codinghorror.com/blog/2008/05/php-sucks-but-it-doesnt-matter.html"&gt;I&amp;#8217;m&lt;/a&gt;
&lt;a class="reference external" href="http://www.phpwtf.org/"&gt;not&lt;/a&gt;
&lt;a class="reference external" href="http://me.veekun.com/blog/2012/04/09/php-a-fractal-of-bad-design/"&gt;the&lt;/a&gt;
&lt;a class="reference external" href="http://alokmenghrajani.github.com/wtf/php.html"&gt;only&lt;/a&gt;
&lt;a class="reference external" href="http://phpsadness.com/"&gt;one&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;My brief experiences with &lt;span class="caps"&gt;PHP&lt;/span&gt; were enough to realise it&amp;#8217;s pretty damn
&lt;a class="reference external" href="http://www.jwz.org/blog/2011/05/computational-feces/"&gt;horrible&lt;/a&gt;.
I feel I know enough about &lt;span class="caps"&gt;PHP&lt;/span&gt; to know I never want to …&lt;/p&gt;</summary><content type="html">&lt;p&gt;It&amp;#8217;s hard to imagine now that early incarnations of this blog started as a
Wordpress&amp;nbsp;site.&lt;/p&gt;
&lt;p&gt;Not that I have anything against Wordpress itself, as such.  It&amp;#8217;s just that
I&amp;#8217;ve developed a deep dislike for &lt;span class="caps"&gt;PHP&lt;/span&gt; (the underlying technology used to
develop Wordpress).
&lt;a class="reference external" href="https://wiki.theory.org/YourLanguageSucks#PHP_sucks_because"&gt;And&lt;/a&gt;
&lt;a class="reference external" href="http://www.codinghorror.com/blog/2008/05/php-sucks-but-it-doesnt-matter.html"&gt;I&amp;#8217;m&lt;/a&gt;
&lt;a class="reference external" href="http://www.phpwtf.org/"&gt;not&lt;/a&gt;
&lt;a class="reference external" href="http://me.veekun.com/blog/2012/04/09/php-a-fractal-of-bad-design/"&gt;the&lt;/a&gt;
&lt;a class="reference external" href="http://alokmenghrajani.github.com/wtf/php.html"&gt;only&lt;/a&gt;
&lt;a class="reference external" href="http://phpsadness.com/"&gt;one&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;My brief experiences with &lt;span class="caps"&gt;PHP&lt;/span&gt; were enough to realise it&amp;#8217;s pretty damn
&lt;a class="reference external" href="http://www.jwz.org/blog/2011/05/computational-feces/"&gt;horrible&lt;/a&gt;.
I feel I know enough about &lt;span class="caps"&gt;PHP&lt;/span&gt; to know I never want to go anywhere near &lt;span class="caps"&gt;PHP&lt;/span&gt;
ever again, if I can help it.  That thankfully short but deeply
unsatisfying dalliance with &lt;span class="caps"&gt;PHP&lt;/span&gt; sent me on a search for a better match my
web development desires, culminating in a much more rewarding tryst with
Django, and occasional flirtations with&amp;nbsp;Flask.&lt;/p&gt;
&lt;p&gt;So it was perhaps strange that I initially considered using Wordpress for a
personal geek blog.  But there was some method to my madness: I actually
hoped the underlying ugliness of &lt;span class="caps"&gt;PHP&lt;/span&gt; might, somewhat paradoxically, be a
benefit in this&amp;nbsp;case.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve started blogs before, with all the best intentions of regularly
writing something (anything!), but they all went no where, languishing for
months without updates, then years, before eventually being scraped and
taken down.  But I think in those initial failed attempts at blogging I did
learn a few things about myself, and the strange love-hate relationship I
have with the writing&amp;nbsp;process.&lt;/p&gt;
&lt;p&gt;I realised one of the side effects of being prone to a sometimes
counter-productive combination of procrastination, perfectionism and nerdy
proclivities is that it&amp;#8217;s all too easy to be distracted by things that are
not actually writing.  Like the blogging technology itself. Or the blog
theme. Or some other technical detail. Which means a lot of technical
tinkering happens, but very little writing gets&amp;nbsp;done.&lt;/p&gt;
&lt;p&gt;Not that I ever had any great ambitions as a blogger.  When approaching
blogging, I have set myself the ultra-low benchmark of just writing for the
sake of writing.  Who knows, maybe if I write enough, I might occasionally
write something worthwhile.  One day.  Eventually.  And if nothing else,
there might (hopefully) be some purely personal benefit in taking the
random thoughts floating around in the chaos of my mind, imposing some
semblance of order and writing them&amp;nbsp;down.&lt;/p&gt;
&lt;p&gt;Regardless of whether anyone reads&amp;nbsp;them.&lt;/p&gt;
&lt;p&gt;The main thing is just to&amp;nbsp;write.&lt;/p&gt;
&lt;p&gt;Because a blog without some attempt at decent content is surely pointless.
Unless you&amp;#8217;re an internet marketer, in which case apparently content is
irrelevant and it&amp;#8217;s all about &lt;span class="caps"&gt;SEO&lt;/span&gt; tricks and link&amp;nbsp;building.&lt;/p&gt;
&lt;p&gt;But I still cling to some semblance old school ideals about aiming for at
least half decent (original) content. So this time I was determined to
start a technical blog and keep it going.  Just my own little place on the
interweb to call my own.  A place to air out my half baked ideas.  Which
means actually writing&amp;nbsp;regularly.&lt;/p&gt;
&lt;p&gt;I actually hoped that using Wordpress would enable me to get more writing
done simply as a virtue of my complete lack of technical interest in
Wordpress as software, and complete disdain for &lt;span class="caps"&gt;PHP&lt;/span&gt; as a programming
environment. I was somewhat naively hoping this would mean I&amp;#8217;d be less
tempted to tinker with the technology in any way, which in theory would
mean I&amp;#8217;d be less likely to get distracted from&amp;nbsp;writing.&lt;/p&gt;
&lt;p&gt;The idea was just to use Wordpress as a tool, a means to an end.  All I had
to do was set it up, configure it, select a theme I could live with without
having to modify it in any way, and start&amp;nbsp;writing.&lt;/p&gt;
&lt;p&gt;Which is what I did.  Although that selecting a theme thing took a really
long time.  The great thing about a mature blogging platform like Wordpress
is that there are a lot of themes to choose from.  The downside about a
mature blogging platform like Wordpress is that there are a lot of themes
to choose from.  An option paralysis inducing amount.  It&amp;#8217;s hard enough to
make a decision amongst so many different choices.  It was even harder
since I&amp;#8217;d given myself the restriction that I was just going to use the
theme as is &amp;#8212; I was not going to waste time customising it in any way.
Because customising a Wordpress theme might mean being exposed to the
horrors of &lt;span class="caps"&gt;PHP&lt;/span&gt;, which is something I wanted to avoid at all&amp;nbsp;cost&lt;/p&gt;
&lt;p&gt;I should have known that was never going to happen.  I set up Wordpress and
finally decided on a theme.  But I could not resist the urge to customise.
As usual, it started by changing a thing a little thing here and there.
Then before I knew it, I was knee deep in the guts of Wordpress, writing
&lt;span class="caps"&gt;PHP&lt;/span&gt;&amp;nbsp;code.&lt;/p&gt;
&lt;p&gt;It was then that I decided Wordpress was not for me.  If I was going to
tinker, I wanted to tinker with technology I actually enjoyed tinkering
with.  So I scrapped the Wordpress idea and went looking for&amp;nbsp;alternatives.&lt;/p&gt;
&lt;p&gt;I found many viable alternatives in the nascent world of static site
generators that were beginning to appear.  Thankfully, by this time,
dynamically generated, database backed blogs were no longer the only
blogging game in town.  By now, it seems many bloggers (especially geek
bloggers) had realised that in some cases, like single author blogs not
frequently updated and written by technically adept command line junkies,
running a database and dynamically generating rarely changed pages for each
request was somewhat redundant.  Not to mention that for those of us
comfortable using powerful text editors like Emacs (and even vi), typing
blog entries into a tiny text box on a web page is not exactly an optimal&amp;nbsp;workflow.&lt;/p&gt;
&lt;p&gt;So there were lots of static site generators appearing.  These make a lot
of sense for technical blogs.  Writing entries as text files in Markdown or
reStructuredText format, and tracking them using a version control tool, is
a familiar workflow for developers.  And statically generating the blog
simplifies and speeds things up&amp;nbsp;immensely.&lt;/p&gt;
&lt;p&gt;I explored what was available at the time, and the most mature at that
point seemed to be Octopress.  However, I&amp;#8217;m not a Ruby guy.  Yet.  I like
what I&amp;#8217;ve seen of Ruby so far, and have every intention of exploring it
further at some point, but for now I&amp;#8217;m still having a lot of fun getting
better acquainted with&amp;nbsp;Python.&lt;/p&gt;
&lt;p&gt;Octopress seemed to be exactly what I wanted though, with some reasonably
good themes to choose from.  And once again, the fact the blogging engine
used technology I wasn&amp;#8217;t very familiar with was potentially a benefit, in
that I was less likely to distract myself from writing by tinkering with
it.  The downside of not being familiar with the underlying technology,
however, is that the learning curve is much steeper, and any problems take
much longer to solve.  This in addition to the overhead of having to
install and maintain a Ruby environment which I otherwise have no need&amp;nbsp;for.&lt;/p&gt;
&lt;p&gt;So I explored further, and found there were a few Python static site
generators around, although none seemed quite as mature at Octopress.  A
Python static site generator would be perfect, since for starters, as a
Python developer, I was already likely to have a Python development
environment set up and good to&amp;nbsp;go.&lt;/p&gt;
&lt;p&gt;The three obvious choices at the time came down to
&lt;a class="reference external" href="http://ringce.com/hyde"&gt;Hyde&lt;/a&gt;,
&lt;a class="reference external" href="http://www.blogofile.com/"&gt;BlogOFile&lt;/a&gt;, and
&lt;a class="reference external" href="http://getpelican.com"&gt;Pelican&lt;/a&gt;.
(I realise there&amp;#8217;s a lot more now.)  I ended up choosing Pelican: I found
it fairly straightforward to set up a blog, it looked like it was being
actively maintained, and there was a reasonable selection of themes&amp;nbsp;available.&lt;/p&gt;
&lt;p&gt;But of course, there was no theme I was completely happy&amp;nbsp;with.&lt;/p&gt;
&lt;p&gt;Fortunately it wasn&amp;#8217;t too hard to figure out how Pelican themes work, and
hack together something more or less to my liking.  What I ended up with
was a hacky custom theme based around Bootstrap 2 and using Font Awesome 3
for icons.  It might not have been too pretty, either under the hood or
from a design point of view, but it looked more or less like I thought a
blog should look, with all the common features I thought a modern blog
(especially a technical blog) should have (sidebar, categories, tag cloud,
decent navigation, etc).  After much tinkering I got the theme to the point
where I was happy enough to leave it alone and just&amp;nbsp;write.&lt;/p&gt;
&lt;p&gt;Then Bootstrap 3 was&amp;nbsp;released.&lt;/p&gt;
&lt;p&gt;Bootstrap 3 deliberately broke backward compatibility with Bootstrap&amp;nbsp;2.&lt;/p&gt;
&lt;p&gt;This meant a substantial amount of tinkering would be required to upgrade
my custom theme.  One of the downsides of tinkering, and why I initially
resisted the urge to customise things.  Because this is what tends to happen
once you start tinkering with technology.  Things change, things break,
things need upgrading.  These things take time.  Time possibly better spent
writing, which is after all the point of a blog (unless you&amp;#8217;re an internet&amp;nbsp;marketer).&lt;/p&gt;
&lt;p&gt;But I resisted the urge to tinker, and stuck with my custom Bootstrap 2
theme for the time&amp;nbsp;being.&lt;/p&gt;
&lt;p&gt;Then Font Awesome 4 was released.  It also broke compatibility with the
previous&amp;nbsp;version.&lt;/p&gt;
&lt;p&gt;So eventually I decided to set aside some time to work on my hacky custom
theme, and update if for both Bootstrap 3 and Font Awesome 4.  While I was
at it, I figured this would be a good time to clean things up a bit, and
try to impose some order on my previously hacky&amp;nbsp;ways.&lt;/p&gt;
&lt;p&gt;The result is &lt;a class="reference external" href="http://www.voidynullness.net/page/voidy-bootstrap-pelican-theme/"&gt;VoidyBootstrap.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A deliberately generic blog theme for Pelican based on Bootstrap 3, but
designed to make it easy (or at least easier) to create a customised (and
less generic) look and&amp;nbsp;feel.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s a theme that I created when I should have been writing.  A theme born
of&amp;nbsp;procrastination.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m not sure if that&amp;#8217;s a sign of my lack of discipline, or testament to my
geek&amp;nbsp;cred.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s kind of ironic that I started this blog with every intention of just
focusing on the writing part of blogging, but ended up spending a lot of
time messing around with the blogging engine and front-end frameworks, and
ended up creating a possibly over complicated blog theme in the&amp;nbsp;process.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m not sure if there&amp;#8217;s a moral of the story to be found in there
somewhere.  Or a point to all this rambling.  Maybe it&amp;#8217;s just that hackers
are gonna&amp;nbsp;hack.&lt;/p&gt;
&lt;p&gt;Maybe it was naive of me to think that I would be able to blog without
getting side tracked by blogging technology and themes.  Maybe I should
just accept the fact that as a geek, if I&amp;#8217;m going to be blogging, I&amp;#8217;m not
just going to be writing &amp;#8212; I&amp;#8217;m inevitably going to be tinkering with
technical things as well.  Because that&amp;#8217;s just&amp;nbsp;me.&lt;/p&gt;
&lt;p&gt;Perhaps is just the nature of the geek&amp;nbsp;beast.&lt;/p&gt;
&lt;p&gt;And perhaps if nothing else, it shows that amongst &lt;span class="caps"&gt;PHP&lt;/span&gt;&amp;#8217;s many failings,
it&amp;#8217;s also useless as a psychological ploy to avoid&amp;nbsp;procrastination.&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related&amp;nbsp;Posts:&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/03/30/introducing-voidy-bootstrap-pelican-theme/"&gt;Introducing VoidyBootstrap: A theme for&amp;nbsp;Pelican&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2015/06/01/voidy-bootstrap-pelican-theme-version-2/"&gt;What&amp;#8217;s new in VoidyBootstrap version&amp;nbsp;2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="Pelican"></category><category term="Python"></category><category term="VoidyBootstrap"></category></entry><entry><title>Upgrading to Pelican 3.3</title><link href="http://www.voidynullness.net/blog/2014/01/23/upgrading-pelican-3-3/" rel="alternate"></link><published>2014-01-23T00:00:00+11:00</published><updated>2014-01-23T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2014-01-23:/blog/2014/01/23/upgrading-pelican-3-3/</id><summary type="html">&lt;p&gt;Maybe it&amp;#8217;s just me, or maybe it comes with the territory of being a geek
with a blog, but seems I often have to fight the urge to tinker with the
blogging technology I&amp;#8217;m using &amp;#8212; in my case &lt;a class="reference external" href="http://getpelican.com/"&gt;Pelican&lt;/a&gt; &amp;#8212; in order to get any actual blogging&amp;nbsp;done.&lt;/p&gt;
&lt;p&gt;Initially, the tinkering took the form of endlessly tweaking the custom
theme I&amp;#8217;d hacked together based on Bootstrap 2.  Eventually the theme got
to the point where I was happy …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Maybe it&amp;#8217;s just me, or maybe it comes with the territory of being a geek
with a blog, but seems I often have to fight the urge to tinker with the
blogging technology I&amp;#8217;m using &amp;#8212; in my case &lt;a class="reference external" href="http://getpelican.com/"&gt;Pelican&lt;/a&gt; &amp;#8212; in order to get any actual blogging&amp;nbsp;done.&lt;/p&gt;
&lt;p&gt;Initially, the tinkering took the form of endlessly tweaking the custom
theme I&amp;#8217;d hacked together based on Bootstrap 2.  Eventually the theme got
to the point where I was happy enough with it to actually leave it alone
and get some writing&amp;nbsp;done.&lt;/p&gt;
&lt;p&gt;Then Bootstrap 3 came out, deliberately breaking backward compatibility
with version 2, which meant upgrading my theme would require substantial
tinkering.  But I resisted, and stayed with the Bootstrap 2 theme for the
time being.  Then Pelican 3.3 came out, and once again I resisted
upgrading, just in case I&amp;#8217;d have to deal with time-consuming upgrade
issues.  Then Font Awesome 4 came out, also breaking compatibility with the
previous&amp;nbsp;version.&lt;/p&gt;
&lt;p&gt;Eventually, I could resist the urge to tinker no longer, and decided to do
the work to upgrade all three in one time-sucking swoop.  Starting with the
Pelican&amp;nbsp;upgrade.&lt;/p&gt;
&lt;p&gt;So it was with the usual slight sense of trepidation that I fired up my
virtualenv and gave the&amp;nbsp;command:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
pip install --upgrade pelican
&lt;/pre&gt;
&lt;p&gt;Turned out my trepidation was somewhat justified.  Things&amp;nbsp;broke.&lt;/p&gt;
&lt;div class="section" id="pelican-3-3-devserver-issues"&gt;
&lt;h2&gt;Pelican 3.3 devserver&amp;nbsp;issues&lt;/h2&gt;
&lt;p&gt;After doing a &lt;tt class="docutils literal"&gt;make serve&lt;/tt&gt;, things didn&amp;#8217;t look quite&amp;nbsp;right:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;127.0.0.1 - - [21/Jan/2014 21:41:51] &amp;quot;GET /theme/css/pygment.css HTTP/1.1&amp;quot; 200 -
WARNING:root:Unable to find /theme/css/pygment.css file.
WARNING:root:Unable to find /theme/css/pygment.css.html file.
WARNING:root:Unable to find /theme/css/pygment.css/index.html file.
127.0.0.1 - - [21/Jan/2014 21:42:24] &amp;quot;GET /blog/2014/01/21/upgrading-pelican-3-3/ HTTP/1.1&amp;quot; 200 -
WARNING:root:Unable to find /blog/2014/01/21/upgrading-pelican-3-3/ file.
WARNING:root:Unable to find /blog/2014/01/21/upgrading-pelican-3-3/.html file.
127.0.0.1 - - [21/Jan/2014 21:42:24] &amp;quot;GET /blog/2014/01/21/upgrading-pelican-3-3/ HTTP/1.1&amp;quot; 200 -
----------------------------------------
Exception happened during processing of request from (&amp;#39;127.0.0.1&amp;#39;, 47703)
Traceback (most recent call last):
  File &amp;quot;/usr/lib/python2.7/SocketServer.py&amp;quot;, line 295, in _handle_request_noblock
    self.process_request(request, client_address)
  File &amp;quot;/usr/lib/python2.7/SocketServer.py&amp;quot;, line 321, in process_request
    self.finish_request(request, client_address)
  File &amp;quot;/usr/lib/python2.7/SocketServer.py&amp;quot;, line 334, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File &amp;quot;/usr/lib/python2.7/SocketServer.py&amp;quot;, line 651, in __init__
    self.finish()
  File &amp;quot;/usr/lib/python2.7/SocketServer.py&amp;quot;, line 704, in finish
    self.wfile.flush()
  File &amp;quot;/usr/lib/python2.7/socket.py&amp;quot;, line 303, in flush
    self._sock.sendall(view[write_offset:write_offset+buffer_size])
error: [Errno 32] Broken pipe
----------------------------------------
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So there&amp;#8217;s the logging thing for starters.  Seems one of the Pelican 3.3
devserver &amp;#8220;improvements&amp;#8221; is to output 3 &amp;#8220;Unable to find&amp;#8221; log messages for
each file it serves, even if the file is actually found and served
successfully.  While initially confusing, it&amp;#8217;s only a superficial&amp;nbsp;annoyance.&lt;/p&gt;
&lt;p&gt;The &amp;#8220;broken pipe&amp;#8221; errors were more concerning though, if only because it
wasn&amp;#8217;t clear whether they were being caused by something messed up in my
system&amp;#8217;s configuration, or they indicated a bug somewhere in&amp;nbsp;Pelican.&lt;/p&gt;
&lt;p&gt;Initially, despite the broken pipe errors, it looked like the pages were
still being served correctly.  Not always, as I soon found&amp;nbsp;out.&lt;/p&gt;
&lt;p&gt;Because I was hacking away at my theme, I was not only using the
development server quite a bit, but also scrolling to specific parts of
pages (like the bottom) to see how things were looking as I made
modifications to the theme.  I soon noticed things were definitely not
looking right, for reasons other than my limited design&amp;nbsp;skills:&lt;/p&gt;
&lt;img alt="Web page with HTTP headers showing" src="http://www.voidynullness.net/images/devserverbugpelican3-3.png" /&gt;
&lt;p&gt;That screenshot shows what should be the bottom of the page.  Obviously the
&lt;span class="caps"&gt;HTTP&lt;/span&gt; headers should not be there, but neither should the truncated 2nd copy
of the page that appears after the &lt;span class="caps"&gt;HTTP&lt;/span&gt;&amp;nbsp;headers.&lt;/p&gt;
&lt;p&gt;I noticed these two things &amp;#8212; the broken pipe errors and the &lt;span class="caps"&gt;HTTP&lt;/span&gt; headers in
the web page &amp;#8212; were happening frequently, but not on every page view, so
it was one of those annoying intermittent&amp;nbsp;problems.&lt;/p&gt;
&lt;p&gt;I googled and found some &lt;a class="reference external" href="https://github.com/getpelican/pelican/issues/1077"&gt;reports of similar problems&lt;/a&gt;, but no where near as
many as I&amp;#8217;d expected, given that I was experiencing this really&amp;nbsp;often.&lt;/p&gt;
&lt;p&gt;Was it something in my&amp;nbsp;setup?&lt;/p&gt;
&lt;p&gt;I had a look at the Pelican source on GitHub, and sure enough, there was
new stuff added to devserver in version&amp;nbsp;3.3.&lt;/p&gt;
&lt;p&gt;Before version 3.3, the Pelican development server was basically just the
standard Python &lt;tt class="docutils literal"&gt;SimpleHTTPServer&lt;/tt&gt;.  But in version 3.3, a
&lt;a class="reference external" href="https://github.com/getpelican/pelican/blob/3.3.0/pelican/server.py#L16-L34"&gt;small wrapper&lt;/a&gt;
was added around &lt;tt class="docutils literal"&gt;SimpleHTTPServer&lt;/tt&gt; to provide some extra functionality.
The extra functionality was some &lt;a class="reference external" href="https://github.com/getpelican/pelican/issues/1038"&gt;basic nginx-style &lt;span class="caps"&gt;URL&lt;/span&gt; re-writing rules&lt;/a&gt;, to provide the
illusion of &amp;#8220;clean&amp;#8221; URLs, without actually having to configure clean URLs
the &amp;#8220;Pelican way&amp;#8221; (i.e. using the &lt;tt class="docutils literal"&gt;*_URL&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;*_SAVE_AS&lt;/tt&gt; settings so
that content ends up in a directory containing an &lt;tt class="docutils literal"&gt;index.html&lt;/tt&gt;).&lt;/p&gt;
&lt;p&gt;Personally I was quite happy with having clean URLs as directories.  It
seems a bit hacky at first, but works well in practice, and keeps things
appropriately simple.  While I can see how this new devserver functionality
might be occasionally useful, I would question the need to make this the
default behaviour, especially since (&lt;span class="caps"&gt;AFAIK&lt;/span&gt;) it&amp;#8217;s entirely&amp;nbsp;undocumented.&lt;/p&gt;
&lt;p&gt;After a bit of investigation and poking around, I came to the conclusion
that both problems I was experiencing with devserver were the result of a
&lt;a class="reference external" href="https://github.com/getpelican/pelican/pull/1178#issuecomment-29881546"&gt;bug introduced in the version 3.3 changes&lt;/a&gt;
to &lt;tt class="docutils literal"&gt;server.py&lt;/tt&gt;.  (And not anything in my setup.)  Somewhat ironically, in
an attempt to provide &amp;#8220;fake&amp;#8221; clean URLs, those changes broke handling of
&amp;#8220;proper&amp;#8221; clean URLs (i.e. serving of all URLs that resolve to an actual
directory on the&amp;nbsp;server).&lt;/p&gt;
&lt;p&gt;I suspect the reason there weren&amp;#8217;t as many reports of these problems as I
expected was because they are more likely to occur if Pelican is configured
to generate &amp;#8220;proper&amp;#8221; clean URLs.  This is something I&amp;#8217;ve tried to do
consistently in my configuration, but it seems I must be in the minority.
The fact they&amp;#8217;re intermittent and not exactly show stopping (though
annoying/confusing) is no doubt also a&amp;nbsp;factor.&lt;/p&gt;
&lt;p&gt;In any case the whole thing bugged me enough that I decided to do a bit of
tangential tinkering &lt;a class="reference external" href="https://github.com/getpelican/pelican/pull/1178"&gt;to try and fix the problem.&lt;/a&gt;
(&lt;span class="caps"&gt;BTW&lt;/span&gt;, anyone out there know why &lt;tt class="docutils literal"&gt;SimpleHTTPRequestHandler&lt;/tt&gt; is not a new
style class under Python&amp;nbsp;2.7?)&lt;/p&gt;
&lt;div class="section" id="workaround"&gt;
&lt;h3&gt;Workaround&lt;/h3&gt;
&lt;p&gt;For anyone also regularly experiencing broken pipe errors with the Pelican
3.3 devserver and/or mangled &lt;span class="caps"&gt;HTML&lt;/span&gt; being served, there are a few ways to
work around this.  Obviously you could just incorporate &lt;a class="reference external" href="https://github.com/robulouski/pelican/commit/301268f67f1a6751a3c9ac51d099fae10b808f8b"&gt;the patch&lt;/a&gt;
into your own&amp;nbsp;setup.&lt;/p&gt;
&lt;p&gt;But for those who don&amp;#8217;t need the new stuff added in 3.3 (and I imagine very
few people would), there are simpler&amp;nbsp;options.&lt;/p&gt;
&lt;p&gt;One is just to use &lt;tt class="docutils literal"&gt;SimpleHTTPServer&lt;/tt&gt; on the command&amp;nbsp;line:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; output&lt;span class="p"&gt;;&lt;/span&gt; python -m SimpleHTTPServer
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Another, for those who want to keep using the devserver, is to change
&lt;a class="reference external" href="https://github.com/getpelican/pelican/blob/3.3.0/pelican/server.py#L34"&gt;one line in Pelican&amp;#8217;s server.py&lt;/a&gt;
file.  If you&amp;#8217;re using a virtualenv (and if not, you should be), this file
will be located somewhere like&amp;nbsp;this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;~/path/to/virtualenv/lib/python2.7/site-packages/pelican/server.py
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Edit &lt;tt class="docutils literal"&gt;server.py&lt;/tt&gt;, replacing this&amp;nbsp;line:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;Handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ComplexHTTPRequestHandler&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With&amp;nbsp;this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;Handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;srvmod&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SimpleHTTPRequestHandler&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This essentially disables the new new Pelican 3.3 devserver functionality
(with the buggy bits) so you essentially get the same behavior as Pelican
3.2 &amp;#8212; plain old &lt;tt class="docutils literal"&gt;SimpleHTTPRequestHandler&lt;/tt&gt;.  The makefile &lt;tt class="docutils literal"&gt;serve&lt;/tt&gt; and
&lt;tt class="docutils literal"&gt;devserver&lt;/tt&gt; targets should now work&amp;nbsp;properly.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="configuration-changes-for-pelican-3-3"&gt;
&lt;h2&gt;Configuration changes for Pelican&amp;nbsp;3.3&lt;/h2&gt;
&lt;p&gt;There weren&amp;#8217;t many changes to &lt;tt class="docutils literal"&gt;pelicanconf.py&lt;/tt&gt; required after upgrading
to&amp;nbsp;3.3.&lt;/p&gt;
&lt;p&gt;The only significant change was as a result of &lt;tt class="docutils literal"&gt;FILES_TO_COPY&lt;/tt&gt; being
deprecated.  It has been &lt;a class="reference external" href="http://docs.getpelican.com/en/3.3.0/settings.html#path-metadata"&gt;replaced with&lt;/a&gt;
&lt;tt class="docutils literal"&gt;STATIC_PATHS&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;EXTRA_PATH_METADATA&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;So in &lt;tt class="docutils literal"&gt;pelicanconf.py&lt;/tt&gt; this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;STATIC_PATHS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;images&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;FILES_TO_COPY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;other/robots.txt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;robots.txt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;other/favicon.ico&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;favicon.ico&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;other/arbitrary.html&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;arbitrary.html&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                 &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Became&amp;nbsp;this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;STATIC_PATHS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;images&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;&amp;#39;other/robots.txt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;&amp;#39;other/favicon.ico&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;&amp;#39;other/arbitrary.html&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;EXTRA_PATH_METADATA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;&amp;#39;other/robots.txt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;path&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;robots.txt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s1"&gt;&amp;#39;other/favicon.ico&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;path&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;favicon.ico&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s1"&gt;&amp;#39;other/arbitrary.html&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;path&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;arbitrary.html&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The official docs don&amp;#8217;t go into a huge amount of detail about
&lt;tt class="docutils literal"&gt;EXTRA_PATH_METADATA&lt;/tt&gt;, and I&amp;#8217;m not sure if I&amp;#8217;ve got things configured
quite right.  In the above excerpts, &lt;tt class="docutils literal"&gt;arbitrary.html&lt;/tt&gt; represents a few
arbitrary &lt;span class="caps"&gt;HTML&lt;/span&gt; files I want Pelican to copy to the root output directory.
I want them copied unmodified, that&amp;#8217;s it.  But for reasons I don&amp;#8217;t
understand Pelican seems to be looking at the contents, possibly wanting to
process them in some way, because I keep getting errors like&amp;nbsp;this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;ERROR: Skipping other/arbitrary.html: could not find information about &amp;#39;title&amp;#39;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I didn&amp;#8217;t see anything like this in version 3.2, and I&amp;#8217;m not sure what it&amp;#8217;s
complaining about.  Sure, those arbitrary &lt;span class="caps"&gt;HTML&lt;/span&gt; files in question don&amp;#8217;t
actually have a title &amp;#8212; they are just &lt;span class="caps"&gt;HTML&lt;/span&gt; fragments, mostly for use by
tools and not for human/browser consumption.  I just want the files copied.
And they are, in fact, being copied to where I want them, so in that
respect things are working.  I&amp;#8217;m just not sure why Pelican considers
this an&amp;nbsp;&amp;#8220;error&amp;#8221;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt;&lt;/strong&gt;: I eventually &lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/30/upgrading-pelican-3-5/"&gt;found a solution to&amp;nbsp;this.&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="images-and-internal-links"&gt;
&lt;h2&gt;Images and internal&amp;nbsp;links&lt;/h2&gt;
&lt;p&gt;It seems another side-effect of the changes to &lt;tt class="docutils literal"&gt;STATIC_PATHS&lt;/tt&gt; was the
default location of image files changed, with the &lt;tt class="docutils literal"&gt;static&lt;/tt&gt; directory
being removed.  This meant I had to modify any places in my theme that
directly (hackily?) referenced images in the output&amp;nbsp;location.&lt;/p&gt;
&lt;p&gt;So stuff like&amp;nbsp;this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&amp;lt;img src=&amp;quot;/static/images/imagefilename.png&amp;quot; alt=&amp;quot;&amp;quot;&amp;gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Became&amp;nbsp;this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&amp;lt;img src=&amp;quot;/images/imagefilename.png&amp;quot; alt=&amp;quot;an image&amp;quot;&amp;gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Another change introduced in Pelican 3.3 with regards to images is the
syntax for links to internal content.  While the old syntax is still
supported, the new syntax uses curly&amp;nbsp;braces:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;{filename}path/to/file
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Also, as of version 3.3, Pelican gives warnings for images without alt&amp;nbsp;attributes:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;WARNING: Empty alt attribute for image
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I don&amp;#8217;t have many posts with image links, so it was easy enough to find the
few image links I did have and add alt attributes to them, like so
(assuming reST&amp;nbsp;format):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;..&lt;/span&gt; &lt;span class="ow"&gt;image&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt; {filename}/images/imagefilename.png
   &lt;span class="nc"&gt;:alt:&lt;/span&gt; &lt;span class="nf"&gt;alternative text&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Since I was going through my previous posts and adding alt attributes, I
also updated the links to use the new internal linking syntax while I was
at&amp;nbsp;it.&lt;/p&gt;
&lt;p&gt;That got rid of most most of the &amp;#8220;Empty alt attribute&amp;#8221; warnings, but a few
still remained.  Turns out Pelican issues this warning not only for images
referenced the &amp;#8220;proper&amp;#8221; way, but also for any &lt;tt class="docutils literal"&gt;&amp;lt;img&amp;gt;&lt;/tt&gt; tags included in
raw &lt;span class="caps"&gt;HTML&lt;/span&gt; blocks (using the reStructuredText &amp;#8220;raw&amp;#8221; directive).  This kind of
surprised me &amp;#8212; and seems overly protective of Pelican.  Not sure how I fee
about Pelican judging me on the quality of my raw (and hacky) &lt;span class="caps"&gt;HTML&lt;/span&gt;&amp;nbsp;code!&lt;/p&gt;
&lt;p&gt;Although it&amp;#8217;s not really my code.  Most of the raw &lt;span class="caps"&gt;HTML&lt;/span&gt; blocks were used to
incorporate &lt;span class="caps"&gt;HTML&lt;/span&gt;/Javascript code snippets from the various increasingly
ubiquitous third party services.  Some of these code blocks had &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;IMG&lt;/span&gt;&lt;/tt&gt;
tags with alt attributes set to an empty&amp;nbsp;string:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Turns out this empty alt attribute is what Pelican was complaining&amp;nbsp;about.&lt;/p&gt;
&lt;p&gt;Surprisingly though, removing those empty alt attribute removed the
warnings.  Seems Pelican is fine with &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;IMG&lt;/span&gt;&lt;/tt&gt; tags in raw &lt;span class="caps"&gt;HTML&lt;/span&gt; blocks
without alt attributes, but it won&amp;#8217;t tolerate missing alt attributes on
reST &lt;tt class="docutils literal"&gt;image&lt;/tt&gt; directives.&amp;nbsp;Weird.&lt;/p&gt;
&lt;p&gt;So to get a &amp;#8220;neat&amp;#8221; build without warning/errors I had to make sure all
&lt;tt class="docutils literal"&gt;image&lt;/tt&gt; directives had an alt tag, but had to remove alt tags from
&lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;IMG&lt;/span&gt;&lt;/tt&gt; elements in raw &lt;span class="caps"&gt;HTML&lt;/span&gt;&amp;nbsp;blocks.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="success"&gt;
&lt;h2&gt;Success&lt;/h2&gt;
&lt;p&gt;After all that however, with a fixed devserver and image references
appropriately tweaked, I did manage to get a functional, updated pelican
setup, along with a mostly error/warning free build of my&amp;nbsp;blog.&lt;/p&gt;
&lt;p&gt;With that out of the way, it was now time to go ahead with updating my blog
to use the latest versions Bootstrap and Font Awesome.  Or at least find
creative ways to&amp;nbsp;procrastinate.&lt;/p&gt;
&lt;p&gt;But that&amp;#8217;s possibly a topic for another blog&amp;nbsp;post.&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h3&gt;Related&amp;nbsp;Posts:&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/11/30/upgrading-pelican-3-5/"&gt;Upgrading to Pelican&amp;nbsp;3.5&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="Pelican"></category><category term="Python"></category></entry><entry><title>Raiders of the Lost Django Registration Templates</title><link href="http://www.voidynullness.net/blog/2014/01/15/raiders-of-the-lost-django-registration-templates/" rel="alternate"></link><published>2014-01-15T00:00:00+11:00</published><updated>2014-01-15T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2014-01-15:/blog/2014/01/15/raiders-of-the-lost-django-registration-templates/</id><summary type="html">&lt;p&gt;&lt;em&gt;Psst!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Hey&amp;nbsp;you.&lt;/p&gt;
&lt;p&gt;Yes, you there, looking at the screen with a combination of confusion,
surprise and frustration.  Is this the first time you&amp;#8217;re trying to create a
Django website with user sign up and log in capabilities?  Looking for a
&amp;#8220;built-in&amp;#8221; way to do&amp;nbsp;that?&lt;/p&gt;
&lt;p&gt;Well, there isn&amp;#8217;t one.  Sometimes implementing common website functionality
that you&amp;#8217;d think should be easy and straightforward isn&amp;#8217;t so much.  But
hey, that&amp;#8217;s pretty much always going to be …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;em&gt;Psst!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Hey&amp;nbsp;you.&lt;/p&gt;
&lt;p&gt;Yes, you there, looking at the screen with a combination of confusion,
surprise and frustration.  Is this the first time you&amp;#8217;re trying to create a
Django website with user sign up and log in capabilities?  Looking for a
&amp;#8220;built-in&amp;#8221; way to do&amp;nbsp;that?&lt;/p&gt;
&lt;p&gt;Well, there isn&amp;#8217;t one.  Sometimes implementing common website functionality
that you&amp;#8217;d think should be easy and straightforward isn&amp;#8217;t so much.  But
hey, that&amp;#8217;s pretty much always going to be the case with any web
framework.  Though as always, be sure to keep in mind that despite moments
of confusion or frustration with the Django learning curve, at least it&amp;#8217;s
not &lt;span class="caps"&gt;PHP&lt;/span&gt;.  So there&amp;#8217;s&amp;nbsp;that.&lt;/p&gt;
&lt;p&gt;So yes, Django has user authentication built in, and you get a nice admin
interface for free if you want it, but none of that is going to help you
much with user sign up, as such.  You&amp;#8217;ll either have to roll your own
solution on top of the bits Django does provide, or use one of many
external packages, each with their unique combination of advantages and&amp;nbsp;disadvantages.&lt;/p&gt;
&lt;p&gt;The closest thing to a &amp;#8220;standard&amp;#8221; way to provide user sign up is
&lt;a class="reference external" href="https://github.com/ubernostrum/django-registration/"&gt;django-registration.&lt;/a&gt;
This only does local sign up (i.e. based on
username/email).  If you want log in via social media accounts, that&amp;#8217;s a
&lt;a class="reference external" href="https://pypi.python.org/pypi/django-allauth"&gt;whole other thing&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But if all you need/want is local sign up, django-registration will get the
job done.  After a bit of fiddling.  Including creating your own&amp;nbsp;templates.&lt;/p&gt;
&lt;p class="introblock"&gt;&lt;strong&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt;:&lt;/strong&gt; Since this post was written, django-registration went through a
period where it was not maintained and seemingly abandoned, which led to
the creation of a &lt;a class="reference external" href="https://github.com/macropin/django-registration"&gt;fork called django-registration-redux&lt;/a&gt;.  &lt;span class="caps"&gt;AFAIK&lt;/span&gt; both are now
maintained and compatible with recent versions of Django.  I have no advice
to offer as to which is preferable theses days, or whether other
alternatives entirely are best&amp;nbsp;considered.&lt;/p&gt;
&lt;p&gt;Keep in mind user sign up is something where there isn&amp;#8217;t likely to be
one-size-fits-all approach that will work for everyone.  Different websites
are likely to want different approaches, hence the different possible
registration backends django-registration provides.  Then there&amp;#8217;s front
end differences.  Not just appearance, but also differences in front-end
frameworks, and any specific django template libraries used within the&amp;nbsp;project.&lt;/p&gt;
&lt;p&gt;So this post isn&amp;#8217;t intended to be authoritative, or an opinion
as to best practices &amp;#8212; just a starting point.  Because having at least
some working sample code is often useful when starting&amp;nbsp;out.&lt;/p&gt;
&lt;p&gt;What follows are some pointers and examples that might be useful for those
trying to get their head around the whole process of integrating
django-registration, and creating the required&amp;nbsp;templates.&lt;/p&gt;
&lt;div class="section" id="required-templates"&gt;
&lt;h2&gt;Required&amp;nbsp;Templates&lt;/h2&gt;
&lt;p&gt;The &lt;a class="reference external" href="https://django-registration.readthedocs.org/en/latest/quickstart.html"&gt;official documentation&lt;/a&gt;
does a pretty good job of walking through the steps necessary to install
and configure&amp;nbsp;django-registration.&lt;/p&gt;
&lt;p&gt;As it points out, django-registration requires &lt;a class="reference external" href="https://django-registration.readthedocs.org/en/latest/quickstart.html#required-templates"&gt;these templates&lt;/a&gt;:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;registration_form.html&lt;/li&gt;
&lt;li&gt;registration_complete.html&lt;/li&gt;
&lt;li&gt;activate.html&lt;/li&gt;
&lt;li&gt;activation_complete.html&lt;/li&gt;
&lt;li&gt;activation_email_subject.txt&lt;/li&gt;
&lt;li&gt;activation_email.txt&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The above templates cover functionality provided by&amp;nbsp;django-registration.&lt;/p&gt;
&lt;p&gt;However, in addition to the above, most non-trivial websites would want to
implement their own templates for things like login, logout and password
resets.  This functionality is provided by
&lt;a class="reference external" href="https://docs.djangoproject.com/en/dev/topics/auth/"&gt;Django&amp;#8217;s built-in user authentication system&lt;/a&gt;.  The
&lt;a class="reference external" href="https://docs.djangoproject.com/en/dev/topics/auth/default/#built-in-auth-views"&gt;authentication views&lt;/a&gt;
make use of the following templates (by&amp;nbsp;default):&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;login.html&lt;/li&gt;
&lt;li&gt;logout.html&lt;/li&gt;
&lt;li&gt;password_change_form.html&lt;/li&gt;
&lt;li&gt;password_change_done.html&lt;/li&gt;
&lt;li&gt;password_reset_form.html&lt;/li&gt;
&lt;li&gt;password_reset_email.html&lt;/li&gt;
&lt;li&gt;password_reset_subject.txt&lt;/li&gt;
&lt;li&gt;password_reset_done.html&lt;/li&gt;
&lt;li&gt;password_reset_confirm.html&lt;/li&gt;
&lt;li&gt;password_reset_complete.html&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="example-django-registration-templates"&gt;
&lt;h2&gt;Example django-registration&amp;nbsp;Templates&lt;/h2&gt;
&lt;p&gt;Here are some simple examples of the templates django-registration
requires, using &lt;a class="reference external" href="http://getbootstrap.com/"&gt;Bootstrap 3&lt;/a&gt;
with the &lt;a class="reference external" href="https://github.com/dyve/django-bootstrap3"&gt;django-bootstrap3&lt;/a&gt;
template&amp;nbsp;library.&lt;/p&gt;
&lt;p&gt;The &lt;a class="reference external" href="https://github.com/robulouski/django-rotldrt"&gt;complete code is on&amp;nbsp;github.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Templates need to be placed in a subdirectory called
&lt;tt class="docutils literal"&gt;registration&lt;/tt&gt; somewhere where the template loader can find it.
(Configure &lt;tt class="docutils literal"&gt;TEMPLATE_DIRS&lt;/tt&gt; in your settings file as&amp;nbsp;appropriate.)&lt;/p&gt;
&lt;p&gt;The following examples assume the default backend is being used, with the
default&amp;nbsp;URLs.&lt;/p&gt;
&lt;div class="section" id="registration-form-html"&gt;
&lt;h3&gt;&lt;tt class="docutils literal"&gt;registration_form.html&lt;/tt&gt;&lt;/h3&gt;
&lt;p&gt;This is the template for the sign up screen.  It will contain the
registration form for the user to fill&amp;nbsp;out.&lt;/p&gt;
&lt;p&gt;You will also mostly likely need to provide a link to &lt;span class="caps"&gt;URL&lt;/span&gt; of the
registration view somewhere in your website &amp;#8212; for example, a &amp;#8220;register&amp;#8221; or
&amp;#8220;sign up&amp;#8221; button on the home page.  With the default backend the view class is
&lt;tt class="docutils literal"&gt;registration.backends.default.views.RegistrationView&lt;/tt&gt;, and the &lt;span class="caps"&gt;URL&lt;/span&gt; is
named &lt;tt class="docutils literal"&gt;registration_register&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;So a &amp;#8220;Register&amp;#8221; button on the home page will look something like this, in
the home page&amp;nbsp;template:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;btn btn-lg btn-primary&amp;quot;&lt;/span&gt;
   &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;{% url &amp;#39;registration_register&amp;#39; %}&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Register&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;When the user clicks this link, the &lt;tt class="docutils literal"&gt;registration_form.html&lt;/tt&gt; will be&amp;nbsp;displayed.&lt;/p&gt;
&lt;p&gt;A &lt;tt class="docutils literal"&gt;form&lt;/tt&gt; context is passed to &lt;tt class="docutils literal"&gt;registration_form.html&lt;/tt&gt;, which it will need to
render.  For the default backend, this will be an instance of
&lt;a class="reference external" href="https://django-registration.readthedocs.org/en/latest/forms.html#registration.forms.RegistrationForm"&gt;registration.forms.RegistrationForm&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;{% extends &amp;quot;base.html&amp;quot; %}
{% load bootstrap3 %}

{% block title %}Registration{% endblock %}

{% block content %}
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;container&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;row&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;col-sm-offset-2 col-sm-10&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Sign up&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Already registered?
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;{% url &amp;#39;django.contrib.auth.views.login&amp;#39; %}&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Sign in here.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;{% url &amp;#39;registration_register&amp;#39; %}&amp;quot;&lt;/span&gt;
        &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;post&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;form&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;form-horizontal&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    {% csrf_token %}
    {% bootstrap_form form layout=&amp;#39;horizontal&amp;#39; %}
    {% buttons %}
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;col-sm-offset-2 col-sm-10&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;submit&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;btn btn-primary&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        {% bootstrap_icon &amp;quot;star&amp;quot; %} Sign Me Up!
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    {% endbuttons %}
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
{% endblock %}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="registration-complete-html"&gt;
&lt;h3&gt;&lt;tt class="docutils literal"&gt;registration_complete.html&lt;/tt&gt;&lt;/h3&gt;
&lt;p&gt;Confirmation to the user that registration has completed&amp;nbsp;successfully.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;{% extends &amp;quot;base.html&amp;quot; %}

{% block title %}Registration complete{% endblock %}

{% block content %}
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;container&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;row&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;col-md-8&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Registration complete!&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;An activation email has been sent.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
{% endblock %}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="activate-html"&gt;
&lt;h3&gt;&lt;tt class="docutils literal"&gt;activate.html&lt;/tt&gt;&lt;/h3&gt;
&lt;p&gt;Displayed if account activation fails.  The &lt;tt class="docutils literal"&gt;activation_key&lt;/tt&gt; context is
provided to display the failed activation key&amp;nbsp;used.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;{% extends &amp;quot;base.html&amp;quot; %}

{% block title %}Account activation error{% endblock %}

{% block content %}
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;container&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;row&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Account activation error&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;alert alert-danger col-md-9&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;The activation key &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;{{ activation_key }}&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; is invalid or expired.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

{% endblock %}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="activation-complete-html"&gt;
&lt;h3&gt;&lt;tt class="docutils literal"&gt;activation_complete.html&lt;/tt&gt;&lt;/h3&gt;
&lt;p&gt;Confirmation to the user that registration has completed&amp;nbsp;successfully.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;{% extends &amp;quot;base.html&amp;quot; %}

{% block title %}Account activation complete{% endblock %}

{% block content %}
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;container&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Success!&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;lead&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Account successfully activated!&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;You can now sign in to the website.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;{% url &amp;#39;django.contrib.auth.views.login&amp;#39; %}&amp;quot;&lt;/span&gt;
        &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;btn btn-success&amp;quot;&lt;/span&gt;
        &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;button&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Sign in&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
{% endblock %}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="activation-email-subject-txt"&gt;
&lt;h3&gt;&lt;tt class="docutils literal"&gt;activation_email_subject.txt&lt;/tt&gt;&lt;/h3&gt;
&lt;p&gt;Subject line for the activation&amp;nbsp;email:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
{{ site.name }}: Please activate your account.
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="activation-email-txt"&gt;
&lt;h3&gt;&lt;tt class="docutils literal"&gt;activation_email.txt&lt;/tt&gt;&lt;/h3&gt;
&lt;p&gt;Message body of the activiation email.  At the very least will need to
display a link to the activation &lt;span class="caps"&gt;URL&lt;/span&gt;, which for the default backend is
named &lt;tt class="docutils literal"&gt;registration_activate&lt;/tt&gt;, passing through the activation key available in
the &lt;tt class="docutils literal"&gt;activation_key&lt;/tt&gt; context.  Optionally, you can also include how many days
before the activation key will&amp;nbsp;expire:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;To activate your account, please visit the following page:

http://{{ site.domain }}{% url &amp;#39;registration_activate&amp;#39; activation_key %}

This page will expire in {{ expiration_days }} day{{ expiration_days|pluralize }}.
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="django-1-6-issues"&gt;
&lt;h2&gt;Django 1.6&amp;nbsp;issues&lt;/h2&gt;
&lt;p&gt;Note that changes to the auth module &lt;a class="reference external" href="https://docs.djangoproject.com/en/dev/releases/1.6/#miscellaneous"&gt;introducted in Django 1.6&lt;/a&gt;
cause some &lt;a class="reference external" href="http://stackoverflow.com/questions/19985103/django-1-6-and-django-registration-built-in-authentication-views-not-picked-up"&gt;incompatability with django-registration&lt;/a&gt;
when it comes to password URLs.  Until &lt;a class="reference external" href="https://bitbucket.org/ubernostrum/django-registration/pull-request/63/django-16-compatibility-fix-auth-views"&gt;django-registration is updated&lt;/a&gt; you may need to add a workaround to your URLs if you&amp;#8217;re providing custom password&amp;nbsp;templates:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;url(r&amp;#39;^accounts/&amp;#39;, include(&amp;#39;registration.backends.default.urls&amp;#39;)),
url(r&amp;#39;^password/change/$&amp;#39;,
                auth_views.password_change,
                name=&amp;#39;password_change&amp;#39;),
url(r&amp;#39;^password/change/done/$&amp;#39;,
                auth_views.password_change_done,
                name=&amp;#39;password_change_done&amp;#39;),
url(r&amp;#39;^password/reset/$&amp;#39;,
                auth_views.password_reset,
                name=&amp;#39;password_reset&amp;#39;),
url(r&amp;#39;^accounts/password/reset/done/$&amp;#39;,
                auth_views.password_reset_done,
                name=&amp;#39;password_reset_done&amp;#39;),
url(r&amp;#39;^password/reset/complete/$&amp;#39;,
                auth_views.password_reset_complete,
                name=&amp;#39;password_reset_complete&amp;#39;),
url(r&amp;#39;^password/reset/confirm/(?P&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;uidb64&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;[0-9A-Za-z_\-]+)/(?P&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;token&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;.+)/$&amp;#39;,
                auth_views.password_reset_confirm,
                name=&amp;#39;password_reset_confirm&amp;#39;),
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="demo-code"&gt;
&lt;h2&gt;Demo&amp;nbsp;code&lt;/h2&gt;
&lt;p&gt;The above templates, as well as complete set of Bootstrap-friendly sample
registration/authentication templates, &lt;a class="reference external" href="https://github.com/robulouski/django-rotldrt"&gt;are on github&lt;/a&gt;.  There&amp;#8217;s also a simple
but functional demo site to show how everything fits&amp;nbsp;together.&lt;/p&gt;
&lt;/div&gt;
</content><category term="Python"></category><category term="Django"></category></entry><entry><title>Booze To The Node</title><link href="http://www.voidynullness.net/blog/2014/01/06/booze-to-the-node/" rel="alternate"></link><published>2014-01-06T00:00:00+11:00</published><updated>2014-01-06T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2014-01-06:/blog/2014/01/06/booze-to-the-node/</id><summary type="html">&lt;p class="first last"&gt;Because when it comes to politics, technical merits don&amp;#8217;t seem to matter.  It&amp;#8217;s all about politicians and pictures of their privates.&amp;nbsp;Apparently.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;Lately, it seems that when it comes to politics and technology, technical
merits don&amp;#8217;t matter.  Politicians only seem to care about technology to the
extent it allows them to &lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/30/deviant-luddites-screwing-us/"&gt;distribute pictures of their&amp;nbsp;privates.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So if we&amp;#8217;re trying to engage our political masters on issues important to
us, why should we constrain ourselves with such things as logic and reason,
&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/01/05/screwed-to-the-node/"&gt;if our politicians&amp;nbsp;don&amp;#8217;t?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Perhaps we should take a leaf from the sordid playbooks of politics and
advertising.  Perhaps we should pay less attention to such things as logic
and facts, and more to spin and&amp;nbsp;hyperbole.&lt;/p&gt;
&lt;p&gt;Because it&amp;#8217;s not as if we&amp;#8217;re going to persuade an apathetic public to care
about our abstract technical issues with mysterious acronyms and jargon.
Whether we&amp;#8217;re trying to persuade politicians or the public, we need to work
out a way to communicate that is effective for an uncaring and
non-technical&amp;nbsp;audience.&lt;/p&gt;
&lt;p&gt;With that in mind, here&amp;#8217;s my attempt to explain &amp;#8212; for a non-technical
audience &amp;#8212; the differences between Labor&amp;#8217;s superior Fibre to the Premises
(&lt;span class="caps"&gt;FTTP&lt;/span&gt;) &lt;span class="caps"&gt;NBN&lt;/span&gt;, and the Coalition&amp;#8217;s crappy Fibre to the Node (&lt;span class="caps"&gt;FTTN&lt;/span&gt;)&amp;nbsp;alternative.&lt;/p&gt;
&lt;div class="section" id="why-fibre-to-the-node-is-stupid-a-non-technical-guide-for-non-geeks-and-alcoholics"&gt;
&lt;h2&gt;Why Fibre to the Node is stupid: a non-technical guide for non-geeks and&amp;nbsp;alcoholics&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s say you want to get drunk.  Really, really drunk.  Because your &lt;span class="caps"&gt;ADSL&lt;/span&gt;
doesn&amp;#8217;t work.
&lt;a class="reference external" href="http://www.sortius-is-a-geek.com/a-fault-like-any-other-fault/"&gt;And Telstra won&amp;#8217;t fix it.&lt;/a&gt;
And even your analogue phone line is a crackly mess of static because the
copper in your street has degraded to buggery.
&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/09/01/australian-broadband-hustle/"&gt;And Telstra won&amp;#8217;t fix it&lt;/a&gt;.
So you have decided to get drunk.  Really&amp;nbsp;drunk.&lt;/p&gt;
&lt;p&gt;Not that I&amp;#8217;m condoning alcohol consumption as a way of dealing with
&lt;span class="caps"&gt;ADSL&lt;/span&gt; problems.  But let&amp;#8217;s say we&amp;#8217;re living in an alternative fantasy
universe where Australians drink responsibly.  (Because only in an
alternative fantasy universe would Fibre to the Node be an acceptable
technical solution to our outdated, half-assed, patchwork broadband
infrastructure.)  An alternative universe where boat people are not an
issue, because any boat people that do get here are so shocked by our
crappy internet that they fuck off to countries with decent upload speeds,
scoffing at us primitive Australians still using &lt;a class="reference external" href="http://www.businessspectator.com.au/article/2013/10/23/technology/nbn-copper-whispering-campaign"&gt;copper networks&lt;/a&gt;
for internet&amp;nbsp;connections.&lt;/p&gt;
&lt;p&gt;So you&amp;#8217;re at home and you want to get drunk.  But you&amp;#8217;re out of booze.  And
it&amp;#8217;s a long way to the nearest bar or bottle shop.  And you don&amp;#8217;t have a
car.  And public transport doesn&amp;#8217;t work because the Liberals are in&amp;nbsp;power.&lt;/p&gt;
&lt;p&gt;Imagine a Booze to the Premises system, where you can get any kind of
alcoholic beverage &amp;#8212; and as much as you want &amp;#8212; delivered right to your
home almost instantly, 24 hours a day, no matter where you live.  Pretty
great, right?  So that&amp;#8217;s the idea of universal &lt;span class="caps"&gt;FTTP&lt;/span&gt; technology.  It will
allow us to quench our thirst for data downloads quickly and efficiently &amp;#8212;
no matter what time, day or night, or &lt;a class="reference external" href="http://www.sortius-is-a-geek.com/a-fault-like-any-other-fault/"&gt;what the weather is&amp;nbsp;like.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So ideally, if you&amp;#8217;re &lt;a class="reference external" href="https://www.netflix.com/au/"&gt;really, really thirsty,&lt;/a&gt;
you&amp;#8217;d want Booze to the Premises.  But what if you were stuck with Booze to
the&amp;nbsp;Node?&lt;/p&gt;
&lt;p&gt;Booze to the Node also promises delivery of alcoholic beverages, but it&amp;#8217;s
much like the promise of a degenerate alcoholic &amp;#8212; forgotten the next day.
Deliveries takes much longer &amp;#8212; sometimes ridiculously long &amp;#8212; and
sometimes they don&amp;#8217;t arrive at&amp;nbsp;all.&lt;/p&gt;
&lt;p&gt;What&amp;#8217;s worse though, is that your booze won&amp;#8217;t be delivered to your
home &amp;#8212; it can only be delivered to a big ugly box at the end of the
street.  A big box with lots of lights and electrical equipment inside that
uses &lt;a class="reference external" href="http://www.businessspectator.com.au/article/2013/4/12/technology/hidden-cost-nbn-street-cabinets"&gt;huge amounts of electricity&lt;/a&gt;
and therefore contributes to greenhouse gas&amp;nbsp;emissions.&lt;/p&gt;
&lt;p&gt;Worse, everyone in the area has to get their booze delivered to the same
box.  So there is a limit to how much you can order at once.  The more
people getting deliveries, the
&lt;a class="reference external" href="http://en.wikipedia.org/wiki/Network_congestion"&gt;less each person can have delivered in one go&lt;/a&gt;.
And once your order arrives at the big ugly box at the end of the street
(if it does arrive) you have to walk down the street to get&amp;nbsp;it.&lt;/p&gt;
&lt;p&gt;&lt;span class="dquo"&gt;&amp;#8220;&lt;/span&gt;But that sounds silly!&amp;#8221; you say.  &amp;#8220;Surely, if they can deliver booze to
the end of my street, then wouldn&amp;#8217;t it just be better and easier and more
practical all round to go that little bit further and actually deliver it
right to my&amp;nbsp;home?&amp;#8221;&lt;/p&gt;
&lt;p&gt;Exactly!&lt;/p&gt;
&lt;p&gt;What could have been an efficient system of getting drunk on conveniently
home-delivered booze in the comfort and safety of your own home, turns into
a time consuming walk down the road, only have to carry all those heavy
bottles back home yourself, and all at the mercy of the weather.  If it&amp;#8217;s
&lt;a class="reference external" href="http://www.dslreports.com/faq/1331"&gt;raining&lt;/a&gt;,
things will get slippery and packaging will soak through, making
it likely at least some bottles will get dropped and
&lt;a class="reference external" href="http://en.wikipedia.org/wiki/Packet_loss"&gt;break on the ground&lt;/a&gt;.
All that expense and effort and nothing to show for it!  What a waste!
You&amp;#8217;ll then have no choice but to order more booze and
&lt;a class="reference external" href="http://en.wikipedia.org/wiki/Retransmission_(data_networks)"&gt;go through the whole process&amp;nbsp;again!&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;But it gets worse.  In addition to the inconvenience of having to walk down
the road to pick up your order, the trip itself is likely to be quite
unpleasant, because the streets are full of cranky &lt;span class="caps"&gt;ADSL&lt;/span&gt; users.  They are
angry and driven to the brink of insanity because their internet
connections keeps dropping out.  It seems no one can do anything for them.
Telstra certainly won&amp;#8217;t do anything.  And even if there was someone to call
for help, it unlikely the phones will be working because the phones use
Telstra&amp;#8217;s copper network, which Telstra won&amp;#8217;t&amp;nbsp;fix.&lt;/p&gt;
&lt;p&gt;So these disgruntled &lt;span class="caps"&gt;ADSL&lt;/span&gt; users just roam the street, plaintively wailing
for help, asking strangers if their &lt;span class="caps"&gt;ADSL&lt;/span&gt; is working and frantically
questioning them about their distance from the exchange.  Sadly, there is
no choice but to venture out and try to avoid them.  They will
&lt;a class="reference external" href="http://en.wikipedia.org/wiki/Electromagnetic_interference"&gt;get in the way and slow things down&lt;/a&gt;,
and if there&amp;#8217;s lots of them around at one time you may have to
&lt;a class="reference external" href="http://en.wikipedia.org/wiki/Routing"&gt;go a different way&lt;/a&gt;
(even if it&amp;#8217;s longer), or just wait till another time.  But these angry
&lt;span class="caps"&gt;ADSL&lt;/span&gt; users are essentially harmless.  Just ignore them and hope they go
away.  That&amp;#8217;s what Telstra&amp;nbsp;does.&lt;/p&gt;
&lt;p&gt;Clearly, Booze to the Premises is the vastly superior option, and it&amp;#8217;s what
the majority of Australians would prefer. But it&amp;#8217;s not what we&amp;#8217;re going to&amp;nbsp;get.&lt;/p&gt;
&lt;p&gt;The Coalition is in power now, so much like a &lt;a class="reference external" href="http://www.malcolmturnbull.com.au/"&gt;devious&lt;/a&gt; &lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/09/01/australian-broadband-hustle/"&gt;con-artist&lt;/a&gt;,
they&amp;#8217;re trying to get us to accept Booze to the&amp;nbsp;Node.&lt;/p&gt;
&lt;p&gt;They&amp;#8217;re trying to screw&amp;nbsp;us.&lt;/p&gt;
&lt;p&gt;Being screwed is bad enough.  What&amp;#8217;s worse is that we are getting screwed
by egotistical, hypocritical politicians who seem to think the internet exists
mainly so that they can &lt;a class="reference external" href="http://www.theguardian.com/world/2013/aug/06/queensland-mp-stands-down-sexting"&gt;distribute pictures of their&amp;nbsp;genitals.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There must be some way we can distract our politicians from
&lt;a class="reference external" href="http://www.couriermail.com.au/news/queensland/sexting-mp-peter-dowling-sent-explicit-images-to-secret-mistress/story-fnihsrf2-1226691713991"&gt;taking photos of their privates&lt;/a&gt;
long enough to explain our desire for a modern, reliable broadband network?
There must be some way to make them understand that we want our internet
the way we want our booze: reliably supplied, readily available, whenever
we want, wherever we happen to be living, and in quantities suitable for&amp;nbsp;binging.&lt;/p&gt;
&lt;p&gt;Anything less would be&amp;nbsp;un-Australian.&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h3&gt;Related&amp;nbsp;Posts:&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Part 1&lt;/strong&gt;: &lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/01/05/screwed-to-the-node/"&gt;Screwed To The&amp;nbsp;Node&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Screaming into the Broadband Void:&lt;/strong&gt;
&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/02/national-broadband-cyber-futility/"&gt;Part 1,&lt;/a&gt;
&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/19/quantitative-geek-screwing/"&gt;Part 2,&lt;/a&gt;
&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/27/hacking-government-an-ineffective-digital-militia/"&gt;Part 3,&lt;/a&gt;
&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/30/deviant-luddites-screwing-us/"&gt;Part&amp;nbsp;4.&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="NBN"></category><category term="Broadband"></category><category term="Ranting"></category><category term="Attempted Humour"></category></entry><entry><title>Screwed To The Node</title><link href="http://www.voidynullness.net/blog/2014/01/05/screwed-to-the-node/" rel="alternate"></link><published>2014-01-05T00:00:00+11:00</published><updated>2014-01-05T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2014-01-05:/blog/2014/01/05/screwed-to-the-node/</id><summary type="html">&lt;p class="first last"&gt;The futility of using logic and reason to convince illogical and unreasonable politicians that a Fibre to the Premises broadband network is the best&amp;nbsp;option.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;This whole &lt;a class="reference external" href="http://spectrum.ieee.org/telecom/internet/the-rise-and-fall-of-australias-44-billion-broadband-project"&gt;&lt;span class="caps"&gt;NBN&lt;/span&gt; thing&lt;/a&gt;
has got me thinking about what happens when the world of technology
intersects with the strange world of politics.  When geeks go up against
politicians, the &lt;a class="reference external" href="http://suck.mirror.theinfo.org/daily/2000/09/08/"&gt;geeks inevitably get screwed&lt;/a&gt;.  Which is exactly what is
happening in Australia with the National Broadband Network, now that the Coalition is in
power and determined to undermine Labor&amp;#8217;s visionary Fibre to the Premises (&lt;span class="caps"&gt;FTTP&lt;/span&gt;)
network with a crappy &lt;a class="reference external" href="http://www.zdnet.com/fttn-nbn-will-leave-a-bad-taste-in-voters-mouths-7000020694/"&gt;Fibre to the Node&lt;/a&gt;
(&lt;span class="caps"&gt;FTTN&lt;/span&gt;) &lt;a class="reference external" href="http://www.zdnet.com/fttn-hfc-are-dead-end-nbn-alternatives-samuel-7000005901/"&gt;alternative.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="http://www.businessspectator.com.au/article/2013/9/3/politics/dont-chuck-nbn-fibre-out-labor"&gt;Much&lt;/a&gt;
&lt;a class="reference external" href="http://www.businessspectator.com.au/article/2013/12/11/technology/nbn-wrecking-crew"&gt;has&lt;/a&gt;
&lt;a class="reference external" href="http://www.businessspectator.com.au/article/2013/7/30/technology/dumbing-down-nbn"&gt;been&lt;/a&gt;
&lt;a class="reference external" href="http://www.businessspectator.com.au/article/2013/10/4/technology/special-report-upgrading-coalition-nbn"&gt;written&lt;/a&gt;
to &lt;a class="reference external" href="http://www.sortius-is-a-geek.com/forget-dbcde-chose-fttp/"&gt;explain&lt;/a&gt;
that Labor&amp;#8217;s &lt;span class="caps"&gt;FTTP&lt;/span&gt; plan is
&lt;a class="reference external" href="http://www.sortius-is-a-geek.com/not-all-technology-is-equal/"&gt;superior&lt;/a&gt;
to the Liberal&amp;#8217;s &lt;span class="caps"&gt;FTTN&lt;/span&gt; version, by people quite knowledgeable on these
matters.  Which is all well and good, as long as we don&amp;#8217;t work under any
misapprehension that things like logic, facts, and technical details matter
in any way shape or form when it comes to&amp;nbsp;politics.&lt;/p&gt;
&lt;p&gt;Politics is a world seemingly untroubled by cognitive dissonance, heedless
of hypocrisy, and unconcerned with facts.  Which means we end up with the
sort of government where the head of a parliamentary ethics committee &amp;#8212;
and married Catholic &amp;#8212; is caught
&lt;a class="reference external" href="http://www.theguardian.com/world/2013/aug/06/queensland-mp-stands-down-sexting"&gt;sending pictures of his penis placed in a glass of red wine&lt;/a&gt;
to his mistress.  We end up with the sort of government where the
&lt;a class="reference external" href="http://www.smh.com.au/comment/tony-abbott-minister-for-women-no-thanks-20130919-2u179.html"&gt;Minister for Women&lt;/a&gt;
is an &lt;a class="reference external" href="http://www.liberal.org.au/member/tony-abbott"&gt;out of touch misogynist deeply unpopular with&amp;nbsp;women.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We end up with the sort of government that racks up debt while
&lt;a class="reference external" href="http://www.theage.com.au/business/robb-to-tackle-trans-pacific-partnership-20131205-2yttu.html"&gt;negotiating&lt;/a&gt;
&lt;a class="reference external" href="http://www.sbs.com.au/news/article/2013/12/06/what-you-need-know-about-trans-pacific-partnership"&gt;secret&lt;/a&gt;
&lt;a class="reference external" href="https://wikileaks.org/tpp/pressrelease.html"&gt;trade agreements,&lt;/a&gt;
&lt;a class="reference external" href="http://www.theguardian.com/world/2013/dec/23/big-tobacco-could-unduly-influence-trade-negotiations-julia-gillard-says"&gt;that&lt;/a&gt;
&lt;a class="reference external" href="http://aftinet.org.au/cms/node/519"&gt;undermine&lt;/a&gt;
&lt;a class="reference external" href="http://www.smh.com.au/business/robb-stands-firm-on-foreign-lawsuits-20130922-2u7tv.html"&gt;Australia&amp;#8217;s&lt;/a&gt;
&lt;a class="reference external" href="http://www.smh.com.au/federal-politics/political-news/australia-fails-antitobacco-bid-20131212-2zaml.html"&gt;sovereignty&lt;/a&gt;,
after hyperbolicaly complaining while in opposition about
&lt;a class="reference external" href="http://blogs.crikey.com.au/thestump/2013/09/22/the-emergency-that-wasnt-our-weekend-with-missingbudget/"&gt;budget&lt;/a&gt;
&lt;a class="reference external" href="http://www.abc.net.au/news/2013-10-17/koukoulas-budget-emergency-fiction/5028770"&gt;emergencies&lt;/a&gt;,
and insisting that poor people in leaky boats didn&amp;#8217;t deserve compasion because they were a threat to
Australia&amp;#8217;s&amp;nbsp;sovereignty.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s a sad indictment on our lobbying ability that we are losing even to
politicians unable to do their job effectively because they&amp;#8217;re too
distracted taking pictures of their junk with their smartphones &amp;#8212; and
sexting with&amp;nbsp;mistresses.&lt;/p&gt;
&lt;p&gt;Do we really think we can reason with people so unreasonable?  Do we really
think we can change their minds with logic, when their actions lack any
logic whatsoever?  (Or common sense, or basic decency for that matter!)  Do
we think we can change their minds with facts or technical details, when
they revel in their ignorance?  I don&amp;#8217;t think&amp;nbsp;so.&lt;/p&gt;
&lt;p&gt;Since facts, logic and reason count for little in politics, a strategy
relying on any combination of them is unlikely to succeed.  Especially in a
political landscape where hypocritical, hyperbolic bullshit reigns supreme.
Which is one of the reasons the technical community constantly get screwed
by those we elect to supposedly represent us &amp;#8212; because we seem to be
unable to out-bullshit the bullshitters.  Instead we misguidedly try to
reason with&amp;nbsp;them.&lt;/p&gt;
&lt;p&gt;So maybe we should try something else.  Something less logical.  Maybe we
should become as unreasonable as the politicians we are vainly trying to
reason with.  The politicians we are making bad political decisions that
affect&amp;nbsp;us.&lt;/p&gt;
&lt;p&gt;After all, why should we be constrained by facts, logic and reason, if our
politicians aren&amp;#8217;t?  If they&amp;#8217;re going to resort to hyperbolic
bullshit, then &lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/01/06/booze-to-the-node/"&gt;why shouldn&amp;#8217;t&amp;nbsp;we?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This gives me an idea.  &lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/01/06/booze-to-the-node/"&gt;Continued in part&amp;nbsp;2&amp;#8230;&lt;/a&gt;&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related&amp;nbsp;Posts:&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Part 2&lt;/strong&gt;: &lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/01/06/booze-to-the-node/"&gt;Booze To The&amp;nbsp;Node&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Screaming into the Broadband Void:&lt;/strong&gt;
&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/02/national-broadband-cyber-futility/"&gt;Part 1,&lt;/a&gt;
&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/19/quantitative-geek-screwing/"&gt;Part 2,&lt;/a&gt;
&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/27/hacking-government-an-ineffective-digital-militia/"&gt;Part 3,&lt;/a&gt;
&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/30/deviant-luddites-screwing-us/"&gt;Part&amp;nbsp;4.&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
</content><category term="NBN"></category><category term="Broadband"></category><category term="Ranting"></category><category term="Attempted Humour"></category></entry><entry><title>The Deviant Luddites Screwing Us</title><link href="http://www.voidynullness.net/blog/2013/12/30/deviant-luddites-screwing-us/" rel="alternate"></link><published>2013-12-30T00:00:00+11:00</published><updated>2013-12-30T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2013-12-30:/blog/2013/12/30/deviant-luddites-screwing-us/</id><summary type="html">&lt;p class="first last"&gt;It&amp;#8217;s bad enough we&amp;#8217;re being screwed, but it&amp;#8217;s worse that those screwing us are such incompetent&amp;nbsp;deviants.&lt;/p&gt;
</summary><content type="html">&lt;div class="section" id="screaming-into-the-broadband-void-part-4"&gt;
&lt;h2&gt;Screaming into the Broadband Void (Part&amp;nbsp;4)&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;It&amp;#8217;s a great day if you&amp;#8217;re a late night talk-show&amp;#8230;you
know&amp;#8230;thing&amp;#8230;this&amp;#8230;because&amp;#8230;former congressman Anthony Weiner is
returning to politics!  Listen, if you had to do this crap every day you
would love it when you hear a weiner is running.  Weiner running again?
That takes balls!  Then you could say things like: &amp;#8220;I guess you can&amp;#8217;t
keep a good weiner down.&amp;#8221; &amp;#8230; Now Weiner is a Democrat, but from what
I&amp;#8217;ve seen, sometimes he leans to the&amp;nbsp;right.&lt;/p&gt;
&lt;p class="attribution"&gt;&amp;mdash;Craig Ferguson, The Late Late Show, April&amp;nbsp;2013&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here in Australia, those of us with an interest in technology &amp;#8212; us geeks
&amp;#8212; are currently undergoing a gangbang sized screwing on two issues in
Australian politics that potentially have profound implications for the
whole country, but especially for anyone who works in &lt;span class="caps"&gt;IT&lt;/span&gt; and other
technology industries: The National Broadband Network, and the
&lt;a class="reference external" href="https://wikileaks.org/tpp/pressrelease.html"&gt;Trans-Pacific Partnership&amp;nbsp;Agreement&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The Coalition is giving up a historic opportunity to correct some of
the problems they caused by
&lt;a class="reference external" href="http://johnmenadue.com/blog/?p=807"&gt;privatising Telstra without structural separation.&lt;/a&gt;
Instead of continuing what Labor started and building a modern
Fibre to the Premises broadband network, they will doom
Australia to a future as a technological backwater with their
&lt;a class="reference external" href="http://www.businessspectator.com.au/article/2013/8/28/technology/can-australia-afford-coalitions-nbn"&gt;inferior&lt;/a&gt;
Fibre to the Node alternative.  Although perhaps that&amp;#8217;s just as well, because if the
&lt;a class="reference external" href="http://www.crikey.com.au/2013/12/11/has-australia-caved-in-on-the-trans-pacific-partnership/"&gt;intellectual property&lt;/a&gt;
&lt;a class="reference external" href="http://en.wikipedia.org/wiki/Trans-Pacific_Partnership_intellectual_property_provisions"&gt;provisions&lt;/a&gt;
of the
&lt;a class="reference external" href="https://www.eff.org/issues/tpp"&gt;Trans-Pacific Partnership&lt;/a&gt;
are implemented as currently drafted, doing just about
&lt;a class="reference external" href="http://theconversation.com/ip-trade-negotiations-a-prescription-for-harm-20141"&gt;anything&lt;/a&gt;
useful on the internet will become
&lt;a class="reference external" href="http://theconversation.com/regional-trade-pact-puts-australia-in-absurd-position-say-experts-20299"&gt;illegal&lt;/a&gt;!  Even
&lt;a class="reference external" href="http://www.policymic.com/articles/73537/trans-pacific-partnership-5-reasons-why-this-matters-to-millennials"&gt;innocuous web browsing&lt;/a&gt;
will &lt;a class="reference external" href="https://www.eff.org/deeplinks/2012/08/whats-wrong-tpp"&gt;become a crime&lt;/a&gt;!
Yes, they&amp;#8217;re even trying to make
&lt;a class="reference external" href="https://www.eff.org/deeplinks/2012/07/temporary-copies-another-way-tpp-profoundly-disconnected"&gt;web browsers illegal&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;span class="caps"&gt;TPP&lt;/span&gt; is an odious attempt by multi-national corporations to control the
way we use the internet and consume media content (ebooks, music, movies
etc).  It&amp;#8217;s an attempt to eliminate all kinds of common consumer
behaviour &amp;#8212; like transferring legitimately purchased media from one
legitimately purchased device to another for more convenient consumption of
that media.  The &lt;span class="caps"&gt;TPP&lt;/span&gt; is, amongst other things, an attempt to ensure you may
only consume the media you purchase in the way the corporation you
purchased it from wants you to consume it, regardless of convenience.  It&amp;#8217;s
an attempt to make sure you can only use their proprietary software with
their proprietary hardware and their proprietary copy
protection &amp;#8212; all of it incompatible with those of their&amp;nbsp;competitors.&lt;/p&gt;
&lt;p&gt;Welcome to the future.  Only in a world where using the internet is mostly
illegal does having a crappy Fibre to the Node network make any kind of&amp;nbsp;sense.&lt;/p&gt;
&lt;p&gt;That&amp;#8217;s the sort of future our wonderfully competent elected leaders are
envisioning for&amp;nbsp;us.&lt;/p&gt;
&lt;p&gt;As the &lt;span class="caps"&gt;NBN&lt;/span&gt; rollout continues &amp;#8212; albeit Malcolm Turnbull&amp;#8217;s crappy, crippled
&lt;span class="caps"&gt;FTTN&lt;/span&gt; version &amp;#8212; and as node cabinets start appearing on street
corners, each one will represent a failure of us in the technology
industries to make a difference in the political process.  Each one will be
a monument to our geeky failures, and further proof of the uselessness of
&lt;a class="reference external" href="http://www.change.org/en-AU/petitions/the-liberal-party-of-australia-reconsider-your-plan-for-a-fttn-nbn-in-favour-of-a-superior-ftth-nbn"&gt;slacktivism&lt;/a&gt;.  Each one will be a reminder of how effectively our political overlords
&lt;a class="reference external" href="http://suck.mirror.theinfo.org/daily/2000/09/08/"&gt;are screwing us&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;However, as the year comes to an end, if we look back at some of the things
our beloved political masters did that made headlines, it certainly makes
one wonder about the calibre of our esteemed elected leaders.  It makes one
question their character, and reflect on their shortcomings.  Yet, these
are the sorts of people who are so efficiently screwing us?  Once again,
this year showed that just when we thought that the dignity of public
office couldn&amp;#8217;t be disgraced any further, our beloved elected officials
proved there were always new depths of disgrace to&amp;nbsp;plumb.&lt;/p&gt;
&lt;p&gt;Canada provided
&lt;a class="reference external" href="http://www.torontolife.com/informer/toronto-politics/2013/11/05/rob-ford-jon-stewart-howard-stern-jay-leno/"&gt;comedians&lt;/a&gt;
around the world with the gift of
&lt;a class="reference external" href="http://www.youtube.com/watch?v=kkGSUzhAw1s"&gt;Rob Ford&lt;/a&gt;,
&lt;a class="reference external" href="http://www.washingtonpost.com/opinions/rob-ford-torontos-crack-smoking-mayor-finally-a-famous-canadian-politician/2013/11/08/92ce9812-47f9-11e3-b6f8-3782ff6cb769_story.html"&gt;Toronto&amp;#8217;s crack-smoking mayor.&lt;/a&gt;
But he only smoked crack while in a drunken stupor,
&lt;a class="reference external" href="http://www.huffingtonpost.com/2013/11/22/rob-ford-obama-congress-toronto_n_4326169.html"&gt;so that&amp;#8217;s &lt;span class="caps"&gt;OK&lt;/span&gt;,&lt;/a&gt;
apparently, &lt;a class="reference external" href="http://www.dailymail.co.uk/news/article-2525710/Red-faced-sweating-crack-smoking-Toronto-mayor-dances-sober-Bob-Marleys-One-Love-middle-council-chambers.html"&gt;in Canada&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In the &lt;span class="caps"&gt;US&lt;/span&gt;, former San Diego Mayor and purveyor of
&lt;a class="reference external" href="http://en.wikipedia.org/wiki/File:Bob_Filner.jpg"&gt;creepy smiles&lt;/a&gt;, Bob Filner, was
&lt;a class="reference external" href="http://www.nytimes.com/2013/10/16/us/criminal-charges-for-bob-filner-former-san-diego-mayor.html?_r=0"&gt;sentenced&lt;/a&gt;
&lt;a class="reference external" href="http://www.nydailynews.com/news/politics/ex-san-diego-mayor-bob-filner-sentenced-harassment-article-1.1542147"&gt;for&lt;/a&gt;
&lt;a class="reference external" href="http://www.theguardian.com/world/2013/dec/09/san-diego-mayor-bob-filner-sexual-harassment"&gt;sexual&lt;/a&gt;
&lt;a class="reference external" href="http://www.theguardian.com/world/2013/dec/09/san-diego-mayor-bob-filner-sexual-harassment-sentencing"&gt;harassment.&lt;/a&gt;
Disgraced former New York Governor and &lt;a class="reference external" href="http://www.nydailynews.com/new-york/high-end-hooker-gov-eliot-spitzer-scary-article-1.1560783"&gt;call girl aficionado&lt;/a&gt;
Eliot Spitzer &lt;a class="reference external" href="http://www.huffingtonpost.com/2013/09/10/eliot-spitzer-scott-stringer-nyc-comptroller_n_3894238.html"&gt;tried and failed&lt;/a&gt;
to become New York City&amp;nbsp;Comptroller.&lt;/p&gt;
&lt;p&gt;Even renown sexter Anthony Weiner attempted an &lt;a class="reference external" href="http://bigstory.ap.org/article/even-most-ny-voters-embarrassed-weiner-spitzer"&gt;apologetic political comeback&lt;/a&gt;.
He was even leading in the polls early on, before his campaign was
ultimately &lt;a class="reference external" href="http://bigstory.ap.org/article/pundits-wonder-why-wont-weiner-just-leave-race"&gt;derailed&lt;/a&gt;
by another sexting scandal, proving that Weiner (&lt;span class="caps"&gt;AKA&lt;/span&gt; &amp;#8220;Carlos Danger&amp;#8221;)
really is the comedy gift that keeps on&amp;nbsp;giving.&lt;/p&gt;
&lt;p&gt;The Spitzer and Weiner comeback campaigns make me wonder about the people
who dedicated resources (money, time, manpower) to help these individuals
get elected.  I’m all for second chances, but is the talent pool really so
shallow that there weren&amp;#8217;t any worthwhile, non-sexting,
&lt;a class="reference external" href="http://nypost.com/2013/12/29/call-girl-tell-all-eliot-spitzer-liked-to-choke-me-was-into-struggle/"&gt;non-call-girl-choking&lt;/a&gt;
candidates to whom those resources could have been better allocated?  If
nothing else, in Weiner&amp;#8217;s case, it showed he had learnt nothing the first
time round, and was certainly not worthy of second&amp;nbsp;chances.&lt;/p&gt;
&lt;p&gt;Here in Australia we had our own Weineresque
&lt;a class="reference external" href="http://bigstory.ap.org/article/aussie-state-ethics-chair-embroiled-sex-scandal"&gt;sexting scandal&lt;/a&gt;,
when revelations surfaced that Queensland &lt;span class="caps"&gt;MP&lt;/span&gt; &lt;a class="reference external" href="http://www.couriermail.com.au/news/queensland/sexting-mp-peter-dowling-sent-explicit-images-to-secret-mistress/story-fnihsrf2-1226691713991"&gt;Peter Dowling&lt;/a&gt;
had taken &lt;a class="reference external" href="http://www.theaustralian.com.au/news/features/an-old-fashioned-scandal/story-e6frg6z6-1226693031208"&gt;pictures of his penis&lt;/a&gt;
placed in a glass of red wine and sent them to his mistress.  This from a
married conservative family man, a supposedly devout Catholic, and
chair of the parliamentary ethics&amp;nbsp;committee!&lt;/p&gt;
&lt;p&gt;I wonder if there was any point in time, before the media got hold of the
story, that Peter Dowling realised the irony and blatant hypocrisy of what
he was doing?  I wonder if just before he was about to send a dick pic to
his mistress, he ever paused for a moment, to ponder if maybe this would at
some point in the future come back to haunt him?  I wonder if, during his
liaisons with his mistress, it ever occurred to him that, as a conservative
family values politician and chairman of the parliament&amp;#8217;s ethics committee,
perhaps screwing around on his wife wasn&amp;#8217;t the best career move, not to
mention morally&amp;nbsp;questionable?&lt;/p&gt;
&lt;p&gt;I suspect not.  There seems to be something about the ego and lack of self awareness of politicians that engenders such blatant tone-deaf hypocrisy.  It&amp;#8217;s the same runaway ego and lack of self-awareness that results in Tony Abbott appointing himself minister for women, most likely completely oblivious to how obnoxious the whole idea appears to an electorate that sees him as misogynistic and out of touch with&amp;nbsp;women.&lt;/p&gt;
&lt;p&gt;Just like it&amp;#8217;s the same level of misguided yet egotistical stubbornness that enables Malcolm Turnbull to advocate for a Fibre to the Node broadband network in the face of ridicule and criticism from the entire technical&amp;nbsp;community.&lt;/p&gt;
&lt;p&gt;It would no doubt be an understatement to suggest that a family values advocating leader of a parliamentary ethics committee taking pictures of his penis in a glass of wine and sending them to his mistress &amp;#8212; perhaps not even considering the possibility of repercussions &amp;#8212; probably has his fair share of personality&amp;nbsp;flaws.&lt;/p&gt;
&lt;p&gt;I suspect it&amp;#8217;s the same kind of personality flaws that enable Malcolm Turnbull to push forward with his silly plans for a Fibre to the Node broadband network, ensconced in the comforting self-delusion that all the experts deriding &lt;span class="caps"&gt;FTTN&lt;/span&gt; technology are wrong, and that there won&amp;#8217;t be any negative repercussions resulting from his choice of inferior networking technology.  I&amp;#8217;m sure Malcolm believes no one will notice the slow speeds and dropouts &amp;#8212; just like no one currently notices the &lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/09/01/australian-broadband-hustle/"&gt;slow speeds and dropouts of &lt;span class="caps"&gt;ADSL&lt;/span&gt;.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Politics is a strange job, and it attracts some strange people, often for all the wrong reasons.  It&amp;#8217;s pretty obvious by now that our politicians are generally deeply flawed individuals.  It might even be their flaws that help them succeed in the strange world of&amp;nbsp;politics.&lt;/p&gt;
&lt;p&gt;I think this might explain why us geeks constantly get screwed over by these dick pick distributing deviants.  There is a huge disparity in personality types and abilities between the world of politics and the world of technology.  They require vastly different skills and personality traits to succeed.  That might be partly why our political leaders make such incredibly bad decisions on matter relating to technology &amp;#8212; they don&amp;#8217;t understand us.  And it&amp;#8217;s also partly why we don&amp;#8217;t fight back effectively &amp;#8212; because we don&amp;#8217;t understand them.  We tend to naively think that we can reason with them.  That we can change their minds by explaining the technical merit of our position.  So we blog and tweet and sign online petitions and post in forums &amp;#8212; all of it pointlessly screaming into the digital void.  Because politicians don&amp;#8217;t care about any of that.  None of that directly affects them in their quest for whatever emotional validation they seek by trying to attain public office.  None of that directly affects their quest for personal gain, power, ego and status &amp;#8212; so they don&amp;#8217;t&amp;nbsp;care.&lt;/p&gt;
&lt;p&gt;Which means to make them care about our geeky concerns, we probably need to learn to think a bit like our deviant political overlords &amp;#8212; as disturbing and distasteful as that prospect may be.  Because surely their flaws and seeming lack of self control could provide some sort of advantage for us?  Since our political leaders seem incapable of anything except taking pictures of their genitals and distributing them to unsuspecting women on social media, isn&amp;#8217;t there any way we can take advantage of&amp;nbsp;this?&lt;/p&gt;
&lt;p&gt;Because it&amp;#8217;s bad enough we&amp;#8217;re being screwed, but it&amp;#8217;s worse that we&amp;#8217;re being screwed by these incompetent, power hungry, sex crazed egotists with no self control and and even less self awareness.  These are the people who are screwing us?  These dick pic distributing deviants?  These family values campaigners by day, and adulterous whore mongers by&amp;nbsp;night?&lt;/p&gt;
&lt;p&gt;We tend to think we&amp;#8217;re kinda smart, aren&amp;#8217;t we?  So is there no way we can outsmart our politically meddlesome masters?  Is there no way we can take advantage of their character flaws to get a good outcome on technology issues we care about?  (And leave them to destroy their own careers in entertainingly embarrassing ways the rest of the&amp;nbsp;time?)&lt;/p&gt;
&lt;p&gt;While our salacious political leaders are busy cavorting with prostitutes and taking pictures of their cocks, can&amp;#8217;t we somehow work out a way to get decent broadband?  While they&amp;#8217;re distracted with finding novel ways to destroy their reputations, can&amp;#8217;t we work out ways to preserve our online freedoms?  While they&amp;#8217;re sticking their dicks in glasses of wine, can&amp;#8217;t we work out ways to reform the patent&amp;nbsp;system?&lt;/p&gt;
&lt;p&gt;Who knows, maybe somehow, in this process, if our political leaders realise we&amp;#8217;re watching them closely, ready to use any of their weaknesses or indiscretions against them, maybe one day there might come a time where some dignity is restored to public&amp;nbsp;office.&lt;/p&gt;
&lt;p&gt;At least until the next sexting&amp;nbsp;scandal.&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h3&gt;Related&amp;nbsp;Posts:&lt;/h3&gt;
&lt;p class="introblock"&gt;This post is &lt;strong&gt;part 4&lt;/strong&gt; of a loose series of rants partly inspired by the stupid
political fuckery surrounding the National Broadband Network.  I know it&amp;#8217;s
pointless writing about this stuff, but sometimes I just need to vent.
More of me &lt;strong&gt;screaming into the broadband void&lt;/strong&gt;:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/02/national-broadband-cyber-futility/"&gt;Part 1: National Broadband&amp;nbsp;Cyber-Futility&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/19/quantitative-geek-screwing/"&gt;Part 2: Quantitative Geek&amp;nbsp;Screwing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/27/hacking-government-an-ineffective-digital-militia/"&gt;Part 3: Hacking Government: An Ineffective Digital&amp;nbsp;Militia&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section" id="see-also"&gt;
&lt;h3&gt;See&amp;nbsp;Also:&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/01/05/screwed-to-the-node/"&gt;Screwed To The&amp;nbsp;Node&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/01/06/booze-to-the-node/"&gt;Booze To The&amp;nbsp;Node&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="Attempted Humour"></category><category term="Ranting"></category><category term="NBN"></category><category term="TPP"></category><category term="Politics"></category></entry><entry><title>Hacking Government: An Ineffective Digital Militia</title><link href="http://www.voidynullness.net/blog/2013/12/27/hacking-government-an-ineffective-digital-militia/" rel="alternate"></link><published>2013-12-27T00:00:00+11:00</published><updated>2013-12-27T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2013-12-27:/blog/2013/12/27/hacking-government-an-ineffective-digital-militia/</id><summary type="html">&lt;p class="first last"&gt;The lack of serious gun control in the &lt;span class="caps"&gt;US&lt;/span&gt; is a testament to how effective the &lt;span class="caps"&gt;NRA&lt;/span&gt; and gun lobbyists are at stopping the government from encroaching on their gun rights.  By contrast, things like a fundamentally broken patent system and legislation like the &lt;span class="caps"&gt;DMCA&lt;/span&gt; are a testament to how useless geeks are at stopping the government from encroaching on their digital&amp;nbsp;rights.&lt;/p&gt;
</summary><content type="html">&lt;div class="section" id="digitally-pissing-in-the-wind-part-3"&gt;
&lt;h2&gt;Digitally Pissing in the Wind (Part&amp;nbsp;3)&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span class="dquo"&gt;&amp;#8220;&lt;/span&gt;I do think the pace of change in the world is increasing. Part of what I
would think about is, I think that we haven’t adapted mechanisms to deal
with some of our old institutions like the law and so on aren’t keeping
up with the rate of change that we’ve caused through technology. You
know, if you look different kinds of laws we make, and things like that,
they’re very old. &amp;#8230;The other thing in my mind is we also haven’t maybe
built mechanisms to allow experimentation. There’s many, many exciting
and important things you could do that you just can’t do ’cause they’re
illegal or they’re not allowed by regulation. And that makes sense, we
don’t want our world to change too fast. But maybe we should set aside
some small part of the world, you know, like going to Burning Man, for
example. Which I’m sure many of you have been to. Yeah, a few Burners out
there. That’s an environment where people try out different things, but
not everybody has to go. And I think that’s a great thing, too. I think
as technologists we should have some safe places where we can try out
some new things and figure out: What is the effect on society? What’s the
effect on people?  Without having to deploy it into the normal world. And
people who like those kinds of things can go there and experience
that. And we don’t have mechanisms for that. So those are the kind of
things I would think&amp;nbsp;about.&amp;#8221;&lt;/p&gt;
&lt;p class="attribution"&gt;&amp;mdash;Larry Page, Google I/O 2013&amp;nbsp;keynote&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;The lack of serious gun control in the &lt;span class="caps"&gt;US&lt;/span&gt; is a testament to how effective
the &lt;span class="caps"&gt;NRA&lt;/span&gt; and gun lobbyists are at stopping the government from encroaching
on their gun rights.  By contrast, things like a fundamentally broken
patent system and legislation like the &lt;span class="caps"&gt;DMCA&lt;/span&gt; are a testament to how useless
geeks are at stopping the government from encroaching on their digital&amp;nbsp;rights.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s strange to observe the
&lt;a class="reference external" href="http://www.theage.com.au/world/sandy-hook-massacre-gun-lobby-targets-australia-20131212-hv5ed.html"&gt;gun control debate&lt;/a&gt;
occurring in the &lt;span class="caps"&gt;US&lt;/span&gt;.  Especially living half a world away, in a country
that has had very strict gun control laws for many years, an no more mass
shootings as a result.  It&amp;#8217;s strange hear the invective used by the gun
lobby about gun control laws being akin to government tyranny, when here in
Australia things don&amp;#8217;t seem any more tyrannical than any other alleged
democracy.  It&amp;#8217;s easy to make fun of Americans and their love of
guns (though not if there are any in the room, because they&amp;#8217;d probably be
armed), and it&amp;#8217;s easy to mock the &lt;span class="caps"&gt;NRA&lt;/span&gt; and their ridiculously overwrought
and hyperbolic stance on gun control.  Especially if one&amp;#8217;s main source of
overseas news is &lt;a class="reference external" href="http://www.youtube.com/playlist?list=PLOKWcH1zBl2kfnCwyyZWk5MW28lgaNa7L"&gt;The Daily Show&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Yet, even though the issue of gun control is not one that I have much
personal interest in, I have been thinking a bit about the &lt;span class="caps"&gt;NRA&lt;/span&gt; because of two
current issues in Australian politics that have no (obvious) connection
with guns &amp;#8212; the newly elected Coalition government&amp;#8217;s
&lt;a class="reference external" href="http://delimiter.com.au/2013/09/07/fttp-dream-coalition-victory-kills-labors-nbn/"&gt;vastly inferior Fibre To The Node&lt;/a&gt;
plan for the National Broadband Network, and
&lt;a class="reference external" href="https://wikileaks.org/tpp/pressrelease.html"&gt;The Trans-Pacific Partnership Agreement&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Both are just two recent examples of something that&amp;#8217;s been happening over
and over again for long time now, all over the world &amp;#8212; politicians doing
really stupid things and making really bad decisions when it comes to
matters of technology, while those most affected do little to effectively
fight back.  It&amp;#8217;s politicians and other Merchants of Bullshit in power
&lt;a class="reference external" href="http://www.suck.com/daily/2000/09/08/"&gt;screwing the geeks&lt;/a&gt;
&amp;#8212; and winning.  Of course, with the way technology is
now a part of everyday life for most people, this means it&amp;#8217;s not just the
geeks getting screwed &amp;#8212; it&amp;#8217;s pretty much everyone that uses the internet
in any way, shape or form.  In the case of the &lt;span class="caps"&gt;TPP&lt;/span&gt;, the effects of the
technologically toxic intellectual property provisions will &lt;a class="reference external" href="http://www.smh.com.au/business/world-business/trade-secrets-why-is-the-us-so-quiet-on-the-transpacific-partnership-20131220-2zqv2.html"&gt;affect&lt;/a&gt; just
about &lt;a class="reference external" href="http://www.smh.com.au/federal-politics/political-news/australians-may-pay-the-price-in-transpacific-partnership-free-trade-agreement-20131113-2xh0m.html"&gt;everyone&lt;/a&gt;.  As &lt;a class="reference external" href="https://wikileaks.org/tpp/pressrelease.html"&gt;Julian Assange eloquently put it&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&amp;#8220;If you read, write, publish, think, listen, dance, sing or invent; if
you farm or consume food; if you’re ill now or might one day be ill, the
&lt;span class="caps"&gt;TPP&lt;/span&gt; has you in its crosshairs.&amp;#8221;&lt;/blockquote&gt;
&lt;p&gt;Modern democracy has wandered far from any ideals of government by the people
and for the people.  The &lt;span class="caps"&gt;TPP&lt;/span&gt; is a great example of government by the rich
elite for &lt;a class="reference external" href="http://pirateparty.org.au/2013/11/14/trans-pacific-partnership-ip-chapter-leaked-enforcement-provisions-abound/"&gt;multinational corporations&lt;/a&gt;
&amp;#8212; as large corporations are the &lt;em&gt;only&lt;/em&gt; beneficiaries of the &lt;span class="caps"&gt;IP&lt;/span&gt; changes, and
everyone else is worse&amp;nbsp;off.&lt;/p&gt;
&lt;p&gt;I find that above quote from Larry Page kind of disturbing, because it
seems to imply that even a company with the money, power and influence of
Google doesn&amp;#8217;t know how to &lt;a class="reference external" href="http://arstechnica.com/business/2013/05/larry-page-wants-you-to-stop-worrying-and-let-him-fix-the-world/"&gt;hack government&lt;/a&gt;.
Even &lt;a class="reference external" href="http://www.washingtonpost.com/wp-dyn/content/article/2006/06/06/AR2006060601723.html"&gt;Google doesn&amp;#8217;t seem to know&lt;/a&gt;
how to deal with technologically clueless yet meddlesome politicians who
often don&amp;#8217;t understand the repercussions of their actions.  This is in
stark contrast to the &lt;span class="caps"&gt;NRA&lt;/span&gt; and the gun lobby, who seem to have a remarkable
ability to get politicians to do what they want, even if what they want is
kind of insane.  While it might be hard to read into the thinking behind
Larry Page&amp;#8217;s rambling
&lt;a class="reference external" href="http://www.techhive.com/article/2038841/hello-larry-googles-page-on-negativity-laws-and-competitors.html"&gt;Google I/O 2013 keynote speech&lt;/a&gt;,
a lot of it does sound like a geek frustrated at being
&lt;a class="reference external" href="http://www.moneymorning.com.au/20131130/23andme-and-the-witch-hunt-over-your-dna.html"&gt;screwed&lt;/a&gt;
by
&lt;a class="reference external" href="http://www.dailyreckoning.com.au/why-multinationals-run-a-better-ship-than-government/2013/05/27/"&gt;government.&lt;/a&gt;
But while Page might be imagining a
&lt;a class="reference external" href="http://www.huffingtonpost.com/2013/05/20/tech-burning-man_n_3308018.html"&gt;fanciful geek utopia&lt;/a&gt;
unrestrained by burdensome, restrictive and misguided government intrusion,
I&amp;#8217;m wondering where are the geek equivalents of
&lt;a class="reference external" href="http://en.wikipedia.org/wiki/Wayne_LaPierre"&gt;Wayne LaPierre&lt;/a&gt;, the &lt;span class="caps"&gt;NRA&lt;/span&gt;&amp;#8217;s
executive vice president &amp;#8212; a guy with an uncanny ability to keep
government at bay in the face of much media ridicule and public hostility.
Where are the tech industry&amp;#8217;s rhetorical soldiers in the war against
government&amp;nbsp;overreach?&lt;/p&gt;
&lt;p&gt;If it&amp;#8217;s too hyperbolic to describe it as a war, then it is at the very
least a game.  It&amp;#8217;s a game we have to play whether we like it or not, no
matter how distasteful or uninteresting it may be, if we want to have any
chance protecting our digital rights and&amp;nbsp;freedoms.&lt;/p&gt;
&lt;p&gt;The &lt;span class="caps"&gt;NRA&lt;/span&gt; appears to be an organisation that&amp;#8217;s &lt;a class="reference external" href="http://www.salon.com/2013/04/13/how_the_nra_got_what_it_wanted/"&gt;remarkably effective&lt;/a&gt; at
playing the dirty game of politics, even though it&amp;#8217;s far more concerned
with the interests of its
&lt;a class="reference external" href="http://www.huffingtonpost.com/josh-horwitz/the-conspiracy-theory-the_b_4069538.html"&gt;corporate backer in the firearms industry&lt;/a&gt;
than the rights of individual gun&amp;nbsp;owners.&lt;/p&gt;
&lt;p&gt;Even though I care little for their cause, I find myself fascinated by
their methods.  Like them or loathe them, they are obviously effective.
Much like money printing economists, the gun lobby is very good at getting
politicians to do insane things, like letting insane people easily buy
guns.  While economists have managed to convince the nation that the cure
for an economy crippled by too much debt is more debt, the gun lobby have
managed to convince the nation that the cure for a country plagued by gun
violence is more&amp;nbsp;guns.&lt;/p&gt;
&lt;p&gt;Both economists and the gun lobby have demonstrated the remarkable power of
bullshitting to achieve their insane ends.  So maybe there&amp;#8217;s something us
geeks can learn from all this, as we struggle to battle governments more
and more determined to encroach on our technology industries, and take away
our digital rights and&amp;nbsp;freedoms.&lt;/p&gt;
&lt;p&gt;Maybe there is some truth in the overblown rhetoric of the &lt;span class="caps"&gt;NRA&lt;/span&gt;.  Maybe in
the modern bullshit world of politics corrupted by mega-corporations with
their mega-campaign-donations, there is no such thing as government
without government overreach.  Because there will always be an&amp;nbsp;agenda.&lt;/p&gt;
&lt;p&gt;Perhaps the gun lobby is right to fear a little gun control will lead to a
lot of gun control.  After all, it started with a little software patent
sneaking it&amp;#8217;s way into the patent system, and now decades later, stuffed
full of junk software patents, the patent system is a horrible, broken,
bloated mess that stifles innovation and benefits no one apart from patent
trolls and large&amp;nbsp;corporations.&lt;/p&gt;
&lt;p&gt;Perhaps the gun lobby is right to fear a gun owner database, as a little
government data collection will inevitably lead to lots of government data
collection.  Just like limited government power to intercept communications
of criminals and select terror suspects has lead to the &lt;span class="caps"&gt;NSA&lt;/span&gt; building a
multi-billion dollar data centre so they can read and store every email from
everyone everywhere&amp;nbsp;forever!&lt;/p&gt;
&lt;p&gt;So maybe the solution to overzealous government sticking its tentacles
where they don&amp;#8217;t belong, is to fight bullshit with bullshit.  So maybe the
gun advocates have got the right idea.  They are not giving the government
the benefit of the doubt.  At all.  No wriggle room, no leeway.  Because
maybe they have a point: That any government, given half chance, will abuse
any power it is given.  So they do whatever they can to stop even
reasonable gun control measures, out of a perhaps a legitimate fear that
reasonable gun control will inevitably lead to unreasonable gun control.
So the try to ensure the government doesn&amp;#8217;t get any more power, no matter
how well meaning the intent of that power might&amp;nbsp;be.&lt;/p&gt;
&lt;p&gt;There is possibly as lesson for us geeks in all this.  Maybe this is the
attitude we need to adopt.  After all, we have been screwed many times by
government overreach.  Legitimate intellectual property laws (copyright)
lead to a broken intellectual property system (software patents, &lt;span class="caps"&gt;DRM&lt;/span&gt;).
Small scale wiretaps lead to widespread &lt;span class="caps"&gt;NSA&lt;/span&gt; spying.  Give the government an
inch, and they pull the whole fucking rope out of your hands and arrest you
on suspicion of terrorism!  (Because who else but a terrorist would be
holding a rope!)  So maybe it&amp;#8217;s time for an &lt;span class="caps"&gt;NRA&lt;/span&gt; style zero tolerance
approach to government restrictions in the digital realm, complete with
hyperbolic rhetoric.  No software patents, because software patents are
stifling innovations and destroying the technology industry.  No
censorship, because the government will inevitably use it to curtail free
speech.  No copy protection, because a little copy protection will lead to
restricted competition and monopolistic practices by&amp;nbsp;corporations.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s also instructive to note that not only is the &lt;span class="caps"&gt;NRA&lt;/span&gt; good at what it
does, but it no doubt helps that gun owners tend to be a vocal and
passionate bunch.  This quote from
&lt;a class="reference external" href="http://web.bryant.edu/~gcarter/bio/bio.html"&gt;an academic&lt;/a&gt; in a
&lt;a class="reference external" href="http://www.salon.com/2013/05/01/big_money_arms_the_nra_partner/"&gt;Salon.com article&lt;/a&gt;
sums things up&amp;nbsp;nicely:&lt;/p&gt;
&lt;blockquote&gt;
&amp;#8220;The issue is not so much how much the &lt;span class="caps"&gt;NRA&lt;/span&gt; gives any senator or member of
the House, it’s how they can make their lives miserable. And how they
make their lives miserable is they e-mail ’em, they call ’em, they fax
’em, they show up at meetings. The typical person who is for gun control
is very different from the [pro-gun] person calling you or being right
there, being an annoyance, hassling you personally. They’re much more
activist than the other side and that’s what really produces their
gains.&amp;#8221;&lt;/blockquote&gt;
&lt;p&gt;Compare and contrast this to the pointless geeky &lt;a class="reference external" href="http://www.change.org/en-AU/petitions/the-liberal-party-of-australia-reconsider-your-plan-for-a-fttn-nbn-in-favour-of-a-superior-ftth-nbn"&gt;slacktivism&lt;/a&gt;
of opponents to the Coalition&amp;#8217;s &lt;span class="caps"&gt;FTTN&lt;/span&gt; &lt;span class="caps"&gt;NBN&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;We geeks bitch and moan in blogs, online forums and social media, where
politicians don&amp;#8217;t care and don&amp;#8217;t notice.  It&amp;#8217;s time to take the battle into
the real world, and really get in the face of politicians, if we want to
make a&amp;nbsp;difference.&lt;/p&gt;
&lt;p&gt;Politicians are going to keep screwing us geeks until we learn how the make
politicians fear us, in the same way American politicians fear the wrath of
the gun&amp;nbsp;lobby.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s time for the geeks to take a stand.  It&amp;#8217;s time to let the politicians
know that we will not give up our digital rights without a real fight &amp;#8212;
in the real world.  It&amp;#8217;s time to let the politicians know they will have to
pry our digital rights from our virtual cold dead digital&amp;nbsp;hands.&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h3&gt;Related&amp;nbsp;Posts:&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Digitally Pissing in the&amp;nbsp;Wind:&lt;/strong&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/02/national-broadband-cyber-futility/"&gt;Part 1: National Broadband&amp;nbsp;Cyber-Futility&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/19/quantitative-geek-screwing/"&gt;Part 2: Quantitative Geek&amp;nbsp;Screwing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/30/deviant-luddites-screwing-us/"&gt;Part 4: The Deviant Luddites Screwing&amp;nbsp;Us&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="Ranting"></category><category term="Attempted Humour"></category><category term="NBN"></category><category term="TPP"></category><category term="Trans Pacific Partnership"></category></entry><entry><title>Quantitative Geek Screwing</title><link href="http://www.voidynullness.net/blog/2013/12/19/quantitative-geek-screwing/" rel="alternate"></link><published>2013-12-19T00:00:00+11:00</published><updated>2013-12-19T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2013-12-19:/blog/2013/12/19/quantitative-geek-screwing/</id><summary type="html">&lt;p class="first last"&gt;Occasionally, I like to ponder the tough (and possibly nonsensical) questions in life, like why do politicians pay no attention when knowledgeable people within technology industries make logical and well thought arguments on issues that directly affect their industries, yet thoroughly discredited economists, who have been proven wrong many times before, still wield so much power that they can influence politicians to implement illogical policies that would have once been considered completely&amp;nbsp;crazy?&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;strong&gt;Again.&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The only kind of economics that is worth a damn is philosophical, not
mathematical or scientific. Real economics is philosophical – like
history or literature – in the sense that it merely tries to observe and
understand, not to manipulate people as if they were pawns on a&amp;nbsp;chessboard.&lt;/p&gt;
&lt;p&gt;The other kind of economics – modern, &amp;#8220;scientific&amp;#8221; economics – is a
fraud. It pretends not only to understand an economy, but also to be able
to improve&amp;nbsp;it.&lt;/p&gt;
&lt;p&gt;Modern economists have been at it for nearly 100 years: planning,
organizing, theorizing, controlling, adjusting, pontificating, forcing,
setting prices, suppressing interest rates and committing other acts of
wanton economic vandalism. During that time, there has not been a single
confirmed sighting of anything close to&amp;nbsp;success.&lt;/p&gt;
&lt;p class="attribution"&gt;&amp;mdash;&lt;a class="reference external" href="http://www.bonnerandpartners.com/wanton-economic-vandalism/"&gt;Bill&amp;nbsp;Bonner&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Occasionally, I like to ponder the tough (and possibly nonsensical) questions in life.  Like, why do politicians pay no attention when knowledgeable people within technology industries make logical and well thought arguments on issues that directly affect their industries?  Yet, thoroughly discredited economists, who have been proven wrong many times before, still wield so much power that they can influence politicians to implement illogical policies that would have once been considered completely&amp;nbsp;crazy?&lt;/p&gt;
&lt;p&gt;What leads me to such pondering is the confluence of recent events.  In particular, the global financial crisis and its aftermath; and more recently, the federal election here in Australia.  As predicted, the Coalition comfortably won the election, which will likely have many implications for the technology community in Australia, but perhaps the most prominent concern is the fate of the National Broadband Network.  With the Liberal Party in charge, the mostly fibre &lt;span class="caps"&gt;NBN&lt;/span&gt; as we know it is now&amp;nbsp;dead.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s unfortunate that the issue of
&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/02/national-broadband-cyber-futility/"&gt;broadband infrastructure has become so politicised in Australia.&lt;/a&gt;
It means that those of us involved with technology &amp;#8212; the geeks of Australia &amp;#8212; are going to be screwed.  Again.  Because based on past experience, when it comes to battling politicians, &lt;a class="reference external" href="http://www.suck.com/daily/2000/09/08/"&gt;we tend to&amp;nbsp;lose.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sure, us geeks might have a &lt;a class="reference external" href="https://www.eff.org/issues/coica-internet-censorship-and-copyright-bill"&gt;minor&lt;/a&gt;
&lt;a class="reference external" href="http://www.sopastrike.com/"&gt;victory&lt;/a&gt;,
every now and then.  But there are
&lt;a class="reference external" href="https://www.eff.org/issues/dmca"&gt;many,&lt;/a&gt;
&lt;a class="reference external" href="https://www.eff.org/issues/dvd"&gt;many&lt;/a&gt;
&lt;a class="reference external" href="https://www.eff.org/issues/file-sharing"&gt;more&lt;/a&gt;
&lt;a class="reference external" href="https://www.eff.org/patent"&gt;failures&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Perhaps because we are at a natural disadvantage when it comes to matters of politics.  We might be smart, but this means we also tend to be logical and rational &amp;#8212; maybe too logical and rational.  Success in our careers is somewhat determined by our abilities to think logically and analytically.  We are therefore prone to take that same approach to other areas.  Even in areas where things like logic and reason are not valued at all, and may in fact be a disadvantage &amp;#8212; like&amp;nbsp;politics.&lt;/p&gt;
&lt;p&gt;Which is why we might think the idea of replacing Australia&amp;#8217;s ageing, degraded copper-based communication network with new optic fibre infrastructure would be an eminently sensible thing to do, for a whole swathe of sound technical reasons.  That doesn&amp;#8217;t mean the politicians and economists running the show will see it that&amp;nbsp;way.&lt;/p&gt;
&lt;p&gt;We might forget, or find it difficult to fathom, that in the world of politics, spin and bullshit reign supreme.  Such antiquated notions like truth and facts don&amp;#8217;t matter much when dealing with the Merchants of Bullshit.  While we were learning and honing our technical skills, the politicians and lawyers and economists were busy honing their bullshitting skills.  It is these master bullshitters that are now our adversaries in areas where technology and politics intersect, like the &lt;span class="caps"&gt;NBN&lt;/span&gt;, but in many other areas as well.  We have no choice but to engage in battle with these bullshitters, because our worlds are likely to intersect more and more often, as new technology disrupts existing&amp;nbsp;industries.&lt;/p&gt;
&lt;p&gt;It probably doesn&amp;#8217;t help that there’s a vein of naivety and apathy about all this within tech communities.  We naively think technological solutions alone will win.  We are too apathetic to engage in what, to us, is the really boring game of&amp;nbsp;politics.&lt;/p&gt;
&lt;p&gt;But just because we aren&amp;#8217;t interested in meddling in politics, doesn&amp;#8217;t mean politicians and others in power won&amp;#8217;t meddle in our industries.  Quite the opposite,&amp;nbsp;actually.&lt;/p&gt;
&lt;p&gt;They will meddle as they see fit, despite their lack of understanding of technical&amp;nbsp;issues.&lt;/p&gt;
&lt;p&gt;We&amp;#8217;ve seen this clearly in Australia for decades now, when it comes to technology and communications policy.  The supposedly pro-free-market Liberal Party &lt;a class="reference external" href="http://www.afr.com/p/technology/telstra_the_monster_that_here_to_CsmPGJdAKfPAyUhe14ae7M"&gt;privatised Telstra&lt;/a&gt;
in a way that made it impossible to have true competition in broadband, because competitors could not compete with Telstra&amp;#8217;s vertically integrated monopoly position in the market.  Yet now, over 15 years later, the Liberal party is arguing that the private sector should build broadband infrastructure, not the government.  Then why hasn&amp;#8217;t the private sector done so by now?  They&amp;#8217;ve had time.  Why are the majority of broadband users in Australia still relying on &lt;span class="caps"&gt;ADSL&lt;/span&gt; technology over poor quality copper&amp;nbsp;wiring?&lt;/p&gt;
&lt;p&gt;Rational arguments from the technical community are falling on deaf ears.  Instead, the new government is already reframing and spinning the issue to suit their purposes.  In response to the totally reasonable concern from those within the technology industry, Communication Minister Malcolm Turnbull has dismissed
&lt;a class="reference external" href="http://www.abc.net.au/news/2013-09-12/malcolm-turnbull-labels-anti-nbn-petition-reckless/4954858"&gt;criticism as reckless&lt;/a&gt;,
&lt;a class="reference external" href="http://www.malcolmturnbull.com.au/media/our-nbn-policy"&gt;petitions as undemocratic&lt;/a&gt;,
and claimed the government has a mandate to implement crappy communications&amp;nbsp;policy.&lt;/p&gt;
&lt;p&gt;Instead of taking advice from people within the technology industry who actually know what they&amp;#8217;re talking about, decisions about the future of one of Australia&amp;#8217;s biggest technology infrastructure projects will be entirely determined by politicians and&amp;nbsp;economists.&lt;/p&gt;
&lt;p&gt;The same professions that largely caused the global financial&amp;nbsp;crisis.&lt;/p&gt;
&lt;p&gt;&lt;span class="caps"&gt;OK&lt;/span&gt;, so not all politicians and economists are equally clueless.  And when it comes to the global financial crisis, there&amp;#8217;s plenty of blame to apportion, both to governments and the private sector.  But it&amp;#8217;s clear some seriously flawed combination of government policy, based on some seriously flawed economic thinking (assuming anyone was actually thinking), contributed to the global financial crisis.  In a sane world, this means the &lt;span class="caps"&gt;GFC&lt;/span&gt; would have completely destroyed the credibility of many mainstream economists, ratings agencies, and&amp;nbsp;politicians.&lt;/p&gt;
&lt;p&gt;That doesn&amp;#8217;t seem to have happened.  The same groups of people are still in charge, the ratings agencies are still in business, and many of the same economists who advocated the market interventions that contributed to the &lt;span class="caps"&gt;GFC&lt;/span&gt; have the temerity to give advice on how to fix the economy &amp;#8212; and people are actually listening to&amp;nbsp;them.&lt;/p&gt;
&lt;p&gt;The tech community could possibly learn something from those economists.  Not about economics, clearly, but about bullshitting for influence, power and&amp;nbsp;profit.&lt;/p&gt;
&lt;p&gt;Seems to to have worked well for them.  Economists still hold the same level of power and influence as before &amp;#8212; maybe even more.  They know how the game is played, and they are so good at playing the game that not even one of the greatest financial crises in history could derail their train of&amp;nbsp;bullshit.&lt;/p&gt;
&lt;p&gt;Too much debt in the economy caused a major financial collapse?  I know, let&amp;#8217;s inject trillions of dollars of more debt into the economy, because nothing could possibly go wrong with that&amp;nbsp;idea!&lt;/p&gt;
&lt;p&gt;&lt;span class="dquo"&gt;&amp;#8220;&lt;/span&gt;Printing money&amp;#8221; has negative, hyper-inflationary connotations, and historically has never, ever worked?  I know, let&amp;#8217;s call it &amp;#8220;quantitative easing&amp;#8221;, and this time it&amp;#8217;ll work for sure, because this time it&amp;#8217;s&amp;nbsp;different!&lt;/p&gt;
&lt;p&gt;Whenever I hear the term &amp;#8220;quantitative easing&amp;#8221;, I can&amp;#8217;t help thinking about a rather inconsequential controversy in Australian politics  way back in the pre-financial crisis 90&amp;#8217;s.  An upstart wannabe political operative from an upstart minor political party, in response to some aggressive questioning from a journalist, said (possibly flippantly) that they could fund their poorly thought out populist and racist policies by printing money.  Whether he meant that seriously, or just said it to get rid of the journalist was unclear, but the media at the time had a field day with that quote!  Oh what a silly racist, they decried.  Not only is this new political party xenophobic and divisive and racist, but economically illiterate as well!  Everyone knows money printing is hyper-inflationary and stupid and silly and insane!  Theses people are not to be taken seriously, and have no business playing the grown up game of politics!  If we’re going to have politicians peddling divisive racism, they must at least be economically literate&amp;nbsp;racists!&lt;/p&gt;
&lt;p&gt;Amazing how much one global financial crisis can change the fortunes of money printing as a&amp;nbsp;concept!&lt;/p&gt;
&lt;p&gt;Now, money printing is all the rage, with the Federal Reserve leading the way, and little criticism from the mainstream media.  The money printers are hailed as saviours of the global economy, as opposed to shady private banking cartels covering their own asses, and screwing the American middle-class in the process.  And the financial markets love it!  Everyone has bought into the bullshit so thoroughly that the merest hint that the Fed will taper sends financial markets into a&amp;nbsp;panic.&lt;/p&gt;
&lt;p&gt;It might be instructive if those in the tech community with allusions to activism kept in mind that this is world we are living in.  A world where you can be proven wrong by a global financial crisis, and still retain credibility.  A world of Schrodinger&amp;#8217;s money printing, where printing money is both bad and good, depending on who is advocating it, and their agenda, not to mention how it&amp;#8217;s&amp;nbsp;branded.&lt;/p&gt;
&lt;p&gt;A world where economists have more say over the future of Australia&amp;#8217;s broadband network than technology&amp;nbsp;experts.&lt;/p&gt;
&lt;p&gt;Economists have managed to convince the world that to cure to all our economic ills is  an obscene amount of money printing, a prospect that would have once been unthinkable in economic&amp;nbsp;circles.&lt;/p&gt;
&lt;p&gt;But the tech community can&amp;#8217;t even convince a few politicians of the benefit of an optic fibre broadband&amp;nbsp;network.&lt;/p&gt;
&lt;p&gt;Not to mention that we also failed to stop politicians censoring the internet, spying on us, invading our privacy online, and taking away our digital&amp;nbsp;rights.&lt;/p&gt;
&lt;p&gt;Clearly, us geeks need to work on our bullshitting skills, if we have any hope of out-bullshitting the&amp;nbsp;bullshitters.&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h2&gt;Related&amp;nbsp;Posts:&lt;/h2&gt;
&lt;p class="introblock"&gt;This post is part of a loose series of rants partly inspired by the stupid
political fuckery surrounding the National Broadband Network.  I know it&amp;#8217;s
pointless writing about this stuff, but sometimes I just need to vent.
More of me digitally pissing into the wind about&amp;nbsp;this:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/02/national-broadband-cyber-futility/"&gt;Part 1: National Broadband&amp;nbsp;Cyber-Futility&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/27/hacking-government-an-ineffective-digital-militia/"&gt;Part 3: Hacking Government: An Ineffective Digital&amp;nbsp;Militia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/30/deviant-luddites-screwing-us/"&gt;Part 4: The Deviant Luddites Screwing&amp;nbsp;Us&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</content><category term="Ranting"></category><category term="NBN"></category><category term="Broadband"></category><category term="Politics"></category></entry><entry><title>National Broadband Cyber-Futility</title><link href="http://www.voidynullness.net/blog/2013/12/02/national-broadband-cyber-futility/" rel="alternate"></link><published>2013-12-02T00:00:00+11:00</published><updated>2013-12-02T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2013-12-02:/blog/2013/12/02/national-broadband-cyber-futility/</id><summary type="html">&lt;div class="section" id="digitally-pissing-in-the-wind-part-1"&gt;
&lt;h2&gt;Digitally Pissing in the Wind (Part&amp;nbsp;1)&lt;/h2&gt;
&lt;p&gt;With the Liberal Party winning the election as expected, they now get to
make good on their election promise/threat to take everything that was good
and holy in Labor’s
&lt;a class="reference external" href="http://www.abc.net.au/news/2013-05-10/broadband-policy-explainer-federal-election/4660778"&gt;&lt;span class="caps"&gt;FTTP&lt;/span&gt; National Broadband Network&lt;/a&gt;
and
&lt;a class="reference external" href="http://delimiter.com.au/2013/09/07/fttp-dream-coalition-victory-kills-labors-nbn/"&gt;replace it with a hellishly cheap and nasty &lt;span class="caps"&gt;FTTN&lt;/span&gt; abomination&lt;/a&gt;.
Because here in Australia, we can’t have nice things, apparently.  Like
&lt;a class="reference external" href="http://www.abc.net.au/news/2013-09-09/alberici-can-the-coalitions-nbn-keep-pace-with-change/4931864"&gt;decent broadband&lt;/a&gt;.
Or a &lt;a class="reference external" href="http://www.smh.com.au/federal-politics/political-news/razor-taken-to-csiro-20131107-2x4fu.html"&gt;technology industry&lt;/a&gt;.
Or &lt;a class="reference external" href="http://www.smh.com.au/technology/sci-tech/science-takes-back-seat-after-50-years-20130916-2tv59.html"&gt;science&lt;/a&gt;.
Or &lt;a class="reference external" href="http://www.smh.com.au/federal-politics/political-news/liberal-senator-attacks-partys-promotion-of-women-20130916-2tu2r.html"&gt;women&lt;/a&gt;
&lt;a class="reference external" href="http://www.newstatesman.com/2013/09/five-reasons-tony-abbott-shouldnt-be-womens-minister"&gt;cabinet&lt;/a&gt;
&lt;a class="reference external" href="http://www.smh.com.au/federal-politics/political-news/tony-abbott-names-his-new-ministry-20130916-2tujb.html"&gt;ministers&lt;/a&gt;.
At least not …&lt;/p&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="section" id="digitally-pissing-in-the-wind-part-1"&gt;
&lt;h2&gt;Digitally Pissing in the Wind (Part&amp;nbsp;1)&lt;/h2&gt;
&lt;p&gt;With the Liberal Party winning the election as expected, they now get to
make good on their election promise/threat to take everything that was good
and holy in Labor’s
&lt;a class="reference external" href="http://www.abc.net.au/news/2013-05-10/broadband-policy-explainer-federal-election/4660778"&gt;&lt;span class="caps"&gt;FTTP&lt;/span&gt; National Broadband Network&lt;/a&gt;
and
&lt;a class="reference external" href="http://delimiter.com.au/2013/09/07/fttp-dream-coalition-victory-kills-labors-nbn/"&gt;replace it with a hellishly cheap and nasty &lt;span class="caps"&gt;FTTN&lt;/span&gt; abomination&lt;/a&gt;.
Because here in Australia, we can’t have nice things, apparently.  Like
&lt;a class="reference external" href="http://www.abc.net.au/news/2013-09-09/alberici-can-the-coalitions-nbn-keep-pace-with-change/4931864"&gt;decent broadband&lt;/a&gt;.
Or a &lt;a class="reference external" href="http://www.smh.com.au/federal-politics/political-news/razor-taken-to-csiro-20131107-2x4fu.html"&gt;technology industry&lt;/a&gt;.
Or &lt;a class="reference external" href="http://www.smh.com.au/technology/sci-tech/science-takes-back-seat-after-50-years-20130916-2tv59.html"&gt;science&lt;/a&gt;.
Or &lt;a class="reference external" href="http://www.smh.com.au/federal-politics/political-news/liberal-senator-attacks-partys-promotion-of-women-20130916-2tu2r.html"&gt;women&lt;/a&gt;
&lt;a class="reference external" href="http://www.newstatesman.com/2013/09/five-reasons-tony-abbott-shouldnt-be-womens-minister"&gt;cabinet&lt;/a&gt;
&lt;a class="reference external" href="http://www.smh.com.au/federal-politics/political-news/tony-abbott-names-his-new-ministry-20130916-2tujb.html"&gt;ministers&lt;/a&gt;.
At least not when the Liberal Party is in&amp;nbsp;charge.&lt;/p&gt;
&lt;p&gt;Australia’s tentacle of every government’s favourite &lt;a class="reference external" href="http://www.rollingstone.com/politics/news/the-great-american-bubble-machine-20100405"&gt;money-sucking vampire
squid&lt;/a&gt;, Malcolm Turnbull, has taken over as Communications Minister, and we
now get to watch with horror as
&lt;a class="reference external" href="http://howfastisthenbn.com.au/"&gt;Labor’s wonderfully aromatic, premium, full-bodied broadband brew&lt;/a&gt;
gets &lt;a class="reference external" href="http://www.abc.net.au/news/2013-09-24/turnbull-moves-to-put-coalitions-stamp-on-nbn/4978020"&gt;unceremoniously flushed down the toilet&lt;/a&gt;,
to be replaced with Turnbull’s
&lt;a class="reference external" href="http://www.liberal.org.au/fast-affordable-sooner-coalitions-plan-better-nbn"&gt;crap-in-a-cup-and-call-it-coffee concoction&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Successive &lt;a class="reference external" href="http://reckoner.com.au/2013/09/australias-broadband-history/"&gt;governments have screwed us on broadband&lt;/a&gt;,
through various combination of incompetence, inaction, and ideology.
Labor&amp;#8217;s &lt;span class="caps"&gt;NBN&lt;/span&gt; was a bright spark in Australia&amp;#8217;s dim and gloomy technology
landscape.  The Liberals are now going to do all they can to make sure Labor&amp;#8217;s
visionary plan for near universal &lt;span class="caps"&gt;FTTP&lt;/span&gt; broadband will be relegated to
history as just a geeky cock tease &amp;#8212; a political mirage in an otherwise
barren desert of Labor Party incompetence and pointless&amp;nbsp;infighting.&lt;/p&gt;
&lt;p&gt;Now, the Liberal Party gets to screw us.  Again.  Which is hardly
surprising, but all the more galling because this represents an opportunity
for the Liberal Party to fix a &lt;a class="reference external" href="http://www.telstra.com.au/"&gt;problem they created&lt;/a&gt;.  Australia&amp;#8217;s current broadband mess is in
large part a result of the Howard government
&lt;a class="reference external" href="http://johnmenadue.com/blog/?p=807"&gt;privatising Telstra without structural separation.&lt;/a&gt;
Now that they&amp;#8217;re in office once again, they have the opportunity, after
decades of inaction, to throw out the ancient copper and put Australia on
the path to a modern broadband network.  Instead, they&amp;#8217;re just going to
screw us all over&amp;nbsp;again.&lt;/p&gt;
&lt;p&gt;What&amp;#8217;s really depressing though, is how this just seems to be another
example of politicians, lawyers and other Merchants of Bullshit doing
whatever they can to &lt;a class="reference external" href="http://www.suck.com/daily/2000/09/08/"&gt;screw geeks&lt;/a&gt;.  It&amp;#8217;s the same pattern playing out
over and over again.  It&amp;#8217;s the same pattern that&amp;#8217;s been happening for
decades now.  And despite many embarrassing defeats, the geeks seem to have
learned nothing about fighting back&amp;nbsp;effectively.&lt;/p&gt;
&lt;p&gt;Of course, it&amp;#8217;s a global phenomenon, this attack on geek interests.  From
software patents to &lt;span class="caps"&gt;DRM&lt;/span&gt; in music files; from &lt;span class="caps"&gt;DMCA&lt;/span&gt; to &lt;a class="reference external" href="http://www.smh.com.au/digital-life/computers/blogs/gadgets-on-the-go/why-does-sony-lie-about-dvd-regioncoding-20130121-2d1yo.html"&gt;region codes of &lt;span class="caps"&gt;DVD&lt;/span&gt;
and Blue Ray&lt;/a&gt;; from the ever present threat of internet censorship to the
many other subtle and &lt;a class="reference external" href="http://delimiter.com.au/2013/11/14/outrage-tpp-leak-reveals-piracy-criminalisation/"&gt;not so subtle ways&lt;/a&gt; of stripping us of our rights
and privacy online.  Geeks are being screwed.  It’s the bullies of the
adult world telling geeks they can’t play here.  It&amp;#8217;s the established
players enlisting thugs in suit with law degrees to legislate and sue the
geeks into submission, put them in their place.  To make it clear the geeks
should fuck right off and play somewhere else, when their disruptive
technology happens to encroach on someone else&amp;#8217;s turf.  In Australia, the
&lt;span class="caps"&gt;NBN&lt;/span&gt; has become just another example of&amp;nbsp;this.&lt;/p&gt;
&lt;p&gt;The problem is that geeks are doing what geeks always do when they’re
displeased: whining about it online.  They’re blogging, and tweeting, and
posting in whatever online forum they can.  Which is all well and good, as
long as we don&amp;#8217;t labour under any misconception that anything we do online
will make any tangible difference in the real&amp;nbsp;world.&lt;/p&gt;
&lt;p&gt;If it’s not exactly a war, it’s at least a game, of sorts.  It’s us, the
geeks, against them, the Merchants of Bullshit in power.  And we play the
game particularly badly.  Because this is not a game that is played online,
in blogs or social media.  It’s played out in the real world.  It’s played
with lawyers, lobby groups, propaganda/advertising, &lt;a class="reference external" href="http://delimiter.com.au/2013/11/27/australia-desperately-needs-good-technology-policy-think-tank/#more-148692"&gt;think tanks&lt;/a&gt;, bribes
(i.e. &amp;#8220;campaign donations&amp;#8221;).  It’s played with spin, with
communicating effectively to a possibly apathetic public, with courting the
influence of those with money and/or power, and with all the tools of
influence and persuasion that money and power can command.  Blog posts and
trending hashtags are just so much digital pissing in the wind, which &lt;a class="reference external" href="http://www.zdnet.com/au/petitions-and-twibbons-wont-save-the-nbn-7000020528/"&gt;will
ultimately achieve nothing&lt;/a&gt;.  As&amp;nbsp;usual.&lt;/p&gt;
&lt;p&gt;Even an &lt;a class="reference external" href="http://www.change.org/en-AU/petitions/the-liberal-party-of-australia-reconsider-your-plan-for-a-fttn-nbn-in-favour-of-a-superior-ftth-nbn"&gt;online petition&lt;/a&gt;, &lt;a class="reference external" href="http://www.abc.net.au/news/2013-09-10/university-student-petition-to-scrap-nbn-takes-off-online/4949372"&gt;no matter how successful&lt;/a&gt;, is unlikely to
&lt;a class="reference external" href="http://theconversation.com/nbn-petition-and-the-backlash-when-does-democracy-speak-18178"&gt;make any difference&lt;/a&gt; in itself, though it may have some utility in
&lt;a class="reference external" href="http://www.smh.com.au/it-pro/government-it/26000-raised-for-nbn-campaign-in-malcolm-turnbulls-electorate-20131011-hv243.html"&gt;fomenting&lt;/a&gt; &lt;a class="reference external" href="http://www.smh.com.au/it-pro/government-it/campaign-for-fibre-nbn-comes-to-malcolm-turnbulls-front-door-20131022-hv26o.html"&gt;dissent&lt;/a&gt;.  Petitions are essentially a democratic
distraction &amp;#8212; merely a mirage provided to the powerless to give them the
illusion of influence, in a way least likely to actually influence
anything.  I doubt Turnbull and his corporate puppet masters are &lt;a class="reference external" href="http://www.theage.com.au/it-pro/government-it/malcolm-turnbull-gives-thumbs-down-to-fibre-nbn-petition-20130913-hv1po.html"&gt;quaking
with fear&lt;/a&gt; because of an online petition.  Turnbull even had the balls to
try to &lt;a class="reference external" href="http://www.malcolmturnbull.com.au/media/our-nbn-policy"&gt;reframe the petition as undemocratic&lt;/a&gt;, which is an indication of
the unabashed, &lt;a class="reference external" href="http://www.malcolmturnbull.com.au/media/the-importance-of-telling-the-truth-especially-if-you-are-a-lecturer-in-com"&gt;high level bullshit&lt;/a&gt; we are dealing with&amp;nbsp;here.&lt;/p&gt;
&lt;p&gt;Turnbull claims the Coalition’s election victory gives them a mandate to
implement crappy broadband.  This conveniently ignores that the election
was lost by Labor and their laughable leadership squabbles, rather than won
by the Liberals with their laughing-stock Luddite&amp;nbsp;leader.&lt;/p&gt;
&lt;p&gt;Australia grudgingly elected the Liberal party with a mandate to never let
either Kevin Rudd or Julia Gillard become Prime Minister ever again &amp;#8212; and
nothing more.  And given our suitably low expectations of politicians, this
is pretty much all we can reasonably expect the Liberals will successfully
achieve while in office.  Well, that, and probably some sort of sexting
scandal, which seems to be disturbingly obligatory these days.  No
electorate in the world has ever given any politician a mandate to send
pictures of their genitals to unsuspecting users of social media, yet there
seems to be quite a bit of that going on around the world at the moment.
Perhaps politicians are labouring under a misconception that social media
exists only for them to distribute pictures of their&amp;nbsp;privates.&lt;/p&gt;
&lt;p&gt;Instructively though, some Merchants of Bullshit know how to play the game
so well that even stupidly embarrassing scandals don&amp;#8217;t always preclude
&lt;a class="reference external" href="http://en.wikipedia.org/wiki/Anthony_Weiner_sexting_scandals"&gt;disgraced degenerates&lt;/a&gt; from
&lt;a class="reference external" href="http://www.huffingtonpost.com/2013/09/11/anthony-weiner-eliot-spitzer_n_3906345.html"&gt;running for public office&lt;/a&gt;.
If &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Kevin_Rudd"&gt;abject failure&lt;/a&gt; and &lt;a class="reference external" href="http://www.smh.com.au/federal-politics/political-news/craig-thomson-could-face-50-new-charges-in-fraud-case-20131126-2y6xj.html"&gt;public&lt;/a&gt;
&lt;a class="reference external" href="http://www.theguardian.com/theguardian/shortcuts/2013/aug/06/peter-dowling-australia-sexting-penis-wine"&gt;humiliation&lt;/a&gt;
are the modern day prerequisites for power, then who do we have to send
pictures of our genitals to around here to get a decent broadband network
built?  Which call girls must we have adulterous liaisons with before the
politicians take our concerns&amp;nbsp;seriously?&lt;/p&gt;
&lt;p&gt;The reality is even if &lt;a class="reference external" href="http://www.news.com.au/technology/most-australians-prefer-labors-faster-yet-pricier-nbn-plan-to-oppositions-policy/story-e6frfro0-1226625363889"&gt;every&lt;/a&gt;
&lt;a class="reference external" href="http://www.abc.net.au/news/2013-09-11/your-say-tony-abbotts-priorities/4946024"&gt;single&lt;/a&gt;
&lt;a class="reference external" href="http://delimiter.com.au/2013/04/15/coalition-rejected-78-support-labors-nbn/"&gt;person&lt;/a&gt;
in Australia signed the petition, Turnbull and the Liberals would still
argue that they have a mandate to do whatever they hell they want.  Because
they can.  Because they know they can get away with it.  Because they know
the worst that will happen is some snarky blogs and tweets will be&amp;nbsp;written.&lt;/p&gt;
&lt;p&gt;The online vitriol is certainly not working so far &amp;#8212; Turnbull has simply
dismisses all the &lt;a class="reference external" href="http://theconversation.com/nbn-petition-and-the-backlash-when-does-democracy-speak-18178"&gt;post-election criticism&lt;/a&gt; as &lt;a class="reference external" href="http://www.abc.net.au/news/2013-09-12/malcolm-turnbull-labels-anti-nbn-petition-reckless/4954858"&gt;reckless&lt;/a&gt;.  Yes, it’s
reckless for people in the technology industry to comment on issues
affecting the technology industry, according to Malcolm.  It’s reckless for
those who understand the technology, who work with the technology day in
day out, who can offer insight into the issues &amp;#8212; it’s reckless for them to
offer an informed opinion.  It&amp;#8217;s reckless for people who work in the
industry to comment on matters that will directly affect their&amp;nbsp;livelihood.&lt;/p&gt;
&lt;p&gt;Instead, in the bullshit alternate universe of politics inhabited by
Malcolm and the Liberals, the best people to make technical decisions about
essential communications infrastructure in Australia are economists and
lawyers and accountants.  Especially if they&amp;#8217;re &lt;a class="reference external" href="http://delimiter.com.au/2013/10/21/turnbull-stacks-nbn-review-telstra-cronies/"&gt;Liberal Party cronies&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The process of democracy will of course be best served by an endless &amp;#8212; and
no doubt expensive &amp;#8212; series of committees and reports and reviews, overseen by
technically clueless public servants, carefully selected to deliver the
predetermined outcome Turnbull requires.  Because that’s the democratic
way, apparently.  Many have accused Turnbull of &lt;a class="reference external" href="http://www.sortius-is-a-geek.com/hypocrisy-thy-name-mal/"&gt;hypocrisy&lt;/a&gt;, which seems kind
of redundant, given hypocrisy is sadly not just synonymous with politics,
but a prerequisite for success.  Hypocrisy is the aioli in the gourmet
bullshit burger of modern&amp;nbsp;politics.&lt;/p&gt;
&lt;p&gt;Hypocrisy is now as closely entwined in politics as sexting scandals.  And
as Australia&amp;#8217;s 44th Parliament unfolds, I&amp;#8217;m sure we&amp;#8217;ll see plenty of both.
Whether we want to or not.  All that&amp;#8217;s left is to wait and see exactly how
we&amp;#8217;re going to get screwed over by this new government of hypocritical,
lying, cheating, backfliping and sexting parliamentary&amp;nbsp;buffoons.&lt;/p&gt;
&lt;p&gt;All we can do now is pray and hope that if there is going to be a sexting
scandal, it doesn&amp;#8217;t involve Clive Palmer.  Because no one deserves to be
subjected to&amp;nbsp;that.&lt;/p&gt;
&lt;p&gt;Given the level of crazy Clive displayed before he was elected, if he does
become afflicted with whatever strange malady causes elected officials to
think it&amp;#8217;s a good idea firstly to take pictures of their genitals, and
secondly to share those pictures with others via the internet, then let&amp;#8217;s
hope his aides can keep him in check.  (&amp;#8220;Clive, what are you doing?  Clive,
put that phone down and put your pants back on.  &lt;em&gt;Hey Clive, look over
there!  Clive!  Put your pants on and look out the window there.  Look!
Over there.&lt;/em&gt; Isn&amp;#8217;t that &lt;a class="reference external" href="http://www.smh.com.au/federal-politics/federal-election-2013/titanic-fury-rupert-murdoch-dragged-into-the-clive-palmer-drama-20130905-2t6lz.html"&gt;Wendi Deng&lt;/a&gt; doing secret Chinese spy shit?  &lt;em&gt;And
over there!  Look!&lt;/em&gt; Isn&amp;#8217;t that a box of votes the &lt;a class="reference external" href="http://www.dailytelegraph.com.au/news/nsw/clive-palmers-war-with-the-australian-electoral-commission-could-force-the-entire-state-back-to-the-polls/story-fni0cx12-1226752008737"&gt;&lt;span class="caps"&gt;AEC&lt;/span&gt;&lt;/a&gt; has been hiding
from you?  &lt;em&gt;Look, Clive, look!&lt;/em&gt;&amp;#8220;)&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s hope everyone can keep it in their pants during their term in office.
After all, they have important work to do, screwing the geeks and the
country out of a decent broadband network, amongst other things.  And until
us geeks learn how to play the bullshit game of politics, as distasteful as
it may be, they’re going to keep screwing us.  Until we work out how to
play the game in the real world, no matter how much we blog or tweet or
sign petitions, we’re not going to get the broadband we want or need &amp;#8212;
we’re going to get the broadband Turnbull and his corporate puppet masters
want us to&amp;nbsp;have.&lt;/p&gt;
&lt;div class="section" id="related-posts"&gt;
&lt;h3&gt;Related&amp;nbsp;Posts:&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;strong&gt;Digitally Pissing in the Wind:&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/19/quantitative-geek-screwing/"&gt;Part 2: Quantitative Geek&amp;nbsp;Screwing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/27/hacking-government-an-ineffective-digital-militia/"&gt;Part 3: Hacking Government: An Ineffective Digital&amp;nbsp;Militia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2013/12/30/deviant-luddites-screwing-us/"&gt;Part 4: The Deviant Luddites Screwing&amp;nbsp;Us&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/01/05/screwed-to-the-node/"&gt;Screwed To The&amp;nbsp;Node&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.voidynullness.net/blog/2014/01/06/booze-to-the-node/"&gt;Booze To The&amp;nbsp;Node&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="NBN"></category><category term="Broadband"></category><category term="Ranting"></category><category term="Politics"></category></entry><entry><title>Mandatory Internet Censorship to the Node</title><link href="http://www.voidynullness.net/blog/2013/09/06/slow-and-censored-broadband-internet/" rel="alternate"></link><published>2013-09-06T00:00:00+10:00</published><updated>2013-09-06T00:00:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2013-09-06:/blog/2013/09/06/slow-and-censored-broadband-internet/</id><summary type="html">&lt;p&gt;So that was&amp;nbsp;weird.&lt;/p&gt;
&lt;p&gt;Yesterday, without fanfare, the Coalition released it&amp;#8217;s &amp;#8220;Policy to Enhance
Online Safety for Children&amp;#8221;.  Because the the Liberal Party really, really
cares about children.  I&amp;#8217;m sure it keeps them up at night.  So much so
they&amp;#8217;re willing dedicate $10 million to keeping children safe online.
Because if the government won&amp;#8217;t keep children safe online then who will?
Their parents?  Or course not!  Parenting is far too important a task to be
left …&lt;/p&gt;</summary><content type="html">&lt;p&gt;So that was&amp;nbsp;weird.&lt;/p&gt;
&lt;p&gt;Yesterday, without fanfare, the Coalition released it&amp;#8217;s &amp;#8220;Policy to Enhance
Online Safety for Children&amp;#8221;.  Because the the Liberal Party really, really
cares about children.  I&amp;#8217;m sure it keeps them up at night.  So much so
they&amp;#8217;re willing dedicate $10 million to keeping children safe online.
Because if the government won&amp;#8217;t keep children safe online then who will?
Their parents?  Or course not!  Parenting is far too important a task to be
left to parents &amp;#8212; the government must be involved every step of the way!
I&amp;#8217;m sure this will be tax payer money well spent, and absolutely none of it
will go towards hiring useless public servants or advisers who will just
sit around all day downloading internet porn.  I&amp;#8217;m sure $10 million
will buy lots of child safety online and none of that money will be wasted
on pointless posturing, like some sort of mandatory internet censorship
scheme.  Oh, but wait, turns out that buried within the policy document was
in fact a plan to introduce &lt;span class="caps"&gt;UK&lt;/span&gt;-style opt-out mandatory internet filtering.
Coalition MPs Malcolm Turnbull and Paul Fletcher spent most of the
afternoon &lt;a class="reference external" href="https://soundcloud.com/triple-j-hack/hack-visits-lismore-and-albo"&gt;promoting&lt;/a&gt;&amp;nbsp;it.&lt;/p&gt;
&lt;p&gt;Not surprisingly, controversy erupted.  After all, this was the political
party that had constantly criticised Labor&amp;#8217;s eerily similar plans for
compulsory internet censorship.  And here we are, less than 2 days before
an election, and without any debate, they spring a policy for mandatory
internet censorship on us at the last minute.  It seems just like the sort
of underhanded thing the Liberals would do.  Labor jumped all over it,
shitting on the Liberal Party for having a policy of mandatory internet
censorship, just like the Liberals have been shitting on Labor for their
policy of mandatory internet censorship, and the circle of hypocrisy was&amp;nbsp;complete.&lt;/p&gt;
&lt;p&gt;But later on last night, just hours later, &lt;a class="reference external" href="http://www.abc.net.au/news/2013-09-05/no-internet-filter-says-turnbull/4939156"&gt;the Coalition backflipped&lt;/a&gt;.
Turnbull &lt;a class="reference external" href="http://www.liberal.org.au/latest-news/2013/09/05/coalitions-policy-enhance-online-safety-children"&gt;released a statement&lt;/a&gt; saying the Coalition did not support
mandatory internet filtering, and that the policy document was &amp;#8220;poorly
worded and&amp;nbsp;incorrect.&amp;#8221;&lt;/p&gt;
&lt;p&gt;I suspect the policy document was &amp;#8220;poorly worded&amp;#8221; in that someone from the
Liberal Party accidentally told the truth&amp;#8230;in direct violation of Liberal
Party policy.  I assume the person responsible &amp;#8212; or his scapegoat &amp;#8212; was
duly fired for this unexpected outbreak of honesty, and it won&amp;#8217;t happen
again.  The last thing Australia needs is honesty in politics.  Not when
we&amp;#8217;re doing so well with our current Merchants of&amp;nbsp;Bullshit.&lt;/p&gt;
&lt;p&gt;So the Liberals introduced mandatory internet censorship then took it back.
They are truly the Jay Leno of &lt;span class="caps"&gt;IT&lt;/span&gt;&amp;nbsp;policy.&lt;/p&gt;
&lt;p&gt;It obviously raises many questions.  Especially since Malcolm Turnbull was
on the radio last night strongly arguing for the policy, before only hours
later announcing the whole thing was a mistake.  Not only that, he tweeted
that he only read the policy shortly before going on air.  On the one hand
you&amp;#8217;ve got to admire Malcolm Turnbull&amp;#8217;s bullshitting skills for so
convincingly standing up for a nonsensical policy he had only just read
before going on air.  He should give some pointers to &lt;a class="reference external" href="http://nullyvoidness.net/post/57485526599/election-2013-abbotts-campaign-kick-off-by"&gt;Jaymes Diaz&lt;/a&gt;.  On
the other hand, it suggests Turnbull will happily weave a web of complete
bullshit about any policy document put in front of him.  So much for
conviction politicians.  The best we can expect these days are conviction
bullshit artists.  (Of which the Coaltion has many, though Jaymes Diaz is
obviously not one of&amp;nbsp;them.)&lt;/p&gt;
&lt;p&gt;Then there&amp;#8217;s the question of who the hell wrote the policy, if the
ministers responsible for it are only reading it for the first time on the
day it&amp;#8217;s released to the public?  The Liberals like to talk about the
&amp;#8220;faceless men&amp;#8221; of the Labor party, but seems the Liberals have their own
faceless men writing their policy documents &amp;#8212; which no one even bothers to
properly proof read before&amp;nbsp;releasing.&lt;/p&gt;
&lt;p&gt;Regardless of whether it was a genuine mistake or something more sinister,
it doesn&amp;#8217;t exactly inspire confidence in the&amp;nbsp;Coalition.&lt;/p&gt;
&lt;p&gt;Not that I really had much confidence in them to begin with.  Certainly not
when it comes to the world of &lt;span class="caps"&gt;IT&lt;/span&gt;.  One of the things that has bothered me
about the Liberal Party for a long time is the impression I get that they
don&amp;#8217;t really understand or even care about the &lt;span class="caps"&gt;IT&lt;/span&gt; industry.  Or even any
technology industry.  Although to be fair, since in the past there haven&amp;#8217;t
been many votes to be had in this area, it&amp;#8217;s something that&amp;#8217;s been
routinely ignored and neglected by both major&amp;nbsp;parties.&lt;/p&gt;
&lt;p&gt;Which made Labor&amp;#8217;s National Broadband Network so unusually impressive.
Here, for once, was a political party implementing genuinely visionary,
nation-building technology infrastructure &amp;#8212; and for the most part getting
it right.  Sure, it&amp;#8217;s expensive and not perfect, but it&amp;#8217;s pretty damn good
on the technical merits &amp;#8212; and long overdue, given the dire state of
Telstra&amp;#8217;s copper network.  Surprisingly, the Labor Party more or less got
it right as far as broadband goes.  Do it once, and do it with fibre &amp;#8212; to
the premises.  Although no doubt there was an element of self interest in
this as well.  Fundamentally, Labor&amp;#8217;s &lt;span class="caps"&gt;NBN&lt;/span&gt; was borne of the realisation &amp;#8212;
way ahead of the Liberals &amp;#8212; that the internet has become mainstream enough
that there are now votes to be bought in this&amp;nbsp;area.&lt;/p&gt;
&lt;p&gt;But sadly not enough this time round.  With a Coalition victory likely at
tomorrow&amp;#8217;s election, it&amp;#8217;s a shame that Labor&amp;#8217;s visionary plan to replace
the crappy copper network with fibre and finally bring our broadband
infrastructure into the 21st century, will be watered down with Turnbull&amp;#8217;s
technically inferior Fibre To The Node&amp;nbsp;alternative.&lt;/p&gt;
&lt;p&gt;That&amp;#8217;s assuming we even get that far.  The reality is once the Liberals get
elected they will do whatever the hell they want, regardless of whatever
&amp;#8220;poorly worded&amp;#8221; policy documents they release before the election.
Including but not limited to finding whatever pretext they can to scrap the
whole &lt;span class="caps"&gt;NBN&lt;/span&gt;, which they never wanted to build in the first place.  Especially
if they get control of the Senate.  The only reason the Coalition even have
a broadband policy is because Labor&amp;#8217;s &lt;span class="caps"&gt;NBN&lt;/span&gt; plan proved to be so popular.
However, I suspect many within the Liberal Party would love nothing more
than to scrap the whole thing.  Especially Tony&amp;nbsp;Abbott.&lt;/p&gt;
&lt;p&gt;The man who will likely be our next Prime Minister, is going into this
election with two major and very expensive policies that he doesn&amp;#8217;t believe
in &amp;#8212; the &lt;span class="caps"&gt;NBN&lt;/span&gt; and paid parental leave &amp;#8212; and I suspect he&amp;#8217;ll take any
opportunity to scrap both.  After all, this is the man who initially said
if he was elected he&amp;#8217;d rip Labor&amp;#8217;s &lt;span class="caps"&gt;NBN&lt;/span&gt; out of the ground.  This is the man
who once said there would be compulsory paid maternity leave &amp;#8220;&lt;a class="reference external" href="http://www.actu.org.au/Media/Mediareleases/PaidparentalleaveovermydeadbodysaysAbbott.aspx"&gt;Over this
Government&amp;#8217;s dead body&lt;/a&gt;&amp;#8220;.&lt;/p&gt;
&lt;p&gt;It therefore feels a bit ominous that just hours from an election, there&amp;#8217;s
a bizarre &lt;span class="caps"&gt;IT&lt;/span&gt; policy backflip, suggesting they&amp;#8217;re making up policy as they
go along.  Which indicates &amp;#8212; as I long suspected &amp;#8212; that the Liberals
don&amp;#8217;t really care about the &lt;span class="caps"&gt;IT&lt;/span&gt; industry, and don&amp;#8217;t really understand the &lt;span class="caps"&gt;IT&lt;/span&gt;
industry.  To them, it&amp;#8217;s just another policy plaything.  They will do
whatever is most politically expedient, without regard for the best
technical solution (hence Turnbull&amp;#8217;s inferior &lt;span class="caps"&gt;FTTN&lt;/span&gt; &lt;span class="caps"&gt;NBN&lt;/span&gt;).&lt;/p&gt;
&lt;p&gt;After the election, I wouldn&amp;#8217;t be at all surprised if they find some excuse
to scrap both the &lt;span class="caps"&gt;NBN&lt;/span&gt; and the paid parental leave.  They might go for the
John Howard approach &amp;#8212; claim Labor left a big secret black hole in
Australia&amp;#8217;s finances, and therefore all those things they promised before
the election are now unaffordable non-core promises, and therefore won&amp;#8217;t
happen.  Goodbye &lt;span class="caps"&gt;NBN&lt;/span&gt;, and goodbye paid parental leave.  They might not be
able to get away with that &amp;#8212; again &amp;#8212; but I don&amp;#8217;t think it&amp;#8217;ll stop them&amp;nbsp;trying.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s clear Tony Abbott thinks an &lt;span class="caps"&gt;NBN&lt;/span&gt; is a waste of money, but seems he
thinks nothing of throwing millions of dollars of tax payer funds at a
chocolate company.  After criticizing Kevin Rudd for giving government
assistance to the struggling car manufacturing industry, &lt;a class="reference external" href="http://www.news.com.au/national-news/federal-election/tony-abbott-pledges-16m-towards-cadbury-factory-revamp-in-tasmania/story-fnho52ip-1226705546266"&gt;Abbott has
promised $16 million&lt;/a&gt; to a profitable multi-national corporation
to upgrade a chocolate factory in Tasmania.  Just the thing we need to be
spending money on in the midst of an obesity crisis and diabetes epidemic
&amp;#8212; chocolate!  Forget about building the broadband infrastructure of the
future &amp;#8212; chocolate manufacturing is what&amp;#8217;s most important!  So we might
not get decent broadband after the election, but we can always gorge
ourselves into a diabetic coma on Australian-made, government-subsidized
chocolate to try and forget about how our &lt;span class="caps"&gt;ADSL&lt;/span&gt; connection keeps dropping&amp;nbsp;out.&lt;/p&gt;
</content><category term="NBN"></category><category term="Broadband"></category><category term="Ranting"></category></entry><entry><title>The Australian Broadband Hustle</title><link href="http://www.voidynullness.net/blog/2013/09/01/australian-broadband-hustle/" rel="alternate"></link><published>2013-09-01T00:00:00+10:00</published><updated>2013-09-01T00:00:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2013-09-01:/blog/2013/09/01/australian-broadband-hustle/</id><summary type="html">&lt;p&gt;It got to the point I just had no choice.  Had to do it.  I&amp;#8217;d had&amp;nbsp;enough.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;d had enough of the increasingly frequent &lt;span class="caps"&gt;ADSL&lt;/span&gt; dropouts on my
increasingly less reliable &lt;span class="caps"&gt;TPG&lt;/span&gt; broadband&amp;nbsp;service.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;d had enough of a Telstra phone line with so much noise, static and
crackling sounds that it was almost impossible to hear the person on the
other&amp;nbsp;end.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;d had enough of both my phone and internet going to hell &lt;a class="reference external" href="http://www.sortius-is-a-geek.com/a-fault-like-any-other-fault/"&gt;every …&lt;/a&gt;&lt;/p&gt;</summary><content type="html">&lt;p&gt;It got to the point I just had no choice.  Had to do it.  I&amp;#8217;d had&amp;nbsp;enough.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;d had enough of the increasingly frequent &lt;span class="caps"&gt;ADSL&lt;/span&gt; dropouts on my
increasingly less reliable &lt;span class="caps"&gt;TPG&lt;/span&gt; broadband&amp;nbsp;service.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;d had enough of a Telstra phone line with so much noise, static and
crackling sounds that it was almost impossible to hear the person on the
other&amp;nbsp;end.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;d had enough of both my phone and internet going to hell &lt;a class="reference external" href="http://www.sortius-is-a-geek.com/a-fault-like-any-other-fault/"&gt;every time it
rained&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;d had enough of an &lt;span class="caps"&gt;ADSL&lt;/span&gt; line so unreliable it would drop out every few&amp;nbsp;minutes.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;d had enough of Telstra&amp;#8217;s copper network in my area which, after years of
intermittent problems, had obviously degraded to the point of being
completely&amp;nbsp;unusable.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;d had enough of the frequent but futile conversations with &lt;span class="caps"&gt;TPG&lt;/span&gt;&amp;#8217;s support
drones, who would hear the noise on the line and insist it was Telstra&amp;#8217;s
fault the &lt;span class="caps"&gt;ADSL&lt;/span&gt; was constantly dropping out.  After all, a line so noisy was
bound to cause &lt;span class="caps"&gt;ADSL&lt;/span&gt; interference, they&amp;nbsp;insisted.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;d had enough of repeatedly reporting the fault to Telstra, only to have a
technician arrive few days later and tell me there wasn&amp;#8217;t anything wrong
with the line, and it was &lt;span class="caps"&gt;TPG&lt;/span&gt;&amp;#8217;s fault the &lt;span class="caps"&gt;ADSL&lt;/span&gt; was constantly dropping out.
Or my phone&amp;#8217;s fault.  Or the line filter&amp;#8217;s fault.  Or my modem&amp;#8217;s fault.  Or
the cables&amp;#8217; fault.  So I replaced the modem, the phones, the line filter, and
all the cables.  Still, the same problems persisted.  So then it was
suddenly my home&amp;#8217;s fault for being so damn distant from the exchange.  Or
my star sign&amp;#8217;s fault.  Or the fault of those pesky cosmic&amp;nbsp;rays.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;d had enough of constantly going around in circles with Telstra and &lt;span class="caps"&gt;TPG&lt;/span&gt;,
each one blaming the other for the dropouts on my &lt;span class="caps"&gt;ADSL&lt;/span&gt; service and noise on
my phone&amp;nbsp;line.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;d had enough of both &lt;span class="caps"&gt;TPG&lt;/span&gt; and Telstra being all too happy to take my money,
while neither was willing to accept any accountability for problems with
the sub-standard services they were&amp;nbsp;providing.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;d had enough of paying for a phone and internet services that had both
become completely&amp;nbsp;useless.&lt;/p&gt;
&lt;p&gt;So I had no choice but to switch from &lt;span class="caps"&gt;ADSL2&lt;/span&gt;+ to cable internet.
Fortunately, I am in an area where cable internet is available.
Unfortunately, it&amp;#8217;s more expensive.  Fortunately, this was an opportunity
to get rid of Telstra completely, as I had the option of another&amp;nbsp;provider.&lt;/p&gt;
&lt;p&gt;&lt;span class="quo"&gt;&amp;#8216;&lt;/span&gt;Yes&amp;#8217;, that other&amp;nbsp;provider.&lt;/p&gt;
&lt;p&gt;So it was goodbye and good riddance to Telstra.  Useless fuckers.  They
treat their customers with contempt in a way only a government sanctioned
monopoly&amp;nbsp;can.&lt;/p&gt;
&lt;p&gt;I switched to cable internet, and for the first time in years I experienced
a stable, reliable, and &lt;em&gt;fast&lt;/em&gt; internet connection.  And a phone line clear
as a bell.  Miraculously enough, the same cables and phone equipment that
the Telstra technicians blamed for my &lt;span class="caps"&gt;ADSL&lt;/span&gt; woes are working fine plugged
into the cable modem.  How about that?  Is it possible the Telstra
technicians were bullshitting&amp;nbsp;me?&lt;/p&gt;
&lt;p&gt;&lt;span class="quo"&gt;&amp;#8216;&lt;/span&gt;Yes&amp;#8217;, I believe it&amp;nbsp;is.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s amazing &lt;a class="reference external" href="http://www.sortius-is-a-geek.com/not-all-technology-is-equal/"&gt;what a difference decent technology makes&lt;/a&gt; to the user
experience.  This is a point that seems to have been lost in the &lt;span class="caps"&gt;NBN&lt;/span&gt;
debate, which has become mostly focused on the differences in speed between
Labor&amp;#8217;s &lt;span class="caps"&gt;NBN&lt;/span&gt; plan and the Coalition&amp;#8217;s crappy alternative.  But the choice of
technology is crucial to other factors &amp;#8212; like reliability &amp;#8212; that makes a
big difference between a good and bad internet experience.  No matter how
fast (or slow) a broadband connection is, it&amp;#8217;s going to be a frustrating
experience if it drops out at crucial times &amp;#8212; which is likely to happen
with the Coalition&amp;#8217;s &lt;span class="caps"&gt;FTTN&lt;/span&gt; network as it uses the existing copper network
and is therefore prone to the sort of problems that the copper network is
renown&amp;nbsp;for.&lt;/p&gt;
&lt;p&gt;These problems went away when I went away from the copper network and went
to cable.  This resolved the technical problems.  But did this other
internet provider manage to cause other&amp;nbsp;problems?&lt;/p&gt;
&lt;p&gt;&lt;span class="quo"&gt;&amp;#8216;&lt;/span&gt;Yes&amp;#8217;, of course they&amp;nbsp;did.&lt;/p&gt;
&lt;p&gt;All I wanted was reliable internet and phone service.  (Is that really too
much to ask?  In Australia, seems the answer is &amp;#8216;Yes&amp;#8217;.)  But of course I
had no choice but to select a &amp;#8220;bundle&amp;#8221;.  Despite checking every &amp;#8220;opt out&amp;#8221;
check box I could find when signing up, I still got a whole bunch of crap I
&lt;a class="reference external" href="https://www.optus.com.au/shop/tv"&gt;didn&amp;#8217;t&lt;/a&gt;
&lt;a class="reference external" href="https://www.optus.com.au/shop/broadband/devices/internetconnectionkit/"&gt;want.&lt;/a&gt;
Fortunately, they were running a promotion at the time I signed up where
(almost) all the crap I didn&amp;#8217;t want was &amp;#8220;free&amp;#8221;.  Kind of.  Once I got
around to setting up the &amp;#8220;free&amp;#8221; &lt;span class="caps"&gt;PVR&lt;/span&gt; included in the bundle, it wasn&amp;#8217;t hard
to see why they were giving it away for &amp;#8220;free&amp;#8221; &amp;#8212; it&amp;#8217;s a device designed
mainly to entice users to select any number of additional services that will
be automatically added to the monthly&amp;nbsp;bill.&lt;/p&gt;
&lt;p&gt;Those extra charges are likely to go unnoticed, because the bills are a
deliberately complicated work of byzantine&amp;nbsp;obfuscation.&lt;/p&gt;
&lt;p&gt;This internet provider (&amp;#8216;Yes&amp;#8217;, that one) easily wins the prize for most
complicated and difficult to decipher bills I have ever encountered.  I
suspect this is all intentional &amp;#8212; an attempt to confuse customers as much
as possible, so that they can scam as much money out of customers as
possible.  Although I do find it somewhat amusing that this company in
question (&amp;#8216;Yes&amp;#8217;, that one) has a section on their website devoted to
explaining their bills.  Doesn&amp;#8217;t this represent a failure of user
experience with regards to their&amp;nbsp;billing?&lt;/p&gt;
&lt;p&gt;&lt;span class="quo"&gt;&amp;#8216;&lt;/span&gt;Yes,&amp;#8217; I believe it&amp;nbsp;does.&lt;/p&gt;
&lt;p&gt;If they actually cared about their customers understanding their bills,
couldn&amp;#8217;t they actually just &lt;em&gt;simplify their bills&lt;/em&gt;?&lt;/p&gt;
&lt;p&gt;&lt;span class="quo"&gt;&amp;#8216;&lt;/span&gt;Yes,&amp;#8217; of course they&amp;nbsp;could.&lt;/p&gt;
&lt;p&gt;But they don&amp;#8217;t particularly want to , because then customers would be more
likely to notice any billing&amp;nbsp;errors.&lt;/p&gt;
&lt;p&gt;Like I did, after a few months, when I received a bill for $125.  Since I
was on an $85 plan, this didn&amp;#8217;t seem quite&amp;nbsp;right.&lt;/p&gt;
&lt;p&gt;Is $125 more than&amp;nbsp;$85?&lt;/p&gt;
&lt;p&gt;&lt;span class="quo"&gt;&amp;#8216;&lt;/span&gt;Yes&amp;#8217;&lt;/p&gt;
&lt;p&gt;Far be it from me to question the wisdom of large corporations.  If there&amp;#8217;s
one thing I learnt from my Catholic school education, it&amp;#8217;s that no good can
come from thinking for yourself and questioning authority.  But because I
don&amp;#8217;t trust my Catholic school education, I turned to Excel.  Because I
totally trust&amp;nbsp;Microsoft.&lt;/p&gt;
&lt;img alt="Excel screenshot" src="http://www.voidynullness.net/images/BroadbandHustle.png" /&gt;
&lt;p&gt;So tell me Excel, is an Australian telecommunications company trying to rip
me&amp;nbsp;off?&lt;/p&gt;
&lt;p&gt;&lt;span class="quo"&gt;&amp;#8216;&lt;/span&gt;Yes.&amp;#8217;  Indeed they&amp;nbsp;are.&lt;/p&gt;
&lt;p&gt;Imagine my complete lack of surprise at this point.  So this is
the choice I have in the marketplace as a consumer of internet services.  I
can either pay for an &lt;span class="caps"&gt;ADSL&lt;/span&gt; service that just doesn&amp;#8217;t work, or I can pay a
premium for a functional cable internet, including extras I don&amp;#8217;t want, and get
overcharged at every turn.  Free market competition at its best, I&amp;#8217;m&amp;nbsp;sure.&lt;/p&gt;
&lt;p&gt;I called up their helpline and spoke to someone from the Land of the
Distant Call Centre, who might have said her name was &amp;#8220;Mary&amp;#8221;, although I
somehow suspect it&amp;nbsp;wasn&amp;#8217;t.&lt;/p&gt;
&lt;p&gt;Turns out I was being charged for the supposedly &amp;#8220;free&amp;#8221; crap I didn&amp;#8217;t want in
the first place, backdated to the time I switched over to this new
cable internet&amp;nbsp;service.&lt;/p&gt;
&lt;p&gt;&lt;span class="dquo"&gt;&amp;#8220;&lt;/span&gt;Mary&amp;#8221; (if that was her real name) agreed to credit back the amount
overcharged.  So all good right?  No harm, no foul?  Maybe.  At this point,
after my experiences with Telstra, I have no goodwill left for
telecommunications companies.  At this point, I choose to take the most
cynical and sinister interpretation of events.  At this point, I choose to
believe the overcharging was intentional.  It&amp;#8217;s all part of standard
operating procedures for telecommunications providers in Australia &amp;#8212;
create deliberately over-complicated plans/bundles, with lots of extras
customers probably don&amp;#8217;t want, confuse/distract the customer with
ridiculously complex bills, then deliberately overcharge them and hope they
don&amp;#8217;t notice.  Worst case scenario, the customer calls and complains, and
maybe gets a refund.  But for each time this happens, there are probably
far more cases where they customer doesn&amp;#8217;t realise they&amp;#8217;ve been ripped off,
which means these corporate con artists get to keep their ill-gotten&amp;nbsp;gains.&lt;/p&gt;
&lt;p&gt;Although calling them con-artists is probably an insult to accomplished
con-artists everywhere.  It would imply that there is some &amp;#8220;artistry&amp;#8221;, or
craft, or at least competence, to what the internet companies are doing.
But there&amp;#8217;s not even that.  The telecommunications industry in Australia is
less an elaborate confidence trick, and more a simple forthright fraud.
It&amp;#8217;s like a street shell game where there is no ball, no prize, and the
moving cups are just a momentary distraction before beating the
unsuspecting mark to the ground, stealing their wallet and phone, then
calmly standing there as if nothing happened, knowing there will be no
repercussions.  It&amp;#8217;s less con artist and more highway&amp;nbsp;robbery.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m not sure what&amp;#8217;s worse.  The fact all Australian telecommunications
companies routinely fuck their customers over any chance they get?  Or that
they fuck their customers in such an obvious and artless way?  It&amp;#8217;s as if
they&amp;#8217;re not even trying!  If I&amp;#8217;m going to be fucked over by an uncaring,
unethical, unscrupulous corporation, I&amp;#8217;d like them to at least put some
effort into it.  If I&amp;#8217;m going to be fucked over, I&amp;#8217;d rather be fucked good!
Saying something will be included in the price then charging extra anyway
and hoping the customer won&amp;#8217;t notice?  How unoriginal!  Put some
imagination into it!  Do it with&amp;nbsp;flair!&lt;/p&gt;
&lt;p&gt;Of course, screwing their customers is hardly confined to the
telecommunications industry.  (I should at least mention Australian banks,
if only in passing.)  But what&amp;#8217;s most disturbing is just how common this
kind of corporate laziness and contempt for customers and has become.  This
culture of mediocrity in Australian business has gotten to the point of
making a mockery of the whole concept of running a private sector business.
In recent months, we&amp;#8217;ve had a car company &lt;a class="reference external" href="http://www.afr.com/p/national/holden_threatens_to_quit_making_Lm1IEAp0YbDuMFDqHP7K2L"&gt;extort the government&lt;/a&gt;,
&lt;a class="reference external" href="http://www.news.com.au/business/companies/holden-says-it-will-cease-manufacturing-in-australia-without-more-cash-from-taxpayers/story-fnda1bsz-1226662588104"&gt;threatening to stop manufacturing cars in Australia&lt;/a&gt; unless it gets more
government handouts; we&amp;#8217;ve had an &lt;a class="reference external" href="http://www.smh.com.au/business/peak-demand-for-profits-is-rising-20130802-2r4rx.html"&gt;electricity company demand the
government pay them to not produce electricity&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;And here I was naively thinking the idea of a business is to provide an
actual product or service in exchange for money from &lt;em&gt;customers&lt;/em&gt;.  I guess
I should stick to software development, as I&amp;#8217;m obviously missing something
about modern business&amp;nbsp;practises.&lt;/p&gt;
&lt;p&gt;Although maybe I&amp;#8217;m being a bit too harsh.  After all, if the government is
stupid enough to give out free money to corporations who don&amp;#8217;t deserve it,
why shouldn&amp;#8217;t those corporations do their best to get as much cash out of
the tax payer as possible?  Surely it must be hard to constantly compete
and innovate and carve out a competitive advantage in a free market?  So
why bother if you don&amp;#8217;t have to?  Why should Australian car companies
adjust to changing market conditions and consumer preferences, when they
can just continue making the same old crappy cars no one want to buy
anymore, safe in the knowledge the government will continue paying them to
do so, even if consumers won&amp;#8217;t?  Why should electricity companies produce
electricity if they can get idiot politicians to pay them not to produce
electricity?  It&amp;#8217;s much easier that way.  And more environmentally friendly
too.  Just think of the reduced carbon footprint?  And what do we need
electricity for&amp;nbsp;anyway?&lt;/p&gt;
&lt;p&gt;And why should Telstra fix the copper network near my place when they&amp;#8217;ve
got a monopoly on the network?  Why wouldn&amp;#8217;t Telstra&amp;#8217;s competitors
deliberately overcharge me, just to see if they can get away with it?  They
no doubt realise that if I&amp;#8217;m a customer of theirs, it&amp;#8217;s because I&amp;#8217;m out of
other options, so who else am I going to churn to?  Telstra?  Ha!  And it&amp;#8217;s
not as if the regulators are going to do anything.  So the
telecommunications companies can do whatever the hell they want.  (How much
to charge for international roaming?  As much as they fucking well&amp;nbsp;can!)&lt;/p&gt;
&lt;p&gt;So it&amp;#8217;s against this backdrop of corporate laziness, and culture of
mediocrity, we have the Labor&amp;#8217;s National Broadband&amp;nbsp;Network.&lt;/p&gt;
&lt;p&gt;Tony Abbott&amp;#8217;s initial reaction to Labor&amp;#8217;s &lt;span class="caps"&gt;FTTP&lt;/span&gt; &lt;span class="caps"&gt;NBN&lt;/span&gt; proposal was to say if
he was elected, Labor&amp;#8217;s &lt;a class="reference external" href="http://www.businessspectator.com.au/news/2011/6/29/technology/gillard-repeats-abbott-would-%E2%80%98rip-nbn-fibre-up%E2%80%99"&gt;&lt;span class="caps"&gt;NBN&lt;/span&gt; would be ripped out of the ground&lt;/a&gt;.  He angrily
insisted broadband infrastructure should be build by the private sector.
Really Tony?  The private sector?  The same private sector unable to
provide me with a clear analogue phone line?  The same private sector
unable to provide me with a reliable &lt;span class="caps"&gt;ADSL&lt;/span&gt; service?  The same private sector
unable to maintain the current copper infrastructure?  The same private
sector that finds the prospect of billing me the same $85 amount every
month too difficult?  The same private sector that can&amp;#8217;t provide me with
reliable mobile internet?  (I&amp;#8217;m looking at you Vodafone.)  The same private
sector that routines charges customers for a service that doesn&amp;#8217;t work?
(I&amp;#8217;m looking at you every single &lt;span class="caps"&gt;ADSL&lt;/span&gt; provider.)  The same private sector
that&amp;#8217;s concerned only with fucking over their&amp;nbsp;customers?&lt;/p&gt;
&lt;p&gt;For starters, there&amp;#8217;s the obvious question of why the private sector hasn&amp;#8217;t
built a decent broadband network by now?  Why are we still stuck with this
ancient, crumbling copper network for our communication infrastructure?
Abbott can&amp;#8217;t blame Labor for this.  The Liberals were in power for 11 years
under John Howard&amp;#8217;s leadership, during a period of great technological
growth and innovation in other parts of the world.  But for their part, it
seemed the Howard government thought Australia&amp;#8217;s role in the great internet
boom was comic relief, appointing a series of &lt;a class="reference external" href="http://www.theregister.co.uk/2003/09/29/worlds_biggest_luddite_to_retire/"&gt;clueless and incompetent &lt;span class="caps"&gt;IT&lt;/span&gt;
ministers&lt;/a&gt;, and making us an international laughing stock in technology
circles.  Worse, the Howard government &lt;a class="reference external" href="http://www.afr.com/p/technology/telstra_the_monster_that_here_to_CsmPGJdAKfPAyUhe14ae7M"&gt;privatised Telstra without
structural separation&lt;/a&gt;, so even privatised it still remains essentially a
government sanctioned monopoly.  This not only prevents proper competition
in the sector, but also goes a long way to preventing proper investment,
making it difficult, or even impossible, for a private company to get a
reasonable return on any investment in broadband&amp;nbsp;infrastructure.&lt;/p&gt;
&lt;p&gt;Saying the private sector should build a next generation broadband network
is all well and good, but if it hasn&amp;#8217;t happened by now it never will.
Which makes Tony Abbott and the Liberal&amp;#8217;s position on broadband so
frustratingly naive, short-sighted and stupid.  They&amp;#8217;re meant to be the
political party that most represents the interests of business, yet they
don&amp;#8217;t seem to understand the current culture of mediocrity that pervades
the Australian business landscape.  Australian business leaders seem
determined to prove themselves incapable of even wiping their asses without
government assistance.  Yet Tony Abbott expects any of them to have the
forward-thinking vision, initiative and ability to build Australia&amp;#8217;s next
generation broadband infrastructure?  What kind of dreamworld is he living
in?  Telstra can&amp;#8217;t even maintain the current infrastructure to a working&amp;nbsp;standard!&lt;/p&gt;
&lt;p&gt;It also represents a deep misunderstanding of the Australian
telecommunications industry &amp;#8212; in that we don&amp;#8217;t really have one.
Australian telecommunications companies &amp;#8212; from Telstra and the various
ISPs to the mobile phone providers and pretty much everyone in between &amp;#8212;
aren&amp;#8217;t in the business of providing phone and internet services.  That&amp;#8217;s
just a side-effect.  They&amp;#8217;re actually in the business of fucking over their
customers in the most direct ways possible.  It all a scam.  A confidence
trick.  A hustle.  And not a particularly clever one at that.  The fact any
&amp;#8220;telecommunications&amp;#8221; are happening at all is probably just because a few
competent people accidentally got hired once.  Or someone didn&amp;#8217;t get a
memo.  The last thing any of these companies want to do is build
communications infrastructure.  (Just look at Vodafone&amp;#8217;s 3G network!)  In
fact, they would rather not, if they can help it.  Building infrastructure
is a unwelcome distraction from their core business model &amp;#8212; screwing their
customers.  (And sometimes screwing the Tax&amp;nbsp;Payer.)&lt;/p&gt;
&lt;p&gt;Labor&amp;#8217;s &lt;span class="caps"&gt;NBN&lt;/span&gt; plan, for it&amp;#8217;s faults, at least takes all this into account.
Labor seems to get it.  They understand the private sector will never build
a decent broadband network.  They understand the copper network is well
past its use-by date, and needs to be replaced by something better
(i.e. fibre).  They understand that for better or worse, the internet is
becoming increasingly ingrained into the fabric of society and business, so
it&amp;#8217;s vital to our future economic prosperity that fast and reliable
internet services are available.  They understand the problem of Telstra as
the monopolistic elephant in the room, which therefore requires it to be
structurally separated for the good of the industry and the country &amp;#8212; even
if it risks replacing &lt;a class="reference external" href="http://www.telstra.com.au/"&gt;one obnoxious government sanctioned monopoly&lt;/a&gt; with
&lt;a class="reference external" href="http://www.nbnco.com.au/"&gt;another&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Malcolm Turnbull might have managed to do the seemingly impossible and
softened Abbott&amp;#8217;s hardline stance on the &lt;span class="caps"&gt;NBN&lt;/span&gt; (although losing an election
partly because of a misguided and unpopular broadband policy stance
probably also helped), with the Coalition now grudgingly promising to build
some kind of half-assed broadband network.  I suspect Turnbull sat down
with Abbott and explained to him using small words and visual aids that
Australia&amp;#8217;s telecommunications industry was actually one great big fraud
perpetrated on the Australian people, and the natives were beginning to
catch on and get restless.  Since Turnbull has experience as a lawyer,
banker and &lt;span class="caps"&gt;ISP&lt;/span&gt; chairman, he no doubt knows all about defrauding the public.
A little too well,&amp;nbsp;perhaps.&lt;/p&gt;
&lt;p&gt;The problem with the Coalitions &lt;span class="caps"&gt;NBN&lt;/span&gt; policy is that it shows no
understanding of the realities of the current state of play that Labor&amp;#8217;s
does.  Labor&amp;#8217;s &lt;span class="caps"&gt;NBN&lt;/span&gt; acknowledges that the current scammy system has become
obsolete and therefore big (and expensive) changes are needed.  Malcolm&amp;#8217;s
&lt;span class="caps"&gt;NBN&lt;/span&gt; is predicated on a convenient fiction that the existing copper network
is still good enough &amp;#8212; which it is not.  Labor&amp;#8217;s &lt;span class="caps"&gt;NBN&lt;/span&gt; is an acknowledgement
that broadband in Australia has become a scam and need to be replaced
(albeit with possibly grander scam, but at least one that revolves around
working, modern technology).  Malcolm&amp;#8217;s &lt;span class="caps"&gt;NBN&lt;/span&gt; is just a continuation of the
current scam.  Malcolm&amp;#8217;s &lt;span class="caps"&gt;NBN&lt;/span&gt; will be just another chapter in the great
Australian broadband hustle &amp;#8212; where corporations get rich, but consumers
get screwed.  The same scam, except with big green node cabinets on every
street&amp;nbsp;corner.&lt;/p&gt;
&lt;p&gt;With the Coalition&amp;#8217;s &lt;span class="caps"&gt;NBN&lt;/span&gt;, it&amp;#8217;s likely to be the same situation we currently
have, with Telstra as a government sanctioned monopoly without corporate
accountability, and no particularly good choices in the marketplace for
consumers.  We either get a crappy service that barely works, or pay
exorbitant prices to get anything even half decent &amp;#8212; and no proper
competition in the market to keep the corporations honest, leaving them
free to continue their scammy ways.  Which means the consumer of broadband
services in Australia is much like a pornstarlet in a gangbang scene &amp;#8212; no
matter who they turn to, they&amp;#8217;re going to get perfunctorily fucked.  One
way or another.  Because that&amp;#8217;s the whole idea, isn&amp;#8217;t it&amp;nbsp;Malcolm?&lt;/p&gt;
&lt;p&gt;&lt;span class="quo"&gt;&amp;#8216;&lt;/span&gt;Yes&amp;#8217;&lt;/p&gt;
</content><category term="NBN"></category><category term="Broadband"></category><category term="Ranting"></category></entry><entry><title>Extract emails from Gmail with Python via IMAP</title><link href="http://www.voidynullness.net/blog/2013/07/25/gmail-email-with-python-via-imap/" rel="alternate"></link><published>2013-07-25T21:00:00+10:00</published><updated>2013-07-25T21:00:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2013-07-25:/blog/2013/07/25/gmail-email-with-python-via-imap/</id><summary type="html">&lt;p&gt;I have a filter setup in a Gmail account to automatically collect what are essentially automatically generated emails from a particular source, and file them neatly away into a label, leaving the inbox relatively uncluttered with their consistently formatted regularness.  Thing is, those particular emails are not achieving their potential for maximum usefulness to me by just sitting there in my Gmail account.  And with their predictable content, they are ripe candidates for parsing and extracting the useful data, and …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I have a filter setup in a Gmail account to automatically collect what are essentially automatically generated emails from a particular source, and file them neatly away into a label, leaving the inbox relatively uncluttered with their consistently formatted regularness.  Thing is, those particular emails are not achieving their potential for maximum usefulness to me by just sitting there in my Gmail account.  And with their predictable content, they are ripe candidates for parsing and extracting the useful data, and storing it in more useful form, like a database or spreadsheet.  But instead they just pile up, and silently mock my supposed geek cred with each passing day.  Well I have had enough of their judgmental presence!  It is high time I finally worked out a way to programmatically download and parse their sorry arse.  And anyway, if the &lt;a class="reference external" href="http://www.theverge.com/2013/7/17/4517480/nsa-spying-prism-surveillance-cheat-sheet"&gt;&lt;span class="caps"&gt;NSA&lt;/span&gt; is allegedly algorithmically accessing my emails&lt;/a&gt; why shouldn&amp;#8217;t I?  So as part of my continuing effort to &lt;a class="reference external" href="/tag/scripting-my-life/"&gt;Script My Life&lt;/a&gt;, I once again turn to trusty Python to make my life easier &amp;#8212; one hackily bespoke script at a&amp;nbsp;time.&lt;/p&gt;
&lt;p&gt;The nice thing about Python is that there&amp;#8217;s a module for just about everything.  The not-so-nice thing about Python is that there&amp;#8217;s usually more than one module for everything.  And often a bewildering number of packages offering the same functionality.  Usually all deprecated &amp;#8212; except for one.  Or possibly all &amp;#8220;un-Pythonic&amp;#8221; &amp;#8212; except for&amp;nbsp;one.&lt;/p&gt;
&lt;p&gt;So while there may be more than one way to programmatically get emails out of Gmail with python, one option is &lt;span class="caps"&gt;IMAP&lt;/span&gt;.  Gmail can be accessed via &lt;span class="caps"&gt;IMAP&lt;/span&gt;, and conveniently enough the Python Standard Library has an &lt;a class="reference external" href="http://docs.python.org/2.7/library/imaplib.html"&gt;&lt;span class="caps"&gt;IMAP&lt;/span&gt; interface&lt;/a&gt;, so it appears not unreasonable to use &lt;a class="reference external" href="http://tools.ietf.org/html/rfc2060.html"&gt;&lt;span class="caps"&gt;IMAP&lt;/span&gt;&lt;/a&gt;.  Unless you&amp;#8217;re reading this in a future where &lt;span class="caps"&gt;IMAP&lt;/span&gt; has been deprecated.  Or deemed&amp;nbsp;un-Pythonic.&lt;/p&gt;
&lt;p&gt;First step is to create an &lt;span class="caps"&gt;IMAP4&lt;/span&gt; instance, preferably the &lt;span class="caps"&gt;SSL&lt;/span&gt; variant for security, connected to the Gmail server at &lt;tt class="docutils literal"&gt;imap.gmail.com&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="ch"&gt;#!/usr/bin/env python&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;imaplib&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;getpass&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;email&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;datetime&lt;/span&gt;

&lt;span class="n"&gt;M&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;imaplib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IMAP4_SSL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;imap.gmail.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next we can attempt to login.  If the login fails, an exception of type &lt;tt class="docutils literal"&gt;imaplib.&lt;span class="caps"&gt;IMAP4&lt;/span&gt;.error:&lt;/tt&gt; will be&amp;nbsp;raised:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;notatallawhistleblowerIswear@gmail.com&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;getpass&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getpass&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;imaplib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IMAP4&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;LOGIN FAILED!!! &amp;quot;&lt;/span&gt;
    &lt;span class="c1"&gt;# ... exit or deal with failure...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If the login is successful, we can now do IMAPy things with our &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;IMAP4&lt;/span&gt;&lt;/tt&gt; object.  Most methods of &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;IMAP4&lt;/span&gt;&lt;/tt&gt; return a tuple where the first element is the return status of the operation (usually &lt;tt class="docutils literal"&gt;'&lt;span class="caps"&gt;OK&lt;/span&gt;'&lt;/tt&gt; for success), and the second element will be either a string or tuple with data from the&amp;nbsp;operation.&lt;/p&gt;
&lt;p&gt;For example, to get a list of mailboxes on the server, we can call &lt;tt class="docutils literal"&gt;list()&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;rv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mailboxes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;rv&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;OK&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Mailboxes:&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;mailboxes&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With Gmail, this will return a list of labels.  To open one of the mailboxes/labels, call &lt;tt class="docutils literal"&gt;select()&lt;/tt&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;rv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Top Secret/PRISM Documents&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;rv&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;OK&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Processing mailbox...&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="n"&gt;process_mailbox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# ... do something with emails, see below ...&lt;/span&gt;
    &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So with the mailbox selected, we can now get the emails within it.  For example, we can get all the emails in the selected mailbox and for each one output the message number, subject, and&amp;nbsp;date:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# Note: This function definition needs to be placed&lt;/span&gt;
&lt;span class="c1"&gt;#       before the previous block of code that calls it.&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_mailbox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;rv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;ALL&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;rv&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;OK&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;No messages found!&amp;quot;&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;

  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
      &lt;span class="n"&gt;rv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;(RFC822)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;rv&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;OK&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;ERROR getting message&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt;

      &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message_from_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
      &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Message &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;: &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Subject&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
      &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Raw Date:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Date&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="n"&gt;date_tuple&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parsedate_tz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Date&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;date_tuple&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="n"&gt;local_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromtimestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mktime_tz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date_tuple&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
          &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Local Date:&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; \
              &lt;span class="n"&gt;local_date&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;%a, &lt;/span&gt;&lt;span class="si"&gt;%d&lt;/span&gt;&lt;span class="s2"&gt; %b %Y %H:%M:%S&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We use the &lt;tt class="docutils literal"&gt;search()&lt;/tt&gt; method to &lt;a class="reference external" href="http://tools.ietf.org/html/rfc2060.html#section-6.4.4"&gt;get a list of message sequence numbers&lt;/a&gt;, then loop over these, calling &lt;tt class="docutils literal"&gt;fetch()&lt;/tt&gt; to get the actual&amp;nbsp;messages.&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;fetch()&lt;/tt&gt; returns the raw message contents.  To avoid having to parse the actual message data from &lt;tt class="docutils literal"&gt;fetch()&lt;/tt&gt; ourselves, we can use the &lt;a class="reference external" href="http://docs.python.org/2.7/library/email.html"&gt;email&lt;/a&gt; package from the standard library.  Once again, there are a few different packages floating around for doing this kind of thing, but I think &lt;tt class="docutils literal"&gt;email&lt;/tt&gt; is currently the one least likely to get you down-voted on Stack&amp;nbsp;Overflow.&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;message_from_string()&lt;/tt&gt; returns a message object, and we can then access header items as a dictionary on that&amp;nbsp;object.&lt;/p&gt;
&lt;p&gt;Which brings us to the &amp;#8220;Date&amp;#8221; header, and the potentially thorny issue of date and timezone.  If you don&amp;#8217;t care about the date/time the emails were sent, then things are much simpler.  But if you do care about such matters, note that the contents of the &amp;#8220;Date&amp;#8221; header may vary depending on the email client sending the email, and the timezone of the sender.  Reliably converting to local time can be surprisingly tricky.  Python is once again comes to the rescue with numerous modules promising to assist you with all your deepest darkest date conversion needs.  The code snippet above shows one possible way of converting to local time, using the capabilities of &lt;tt class="docutils literal"&gt;email.util&lt;/tt&gt;.  It&amp;#8217;s currently working well enough for my purposes, but there may be better ways to accomplish&amp;nbsp;this.&lt;/p&gt;
&lt;p&gt;The message body can be obtained by calling &lt;tt class="docutils literal"&gt;msg.get_payload()&lt;/tt&gt;, which will return the payload data as a string (if the message is not multi-part).  For text messages, you could then parse the data using &lt;a class="reference external" href="http://docs.python.org/2.7/library/re.html"&gt;regular expressions&lt;/a&gt;.  For parsing contents of &lt;span class="caps"&gt;HTML&lt;/span&gt; emails however, you must not use regular expressions.  Ever.  Or you will feel &lt;a class="reference external" href="http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454"&gt;the Lovecraftian wrath of the Stack Overflow minions&lt;/a&gt;.  Instead, use a &lt;a class="reference external" href="https://github.com/html5lib"&gt;&lt;span class="caps"&gt;HTML&lt;/span&gt; parser&lt;/a&gt;, or higher level scraper like &lt;a class="reference external" href="http://www.crummy.com/software/BeautifulSoup/"&gt;Beautiful Soup&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt;:&lt;/strong&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;A complete version of the above code is available &lt;a class="reference external" href="https://gist.github.com/robulouski/7441883"&gt;in this gist&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;For a variation on the theme, &lt;a class="reference external" href="https://gist.github.com/robulouski/7442321"&gt;see also this gist&lt;/a&gt;: a script that simply dumps all
emails in an &lt;span class="caps"&gt;IMAP&lt;/span&gt; folder to&amp;nbsp;files.&lt;/li&gt;
&lt;/ul&gt;
</content><category term="IMAP"></category><category term="Gmail"></category><category term="Scripting My Life"></category><category term="Python"></category></entry><entry><title>Subclassing QTableWidget into submission</title><link href="http://www.voidynullness.net/blog/2013/06/21/qt-qtablewidget-copy-paste-row-into-excel/" rel="alternate"></link><published>2013-06-21T10:19:00+10:00</published><updated>2013-06-21T10:19:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2013-06-21:/blog/2013/06/21/qt-qtablewidget-copy-paste-row-into-excel/</id><summary type="html">&lt;p&gt;&lt;strong&gt;Python example of subclassing a Qt QTableWidget control and overriding
copy behavior so that the entire selected row is copied to the clipboard,
and stored in a Excel-friendly format for proper&amp;nbsp;pasting.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Hello there &lt;tt class="docutils literal"&gt;QTableWidget&lt;/tt&gt;, you look like just the sort of Qt control I&amp;#8217;m
looking for.  I want to stick some data into you.  But once the data is
inside you, I might want to do other things.  Like perhaps copy and paste
rows of data into Excel …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;Python example of subclassing a Qt QTableWidget control and overriding
copy behavior so that the entire selected row is copied to the clipboard,
and stored in a Excel-friendly format for proper&amp;nbsp;pasting.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Hello there &lt;tt class="docutils literal"&gt;QTableWidget&lt;/tt&gt;, you look like just the sort of Qt control I&amp;#8217;m
looking for.  I want to stick some data into you.  But once the data is
inside you, I might want to do other things.  Like perhaps copy and paste
rows of data into Excel or some other spreadsheet.  I wouldn&amp;#8217;t have thought
that&amp;#8217;s an overly unusual request.  But looks like you won&amp;#8217;t do that without
some overt persuasion.  Seems like you&amp;#8217;re not into data swapping with other
applications.  Well then, you&amp;#8217;ve left me no choice but to subclass your&amp;nbsp;ass:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="ch"&gt;#!/usr/bin/env python&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;PySide.QtCore&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;PySide.QtGui&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TableWidgetCustom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;QTableWidget&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TableWidgetCustom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;keyPressEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;QKeySequence&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Copy&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;QTableWidget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keyPressEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;selection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;selectionModel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;indexes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;selection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;selectedRows&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;indexes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# No row selected&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;
        &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;indexes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;columnCount&lt;/span&gt;&lt;span class="p"&gt;()):&lt;/span&gt;
                &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;
            &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;
        &lt;span class="n"&gt;QApplication&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clipboard&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;See &lt;tt class="docutils literal"&gt;QTableWidget&lt;/tt&gt;, that wasn&amp;#8217;t so bad after all now, was&amp;nbsp;it?&lt;/p&gt;
&lt;p&gt;I expected the Qt table widgets would implement proper copy and paste of
rows by default, especially if options like &lt;tt class="docutils literal"&gt;QTableWidget.SelectRows&lt;/tt&gt; are
set.  But seems I was being overly optimistic.  No matter what options I
tried, it would only copy the text in the single cell that was clicked on,
regardless of how many cells were actually highlighted.  So had to resort
to subclassing.  The above is a fairly minimal implementation that seems to
work well enough for my&amp;nbsp;purposes.&lt;/p&gt;
&lt;p&gt;For data being pasted from the clipboard, apparently Excel expects columns
to be tab delimited, with rows ending with a newline.  The &lt;tt class="docutils literal"&gt;copy()&lt;/tt&gt;
method above attempts to satisfy Excel&amp;#8217;s desires in this regard, and places
the copied text in the required format onto the&amp;nbsp;clipboard.&lt;/p&gt;
&lt;p&gt;To see this in action, the customised &lt;tt class="docutils literal"&gt;QTableWidget&lt;/tt&gt; can be used as&amp;nbsp;normal:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;QDialog&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;tableLabel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Behold, some data, in a table:&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customTable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TableWidgetCustom&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customTable&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setEditTriggers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;QTableWidget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NoEditTriggers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customTable&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setSelectionBehavior&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;QTableWidget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SelectRows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customTable&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setSelectionMode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                             &lt;span class="n"&gt;QTableWidget&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SingleSelection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;layout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QVBoxLayout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tableLabel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customTable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setWindowTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;QTableWidget Copy and Paste Example&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customTable&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setColumnCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customTable&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setRowCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QTableWidgetItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Row &lt;/span&gt;&lt;span class="si"&gt;%d&lt;/span&gt;&lt;span class="s2"&gt; Column &lt;/span&gt;&lt;span class="si"&gt;%d&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                                             &lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customTable&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QApplication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exec_&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The above code creates a dialog box with an instance of our customised
&lt;tt class="docutils literal"&gt;QTableWidget&lt;/tt&gt; and populates it with some dummy data.  Selecting a row
and pressing &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Control-C&lt;/span&gt;&lt;/tt&gt; will copy that row to the clipboard, and it can
then be pasted into Excel (also works in LibreOffice).  But if you were to
replace the &lt;tt class="docutils literal"&gt;TableWidgetCustom&lt;/tt&gt; control with a standard &lt;tt class="docutils literal"&gt;QTableWidget&lt;/tt&gt;,
you&amp;#8217;d see that &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Control-C&lt;/span&gt;&lt;/tt&gt; will only copy the data in one cell, not the
entire&amp;nbsp;row.&lt;/p&gt;
</content><category term="PyQt"></category><category term="PySide"></category><category term="Qt"></category><category term="Excel"></category></entry><entry><title>HTML meta mischief in Pelican blog posts</title><link href="http://www.voidynullness.net/blog/2013/05/25/html-meta-description-in-pelican-blog-posts/" rel="alternate"></link><published>2013-05-25T18:45:00+10:00</published><updated>2013-05-25T18:45:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2013-05-25:/blog/2013/05/25/html-meta-description-in-pelican-blog-posts/</id><summary type="html">&lt;p class="first last"&gt;How to add support for &lt;span class="caps"&gt;HTML&lt;/span&gt; meta description tags to a Pelican theme by taking advantage of the ability to add arbitrary metadata to article and page&amp;nbsp;content.&lt;/p&gt;
</summary><content type="html">&lt;p&gt;For some reason recently I got to thinking about &lt;span class="caps"&gt;HTML&lt;/span&gt; meta elements, and thinking
about these kinds of things often leads to acts of anal retentive
geekiness.  Like noticing that few &lt;a class="reference external" href="http://pelican.notmyidea.org"&gt;Pelican&lt;/a&gt; &lt;a class="reference external" href="https://github.com/getpelican/pelican-themes"&gt;themes&lt;/a&gt; do much with &lt;span class="caps"&gt;HTML&lt;/span&gt;
meta elements, and usually nothing with the description tag in particular.
And it was the &lt;span class="caps"&gt;HTML&lt;/span&gt; meta description tag I was thinking about&amp;nbsp;most.&lt;/p&gt;
&lt;p&gt;I was thinking about whether it&amp;#8217;s even worth thinking about, for it seems
these days &lt;span class="caps"&gt;HTML&lt;/span&gt; meta elements are considered somewhat unimportant as far as
&lt;span class="caps"&gt;SEO&lt;/span&gt; goes.  Search engines may or may not use a meta description tag (or
part thereof) as summary snippets on search results pages, which may
influence click through rates, for those that care about such&amp;nbsp;things.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m not sure I do, but it did get me thinking a bit about the way Pelican
handles &lt;a class="reference external" href="http://docs.getpelican.com/en/latest/getting_started.html#file-metadata"&gt;article summaries&lt;/a&gt;
and other such&amp;nbsp;things.&lt;/p&gt;
&lt;p&gt;For some posts I prefer to provide my own summary, while for others
I&amp;#8217;m happy for Pelican to extract a certain number of words from the&amp;nbsp;start.&lt;/p&gt;
&lt;p&gt;In the same way, for some posts, I might be happy for search engines to
come up with their own summaries, which are likely to be the first sentence
or two.  However, there are definitely some posts where not only would I
like to have some say in the summary that&amp;#8217;s displayed on a search engine
result page, but I would also be willing to go to great lengths to make
sure it isn&amp;#8217;t anything from the first paragraph.  Especially if I&amp;#8217;ve
decided to be deliberately long-winded or scatological in the first
paragraph.  (Of course, some might suggest the best course of action is not
to be long-winded or scatological, but what would be the fun of&amp;nbsp;that?)&lt;/p&gt;
&lt;p&gt;So I decided I did want to have more control over these kinds of things,
and therefore having the ability to optionally specify a meta description
tag for blog posts would be a useful feature to have in my increasingly
hacky custom&amp;nbsp;theme.&lt;/p&gt;
&lt;p&gt;A possibly viable option for some might be to just to take the article
summary and use that as the content of the meta description too.  But I
wanted more control than that &amp;#8212; more often than not I would want the
summary to be different to that of the meta description.  So I took a
different&amp;nbsp;approach.&lt;/p&gt;
&lt;p&gt;With Pelican it&amp;#8217;s possible to add &lt;a class="reference external" href="http://docs.getpelican.com/en/latest/faq.html#can-i-use-arbitrary-metadata-in-my-templates"&gt;arbitrary metadata tags&lt;/a&gt; to a blog
post, and the value of this metadata tag will be available in templates as
an attribute of the article object.  This is great, because it means I can
add all kinds of metadata tags that make sense to me (if no one else) and
modify my theme&amp;#8217;s templates to render that metadata as&amp;nbsp;appropriate.&lt;/p&gt;
&lt;p&gt;For example, let&amp;#8217;s say we have the following blog post in reStructuredText&amp;nbsp;format:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="gh"&gt;Mild Self Loathing&lt;/span&gt;
&lt;span class="gh"&gt;##################&lt;/span&gt;

&lt;span class="nc"&gt;:date:&lt;/span&gt; &lt;span class="nf"&gt;2010-10-03 10:20&lt;/span&gt;
&lt;span class="nc"&gt;:tags:&lt;/span&gt; &lt;span class="nf"&gt;mindless drivel, incoherent whining&lt;/span&gt;
&lt;span class="nc"&gt;:category:&lt;/span&gt; &lt;span class="nf"&gt;self indulgent rambling&lt;/span&gt;
&lt;span class="nc"&gt;:slug:&lt;/span&gt; &lt;span class="nf"&gt;mild-self-loathing&lt;/span&gt;
&lt;span class="nc"&gt;:author:&lt;/span&gt; &lt;span class="nf"&gt;me&lt;/span&gt;
&lt;span class="nc"&gt;:description:&lt;/span&gt; &lt;span class="nf"&gt;This text will be put in the meta description tag.&lt;/span&gt;

Main text of the blog entry.
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note it contains an arbitrary metadata tag called&amp;nbsp;&amp;#8220;description&amp;#8221;.&lt;/p&gt;
&lt;p&gt;In the theme templates, the value of this description tag will be
available as &lt;tt class="docutils literal"&gt;article.description&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;So in the theme&amp;#8217;s &lt;tt class="docutils literal"&gt;base.html&lt;/tt&gt; file we could add the&amp;nbsp;following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;meta&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;description&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;{% block metadesc %}{% endblock %}&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This would define an empty meta description by default.  (Alternatively, we
could have instead specified some default text for the description&amp;nbsp;tag.)&lt;/p&gt;
&lt;p&gt;We can then override this block in the theme&amp;#8217;s &lt;tt class="docutils literal"&gt;article.html&lt;/tt&gt; to define a
meta description specific to the blog&amp;nbsp;post:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;{% block metadesc %}{{ article.description|e }}{% endblock %}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The value of &lt;tt class="docutils literal"&gt;article.description&lt;/tt&gt; will be the value given in the blog
post&amp;#8217;s metadata.  So in the above example, that blog post will include the
following &lt;span class="caps"&gt;HTML&lt;/span&gt; meta element in the generated &lt;span class="caps"&gt;HTML&lt;/span&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;meta&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;description&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;This text will be put in the meta description tag.&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The same thing can be done with Pelican pages, except in this case the
object we&amp;#8217;re working with in the template will be called &amp;#8220;page&amp;#8221;.  So a
similar block in the theme&amp;#8217;s &lt;tt class="docutils literal"&gt;page.html&lt;/tt&gt; file might look something&amp;nbsp;like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;{% block metadesc %}
{% if page.description %}{{ page.description|e }}
{% else%}A page in my blog called {{ page.title }}
{% endif %}
{% endblock %}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The above will use a description metatag if one is specified, otherwise it
will create a generic one using the page&amp;nbsp;title.&lt;/p&gt;
&lt;p&gt;Of course, there are other more esoteric things that can be done with &lt;span class="caps"&gt;HTML&lt;/span&gt;
meta elements.  For instance, if you&amp;#8217;d prefer tag pages not clutter up
potential search engine results, you can suggest that search engines not
index them by adding a robots meta tag to the tag archive page.  In the
theme&amp;#8217;s &lt;tt class="docutils literal"&gt;base.html&lt;/tt&gt; add this&amp;nbsp;line:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;{% block meta_other %}{% endblock %}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then in the theme&amp;#8217;s &lt;tt class="docutils literal"&gt;tag.html&lt;/tt&gt; file, override the &lt;tt class="docutils literal"&gt;meta_other&lt;/tt&gt; block
like&amp;nbsp;this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;{% block meta_other %}&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;meta&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;robots&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;noindex&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
{% endblock %}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, the tag archive pages will have a robots noindex directive in the&amp;nbsp;head.&lt;/p&gt;
&lt;p&gt;We can of course conditionally include or exclude content depending on the
value of metadata.  So, for example, we could do something like this in
&lt;tt class="docutils literal"&gt;article.html&lt;/tt&gt; to prevent draft posts from being indexed by search&amp;nbsp;engines:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;{% block meta_other %}
{% if article.status == &amp;#39;draft&amp;#39; %}
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;meta&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;robots&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;noindex&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
{% else %}{% endif %}
{% endblock %}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The above example used the standard &amp;#8220;status&amp;#8221; metadata, but of course, given
we can add all the arbitrary metadata we like, similar things can be done
with our own custom metadata tags, which makes it relatively
straightforward to add custom conditional features to Pelican&amp;nbsp;themes.&lt;/p&gt;
</content><category term="Pelican"></category></entry><entry><title>I’ll write a script instead…</title><link href="http://www.voidynullness.net/blog/2013/04/12/screw-excel-i-will-write-a-script-instead/" rel="alternate"></link><published>2013-04-12T14:32:00+10:00</published><updated>2013-04-12T14:32:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2013-04-12:/blog/2013/04/12/screw-excel-i-will-write-a-script-instead/</id><summary type="html">&lt;p&gt;&lt;strong&gt;A Python script to convert date fields in a &lt;span class="caps"&gt;CSV&lt;/span&gt; file from &lt;span class="caps"&gt;MM&lt;/span&gt;/&lt;span class="caps"&gt;DD&lt;/span&gt;/&lt;span class="caps"&gt;YYYY&lt;/span&gt;
to &lt;span class="caps"&gt;DD&lt;/span&gt;/&lt;span class="caps"&gt;MM&lt;/span&gt;/&lt;span class="caps"&gt;YYYY&lt;/span&gt; format &amp;#8212; because Excel wouldn&amp;#8217;t do it&amp;nbsp;properly!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I imagine there must be many jobs, especially in and around the finance
industry, where using Excel is part of daily life.  I feel sorry for those&amp;nbsp;people.&lt;/p&gt;
&lt;p&gt;I find myself using spreadsheets quite a bit lately, and it&amp;#8217;s often a
frustrating experience.  There&amp;#8217;s a lot of annoyingly repetitive pointing and …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;strong&gt;A Python script to convert date fields in a &lt;span class="caps"&gt;CSV&lt;/span&gt; file from &lt;span class="caps"&gt;MM&lt;/span&gt;/&lt;span class="caps"&gt;DD&lt;/span&gt;/&lt;span class="caps"&gt;YYYY&lt;/span&gt;
to &lt;span class="caps"&gt;DD&lt;/span&gt;/&lt;span class="caps"&gt;MM&lt;/span&gt;/&lt;span class="caps"&gt;YYYY&lt;/span&gt; format &amp;#8212; because Excel wouldn&amp;#8217;t do it&amp;nbsp;properly!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I imagine there must be many jobs, especially in and around the finance
industry, where using Excel is part of daily life.  I feel sorry for those&amp;nbsp;people.&lt;/p&gt;
&lt;p&gt;I find myself using spreadsheets quite a bit lately, and it&amp;#8217;s often a
frustrating experience.  There&amp;#8217;s a lot of annoyingly repetitive pointing and
clicking for one thing, which is frustrating for a Unixy guy like myself.
Then there&amp;#8217;s Excel&amp;#8217;s remarkable ability to find unique and unexpected ways
to mangle the data I&amp;#8217;m manipulating each step of the way.  (And from what
I&amp;#8217;ve seen, Libre Office isn&amp;#8217;t much better.)  But what really gets to me is
when I have to do something that seems like it should be relatively simple
to do, but turns out to be anything but&amp;nbsp;simple.&lt;/p&gt;
&lt;p&gt;For example, I recently found myself wanting to import a &lt;span class="caps"&gt;CSV&lt;/span&gt; file into
Excel.  A seemingly straightforward enough task in itself, assuming the &lt;span class="caps"&gt;CSV&lt;/span&gt;
file is properly formatted, which in this case it was.  The problem was
that the &lt;span class="caps"&gt;CSV&lt;/span&gt; file in question had a date-time field, and the date part was
in &lt;span class="caps"&gt;US&lt;/span&gt; format (&lt;span class="caps"&gt;MM&lt;/span&gt;/&lt;span class="caps"&gt;DD&lt;/span&gt;/&lt;span class="caps"&gt;YYYY&lt;/span&gt; hh:mm), and I wanted it in &amp;#8220;Australian&amp;#8221; format.
(&lt;span class="caps"&gt;DD&lt;/span&gt;/&lt;span class="caps"&gt;MM&lt;/span&gt;/&lt;span class="caps"&gt;YYY&lt;/span&gt; hh:mm).  Well, to be exact, I didn&amp;#8217;t&amp;#8217; really care about the date
format, but I wanted it converted into a proper &amp;#8220;date&amp;#8221; field in Excel with
the correct value, so I could sort by date.  This proved to be a problem.
Annoyingly though, the functionality appears to be there.  There is a &amp;#8220;Text
Import Wizard&amp;#8221; which in theory allows date fields to be marked, and even
the order (e.g. &amp;#8220;D/M/Y&amp;#8221;) to be specified.  It just didn&amp;#8217;t work.  For me.
For this file.  I think it was getting confused by the time part, and
despite much trial and error and fiddling on my part, it would not parse
the date-time field&amp;nbsp;correctly.&lt;/p&gt;
&lt;p&gt;There might have been a way to get this work.  And I&amp;#8217;m pretty sure I did
get something like this working in the past (maybe using Libre Office??).
But in frustration, I thought, &amp;#8220;screw Excel, I&amp;#8217;ll write a script to do this&amp;nbsp;instead.&amp;#8221;&lt;/p&gt;
&lt;p&gt;And so I did.  I wrote a Python script to reformat date-time fields in a &lt;span class="caps"&gt;CSV&lt;/span&gt;
file just so I could then load the &lt;span class="caps"&gt;CSV&lt;/span&gt; file into Excel and have it properly
recognise the date-time values.  What fun.  There&amp;#8217;s time well&amp;nbsp;spent.&lt;/p&gt;
&lt;p&gt;So for anyone who might be even remotely interested &amp;#8212; and so that they don&amp;#8217;t
have to do this themselves &amp;#8212; here is the&amp;nbsp;script.&lt;/p&gt;
&lt;p&gt;It takes 3 command line&amp;nbsp;arguments:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Input&amp;nbsp;filename&lt;/li&gt;
&lt;li&gt;Output&amp;nbsp;filename&lt;/li&gt;
&lt;li&gt;Index of the date-time field to reformat&amp;nbsp;(zero-based)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It makes the following&amp;nbsp;assumptions:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;File is comma&amp;nbsp;delimited.&lt;/li&gt;
&lt;li&gt;First line in the file is a header, and discarded, so output is without a header&amp;nbsp;line.&lt;/li&gt;
&lt;li&gt;In date-time fields, only the date part is modified.  If there&amp;#8217;s any text
after the date part, it&amp;#8217;s included in the results unmodified, so both
date and date-time fields should be handled&amp;nbsp;properly.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="ch"&gt;#!/usr/bin/env python&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;re&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;csv&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;input_filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Using input file:&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input_filename&lt;/span&gt;
    &lt;span class="n"&gt;output_filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Using output file:&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;output_filename&lt;/span&gt;
    &lt;span class="n"&gt;field_index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Usage: csv_us2au_date.py &amp;lt;inputfile&amp;gt; &amp;lt;outputfile&amp;gt; &amp;lt;fieldindex&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;prog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;r&amp;#39;(\d+)/(\d+)/(\d+)(.*)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output_filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;wb&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input_filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rb&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;csvfile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;writer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csvfile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csvfile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;       &lt;span class="c1"&gt;# skip first line!&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;prog&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;field_index&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;INVALID DATE AT LINE &lt;/span&gt;&lt;span class="si"&gt;%d&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;line_num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;field_index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;field_index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;quot;&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;quot;&amp;#39;&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;field_index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;%02d&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="si"&gt;%02d&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="si"&gt;%d&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
                                                 &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
                                                 &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;field_index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;writerow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So nothing earth-shattering there, just annoying this is what I had to
resort to in an attempt to get Excel to do what I wanted it&amp;nbsp;to.&lt;/p&gt;
&lt;p&gt;Which got me thinking about how, as a coder, there is a tendency to
re-invent the wheel (&amp;#8220;That way of doing this is fucked, I want to do things
my way, because my way will be better!&amp;#8221;)  This is something I (and I
imagine most coders) have to be careful of, and often fight&amp;nbsp;against.&lt;/p&gt;
&lt;p&gt;For one thing, it&amp;#8217;s not always efficient in terms of time and energy.  In
this case, it&amp;#8217;s debatable whether I saved any time.  It&amp;#8217;s not a long or
complex script by any means, but the input file wasn&amp;#8217;t particularly big
either.  It probably would have taken me a similar amount of time just to
manually adjust the date fields.  Although that would have been much less&amp;nbsp;&amp;#8220;fun&amp;#8221;.&lt;/p&gt;
&lt;p&gt;(The problem was, I didn&amp;#8217;t stop just there.  Once I started coding, I kept
coding!  I ended up writing a &lt;a class="reference external" href="https://github.com/robulouski/trade-herder"&gt;whole bunch of far less trivial scripts&lt;/a&gt; to
essentially automate all the data processing I was intending to do in Excel
manually.  This definitely took more time than it would have taken to do
manually, but if nothing else it was an interesting exercise in Python
programming and using SQLAlchemy.  It also means doing the same thing when
Tax Return time comes round again next year should be a lot simpler &amp;#8212;
assuming the broker doesn&amp;#8217;t change the format of it&amp;#8217;s &lt;span class="caps"&gt;CSV&lt;/span&gt; export&amp;nbsp;file!)&lt;/p&gt;
&lt;p&gt;On the other hand, many a great software product or open source project has
started just this way &amp;#8212; with someone cracking the shits and turning to
coding to solve a particular problem or automate some tedious&amp;nbsp;task.&lt;/p&gt;
&lt;p&gt;This is all well and good for those of us who can code &amp;#8212; for those of us
who do have the option of saying, &amp;#8220;screw it, I&amp;#8217;ll write a script to do this
instead&amp;#8221;.  But what about those who don&amp;#8217;t have that &amp;#8220;luxury&amp;#8221;?  What about
those who&amp;#8217;s only interest in computers and software is as a tool to get
things done?  Like those people who might have to use spreadsheets as part
of their day job (for want of a more specialised tool)?  What do they do
when face with some simple text processing task, like in this
case converting a date-time format.  What then?  Write a &lt;span class="caps"&gt;VBA&lt;/span&gt; macro?  Sure,
that&amp;#8217;s presumably why there&amp;#8217;s a scripting language is embedded into Excel, to
allow (power) users to deal with (advanced/unusual) situations the software
by default cannot handle (easily).  But that means learning &lt;span class="caps"&gt;VBA&lt;/span&gt;, and by
extension, learning something about scripting/programming.  Not everyone is
interested or cut out to be a coder, so this isn&amp;#8217;t going to be a great
option for them.  Which leaves lots of manual pointing and&amp;nbsp;clicking.&lt;/p&gt;
&lt;p&gt;Of course, I&amp;#8217;m looking at this from the point of view of a programmer.  I
know that converting between date formats is a simple text processing task,
the sort of simple text processing task computers are well suited for.
Which is why I am frustrated to find I cannot get Excel to do it easily.
Perhaps someone less computer-literate might just resign themselves to do
it manually and not give it a second&amp;nbsp;thought.&lt;/p&gt;
&lt;p&gt;There are some that therefore say this is why some coding knowledge is
useful even for non-coders in this day and age.  Well, kind of.  If someone
is interested in learning to code, I&amp;#8217;m all for it, have at it.  But I think
the reality is not everyone is cut out to be a (good) coder.  And there are
some people who just have no interest in coding, which I think is fine.
Computers after all are just a tool, a machine, a labour saving device.  I
don&amp;#8217;t think computer users should need to be coders to use computers
effectively, in the same way car drivers shouldn&amp;#8217;t need to be mechanics to
drive a car!  If anything, I think the onus is on us coders to do a better
job of creating and designing software that allows users to do what they
need to do as efficiently as possible and with the minimum amount of
annoyances&amp;nbsp;possible.&lt;/p&gt;
&lt;p&gt;In this respect, it seems despite the advances that have been made in
technology and human-computer interaction, we still have a long way to go
to make the technology stay out of the way for users who just want to get
things done, without having to tinker under the hood.  Well, at least
that&amp;#8217;s the case with&amp;nbsp;Excel.&lt;/p&gt;
</content><category term="Python"></category><category term="Excel"></category><category term="Trading"></category></entry><entry><title>Populate a Qt combo box from a database table in PyQt</title><link href="http://www.voidynullness.net/blog/2013/02/05/qt-populate-combo-box-from-database-table/" rel="alternate"></link><published>2013-02-05T14:46:00+11:00</published><updated>2013-02-05T14:46:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2013-02-05:/blog/2013/02/05/qt-populate-combo-box-from-database-table/</id><summary type="html">&lt;p&gt;Qt provides some useful mappers for easily linking relational database
tables with table/grid widgets.  This works well for quickly producing
simple &lt;span class="caps"&gt;CRUD&lt;/span&gt; applications.  But sometimes we might want to escape the
limitations of table and grid controls, and do something fancier &amp;#8212;
something to provide users with a more customised, fine-grained interface,
which usually ends up being something based on forms/dialogs.  So we design
a form, populate it with controls, and we are then faced with having to
populate …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Qt provides some useful mappers for easily linking relational database
tables with table/grid widgets.  This works well for quickly producing
simple &lt;span class="caps"&gt;CRUD&lt;/span&gt; applications.  But sometimes we might want to escape the
limitations of table and grid controls, and do something fancier &amp;#8212;
something to provide users with a more customised, fine-grained interface,
which usually ends up being something based on forms/dialogs.  So we design
a form, populate it with controls, and we are then faced with having to
populate individual controls from database&amp;nbsp;tables.&lt;/p&gt;
&lt;p&gt;I did this recently, and was then faced by what I assume would be a
fairly common situation: I had a simple database table for storing
status values, and wanted to populate a combo box on a dialog with data
from that table (and retrieve the matching &lt;span class="caps"&gt;ID&lt;/span&gt; the user has selected at some&amp;nbsp;point).&lt;/p&gt;
&lt;p&gt;Surprisingly I couldn&amp;#8217;t find a simple example of this online or in
&lt;a
href="http://www.amazon.com/gp/product/0132354187/ref=as_li_tf_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0132354187&amp;linkCode=as2&amp;tag=voidynullness-20"&gt;the Summerfield
book&lt;/a&gt;&lt;img
src="http://www.assoc-amazon.com/e/ir?t=voidynullness-20&amp;l=as2&amp;o=1&amp;a=0132354187"
width="1" height="1" border="0" style="border:none !important;
margin:0px !important;" /&gt;, so I thought I&amp;#8217;d write about the approach I used.
(Let me know in the comments if there&amp;#8217;s a better&amp;nbsp;way!)
&lt;/p&gt;&lt;p&gt;For example, in a hypothetical contact management application, we might
have an SQLite table for storing the &amp;#8220;category&amp;#8221; of phone&amp;nbsp;numbers:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;phone_number_type&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
     &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="n"&gt;AUTOINCREMENT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So in this case we essentially have a glorified enum (but perhaps one which
the user can add/modify, so it can&amp;#8217;t just be hard-coded into the
application).  At a minimum, there would be an integer primary key field,
along with a corresponding string for the category name.  (There could
possibly be other fields as well, but we can happily ignore them for the
task at&amp;nbsp;hand.)&lt;/p&gt;
&lt;p&gt;We can populate the table with some data like&amp;nbsp;so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="ss"&gt;&amp;quot;phone_number_type&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Home&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="ss"&gt;&amp;quot;phone_number_type&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Work&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="ss"&gt;&amp;quot;phone_number_type&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Mobile&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="ss"&gt;&amp;quot;phone_number_type&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Mistress&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="ss"&gt;&amp;quot;phone_number_type&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Meth Dealer&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Since in such cases we&amp;#8217;re usually dealing with a small amount of data, a
valid approach might be to just load all the data from the table into a
data structure in memory, and populate the combo box from that as
appropriate.  However, this approach is less than ideal when the table in
question contains data that the user can modify, and therefore might change
frequently.  It also means writing repetitive boilerplate&amp;nbsp;code.&lt;/p&gt;
&lt;p&gt;In this case we can use the Qt Framework&amp;#8217;s &lt;tt class="docutils literal"&gt;QSqlTableModel&lt;/tt&gt; class to help
us out.  The following example creates a simple dialog box for editing
phone numbers.  The dialog box will contain a combo box widget populated
with data from the &lt;tt class="docutils literal"&gt;phone_number_type&lt;/tt&gt; table, as defined&amp;nbsp;above.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="ch"&gt;#!/usr/bin/env python&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;PyQt4.QtCore&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;PyQt4.QtGui&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;PyQt4.QtSql&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;

&lt;span class="n"&gt;CONFIG_DATABASE_PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;./&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;CONFIG_DATABASE_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;comboboxexample.db&amp;quot;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EditItemDlg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;QDialog&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nb"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EditItemDlg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setWindowTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Edit Phone Number&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Create model&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QSqlTableModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setTable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;phone_number_type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;select&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="n"&gt;buttonBox&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QDialogButtonBox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;QDialogButtonBox&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Ok&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
                                     &lt;span class="n"&gt;QDialogButtonBox&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Cancel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;buttonBox&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;QDialogButtonBox&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setDefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;phoneEdit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QLineEdit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;phoneLabel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;amp;Phone Number:&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;phoneLabel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setBuddy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;phoneEdit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Create combo and set its model&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;typeComboBox&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QComboBox&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;typeComboBox&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;typeComboBox&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setModelColumn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                          &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fieldIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;label&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;typeLabel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;amp;Type:&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;typeLabel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setBuddy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;typeComboBox&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;controlLayout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QGridLayout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;controlLayout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;phoneLabel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;controlLayout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;phoneEdit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;controlLayout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;typeLabel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;controlLayout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;typeComboBox&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;controlLayout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addWidget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buttonBox&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                &lt;span class="n"&gt;Qt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AlignRight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setLayout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;controlLayout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;125&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buttonBox&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SIGNAL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;accepted()&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                     &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SLOT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;accept()&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buttonBox&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SIGNAL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;rejected()&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                     &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SLOT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;reject()&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QApplication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CONFIG_DATABASE_PATH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="n"&gt;CONFIG_DATABASE_NAME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;QSqlDatabase&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;addDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;QSQLITE&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setDatabaseName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="n"&gt;QMessageBox&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;warning&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Combo Box Example&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;QString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Database Error: %1&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lastError&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
        &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Would normally be invoked as modal dialog.&lt;/span&gt;
    &lt;span class="c1"&gt;# But for simplicity we use it as the main form here.&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EditItemDlg&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exec_&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;del&lt;/span&gt; &lt;span class="n"&gt;form&lt;/span&gt;
    &lt;span class="k"&gt;del&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;main()&lt;/tt&gt; function is mostly just Qt boilerplate &amp;#8212; and code to
initialise the database and main dialog window.  The &lt;tt class="docutils literal"&gt;EditItemDlg&lt;/tt&gt; class
demonstrates a simple use of &lt;tt class="docutils literal"&gt;QSqlTableModel&lt;/tt&gt; to populate a combo&amp;nbsp;box.&lt;/p&gt;
&lt;p&gt;In the &lt;tt class="docutils literal"&gt;__init__&lt;/tt&gt; method of &lt;tt class="docutils literal"&gt;EditItemDlg&lt;/tt&gt;, we create an
&lt;tt class="docutils literal"&gt;QSqlTableModel&lt;/tt&gt; for the &lt;tt class="docutils literal"&gt;phone_number_type&lt;/tt&gt; table.  We then create
&lt;tt class="docutils literal"&gt;QComboBox&lt;/tt&gt; control, and replace its default model with our
&lt;tt class="docutils literal"&gt;QSqlTableModel&lt;/tt&gt; by calling the &lt;tt class="docutils literal"&gt;setModel()&lt;/tt&gt; method.&lt;/p&gt;
&lt;p&gt;We then call &lt;tt class="docutils literal"&gt;setModelColumn()&lt;/tt&gt; to tell the combo box which database
field it should use as option text to populate the choices in the drop
down of the combo box &amp;#8212; in this case, the &lt;tt class="docutils literal"&gt;label&lt;/tt&gt; field of the
&lt;tt class="docutils literal"&gt;phone_number_type&lt;/tt&gt; table.&lt;/p&gt;
&lt;p&gt;The result is a combo box widget conveniently populated with choices based
on data currently in the &lt;tt class="docutils literal"&gt;phone_number_type&lt;/tt&gt; table.&lt;/p&gt;
</content><category term="PyQt"></category><category term="Qt"></category><category term="PySide"></category></entry><entry><title>PyQt database driver loading issues on Windows after installing PySide</title><link href="http://www.voidynullness.net/blog/2013/01/24/pyqt-database-driver-loading-issues-on-windows-after-installing-pyside/" rel="alternate"></link><published>2013-01-24T14:14:00+11:00</published><updated>2013-01-24T14:14:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2013-01-24:/blog/2013/01/24/pyqt-database-driver-loading-issues-on-windows-after-installing-pyside/</id><summary type="html">&lt;p&gt;Had a Windows machine with a perfectly fine and functioning development setup of ActiveState Python 2.7, &lt;span class="caps"&gt;QT&lt;/span&gt; &lt;span class="caps"&gt;SDK&lt;/span&gt;, and PyQt bindings.  Then decided to install PySide.  What could possibly go&amp;nbsp;wrong?&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s always&amp;nbsp;something&amp;#8230;&lt;/p&gt;
&lt;p&gt;After installing PySide, none of my PyQt SQLite database applications would work anymore (while still using the PyQt bindings).  Not even the example programs.  I would get a &amp;#8220;Driver not loaded&amp;#8221; error when trying to initialise the database.  However, the PySide database examples ran …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Had a Windows machine with a perfectly fine and functioning development setup of ActiveState Python 2.7, &lt;span class="caps"&gt;QT&lt;/span&gt; &lt;span class="caps"&gt;SDK&lt;/span&gt;, and PyQt bindings.  Then decided to install PySide.  What could possibly go&amp;nbsp;wrong?&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s always&amp;nbsp;something&amp;#8230;&lt;/p&gt;
&lt;p&gt;After installing PySide, none of my PyQt SQLite database applications would work anymore (while still using the PyQt bindings).  Not even the example programs.  I would get a &amp;#8220;Driver not loaded&amp;#8221; error when trying to initialise the database.  However, the PySide database examples ran fine, so looks like installing PySide messed something up in the PyQt installation.  After a couple hours of poking around and Googling (there&amp;#8217;s hours of my life I&amp;#8217;m not getting back!), I worked out what the problem&amp;nbsp;was.&lt;/p&gt;
&lt;p&gt;After installing PySide, this is what &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;C:\Python27\qt.conf&lt;/span&gt;&lt;/tt&gt; contained:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
[Paths]
Prefix = C:/Python27/Lib/site-packages/PySide
Binaries = C:/Python27/Lib/site-packages/PySide
Plugins = C:/Python27/Lib/site-packages/PySide/plugins
Translations = C:/Python27/Lib/site-packages/PySide/translations
&lt;/pre&gt;
&lt;p&gt;I changed it&amp;nbsp;to:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
[Paths]
Prefix = C:/Python27/Lib/site-packages/PyQt4
Binaries = C:/Python27/Lib/site-packages/PyQt4
Plugins = C:/Python27/Lib/site-packages/PyQt4/plugins
Translations = C:/Python27/Lib/site-packages/PyQt4/translations
&lt;/pre&gt;
&lt;p&gt;And once again, I was able to run my existing PyQt database code&amp;nbsp;successfully.&lt;/p&gt;
&lt;p&gt;Looks like I&amp;#8217;ll have to maintain 2 copies of that &lt;tt class="docutils literal"&gt;qt.conf&lt;/tt&gt; file, and switch between them depending on whether I&amp;#8217;m running PySide or PyQt applications.  Not ideal, but at least things are working once&amp;nbsp;again.&lt;/p&gt;
&lt;p&gt;In hindsight, I probably should have used the &lt;a class="reference external" href="http://qt-project.org/wiki/PySide_Binaries_Windows"&gt;setuptools installation method&lt;/a&gt;, possibly inside a&amp;nbsp;virtualenv.&lt;/p&gt;
</content><category term="PyQt"></category><category term="PySide"></category><category term="Python"></category></entry><entry><title>Installing NX Client on Linux</title><link href="http://www.voidynullness.net/blog/2012/10/17/install-nx-client-linux/" rel="alternate"></link><published>2012-10-17T17:33:00+11:00</published><updated>2012-10-17T17:33:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2012-10-17:/blog/2012/10/17/install-nx-client-linux/</id><summary type="html">&lt;p&gt;So you wanna remotely access a Linux box?  From a Windows machine?  The
&lt;a class="reference external" href="http://www.nomachine.com/download.php"&gt;Nomachine &lt;span class="caps"&gt;NX&lt;/span&gt; Client&lt;/a&gt; looks like a reasonable&amp;nbsp;option.&lt;/p&gt;
&lt;p&gt;To install on a 64-bit (Ubuntu-based) Linux, first &lt;a class="reference external" href="http://www.nomachine.com/download-package.php?Prod_Id=3776"&gt;download the &lt;span class="caps"&gt;NX&lt;/span&gt; Free
Edition for Linux&lt;/a&gt;.  You should end up with something like the following
deb&amp;nbsp;packages:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
nxclient_3.5.0-7_amd64.deb
nxnode_3.5.0-9_amd64.deb
nxserver_3.5.0-11_amd64.deb
&lt;/pre&gt;
&lt;p&gt;Then:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo chmod 755 /usr/lib/cups/backend/ipp
sudo dpkg -i nxclient_3.5.0-7_amd64.deb
sudo dpkg -i nxnode_3.5 …&lt;/pre&gt;</summary><content type="html">&lt;p&gt;So you wanna remotely access a Linux box?  From a Windows machine?  The
&lt;a class="reference external" href="http://www.nomachine.com/download.php"&gt;Nomachine &lt;span class="caps"&gt;NX&lt;/span&gt; Client&lt;/a&gt; looks like a reasonable&amp;nbsp;option.&lt;/p&gt;
&lt;p&gt;To install on a 64-bit (Ubuntu-based) Linux, first &lt;a class="reference external" href="http://www.nomachine.com/download-package.php?Prod_Id=3776"&gt;download the &lt;span class="caps"&gt;NX&lt;/span&gt; Free
Edition for Linux&lt;/a&gt;.  You should end up with something like the following
deb&amp;nbsp;packages:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
nxclient_3.5.0-7_amd64.deb
nxnode_3.5.0-9_amd64.deb
nxserver_3.5.0-11_amd64.deb
&lt;/pre&gt;
&lt;p&gt;Then:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo chmod 755 /usr/lib/cups/backend/ipp
sudo dpkg -i nxclient_3.5.0-7_amd64.deb
sudo dpkg -i nxnode_3.5.0-9_amd64.deb
sudo dpkg -i nxserver_3.5.0-11_amd64.deb
&lt;/pre&gt;
&lt;p&gt;If all goes well, that should conclude the Linux side&amp;nbsp;installation.&lt;/p&gt;
&lt;p&gt;All that remains is to download and install the &lt;a class="reference external" href="http://www.nomachine.com/download-package.php?Prod_Id=3835"&gt;&lt;span class="caps"&gt;NX&lt;/span&gt; Client for Windows&lt;/a&gt; on
the Windows machine, and a world of stultifyingly laggy screen refreshes&amp;nbsp;awaits.&lt;/p&gt;
</content><category term="NX"></category><category term="Things To Do After Installing Linux"></category></entry><entry><title>SVN in a world of Git and Mercurial</title><link href="http://www.voidynullness.net/blog/2012/08/08/svn-branching-merging/" rel="alternate"></link><published>2012-08-08T00:00:00+10:00</published><updated>2012-08-08T00:00:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2012-08-08:/blog/2012/08/08/svn-branching-merging/</id><summary type="html">&lt;p&gt;Oh, so source code for that project I&amp;#8217;m working on has been moved from &lt;span class="caps"&gt;CVS&lt;/span&gt; to &lt;span class="caps"&gt;SVN&lt;/span&gt;?  Great, thanks for not telling me earlier so I could make sure all my changes were committed&amp;nbsp;first.&lt;/p&gt;
&lt;p&gt;Well it is about time we got rid of &lt;span class="caps"&gt;CVS&lt;/span&gt;.  But isn&amp;#8217;t moving &lt;em&gt;to&lt;/em&gt; &lt;span class="caps"&gt;SVN&lt;/span&gt; a bit anachronistic given we have Git and Mercurial (and even Bazaar) nowadays,  ready and willing to fulfill all our deepest, darkest version control needs?  Isn&amp;#8217;t &lt;span class="caps"&gt;SVN …&lt;/span&gt;&lt;/p&gt;</summary><content type="html">&lt;p&gt;Oh, so source code for that project I&amp;#8217;m working on has been moved from &lt;span class="caps"&gt;CVS&lt;/span&gt; to &lt;span class="caps"&gt;SVN&lt;/span&gt;?  Great, thanks for not telling me earlier so I could make sure all my changes were committed&amp;nbsp;first.&lt;/p&gt;
&lt;p&gt;Well it is about time we got rid of &lt;span class="caps"&gt;CVS&lt;/span&gt;.  But isn&amp;#8217;t moving &lt;em&gt;to&lt;/em&gt; &lt;span class="caps"&gt;SVN&lt;/span&gt; a bit anachronistic given we have Git and Mercurial (and even Bazaar) nowadays,  ready and willing to fulfill all our deepest, darkest version control needs?  Isn&amp;#8217;t &lt;span class="caps"&gt;SVN&lt;/span&gt; a bit&amp;#8230;2002, as opposed to&amp;nbsp;2012?&lt;/p&gt;
&lt;p&gt;No I am not being a smartarse.  Just saying, is all.  If I was being a smartarse I&amp;#8217;d say that &lt;span class="caps"&gt;SVN&lt;/span&gt; is only an improvement to &lt;span class="caps"&gt;CVS&lt;/span&gt; in the same way being poked with a less pointy stick is better than being poked with a really pointy stick, but ideally I&amp;#8217;d rather just not be poked by&amp;nbsp;anything.&lt;/p&gt;
&lt;p&gt;Oh, so eventually all the projects are going to move to &lt;span class="caps"&gt;SVN&lt;/span&gt;, but we can&amp;#8217;t just yet?  Because a large legacy project with decades of history was just imported into the one central &lt;span class="caps"&gt;SVN&lt;/span&gt; repository and it blew out the disk usage?  So we now have to get a new machine to act as the &lt;span class="caps"&gt;SVN&lt;/span&gt;&amp;nbsp;server?&lt;/p&gt;
&lt;p&gt;You realise that with Git or Mercurial, you can pretty much put the repositores just about anywhere, and even move them around pretty much at will?  Or even use one of the cloud hosting&amp;nbsp;services?&lt;/p&gt;
&lt;p&gt;No I am not being a smartarse.  Just saying, is all.  If I was being a smartarse I might make some kind of tortured analogy, comparing the switch from &lt;span class="caps"&gt;CVS&lt;/span&gt; to &lt;span class="caps"&gt;SVN&lt;/span&gt; to turning up to a gunfight with a butter knife, sneaking away to a weapons store, walking down the back past racks with all manner of handguns and automated weaponry, selecting a machette, then returning to the gunfight full of misguided confidence.  The machettee might be better than a butter knife, but in a gunfight it&amp;#8217;s not exactly the best tool for the job at hand.  And &lt;span class="caps"&gt;SVN&lt;/span&gt; is to modern version control what a large piece of warm, soggy lettuce is to both grastonomy and flagellation &amp;#8212; an entirely unsatisfying&amp;nbsp;experience.&lt;/p&gt;
&lt;p&gt;No I do not want to have a meeting to discuss my attitude problem.  Merely expressing a subjective&amp;nbsp;opinion.&lt;/p&gt;
&lt;p&gt;Oh, and to make matters worse, the build systems for some projects have weird dependencies on the actual &lt;span class="caps"&gt;SVN&lt;/span&gt; revision numbers?  Making moving projects or splitting up the central repository tricky at best and insanely complicated at worse?  This just keeps getting better and&amp;nbsp;better.&lt;/p&gt;
&lt;p&gt;No, I certainly do not want the job of build controller.  I&amp;#8217;ll shut up&amp;nbsp;now.&lt;/p&gt;
&lt;p&gt;With teeth gritted and expectations suitably lowered, I will adjust my workflow to &lt;span class="caps"&gt;SVN&lt;/span&gt;&amp;#8230;while silently closing my eyes and thinking of&amp;nbsp;Git&amp;#8230;&lt;/p&gt;
&lt;div class="section" id="some-obscure-and-not-so-obscure-svn-tasks"&gt;
&lt;h2&gt;Some obscure (and not so obscure) &lt;span class="caps"&gt;SVN&lt;/span&gt;&amp;nbsp;tasks&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;SVN&lt;/span&gt; diff without unified diff&amp;nbsp;format:&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="literal-block"&gt;
svn diff --diff-cmd diff -x -b &amp;lt;filename&amp;gt;
&lt;/pre&gt;
&lt;hr class="docutils" /&gt;
&lt;p&gt;&lt;strong&gt;Merging cherrypicked changes (in individual files) from trunk to&amp;nbsp;branch:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Check out&amp;nbsp;branch:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
svn co svn+ssh://svn/usr/local/svn/project/branches/ver_1_42/ ver_1_42
&lt;/pre&gt;
&lt;p&gt;Find revision number of change on&amp;nbsp;trunk:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
svn diff -c 9176 file.c
&lt;/pre&gt;
&lt;p&gt;Change current working directory to branch checkout and merge just the changes in the specific revision from the&amp;nbsp;trunk:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
cd ver_1_42/src/sub/dir/
svn merge -c 9176 svn+ssh://svn/usr/local/svn/project/trunk/src/sub/dir/file.c file.c
&lt;/pre&gt;
&lt;p&gt;Rinse and repeat for all files as&amp;nbsp;necessary.&lt;/p&gt;
&lt;p&gt;(This worked, but in this case I was only interested in the changeset from a single commit/revision, albeit with many files affected.   Might not work as well across multiple&amp;nbsp;revisions?)&lt;/p&gt;
&lt;hr class="docutils" /&gt;
&lt;p&gt;&lt;strong&gt;Revert changes from one file on new branch (reverse merge from&amp;nbsp;trunk):&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="literal-block"&gt;
cd ~/checkout/project/tags/ver_2_41_3/src/sub/dir
svn merge -r 1449:1448 svn+ssh://svn/usr/local/svn/project/trunk/src/sub/dir/file.c file.c
&lt;/pre&gt;
&lt;/div&gt;
</content><category term="SVN"></category><category term="Ranting"></category></entry><entry><title>Canon MP Navigator “Scan Failed” Error</title><link href="http://www.voidynullness.net/blog/2012/08/07/canon-mp800-navigator-scan-failed-error/" rel="alternate"></link><published>2012-08-07T23:31:00+10:00</published><updated>2012-08-07T23:31:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2012-08-07:/blog/2012/08/07/canon-mp800-navigator-scan-failed-error/</id><summary type="html">&lt;p&gt;It was late.  I should have gone to sleep by now.  I wanted to go to sleep.  I was about to shut down my laptop and get ready to go to sleep.  But I remembered I had to scan a document then email it.  I should have done this weeks ago.  It&amp;#8217;s late, but I&amp;#8217;ll quickly do it anyway.  Shouldn&amp;#8217;t take long.  The laptop is on, the Canon Multifunction &lt;span class="caps"&gt;MP800&lt;/span&gt; is right there next to it, thanks …&lt;/p&gt;</summary><content type="html">&lt;p&gt;It was late.  I should have gone to sleep by now.  I wanted to go to sleep.  I was about to shut down my laptop and get ready to go to sleep.  But I remembered I had to scan a document then email it.  I should have done this weeks ago.  It&amp;#8217;s late, but I&amp;#8217;ll quickly do it anyway.  Shouldn&amp;#8217;t take long.  The laptop is on, the Canon Multifunction &lt;span class="caps"&gt;MP800&lt;/span&gt; is right there next to it, thanks to a recent reorganisation of furniture so that all the computer equipment is in one place, and I have the document right&amp;nbsp;here.&lt;/p&gt;
&lt;p&gt;How long could it possibly take?  (Ha!  I had to&amp;nbsp;ask!)&lt;/p&gt;
&lt;p&gt;Always far longer than I expect, it&amp;nbsp;seems.&lt;/p&gt;
&lt;p&gt;I turn on my temperamental
&lt;a href="http://www.amazon.com/gp/product/B000AZ0QC2/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=B000AZ0QC2&amp;linkCode=as2&amp;tag=voidynullness-20&amp;linkId=56UBRWQ3COILSWUD"&gt;&lt;span class="caps"&gt;MP800&lt;/span&gt; multifunction printer/scanner&lt;/a&gt;&lt;img src="http://ir-na.amazon-adsystem.com/e/ir?t=voidynullness-20&amp;l=as2&amp;o=1&amp;a=B000AZ0QC2" width="1" height="1" border="0" style="border:none !important; margin:0px !important;" /&gt;
and wait for it to complain it&amp;#8217;s out of&amp;nbsp;ink.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Yes I know you are out of ink,
and I don&amp;#8217;t care, because I use the cheap laser printer next to
you for my printing needs, to avoid the corporate extortion that is
&lt;a href="http://www.amazon.com/gp/product/B000BV0AYY/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=B000BV0AYY&amp;linkCode=as2&amp;tag=voidynullness-20&amp;linkId=B5LEIFPDWZREVEIW"&gt;inkjet ink prices&lt;/a&gt;&lt;img src="http://ir-na.amazon-adsystem.com/e/ir?t=voidynullness-20&amp;l=as2&amp;o=1&amp;a=B000BV0AYY" width="1" height="1" border="0" style="border:none !important; margin:0px !important;" /&gt;, so you have been relegated to just occasional scanning duties.  Now
hold still while I semi-randomly hold down various combinations of
buttons on your control panel until I eventually manage to dismiss your
annoyingly persistent&amp;nbsp;errors.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;I start up the Canon &lt;span class="caps"&gt;MP&lt;/span&gt; Navigator application on the laptop, which has usually done a serviceable job of scanning documents and saving them as &lt;span class="caps"&gt;PDF&lt;/span&gt; files.  I place the document on the scanner.  I click the &amp;#8220;Scan to &lt;span class="caps"&gt;PDF&lt;/span&gt;&amp;#8221; button in &lt;span class="caps"&gt;MP&lt;/span&gt; Navigator.  &lt;span class="caps"&gt;MP&lt;/span&gt; Navigator  seems to sit and ponder this task for a while, and then a &amp;#8220;Scan failed&amp;#8221; error message appears.  &lt;em&gt;Thank you for that oh so helpful and detailed error message you useless piece of corporate bloatware.  What do mean &amp;#8220;Scan failed?&amp;#8221;  The scanner is right there next to you, all plugged in and waiting for your&amp;nbsp;command!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;And you were working fine last time I tried&amp;nbsp;this.&lt;/p&gt;
&lt;p&gt;At least I think you&amp;nbsp;were.&lt;/p&gt;
&lt;p&gt;This actually did get me thinking.  I suspect I might have been doing most of my scanning in the past with my old Vista laptop, where everything was working fine.  However I was sure that at some point reasonably recently I also did some scanning with my this particular laptop in question &amp;#8212; a newer Windows 7 machine.  In any case, it certainly had all the right software installed.  But I suppose it is possible that while I did install all the required software, I have never actually tried scanning from this particular laptop.  I have almost certainly printed from this laptop, but perhaps I have never used it for&amp;nbsp;scanning?&lt;/p&gt;
&lt;p&gt;In any case, scanning is now&amp;nbsp;broken.&lt;/p&gt;
&lt;p&gt;So much for an early night.  Because I Will Not Be Able To Sleep Until I Get This Fucking Thing&amp;nbsp;Working.&lt;/p&gt;
&lt;p&gt;I go to the Canon website.  I check for newer versions of drivers and &lt;span class="caps"&gt;MP&lt;/span&gt; Navigator.  Looks like my system has the latest versions of&amp;nbsp;everything.&lt;/p&gt;
&lt;p&gt;I delve into the dark depths of the start menu, looking for any other piece of software that might be able to scan.  I do actually find something, and manage to  successfully scan an image using a different piece of software already installed on my system.  This would indicate that the actual scanner is working, so the problem must be with the &lt;span class="caps"&gt;MP&lt;/span&gt; Navigator software.  Unfortunately while I can get a scanned image, I can&amp;#8217;t export to &lt;span class="caps"&gt;PDF&lt;/span&gt; with this other software, so I still need to work out what the hell is wrong with &lt;span class="caps"&gt;MP&lt;/span&gt;&amp;nbsp;Navigator.&lt;/p&gt;
&lt;p&gt;So I google.  Eventually, I manage to find a&amp;nbsp;solution.&lt;/p&gt;
&lt;p&gt;I get scanning working by adding the following directory to the user &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;PATH&lt;/span&gt;&lt;/tt&gt; environment&amp;nbsp;variable:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
C:\Windows\twain_32\MP800
&lt;/pre&gt;
&lt;p&gt;For those not used to delving into the long forgotten labyrinthine depths of the Windows 7 Control Panel to change an environment variable, follow these&amp;nbsp;steps:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Navigate to &lt;tt class="docutils literal"&gt;Control &lt;span class="pre"&gt;Panel--&amp;gt;System&lt;/span&gt; and &lt;span class="pre"&gt;Security--&amp;gt;System&lt;/span&gt;&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;Select the &amp;#8220;Advanced system settings&amp;#8221; option that&amp;#8217;s attempting to hide unobtrusively in the sidebar, which will bring up the &amp;#8220;System Properties&amp;#8221;&amp;nbsp;dialog.&lt;/li&gt;
&lt;li&gt;Go to the &amp;#8220;Advanced&amp;#8221; tab, and click on the &amp;#8220;Environment Variables&amp;#8221; button at the&amp;nbsp;bottom.&lt;/li&gt;
&lt;li&gt;Pause momentarily to marvel at the simplicity and intuitiveness of&amp;nbsp;Windows.&lt;/li&gt;
&lt;li&gt;Select the &lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;PATH&lt;/span&gt;&lt;/tt&gt; environment variable from the list, then click the &amp;#8220;Edit&amp;#8230;&amp;#8221;&amp;nbsp;button.&lt;/li&gt;
&lt;li&gt;Add the above directory to the list of semi-colon separated directories already&amp;nbsp;there.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Scanning should now&amp;nbsp;work.&lt;/p&gt;
&lt;p&gt;After doing the above I was able to scan and save documents as &lt;span class="caps"&gt;PDF&lt;/span&gt; using &lt;span class="caps"&gt;MP&lt;/span&gt; Navigator.  Better late than&amp;nbsp;never.&lt;/p&gt;
&lt;p&gt;As is often the case with these things, the problem was relatively straightforward to solve once I knew what the problem was.  But the weird thing is I don&amp;#8217;t remember having this problem, or having to manually configure this environment variable, on my old Windows Vista&amp;nbsp;laptop.&lt;/p&gt;
&lt;p&gt;The whole thing reminds me of an &lt;a class="reference external" href="http://youtu.be/k6C_HjWr3Nk"&gt;old Eddie Izzard routine&lt;/a&gt;.  &amp;#8220;Control-P-print&amp;#8221; indeed.  Or in this case, &amp;#8220;Scan, damn&amp;nbsp;you!&amp;#8221;&lt;/p&gt;
 &lt;iframe width="420" height="315"  src="http://www.youtube.com/embed/k6C_HjWr3Nk" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;</content><category term="Ranting"></category></entry><entry><title>What license agreement?</title><link href="http://www.voidynullness.net/blog/2012/06/26/what-license-agreement/" rel="alternate"></link><published>2012-06-26T18:56:00+10:00</published><updated>2012-06-26T18:56:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2012-06-26:/blog/2012/06/26/what-license-agreement/</id><summary type="html">&lt;p&gt;&lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;DEVELOPER&lt;/span&gt;:&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve create a new &lt;span class="caps"&gt;MSI&lt;/span&gt; installer using WiX, for that legacy front end Windows application.  Does the install wizard need to display a license&amp;nbsp;agreement?&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;MANAGER&lt;/span&gt;:&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;License&amp;nbsp;agreement?&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;DEVELOPER&lt;/span&gt;:&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;Yeah, the default WiX user interface includes a license agreement&amp;nbsp;page.&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;MANAGER&lt;/span&gt;:&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;What&amp;#8217;s on the license agreement page at the moment?  Boiler plate&amp;nbsp;text?&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;DEVELOPER&lt;/span&gt;:&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;No idea.  Never read it.  It&amp;#8217;s a license agreement page.  Just ignored it and clicked&amp;nbsp;next&amp;#8230;&lt;/p&gt;
</summary><content type="html">&lt;p&gt;&lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;DEVELOPER&lt;/span&gt;:&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve create a new &lt;span class="caps"&gt;MSI&lt;/span&gt; installer using WiX, for that legacy front end Windows application.  Does the install wizard need to display a license&amp;nbsp;agreement?&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;MANAGER&lt;/span&gt;:&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;License&amp;nbsp;agreement?&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;DEVELOPER&lt;/span&gt;:&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;Yeah, the default WiX user interface includes a license agreement&amp;nbsp;page.&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;MANAGER&lt;/span&gt;:&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;What&amp;#8217;s on the license agreement page at the moment?  Boiler plate&amp;nbsp;text?&lt;/p&gt;
&lt;p&gt;&lt;tt class="docutils literal"&gt;&lt;span class="caps"&gt;DEVELOPER&lt;/span&gt;:&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;No idea.  Never read it.  It&amp;#8217;s a license agreement page.  Just ignored it and clicked&amp;nbsp;next&amp;#8230;&lt;/p&gt;
</content><category term="WiX"></category><category term="Attempted Humour"></category></entry><entry><title>Scripts for batch renaming of files to add a date prefix</title><link href="http://www.voidynullness.net/blog/2012/03/29/script-rename-move-date-reformat/" rel="alternate"></link><published>2012-03-29T00:00:00+11:00</published><updated>2012-03-29T00:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2012-03-29:/blog/2012/03/29/script-rename-move-date-reformat/</id><summary type="html">&lt;p&gt;A financial institution of which I am a customer (which shall remain nameless) frequently (like almost every weekday!) emails me &lt;span class="caps"&gt;PDF&lt;/span&gt; statements.  I rarely need to refer to said statements, so I could just configure my email client to automatically filter them away into some folder and not give them the slightest consideration.  But occasionally I might need to check something in one of these statements, usually around Tax Return time, and usually something from many months/years past.  Sifting …&lt;/p&gt;</summary><content type="html">&lt;p&gt;A financial institution of which I am a customer (which shall remain nameless) frequently (like almost every weekday!) emails me &lt;span class="caps"&gt;PDF&lt;/span&gt; statements.  I rarely need to refer to said statements, so I could just configure my email client to automatically filter them away into some folder and not give them the slightest consideration.  But occasionally I might need to check something in one of these statements, usually around Tax Return time, and usually something from many months/years past.  Sifting through PDFs stored as email attachments is not ideal.  Therefore, I download the statements, and store them in a Dropbox folder for safekeeping, in case The Tax Man ever enquires about their numerical specifics.  This makes things easier to find if I need to look something up.  Or it would if the financial institution in question had shown more foresight in the naming convention of said statements.  They have filenames&amp;nbsp;like:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
29 March 2012 Statement.pdf
&lt;/pre&gt;
&lt;p&gt;I probably shouldn&amp;#8217;t complain about this.  At least there is an unambiguous and &amp;#8212; more importantly &amp;#8212; &lt;em&gt;consistent&lt;/em&gt; date component as part of the filename.  Including the year.  That&amp;#8217;s certainly better than having each and every statement file called&amp;nbsp;&amp;#8220;Statement.pdf&amp;#8221;.&lt;/p&gt;
&lt;p&gt;Still, ideally I&amp;#8217;d want the date to be of the format &lt;span class="caps"&gt;YYY&lt;/span&gt;-mm-dd, so that a statement for a particular date is easier to find, given a directory full of these&amp;nbsp;files.&lt;/p&gt;
&lt;p&gt;But I&amp;#8217;m certainly not going to bother renaming each file manually.  Especially since I&amp;#8217;m a coder.  I&amp;#8217;ll write a script to do this instead.  But if I&amp;#8217;m going to write a script, might as well also automate the step of copying these &lt;span class="caps"&gt;PDF&lt;/span&gt; files from the &amp;#8220;Downloads&amp;#8221; folder, where the attachments initially end up, to their ultimate destination in my&amp;nbsp;Dropbox.&lt;/p&gt;
&lt;p&gt;So here&amp;#8217;s an implementation of this as a Bash&amp;nbsp;script:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="ch"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="nv"&gt;FROM_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/home/rob/Downloads
&lt;span class="nv"&gt;TO_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/home/rob/Dropbox/Docs/statements

&lt;span class="nb"&gt;shopt&lt;/span&gt; -s nullglob
&lt;span class="k"&gt;for&lt;/span&gt; f in &lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;FROM_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/*Statement.pdf
&lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="nv"&gt;date_part&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;basename &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sed -e &lt;span class="s1"&gt;&amp;#39;s/ *[S|s]tatement.*pdf//;&amp;#39;&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
    &lt;span class="nv"&gt;new_date&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;date --date&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$date_part&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;+%Y-%m-%d&amp;quot;&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
    &lt;span class="nv"&gt;suffix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;basename &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sed -e &lt;span class="s1"&gt;&amp;#39;s/ //g;&amp;#39;&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
    &lt;span class="nv"&gt;new_filename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;new_date&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_&lt;/span&gt;&lt;span class="nv"&gt;$suffix&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; -e &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TO_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;new_filename&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;`basename &amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;` not copied. File already exists: &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;new_filename&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Moving `basename &amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;` to &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;new_filename&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
        mv -i &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TO_DIR&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;new_filename&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And here&amp;#8217;s the same thing as a PowerShell script, so that I can download these statements from whatever machine I&amp;#8217;m currently working on, be it Linux or&amp;nbsp;Windows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nv"&gt;$from_dir&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;C:\Users\Rob\Downloads&amp;quot;&lt;/span&gt;
&lt;span class="nv"&gt;$to_dir&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;C:\Users\Rob\Documents\Dropbox\Docs\statements&amp;quot;&lt;/span&gt;

&lt;span class="nv"&gt;$files&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;get-childitem&lt;/span&gt; &lt;span class="nv"&gt;$from_dir&lt;/span&gt;&lt;span class="p"&gt;\*&lt;/span&gt; &lt;span class="n"&gt;-include&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Statement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pdf&lt;/span&gt;
&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;$files&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;-match&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;^\d\d [A-Z]{3} \d{4} Statement.pdf$&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$date_part&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="no"&gt;[regex]&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot; *Statement.*\.pdf&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nv"&gt;$new_date&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;get-date&lt;/span&gt; &lt;span class="nv"&gt;$date_part&lt;/span&gt; &lt;span class="n"&gt;-format&lt;/span&gt; &lt;span class="n"&gt;yyyy-MM-dd&lt;/span&gt;
        &lt;span class="nv"&gt;$suffix&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;-replace&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;($?)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$new_file&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$new_date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;_&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$suffix&lt;/span&gt;
            &lt;span class="s2"&gt;&amp;quot;Moving &amp;quot;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot; to &amp;quot;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$new_file&lt;/span&gt;
            &lt;span class="nv"&gt;$new_path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$to_dir&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;\&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$new_file&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Test-Path&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$new_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;-PathType&lt;/span&gt; &lt;span class="n"&gt;leaf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;&amp;quot;File already exists in destination!!!&amp;quot;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nb"&gt;move-item&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt; &lt;span class="nv"&gt;$new_path&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;&amp;quot;Error processing &amp;quot;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;&amp;quot;Skipping &amp;quot;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
</content><category term="bash"></category><category term="PowerShell"></category><category term="Scripting My Life"></category></entry><entry><title>Programmatically playing with AmiBroker watchlists</title><link href="http://www.voidynullness.net/blog/2012/03/03/generate-amibroker-watchlist-indexes-from-spreadsheet/" rel="alternate"></link><published>2012-03-03T15:00:00+11:00</published><updated>2012-03-03T15:00:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2012-03-03:/blog/2012/03/03/generate-amibroker-watchlist-indexes-from-spreadsheet/</id><summary type="html">&lt;p&gt;If you&amp;#8217;re an &lt;a class="reference external" href="http://www.amibroker.com/"&gt;AmiBroker&lt;/a&gt; user, you may have spent much time painstakingly creating and editing watchlists of stocks, with all the repetitive pointing and clicking that entails, to get them just right.  With that done, and your watchlists for each and every database now organised to perfection, you might now be wondering: &amp;#8220;How can I fuck it all up completely in the minimum amount of time?&amp;#8221;  Got Perl installed?  Well then have I got the perfect Perl script for …&lt;/p&gt;</summary><content type="html">&lt;p&gt;If you&amp;#8217;re an &lt;a class="reference external" href="http://www.amibroker.com/"&gt;AmiBroker&lt;/a&gt; user, you may have spent much time painstakingly creating and editing watchlists of stocks, with all the repetitive pointing and clicking that entails, to get them just right.  With that done, and your watchlists for each and every database now organised to perfection, you might now be wondering: &amp;#8220;How can I fuck it all up completely in the minimum amount of time?&amp;#8221;  Got Perl installed?  Well then have I got the perfect Perl script for&amp;nbsp;you!&lt;/p&gt;
&lt;p&gt;(Because nothing has the power to mess up perfectly good data like a poorly written Perl script!  Well, &lt;span class="caps"&gt;OK&lt;/span&gt;, that&amp;#8217;s not really true.  Regardless of programming language, any determinedly incompetent programmer could no doubt write a script to neatly screw up data and/or sanity with a simple command line execution.  Sadly, sometimes this even happens to the best of us.  Which is a roundabout way of saying having a backup of any data before running experimental scripts to mess with that data might be a good idea.  I should also point out what follows is intended mostly as an attempt to get my own thoughts in order, rather than being any practical use to anyone else, as I realise the potential audience of Perl-programming AmiBroker users is small to non-existent.  This is merely an idea I&amp;#8217;ve been messing&amp;nbsp;with.)&lt;/p&gt;
&lt;p&gt;My motivation for this script (and this post) is a frustration with the unnecessarily repetitive pointing-and-clicking that many &lt;span class="caps"&gt;GUI&lt;/span&gt; applications inflict on their users (namely, me).  Charting application are especially prone to this, and given their visual nature this might be somewhat unavoidable.  But it seems to me even well designed charting applications &amp;#8212; and I consider AmiBroker to be an &lt;a class="reference external" href="http://www.voidynullness.net/blog/2012/01/28/hello-amibroker/"&gt;excellent example of the genre&lt;/a&gt; &amp;#8212; have their user interface annoyances.  Or maybe I&amp;#8217;ve just been spending too much time in the command-line world of Linux lately.  Or maybe I expect things from charting applications that no one else does.  Or maybe I do things with watchlists that no one else wants to do.  But in any case, I have yet to find a charting application that provides some way to graphically maintain &amp;#8220;watchlists&amp;#8221; of stocks without making me pine for a command line&amp;nbsp;alternative.&lt;/p&gt;
&lt;p&gt;The annoyance in this case some might consider a minor one, but it annoyed me enough to make me turn to two things that I often find even more annoying &amp;#8212; Excel and&amp;nbsp;Perl.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s the thing.  Not counting databases for indices, I have 4 AmiBroker databases set up &amp;#8212; one &lt;span class="caps"&gt;ASX&lt;/span&gt; database for Australian stocks, and three &lt;span class="caps"&gt;US&lt;/span&gt; databases, one for each of the major exchanges (&lt;span class="caps"&gt;NYSE&lt;/span&gt;, &lt;span class="caps"&gt;NASDAQ&lt;/span&gt; and &lt;span class="caps"&gt;AMEX&lt;/span&gt;, though can&amp;#8217;t remember the last time I looked at an &lt;span class="caps"&gt;AMEX&lt;/span&gt; stock chart).  Since each database has its own separate sets of watchlists, that means 4 sets of watchlists to maintain.  (Note I&amp;#8217;m talking about the names and order of the watchlists for each AmiBroker database, not the individual stocks, which obviously will be different for each&amp;nbsp;exchange).&lt;/p&gt;
&lt;p&gt;In an effort to keep on top of the more mundane record keeping tasks of trading, while spending as little time as possible doing so, I have been becoming more militant with maintaining watchlists.  In some cases, I might want the same semantic watchlist across all 4 database &amp;#8212; for example, a watchlist for currently open trades, so I can quickly scroll through charts of all my current trades with minimal keystrokes/mouseclicks.  In other cases, however, I might have a watchlist that is only specific to &lt;span class="caps"&gt;ASX&lt;/span&gt;, and not to the &lt;span class="caps"&gt;US&lt;/span&gt; exchanges &amp;#8212; for example, a watchlist for Australian resource companies.  So in general, I want the AmiBroker databases for the 3 &lt;span class="caps"&gt;US&lt;/span&gt; exchanges to have &lt;em&gt;identical&lt;/em&gt; watchlists, but the &lt;span class="caps"&gt;ASX&lt;/span&gt; one to be a bit different.  Of course, I can do this manually.  By pointing and clicking.  But I am a coder.  That&amp;#8217;s not how I&amp;nbsp;roll.&lt;/p&gt;
&lt;p&gt;So I wrote a&amp;nbsp;script.&lt;/p&gt;
&lt;p&gt;Fortunately, AmiBroker uses a &lt;a class="reference external" href="http://www.amibroker.com/guide/h_watchlist.html"&gt;simple text-based watchlist format&lt;/a&gt; that lends itself to programmatic hacking.  Within each AmiBroker database directory, there will a subdirectory for &amp;#8220;watchlists&amp;#8221;.  Within this directory, there will be a file called &lt;tt class="docutils literal"&gt;index.txt&lt;/tt&gt;.  This is a simple text file, where each line is the name of a watchlist, specific to the database in question.  There can apparently be any number of watchlists.  The actual stocks that comprise each watchlist are stored in separate data files &amp;#8212; for each entry in &lt;tt class="docutils literal"&gt;index.txt&lt;/tt&gt;, there should be a corresponding text file with a &lt;tt class="docutils literal"&gt;.tls&lt;/tt&gt; extension, which is simply a list of stock codes comprising that watchlist.  But these &lt;tt class="docutils literal"&gt;tls&lt;/tt&gt; files don&amp;#8217;t concern us for&amp;nbsp;now.&lt;/p&gt;
&lt;p&gt;Of course, all this is current at the time of writing, and subject to change.  But with keen awareness of the hackiness of it all, I created a spreadsheet with the names of watchlists, arranged how I wanted them, then wrote a script to export that spreadsheet into AmiBroker watchlist index files.  This feels hacky, and will obviously break if future versions of AmiBroker handle watchlists differently, but for now it achieves its intended purpose of saving me some tedious mouse clicking.  It means when I want to add, delete, or rearrange ordering of watchlists, I can far more quickly edit the spreadsheet and run the script.  (Before backing up the AmiBroker databases first, of course!  And making sure AmiBroker isn&amp;#8217;t currently running at the time, or Bad Things Could&amp;nbsp;Happen.)&lt;/p&gt;
&lt;p&gt;For anyone who&amp;#8217;s interested, here is the&amp;nbsp;script:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="ch"&gt;#!/usr/bin/perl&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="n"&gt;strict&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="n"&gt;warnings&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;Spreadsheet::&lt;/span&gt;&lt;span class="n"&gt;ParseExcel&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Check and extract command line arguments -- or setup OS-specific defaults.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$g_infile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;AmibrokerWatchlists.xls&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$g_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;watchlistdb&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$#ARGV&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$g_infile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$ARGV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nv"&gt;$g_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$ARGV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;die&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Usage: $0 &amp;lt;infile.xls&amp;gt; &amp;lt;outdir&amp;gt;\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Column 0 is index number of watchlist.&lt;/span&gt;
&lt;span class="c1"&gt;# Column 2 is ASX&lt;/span&gt;
&lt;span class="c1"&gt;#        3 is NYSE&lt;/span&gt;
&lt;span class="c1"&gt;#        4 is NASDAQ&lt;/span&gt;
&lt;span class="c1"&gt;#        5 is AMEX&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;

&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Indexes of columns in spreadsheet, and corresponding exchange names.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$CI_INDEX&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$CI_ASX&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$CI_NYSE&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$CI_NASDAQ&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$CI_AMEX&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;%exchange&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$exchange&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;ASX&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$CI_ASX&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$exchange&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;NYSE&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$CI_NYSE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$exchange&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;NASDAQ&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$CI_NASDAQ&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$exchange&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;AMEX&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$CI_AMEX&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;%watchlist&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="nv"&gt;$g_dir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$g_dir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt;  &lt;span class="nb"&gt;die&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Can&amp;#39;t create $g_dir directory: $!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$parser&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Spreadsheet::&lt;/span&gt;&lt;span class="n"&gt;ParseExcel&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$workbook&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$parser&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$g_infile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;defined&lt;/span&gt; &lt;span class="nv"&gt;$workbook&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;die&lt;/span&gt; &lt;span class="nv"&gt;$parser&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;.\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Extract data from spreadsheet.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$sheet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$workbook&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;worksheet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$cell&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$wname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$windex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$row_min&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$row_max&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$sheet&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;row_range&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$col_min&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$col_max&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$sheet&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;col_range&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$row_min&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nv"&gt;$row_max&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;die&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Invalid input file: not enough rows!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$row&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$row_min&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;..&lt;/span&gt; &lt;span class="nv"&gt;$row_max&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;#&lt;/span&gt;
    &lt;span class="c1"&gt;# Get value of first column.&lt;/span&gt;
    &lt;span class="c1"&gt;#&lt;/span&gt;
    &lt;span class="nv"&gt;$cell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$sheet&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;get_cell&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$CI_INDEX&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;next&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;defined&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$cell&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;# Skip row if the first column is blank&lt;/span&gt;
    &lt;span class="nv"&gt;$windex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$cell&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;$windex:\t&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;each&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;%exchange&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$cell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$sheet&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;get_cell&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;defined&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$cell&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$wname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;List$windex&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$wname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$cell&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="nv"&gt;$wname&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt; &lt;span class="sr"&gt;s/^\s+//&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nv"&gt;$wname&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt; &lt;span class="sr"&gt;s/\s+$//&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nb"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;@&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$watchlist&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt; &lt;span class="nv"&gt;$wname&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;$wname ($e)\t&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;\n=====\n\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Generate output files.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$k&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;keys&lt;/span&gt; &lt;span class="nv"&gt;%exchange&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;$g_dir/$k&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;# Delete any existing TLS files in the directory.&lt;/span&gt;
        &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;@existing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;&amp;lt;$g_dir/$k/*.tls&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$tls&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;@existing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Deleting: $tls\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nb"&gt;unlink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$tls&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;$g_dir/$k&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt;  &lt;span class="nb"&gt;die&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Can&amp;#39;t create $g_dir directory: $!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OUTPUT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;$g_dir/$k/index.txt&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;die&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Can&amp;#39;t open output file: $!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$l&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;@&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$watchlist&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$k&lt;/span&gt;&lt;span class="p"&gt;}})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;OUTPUT&lt;/span&gt; &lt;span class="nv"&gt;$l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nb"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OUTPUT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(&lt;a class="reference external" href="https://gist.github.com/robulouski/7692098"&gt;View as a gist here&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;The idea here is fairly simple.  The script generates index files for each database based on the first worksheet in the spreadsheet file.  It outputs one index file for each database (i.e. stock exchange), placing each one in a subdirectory with the database name.  It doesn&amp;#8217;t directly modify or overwrite any files in an AmiBroker database (I&amp;#8217;ve got another script for that!), nor does it attempt to even mimic the proper directory structure.  All it does is output &lt;tt class="docutils literal"&gt;index.txt&lt;/tt&gt; files which can then be (manually, and carefully!) copied to the appropriate subdirectories within the respective AmiBroker&amp;nbsp;databases.&lt;/p&gt;
&lt;p&gt;The first 5 rows of the spreadsheet are ignored, so they can contain any arbitrary header information for human&amp;nbsp;consumption.&lt;/p&gt;
&lt;p&gt;The first column (from row 6 onwards) must contain either a number, or be blank.  If it&amp;#8217;s blank, that entire row is ignored.  If it has a number, then this number represents a watchlist index number.  Column B is ignroed.  Columns C to F contain the names of watchlists for databases &lt;span class="caps"&gt;ASX&lt;/span&gt;, &lt;span class="caps"&gt;NYSE&lt;/span&gt;, &lt;span class="caps"&gt;NASDAQ&lt;/span&gt;, &lt;span class="caps"&gt;AMEX&lt;/span&gt; (in that order).  So if column A has an index number, then columns C to F in that row represent the watchlist names with that index number, for all the respective&amp;nbsp;databases.&lt;/p&gt;
&lt;p&gt;Since I like to have all the &lt;span class="caps"&gt;US&lt;/span&gt; watchlists identical, I could have made the script more specific and just had 2 columns &amp;#8212; one for &lt;span class="caps"&gt;ASX&lt;/span&gt;, and one for &lt;span class="caps"&gt;US&lt;/span&gt; databases, but I decided to implement the more general case, even if it means having to do a fill in Excel after editing &lt;span class="caps"&gt;US&lt;/span&gt;&amp;nbsp;watchlists.&lt;/p&gt;
</content><category term="AmiBroker"></category><category term="Scripting My Life"></category><category term="Trading"></category><category term="Perl"></category></entry><entry><title>Goodbye crappy overpriced overhyped charting application, hello AmiBroker</title><link href="http://www.voidynullness.net/blog/2012/01/28/hello-amibroker/" rel="alternate"></link><published>2012-01-28T16:15:00+11:00</published><updated>2012-01-28T16:15:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2012-01-28:/blog/2012/01/28/hello-amibroker/</id><summary type="html">&lt;p&gt;So I&amp;#8217;ve had this idea for a post/rant knocking around in my head for ages, but been unsure whether I should actually write it.  For one thing, it would essentially amount to a review of software I no longer use, haven&amp;#8217;t used in a long time, and have no intention of ever using again.  However, I do use one of it&amp;#8217;s competitors, which I consider a much superior piece of software, and which I will happily …&lt;/p&gt;</summary><content type="html">&lt;p&gt;So I&amp;#8217;ve had this idea for a post/rant knocking around in my head for ages, but been unsure whether I should actually write it.  For one thing, it would essentially amount to a review of software I no longer use, haven&amp;#8217;t used in a long time, and have no intention of ever using again.  However, I do use one of it&amp;#8217;s competitors, which I consider a much superior piece of software, and which I will happily continue to use.  Like all software, however, it is not perfect, and there are some things about the user interface I find a bit frustrating, though no where near as much as the former.  So just in case at some point I happen to write something that might be remotely critical of the latter, I should at least bag the shit out of the former first, especially since it is what made me appreciate the latter so much &amp;#8212; and as such provide some context for any future ramblings about trading software.  Not to mention it might be good to vent.  So here&amp;nbsp;goes.&lt;/p&gt;
&lt;p&gt;Once upon a time, years ago, I decided to dedicate an increasingly large chunk of my increasingly smaller free time to trading the stock market.  That was probably my first mistake.  So I went searching for software tools to assist me in this misguided quest.  Specifically, I wanted a charting program.  Being a beginner trader, my needs were fairly modest, but I thought I had a good idea of what I wanted &amp;#8212; just the common technical analysis indicators, and ability to search a stock price database based on common technical criteria.  My research led me to one piece of software which seemed popular and well regarded &amp;#8212; something which now, having used the software in question, I find completely mystifying.  I won&amp;#8217;t mention the name of this charting application, because it is an abomination against all that is good and holy in user interface design and software quality.  Let&amp;#8217;s call it the &amp;#8220;Charting Application That For Usability Crappiness The Name Of Which Is Not To Henceforth Ever Be Uttered or Mentioned&amp;#8221;, or &lt;span class="caps"&gt;CATFUCTNOWINTHEBUM&lt;/span&gt; for short.  &lt;span class="caps"&gt;OK&lt;/span&gt;, that&amp;#8217;s not very short.  It&amp;#8217;s actually twice as many letters as the real name of the software.  So how about we just call it the Charting Application That Possesses Pathetically Poor Usability (&lt;span class="caps"&gt;CATPPPU&lt;/span&gt;), and just agree never to mention its&amp;nbsp;name?&lt;/p&gt;
&lt;p&gt;Well, &lt;span class="caps"&gt;OK&lt;/span&gt;, to be fair (kind of), if all you want to do is look at the occasional chart, &lt;span class="caps"&gt;CATPPPU&lt;/span&gt; does the job.  (Though with the current state of computer hardware/software, drawing a 2 dimensional chart of stock prices is hardly a taxing task.)  Where the software really fell down is with the more advanced functionality around its charting core &amp;#8212; like searching through stock price data, and manipulating and maintaining lists of&amp;nbsp;stocks.&lt;/p&gt;
&lt;p&gt;The user interface was like something out of a bad 90&amp;#8217;s shareware application.  It was full of small, cramped, non-resizable dialog boxes &amp;#8212; one of my personal pet-peeves of user-interface design.  What&amp;#8217;s worse, these undersized dialogs were either crammed with controls, or were filled with one or more table widgets full of data, which, once populated, necessitated constant scrolling of sliders to see the data.  I felt this was just inexcusable for a mature software application like this, since one of its main features &amp;#8212; and reason for existing &amp;#8212; is allowing users to generate and work with that data easily!  And the ultimate frustration of not having resizable dialog boxes in an interface of a charting application for traders, is that if any class of computer user (apart from developers) are likely to have large screens and even multiple monitors, it&amp;#8217;s traders!  Nowadays large &lt;span class="caps"&gt;LCD&lt;/span&gt; screens and multiple monitor setups are relatively common for desktops machines, but hardcore traders have been using multiple flat screens way back when most people were still stuck with a single bulky &lt;span class="caps"&gt;CRT&lt;/span&gt;.  So I would regard it as quite a serious deficiency in a piece of software supposedly aimed at serious traders, to cram all its advanced functionality into small, cramped dialogs that can&amp;#8217;t be resized to take advantage of the larger screen(s) the target end user is likely to&amp;nbsp;have!&lt;/p&gt;
&lt;p&gt;Then there&amp;#8217;s the functionality for creating and managing &amp;#8220;watchlists&amp;#8221;, such as it was.  It seemed this part of the user interface was modelled loosely on early versions of Internet Explorer&amp;#8217;s &amp;#8220;Favourites&amp;#8221; feature.  Modelling &lt;em&gt;anything&lt;/em&gt; on Internet Explorer features is rarely a good&amp;nbsp;idea.&lt;/p&gt;
&lt;p&gt;The whole &amp;#8220;watchlist&amp;#8221; thing was actually my main reason for buying an overpriced charting application in the first place.  The workflow I wanted to achieve is to to create a list of stocks, usually by a search based on technical analysis criteria (e.g. moving averages, etc), then quickly scroll through the resulting list, having a quick look at each one, and discarding those I didn&amp;#8217;t like the look of.  The remaining stocks on that list would then be worthy of deeper analysis.  I didn&amp;#8217;t think that was too much to ask of a modern charting application.  But if there was a way to easily achieve this workflow, I couldn&amp;#8217;t work it out, despite going through the manual and googling.  I had to resort to copying results of searches into Excel, then flicking back and forth between the two applications to get anything even close to the workflow I&amp;nbsp;wanted.&lt;/p&gt;
&lt;p&gt;Even worse, the minimal watchlist functionality this software did have was poorly implemented, buggy and slow as all fuck.  The program would frequently crash while I was trying to manipulate watchlists.  And even when it didn&amp;#8217;t, deleting one or more stocks from a list would make it freeze up and furiously thrash the hard drive for minutes at a time.  To delete one item from a list!  On a modern &lt;span class="caps"&gt;PC&lt;/span&gt;!  Seriously!  We&amp;#8217;re not talking about huge data structures here &amp;#8212; just lists of stock codes, or some kind of references to data files on a local hard drive.  What kind of convoluted internal data structure were these watchlists using that it took up to 10 minutes of thrashing the hard drive to delete one tiny item of data from a list?  What could it possibly be doing for so long?  As a developer, that indicates the watchlist functionality was phenomenally poorly implemented.  What happened?  Did they get the work experience kid to work on that part of the program?  Without supervision?  This kind of thing is seriously amateur hour &amp;#8212; and I paid a thousand bucks for this&amp;nbsp;shit!&lt;/p&gt;
&lt;p&gt;I persevered for a while, but then it came time to get a new &lt;span class="caps"&gt;PC&lt;/span&gt;, with a newer version of Windows &amp;#8212; Vista.  Not surprisingly, the version of &lt;span class="caps"&gt;CATPPPU&lt;/span&gt; I was using was not compatible with Vista, and there was no fucking way I was going to spend more money to upgrade this shitty software.  So I went looking for alternatives.  I ended up switching to &lt;a class="reference external" href="http://www.amibroker.com/"&gt;AmiBroker&lt;/a&gt;, which turned out to be better in just about every way.  Not only that, it was cheaper, and worked across any version of Windows I cared&amp;nbsp;about.&lt;/p&gt;
&lt;p&gt;Now, I don&amp;#8217;t really like getting all philosophical about software development.  The people who do wax lyrical about software/websites/apps as &amp;#8220;art&amp;#8221; are usually either trying to bullshit their way into getting venture capital funding, or a venture capital douchebag trying to justify why he just invested millions of dollars in a company that isn&amp;#8217;t making any money and will likely never ever make any money.  Or just Apple&amp;nbsp;fanboys.&lt;/p&gt;
&lt;p&gt;But there is undeniably an aspect of art involved, both in the process of coding, but also in the more visible area of user-interface design.  When watching a good movie or experiencing a great band perform, it is often obvious from the start that the people involved really know what they&amp;#8217;re doing, they&amp;#8217;re on top of their game, that they have crafted their art with skill and attention to detail.  In the same way, it can be obvious when a piece of software has been well crafted by people who put some thought and attention into how it should work, as opposed to just a bunch of careless cubicle monkeys phoning it in.  That is the difference between AmiBroker and &lt;span class="caps"&gt;CATPPPU&lt;/span&gt;.  AmiBroker and &lt;span class="caps"&gt;CATPPPU&lt;/span&gt; are both applications that set out to fill a particular need and provide a specific set of functionality.  Yet, while &lt;span class="caps"&gt;CATPPPU&lt;/span&gt; does kind of get the job done, it does it clumsily &amp;#8212; it&amp;#8217;s basically a great example of lazy software, as the user inferface it provides is about as basic and minimal as possible, and certainly without style.  They obviously threw a bunch of features in there, while doing as little work possible to expose those features to the end user.  They certainly didn&amp;#8217;t think about the user experience in using those features.  AmiBroker, by contrast, is an example of the same basic idea done right.  It&amp;#8217;s not perfect, but it gets the job done with a clean, modern user&amp;nbsp;interface.&lt;/p&gt;
&lt;p&gt;I actually found myself at an &amp;#8220;educational&amp;#8221; trading seminar last year &amp;#8212; where &amp;#8220;educational&amp;#8221; in this context means &amp;#8220;shameless promotion of trading products and services but with a few authors of second rate trading books throwing up some charts every now and then to provide a thin veneer of credibility, before shamelessly spruiking their own second rate books&amp;#8221;.  At one point some guy from the company currently distributing &lt;span class="caps"&gt;CATPPPU&lt;/span&gt; in Australia got up and bullshitted about what a great product it is, while I sat down the back and tried to refrain from laughing hysterically.  He hooked his laptop to the projector to provide a demonstration.  I&amp;#8217;d completely given up on &lt;span class="caps"&gt;CATPPPU&lt;/span&gt; by this stage, and had long since switched to AmiBroker.  Watching him work &lt;span class="caps"&gt;CATPPPU&lt;/span&gt; on the projector I felt even more justified in my decision, as it reminded me of some other user interface failings of the software that by then I had&amp;nbsp;forgotten.&lt;/p&gt;
&lt;p&gt;He demonstrated how to run scans on the database, but to do so involves selecting which stocks (or subset of stocks) to search through.  This is done though fairly standard windows open/browse dialog boxes (non-resizable, if I remember right?).  But I don&amp;#8217;t think there&amp;#8217;s any way to select a directory (and it&amp;#8217;s entire contents).  You have to go into every directory, press &lt;span class="caps"&gt;CTRL&lt;/span&gt;-A to select every data file in it, wait while the software freezes up for a bit if there are lots of files in the directory (which there usually will be), click open, then repeat the process for each directory (of which there will be around 26 if you happen to have the data files sorted in A-Z directories, a default of many data suppliers because the proprietry file format it uses has an arbitrary limit of 2000 data files per directory!).  And you have to do this every fucking time you want to run a scan &amp;#8212; unless you manage to painstakingly, and with much hard drive thrashing, create a watchlist without the software crashing on you.  Not surprisingly he glossed over this point during the&amp;nbsp;demonstration.&lt;/p&gt;
&lt;p&gt;The real kicker for me, however, was when, in an attempt a levity, he pointed out the most common support call they get from customers is right after they install and run the software for the first time.  And it&amp;#8217;s always the same&amp;nbsp;question:&lt;/p&gt;
&lt;p&gt;&lt;span class="dquo"&gt;&amp;#8220;&lt;/span&gt;What do I do&amp;nbsp;now?&amp;#8221;&lt;/p&gt;
&lt;p&gt;Because the software starts up with essentially a blank window with only a menu bar at the top.  Nothing to indicate how to open a chart, or where to load data from.  He then went to great lengths to reassure everyone that their support department is ready and waiting for their calls, and will be all to happy to help out if anyone encounters problem during or after installation.  This for me was more proof of how hopelessly broken this software was from an user experience point of view.  He shouldn&amp;#8217;t have had to make that assurance, and ideally the software should do more to guide users what to do when first&amp;nbsp;run.&lt;/p&gt;
&lt;p&gt;Another telling example of the difference between the art of making quality software with care for the end user experience and attention to detail, and software just hacked together for the money.  Don&amp;#8217;t get me wrong, &lt;span class="caps"&gt;CATPPPU&lt;/span&gt; does what it claims to do, but in my subjective opinion, it doesn&amp;#8217;t do it at all well.  I think just about everything in its user interface could have been implemented better.  AmiBroker is proof of&amp;nbsp;that.&lt;/p&gt;
</content><category term="AmiBroker"></category></entry><entry><title>Goodbye Unity, hello once again KDE</title><link href="http://www.voidynullness.net/blog/2011/12/06/goodbye-unity-hello-once-again-kde/" rel="alternate"></link><published>2011-12-06T19:23:00+11:00</published><updated>2011-12-06T19:23:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2011-12-06:/blog/2011/12/06/goodbye-unity-hello-once-again-kde/</id><summary type="html">&lt;p&gt;Goodbye Unity.  I gave you a go, I really did.  You are a bold move in the world of Linux, which is good to see.  But you&amp;#8217;re just not working for me.  You&amp;#8217;re &lt;span class="caps"&gt;OK&lt;/span&gt;, and no where near as bad as some have made you out to be, but as a development machine desktop, I find you&amp;#8217;re less than ideal.  So I&amp;#8217;m going back to &lt;span class="caps"&gt;KDE&lt;/span&gt;.  Which is not to say that &lt;span class="caps"&gt;KDE&lt;/span&gt; is perfect, just …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Goodbye Unity.  I gave you a go, I really did.  You are a bold move in the world of Linux, which is good to see.  But you&amp;#8217;re just not working for me.  You&amp;#8217;re &lt;span class="caps"&gt;OK&lt;/span&gt;, and no where near as bad as some have made you out to be, but as a development machine desktop, I find you&amp;#8217;re less than ideal.  So I&amp;#8217;m going back to &lt;span class="caps"&gt;KDE&lt;/span&gt;.  Which is not to say that &lt;span class="caps"&gt;KDE&lt;/span&gt; is perfect, just the lesser of desktop environment evils.  And I do appreciate how integrated and polished you are in a lot of ways Unity, especially visually.  This is in contrast to the &lt;span class="caps"&gt;GTK&lt;/span&gt; based applications like Firefox and Thunderbird on &lt;span class="caps"&gt;KDE&lt;/span&gt;, which end up &lt;a class="reference external" href="http://cristalinux.blogspot.com/2011/10/make-kde-feel-like-home-for-firefox.html"&gt;looking annoyingly out of place and ugly&lt;/a&gt;.  But &lt;a class="reference external" href="http://oxygenkde.altervista.org/index.html"&gt;unless I find workarounds&lt;/a&gt;, I will put up with the ugliness, because since I spend most of my time doing fairly low level back end coding, I care little for fancy GUIs and desktop environments, and would just prefer they stay out of my way as much as possible.  But goddamit Firefox you are looking hideous on &lt;span class="caps"&gt;KDE&lt;/span&gt; compared to&amp;nbsp;Unity&amp;#8230;&lt;/p&gt;
&lt;p&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt;:  Installing &lt;span class="caps"&gt;KDE&lt;/span&gt; on top of Ubuntu (though the package manager), as opposed to Kubuntu, might have contributed to the above ugliness.  I&amp;#8217;m not sure if recent Kubuntu distributions have the same quirk, but I notice Firefox looks fine on a home &lt;span class="caps"&gt;PC&lt;/span&gt; currently running Mint 13 &lt;span class="caps"&gt;KDE&lt;/span&gt;.&lt;/p&gt;
</content><category term="KDE"></category><category term="Linux"></category></entry><entry><title>Enable Apache userdir</title><link href="http://www.voidynullness.net/blog/2011/11/07/enable-apache-userdir/" rel="alternate"></link><published>2011-11-07T20:37:00+11:00</published><updated>2011-11-07T20:37:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2011-11-07:/blog/2011/11/07/enable-apache-userdir/</id><summary type="html">&lt;p&gt;If I&amp;#8217;m using a Linux box as a development machine, I usually like to have
Apache installed with userdir enabled, even if I&amp;#8217;m not necessarily doing
web-development, just in case I need to play with something&amp;nbsp;webby/internety.&lt;/p&gt;
&lt;p&gt;Enabling the userdir module on Unbuntu and its derivatives is usually
something&amp;nbsp;like:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo a2enmod userdir
&lt;/pre&gt;
&lt;p&gt;If required, further tweaking of userdir configuration can be done by&amp;nbsp;editing:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
/etc/apache2/mods-enabled/userdir.conf
&lt;/pre&gt;
&lt;p&gt;Then restart&amp;nbsp;apache:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo /etc/init.d …&lt;/pre&gt;</summary><content type="html">&lt;p&gt;If I&amp;#8217;m using a Linux box as a development machine, I usually like to have
Apache installed with userdir enabled, even if I&amp;#8217;m not necessarily doing
web-development, just in case I need to play with something&amp;nbsp;webby/internety.&lt;/p&gt;
&lt;p&gt;Enabling the userdir module on Unbuntu and its derivatives is usually
something&amp;nbsp;like:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo a2enmod userdir
&lt;/pre&gt;
&lt;p&gt;If required, further tweaking of userdir configuration can be done by&amp;nbsp;editing:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
/etc/apache2/mods-enabled/userdir.conf
&lt;/pre&gt;
&lt;p&gt;Then restart&amp;nbsp;apache:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
sudo /etc/init.d/apache2 restart
&lt;/pre&gt;
&lt;p&gt;After this, all manner of &lt;span class="caps"&gt;HTML&lt;/span&gt;-based experiments can be installed or
inclubated in the relative safety and convenience of a user&amp;#8217;s home
directory at &lt;tt class="docutils literal"&gt;~/public_html/&lt;/tt&gt;, which should be accessible on
&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;http://localhost/~username/&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Just make sure all subdirectories in path to public_html have read and
execute&amp;nbsp;permissions.&lt;/p&gt;
</content><category term="Apache"></category><category term="Unix"></category><category term="Linux"></category><category term="Things To Do After Installing Linux"></category></entry><entry><title>Make Firefox open new tabs at far right</title><link href="http://www.voidynullness.net/blog/2011/11/03/make-firefox-open-new-tabs-at-far-right/" rel="alternate"></link><published>2011-11-03T19:43:00+11:00</published><updated>2011-11-03T19:43:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2011-11-03:/blog/2011/11/03/make-firefox-open-new-tabs-at-far-right/</id><summary type="html">&lt;p&gt;Looks like I&amp;#8217;m gonna have to do this every time I do a fresh Linux install
&amp;#8212; configure Firefox to open links in new tabs with the new tab positioned
at the far right.  The way I like&amp;nbsp;it.&lt;/p&gt;
&lt;p&gt;Type the following into the address&amp;nbsp;bar:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
about:config
&lt;/pre&gt;
&lt;p&gt;If a warning shows up, promise to be&amp;nbsp;careful.&lt;/p&gt;
&lt;p&gt;The option that needs to be configued&amp;nbsp;is:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
browser.tabs.insertRelatedAfterCurrent
&lt;/pre&gt;
&lt;p&gt;Easiest way to find it is enter it into the search box …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Looks like I&amp;#8217;m gonna have to do this every time I do a fresh Linux install
&amp;#8212; configure Firefox to open links in new tabs with the new tab positioned
at the far right.  The way I like&amp;nbsp;it.&lt;/p&gt;
&lt;p&gt;Type the following into the address&amp;nbsp;bar:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
about:config
&lt;/pre&gt;
&lt;p&gt;If a warning shows up, promise to be&amp;nbsp;careful.&lt;/p&gt;
&lt;p&gt;The option that needs to be configued&amp;nbsp;is:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
browser.tabs.insertRelatedAfterCurrent
&lt;/pre&gt;
&lt;p&gt;Easiest way to find it is enter it into the search box.  Set it to&amp;nbsp;&amp;#8220;False&amp;#8221;.&lt;/p&gt;
&lt;p&gt;Now tabs will open where I expect them to&amp;nbsp;open.&lt;/p&gt;
</content><category term="Firefox"></category><category term="Things To Do After Installing Linux"></category></entry><entry><title>Batch rename of filenames to lowercase</title><link href="http://www.voidynullness.net/blog/2011/10/10/batch-rename-of-filenames-to-lowercase/" rel="alternate"></link><published>2011-10-10T18:59:00+11:00</published><updated>2011-10-10T18:59:00+11:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2011-10-10:/blog/2011/10/10/batch-rename-of-filenames-to-lowercase/</id><summary type="html">&lt;p&gt;I must have done something terrible in a past life, for as part of my day job I have to maintain software written in Visual Basic.  Version 6.  Yes, version 6.  And it&amp;#8217;s 2011.  I&amp;#8217;ve checked my watch.&amp;nbsp;Twice.&lt;/p&gt;
&lt;p&gt;The Visual Basic abomonation is only a small part of a much larger Unix-based client-server system &amp;#8212; the &lt;span class="caps"&gt;VB&lt;/span&gt; applications are the &lt;span class="caps"&gt;GUI&lt;/span&gt; front end.  It&amp;#8217;s interesting that even when doing Windows development, remarkably often I find the need …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I must have done something terrible in a past life, for as part of my day job I have to maintain software written in Visual Basic.  Version 6.  Yes, version 6.  And it&amp;#8217;s 2011.  I&amp;#8217;ve checked my watch.&amp;nbsp;Twice.&lt;/p&gt;
&lt;p&gt;The Visual Basic abomonation is only a small part of a much larger Unix-based client-server system &amp;#8212; the &lt;span class="caps"&gt;VB&lt;/span&gt; applications are the &lt;span class="caps"&gt;GUI&lt;/span&gt; front end.  It&amp;#8217;s interesting that even when doing Windows development, remarkably often I find the need to do something that would be easily accomplished on a Unix box, but is innordinately difficult to do on a Windows machine.  Even as a (power) user, I&amp;#8217;m increasingly finding I&amp;#8217;m more productive, not to mention less annoyed, with the user experience on my Linux box at work, compared to my Windows 7 machine at home.  (Although both Linux and Windows &lt;span class="caps"&gt;GUI&lt;/span&gt; environments have things that annoy&amp;nbsp;me.)&lt;/p&gt;
&lt;p&gt;In fact, pretty much the only compelling argument I&amp;#8217;ve heard to justify the relative expense of purchasing a Mac is that underneath the eye-candy and consumer friendly front-end of &lt;span class="caps"&gt;OS&lt;/span&gt; X, there lies the power of Unix, for those that might want or need it.  Although to be fair, PowerShell does go some way towards solving simple cases of where one might need some command-line goodness.  But that would mean having to learn&amp;nbsp;PowerShell.&lt;/p&gt;
&lt;p&gt;And so once again I find myself in a situation where Windows unnecessarily gets in my way, but thankfully I have access to a Unix system, which allows me to easily fix the problem at hand relatively easy.  In this case, the problem is that one of the many, many, many annoyances I am faced with is Visual Basic&amp;#8217;s tendency to change the case of filenames that are part of the project.  This is not normally an issue in the case-insensitive world of Windows.  But these pieces of Visual Basic detritus are parts of a mainly Unix system, so therefore it is on the Unix side of things where the source code version control is handled, and where what should be a simple act of committing code changes inevitably become a 3 act tragedy, often involving much time working with Emacs ediff&amp;nbsp;mode.&lt;/p&gt;
&lt;p&gt;Fortunately, doing batch renames on Unix/Linux is fairly straightforward thanks to the rename command.  So to ensure all files in the current directory with a &amp;#8220;.frm&amp;#8221; extension have all lowercase&amp;nbsp;filenames:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;      rename &amp;#39;y/A-Z/a-z/&amp;#39; *.frm
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Easily fixed on just about any Unix/Linux system, thank you Larry Wall.  Try doing that on any out-of-the-box Windows installation &amp;#8212; without the tedium of endless pointing and clicking.  Or learning&amp;nbsp;PowerShell.&lt;/p&gt;</content><category term="Unix"></category><category term="VisualBasic"></category></entry><entry><title>Cold And Grumpy: Why hast thou failed me my modern mod cons?</title><link href="http://www.voidynullness.net/blog/2011/09/04/central-heating-tv-reception-interference/" rel="alternate"></link><published>2011-09-04T16:43:00+10:00</published><updated>2011-09-04T16:43:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2011-09-04:/blog/2011/09/04/central-heating-tv-reception-interference/</id><summary type="html">&lt;p&gt;It seems to happen in threes.  All of a sudden my digital &lt;span class="caps"&gt;TV&lt;/span&gt; reception has gone to hell.  Being without &lt;span class="caps"&gt;TV&lt;/span&gt; I might consider a minor annoyance, in a world of online streaming of &lt;span class="caps"&gt;TV&lt;/span&gt; shows (and *cough* BitTorrent *cough*).  But my &lt;span class="caps"&gt;ADSL&lt;/span&gt; is constantly dropping out too.  And my central heating just broke down.  So I am without both &lt;span class="caps"&gt;TV&lt;/span&gt; and internet.  And I&amp;#8217;m cold.  Needless to say I&amp;#8217;m fucking&amp;nbsp;grumpy.&lt;/p&gt;
&lt;p&gt;The &lt;span class="caps"&gt;ADSL&lt;/span&gt; I&amp;#8217;ve been having …&lt;/p&gt;</summary><content type="html">&lt;p&gt;It seems to happen in threes.  All of a sudden my digital &lt;span class="caps"&gt;TV&lt;/span&gt; reception has gone to hell.  Being without &lt;span class="caps"&gt;TV&lt;/span&gt; I might consider a minor annoyance, in a world of online streaming of &lt;span class="caps"&gt;TV&lt;/span&gt; shows (and *cough* BitTorrent *cough*).  But my &lt;span class="caps"&gt;ADSL&lt;/span&gt; is constantly dropping out too.  And my central heating just broke down.  So I am without both &lt;span class="caps"&gt;TV&lt;/span&gt; and internet.  And I&amp;#8217;m cold.  Needless to say I&amp;#8217;m fucking&amp;nbsp;grumpy.&lt;/p&gt;
&lt;p&gt;The &lt;span class="caps"&gt;ADSL&lt;/span&gt; I&amp;#8217;ve been having problems with on and off for a very long time.  It&amp;#8217;s no doubt a result of Telstra&amp;#8217;s crappy copper infrastructure.  The central heating unit is old, and has been breaking down with remarkable regularity every year.  The &lt;span class="caps"&gt;TV&lt;/span&gt; reception problem, however, is new.  I have not had a problem with this before, but all of a sudden it is so bad it&amp;#8217;s pretty much unwatchable, all channels are totally garbled.  Switching to analogue, the picture is watchable, although with interference lines moving up and down the screen and regular audio glitches.  What the fuck?  Nothing has changed in my &lt;span class="caps"&gt;TV&lt;/span&gt; setup&amp;nbsp;lately.&lt;/p&gt;
&lt;p&gt;When I switched to digital, I replaced all the antenna cables.  It seems the old ones were made from a material completely incapable of transmitting digital data reliably.  Much like Telstra&amp;#8217;s copper&amp;nbsp;network.&lt;/p&gt;
&lt;p&gt;So I have new, properly shielded cables, along with a powered splitter.  It&amp;#8217;s all been working fine for months.  Nothing has changed.  What is going&amp;nbsp;on?&lt;/p&gt;
&lt;p&gt;I checked and double checked all the cables and connections.  I moved things around.  I unplugged everything except the &lt;span class="caps"&gt;TV&lt;/span&gt;.  I disconnected the splitter and ran the &lt;span class="caps"&gt;TV&lt;/span&gt; antenna cable straight into the socket.  Nothing made a difference.  The &lt;span class="caps"&gt;TV&lt;/span&gt; was reception still stuffed.  I looked at the &lt;span class="caps"&gt;TV&lt;/span&gt; antenna outside.  As far as I could tell, everything was still connected, cables and connectors intact, nothing looked obviously&amp;nbsp;wrong.&lt;/p&gt;
&lt;p&gt;What could I do?  Call someone?  Who do I even call for &lt;span class="caps"&gt;TV&lt;/span&gt; reception problems like&amp;nbsp;this?&lt;/p&gt;
&lt;p&gt;I thought I&amp;#8217;d wait a few days and see if the problem would go away on its own.  (An eternal optimist, aren&amp;#8217;t I?)  It didn&amp;#8217;t.  The &lt;span class="caps"&gt;TV&lt;/span&gt; reception problems continued for days.  Cold days.  With no heating.  And only intermittent&amp;nbsp;internet.&lt;/p&gt;
&lt;p&gt;I was also wondering what to do about the heating.  Looks like it&amp;#8217;s time to replace the heating unit, but with the colder months behind us for the year, might wait till next year before deciding whether to replace or repair the damn thing.  But in thinking about this, it occurred to me that the &lt;span class="caps"&gt;TV&lt;/span&gt; reception went to hell on the same day the central heating stopped working.  Coincidence?  Is there such a thing as coincidence when it comes to&amp;nbsp;technology?&lt;/p&gt;
&lt;p&gt;I went outside, around the side of the house, to the central heating unit.  I opened the front panel and had a look inside the .  The unit was so old it still has a pilot light.  Apparently modern units don&amp;#8217;t have them.  Not surprisingly, the pilot light was out.  As a result, the &amp;#8220;electronic pilot relighter&amp;#8221; was sparking at regular intervals, trying to relight it, but in vain, as most likely something somewhere else had broken down, preventing the pilot light from actually&amp;nbsp;lighting.&lt;/p&gt;
&lt;p&gt;I flicked the switch to turn off the automatic pilot relighter, then went back inside and had a look at the &lt;span class="caps"&gt;TV&lt;/span&gt;.  It was back!  The pristine &lt;span class="caps"&gt;TV&lt;/span&gt; reception is back, in all its crisp digital glory.  So that is what had happened.  The central heating had broken down, causing the pilot light to go out, unable to be relighted.  But that didn&amp;#8217;t stop the automatic pilot lighter constantly generating a spark to try and relight the pilot light, and this spark must have been causing massive interference with my digital &lt;span class="caps"&gt;TV&lt;/span&gt; reception.  Turning off the automatic pilot lighter fixed the&amp;nbsp;problem.&lt;/p&gt;
&lt;p&gt;So that&amp;#8217;s one problem&amp;nbsp;resolved.&lt;/p&gt;
&lt;p&gt;Now if only I could fix my &lt;span class="caps"&gt;ADSL&lt;/span&gt; problems by simply flicking a&amp;nbsp;switch.&lt;/p&gt;
</content><category term="Ranting"></category><category term="Broadband"></category></entry><entry><title>JasperReports Font Foibles</title><link href="http://www.voidynullness.net/blog/2011/08/30/jasperreports-font-foibles/" rel="alternate"></link><published>2011-08-30T22:51:00+10:00</published><updated>2011-08-30T22:51:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2011-08-30:/blog/2011/08/30/jasperreports-font-foibles/</id><summary type="html">&lt;p&gt;One moment I&amp;#8217;m thinking JasperReports is great, it&amp;#8217;s exactly what I need,
it&amp;#8217;s making things so easy and my job/life/world is all the better for it.
The next moment I find I&amp;#8217;ve overlooked/forgotten/misunderstood some arcane
aspect of it and everything degenerates into a horrible, broken, useless
mess, and I&amp;#8217;m thinking why am I bothering with all this when it just seems
to be an exercise in endless frustration and misery?  Kind …&lt;/p&gt;</summary><content type="html">&lt;p&gt;One moment I&amp;#8217;m thinking JasperReports is great, it&amp;#8217;s exactly what I need,
it&amp;#8217;s making things so easy and my job/life/world is all the better for it.
The next moment I find I&amp;#8217;ve overlooked/forgotten/misunderstood some arcane
aspect of it and everything degenerates into a horrible, broken, useless
mess, and I&amp;#8217;m thinking why am I bothering with all this when it just seems
to be an exercise in endless frustration and misery?  Kind of like some
past relationships.  It&amp;#8217;s as if we&amp;#8217;re&amp;nbsp;dating.&lt;/p&gt;
&lt;p&gt;The latest frustration is fonts.  After much time spent creating a
particularly &amp;#8220;dense&amp;#8221; report, with lots of fields, lots of data, and much
time spent meticulously tweaking so that everything lines up and is spaced
out appropriately while still fitting in all the data and displaying
properly, I upload the final project to the production server, only to find
this particular report no longer displays properly &amp;#8212; some of the fields
are truncated.  &lt;span class="caps"&gt;WTF&lt;/span&gt;?  I checked this.  Many times.  It was all working
properly on my machine.  What&amp;#8217;s different between my machine and the
production machine?  Java and JasperReports versions are the same.  Turns
out the production machine is running RedHat Linux, while I am developing
on Ubuntu.  Looks like it&amp;#8217;s a fonts thing.  I was using Java logical fonts
for the reports.  Seems there is no guarantee even between different Linux
distributions that these fonts will map to the same (size) physical font.
And seems there are more &lt;a class="reference external" href="http://grysz.com/2010/06/01/use-custom-fonts-in-jasperreports-pdf-exporter/"&gt;hoops to&lt;/a&gt; &lt;a class="reference external" href="http://mdahlman.wordpress.com/2010/05/28/jaspersoft-v3-7-font-extensions/"&gt;jump through&lt;/a&gt; to be absolutely sure
of getting &lt;a class="reference external" href="http://jasperreports.sourceforge.net/sample.reference/fonts/index.html#fontextensions"&gt;the right font&lt;/a&gt; in a &lt;span class="caps"&gt;PDF&lt;/span&gt;&amp;nbsp;report.&lt;/p&gt;
</content><category term="JasperReports"></category><category term="Linux"></category><category term="Java"></category></entry><entry><title>Generating ssh keys</title><link href="http://www.voidynullness.net/blog/2011/08/17/generating-ssh-keys/" rel="alternate"></link><published>2011-08-17T18:57:00+10:00</published><updated>2011-08-17T18:57:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2011-08-17:/blog/2011/08/17/generating-ssh-keys/</id><summary type="html">&lt;p&gt;To set up ssh to allow logins without having to type a password, first
generate keys on the local&amp;nbsp;machine:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
ssh-keygen -t rsa
&lt;/pre&gt;
&lt;p&gt;Copy (securely) the freshly generated public key (&lt;tt class="docutils literal"&gt;id_rsa.pub&lt;/tt&gt;) to the
remote&amp;nbsp;machine.&lt;/p&gt;
&lt;p&gt;Append the contents of &lt;tt class="docutils literal"&gt;id_rsa.pub&lt;/tt&gt; to the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~/.ssh/authorized_keys&lt;/span&gt;&lt;/tt&gt; file
in the home directory on the remote&amp;nbsp;machine.&lt;/p&gt;
&lt;p&gt;Finally, if&amp;nbsp;necessary:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
chmod 600 ~/.ssh/authorized_keys
&lt;/pre&gt;
&lt;p&gt;The above procedure will also stop &lt;span class="caps"&gt;SVN&lt;/span&gt; from constantly pestering for a
password when checking out a repository …&lt;/p&gt;</summary><content type="html">&lt;p&gt;To set up ssh to allow logins without having to type a password, first
generate keys on the local&amp;nbsp;machine:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
ssh-keygen -t rsa
&lt;/pre&gt;
&lt;p&gt;Copy (securely) the freshly generated public key (&lt;tt class="docutils literal"&gt;id_rsa.pub&lt;/tt&gt;) to the
remote&amp;nbsp;machine.&lt;/p&gt;
&lt;p&gt;Append the contents of &lt;tt class="docutils literal"&gt;id_rsa.pub&lt;/tt&gt; to the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;~/.ssh/authorized_keys&lt;/span&gt;&lt;/tt&gt; file
in the home directory on the remote&amp;nbsp;machine.&lt;/p&gt;
&lt;p&gt;Finally, if&amp;nbsp;necessary:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
chmod 600 ~/.ssh/authorized_keys
&lt;/pre&gt;
&lt;p&gt;The above procedure will also stop &lt;span class="caps"&gt;SVN&lt;/span&gt; from constantly pestering for a
password when checking out a repository.  (For those of us unfortunate
enough to still be using &lt;span class="caps"&gt;SVN&lt;/span&gt;.)&lt;/p&gt;
</content><category term="ssh"></category><category term="SVN"></category><category term="Unix"></category><category term="Linux"></category><category term="Things To Do After Installing Linux"></category></entry><entry><title>Generating gSOAP stubs in C</title><link href="http://www.voidynullness.net/blog/2011/07/20/generating-gsoap-stubs-in-c/" rel="alternate"></link><published>2011-07-20T23:09:00+10:00</published><updated>2011-07-20T23:09:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2011-07-20:/blog/2011/07/20/generating-gsoap-stubs-in-c/</id><summary type="html">&lt;p&gt;I think I might have enjoying my recent foray into the weird world of web services and &lt;span class="caps"&gt;SOAP&lt;/span&gt; had it not felt so much like trying to fit a square peg in a round hole.  Reverse engineering a communication protocol that has its roots in &lt;span class="caps"&gt;RS&lt;/span&gt;-232 serial coms was bad enough.   But then to work out how to send that data over a web service interface defined by a third part&amp;#8230;while maintaining backwards compatibility&amp;#8230;in C&amp;#8230;let&amp;#8217;s …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I think I might have enjoying my recent foray into the weird world of web services and &lt;span class="caps"&gt;SOAP&lt;/span&gt; had it not felt so much like trying to fit a square peg in a round hole.  Reverse engineering a communication protocol that has its roots in &lt;span class="caps"&gt;RS&lt;/span&gt;-232 serial coms was bad enough.   But then to work out how to send that data over a web service interface defined by a third part&amp;#8230;while maintaining backwards compatibility&amp;#8230;in C&amp;#8230;let&amp;#8217;s just say it was even less fun that it&amp;nbsp;sounds.&lt;/p&gt;
&lt;p&gt;gSOAP was used to handle the &lt;span class="caps"&gt;SOAP&lt;/span&gt; stuff, and turned out to be easiest and most reliable part of the whole project&amp;#8230;relatively speaking.  Because this isn&amp;#8217;t a scenario the gSOAP documentation emphasizes (although the info is in there, sortof), here are some crib&amp;nbsp;notes.&lt;/p&gt;
&lt;p&gt;So you have some xsd and wsdl files from a third party that specify a web service interface.  And for better or worse, you want/need to work with straight C code, as opposed to&amp;nbsp;C++.&lt;/p&gt;
&lt;p&gt;Assuming wsdl and xsd files have been downloaded to a local directory,
create a &amp;#8220;&lt;tt class="docutils literal"&gt;typemap.dat&lt;/tt&gt;&amp;#8221; file in this directory and add a namespace prefix.  For example, add a line similar&amp;nbsp;to:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
thirdparty = &amp;quot;http://xml.thirdparty.com/WS&amp;quot;
&lt;/pre&gt;
&lt;p&gt;Then use &lt;tt class="docutils literal"&gt;wsdl2h&lt;/tt&gt; to create the header&amp;nbsp;file:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
wsdl2h -c WebService.wsdl
&lt;/pre&gt;
&lt;p&gt;This creates &lt;tt class="docutils literal"&gt;WebService.h&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Then generate the code stubs using &lt;tt class="docutils literal"&gt;soapcpp2&lt;/tt&gt;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
soapcpp2 -c -C -x -pfilenameprefix WebService.h
&lt;/pre&gt;
&lt;p&gt;The &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-c&lt;/span&gt;&lt;/tt&gt; options means generate C code, while using the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;-C&lt;/span&gt;&lt;/tt&gt; option generates only client side&amp;nbsp;code.&lt;/p&gt;
</content><category term="gSOAP"></category><category term="SOAP"></category><category term="Web Services"></category></entry><entry><title>Move Gnome 2 window controls to right</title><link href="http://www.voidynullness.net/blog/2011/07/14/move-gnome-2-window-controls-to-right/" rel="alternate"></link><published>2011-07-14T22:18:00+10:00</published><updated>2011-07-14T22:18:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2011-07-14:/blog/2011/07/14/move-gnome-2-window-controls-to-right/</id><summary type="html">&lt;p&gt;I&amp;#8217;ll give Unity a go one day, but for now I&amp;#8217;m persisting with Gnome 2 on my
work &lt;span class="caps"&gt;PC&lt;/span&gt;, because I have it set up with the &lt;span class="caps"&gt;GUI&lt;/span&gt; staying out of my way as much as
possible, so for now it is the path of least&amp;nbsp;annoyance.&lt;/p&gt;
&lt;p&gt;At least now that I have worked out how to fix one of Ubuntu&amp;#8217;s annoying
allusions to &lt;span class="caps"&gt;OS&lt;/span&gt; X of having Gnome position the minimize, maximize and close
buttons on …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I&amp;#8217;ll give Unity a go one day, but for now I&amp;#8217;m persisting with Gnome 2 on my
work &lt;span class="caps"&gt;PC&lt;/span&gt;, because I have it set up with the &lt;span class="caps"&gt;GUI&lt;/span&gt; staying out of my way as much as
possible, so for now it is the path of least&amp;nbsp;annoyance.&lt;/p&gt;
&lt;p&gt;At least now that I have worked out how to fix one of Ubuntu&amp;#8217;s annoying
allusions to &lt;span class="caps"&gt;OS&lt;/span&gt; X of having Gnome position the minimize, maximize and close
buttons on the left corner of window borders.  Like most people, I still
have to use Windows, and I see no need to have to mentally acclimatize to
this arbitrary difference between the 2 operating systems I regularly&amp;nbsp;use.&lt;/p&gt;
&lt;p&gt;To change the position of the window controls to the right, run the
Configuration Editor by pressing &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Alt-F2&lt;/span&gt;&lt;/tt&gt; then typing &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;gconf-editor&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Navigate&amp;nbsp;to:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
apps/metacity/general
&lt;/pre&gt;
&lt;p&gt;Find the &lt;tt class="docutils literal"&gt;button_layout&lt;/tt&gt; setting.&lt;/p&gt;
&lt;p&gt;Change the value&amp;nbsp;to:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
menu:minimize,maximize,close
&lt;/pre&gt;
</content><category term="Gnome"></category><category term="Ubuntu"></category><category term="Things To Do After Installing Linux"></category></entry><entry><title>Emacs search and replace newline shenanigans</title><link href="http://www.voidynullness.net/blog/2011/07/05/emacs-search-and-replace-newline-shenanigans/" rel="alternate"></link><published>2011-07-05T20:32:00+10:00</published><updated>2011-07-05T20:32:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2011-07-05:/blog/2011/07/05/emacs-search-and-replace-newline-shenanigans/</id><summary type="html">&lt;p&gt;I can&amp;#8217;t believe I&amp;#8217;ve never had to do this before: replace a string of one
or more characters in a buffer with a single newline.  But how to tell
Emacs the replace text is a literal newline?  The obvious escape characters
like &lt;code&gt;\n&lt;/code&gt; don&amp;#8217;t work.  After googling, turns out the answer is deceptively&amp;nbsp;simple:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;      C-q C-j
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Not exactly intuitive, but kinda sorta makes sesnse in an Emacsian way.
Weird how I&amp;#8217;ve never had to do this …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I can&amp;#8217;t believe I&amp;#8217;ve never had to do this before: replace a string of one
or more characters in a buffer with a single newline.  But how to tell
Emacs the replace text is a literal newline?  The obvious escape characters
like &lt;code&gt;\n&lt;/code&gt; don&amp;#8217;t work.  After googling, turns out the answer is deceptively&amp;nbsp;simple:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;      C-q C-j
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Not exactly intuitive, but kinda sorta makes sesnse in an Emacsian way.
Weird how I&amp;#8217;ve never had to do this before, but today I needed to do this&amp;nbsp;twice!&lt;/p&gt;</content><category term="Unix"></category><category term="Emacs"></category></entry><entry><title>First Post</title><link href="http://www.voidynullness.net/blog/2011/07/02/first-post/" rel="alternate"></link><published>2011-07-02T16:23:00+10:00</published><updated>2011-07-02T16:23:00+10:00</updated><author><name>Rob</name></author><id>tag:www.voidynullness.net,2011-07-02:/blog/2011/07/02/first-post/</id><summary type="html">&lt;p&gt;So you know how sometimes when you&amp;#8217;re coding or doing some sysadmin kinda thing to try and get the technology to do something you want it to, preferably in the way you want it to do it, and you figure it&amp;#8217;s probably something someone else has tried to do in the past and didn&amp;#8217;t know how so the question has already been asked on a forum or possibly preemptively answered in a blog post, so the answer …&lt;/p&gt;</summary><content type="html">&lt;p&gt;So you know how sometimes when you&amp;#8217;re coding or doing some sysadmin kinda thing to try and get the technology to do something you want it to, preferably in the way you want it to do it, and you figure it&amp;#8217;s probably something someone else has tried to do in the past and didn&amp;#8217;t know how so the question has already been asked on a forum or possibly preemptively answered in a blog post, so the answer could be out there somewhere on the wide web world, so you google and sure enough you find a web page or blog post or Stack Overflow question that provide exactly the information you&amp;#8217;re after.  Joy and happiness!  So you manage to get the technology to do what you want it to do in a manner more or less approximating the way you want it done.  Then 6 months later you have to do the same thing again but you have forgotten how to because it&amp;#8217;s not something you need to do all that often, so once it was done and working well enough it was out of sight and out of mind and you didn&amp;#8217;t make any notes on how you managed to get it working because you didn&amp;#8217;t think you&amp;#8217;d ever have to do anything like that ever again but that&amp;#8217;s exactly when fate and the universe at large and the Gods of Irony conspire to work their perverse mischief and lo and behold here you are again vainly trying to remember how the hell you did that thing to make it work last time, but to no avail, so you end up having to google for it all over again&amp;#8230;.then 6 months after that&amp;nbsp;you&amp;#8230;&lt;/p&gt;
&lt;p&gt;No?  That&amp;#8217;s never happened to&amp;nbsp;you?&lt;/p&gt;
&lt;p&gt;Well then, you have totally stumbled across the wrong blog.  Move along now.  Nothing for you to see&amp;nbsp;here.&lt;/p&gt;
&lt;p&gt;I figure I should write some stuff down, if for no other reason that I might want to refer it later on at some point, and do it in blog form on the off chance there might be someone out there googling hungrily for the same morsel of&amp;nbsp;information.&lt;/p&gt;
&lt;p&gt;Hence, my geek blog.  A place for my brain dumps, and random rambling, and hopefully something of some interest to someone out there on the&amp;nbsp;interweb.&lt;/p&gt;
&lt;p&gt;Hopefully with shorter sentences than this first&amp;nbsp;post.&lt;/p&gt;</content></entry></feed>