a technical notebook
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.html 94KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321
  1. <!DOCTYPE html>
  2. <html lang=en>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>workings: a technical notebook</title>
  6. <link rel=stylesheet href="workings.css" />
  7. <link rel="alternate" type="application/atom+xml" title="changes" href="//squiggle.city/~brennen/workings-book/feed.xml" />
  8. <script src="js/jquery.js" type="text/javascript"></script>
  9. </head>
  10. <body>
  11. <h1 class=bigtitle>workings</h1>
  12. <article>
  13. <h1><a name=a-technical-notebook href=#a-technical-notebook>#</a> a technical notebook</h1>
  14. <p>I&rsquo;ve been working on <a href="https://p1k3.com/userland-book/">a short book</a> on the basics of the command
  15. line. This one is something else altogether. It&rsquo;s a long-form technical
  16. logbook or journal, capturing the outlines of problems and their solutions as I
  17. encounter them. It is dry, incomplete, and sometimes wrong. It is unlikely to
  18. be useful for the general reader. I&rsquo;m compiling it because I want a record of
  19. what I learn, and I hope that writing documentation will help me do cleaner,
  20. more reproducible work. If it helps people with similar problems along the
  21. way, so much the better.</p>
  22. <p>&mdash; bpb / <a href="https://p1k3.com">p1k3</a>
  23. / <a href="https://ello.co/brennen">@brennen</a>
  24. / <a href="http://squiggle.city/~brennen/">~brennen</a></p>
  25. <h2><a name=a-technical-notebook-copying href=#a-technical-notebook-copying>#</a> copying</h2>
  26. <p><a href="http://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a></p>
  27. <div class=details>
  28. <h2 class=clicker><a name=a-technical-notebook-contents href=#a-technical-notebook-contents>#</a> contents</h2>
  29. <div class=full>
  30. <div class=contents><ol>
  31. <li><a href="#a-technical-notebook">a technical notebook</a>
  32. <ul>
  33. <li><a href="#a-technical-notebook-copying">copying</a></li>
  34. <li><a href="#a-technical-notebook-contents">contents</a></li>
  35. </ul>
  36. </li>
  37. <li><a href="#Wednesday-December-3-2014">Wednesday, December 3, 2014</a>
  38. <ul>
  39. <li><a href="#Wednesday-December-3-2014-makecitizen">makecitizen</a></li>
  40. </ul>
  41. </li>
  42. <li><a href="#Friday-December-5-2014">Friday, December 5, 2014</a>
  43. <ul>
  44. <li><a href="#Friday-December-5-2014-notes-on-vim">notes on vim</a></li>
  45. <li><a href="#Friday-December-5-2014-keybindings">keybindings</a></li>
  46. </ul>
  47. </li>
  48. <li><a href="#Sunday-December-7-2014">Sunday, December 7, 2014</a>
  49. <ul>
  50. <li><a href="#Sunday-December-7-2014-notes-directory">notes directory</a></li>
  51. </ul>
  52. </li>
  53. <li><a href="#Monday-December-8-2014">Monday, December 8, 2014</a>
  54. <ul>
  55. <li><a href="#Monday-December-8-2014-ssh">ssh</a></li>
  56. <li><a href="#Monday-December-8-2014-mosh">mosh</a></li>
  57. <li><a href="#Monday-December-8-2014-time-tracking">time tracking</a></li>
  58. <li><a href="#Monday-December-8-2014-noobs-raspbian">noobs / raspbian</a></li>
  59. <li><a href="#Monday-December-8-2014-beaglebone-black">beaglebone black</a></li>
  60. <li><a href="#Monday-December-8-2014-reading-list">reading list</a></li>
  61. </ul>
  62. </li>
  63. <li><a href="#Wednesday-December-10-2014">Wednesday, December 10, 2014</a>
  64. <ul>
  65. <li><a href="#Wednesday-December-10-2014-listusers-squiggle-city-repo">listusers / squiggle.city repo</a></li>
  66. </ul>
  67. </li>
  68. <li><a href="#Thursday-December-18-2014">Thursday, December 18, 2014</a>
  69. <ul>
  70. <li><a href="#Thursday-December-18-2014-screencast-gifs">screencast gifs</a></li>
  71. </ul>
  72. </li>
  73. <li><a href="#Friday-December-19-2014">Friday, December 19, 2014</a>
  74. <ul>
  75. <li><a href="#Friday-December-19-2014-drawing-tools">drawing tools</a></li>
  76. </ul>
  77. </li>
  78. <li><a href="#Tuesday-December-23-2014">Tuesday, December 23, 2014</a>
  79. <ul>
  80. <li><a href="#Tuesday-December-23-2014-screenshots">screenshots</a></li>
  81. </ul>
  82. </li>
  83. <li><a href="#Sunday-December-28-2014">Sunday, December 28, 2014</a>
  84. <ul>
  85. <li><a href="#Sunday-December-28-2014-candles-amp-candlemaking">candles &amp; candlemaking</a></li>
  86. </ul>
  87. </li>
  88. <li><a href="#Saturday-January-3-2015">Saturday, January 3, 2015</a>
  89. <ul>
  90. <li><a href="#Saturday-January-3-2015-ipv6">ipv6</a></li>
  91. </ul>
  92. </li>
  93. <li><a href="#Wednesday-January-7-2014">Wednesday, January 7, 2014</a>
  94. <ul>
  95. <li><a href="#Wednesday-January-7-2014-local-webservers-and-static-html-generation">local webservers and static html generation</a></li>
  96. </ul>
  97. </li>
  98. <li><a href="#Monday-January-12">Monday, January 12</a>
  99. <ul>
  100. <li><a href="#Monday-January-12-Debian-packaging">Debian packaging</a></li>
  101. <li><a href="#Monday-January-12-MS-DOS-AGT">MS-DOS / AGT</a></li>
  102. </ul>
  103. </li>
  104. <li><a href="#Tuesday-January-13">Tuesday, January 13</a>
  105. <ul>
  106. <li><a href="#Tuesday-January-13-rtd-bus-schedules-transit-data">rtd / bus schedules / transit data</a></li>
  107. </ul>
  108. </li>
  109. <li><a href="#Wednesday-January-14-2015">Wednesday, January 14, 2015</a></li>
  110. <li><a href="#Friday-January-16">Friday, January 16</a></li>
  111. <li><a href="#Tuesday-January-20">Tuesday, January 20</a></li>
  112. <li><a href="#Thursday-January-22">Thursday, January 22</a>
  113. <ul>
  114. <li><a href="#Thursday-January-22-deleting-files-from-git-history">deleting files from git history</a></li>
  115. <li><a href="#Thursday-January-22-postscript-on-finding-bugs">postscript: on finding bugs</a></li>
  116. </ul>
  117. </li>
  118. <li><a href="#Sunday-January-25-2015">Sunday, January 25, 2015</a>
  119. <ul>
  120. <li><a href="#Sunday-January-25-2015-background-colors-for-tmux">background colors for tmux</a></li>
  121. </ul>
  122. </li>
  123. <li><a href="#Tuesday-January-27">Tuesday, January 27</a>
  124. <ul>
  125. <li><a href="#Tuesday-January-27-what-version-of-what-linux-distribution-is-this">what version of what linux distribution is this?</a></li>
  126. <li><a href="#Tuesday-January-27-armhf">armhf</a></li>
  127. </ul>
  128. </li>
  129. <li><a href="#Wednesday-January-28">Wednesday, January 28</a>
  130. <ul>
  131. <li><a href="#Wednesday-January-28-on-replicating-process">on replicating process</a></li>
  132. <li><a href="#Wednesday-January-28-what-makes-programming-hard">what makes programming hard?</a></li>
  133. <li><a href="#Wednesday-January-28-debian-packaging-again">debian packaging again</a></li>
  134. <li><a href="#Wednesday-January-28-vagrant">vagrant</a></li>
  135. </ul>
  136. </li>
  137. <li><a href="#Thursday-January-29">Thursday, January 29</a>
  138. <ul>
  139. <li><a href="#Thursday-January-29-raspberry-pi-kernels">raspberry pi kernels</a></li>
  140. </ul>
  141. </li>
  142. <li><a href="#Monday-February-2">Monday, February 2</a>
  143. <ul>
  144. <li><a href="#Monday-February-2-kernel-o-matic-amp-pi-finder">kernel-o-matic &amp; pi finder</a></li>
  145. <li><a href="#Monday-February-2-raspberry-pi-2">raspberry pi 2</a></li>
  146. <li><a href="#Monday-February-2-telling-composer-to-ignore-php-version-requirements">telling composer to ignore php version requirements</a></li>
  147. </ul>
  148. </li>
  149. <li><a href="#Sunday-February-8">Sunday, February 8</a>
  150. <ul>
  151. <li><a href="#Sunday-February-8-systemd-amp-fsck">systemd &amp; fsck</a></li>
  152. </ul>
  153. </li>
  154. <li><a href="#Monday-March-2">Monday, March 2</a>
  155. <ul>
  156. <li><a href="#Monday-March-2-python">python</a></li>
  157. </ul>
  158. </li>
  159. <li><a href="#Thursday-April-9">Thursday, April 9</a>
  160. <ul>
  161. <li><a href="#Thursday-April-9-CGI-Fast-and-multi-param">CGI::Fast and multi_param()</a></li>
  162. </ul>
  163. </li>
  164. <li><a href="#Monday-April-20">Monday, April 20</a>
  165. <ul>
  166. <li><a href="#Monday-April-20-getting-recent-posts-from-pinboard-machine-readably">getting recent posts from pinboard machine-readably</a></li>
  167. </ul>
  168. </li>
  169. <li><a href="#Monday-January-18">Monday, January 18</a>
  170. <ul>
  171. <li><a href="#Monday-January-18-moved-to-p1k3-com">moved to p1k3.com</a></li>
  172. </ul>
  173. </li>
  174. <li><a href="#tools-amp-toolchains-for-data-munging-amp-analysis">tools &amp; toolchains for data munging &amp; analysis</a>
  175. <ul>
  176. <li><a href="#tools-amp-toolchains-for-data-munging-amp-analysis-csvkit">csvkit</a></li>
  177. <li><a href="#tools-amp-toolchains-for-data-munging-amp-analysis-jq">jq</a></li>
  178. </ul>
  179. </li>
  180. <li><a href="#systemd-notes">systemd notes</a></li>
  181. </ol>
  182. </div>
  183. </div>
  184. </div>
  185. </article>
  186. <article>
  187. <h1><a name=Wednesday-December-3-2014 href=#Wednesday-December-3-2014>#</a> Wednesday, December 3, 2014</h1>
  188. <h2><a name=Wednesday-December-3-2014-makecitizen href=#Wednesday-December-3-2014-makecitizen>#</a> makecitizen</h2>
  189. <p>{sysops, scripting, adduser, chfn}</p>
  190. <p>Paul Ford sent out an e-mail to the tilde.club waitlist pointing at
  191. ~pfhawkins&rsquo;s list of other tildes, so I&rsquo;m getting signup requests. There are
  192. enough that I want to write a script for adding a new squiggle.city user. I&rsquo;m
  193. not determined to be very fancy about this right now; I just want to save some
  194. keystrokes.</p>
  195. <p>The first thing I do is google &ldquo;adduser&rdquo;. <code>adduser(1)</code> is basically just a
  196. front end to <code>useradd(1)</code>. (This distinction will never stop being confusing,
  197. and should probably be a lesson to anyone considering that naming pattern.) I
  198. learn via Wikipedia that the metadata (name, room number, phone, etc.) which
  199. adduser prompts for is called the
  200. <a href="http://en.wikipedia.org/wiki/Gecos_field">GECOS field</a>, and is a relic of something
  201. called the General Electric Comprehensive Operating System, which ran on some
  202. machines at Bell Labs.</p>
  203. <p>You can change that info with <code>chfn(1)</code>.</p>
  204. <p>What my script needs to do is:</p>
  205. <ol>
  206. <li>create a user with a given <code>$USERNAME</code></li>
  207. <li>generate a random password for the user and tell me</li>
  208. <li>do <code>chage -d0 $USERNAME</code></li>
  209. <li>put a given public key in <code>~$USERNAME/.ssh/authorized_keys</code></li>
  210. </ol>
  211. <p>You can&rsquo;t log in to squiggle.city with a password, so why go to the trouble of
  212. setting a random one and forcing users to change it at their first login?
  213. Mostly because users are going to need to know a password for things like
  214. changing their shell or in the case that they get operator privileges one day.</p>
  215. <p>This is what I come up with, after a couple of even dumber iterations:</p>
  216. <pre><code>#!/bin/bash
  217. CITIZEN=$1
  218. KEYSTRING=$2
  219. # Complain and exit if we weren't given a path and a property:
  220. if [[ ! $CITIZEN || ! $KEYSTRING ]]; then
  221. echo "usage: makecitizen &lt;username&gt; &lt;key&gt;"
  222. exit 64
  223. fi
  224. # this should actually check if a _user_ exists,
  225. # not just the homedir
  226. if [ -d /home/$CITIZEN ]; then
  227. echo "$CITIZEN already exists - giving up"
  228. exit 68
  229. fi
  230. PASSWORD=`apg -d -n2`
  231. adduser --disabled-login $CITIZEN
  232. echo "$CITIZEN:$PASSWORD" | chpasswd
  233. chage -d 0 $CITIZEN
  234. echo "$KEYSTRING" &gt;&gt; /home/$CITIZEN/.ssh/authorized_keys
  235. echo "passwd: $PASSWORD"
  236. exit 0
  237. </code></pre>
  238. <p>This is used like so:</p>
  239. <pre><code>root@squiggle:~# ./makecitizen jrandomuser "ssh-rsa ..."
  240. </code></pre>
  241. <p>It&rsquo;ll still do <code>adduser</code> interactively, which is fine for my purposes.</p>
  242. <p>I think this would be improved if it took a fullname and e-mail as input,
  243. and then sent that person a message, or at least output the text of one,
  244. telling them their password.</p>
  245. <p>It&rsquo;d probably be improved even more than that if it operated in batch mode, was
  246. totally idempotent, and could be driven off some separate file or output
  247. containing the set of users.</p>
  248. <p>(Thoughts like this are how systems like Puppet and Chef are born.)</p>
  249. </article>
  250. <article>
  251. <h1><a name=Friday-December-5-2014 href=#Friday-December-5-2014>#</a> Friday, December 5, 2014</h1>
  252. <h2><a name=Friday-December-5-2014-notes-on-vim href=#Friday-December-5-2014-notes-on-vim>#</a> notes on vim</h2>
  253. <p>Vim is a text editor. My slowly-evolving configuration can be found on GitHub,
  254. in <a href="https://github.com/brennen/bpb-kit">bpb-kit</a>.</p>
  255. <p><a href="https://github.com/thcipriani/">Tyler Cipriani</a> is a lot smarter than I am about vim (and, in
  256. fact, most things), but I am particular and don&rsquo;t always share his preferences.</p>
  257. <h2><a name=Friday-December-5-2014-keybindings href=#Friday-December-5-2014-keybindings>#</a> keybindings</h2>
  258. <p>I&rsquo;m starting in on this notebook, which uses a Makefile, and think it might be
  259. nice to have a quick vim keybinding for <code>:make</code>. I would use <code>F5</code>, by analogy
  260. to QBasic, but I&rsquo;ve already bound that to <code>:wall</code>, which writes all the open
  261. buffers with changes.</p>
  262. <p>I think that maybe <code>&lt;leader&gt;m</code>, which in my case means <code>,m</code>, would be ok. Then
  263. I&rsquo;m not sure if something is already mapped starting with that, so I try <code>:map</code>.</p>
  264. <p>I want to search through the list produced by <code>:map</code>, and think it&rsquo;d be nice if
  265. I could just read it into a buffer. The first thing I google is &ldquo;vim read
  266. output of command into file&rdquo;. This could easily enough give hits for reading
  267. the output of a shell command, but the 3rd thing down the page is
  268. <a href="http://vim.wikia.com/wiki/Capture_ex_command_output">Capture ex command output</a>
  269. on the Vim Tips Wiki.</p>
  270. <p>There are a bunch of interesting ideas there, but the first basic idea is this:</p>
  271. <pre><code>:redir @a
  272. :set all
  273. :redir END
  274. </code></pre>
  275. <p>Then you can open a new buffer - <code>:new</code> - and do <code>"ap</code>. This says &ldquo;using the named
  276. register a, paste&rdquo;.</p>
  277. <p>This seems to work with <code>:set all</code>, but not so much with <code>:map</code>. Why not? I skim
  278. <code>:help map</code> and <code>help redir</code> without getting very far. Updates to come.</p>
  279. <p>With that digression still unanswered, the mapping I settled on is simple:</p>
  280. <pre><code>nmap &lt;leader&gt;m :make&lt;CR&gt;
  281. </code></pre>
  282. <p>I never know if these are going to take with me. The handful of custom
  283. bindings that have actually entered my vocabulary are super-useful, but more
  284. often than not I wind up forgetting about an idea not long after I&rsquo;ve
  285. implemented it.</p>
  286. </article>
  287. <article>
  288. <h1><a name=Sunday-December-7-2014 href=#Sunday-December-7-2014>#</a> Sunday, December 7, 2014</h1>
  289. <h2><a name=Sunday-December-7-2014-notes-directory href=#Sunday-December-7-2014-notes-directory>#</a> notes directory</h2>
  290. <p>On organizing todo lists, see <a href="https://p1k3.com/2014/8/23">the p1k3 entry from August of
  291. 2014</a>.</p>
  292. <p>For years now, I&rsquo;ve kept that sort of thing in a <code>notes.txt</code>. At some point
  293. notes.txt got its own directory with a haphazard jumble of auxiliary files. It
  294. looks like I turned that directory into a git repository a couple of years ago.</p>
  295. <p>Unlike a lot of what I keep in git, <code>~/notes/</code> isn&rsquo;t meant for any kind of
  296. publication. In fact, it&rsquo;d be pretty dumb to let it out in the world. So I got
  297. to thinking: I should really encrypt this.</p>
  298. <p>So what&rsquo;s the best way to encrypt a single directory on Linux?</p>
  299. <p>Two search strings:</p>
  300. <ul>
  301. <li>linux encrypted directory</li>
  302. <li>encrypted git repo</li>
  303. </ul>
  304. <p>It looks like maybe [<a href="http://ecryptfs.org/">http://ecryptfs.org/</a>][eCryptFS] is the thing? This machine&rsquo;s an
  305. Ubuntu, so let&rsquo;s see what we can find:</p>
  306. <pre><code>$ apt-cache search ecryptfs
  307. ecryptfs-utils - ecryptfs cryptographic filesystem (utilities)
  308. ecryptfs-utils-dbg - ecryptfs cryptographic filesystem (utilities; debug)
  309. libecryptfs-dev - ecryptfs cryptographic filesystem (development)
  310. libecryptfs0 - ecryptfs cryptographic filesystem (library)
  311. python-ecryptfs - ecryptfs cryptographic filesystem (python)
  312. zescrow-client - back up eCryptfs Encrypted Home or Encrypted Private Configuration
  313. </code></pre>
  314. <p>Google suggests that ecryptfs-utils might be what I&rsquo;m looking for.</p>
  315. <p>I become distracted reading about protests and leave this idea for another day.</p>
  316. </article>
  317. <article>
  318. <h1><a name=Monday-December-8-2014 href=#Monday-December-8-2014>#</a> Monday, December 8, 2014</h1>
  319. <h2><a name=Monday-December-8-2014-ssh href=#Monday-December-8-2014-ssh>#</a> ssh</h2>
  320. <p>I use SSH for damn near everything. We need SSH for damn near everything.</p>
  321. <p>I have this thought that SSH is quite possibly the only end-user-exposed
  322. implementation of acceptable crypto in wide use which actually satisfies the
  323. &ldquo;actual human beings can use this&rdquo; constraint at the same time as satisfying
  324. the &ldquo;this makes your shit relatively secure&rdquo; constraint. That&rsquo;s not to say
  325. it&rsquo;s easy for the average mortal to comprehend, but it beats the shit out of
  326. almost everything else I can think of.</p>
  327. <p>In &ldquo;almost everything else&rdquo;, I include SSL/TLS/HTTPS, which sort-of works as
  328. far as the general user population of browsers is concerned, much of the time,
  329. but which is an absolute nightmare to administer and which is a fundamentally
  330. broken design on a political / systems-of-control / economic /
  331. regular-admins-get-this-right level. Arguably, the only thing that has been
  332. worse for the wide adoption of crypto by normal users than SSL/TLS is PGP.</p>
  333. <p>DISCLAIMER: I DON&rsquo;T KNOW SHIT ABOUT CRYPTO. Tell me how I&rsquo;m wrong.</p>
  334. <p style="text-align:center;"> ✴</p>
  335. <ul>
  336. <li>&ldquo;<a href="http://harmful.cat-v.org/software/ssh">Sorry Theo, but SSH Sucks</a>&rdquo;</li>
  337. </ul>
  338. <h2><a name=Monday-December-8-2014-mosh href=#Monday-December-8-2014-mosh>#</a> mosh</h2>
  339. <p>I&rsquo;m not exactly sure when mosh started to catch on with people I know, but I&rsquo;d
  340. say it&rsquo;s on the order of a year or two that I&rsquo;ve been aware of it. The basic
  341. thing here is that it&rsquo;s essentially OpenSSH with better characteristics for a
  342. specific cluster of use cases:</p>
  343. <ul>
  344. <li>laggy, high-latency, intermittently-broken network connections</li>
  345. <li>client machines that frequently hop networks and/or suspend operations</li>
  346. <li>unreliable VPNs (which is to say very nearly all VPNS in actual use)</li>
  347. </ul>
  348. <h2><a name=Monday-December-8-2014-time-tracking href=#Monday-December-8-2014-time-tracking>#</a> time tracking</h2>
  349. <p>I&rsquo;m about to start in on some remote contracting stuff, so I go looking for a
  350. time tracking tool. For the moment I settle on this little tray widget called
  351. <a href="http://projecthamster.wordpress.com/">hamster</a>, which looks functional if not
  352. precisely inspiring.</p>
  353. <h2><a name=Monday-December-8-2014-noobs-raspbian href=#Monday-December-8-2014-noobs-raspbian>#</a> noobs / raspbian</h2>
  354. <p>Last year I did a bunch of work on a Raspberry Pi, but it&rsquo;s been a few months
  355. since I booted one up. I got a model B+ (more USB ports, various hardware
  356. tweaks, takes a microSD card instead of the full-size one) in my last employee
  357. order at SparkFun, and I&rsquo;m stepping through what seems to be the stock
  358. recommended installation process.</p>
  359. <ul>
  360. <li><a href="http://www.raspberrypi.org/new-raspbian-and-noobs-releases/">http://www.raspberrypi.org/new-raspbian-and-noobs-releases/</a></li>
  361. <li><a href="http://www.raspberrypi.org/downloads/">http://www.raspberrypi.org/downloads/</a></li>
  362. <li><a href="http://downloads.raspberrypi.org/NOOBS_latest.torrent">http://downloads.raspberrypi.org/NOOBS_latest.torrent</a></li>
  363. </ul>
  364. <p>I torrented <code>NOOBS_v1_3_10.zip</code>. Be careful unzipping this one - everything is at
  365. the top level of the archive (advice to distributors of basically anything: don&rsquo;t
  366. do that).</p>
  367. <p>If I&rsquo;d been smart I probably would have done:</p>
  368. <pre><code>$ mkdir noobs &amp;&amp; unzip NOOBS_v1_3_10.zip -d noobs/
  369. </code></pre>
  370. <p>The basic system here is &ldquo;get an SD card, put the stuff in this zip file on the
  371. SD card, put it in the Pi&rdquo;. Everything about this has always felt kind of
  372. weird (if not actively broken) to me, but it&rsquo;s probably important to remember
  373. that for most users &ldquo;put some files on this media&rdquo; is a lot easier than &ldquo;image
  374. this media with the filesystem contained in this file&rdquo;.</p>
  375. <p style="text-align:center;"> ✩</p>
  376. <p>So I plug in all the stuff: microSD card, keyboard, HDMI cable to random spare
  377. monitor, power.</p>
  378. <p>Nothing. Well, almost nothing. Blinkenlights, no video output. Red light is
  379. steady, green light blinks a couple of times periodically.</p>
  380. <p>I am reminded that this is, fundamentally, a terrible piece of hardware.</p>
  381. <p>Power down, remove SD card, mount SD card on Linux machine, google variously,
  382. delete and recreate FAT32 partition using gparted, re-copy NOOBS files, unmount
  383. SD card, replace card in Pi, re-apply power.</p>
  384. <p>Green LED flashes spasmodically for a bit then seems mostly off, but is actually
  385. flickering faintly on closer examination. Red light is solid.</p>
  386. <p><a href="http://elinux.org/R-Pi_Troubleshooting#Red_power_LED_is_on.2C_green_LED_does_not_flash.2C_nothing_on_display">This wiki page</a>
  387. suggests this means that no boot code has been executed at all. It&rsquo;s failing to
  388. read the card, or it&rsquo;s missing some file, or something is corrupt.</p>
  389. <p>Ok, so, mount SD card on Linux machine again; immediately discover that the
  390. card is now a volume called &ldquo;SETTINGS&rdquo;, or seems to be.</p>
  391. <pre><code>$ ls /media/brennen/SETTINGS
  392. lost+found
  393. noobs.conf
  394. $ cat /media/brennen/SETTINGS/noobs.conf
  395. [General]
  396. display_mode=0
  397. keyboard_layout=gb
  398. language=en
  399. brennen@desiderata 15:52:24 /home/brennen ★ sudo parted /dev/mmcblk0
  400. GNU Parted 2.3
  401. Using /dev/mmcblk0
  402. Welcome to GNU Parted! Type 'help' to view a list of commands.
  403. (parted) print
  404. Model: SD SL16G (sd/mmc)
  405. Disk /dev/mmcblk0: 15.9GB
  406. Sector size (logical/physical): 512B/512B
  407. Partition Table: msdos
  408. Number Start End Size Type File system Flags
  409. 1 1049kB 823MB 822MB primary fat32 lba
  410. 2 826MB 15.9GB 15.1GB extended
  411. 3 15.9GB 15.9GB 33.6MB primary ext4
  412. (parted)
  413. </code></pre>
  414. <p>Well, obviously something ran, because I definitely didn&rsquo;t arrange anything
  415. that way. And this seems a little telling:</p>
  416. <pre><code>brennen@desiderata 15:55:36 /home/brennen ★ dmesg | tail -12
  417. [51329.226687] mmc0: card aaaa removed
  418. [51776.154562] mmc0: new high speed SDHC card at address aaaa
  419. [51776.154894] mmcblk0: mmc0:aaaa SL16G 14.8 GiB
  420. [51776.169240] mmcblk0: p1 p2 &lt; &gt; p3
  421. [51781.342106] EXT4-fs (mmcblk0p3): mounted filesystem with ordered data mode. Opts: (null)
  422. [51791.757878] mmc0: card aaaa removed
  423. [51791.773880] JBD2: Error -5 detected when updating journal superblock for mmcblk0p3-8.
  424. [51793.651277] mmc0: new high speed SDHC card at address aaaa
  425. [51793.651601] mmcblk0: mmc0:aaaa SL16G 14.8 GiB
  426. [51793.666335] mmcblk0: p1 p2 &lt; &gt; p3
  427. [51799.516813] EXT4-fs (mmcblk0p3): recovery complete
  428. [51799.518183] EXT4-fs (mmcblk0p3): mounted filesystem with ordered data mode. Opts: (null)
  429. </code></pre>
  430. <p>(The &ldquo;Error -5 detected bit.)</p>
  431. <p>Ok, so I bought a new Sandisk-branded card because I didn&rsquo;t have a decently
  432. fast microSD card laying around. What I&rsquo;m going to check before I go any
  433. further is whether I got one the Pi can&rsquo;t deal with. (Or just one that&rsquo;s bunk.
  434. I bought this thing for 15 bucks at Best Buy, so who knows.)</p>
  435. <p>Here&rsquo;s an 8 gig class 4 card, branded Kingston, but I probably got it off the
  436. shelves at SparkFun some time in the last 3 years, so its actual provenance is
  437. anybody&rsquo;s guess. Looking at what&rsquo;s on here, I&rsquo;ve already used it for a
  438. Raspberry Pi of some flavor in the past. Let&rsquo;s see if it&rsquo;ll boot as-is.</p>
  439. <p>Ok, no dice. I&rsquo;m starting to suspect my problem lies elsewhere, but I&rsquo;ll try
  440. one more time on this card with NOOBS.</p>
  441. <p>Again: No dice.</p>
  442. <p>Also checked:</p>
  443. <ul>
  444. <li>the monitor with other inputs, because who knows</li>
  445. <li>tried a couple of different power supplies - USB cable from my laptop, 5V
  446. wall wart purchased from SFE, cell phone charger.</li>
  447. <li>the usual plug-things-in-one-at-a-time routine.</li>
  448. </ul>
  449. <p style="text-align:center;"> ✦</p>
  450. <p>Time to try one of these cards with an older RasPi, if I can figure out where I
  451. put any of them.</p>
  452. <p>After much shuffling through stuff on my dining room table / workbench, I find
  453. a model B. It fails in much the same way, which leads me to suspect again that
  454. I&rsquo;m doing something wrong with the card, but then I can&rsquo;t quite remember if
  455. this one still worked the last time I plugged it in. They can be fragile
  456. little critters.</p>
  457. <p>Here&rsquo;s a thought, using a Raspbian image I grabbed much earlier this year:</p>
  458. <pre><code>brennen@desiderata 17:10:03 /home/brennen/isos ★ sudo dd if=/home/brennen/isos/2014-01-07-wheezy-raspbian.img of=/dev/mmcblk0
  459. </code></pre>
  460. <p>No dice on either the model B or model B+, using the new SanDisk.</p>
  461. <p>Trying with the older card, <code>dd</code> spins through 800ish megs before giving me an I/O error.</p>
  462. <p>It may be time to start drinking.</p>
  463. <p style="text-align:center;"> ✦</p>
  464. <p>The next day: I swing through a couple of stores in town with the <a href="http://www.raspberrypi.org/forums/viewtopic.php?t=58151">wiki list
  465. of known cards in hand</a> and buy a pile
  466. of cards across a handful of brands, plus a $20 card reader (the Insignia
  467. NS-CR20A1) since there&rsquo;s not one built in to the laptop I&rsquo;m carrying today.
  468. The first card I try boots NOOBS instantly; an installer is running as I type
  469. this.</p>
  470. <p>Suddenly It occurs to me that the card reader on the laptop I was using last
  471. night might is likely dying/dead.</p>
  472. <p>This is a really slick install process now, so good work to somebody on that.</p>
  473. <h2><a name=Monday-December-8-2014-beaglebone-black href=#Monday-December-8-2014-beaglebone-black>#</a> beaglebone black</h2>
  474. <p>I&rsquo;ve got a Beaglebone Black sitting here new in the box. It comes with a USB
  475. cable, so I plug it in. Instantly there are bright blue blinky lights, and my
  476. laptop tells me I&rsquo;m connected to an ethernet network and I&rsquo;ve got a new drive
  477. mounted with some README files in it.</p>
  478. <p>This is kind of great.</p>
  479. <p>Browsing to to 192.168.7.2 gets a bunch of docs and a link to Cloud9, an
  480. in-browser IDE that happens to include a root terminal.</p>
  481. <p>I don&rsquo;t really know what&rsquo;s going on here. I think it might be a little
  482. scattered and confused as a user experience, in some ways. But it immediately
  483. strikes me as good tech in a bunch of ways.</p>
  484. <p>Josh Datko, who I&rsquo;ve gotten to know a little bit, has a book called <em>Beaglebone
  485. for Secret Agents</em>. It&rsquo;s been on my ever-growing to-read list for a while; I&rsquo;m
  486. going to have to give it a look sooner rather than later.</p>
  487. <h2><a name=Monday-December-8-2014-reading-list href=#Monday-December-8-2014-reading-list>#</a> reading list</h2>
  488. <ul>
  489. <li><a href="http://www.jann.cc/2013/01/15/trying_out_the_adafruit_webide.html">http://www.jann.cc/2013/01/15/trying_out_the_adafruit_webide.html</a></li>
  490. <li><a href="http://www.angstrom-distribution.org/">http://www.angstrom-distribution.org/</a></li>
  491. <li><a href="http://www.raspberrypi.org/documentation/configuration/config-txt.md">http://www.raspberrypi.org/documentation/configuration/config-txt.md</a></li>
  492. </ul>
  493. </article>
  494. <article>
  495. <h1><a name=Wednesday-December-10-2014 href=#Wednesday-December-10-2014>#</a> Wednesday, December 10, 2014</h1>
  496. <h2><a name=Wednesday-December-10-2014-listusers-squiggle-city-repo href=#Wednesday-December-10-2014-listusers-squiggle-city-repo>#</a> listusers / squiggle.city repo</h2>
  497. <p>There&rsquo;s now a <a href="https://github.com/squigglecity/">squigglecity organization on GitHub</a>.
  498. What little is there is a classic duct-tape mess complete with a bunch of
  499. commits made as root, but may contain a few useful bits.</p>
  500. <p>I&rsquo;m planning to clean up <a href="https://github.com/squigglecity/squiggle.city/blob/1a07ccc8415b05ad239116a062d2992ae1537541/listusers.pl">this version of listusers.pl</a> into a
  501. more generic <code>listusers</code> utility that just outputs TSV and pipe to csvkit / <code>jq</code>
  502. for HTML &amp; JSON.</p>
  503. <p>Oh, right &mdash; about the JSON. ~ford proposed a standard <code>tilde.json</code> <a href="http://squiggle.city/tilde.json">kind of
  504. like this</a>, which I think is not a terrible
  505. idea at all though that one&rsquo;s a bit rough and the format could still use a
  506. little tweaking as of this writing.</p>
  507. <p>This is the kind of thing it&rsquo;s unbelievably easy to overthink. I&rsquo;m hoping
  508. we&rsquo;ll give it enough thought to do a few smart things but not so much thought
  509. that no one actually uses it.</p>
  510. </article>
  511. <article>
  512. <h1><a name=Thursday-December-18-2014 href=#Thursday-December-18-2014>#</a> Thursday, December 18, 2014</h1>
  513. <h2><a name=Thursday-December-18-2014-screencast-gifs href=#Thursday-December-18-2014-screencast-gifs>#</a> screencast gifs</h2>
  514. <p>Looking to make some GIFs of things that happen on my screen, found <code>byzanz</code>.</p>
  515. <pre><code>$ sudo apt-get install byzanz
  516. byzanz-record -x 1 -y 1 --delay=4 -h 150 -w 700 hello_world.gif
  517. </code></pre>
  518. <p>Options:</p>
  519. <ul>
  520. <li><code>-x</code> and <code>-y</code> set origin of capture on screen</li>
  521. <li><code>-h</code> and <code>-w</code> set height and width to capture</li>
  522. </ul>
  523. <p>I think I need a more clever way to trigger / manage this than just fiddling
  524. with CLI options, but it works really well and produces lightweight image
  525. files.</p>
  526. <p>I think it would be cool if there were a utility that let me use arrow keys /
  527. hjkl / the mouse cursor to visually select a region of the screen. It could
  528. return x, y, height, and width, then I&rsquo;d let byzanz handle the capture.</p>
  529. <p>That can&rsquo;t be the <em>hardest</em> thing in the world to do.</p>
  530. <p style="text-align:center;"> ☆</p>
  531. <p><a href="http://www.semicomplete.com/projects/xdotool/">xdotool</a> seems like kind of a
  532. swiss army knife, and has a <code>getmouselocation</code> command. Theoretically, at
  533. least, you can have it respond to events, including a mouse click. I can&rsquo;t
  534. quite wrap my head around how this is supposed to work, and my first few
  535. attempts fall flat.</p>
  536. <p><a href="https://www.gnu.org/software/xnee/">GNU xnee</a> might also be promising, but I
  537. don&rsquo;t really get anywhere with it.</p>
  538. <p>Eventually I find an
  539. <a href="http://askubuntu.com/questions/107726/how-to-create-animated-gif-images-of-a-screencast">Ask Ubuntu</a>
  540. thread on creating screencast gifs, which points to
  541. <a href="https://github.com/lolilolicon/xrectsel">xrectsel</a>, a tool for
  542. returning the coordinates and size of a screen region selected with the mouse:</p>
  543. <pre><code>brennen@desiderata 22:06:28 /var/www/workings-book (master) ★ xrectsel "%x %y %w %h"
  544. 432 130 718 575%
  545. </code></pre>
  546. <p>I wind up with <a href="https://github.com/brennen/bpb-kit/blob/master/bin/gif_sel"><code>gif_sel</code></a>:</p>
  547. <pre><code>#!/usr/bin/env bash
  548. # requires:
  549. # https://github.com/lolilolicon/xrectsel.git
  550. eval `xrectsel "BYZANZ_X=%x; BYZANZ_Y=%y; BYZANZ_WIDTH=%w; BYZANZ_HEIGHT=%h"`
  551. byzanz-record -x $BYZANZ_X -y $BYZANZ_Y --delay=4 -h $BYZANZ_HEIGHT -w $BYZANZ_WIDTH ~/screenshots/screencast-`date +"%Y-%m-%d-%T"`.gif
  552. </code></pre>
  553. <p>I&rsquo;ll probably wind up with a couple of wrappers for this for different lengths
  554. of recording (for starting with dmenu), though it would be nice if I could just
  555. have it record until I press some hotkey.</p>
  556. </article>
  557. <article>
  558. <h1><a name=Friday-December-19-2014 href=#Friday-December-19-2014>#</a> Friday, December 19, 2014</h1>
  559. <p>{timetracking}</p>
  560. <p>So hamster really doesn&rsquo;t scratch my particular itch all that well. Rather
  561. than devote any serious brain energy to finding or writing a replacement that
  562. does, I&rsquo;ve decided to just use a text file.</p>
  563. <p>It looks like the following:</p>
  564. <pre><code>2014-12-17 21:55 - 2014-12-17 11:40
  565. 2014-12-18 10:05 - 2014-12-18 12:50
  566. 2014-12-18 13:45 - 2014-12-18 16:00
  567. </code></pre>
  568. <p>This is just two datetimes for each range of time when I&rsquo;m working on a given
  569. thing, delimited by <code>/ - /</code>. I just want a quick script to tally the time
  570. represented. (Later, if I need to track more than one project, I&rsquo;ll expand on
  571. this by adding a project name and/or notes to the end of the line.)</p>
  572. <p>It kind of seems like I should be able to do this with GNU <code>date</code>, but let&rsquo;s
  573. find out. Here&rsquo;re the <a href="https://www.gnu.org/software/coreutils/manual/html_node/Examples-of-date.html">official examples</a>. This sounds about
  574. right:</p>
  575. <blockquote><p>To convert a date string to the number of seconds since the epoch (which is
  576. 1970-01-01 00:00:00 UTC), use the &ndash;date option with the ‘%s’ format. That
  577. can be useful in sorting and/or graphing and/or comparing data by date. The
  578. following command outputs the number of the seconds since the epoch for the
  579. time two minutes after the epoch:</p>
  580. <pre><code> date --date='1970-01-01 00:02:00 +0000' +%s
  581. 120
  582. </code></pre></blockquote>
  583. <p>As a test case, I start here:</p>
  584. <pre><code>$ cat ~/bin/timelog
  585. #!/usr/bin/env bash
  586. date --date="$1" +%s
  587. $ timelog '2014-12-17 21:55'
  588. 1418878500
  589. </code></pre>
  590. <p>Ok, groovy.</p>
  591. <p>I was going to do the rest of this in shell or awk or something, but then I
  592. thought &ldquo;I should not spend more than 10 minutes on this&rdquo;, and wrote the following
  593. Perl:</p>
  594. <pre><code>#!/usr/bin/env perl
  595. use warnings;
  596. use strict;
  597. use 5.10.0;
  598. my $total_hours = 0;
  599. # while we've got input from a file/stdin, split it into two datestamps
  600. # and feed that to date(1)
  601. while (my $line = &lt;&gt;) {
  602. chomp($line);
  603. my ($start, $end) = map { get_seconds($_) } split / - /, $line;
  604. my $interval = $end - $start;
  605. my $hours = $interval / 3600;
  606. $total_hours += $hours;
  607. say sprintf("$line - %.3f hours", $hours);
  608. }
  609. say sprintf("%.3f total hours", $total_hours);
  610. sub get_seconds {
  611. my ($stamp) = @_;
  612. my $seconds = `date --date="$stamp" +%s`;
  613. chomp($seconds);
  614. return $seconds;
  615. }
  616. </code></pre>
  617. <p>Which gives this sort of output:</p>
  618. <pre><code>brennen@desiderata 14:54:38 /home/brennen/bin (master) ★ timelog ~/notes/some_employer.txt
  619. 2014-12-15 13:10 - 2014-12-15 14:35 - 1.417 hours
  620. 2014-12-16 10:00 - 2014-12-16 12:55 - 2.917 hours
  621. 2014-12-16 14:00 - 2014-12-16 17:15 - 3.250 hours
  622. 2014-12-17 15:00 - 2014-12-17 16:51 - 1.850 hours
  623. 2014-12-17 21:55 - 2014-12-17 23:40 - 1.750 hours
  624. 2014-12-18 10:05 - 2014-12-18 12:50 - 2.750 hours
  625. 2014-12-18 13:45 - 2014-12-18 16:00 - 2.250 hours
  626. 2014-12-18 17:00 - 2014-12-18 17:30 - 0.500 hours
  627. 16.683 total hours
  628. </code></pre>
  629. <p>This is me once again being lazy and treating Perl as a way to wrap shell
  630. utilities when I want to easily chop stuff up and do arithmetic. It is <em>many
  631. kinds of wrong</em> to do things this way, but right now I don&rsquo;t care.</p>
  632. <p>If this were going to be used by anyone but me I would do it in pure-Perl and
  633. make it robust against stupid input.</p>
  634. <h2><a name=Friday-December-19-2014-drawing-tools href=#Friday-December-19-2014-drawing-tools>#</a> drawing tools</h2>
  635. <p>Ok, so because I&rsquo;m starting to poke at drawing again for the first time in
  636. quite a while (even to the extent that I&rsquo;ll soon be publishing some stuff that
  637. includes cartoon graphics, despite having <em>no</em> idea what I&rsquo;m doing), I thought
  638. I&rsquo;d take some rough notes on where I&rsquo;m at with toolset.</p>
  639. <p>The first thing is that I&rsquo;m not using any Adobe tools, or indeed any
  640. proprietary software (unless you count the firmware on my cameras and maybe
  641. Flickr) to work with images. I am fully aware that this is a <em>ridiculous</em>
  642. limitation to self-impose, but I want to stick with it as best I can.</p>
  643. <p>For a long time, I&rsquo;ve sort of fumbled my way through GIMP whenever I needed to
  644. do the kind of light image editing stuff that inevitably comes up in the life
  645. of a web developer no matter how many things you foist off on your
  646. Photoshop-skilled, design-happy coworkers. I think GIMP gets kind of an unfair
  647. rap; it&rsquo;s a pretty capable piece of software. That said, I&rsquo;ve still never
  648. really put the time in to get genuinely skilled with it, and it&rsquo;s not the most
  649. accessible thing for just doodling around.</p>
  650. <p>Several years back, I <a href="https://p1k3.com/2011/4/13">bought a cheap Wacom tablet</a>.
  651. I was maybe a little optimistic in that writeup, but I still really enjoy
  652. <a href="http://mypaint.intilinux.com/">MyPaint</a>. The problem is that, while it&rsquo;s really
  653. fun for a sketchy/painty/extemperaneous kind of workflow, and dovetails
  654. beautifully with the tablet interface, it deliberately eschews a lot of features
  655. that you start to want for <em>editing</em> an image. I don&rsquo;t blame its developers for
  656. that &mdash; they&rsquo;re obviously trying to do a certain kind of thing, and constraints
  657. often make for great art &mdash; but I&rsquo;m wondering if I can&rsquo;t get some of the same
  658. vibe with a tool that also lets me easily cut/copy/scale stuff.</p>
  659. <p>I&rsquo;m giving <a href="https://krita.org/">Krita</a> a shot with that in mind. It has a real
  660. KDE vibe to it. Lots of modular GUI widgets, menus, etc. A little
  661. bureaucratic. It doesn&rsquo;t feel as fluid or immediate as MyPaint right out of
  662. the gate, but it&rsquo;s definitely got more in the way of features. Could grow on
  663. me.</p>
  664. </article>
  665. <article>
  666. <h1><a name=Tuesday-December-23-2014 href=#Tuesday-December-23-2014>#</a> Tuesday, December 23, 2014</h1>
  667. <h2><a name=Tuesday-December-23-2014-screenshots href=#Tuesday-December-23-2014-screenshots>#</a> screenshots</h2>
  668. <p>Looking to streamline capture of static screenshots a bit. Options:</p>
  669. <ul>
  670. <li><code>gnome-screenshot</code> - use this already, it&rsquo;s fine, whatever.</li>
  671. <li><code>shutter</code> - weirdness with my xmonad setup? Errors and I don&rsquo;t feel like taking
  672. the time to find out why.</li>
  673. <li><code>scrot</code> - buncha nice command line options</li>
  674. </ul>
  675. <p>I wind up forking Tyler&rsquo;s <a href="https://github.com/thcipriani/dotfiles/blob/master/bin/grab">grab</a>,
  676. a nice wrapper for <code>scrot</code>, which is pretty much what I was going to write anyway.</p>
  677. <p>This is pretty good at defining a region for a static screenshot.</p>
  678. </article>
  679. <article>
  680. <h1><a name=Sunday-December-28-2014 href=#Sunday-December-28-2014>#</a> Sunday, December 28, 2014</h1>
  681. <h2><a name=Sunday-December-28-2014-candles-amp-candlemaking href=#Sunday-December-28-2014-candles-amp-candlemaking>#</a> candles &amp; candlemaking</h2>
  682. <p>A year ago at Christmastime, I decided to see what kind of candlemaking
  683. supplies were still at my parents' house, and wound up digging a couple of big
  684. Rubbermaid tubs worth of molds, dyes, additives, wick, wax, &amp;c out of the
  685. basement.</p>
  686. <p>I used to do this a lot, but I&rsquo;ve mostly forgotten the details of technique.</p>
  687. <p>Rough notes:</p>
  688. <ul>
  689. <li>Wax temperature when pouring is important. I&rsquo;m aiming for 210-220 F
  690. with metal molds, but it&rsquo;s hard to get there with the little hot plate I&rsquo;m
  691. using. I can usually get it just over 200, according to the thermometer
  692. I&rsquo;ve got. This doesn&rsquo;t seem to be doing too much damage, but I do think
  693. the results would be a little better with hotter wax.</li>
  694. <li>You&rsquo;re supposed to use a proper double boiler or a purpose-built wax melter.
  695. I put various sizes of can in some water in a medium size pan.</li>
  696. <li>I remember that I used to melt wax on the woodstove in my dad&rsquo;s shop, but if
  697. so we must have been running the stove hotter in those days or I had a lot
  698. more patience. it does work well for holding wax at a reasonable
  699. temperature until you have to do a second pour.</li>
  700. <li>With metal molds, keeping the wax from streaming out the wick hole at the
  701. bottom is often kind of problematic. I think you&rsquo;re supposed to affix the
  702. wicking with a little screw and put some tacky putty-type stuff over the
  703. screw, but if you&rsquo;re low on the putty or don&rsquo;t have just the right size
  704. screw this doesn&rsquo;t work so great. Things tried this time around: The
  705. remaining putty and then everything kind of smashed down on a wood block
  706. (Ben&rsquo;s idea), pouring a little wax in the bottom and letting it harden first,
  707. the wrong size screw, silicone caulk. The wood block and the silicone caulk
  708. both worked pretty well.</li>
  709. <li>You can dye beeswax, but you have to keep in mind that the stuff is already
  710. pretty yellow and opaque. Shades of green work well. Other colors&hellip; Well,
  711. I wound up with some the color of a strange weird woodland fungus.</li>
  712. <li>Last time I did this, I wound up with a bunch of pillars that burned really
  713. poorly and with a small flame. I think I wasn&rsquo;t using a heavy enough wick.
  714. Tried to go with heavier braided wicking this time. Guess I&rsquo;ll see how that
  715. pans out.</li>
  716. </ul>
  717. </article>
  718. <article>
  719. <h1><a name=Saturday-January-3-2015 href=#Saturday-January-3-2015>#</a> Saturday, January 3, 2015</h1>
  720. <h2><a name=Saturday-January-3-2015-ipv6 href=#Saturday-January-3-2015-ipv6>#</a> ipv6</h2>
  721. <p>I was hanging out on the internet and heard that <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#105;&#109;&#116;&#64;&#112;&#114;&#111;&#116;&#111;&#99;&#111;&#108;&#46;&#99;&#108;&#117;&#98;">&#105;&#109;&#116;&#64;&#112;&#114;&#111;&#116;&#111;&#99;&#111;&#108;&#46;&#99;&#108;&#117;&#98;</a> had set up
  722. <a href="https://club6.nl">club6.nl</a>, a tildebox reachable only over ipv6. I applied
  723. for an account and <a href="https://club6.nl/~brennen">got one</a> (very speedy turnaround,
  724. <a href="https://club6.nl/~imt/">~imt</a>).</p>
  725. <p>The next problem was how to connect. I am an utter prole when it comes to
  726. networking. The first thing I remembered was that DigitalOcean optionally
  727. supports ipv6 when creating a new droplet, and sure enough they
  728. also <a href="https://www.digitalocean.com/community/tutorials/how-to-enable-ipv6-for-digitalocean-droplets">have a guide for enabling it</a> on existing droplets.</p>
  729. <p>TODO: Get my own sites resolving and reachable via ipv6.</p>
  730. </article>
  731. <article>
  732. <h1><a name=Wednesday-January-7-2014 href=#Wednesday-January-7-2014>#</a> Wednesday, January 7, 2014</h1>
  733. <h2><a name=Wednesday-January-7-2014-local-webservers-and-static-html-generation href=#Wednesday-January-7-2014-local-webservers-and-static-html-generation>#</a> local webservers and static html generation</h2>
  734. <p>I haven&rsquo;t always run an httpd on my main local machine, but I&rsquo;ve been doing it
  735. again for the last year or two now, and it feels like a major help. I started
  736. by setting up a development copy of <a href="https://github.com/brennen/display">display</a> under Apache, then noticed
  737. that it was kind of nice to use it for static files. I&rsquo;m not sure why it&rsquo;s any
  738. better than accessing them via the filesystem, except maybe that
  739. <code>localhost/foo</code> is easier to type than <code>file://home/brennen/something/foo</code>, but
  740. it has definitely made me better at checking things before I publish them.</p>
  741. <p>(Why Apache? Well, it was easier to re-derive the configuration I needed for
  742. p1k3 things under Apache than write it from scratch under nginx, although one
  743. of these days I may make the leap anyway. I don&rsquo;t see any reason Perl FastCGI
  744. shouldn&rsquo;t work under nginx. I also still think Apache has its merits, though
  745. most of my domain knowledge has evaporated over the last few years of doing
  746. mainly php-fpm under nginx.)</p>
  747. <p>I&rsquo;ve resisted the static blog engine thing for a long time now, but lately my
  748. favorite way to write things is a super-minimal <code>Makefile</code>, some files in
  749. Markdown, and a little bit of Perl wrapping <code>Text::Markdown::Discount</code>. I
  750. haven&rsquo;t yet consolidated all these tools into a single generically reusable
  751. piece of software, but it would probably be easy enough, and I&rsquo;ll probably go
  752. for it when I start a third book using this approach.</p>
  753. <p>I&rsquo;d like to be able to define something like a standard <code>book/</code> dir that would
  754. be to a given text what <code>.git/</code> is to the working copy of a repo. I suppose
  755. you wouldn&rsquo;t need much.</p>
  756. <pre><code>book/
  757. authors
  758. title
  759. description
  760. license
  761. toc
  762. </code></pre>
  763. <p><code>toc</code> would just be an ordered list of files to include as &ldquo;chapters&rdquo; from the
  764. root of the project. You&rsquo;d just organize it however you liked and optionally
  765. use commands like</p>
  766. <pre><code>book add chapter/index.md after other_chapter/index.md
  767. book move chapter/index.md before other_chapter/index.md
  768. </code></pre>
  769. <p>to manage it, though really a text editor should be enough. (Maybe I&rsquo;m
  770. overthinking this. Maybe there should just be a directory full of chapters
  771. sorted numerically on leading digits or something, but I&rsquo;ve liked being able to
  772. reorder things in an explicit list.)</p>
  773. <p>Before long I might well add handling for some</p>
  774. <p>I should add a feature to Display.pm for outputting all of its content
  775. statically.</p>
  776. </article>
  777. <article>
  778. <h1><a name=Monday-January-12 href=#Monday-January-12>#</a> Monday, January 12</h1>
  779. <h2><a name=Monday-January-12-Debian-packaging href=#Monday-January-12-Debian-packaging>#</a> Debian packaging</h2>
  780. <p>A lot of time today with
  781. the <a href="https://www.debian.org/doc/manuals/maint-guide/">Debian New Maintainer&rsquo;s Guide</a>
  782. and google for a project that needs some simple packages.</p>
  783. <p>This is one of those things where the simple cases are simple and then it&rsquo;s
  784. easy to get lost in a thicket of overlapping mechanisms and terminology.</p>
  785. <p>Thought for providers of technical HOWTOs:</p>
  786. <p>If you&rsquo;re describing the cumulative assembly of a file structure, provide a
  787. copy (repository, tarball, whatever) of that file structure.</p>
  788. <p>(I should probably take this notion to heart.)</p>
  789. <p>Things to remember:</p>
  790. <ul>
  791. <li><a href="http://man.he.net/man1/fakeroot">http://man.he.net/man1/fakeroot</a></li>
  792. </ul>
  793. <h2><a name=Monday-January-12-MS-DOS-AGT href=#Monday-January-12-MS-DOS-AGT>#</a> MS-DOS / AGT</h2>
  794. <p>So I was scrolling through archive.org&rsquo;s newly-shiny MS-DOS archive (with the
  795. crazy in-browser DOSBOX emulation), trying to think of what to look for.</p>
  796. <p>I found some old friends:</p>
  797. <ul>
  798. <li><a href="https://archive.org/details/msdos__1CRYSTL_shareware"><em>Crystal Caves</em></a></li>
  799. <li><a href="https://archive.org/details/msdos_Commander_Keen_1_-_Marooned_on_Mars_1990"><em>Commander Keen</em></a></li>
  800. <li><a href="https://archive.org/details/msdos_Heretic_-_Shadow_of_the_Serpent_Riders_1996"><em>Heretic</em></a> &mdash; still a pretty solid game and maybe my favorite iteration of the Doom Engine</li>
  801. <li><a href="https://archive.org/details/msdos_Rise_of_the_Triad_-_The_Hunt_Begins_Deluxe_Edition_1995"><em>Rise of the Triads</em></a> &mdash; there is absolutely <em>no way</em> that ROTT actually
  802. looked as bad as this emulation at the time on baseline hardware, but we&rsquo;ll let
  803. that slide &mdash; the graphics may have been better than they show here, but it
  804. was the Duke Nukem property of its moment, which is to say ultimately a
  805. regressive and not-very-consequential signpost on the way to later
  806. developments</li>
  807. </ul>
  808. <p>And then I got to thinking about the Adventure Game Toolkit, which was this
  809. sort of declarative, not-really-programmable interpreter for simple adventure
  810. games. The way I remember it, you wrote static descriptions of rooms, objects,
  811. and characters. It was a limited system, and the command interpreter was
  812. pretty terrible, but it was also a lot more approachable than things like TADS
  813. for people who didn&rsquo;t really know how to program anyway. (Like me at the time.)</p>
  814. <p>I&rsquo;d like to get AGT running on squiggle.city, just because. It turns out
  815. there&rsquo;s a <a href="http://www.ifarchive.org/indexes/if-archiveXprogrammingXagtXagility.html">portable interpreter called AGiliTY</a>, although maybe not
  816. one that&rsquo;s well packaged. I&rsquo;ll probably explore this more.</p>
  817. </article>
  818. <article>
  819. <h1><a name=Tuesday-January-13 href=#Tuesday-January-13>#</a> Tuesday, January 13</h1>
  820. <h2><a name=Tuesday-January-13-rtd-bus-schedules-transit-data href=#Tuesday-January-13-rtd-bus-schedules-transit-data>#</a> rtd / bus schedules / transit data</h2>
  821. <p>I&rsquo;m taking the bus today, so I got to thinking about bus schedules. I use
  822. Google Calendar a little bit (out of habit and convenience more than any
  823. particular love), and I was thinking &ldquo;why doesn&rsquo;t my calendar just know the
  824. times of transit routes I use?&rdquo;</p>
  825. <p>I thought maybe there&rsquo;d be, say, iCal (CalDAV? What is actually the thing?)
  826. data somewhere for a given RTD schedule, or failing that, maybe JSON or TSV or
  827. something. A cursory search doesn&rsquo;t turn up much, but I did find these:</p>
  828. <ul>
  829. <li><a href="http://www.rtd-denver.com/Developer.shtml">http://www.rtd-denver.com/Developer.shtml</a></li>
  830. <li><a href="https://developers.google.com/transit/gtfs/reference?csw=1">https://developers.google.com/transit/gtfs/reference?csw=1</a></li>
  831. <li><a href="http://www.rtd-denver.com/GoogleFeeder/">http://www.rtd-denver.com/GoogleFeeder/</a></li>
  832. <li><a href="http://www.rtd-denver.com/GoogleFeeder/google_transit_Jan15_Runboard.zip">http://www.rtd-denver.com/GoogleFeeder/google_transit_Jan15_Runboard.zip</a></li>
  833. </ul>
  834. <p>I grabbed that last one.</p>
  835. <pre><code>brennen@desiderata 16:16:43 /home/brennen ★ mkdir rtd &amp;&amp; mv google_transit_Jan15_Runboard.zip rtd
  836. brennen@desiderata 16:16:51 /home/brennen ★ cd rtd
  837. brennen@desiderata 16:16:53 /home/brennen/rtd ★ unzip google_transit_Jan15_Runboard.zip
  838. Archive: google_transit_Jan15_Runboard.zip
  839. inflating: calendar.txt
  840. inflating: calendar_dates.txt
  841. inflating: agency.txt
  842. inflating: shapes.txt
  843. inflating: stop_times.txt
  844. inflating: trips.txt
  845. inflating: stops.txt
  846. inflating: routes.txt
  847. </code></pre>
  848. <p>Ok, so this is pretty minimalist CSV stuff from the look of most of it.</p>
  849. <pre><code>brennen@desiderata 16:22:12 /home/brennen/rtd ★ grep Lyons stops.txt
  850. 20921,Lyons PnR,Vehicles Travelling East, 40.223979,-105.270174,,,0
  851. </code></pre>
  852. <p>So it looks like stops have an individual id?</p>
  853. <pre><code>brennen@desiderata 16:24:41 /home/brennen/rtd ★ grep '20921' ./*.txt | wc -l
  854. 87
  855. </code></pre>
  856. <p>A lot of this is noise, but:</p>
  857. <pre><code>brennen@desiderata 16:26:23 /home/brennen/rtd ★ grep 20921 ./stop_times.txt
  858. 8711507,12:52:00,12:52:00,20921,43,,1,0,
  859. 8711508,11:32:00,11:32:00,20921,43,,1,0,
  860. 8711509,07:55:00,07:55:00,20921,43,,1,0,
  861. 8711512,16:41:00,16:41:00,20921,43,,1,0,
  862. 8711519,05:37:00,05:37:00,20921,3,,0,1,
  863. 8711517,16:47:00,16:47:00,20921,1,,0,1,
  864. 8711511,17:58:00,17:58:00,20921,43,,1,0,
  865. 8711514,13:02:00,13:02:00,20921,1,,0,1,
  866. 8711516,07:59:00,07:59:00,20921,1,,0,1,
  867. 8711515,11:42:00,11:42:00,20921,1,,0,1,
  868. 8711510,19:10:00,19:10:00,20921,43,,1,0,
  869. 8711513,18:05:00,18:05:00,20921,1,,0,1,
  870. 8711518,06:47:00,06:47:00,20921,1,,0,1,
  871. brennen@desiderata 16:26:57 /home/brennen/rtd ★ head -1 stop_times.txt
  872. trip_id,arrival_time,departure_time,stop_id,stop_sequence,stop_headsign,pickup_type,drop_off_type,shape_dist_traveled
  873. </code></pre>
  874. <p>So:</p>
  875. <pre><code>brennen@desiderata 16:41:47 /home/brennen/code/rtd-tools (master) ★ grep ',20921,' ./stop_times.txt | cut -d, -f1,3 | sort -n
  876. 8711507,12:52:00
  877. 8711508,11:32:00
  878. 8711509,07:55:00
  879. 8711510,19:10:00
  880. 8711511,17:58:00
  881. 8711512,16:41:00
  882. 8711513,18:05:00
  883. 8711514,13:02:00
  884. 8711515,11:42:00
  885. 8711516,07:59:00
  886. 8711517,16:47:00
  887. 8711518,06:47:00
  888. 8711519,05:37:00
  889. </code></pre>
  890. <p>That first number is a <code>trip_id</code>, the second one departure time. Trips
  891. are provided in <code>trips.txt</code>:</p>
  892. <pre><code>brennen@desiderata 16:54:56 /home/brennen/code/rtd-tools (master) ★ head -2 trips.txt
  893. route_id,service_id,trip_id,trip_headsign,direction_id,block_id,shape_id
  894. 0,SA,8690507,Union Station,0, 0 2,793219
  895. </code></pre>
  896. <p>I don&rsquo;t usually use <code>join</code> very much, but this seems like a logical place for
  897. it. It turns out that <code>join</code> wants its input sorted on the join field, so I do
  898. this:</p>
  899. <pre><code>brennen@desiderata 16:54:38 /home/brennen/code/rtd-tools (master) ★ sort -t, -k1 stop_times.txt &gt; stop_times.sorted.txt
  900. brennen@desiderata 16:54:38 /home/brennen/code/rtd-tools (master) ★ sort -t, -k3 trips.txt &gt; trips.sorted.txt
  901. </code></pre>
  902. <p>And then:</p>
  903. <pre><code>brennen@desiderata 16:51:07 /home/brennen/code/rtd-tools (master) ★ join -t, -1 1 -2 3 ./stop_times.sorted.txt ./trips.sorted.txt | grep 20921
  904. ,Y,WK,Lyons PnR,0, Y 16,79481043,,1,0,
  905. ,Y,WK,Lyons PnR,0, Y 16,79481043,,1,0,
  906. ,Y,WK,Lyons PnR,0, Y 15,79481043,,1,0,
  907. ,Y,WK,Lyons PnR,0, Y 41,79480943,,1,0,
  908. ,Y,WK,Lyons PnR,0, Y 41,79481043,,1,0,
  909. ,Y,WK,Lyons PnR,0, Y 41,79481043,,1,0,
  910. ,Y,WK,Boulder Transit Center,1, Y 41,794814
  911. ,Y,WK,Boulder Transit Center,1, Y 16,794812
  912. ,Y,WK,Boulder Transit Center,1, Y 16,794814
  913. ,Y,WK,Boulder Transit Center,1, Y 15,794812
  914. ,Y,WK,Boulder Transit Center,1, Y 41,794813
  915. ,Y,WK,Boulder Transit Center,1, Y 15,794813
  916. ,Y,WK,Boulder Transit Center,1, 206 1,794816
  917. </code></pre>
  918. <p>Ok, waitasec. What the fuck is going on here? The string <code>20921</code> appears
  919. nowhere in these lines. It takes me too long to figure out that the
  920. text files have CRLF line-endings and this is messing with something in
  921. the chain (probably just output from <code>grep</code>, since it&rsquo;s obviously
  922. finding the string). So:</p>
  923. <pre><code>brennen@desiderata 16:59:35 /home/brennen/code/rtd-tools (master) ★ dos2unix *.sorted.txt
  924. dos2unix: converting file stop_times.sorted.txt to Unix format ...
  925. dos2unix: converting file trips.sorted.txt to Unix format ...
  926. </code></pre>
  927. <p>Why does <code>dos2unix</code> operate in-place on files instead of printing to STDOUT?
  928. It beats me, but I sure am glad I didn&rsquo;t run it on anything especially
  929. breakable. It <em>does</em> do what you&rsquo;d expect when piped to, anyway, which is
  930. probably what I should have done.</p>
  931. <p>So this seems to work:</p>
  932. <pre><code>brennen@desiderata 17:04:45 /home/brennen/code/rtd-tools (master) ★ join -t, -1 1 -2 3 ./stop_times.sorted.txt ./trips.sorted.txt | grep 20921
  933. 8711507,12:52:00,12:52:00,20921,43,,1,0,,Y,WK,Lyons PnR,0, Y 16,794810
  934. 8711508,11:32:00,11:32:00,20921,43,,1,0,,Y,WK,Lyons PnR,0, Y 16,794810
  935. 8711509,07:55:00,07:55:00,20921,43,,1,0,,Y,WK,Lyons PnR,0, Y 15,794810
  936. 8711510,19:10:00,19:10:00,20921,43,,1,0,,Y,WK,Lyons PnR,0, Y 41,794809
  937. 8711511,17:58:00,17:58:00,20921,43,,1,0,,Y,WK,Lyons PnR,0, Y 41,794810
  938. 8711512,16:41:00,16:41:00,20921,43,,1,0,,Y,WK,Lyons PnR,0, Y 41,794810
  939. 8711513,18:05:00,18:05:00,20921,1,,0,1,,Y,WK,Boulder Transit Center,1, Y 41,794814
  940. 8711514,13:02:00,13:02:00,20921,1,,0,1,,Y,WK,Boulder Transit Center,1, Y 16,794812
  941. 8711515,11:42:00,11:42:00,20921,1,,0,1,,Y,WK,Boulder Transit Center,1, Y 16,794814
  942. 8711516,07:59:00,07:59:00,20921,1,,0,1,,Y,WK,Boulder Transit Center,1, Y 15,794812
  943. 8711517,16:47:00,16:47:00,20921,1,,0,1,,Y,WK,Boulder Transit Center,1, Y 41,794813
  944. 8711518,06:47:00,06:47:00,20921,1,,0,1,,Y,WK,Boulder Transit Center,1, Y 15,794813
  945. 8711519,05:37:00,05:37:00,20921,3,,0,1,,Y,WK,Boulder Transit Center,1, 206 1,794816
  946. </code></pre>
  947. <p>Which seems kind of right for the <a href="http://www3.rtd-denver.com/schedules/getSchedule.action?runboardId=151&amp;routeId=Y&amp;routeType=12&amp;direction=S-Bound&amp;serviceType=3">South</a> &amp;
  948. <a href="http://www3.rtd-denver.com/schedules/getSchedule.action?runboardId=151&amp;routeId=Y&amp;routeType=12&amp;direction=N-Bound&amp;serviceType=3">Northbound</a> schedules, but they&rsquo;re weirdly intermingled. I think
  949. this pulls departure time and a <code>direction_id</code> field:</p>
  950. <pre><code>brennen@desiderata 17:15:12 /home/brennen/code/rtd-tools (master) ★ join -t, -1 1 -2 3 ./stop_times.sorted.txt ./trips.sorted.txt | grep 20921 | cut -d, -f3,13 | sort -n
  951. 05:37:00,1
  952. 06:47:00,1
  953. 07:55:00,0
  954. 07:59:00,1
  955. 11:32:00,0
  956. 11:42:00,1
  957. 12:52:00,0
  958. 13:02:00,1
  959. 16:41:00,0
  960. 16:47:00,1
  961. 17:58:00,0
  962. 18:05:00,1
  963. 19:10:00,0
  964. </code></pre>
  965. <p>So southbound, I guess:</p>
  966. <pre><code>brennen@desiderata 17:15:59 /home/brennen/code/rtd-tools (master) ★ join -t, -1 1 -2 3 ./stop_times.sorted.txt ./trips.sorted.txt | grep 20921 | cut -d, -f3,13 | grep ',1' | sort -n
  967. 05:37:00,1
  968. 06:47:00,1
  969. 07:59:00,1
  970. 11:42:00,1
  971. 13:02:00,1
  972. 16:47:00,1
  973. 18:05:00,1
  974. </code></pre>
  975. <p>This should probably be where I think oh, right, this is a Google spec - maybe
  976. there&rsquo;s <a href="https://github.com/google/transitfeed">already some tooling</a>. Failing
  977. that, slurping them into SQLite or something would be a lot less painful. Or
  978. at least using csvkit.</p>
  979. </article>
  980. <article>
  981. <h1><a name=Wednesday-January-14-2015 href=#Wednesday-January-14-2015>#</a> Wednesday, January 14, 2015</h1>
  982. <p>On making a web page remind me of a quality I never fully appreciated in
  983. HyperCard.</p>
  984. <p>So I generally am totally ok with scrolling on web pages. I think in
  985. fact it&rsquo;s a major advantage of the form.</p>
  986. <p>Then again, I just got to indulging a few minutes of thinking about
  987. HyperCard, and I think that this time rather than read the same old
  988. articles about its ultimate doom over and over again, maybe I should do
  989. something by way of recreating part of it that was different from the
  990. web in general.</p>
  991. <p>The web has plenty of stupid carousels and stuff, but despite their example I&rsquo;m
  992. curious whether HyperCard&rsquo;s stack model could still hold up as an idea. I was
  993. never sure whether it was the important thing or not. It was so obviously and
  994. almost clumsily a <em>metaphor</em>. (A skeuomorphism which I have never actually
  995. seen anyone bag on when they are playing that game, perhaps because Designer
  996. Ideologues know there&rsquo;s not much percentage in talking shit about HyperCard.)</p>
  997. <p>Here is some JavaScript to start:</p>
  998. <pre><code>$('article').each(function (i, a) {
  999. $(a).hide();
  1000. });
  1001. $('article').first().show();
  1002. </code></pre>
  1003. <p>I&rsquo;ll spare you the usual slow-composition narrative of where I go from here,
  1004. and jump straight to my eventual <a href="https://github.com/brennen/tildebrennen/commit/560826a9884dae47998843dcf4917266b3344fec">first-pass solution</a>.</p>
  1005. <p>(Ok, actually I just repurposed a terrible thing I did for some slides a while
  1006. back, after recreating about 75% without remembering that I had already written
  1007. the same code within the last couple of months. It&rsquo;s amazing how often that
  1008. happens, or I guess it would be amazing if my short term memory weren&rsquo;t so
  1009. thoroughly scrambled from all the evil living I do.)</p>
  1010. </article>
  1011. <article>
  1012. <h1><a name=Friday-January-16 href=#Friday-January-16>#</a> Friday, January 16</h1>
  1013. <p><a href="http://www.raspberrypi.org/documentation/configuration/wireless/wireless-cli.md">Wireless configuration under Raspbian</a>.</p>
  1014. </article>
  1015. <article>
  1016. <h1><a name=Tuesday-January-20 href=#Tuesday-January-20>#</a> Tuesday, January 20</h1>
  1017. <p>I wanted to figure out where I used a library in existing code.</p>
  1018. <p>This is what I wound up doing in zsh:</p>
  1019. <pre><code>brennen@exuberance 11:48:07 /home/brennen/code $ for foo in `ls -f`; do; if [[ -d $foo/.git ]]; then cd $foo; echo '--' $foo '--'; git grep 'IPC::System::Simple'; cd ~/code; fi; done
  1020. -- thcipriani-dotfiles --
  1021. -- sfe-sysadmin --
  1022. -- pi_bootstrap --
  1023. -- bpb-kit --
  1024. -- batchpcb --
  1025. -- according-to-pete --
  1026. -- meatbags --
  1027. -- sfe-paleo --
  1028. -- instruct --
  1029. -- sfe-openstack --
  1030. -- YouTube_Captions --
  1031. -- batchpcb_rails --
  1032. -- userland-book --
  1033. slides/render.pl:use IPC::System::Simple qw(capturex);
  1034. -- sfe-custom-queries --
  1035. -- brennen-sparklib-fork --
  1036. -- tilde.club --
  1037. -- display --
  1038. -- sfe-chef --
  1039. -- xrectsel --
  1040. -- git-feed --
  1041. git-feed:use IPC::System::Simple qw(capturex);
  1042. sample_feed.xml: use IPC::System::Simple qw(capturex);
  1043. sample_feed.xml:+use IPC::System::Simple qw(capturex);
  1044. -- reddit --
  1045. -- rtd-tools --
  1046. -- sparkfun --
  1047. -- mru --
  1048. </code></pre>
  1049. <p>Lame-ish, but I&rsquo;m perpetually forgetting shell loop and conditional syntax, so
  1050. it seems worth making a note of.</p>
  1051. </article>
  1052. <article>
  1053. <h1><a name=Thursday-January-22 href=#Thursday-January-22>#</a> Thursday, January 22</h1>
  1054. <h2><a name=Thursday-January-22-deleting-files-from-git-history href=#Thursday-January-22-deleting-files-from-git-history>#</a> deleting files from git history</h2>
  1055. <p>Working on a project where we included some built files that took up a bunch of
  1056. space, and decided we should get rid of those. The git repository isn&rsquo;t public
  1057. yet and is only shared by a handful of users, so it seemed worth thinking about
  1058. rewriting the history a bit.</p>
  1059. <p>There&rsquo;s reasonably good documentation for this in the usual places if you look,
  1060. but I ran into some trouble.</p>
  1061. <p>First, what seemed to work: David Underhill has a <a href="http://dound.com/2009/04/git-forever-remove-files-or-folders-from-history/">good short script</a> from
  1062. back in 2009 for using <code>git filter-branch</code> to eliminate particular files from
  1063. history:</p>
  1064. <blockquote><p>I recently had a need to rewrite a git repository’s history. This isn’t
  1065. generally a very good idea, though it is useful if your repository contains
  1066. files it should not (such as unneeded large binary files or copyrighted
  1067. material). I also am using it because I had a branch where I only wanted to
  1068. merge a subset of files back into master (though there are probably better
  1069. ways of doing this). Anyway, it is not very hard to rewrite history thanks to
  1070. the excellent git-filter-branch tool which comes with git.</p></blockquote>
  1071. <p>I&rsquo;ll reproduce the script here, in the not-unlikely event that his writeup goes
  1072. away:</p>
  1073. <pre><code>#!/bin/bash
  1074. set -o errexit
  1075. # Author: David Underhill
  1076. # Script to permanently delete files/folders from your git repository. To use
  1077. # it, cd to your repository's root and then run the script with a list of paths
  1078. # you want to delete, e.g., git-delete-history path1 path2
  1079. if [ $# -eq 0 ]; then
  1080. exit 0
  1081. fi
  1082. # make sure we're at the root of git repo
  1083. if [ ! -d .git ]; then
  1084. echo "Error: must run this script from the root of a git repository"
  1085. exit 1
  1086. fi
  1087. # remove all paths passed as arguments from the history of the repo
  1088. files=$@
  1089. git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch $files" HEAD
  1090. # remove the temporary history git-filter-branch otherwise leaves behind for a long time
  1091. rm -rf .git/refs/original/ &amp;&amp; git reflog expire --all &amp;&amp; git gc --aggressive --prune
  1092. </code></pre>
  1093. <p>A big thank you to Mr. Underhill for documenting this one. <code>filter-branch</code>
  1094. seems really powerful, and not as brain-hurting as some things in git land.
  1095. The <a href="http://git-scm.com/docs/git-filter-branch">docs</a> are currently pretty good, and worth a read if you&rsquo;re trying to
  1096. solve this problem.</p>
  1097. <blockquote><p>Lets you rewrite Git revision history by rewriting the branches mentioned in
  1098. the <rev-list options>, applying custom filters on each revision. Those
  1099. filters can modify each tree (e.g. removing a file or running a perl rewrite
  1100. on all files) or information about each commit. Otherwise, all information
  1101. (including original commit times or merge information) will be preserved.</p></blockquote>
  1102. <p>After this, things got muddier. The script seemed to work fine, and after
  1103. running it I was able to see all the history I expected, minus some troublesome
  1104. files. (A version with <code>--prune-empty</code> added to the <code>git filter-branch</code>
  1105. invocation got rid of some empty commits.) But then:</p>
  1106. <pre><code>brennen@exuberance 20:05:00 /home/brennen/code $ du -hs pi_bootstrap
  1107. 218M pi_bootstrap
  1108. brennen@exuberance 20:05:33 /home/brennen/code $ du -hs experiment
  1109. 199M experiment
  1110. </code></pre>
  1111. <p>That second repo is a clone of the original with the script run against it.
  1112. Why is it only tens of megabytes smaller, when minus the big binaries I zapped,
  1113. it should come in somewhere under 10 megs?</p>
  1114. <p>I will spare you, dear reader, the contortions I went through arriving at a
  1115. solution for this, partially because I don&rsquo;t have the energy left to
  1116. reconstruct them from the tattered history of my googling over the last few
  1117. hours. What I figured out was that for some reason, a bunch of blobs were
  1118. persisting in a pack file, despite not being referenced by any commits, and no
  1119. matter what I couldn&rsquo;t get <code>git gc</code> or <code>git repack</code> to zap them.</p>
  1120. <p>I more or less got this far with commands like:</p>
  1121. <pre><code>brennen@exuberance 20:49:10 /home/brennen/code/experiment2/.git (master) $ git count-objects -v
  1122. count: 0
  1123. size: 0
  1124. in-pack: 2886
  1125. packs: 1
  1126. size-pack: 202102
  1127. prune-packable: 0
  1128. garbage: 0
  1129. size-garbage: 0
  1130. </code></pre>
  1131. <p>And:</p>
  1132. <pre><code>git verify-pack -v ./objects/pack/pack-b79fc6e30a547433df5c6a0c6212672c5e5aec5f &gt; ~/what_the_fuck
  1133. </code></pre>
  1134. <p>&hellip;which gives a list of all the stuff in a pack file, including
  1135. super-not-human-readable sizes that you can sort on, and many permutations of
  1136. things like:</p>
  1137. <pre><code>brennen@exuberance 20:49:12 /home/brennen/code/experiment2/.git (master) $ git log --pretty=oneline | cut -f1 -d' ' | xargs -L1 git cat-file -s | sort -nr | head
  1138. 589
  1139. 364
  1140. 363
  1141. 348
  1142. 341
  1143. 331
  1144. 325
  1145. 325
  1146. 322
  1147. 320
  1148. </code></pre>
  1149. <p>&hellip;where <code>cat-file</code> is a bit of a Swiss army knife for looking at objects, with
  1150. <code>-s</code> meaning &ldquo;tell me a size&rdquo;.</p>
  1151. <p>(An aside: If you are writing software that outputs a size in bytes, blocks,
  1152. etc., and you do not provide a &ldquo;human readable&rdquo; option to display this in
  1153. comprehensible units, the innumerate among us quietly hate your guts. This is
  1154. perhaps unjust of us, but I&rsquo;m just trying to communicate my experience here.)</p>
  1155. <p>And finally, <a href="https://stackoverflow.com/questions/223678/which-commit-has-this-blob/223890#223890">Aristotle Pagaltzis&rsquo;s script</a> for figuring out which commit
  1156. has a given blob (the answer is <em>fucking none of them</em>, in my case):</p>
  1157. <pre><code>#!/bin/sh
  1158. obj_name="$1"
  1159. shift
  1160. git log "$@" --pretty=format:'%T %h %s' \
  1161. | while read tree commit subject ; do
  1162. if git ls-tree -r $tree | grep -q "$obj_name" ; then
  1163. echo $commit "$subject"
  1164. fi
  1165. done
  1166. </code></pre>
  1167. <p>Also somewhere in there I learned how to use <a href="http://git-scm.com/docs/git-bisect"><code>git bisect</code></a> (which is
  1168. really cool and likely something I will use again) and went through and made
  1169. entirely certain there was nothing in the history with a bunch of big files
  1170. in it.</p>
  1171. <p>So eventually I got to thinking ok, there&rsquo;s something here that is keeping
  1172. these objects from getting expired or pruned or garbage collected or whatever,
  1173. so how about doing a clone that just copies the stuff in the commits that still
  1174. exist at this point. Which brings us to:</p>
  1175. <pre><code>brennen@exuberance 19:03:08 /home/brennen/code/experiment2 (master) $ git help clone
  1176. brennen@exuberance 19:06:52 /home/brennen/code/experiment2 (master) $ cd ..
  1177. brennen@exuberance 19:06:55 /home/brennen/code $ git clone --no-local ./experiment2 ./experiment2_no_local
  1178. Cloning into './experiment2_no_local'...
  1179. remote: Counting objects: 2874, done.
  1180. remote: Compressing objects: 100% (1611/1611), done.
  1181. remote: Total 2874 (delta 938), reused 2869 (delta 936)
  1182. Receiving objects: 100% (2874/2874), 131.21 MiB | 37.48 MiB/s, done.
  1183. Resolving deltas: 100% (938/938), done.
  1184. Checking connectivity... done.
  1185. brennen@exuberance 19:07:15 /home/brennen/code $ du -hs ./experiment2_no_local
  1186. 133M ./experiment2_no_local
  1187. brennen@exuberance 19:07:20 /home/brennen/code $ git help clone
  1188. brennen@exuberance 19:08:34 /home/brennen/code $ git clone --no-local --single-branch ./experiment2 ./experiment2_no_local_single_branch
  1189. Cloning into './experiment2_no_local_single_branch'...
  1190. remote: Counting objects: 1555, done.
  1191. remote: Compressing objects: 100% (936/936), done.
  1192. remote: Total 1555 (delta 511), reused 1377 (delta 400)
  1193. Receiving objects: 100% (1555/1555), 1.63 MiB | 0 bytes/s, done.
  1194. Resolving deltas: 100% (511/511), done.
  1195. Checking connectivity... done.
  1196. brennen@exuberance 19:08:47 /home/brennen/code $ du -hs ./experiment2_no_local_single_branch
  1197. 3.0M ./experiment2_no_local_single_branch
  1198. </code></pre>
  1199. <p>What&rsquo;s going on here? <a href="http://git-scm.com/docs/git-clone">Well</a>, <code>git clone --no-local</code>:</p>
  1200. <pre><code>--local
  1201. -l
  1202. When the repository to clone from is on a local machine, this flag
  1203. bypasses the normal "Git aware" transport mechanism and clones the
  1204. repository by making a copy of HEAD and everything under objects and
  1205. refs directories. The files under .git/objects/ directory are
  1206. hardlinked to save space when possible.
  1207. If the repository is specified as a local path (e.g., /path/to/repo),
  1208. this is the default, and --local is essentially a no-op. If the
  1209. repository is specified as a URL, then this flag is ignored (and we
  1210. never use the local optimizations). Specifying --no-local will override
  1211. the default when /path/to/repo is given, using the regular Git
  1212. transport instead.
  1213. </code></pre>
  1214. <p>And <code>--single-branch</code>:</p>
  1215. <pre><code>--[no-]single-branch
  1216. Clone only the history leading to the tip of a single branch, either
  1217. specified by the --branch option or the primary branch remote’s HEAD
  1218. points at. When creating a shallow clone with the --depth option, this
  1219. is the default, unless --no-single-branch is given to fetch the
  1220. histories near the tips of all branches. Further fetches into the
  1221. resulting repository will only update the remote-tracking branch for
  1222. the branch this option was used for the initial cloning. If the HEAD at
  1223. the remote did not point at any branch when --single-branch clone was
  1224. made, no remote-tracking branch is created.
  1225. </code></pre>
  1226. <p>I have no idea why <code>--no-local</code> by itself reduced the size but didn&rsquo;t really do
  1227. the job.</p>
  1228. <p>It&rsquo;s possible the lingering blobs would have been garbage collected
  1229. <em>eventually</em>, and at any rate it seems likely that in pushing them to a remote
  1230. repository I would have bypassed whatever lazy local file copy operation was
  1231. causing everything to persist on cloning, thus rendering all this
  1232. head-scratching entirely pointless, but then who knows. At least I understand
  1233. git file structure a little better than I did before.</p>
  1234. <p>For good measure, I just remembered how old much of the software on this
  1235. machine is, and I feel like kind of an ass:</p>
  1236. <pre><code>brennen@exuberance 21:20:50 /home/brennen/code $ git --version
  1237. git version 1.9.1
  1238. </code></pre>
  1239. <p>This is totally an old release. If there&rsquo;s a bug here, maybe it&rsquo;s fixed by
  1240. now. I will not venture a strong opinion as to whether there is a bug. Maybe
  1241. this is entirely expected behavior. It is time to drink a beer.</p>
  1242. <h2><a name=Thursday-January-22-postscript-on-finding-bugs href=#Thursday-January-22-postscript-on-finding-bugs>#</a> postscript: on finding bugs</h2>
  1243. <p>The first thing you learn, by way of considerable personal frustration and
  1244. embarrassment, goes something like this:</p>
  1245. <blockquote><p>Q: My stuff isn&rsquo;t working. I think there is probably a bug in this mature
  1246. and widely-used (programming language | library | utility software).</p>
  1247. <p>A: Shut up shut up shut up <em>shut up</em> there is not a bug. Now go and figure
  1248. out what is wrong with your code.</p></blockquote>
  1249. <p>The second thing goes something like this:</p>
  1250. <blockquote><p>Oh. I guess that&rsquo;s actually a bug.</p></blockquote>
  1251. <p>Which is to say: I have learned that I&rsquo;m probably wrong, but sometimes I&rsquo;m
  1252. also wrong about being wrong.</p>
  1253. </article>
  1254. <article>
  1255. <h1><a name=Sunday-January-25-2015 href=#Sunday-January-25-2015>#</a> Sunday, January 25, 2015</h1>
  1256. <h2><a name=Sunday-January-25-2015-background-colors-for-tmux href=#Sunday-January-25-2015-background-colors-for-tmux>#</a> background colors for tmux</h2>
  1257. <p>I&rsquo;m logged into too many machines. I make an effort to have prompt colors differ
  1258. between hosts, but tmux is the same everywhere.</p>
  1259. <p>You can do this sort of thing:</p>
  1260. <pre><code>brennen@exuberance 11:54:43 /home/brennen/code $ cat ~/.tmux.conf
  1261. # Set window notifications
  1262. setw -g monitor-activity on
  1263. set -g visual-activity on
  1264. set -g status-bg blue
  1265. set -g status-fg white
  1266. </code></pre>
  1267. <p>&hellip;where <code>status-bg</code> and <code>status-fg</code> are colors for the status bar.</p>
  1268. <p>It seems like there may be ways to conditionalize this, but at this point I&rsquo;m
  1269. tempted to just pull some simple templating system into my <a href="https://github.com/brennen/bpb-kit">dotfile
  1270. stuff</a> and generate a subset of config files on a per-host basis.</p>
  1271. </article>
  1272. <article>
  1273. <h1><a name=Tuesday-January-27 href=#Tuesday-January-27>#</a> Tuesday, January 27</h1>
  1274. <h2><a name=Tuesday-January-27-what-version-of-what-linux-distribution-is-this href=#Tuesday-January-27-what-version-of-what-linux-distribution-is-this>#</a> what version of what linux distribution is this?</h2>
  1275. <p>Some luck <em>may</em> be had with one or more of:</p>
  1276. <pre><code>root@beaglebone:~# uname -a
  1277. Linux beaglebone 3.8.13-bone47 #1 SMP Fri Apr 11 01:36:09 UTC 2014 armv7l GNU/Linux
  1278. root@beaglebone:~# lsb_release -a
  1279. No LSB modules are available.
  1280. Distributor ID: Debian
  1281. Description: Debian GNU/Linux 7.8 (wheezy)
  1282. Release: 7.8
  1283. Codename: wheezy
  1284. root@beaglebone:~# cat /etc/debian_version
  1285. 7.8
  1286. root@beaglebone:~# cat /etc/dogtag
  1287. BeagleBoard.org BeagleBone Debian Image 2014-04-23
  1288. root@beaglebone:~# cat /etc/os-release
  1289. PRETTY_NAME="Debian GNU/Linux 7 (wheezy)"
  1290. NAME="Debian GNU/Linux"
  1291. VERSION_ID="7"
  1292. VERSION="7 (wheezy)"
  1293. ID=debian
  1294. ANSI_COLOR="1;31"
  1295. HOME_URL="http://www.debian.org/"
  1296. SUPPORT_URL="http://www.debian.org/support/"
  1297. BUG_REPORT_URL="http://bugs.debian.org/"
  1298. </code></pre>
  1299. <h2><a name=Tuesday-January-27-armhf href=#Tuesday-January-27-armhf>#</a> armhf</h2>
  1300. <p><a href="https://blogs.oracle.com/jtc/entry/is_it_armhf_or_armel">Is it armhf or armel?</a>:</p>
  1301. <blockquote><p>During diagnosis, the question becomes, how can I determine whether my Linux
  1302. distribution is based on armel or armhf? Turns out this is not as
  1303. straightforward as one might think. Aside from experience and anecdotal
  1304. evidence, one possible way to ascertain whether you&rsquo;re running on armel or
  1305. armhf is to run the following obscure command:</p>
  1306. <pre><code>$ readelf -A /proc/self/exe | grep Tag_ABI_VFP_args
  1307. </code></pre>
  1308. <p>If the Tag_ABI_VFP_args tag is found, then you&rsquo;re running on an armhf system.
  1309. If nothing is returned, then it&rsquo;s armel. To show you an example, here&rsquo;s what
  1310. happens on a Raspberry Pi running the Raspbian distribution:</p>
  1311. <pre><code>pi@raspberrypi:~$ readelf -A /proc/self/exe | grep Tag_ABI_VFP_args
  1312. Tag_ABI_VFP_args: VFP registers
  1313. </code></pre>
  1314. <p>This indicates an armhf distro, which in fact is what Raspbian is. On the
  1315. original, soft-float Debian Wheezy distribution, here&rsquo;s what happens:</p>
  1316. <pre><code>pi@raspberrypi:~$ readelf -A /proc/self/exe | grep Tag_ABI_VFP_args
  1317. </code></pre>
  1318. <p>Nothing returned indicates that this is indeed armel.</p></blockquote>
  1319. <p>On a recent-ish Beaglebone Black:</p>
  1320. <pre><code>root@beaglebone:~# readelf -A /proc/self/exe | grep Tag_ABI_VFP_args
  1321. Tag_ABI_VFP_args: VFP registers
  1322. </code></pre>
  1323. </article>
  1324. <article>
  1325. <h1><a name=Wednesday-January-28 href=#Wednesday-January-28>#</a> Wednesday, January 28</h1>
  1326. <h2><a name=Wednesday-January-28-on-replicating-process href=#Wednesday-January-28-on-replicating-process>#</a> on replicating process</h2>
  1327. <p>Ok, so here we are. It&rsquo;s 2015. The gold standard for explaining how you
  1328. solved a technical problem to the internet at large is a blog post with things
  1329. you can copy and paste or maybe some pictures.</p>
  1330. <p>If you&rsquo;re really lucky, someone actually has reusable a public repository of
  1331. some kind. If you&rsquo;re <em>really</em> lucky, their code works, and if all the gods
  1332. are smiling on you at once, their code is <em>documented</em>.</p>
  1333. <p>It seems to me that we can do better than this. We possess a great many of the
  1334. right <em>tools</em> to do better than this, at least for a lot of common problems.
  1335. What does it take to make a given workflow both repeatable and legible to
  1336. people without the context we have for a given thing (including ourselves)?
  1337. Writing about it is surely desirable, but how do you approach a problem so
  1338. that, instead of being scattered across your short term memory and a dozen
  1339. volatile buffers, your work becomes a kind of document unto itself?</p>
  1340. <p>This is the (beautiful) root of what version control does, after all: It
  1341. renders a normally-invisible process legible, and in its newfound legibility,
  1342. at least a little susceptible to transmission and reuse.</p>
  1343. <p>What do I know works well for transmitting process and discovery, as far as it
  1344. goes?</p>
  1345. <ul>
  1346. <li>version control (so really git, which is severally horrible but also
  1347. brilliant and wins anyway)</li>
  1348. <li>Makefiles (except that I don&rsquo;t understand make at <em>all</em>)</li>
  1349. <li>shell scripts (except that shell programming is an utter nightmare)</li>
  1350. <li>Debian packages (which are more or less compounded of the above, and
  1351. moderately torturous to build)</li>
  1352. <li>IRC, if you keep logs, because it&rsquo;s amazing how much knowledge is most purely
  1353. conveyed in the medium of internet chat</li>
  1354. <li>Stackoverflow &amp; friends (I hate this, but there it is, it&rsquo;s a fact, we have to
  1355. deal with it no matter how much we hate process jockies, just like Wikipedia)</li>
  1356. <li>screenshots and screencasts (a pain to make, all-too-often free of context, and
  1357. yet)</li>
  1358. </ul>
  1359. <p>Here are some things that I think are often terrible at this stuff despite
  1360. their ubiquity:</p>
  1361. <ul>
  1362. <li>mailing lists (so bad, so <em>routinely pathological</em>, so utterly necessary to
  1363. everything)</li>
  1364. <li>web forums like phpBB and stuff (so bad, so ubiquitous, so going to show up
  1365. in your google results with the hint you desperately needed, but only if you&rsquo;re
  1366. smart enough to parse it out of the spew)</li>
  1367. </ul>
  1368. <p>Here&rsquo;s one problem: There are a lot of relatively painless once you know them
  1369. tools, like &ldquo;let&rsquo;s just make this a dvcs repo because it&rsquo;s basically free&rdquo;,
  1370. that if you know they exist and you really want to avoid future suffering you
  1371. just get in the habit of using by default. But most people don&rsquo;t know these
  1372. tools exist, or that they&rsquo;re <em>generally applicable tools</em> and not just
  1373. specialist things you might use for the one important thing at your job because
  1374. somebody said you should.</p>
  1375. <h2><a name=Wednesday-January-28-what-makes-programming-hard href=#Wednesday-January-28-what-makes-programming-hard>#</a> what makes programming hard?</h2>
  1376. <ol>
  1377. <li>Most of the existing programs.</li>
  1378. <li>Most of the existing programming languages.</li>
  1379. <li>Other programmers.</li>
  1380. <li>Human thought is brutally constrained in understanding complex systems.</li>
  1381. <li>Ok you wrote some programs anyway now GOTO 0.</li>
  1382. </ol>
  1383. <h2><a name=Wednesday-January-28-debian-packaging-again href=#Wednesday-January-28-debian-packaging-again>#</a> debian packaging again</h2>
  1384. <p>I&rsquo;m starting <a href="https://www.debian.org/doc/manuals/maint-guide/">here</a> again.</p>
  1385. <ul>
  1386. <li><a href="https://wiki.debian.org/IntroDebianPackaging">https://wiki.debian.org/IntroDebianPackaging</a></li>
  1387. <li><a href="https://www.debian.org/doc/manuals/packaging-tutorial/packaging-tutorial.en.pdf">https://www.debian.org/doc/manuals/packaging-tutorial/packaging-tutorial.en.pdf</a>
  1388. (actually more helpful than anything else I&rsquo;ve found so far)</li>
  1389. </ul>
  1390. <h2><a name=Wednesday-January-28-vagrant href=#Wednesday-January-28-vagrant>#</a> vagrant</h2>
  1391. <p>Vagrant is a thing for quickly provisioning / tearing down / connecting to
  1392. virtual machines. It wraps VirtualBox, among other providers. I think the
  1393. basic appeal is that you get cheap, more-or-less disposable environments with a
  1394. couple of commands, and there&rsquo;s scaffolding for simple scripts to configure a
  1395. box when it&rsquo;s brought up, or share directories with the host filesystem. It&rsquo;s
  1396. really lightweight to try out.</p>
  1397. <p>Go to the <a href="http://www.vagrantup.com/downloads">downloads page</a> and install from
  1398. there. I used the 64 bit Ubuntu .deb.</p>
  1399. <pre><code>$ sudo apt-get install virtualbox
  1400. $ sudo dpkg -i vagrant_1.7.2_x86_64.deb
  1401. $ mkdir vagrant_test
  1402. $ cd vagrant_test
  1403. $ vagrant init hashicorp/precise32
  1404. $ vagrant up
  1405. $ vagrant ssh
  1406. </code></pre>
  1407. <p>This stuff takes a while on the first run through, but is generally really
  1408. slick. <code>hashicorp/precise32</code> is more or less just a preconfigured image pulled
  1409. from a central repository.</p>
  1410. <p>Their <a href="http://docs.vagrantup.com/v2/getting-started/index.html">Getting Started</a> is pretty
  1411. decent.</p>
  1412. <p>People around me have been enthusing about this kind of thing for ages, but I
  1413. haven&rsquo;t really gotten around to figuring out why I should care until recently.
  1414. I will probably be using this tool for a lot of development tasks.</p>
  1415. <p>Other notes:</p>
  1416. <ul>
  1417. <li>stackoverflow: <a href="https://stackoverflow.com/questions/17117063/how-can-i-create-a-vm-in-vagrant-with-virtualbox-with-two-cpus">How can I create a VM in vagrant with virtualbox with two cpus?</a></li>
  1418. <li><a href="https://tylercipriani.com/2014/05/25/lightweight-portable-vagrant-docker.html">Development Environments with Vagrant, Docker, and Supervisord</a></li>
  1419. </ul>
  1420. </article>
  1421. <article>
  1422. <h1><a name=Thursday-January-29 href=#Thursday-January-29>#</a> Thursday, January 29</h1>
  1423. <h2><a name=Thursday-January-29-raspberry-pi-kernels href=#Thursday-January-29-raspberry-pi-kernels>#</a> raspberry pi kernels</h2>
  1424. <ul>
  1425. <li><a href="http://elinux.org/Raspberry_Pi_Kernel_Compilation">http://elinux.org/Raspberry_Pi_Kernel_Compilation</a></li>
  1426. </ul>
  1427. </article>
  1428. <article>
  1429. <h1><a name=Monday-February-2 href=#Monday-February-2>#</a> Monday, February 2</h1>
  1430. <h2><a name=Monday-February-2-kernel-o-matic-amp-pi-finder href=#Monday-February-2-kernel-o-matic-amp-pi-finder>#</a> kernel-o-matic &amp; pi finder</h2>
  1431. <p>Published Friday:</p>
  1432. <ul>
  1433. <li><a href="https://github.com/adafruit/Adafruit-Pi-Kernel-o-Matic">https://github.com/adafruit/Adafruit-Pi-Kernel-o-Matic</a></li>
  1434. <li><a href="https://learn.adafruit.com/raspberry-pi-kernel-o-matic">https://learn.adafruit.com/raspberry-pi-kernel-o-matic</a></li>
  1435. </ul>
  1436. <p>Published a week or so before:</p>
  1437. <ul>
  1438. <li><a href="https://github.com/adafruit/Adafruit-Pi-Finder">https://github.com/adafruit/Adafruit-Pi-Finder</a></li>
  1439. <li><a href="https://blog.adafruit.com/2015/01/23/help-us-test-our-new-raspberry-pi-bootstrap-piday-raspberrypi/">https://blog.adafruit.com/2015/01/23/help-us-test-our-new-raspberry-pi-bootstrap-piday-raspberrypi/</a></li>
  1440. </ul>
  1441. <p>These have been a lot of my working time these last couple weeks, an
  1442. overlapping set of projects aimed at making the Pi (and eventually other
  1443. single-board computers) more usable and Adafruit&rsquo;s hardware and tutorials both
  1444. more accessible. This has been frustrating and rewarding by turns. I&rsquo;m trying
  1445. to reduce the complexity of a domain I just barely understand, in a lot of
  1446. ways, which may be a good summary of software development in general.</p>
  1447. <p><a href="https://www.vagrantup.com/">Vagrant</a> is something I should have paid attention
  1448. to sooner. The interfaces to virtualization are finally starting to overcome
  1449. my innate laziness on the whole question.</p>
  1450. <p>I just booted a Windows XP box for some reason. It made that noise. You know
  1451. the one.</p>
  1452. <h2><a name=Monday-February-2-raspberry-pi-2 href=#Monday-February-2-raspberry-pi-2>#</a> raspberry pi 2</h2>
  1453. <p>Announced today:</p>
  1454. <ul>
  1455. <li><a href="http://www.raspberrypi.org/products/raspberry-pi-2-model-b/">http://www.raspberrypi.org/products/raspberry-pi-2-model-b/</a></li>
  1456. <li><a href="https://blog.adafruit.com/2015/02/02/raspberry-pi-2-model-b-armv7-with-1g-ram-is-here-benchmarks-and-more-raspberry_pi-raspberryp/">https://blog.adafruit.com/2015/02/02/raspberry-pi-2-model-b-armv7-with-1g-ram-is-here-benchmarks-and-more-raspberry_pi-raspberryp/</a></li>
  1457. <li><a href="http://hackaday.com/2015/02/02/introducing-the-raspberry-pi-2/">http://hackaday.com/2015/02/02/introducing-the-raspberry-pi-2/</a></li>
  1458. </ul>
  1459. <p>Expect this to prove interesting. I&rsquo;ve been having a lot of conversations
  1460. about the relative merits of small computing systems, and while this can hardly
  1461. be said to address all the complaints you might have about the Pi, boosting
  1462. processor and RAM will do a lot for practical usability.</p>
  1463. <h2><a name=Monday-February-2-telling-composer-to-ignore-php-version-requirements href=#Monday-February-2-telling-composer-to-ignore-php-version-requirements>#</a> telling composer to ignore php version requirements</h2>
  1464. <p>Using <a href="https://getcomposer.org/">Composer</a> to set up a little project, I run
  1465. into the problem that the locally-installed PHP is a bit behind the times.</p>
  1466. <pre><code>brennen@exuberance 0:09:32 /home/brennen/code/project $ ./composer.phar install
  1467. Loading composer repositories with package information
  1468. Installing dependencies (including require-dev)
  1469. Your requirements could not be resolved to an installable set of packages.
  1470. Problem 1
  1471. - sparkfun/sparklib 1.1.9 requires php &gt;=5.5.17 -&gt; no matching package found.
  1472. - sparkfun/sparklib 1.1.8 requires php &gt;=5.5.17 -&gt; no matching package found.
  1473. - sparkfun/sparklib 1.1.7 requires php &gt;=5.5.17 -&gt; no matching package found.
  1474. - sparkfun/sparklib 1.1.6 requires php &gt;=5.5.17 -&gt; no matching package found.
  1475. - sparkfun/sparklib 1.1.5 requires php &gt;=5.5.17 -&gt; no matching package found.
  1476. - sparkfun/sparklib 1.1.4 requires php &gt;=5.5.17 -&gt; no matching package found.
  1477. - sparkfun/sparklib 1.1.3 requires php &gt;=5.5.17 -&gt; no matching package found.
  1478. - sparkfun/sparklib 1.1.2 requires php &gt;=5.5.17 -&gt; no matching package found.
  1479. - sparkfun/sparklib 1.1.11 requires php &gt;=5.5.17 -&gt; no matching package found.
  1480. - sparkfun/sparklib 1.1.10 requires php &gt;=5.5.17 -&gt; no matching package found.
  1481. - sparkfun/sparklib 1.1.1 requires php &gt;=5.5.17 -&gt; no matching package found.
  1482. - sparkfun/sparklib 1.1.0 requires php &gt;=5.5.17 -&gt; no matching package found.
  1483. - Installation request for sparkfun/sparklib ~1.1 -&gt; satisfiable by sparkfun/sparklib[1.1.0, 1.1.1, 1.1.10, 1.1.11, 1.1.2, 1.1.3, 1.1.4, 1.1.5, 1.1.6, 1.1.7, 1.1.8, 1.1.9].
  1484. Potential causes:
  1485. - A typo in the package name
  1486. - The package is not available in a stable-enough version according to your minimum-stability setting
  1487. see &lt;https://groups.google.com/d/topic/composer-dev/_g3ASeIFlrc/discussion&gt; for more details.
  1488. Read &lt;http://getcomposer.org/doc/articles/troubleshooting.md&gt; for further common problems.
  1489. </code></pre>
  1490. <p>Well, ok. I wrote a lot of that code, and I&rsquo;m pretty sure nothing I want out
  1491. of it will break under a slightly stale PHP. I check <code>./composer.phar help install</code>,
  1492. and sure enough, there&rsquo;s an option to ignore this requirement:</p>
  1493. <pre><code>brennen@exuberance 0:13:21 /home/brennen/code/project $ ./composer.phar install --ignore-platform-reqs
  1494. Loading composer repositories with package information
  1495. Installing dependencies (including require-dev)
  1496. - Installing sparkfun/sparklib (1.1.11)
  1497. Downloading: 100%
  1498. Writing lock file
  1499. Generating autoload files
  1500. </code></pre>
  1501. <p>I never used to quite get the &ldquo;install an executable utility script in the root
  1502. directory of your project&rdquo; thing, but the whole paradigm is growing on me a little
  1503. as my projects accumulate little Makefiles and shell scripts to render HTML,
  1504. publish revisions, or deploy packages.</p>
  1505. </article>
  1506. <article>
  1507. <h1><a name=Sunday-February-8 href=#Sunday-February-8>#</a> Sunday, February 8</h1>
  1508. <h2><a name=Sunday-February-8-systemd-amp-fsck href=#Sunday-February-8-systemd-amp-fsck>#</a> systemd &amp; fsck</h2>
  1509. <p>I just hit my first real frustration with systemd, which is running on the
  1510. Novena. The default storage here is a microSD card, and I&rsquo;ve had to
  1511. force-reboot this thing enough times that I&rsquo;d like to run <code>fsck</code> on the
  1512. root filesystem.</p>
  1513. <p>It used to be that you could call <code>shutdown -F</code> to force an fsck on boot.
  1514. The old aliases still exist, but I think the thing I&rsquo;m supposed to do here
  1515. is <code>systemctl reboot</code>, and there doesn&rsquo;t seem to be an analogous pattern any
  1516. more.</p>
  1517. <p>On the other hand, some of the choices immediatly evident in the design of
  1518. <code>systemctl</code> and <code>journalctl</code> seem interesting and not without merit.</p>
  1519. </article>
  1520. <article>
  1521. <h1><a name=Monday-March-2 href=#Monday-March-2>#</a> Monday, March 2</h1>
  1522. <h2><a name=Monday-March-2-python href=#Monday-March-2-python>#</a> python</h2>
  1523. <p>Significant whitespace isn&rsquo;t exactly a disaster, but on balance still feels
  1524. to me like it causes more problems than it solves: Copy &amp; paste headaches,
  1525. editor hassles, etc.</p>
  1526. </article>
  1527. <article>
  1528. <h1><a name=Thursday-April-9 href=#Thursday-April-9>#</a> Thursday, April 9</h1>
  1529. <h2><a name=Thursday-April-9-CGI-Fast-and-multi-param href=#Thursday-April-9-CGI-Fast-and-multi-param>#</a> CGI::Fast and multi_param()</h2>
  1530. <p>A little while ago, changes were made to <a href="http://search.cpan.org/~leejo/CGI-4.14/lib/CGI.pod">Perl&rsquo;s CGI.pm</a> because of a <a href="http://seclists.org/vulnwatch/2006/q4/6">class
  1531. of exploits</a> arising from calling <code>param()</code> in list context.</p>
  1532. <p>I had code in a wrapper for <a href="https://github.com/brennen/display">Display</a> that called <code>param()</code> in list context
  1533. deliberately:</p>
  1534. <pre><code># Handle input from FastCGI:
  1535. while (my $query = CGI::Fast-&gt;new) {
  1536. my @params = $query-&gt;param('keywords');
  1537. print $d-&gt;display(@params);
  1538. }
  1539. </code></pre>
  1540. <p>In due course, I started getting warnings about calling <code>param()</code> in list context.
  1541. They looked sort of like this:</p>
  1542. <pre><code>brennen@exuberance 18:46:13 /home/brennen/www (master) ★ perl display.fcgi 2&gt;&amp;1 | head -1
  1543. CGI::param called in list context from package main line 38, this can lead to vulnerabilities. See the warning in "Fetching the value or values of a single named parameter" at /usr/local/share/perl/5.20.1/CGI.pm line 408.
  1544. </code></pre>
  1545. <p>Problematic, since a variable containing that list is <em>exactly what I want</em>. On
  1546. googling, I found that in addition to the warning, CGI.pm had been amended to
  1547. include <code>multi_param()</code> for <a href="http://search.cpan.org/~leejo/CGI-4.14/lib/CGI.pod#Fetching_the_value_or_values_of_a_single_named_parameter:">the cases</a> where you explicitly want a list.
  1548. Ok, cool, I&rsquo;ll use that.</p>
  1549. <p>Fast forward to just now. <code>display.fcgi</code> is blowing up on my local machine. Why?</p>
  1550. <pre><code>[Thu Apr 09 18:28:29.606663 2015] [fcgid:warn] [pid 13984:tid 140343326992128] [client 127.0.0.1:41335] mod_fcgid: stderr: Undefined subroutine CGI::Fast::multi_param
  1551. </code></pre>
  1552. <p>Well, ok, I upgraded Ubuntu a while back. Maybe I need to reinstall CGI::Fast
  1553. from CPAN because the Ubuntu packages aren&rsquo;t up to date. So:</p>
  1554. <pre><code>$ sudo cpan -i CGI::Fast
  1555. </code></pre>
  1556. <p>No dice. What am I missing here? Oh, right. CGI::Fast inherits from CGI.pm.</p>
  1557. <pre><code>$ sudo cpan -i CGI
  1558. </code></pre>
  1559. <p>Golden.</p>
  1560. <p>Granted, I should probably stop using CGI.pm altogether.</p>
  1561. </article>
  1562. <article>
  1563. <h1><a name=Monday-April-20 href=#Monday-April-20>#</a> Monday, April 20</h1>
  1564. <h2><a name=Monday-April-20-getting-recent-posts-from-pinboard-machine-readably href=#Monday-April-20-getting-recent-posts-from-pinboard-machine-readably>#</a> getting recent posts from pinboard machine-readably</h2>
  1565. <p>I&rsquo;ve been experimenting again with using Pinboard to track links of interest,
  1566. and thought that maybe it&rsquo;d be a good idea to use these to add a linkblog back
  1567. to p1k3.</p>
  1568. <p>First I thought ok, there&rsquo;s probably an API, which, sure enough, <a href="https://pinboard.in/api">is
  1569. true</a>. Here&rsquo;s a one-liner that will grab JSON of recent posts by
  1570. a user:</p>
  1571. <pre><code>curl "https://brennen:[brennen's password goes here]@api.pinboard.in/v1/posts/recent?count=25&amp;format=json"
  1572. </code></pre>
  1573. <p>&hellip;but then I thought ok, this is dumb. I know there&rsquo;s RSS, so why not just use
  1574. a standard format that could pull from other sources as well?</p>
  1575. <pre><code>curl https://feeds.pinboard.in/rss/u:brennen/
  1576. </code></pre>
  1577. <p>Further thoughts: Instead of doing this dynamically on the server, I could
  1578. just periodically pull data into the p1k3 archives and render it using some
  1579. service. I&rsquo;m getting ever-more leery of running any dynamic code where I don&rsquo;t
  1580. have to, and even considering rewriting all of the p1k3 stuff to generate
  1581. static files instead of building pages on the fly, so maybe this would be a
  1582. good experiment.</p>
  1583. </article>
  1584. <article>
  1585. <h1><a name=Monday-January-18 href=#Monday-January-18>#</a> Monday, January 18</h1>
  1586. <h2><a name=Monday-January-18-moved-to-p1k3-com href=#Monday-January-18-moved-to-p1k3-com>#</a> moved to p1k3.com</h2>
  1587. <p>I&rsquo;ve decided to pick this project back up, but it seems like I&rsquo;ll probably be
  1588. better at updating it if I <a href="https://p1k3.com/2016/1/16">integrate it</a> into
  1589. <a href="https://p1k3.com/">p1k3.com</a>. I&rsquo;ve copied all of these entries over into
  1590. the p1k3 tree, and new ones will appear there, but I&rsquo;ll leave this document
  1591. in place since I feel like it&rsquo;s uncool to break links.</p>
  1592. </article>
  1593. <article>
  1594. <h1><a name=tools-amp-toolchains-for-data-munging-amp-analysis href=#tools-amp-toolchains-for-data-munging-amp-analysis>#</a> tools &amp; toolchains for data munging &amp; analysis</h1>
  1595. <h2><a name=tools-amp-toolchains-for-data-munging-amp-analysis-csvkit href=#tools-amp-toolchains-for-data-munging-amp-analysis-csvkit>#</a> csvkit</h2>
  1596. <p>This is super handy. Wish I&rsquo;d started using it sooner:</p>
  1597. <blockquote><p>csvkit is a suite of utilities for converting to and working with CSV, the
  1598. king of tabular file formats.</p>
  1599. <p>&hellip;</p>
  1600. <p>csvkit is to tabular data what the standard Unix text processing suite (grep,
  1601. sed, cut, sort) is to text. As such, csvkit adheres to the Unix philosophy.</p>
  1602. <ol>
  1603. <li>Small is beautiful.</li>
  1604. <li>Make each program do one thing well.</li>
  1605. <li>Build a prototype as soon as possible.</li>
  1606. <li>Choose portability over efficiency.</li>
  1607. <li>Store data in flat text files.</li>
  1608. <li>Use software leverage to your advantage.</li>
  1609. <li>Use shell scripts to increase leverage and portability.</li>
  1610. <li>Avoid captive user interfaces.</li>
  1611. <li>Make every program a filter.</li>
  1612. </ol>
  1613. </blockquote>
  1614. <p>&ndash; <a href="https://csvkit.readthedocs.org/en/0.9.0">csvkit 0.9.0</a></p>
  1615. <h2><a name=tools-amp-toolchains-for-data-munging-amp-analysis-jq href=#tools-amp-toolchains-for-data-munging-amp-analysis-jq>#</a> jq</h2>
  1616. <p>Also super handy, if a notch less intuitive. Powerful DSL / pretty-printer /
  1617. filter for working with JSON records at the command line.</p>
  1618. <ul>
  1619. <li><a href="http://stedolan.github.io/jq/">http://stedolan.github.io/jq/</a></li>
  1620. </ul>
  1621. </article>
  1622. <article>
  1623. <h1><a name=systemd-notes href=#systemd-notes>#</a> systemd notes</h1>
  1624. <ul>
  1625. <li><a href="https://letsgettechnicalblog.wordpress.com/2014/07/07/systemd-on-raspbian/">https://letsgettechnicalblog.wordpress.com/2014/07/07/systemd-on-raspbian/</a></li>
  1626. </ul>
  1627. </article>
  1628. <script>
  1629. $(document).ready(function () {
  1630. // ☜ ☝ ☞ ☟ ☆ ✠ ✡ ✢ ✣ ✤ ✥ ✦ ✧ ✩ ✪
  1631. var closed_sigil = 'show';
  1632. var open_sigil = 'hide';
  1633. var togglesigil = function (elem) {
  1634. var sigil = $(elem).html();
  1635. if (sigil === closed_sigil) {
  1636. $(elem).html(open_sigil);
  1637. } else {
  1638. $(elem).html(closed_sigil);
  1639. }
  1640. };
  1641. $(".details").each(function () {
  1642. var $this = $(this);
  1643. var $button = $('<button class=clicker-button>' + open_sigil + '</button>');
  1644. var $details_full = $(this).find('.full');
  1645. $button.click(function (e) {
  1646. e.preventDefault();
  1647. $details_full.toggle({
  1648. duration: 550
  1649. });
  1650. togglesigil(this);
  1651. });
  1652. $(this).find('.clicker').append($button);
  1653. $button.show();
  1654. });
  1655. // $('.details .full').hide();
  1656. });
  1657. </script>
  1658. </body>
  1659. </html>