<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" media="screen" href="/css/notes.css" ?>
<?xml-stylesheet type="text/css" media="screen" href="/css/feed.a7f4a028203ca4d72034f6ffc7c457af43614e850c423c883f89477b469167c8.css" ?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <link href="https://hacker.klever.net/" rel="alternate" type="text/html" title="digressions from meandering" />

  <link href="https://hacker.klever.net/atom.xml " rel="self" type="application/atom+xml" title="digressions from meandering" />
  <id>https://hacker.klever.net/atom.xml</id>

  <title>digressions from meandering</title>
  <author>
    <name>Michael Krelin</name>
  </author>
  <updated>2012-12-11T22:18:24Z</updated>
    <entry>
      <id>https://hacker.klever.net/n/2012/12/11/pumpkin-goes-osx/</id>
      <link rel="alternate"  href="https://hacker.klever.net/n/2012/12/11/pumpkin-goes-osx/" />
      <updated>2012-12-11T22:18:24Z</updated>
      <published>2012-12-11T22:18:24Z</published>
      <title>PumpKIN goes OSX</title>
      <content type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml"><p>I&rsquo;ve done a lot of windows programming when I was using the system. I&rsquo;ve been
creating things I needed back then. Then I moved to use mostly (and then almost
exclusively) linux and continued creating things I needed there. I still use
linux a lot, of course, but I&rsquo;ve also added another system to my everyday life
(which, I must admit, I like) — Mac OS X.</p>
<p>I have to admit, there&rsquo;s no particular need in <em>TFTP</em> server and client on OS X,
since it has command line tools for these needs, but still sometimes it is more
convenient to fire up a nice GUI, especially when it comes to the server.</p>
<p>Anyway, to expand my horizons, learn a bit about the platform I use, dig a bit
deeper into Objective-C, etc. I have ported the well-known
<a href="https://kin.klever.net/pumpkin/">PumpKIN</a> <em>TFTP</em> daemon to Mac. (Icons were the
hardest part).</p>
<p>This is the very <code>0.0</code> version, but it seems to work. And feedback is
appreciated if anyone cares to try.</p>
<p style="font-weight: bold; text-indent: 0px;">Love,<br/><a href="https://hacker.klever.net/">H</a></p></div>
      </content>
    </entry>
    <entry>
      <id>https://hacker.klever.net/n/2012/11/11/just-say-it/</id>
      <link rel="alternate"  href="https://hacker.klever.net/n/2012/11/11/just-say-it/" />
      <updated>2012-10-26T21:40:13Z</updated>
      <published>2012-11-11T15:34:01Z</published>
      <title>Что делает кот, когда ему делать нечего?</title>
      <content type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml"><script src="//hacker.klever.net/script/verbalizer.js?4" type="text/javascript"> </script>
<script type="text/javascript">//<![CDATA[
 var VV=(function(){
  var $fa = { g:'f', a:0, s:{n:'-а',g:'-ы',d:'-е',a:'-у',i:'-ой',p:'-е'}, p:{n:'-ы',g:'-',d:'-ам',a:'-ы',i:'-ами',p:'-ах'} };
  var $fb = { g:'f', a:1, s:{n:'-ь',g:'-и',d:'-и',a:'-ь',i:'-ью',p:'-и'}, p:{n:'-и',g:'-ей',d:'-ям',a:'-и',i:'-ями',p:'-ях'} };
  var $ma = { g:'m', a:1, s:{n:'-',g:'-а',d:'-у',a:'-а',i:'-ом',p:'-е'}, p:{n:'-ы',g:'-ов',d:'-ам',a:'-ов',i:'-ами',p:'-ах'} };
  var subjects = V.P([
   { _:'бобрыльд', $:$fa },
   { _:'стерляд', $:$fb },
   { _:'балясин', $:$fa },
   { _:'пилястр', $:$fa },
   { _:'пиляд', $:$fb },
   { _:'куздр', $:$fa, a:1, p:{a:'-'} },
   { _:'бричмулл', $:$fa, s:{i:'-ою'} },
   { _:'бокр', $:$ma },
   { _:'плим', $:$ma, a:0, s:{a:'-'}, p:{a:'-ы'} },
   { _:'кукарямб', $:$fa },
   { s:{n:'бяка-закаляка',g:'бяки-закаляки',d:'бяке-закаляке',a:'бяку-закаляку',i:'бякой-закалякой',p:'бяке-закаляке'},
     p:{n:'бяки-закаляки',g:'бяк-закаляк',d:'бякам-закалякам',a:'бяк-закаляк',i:'бяками-закаляками',p:'бяках-закаляках'}, g:'f',a:true },
   { _:'клизмотрон', $:$ma, a:0, s:{a:'-'}, p:{a:'-ы'} },
   { _:'слонопотам', $:$ma },
   { g:'f', a:0, _:'мухлопендри',
     s:{n:'-я',g:'-и',d:'-и',a:'-ю',i:'-ей',p:'-и'}, p:{n:'-и',g:'-й',d:'-ям',a:'-и',i:'-ями',p:'-ях'} }
  ]);
  var cases = {
   n:{n:'именительном',t:'Полюбуйтесь — <em>%</em>.'},
   g:{n:'родительном',t:'В отсутствие <em>%</em> изюм, цукерброт и пастила манкируют своими обязанностями.'},
   d:{n:'дательном',t:'Уделите внимание <em>%</em>, пожалуйста.'},
   a:{n:'винительном',t:'Посмотрите на <em>%</em>!'},
   i:{n:'творительном',t:'Разве вы не гордитесь <em>%</em>?!'},
   p:{n:'предложном',t:'Кстати о <em>%</em>…'}
  };
  var F, O;

  function update() {
   try {
    O.innerHTML = cases[F.c.value].t.replace('%',V.something(F.n.value.replace(/[^0-9]/,''),subjects[F.s.value],F.c.value,true));
    try { _gaq.push(['_trackEvent','verbalize','update']); }catch(e) { }
   }catch(e) { console.log(e); }
  }
  function randomize() {
  try { _gaq.push(['_trackEvent','verbalize','randomize']); }catch(e) { }
   F.s.value=Math.floor(Math.random()*subjects.length);
   var n='';
   for(var i=0;i<30 && Math.random()*30>i;++i) n+=Math.floor(n?Math.random()*10:(1+Math.random()*9)).toString();
   F.n.value=n;
   F.c.value='ngdaip'.charAt(Math.random()*6);
   update();
  }

  return {
   update: update,
   randomize: randomize,
   load: function() {
try {
    F = document.getElementById('verbalizer_form');
    O = document.getElementById('verbalizer_output');
    for(var i=0;i<subjects.length;++i) F.s.options.add(new Option(subjects[i].s.n,i));
    for(var i in cases) F.c.options.add(new Option(cases[i].n,i));
    randomize();
}catch(e) { }
   }
  };
 })();
 if(document.addEventListener)
  document.addEventListener('DOMContentLoaded',VV.load);
 else
  document.attachEvent('onreadystatechange',VV.load);
//]]></script>
<p>Склоняя на все лады разнообразные числительные к сожительству с разнообразными
существительными во всевозможных падежах, я решил что человечество вправе об
этом знать, а то и присоединиться. А то и сказать мне как я обосшибся.</p>
   <form id="verbalizer_form" onsubmit="return VV.update(),false;" style="margin: 1em 4em; padding: 1ex; border: dashed 1px fray;">
    <button style="width: 100%; height: 3em; margin-bottom: 1em" onclick="return VV.randomize(),true">А шо попало!</button>
    Герой дня —
    <select name="s" onchange="return VV.update(),true"></select>,
    числом <input name="n" maxlength="30" text="" onchange="return VV.update(),true" onkeyup="return VV.update(),true" />, в
    <select name="c" onchange="return VV.update(),true"></select>
    падеже:
    <div id="verbalizer_output" style="margin: 2em; padding: 1em; background: #fffff0; font-family: serif; font-size: 110%; border: solid 1px gray"> </div>
   </form>
<p>Ежели кому-то хочется или нужно повторить подвиг, то этот кто-то, будучи не
ленивым, может даже стырить код, это не трудно.</p>
</div>
      </content>
    </entry>
    <entry>
      <id>https://hacker.klever.net/n/2012/10/26/git-for-configuration-files-tracking/</id>
      <link rel="alternate"  href="https://hacker.klever.net/n/2012/10/26/git-for-configuration-files-tracking/" />
      <updated>2016-08-01T12:10:48Z</updated>
      <published>2012-10-26T21:13:22Z</published>
      <title>git for configuration files tracking</title>
      <content type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml"><p>There are some things that are awfully out of fashion, that I still do. One of
those things is maintaining server with its own configuration — personality, if
you please. As opposed to maintaining the army of 125000 identical machines
(yes, right, the same goes for humans).</p>
<p>That definitely doesn&rsquo;t take any enterprise grade configuration management
system unless done in corporate environment, due to the lack of managers to keep
confused. For tracking configuration files one can get away with widely
available tools while nobody sees. In particular, I like putting files in
<code>git</code> repository.</p>
<p>So I thought I&rsquo;d put some snippets here for future reference and copy pasting.</p>
<p>First thing is add a nice alias for the root user (that guy who is in charge of
breaking configuration):</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>alias cfgit<span style="color:#f92672">=</span><span style="color:#e6db74">&#39;git --git-dir=/var/cfgit --work-tree=/&#39;</span>
</span></span></code></pre></div><p>Or even</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>eval <span style="color:#66d9ef">$(</span>echo <span style="color:#e6db74">&#34;alias cfgit=&#39;git --git-dir=/var/cfgit --work-tree=/&#39;&#34;</span> | tee -a /root/.bash_aliases<span style="color:#66d9ef">)</span>
</span></span></code></pre></div><p>(depending on the distribution). Then initialize and configure the <code>/var/cfgit</code>
repository:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>git init --bare --shared<span style="color:#f92672">=</span><span style="color:#ae81ff">0600</span> /var/cfgit
</span></span><span style="display:flex;"><span>cfgit config core.logallrefupdates true
</span></span><span style="display:flex;"><span>cfgit config user.name root@<span style="color:#66d9ef">$(</span>hostname<span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span>cfgit config user.email root@klever.net
</span></span><span style="display:flex;"><span>echo /<span style="color:#ae81ff">\*</span> &gt;/var/cfgit/info/exclude
</span></span></code></pre></div><p>Done. Now one can add files to track before breaking the system.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>cfgit add -f /etc/tobebroken/
</span></span><span style="display:flex;"><span>cfgit commit -m <span style="color:#e6db74">&#39;stock tobebroken package configs&#39;</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>cfgit add -f /usr/local/bin/mygreatscript
</span></span><span style="display:flex;"><span>cfgit commit -m <span style="color:#e6db74">&#39;my great script before I broke it&#39;</span>
</span></span></code></pre></div><p>and so forth…</p>
</div>
      </content>
    </entry>
    <entry>
      <id>https://hacker.klever.net/n/2012/08/11/consolidating-iphoto-library-with-disrespectful-sql-hacking/</id>
      <link rel="alternate"  href="https://hacker.klever.net/n/2012/08/11/consolidating-iphoto-library-with-disrespectful-sql-hacking/" />
      <updated>2012-08-11T20:37:52Z</updated>
      <published>2012-08-11T20:37:52Z</published>
      <title>consolidating iPhoto library with disrespectful SQL hacking</title>
      <content type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml"><p>Don&rsquo;t. Really. Unless you understand it.</p>
<p>I had an iPhoto library of some 30K pictures — some managed, some referenced and
I wanted to consolidate the library — that is to copy the originals (a.k.a.
masters) to the iPhoto Library for those photos that were copied with the
appropriate preference off. Searching the web, looking at tools seemed to be of
no help, so this is where I had to dig into iPhoto library guts and see if I can
do it on my own.</p>
<p>It didn&rsquo;t take long to find that the <code>Database/apdb/Library.apdb</code> file and its
<code>RKMaster</code> table have the information in question. Thank you, Apple, for
adopting the sane standard for the databases, BTW. So, all I had to do is to
copy files to the <code>Masters</code> directory (the subdirectory structure there is
pretty straightforward — <code>%Y/%m/%d/%Y%m%d-%H%M%S</code> in terms of strftime) and
update the database.</p>
<p>The shell script follows (note, that I used the script on linux, where the
network storage resides, it may not be compatible with other environments out of
the box). What makes it a bit longer than one might expect from the description
above is that it puts no more than 2000 files in one directory.</p>
<pre class="quotedcode">
#!/bin/bash
ipl="<b>/path/to/your/iPhoto Library.photolibrary</b>"
fvuuid="<b>the-uuid-of-the-volume</b>"
fvpath="<b>/path/to/the/volume/on/disk</b>"

dryrun="<b>echo</b>"
cpln="<b>ln</b>"

lf="/tmp/masterslist.$$"
trap "rm $lf" EXIT
sqlite3 "$ldb" "SELECT modelId,imagePath,originalFileName FROM RKMaster WHERE fileIsReference and fileVolumeUuid='$fvuuid'" &gt;$lf \
|| { echo "Couldn't fetch the list of images" ; exit 1 ; }
while IFS=\| read mid ip ofn ; do
 [[ -r "$fvpath/$ip" ]] || { echo "$fvpath/$ip not found" ; continue; }
 [[ -n "$idir" &amp;&amp; -e "$mpath/$idir/$ofn" ]] &amp;&amp; idir=''
 [[ -z "$idir" || "$((++nf))" -ge 2000 ]] &amp;&amp; { sleep $(((nf=0)+1)) ; idir="$(date +%Y/%m/%d/%Y%m%d-%H%M%S)" ; $dryrun mkdir -p "$mpath/$idir" ; }
 $dryrun $cpln -v "$fvpath/$ip" "$mpath/$idir/$ofn" || { echo "failed to $cpln $fvpath/$ip to $mpath/$idir/$ofn" ; exit 1; }
 $dryrun sqlite3 "$ldb" "UPDATE RKMaster SET fileVolumeUuid=NULL, fileIsReference=0, imagePath='$idir/$ofn' WHERE modelId=$mid" \
 || { echo "failed to update database to reflect copy of $fvpath/$ip to $mpath/$idir/$ofn" ; exit 1; }
done &lt;$lf
</pre>
<p>Bold parts are the parameters to be modified. To get the uuid of the source
volume one needs to peek into the database. It&rsquo;s the second column of the
<code>sqlite3 Database/apdb/Library.apdb &quot;SELECT * FROM RKVolume&quot;</code> output.</p>
<p>And again. If you don&rsquo;t understand, don&rsquo;t do it. At any rate, backup what is there to backup. And don&rsquo;t hold it against me if you fail.</p>
</div>
      </content>
    </entry>
    <entry>
      <id>https://hacker.klever.net/n/2012/01/21/triple-i-goes-0-3/</id>
      <link rel="alternate"  href="https://hacker.klever.net/n/2012/01/21/triple-i-goes-0-3/" />
      <updated>2012-01-21T16:46:59Z</updated>
      <published>2012-01-21T16:46:59Z</published>
      <title>triple i goes 0.3</title>
      <content type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml"><p>Not really a breakthrough, but the amount of small changes justifies a release.
The new <a href="https://kin.klever.net/iii/">iii</a> now consumes less memory when
calculating integrity digest, accepts all files the card is willing to send and
complains better when being wronged (the latter is only important if you haven&rsquo;t
got it to work yet).</p>
<p style="font-weight: bold; text-indent: 0px;">Love,<br/><a href="https://hacker.klever.net/">H</a></p></div>
      </content>
    </entry>
</feed>

