An explorer's loghttp://nakkaya.comRandom bits and pieces on stuff that I find interesting.Bare Metal Lisp - RC Control using Ferrethttp://nakkaya.com/2017/02/15/bare-metal-lisp-rc-control-using-ferret/Wed, 15 Feb 2017 00:00:00 +0200<p> Some sample code to demonstrate FFI capabilities of Ferret on embedded systems. Ferret is a free software Clojure implementation, it compiles a restricted subset of the Clojure language to self contained ISO C++11 which allows for the use of Clojure in real time embedded control systems. See <a href="http://ferret-lang.org">Project Home Page</a>. Mobile platform used in this post is a <a href="https://www.pololu.com/product/2506">Zumo Robot</a> (required <a href="https://github.com/pololu/zumo-shield">third party libraries</a>) and the microcontroller is a Arduino Uno / Atmega328. </p> <p> <img width="60%" src="/images/post/bare-metal-lisp-rc-control-using-ferret.jpg" /> </p> <div class="org-src-container"> <pre class="src src-clojure" id="header">(configure-ferret! <span style="font-weight: bold; text-decoration: underline;">:command</span> <span style="color: #afafff; font-style: italic;">"mv ferret-rc-control.cpp ferret-rc-control.ino"</span>) </pre> </div> <p> Ferret outputs a <i>cpp</i> file however Arduino IDE expects a <i>ino</i> file. We override build command to rename the <i>cpp</i> file to a <i>ino</i> file. </p> <div class="org-src-container"> <pre class="src src-clojure" id="header">(configure-runtime! <span style="font-weight: bold; text-decoration: underline;">FERRET_MEMORY_POOL_SIZE</span> 1024) </pre> </div> <p> On embedded systems Ferret can be configured to avoid calling malloc/free. Enabling memory pooling will allocate (1 kb in this case) memory to be used as heap. </p> <p> Ferret's FFI is modeled after Gambit scheme. Whereas Gambit scheme lets you embed C into Scheme, Ferret lets you embed C or C++ into Clojure. </p> <div class="org-src-container"> <pre class="src src-clojure" id="ffi">(native-header <span style="color: #afafff; font-style: italic;">"ZumoMotors.h"</span>) (<span style="color: #ff5f00; font-weight: bold;">defn</span> <span style="color: #d7af00; font-weight: bold;">new-motor</span> [] <span style="color: #afafff; font-style: italic;">"__result = obj&lt;value&lt;ZumoMotors&gt;&gt;();"</span>) </pre> </div> <p> A <i>value</i> object is useful when dealing with C++ objects. It acts as a container for native object. It can wrap any type <i>T</i>, once wrapped it can be used just like any other Ferret variable. (Any arguments passed to <i>obj</i> will be forwarded to <i>T</i> constructor.) </p> <div class="org-src-container"> <pre class="src src-clojure" id="ffi">(<span style="color: #ff5f00; font-weight: bold;">defn</span> <span style="color: #d7af00; font-weight: bold;">speeds</span> [m s1 s2] <span style="color: #afafff; font-style: italic;">"ZumoMotors motor = value&lt;ZumoMotors&gt;::to_value(m);</span> <span style="color: #afafff; font-style: italic;"> motor.setSpeeds(number::to&lt;int&gt;(s1), number::to&lt;int&gt;(s2));"</span>) (<span style="color: #ff5f00; font-weight: bold;">defn</span> <span style="color: #d7af00; font-weight: bold;">pulse-in</span> [pin] <span style="color: #afafff; font-style: italic;">"__result = obj&lt;number&gt;(pulseIn(number::to&lt;int&gt;(pin), HIGH,25000));"</span>) </pre> </div> <p> Calling C++ functions with Ferret variables is just as easy, every Ferret object type has a corresponding <i>to</i> / <i>from</i> function/s. These can be used to convert native types to ferret types and vice versa. (Ferret is a strongly, dynamically typed language. If you try to convert a ferret number to a value you will get a segmentation fault.) </p> <div class="org-src-container"> <pre class="src src-clojure" id="control"><span style="color: #008787; font-weight: bold; font-style: italic;">;; </span><span style="color: #008787; font-weight: bold; font-style: italic;">throttle - ch 1</span> <span style="color: #008787; font-weight: bold; font-style: italic;">;; </span><span style="color: #008787; font-weight: bold; font-style: italic;">steering - ch 2</span> (<span style="color: #ff5f00; font-weight: bold;">defn</span> <span style="color: #d7af00; font-weight: bold;">read-control</span> [] (<span style="color: #ff5f00; font-weight: bold;">let</span> [throttle (scale (pulse-in 4) 981 1998 0 254) steering (scale (pulse-in 5) 981 1998 -254 254)] (list (<span style="color: #ff5f00; font-weight: bold;">if</span> (&lt; throttle 5) <span style="color: #008787; font-weight: bold; font-style: italic;">;; </span><span style="color: #008787; font-weight: bold; font-style: italic;">setup dead zone</span> 0 throttle) (<span style="color: #ff5f00; font-weight: bold;">if</span> (&lt; -5 steering 5) <span style="color: #008787; font-weight: bold; font-style: italic;">;; </span><span style="color: #008787; font-weight: bold; font-style: italic;">setup dead zone</span> 0 steering)))) (<span style="color: #ff5f00; font-weight: bold;">let</span> [motor (new-motor)] (forever (<span style="color: #ff5f00; font-weight: bold;">let</span> [[throttle steering] (read-control)] (speeds motor (+ throttle steering) (- throttle steering))))) </pre> </div> <p> Radio-control transmitters and receivers are used to drive model cars or planes. They typically have a bunch of control surfaces like joysticks. Each degree of freedom that the controller gives is assigned a channel. They are typically used to control servos so each channel outputs a signal called PWM (Pulse Width Modulation). i.e Width of the signal changes as control input changes. Arduino platform has a function called <i>pulseIn</i> which we wrapped in a Ferret function that returns the length of the pulse, this pulse is then converted to a PWM value which is used to drive the motors on the robot. </p> <p> Forward motion is controlled by mapping the current pulse width on channel 1 to a value between 0 and 254. No throttle 0 PWM full throttle 254 PWM. Steering is controlled in a similar manner but instead of mapping from 0 to 254 it is mapped to -254 to 254. Final motor speed is calculated by adding throttle and steering controls together and apply the resulting PWM to motors. </p> Ferret - A Hard Real-Time Clojure for Lisp Machineshttp://nakkaya.com/2016/06/10/ferret-a-hard-real-time-clojure-for-lisp-machines/Fri, 10 Jun 2016 00:00:00 +0300<p> Ferret is a free software Clojure implementation, it compiles a restricted subset of the Clojure language to self contained ISO C++11 which allows for the use of Clojure in real time embedded control systems. It has been verified to run on architectures ranging from embedded systems with as little as 2KB of RAM to general purpose computers running Linux/Mac OS X/Windows. </p> <ul class="org-ul"> <li><a href="http://ferret-lang.org">Project Home Page</a> </li> <li><a href="http://ferret-lang.org/builds/ferret">Executable</a> (Requires Bash and JVM) </li> <li><a href="http://ferret-lang.org/builds/ferret.jar">Standalone Jar</a> (Requires JVM) </li> </ul> <p> Unlike other Lisp implementations Ferret is specifically tailored for real time control applications, provides deterministic execution and gives you total control on memory management. (Achilles heel of high level languages for hard real time control). Ferret programs when running on embedded systems or in single threaded mode can be configured to run using a memory pool. This avoids calling malloc/heap at runtime, improves performance and determinism, you can also tell how much memory will be used at compile time. </p> <p> Starting with a simple example, following shows a simple Arduino Due example to generate a Sawtooth wave, </p> <p><center><img src="/images/post/ferret-saw-tooth.jpg" alt="Ferret Real Time Lisp Saw Tooth Wave" width="500" /></center></p> <div class="org-src-container"> <pre class="src src-clojure"><span style="color: #008787; font-weight: bold; font-style: italic;">;; </span><span style="color: #008787; font-weight: bold; font-style: italic;">saw.clj</span> (configure-runtime! <span style="font-weight: bold; text-decoration: underline;">FERRET_DISABLE_STD_OUT</span> <span style="font-weight: bold; text-decoration: underline;">true</span> <span style="color: #008787; font-weight: bold; font-style: italic;">;; </span><span style="color: #008787; font-weight: bold; font-style: italic;">Disable Serial</span> <span style="font-weight: bold; text-decoration: underline;">FERRET_PROGRAM_MAIN</span> <span style="color: #afafff; font-style: italic;">"signal()"</span> <span style="color: #008787; font-weight: bold; font-style: italic;">;; </span><span style="color: #008787; font-weight: bold; font-style: italic;">Main Entry for the application</span> <span style="color: #008787; font-weight: bold; font-style: italic;">;; </span><span style="color: #008787; font-weight: bold; font-style: italic;">Ferret functions are C++ functors</span> <span style="font-weight: bold; text-decoration: underline;">FERRET_MEMORY_POOL_SIZE</span> 512) <span style="color: #008787; font-weight: bold; font-style: italic;">;; </span><span style="color: #008787; font-weight: bold; font-style: italic;">Allocate 512 Bytes of static memory</span> (<span style="color: #ff5f00; font-weight: bold;">defn</span> <span style="color: #d7af00; font-weight: bold;">dac-1</span> [] <span style="color: #afafff; font-style: italic;">"__result = obj&lt;number&gt;(DAC1);"</span>) (<span style="color: #ff5f00; font-weight: bold;">defn</span> <span style="color: #d7af00; font-weight: bold;">signal</span> [] (<span style="color: #ff5f00; font-weight: bold;">doseq</span> [sample (range 255)] (analog-write (dac-1) sample) (sleep 10))) </pre> </div> <p> All functions mimic their Clojure counterparts the only thing that's different from Clojure is the <b>dac-1</b> function. A function with just a string in its body is assumed to be a FFI call and the string is assumed to be native statement/s. In this case <b>dac-1</b> function when called returns the value of <b>DAC1</b>. (Pin number of digital analog converter on Due.) In order to run the example on hardware just compile it using Ferret, </p> <pre class="example"> $ mkdir saw $ ./ferret -i saw.clj $ mv saw.cpp saw.ino </pre> <p> then upload as usual. Best way to experiment with Arduino and Ferret is to set the Arduino IDE to use an external editor in preferences and add the following to you Ferret program, (Overrides the compile command with <b>mv</b> by default Ferret uses <b>g++</b> or the value of <b>CXX</b> environment variable to compile the generated code into binary.) </p> <div class="org-src-container"> <pre class="src src-clojure">(configure-ferret! <span style="font-weight: bold; text-decoration: underline;">:command</span> <span style="color: #afafff; font-style: italic;">"mv saw.cpp saw.ino"</span>) </pre> </div> <p> then you can just run, </p> <pre class="example"> $ ./ferret -i saw.clj -c </pre> <p> Arduino IDE will pick up changes automatically when you hit upload. Moving on to a more complicated example, a line following robot, following shows the built in primitives of Ferret for control (State Machines, PID Controller) and interfacing with third party C++ libraries using an Arduino Due and a <a href="https://www.pololu.com/product/2510">Zumo</a> robot platform. </p> <p><center><img src="/images/post/ferret-line-follower.gif" alt="Ferret Real Time Lisp Line Follower" width="750" /></center></p> <div class="org-src-container"> <pre class="src src-clojure">(configure-runtime! <span style="font-weight: bold; text-decoration: underline;">FERRET_DISABLE_STD_OUT</span> <span style="font-weight: bold; text-decoration: underline;">true</span> <span style="color: #008787; font-weight: bold; font-style: italic;">;;</span><span style="color: #008787; font-weight: bold; font-style: italic;">save memory</span> <span style="font-weight: bold; text-decoration: underline;">FERRET_PROGRAM_MAIN</span> program <span style="color: #008787; font-weight: bold; font-style: italic;">;; </span><span style="color: #008787; font-weight: bold; font-style: italic;">Default function to run.</span> <span style="font-weight: bold; text-decoration: underline;">FERRET_MEMORY_POOL_SIZE</span> 1024) <span style="color: #008787; font-weight: bold; font-style: italic;">;; </span><span style="color: #008787; font-weight: bold; font-style: italic;">Allocate 1kb Heap</span> <span style="color: #008787; font-weight: bold; font-style: italic;">;; </span><span style="color: #008787; font-weight: bold; font-style: italic;">Inlucde Third Party Headers</span> <span style="color: #008787; font-weight: bold; font-style: italic;">;; </span><span style="color: #008787; font-weight: bold; font-style: italic;">https://github.com/pololu/zumo-shield</span> (native-header <span style="color: #afafff; font-style: italic;">"QTRSensors.h"</span> <span style="color: #afafff; font-style: italic;">"ZumoReflectanceSensorArray.h"</span> <span style="color: #afafff; font-style: italic;">"ZumoMotors.h"</span> <span style="color: #afafff; font-style: italic;">"Pushbutton.h"</span>) <span style="color: #008787; font-weight: bold; font-style: italic;">;; </span><span style="color: #008787; font-weight: bold; font-style: italic;">Initialize Hardware</span> (native-declare <span style="color: #afafff; font-style: italic;">"unsigned int line_buffer[6];</span> <span style="color: #afafff; font-style: italic;"> ZumoReflectanceSensorArray line_sensors;</span> <span style="color: #afafff; font-style: italic;"> ZumoMotors zumo_motors;</span> <span style="color: #afafff; font-style: italic;"> Pushbutton button(ZUMO_BUTTON);"</span>) (<span style="color: #ff5f00; font-weight: bold;">defn</span> <span style="color: #d7af00; font-weight: bold;">wait-button</span> [] <span style="color: #afafff; font-style: italic;">"button.waitForButton();</span> <span style="color: #afafff; font-style: italic;"> button.waitForRelease();</span> <span style="color: #afafff; font-style: italic;"> __result = obj&lt;boolean&gt;(true)"</span>) (<span style="color: #ff5f00; font-weight: bold;">defn</span> <span style="color: #d7af00; font-weight: bold;">button-pressed?</span> [] <span style="color: #afafff; font-style: italic;">"__result = obj&lt;boolean&gt;(button.isPressed())"</span>) (<span style="color: #ff5f00; font-weight: bold;">defn</span> <span style="color: #d7af00; font-weight: bold;">motors</span> ([] <span style="color: #afafff; font-style: italic;">"zumo_motors.setSpeeds(0,0);"</span>) ([c] <span style="color: #afafff; font-style: italic;">"int corr = number::to&lt;int&gt;(c);</span> <span style="color: #afafff; font-style: italic;"> zumo_motors.setSpeeds(400 + (-1 * corr), 400 + corr);"</span>) ([m1 m2] <span style="color: #afafff; font-style: italic;">"zumo_motors.setSpeeds(number::to&lt;int&gt;(m1), number::to&lt;int&gt;(m2));"</span>)) (<span style="color: #ff5f00; font-weight: bold;">defn</span> <span style="color: #d7af00; font-weight: bold;">read-line</span> [] <span style="color: #afafff; font-style: italic;">"__result = obj&lt;number&gt;(line_sensors.readLine(line_buffer,QTR_EMITTERS_ON,1));"</span>) </pre> </div> <p> Wrappers for Zumo Libraries needed to interface with the shield. All follow the same FFI convention explained in the first example. </p> <div class="org-src-container"> <pre class="src src-clojure">(<span style="color: #ff5f00; font-weight: bold;">defn</span> <span style="color: #d7af00; font-weight: bold;">calibrate</span> [] (cxx <span style="color: #afafff; font-style: italic;">"line_sensors.init();"</span>) (sleep 1000) (<span style="color: #ff5f00; font-weight: bold;">dotimes</span> [i 80] (<span style="color: #ff5f00; font-weight: bold;">if</span> (<span style="color: #ff5f00; font-weight: bold;">or</span> (<span style="color: #ff5f00; font-weight: bold;">and</span> (&gt; i 10) (&lt;= i 30)) (<span style="color: #ff5f00; font-weight: bold;">and</span> (&gt; i 50) (&lt;= i 70))) (motors -200 200) (motors 200 -200)) (cxx <span style="color: #afafff; font-style: italic;">"line_sensors.calibrate();"</span>) (sleep 20)) (motors)) </pre> </div> <p> <b>calibrate</b> function is run when the robots boots up and used to calibrate the Pololu QTR Reflectance Sensors on the shield. <b>cxx</b> macro is a convenience macro for calling native code in place. It will define a <b>fn</b> and call it in place so, </p> <div class="org-src-container"> <pre class="src src-clojure"></pre> </div> <p> is equivalent to, </p> <div class="org-src-container"> <pre class="src src-clojure">((<span style="color: #ff5f00; font-weight: bold;">fn</span> [] <span style="color: #afafff; font-style: italic;">"line_sensors.init();"</span>)) </pre> </div> <p> Next we define a PID controller. It takes the result of <b>read-line</b>, a number between 0 to 5000 depending on the position of the line under the sensor and returns correction that we are going to feed in to <b>motors</b> function that will keep the sensor at position 2500 which means the line is in the middle of the robot. </p> <div class="org-src-container"> <pre class="src src-clojure">(<span style="color: #ff5f00; font-weight: bold;">def</span> <span style="font-weight: bold; font-style: italic;">motor-controller</span> (pid-controller <span style="font-weight: bold; text-decoration: underline;">:kp</span> 0.75 <span style="font-weight: bold; text-decoration: underline;">:ki</span> 0 <span style="font-weight: bold; text-decoration: underline;">:kd</span> 1 <span style="font-weight: bold; text-decoration: underline;">:set-point</span> 2500 <span style="font-weight: bold; text-decoration: underline;">:bounds</span> [0 5000 -400 400] <span style="font-weight: bold; text-decoration: underline;">:continuous</span> <span style="font-weight: bold; text-decoration: underline;">false</span>)) </pre> </div> <p> A state machine glues all of the above together. <b>state-machine</b> macro compiles a function, which when called will iterate through its transition states. </p> <div class="org-src-container"> <pre class="src src-clojure">(<span style="color: #ff5f00; font-weight: bold;">def</span> <span style="font-weight: bold; font-style: italic;">program</span> (state-machine (states (boot (motors) (pin-mode 53 <span style="font-weight: bold; text-decoration: underline;">:output</span>) (wait-button) (calibrate)) (follow-line (digital-write 53 1) (<span style="color: #ff5f00; font-weight: bold;">-&gt;&gt;</span> (read-line) (motor-controller) (motors)) (digital-write 53 0)) (stop (motors) (cxx <span style="color: #afafff; font-style: italic;">"button.waitForRelease();"</span>))) (transitions (boot wait-button follow-line) (follow-line button-pressed? stop) (stop wait-button follow-line)))) </pre> </div> <p> Robot starts at <b>boot</b> state, where we wait for the user to press a button to start calibrating the sensors, when done we wait for another button press to transition into <b>follow-line</b> state where we read the current position of the line and feed it to the PID controller and feed the controllers result to <b>motors</b> function. After each iteration of <b>follow-line</b> we check if the button is pressed when pressed we transition into <b>stop</b> state otherwise we keep executing <b>follow-line</b> state. In <b>stop</b> state we stop and wait for the user to press the button again to continue following the line. </p> <p> Pin 53 is used to produce to following oscilloscope output to show the jitter in the system. </p> <p><center><img src="/images/post/ferret-line-follower.jpg" alt="Ferret Real Time Lisp Line Follower" width="750" /></center></p> Static Galleria Scripthttp://nakkaya.com/2014/10/7/static-galleria-script/Tue, 7 Oct 2014 00:00:00 +0300<p> Following is a Clojure shell script that piggy backs on the <a href="http://nakkaya.com/static.html">static.jar</a> to create static image galleries using galleria and upload them to S3. </p> <p> Either tangle this file (it will tangle to ~/.bin/static-galleria) or copy/paste the snippets into a file on your path and make it executable, and update path to static.jar. This script depends on ImageMagick command line tools. </p> <pre class="example"> bash ~/.bin/static-galleria "Photo Folder" </pre> <p> See <a href="http://nakkaya.com/photos.html">Photos</a> page for example static galleries hosted on S3. </p> <div class="org-src-container"> <pre class="src src-sh" id="header"><span style="color: #008787; font-weight: bold; font-style: italic;">#</span><span style="color: #008787; font-weight: bold; font-style: italic;">^:shebang '[</span> <span style="color: #ff5f00; font-weight: bold;">exec</span> java -cp <span style="color: #afafff; font-style: italic;">"static-app.jar"</span> clojure.main <span style="color: #afafff; font-style: italic;">"$0"</span> -- <span style="color: #afafff; font-style: italic;">"$@"</span> ] </pre> </div> <div class="org-src-container"> <pre class="src src-clojure" id="script">(<span style="color: #ff5f00; font-weight: bold;">ns</span> <span style="font-weight: bold; text-decoration: underline;">album-builder</span> (<span style="font-weight: bold; text-decoration: underline;">:use</span> <span style="font-weight: bold; text-decoration: underline;">clojure.java.shell</span>) (<span style="font-weight: bold; text-decoration: underline;">:use</span> [static io core config])) (<span style="color: #ff5f00; font-weight: bold;">defn</span> <span style="color: #d7af00; font-weight: bold;">images</span> [in-dir] (<span style="color: #ff5f00; font-weight: bold;">-&gt;&gt;</span> (map #(<span style="font-weight: bold; text-decoration: underline;">java.io.File.</span> in-dir <span style="font-weight: bold; font-style: italic;">%</span>) (<span style="color: #afd700; font-weight: bold;">.list</span> in-dir)) (filter #(<span style="color: #ff5f00; font-weight: bold;">let</span> [ext (<span style="font-weight: bold; text-decoration: underline;">org.apache.commons.io.FilenameUtils</span>/<span style="color: #afd700; font-weight: bold;">getExtension</span> (<span style="color: #afd700; font-weight: bold;">.toString</span> <span style="font-weight: bold; font-style: italic;">%</span>))] (<span style="color: #ff5f00; font-weight: bold;">and</span> (<span style="color: #afd700; font-weight: bold;">.isFile</span> <span style="font-weight: bold; font-style: italic;">%</span>) (contains? #{<span style="color: #afafff; font-style: italic;">"JPG"</span> <span style="color: #afafff; font-style: italic;">"jpg"</span> <span style="color: #afafff; font-style: italic;">"JPEG"</span> <span style="color: #afafff; font-style: italic;">"jpeg"</span> <span style="color: #afafff; font-style: italic;">"png"</span> <span style="color: #afafff; font-style: italic;">"gif"</span>} ext)))))) (<span style="color: #ff5f00; font-weight: bold;">defn</span> <span style="color: #d7af00; font-weight: bold;">prep-images</span> [in-dir out-dir] (println <span style="color: #afafff; font-style: italic;">"Prepping Images"</span>) (<span style="color: #ff5f00; font-weight: bold;">doall</span> (pmap (<span style="color: #ff5f00; font-weight: bold;">fn</span> [f] (<span style="font-weight: bold; text-decoration: underline;">org.apache.commons.io.FileUtils</span>/<span style="color: #afd700; font-weight: bold;">copyFileToDirectory</span> f out-dir) <span style="color: #008787; font-weight: bold; font-style: italic;">;;</span><span style="color: #008787; font-weight: bold; font-style: italic;">fix orientation</span> (<span style="color: #ff5f00; font-weight: bold;">let</span> [file (str out-dir <span style="color: #afafff; font-style: italic;">"/"</span> (<span style="color: #ff5f00; font-weight: bold;">-&gt;&gt;</span> (<span style="color: #afd700; font-weight: bold;">.toString</span> f) (<span style="font-weight: bold; text-decoration: underline;">org.apache.commons.io.FilenameUtils</span>/<span style="color: #afd700; font-weight: bold;">getName</span>)))] (<span style="font-weight: bold; text-decoration: underline;">clojure.java.shell</span>/sh <span style="color: #afafff; font-style: italic;">"convert"</span> <span style="color: #afafff; font-style: italic;">"-auto-orient"</span> file file))) (images in-dir))) <span style="color: #008787; font-weight: bold; font-style: italic;">;;</span><span style="color: #008787; font-weight: bold; font-style: italic;">scale originals</span> (sh <span style="color: #afafff; font-style: italic;">"mogrify"</span> <span style="color: #afafff; font-style: italic;">"-geometry"</span> <span style="color: #afafff; font-style: italic;">"1024x"</span> (str out-dir <span style="color: #afafff; font-style: italic;">"/*"</span>)) <span style="color: #008787; font-weight: bold; font-style: italic;">;; </span><span style="color: #008787; font-weight: bold; font-style: italic;">generate thumbs</span> (sh <span style="color: #afafff; font-style: italic;">"mkdir"</span> (str out-dir <span style="color: #afafff; font-style: italic;">"/thumbs"</span>)) (sh <span style="color: #afafff; font-style: italic;">"mogrify"</span> <span style="color: #afafff; font-style: italic;">"-thumbnail"</span> <span style="color: #afafff; font-style: italic;">"256x"</span> <span style="color: #afafff; font-style: italic;">"-path"</span> (str (str out-dir <span style="color: #afafff; font-style: italic;">"/"</span>) <span style="color: #afafff; font-style: italic;">"thumbs"</span>) (str out-dir <span style="color: #afafff; font-style: italic;">"/*"</span>))) (<span style="color: #ff5f00; font-weight: bold;">defn</span> <span style="color: #d7af00; font-weight: bold;">galleria-img-json</span> [idx files] (str <span style="color: #afafff; font-style: italic;">"</span> <span style="color: #afafff; font-style: italic;"> var data"</span> idx <span style="color: #afafff; font-style: italic;">" = ["</span> (reduce (<span style="color: #ff5f00; font-weight: bold;">fn</span>[h v] (<span style="color: #ff5f00; font-weight: bold;">let</span> [name (<span style="color: #ff5f00; font-weight: bold;">-&gt;&gt;</span> (<span style="color: #afd700; font-weight: bold;">.toString</span> v) (<span style="font-weight: bold; text-decoration: underline;">org.apache.commons.io.FilenameUtils</span>/<span style="color: #afd700; font-weight: bold;">getName</span>) (str <span style="color: #afafff; font-style: italic;">"./"</span>)) thumb (<span style="color: #ff5f00; font-weight: bold;">-&gt;&gt;</span> (<span style="color: #afd700; font-weight: bold;">.toString</span> v) (<span style="font-weight: bold; text-decoration: underline;">org.apache.commons.io.FilenameUtils</span>/<span style="color: #afd700; font-weight: bold;">getName</span>) (str <span style="color: #afafff; font-style: italic;">"./thumbs/"</span>))] (str h <span style="color: #afafff; font-style: italic;">"{thumb: '"</span> thumb <span style="color: #afafff; font-style: italic;">"',"</span> <span style="color: #afafff; font-style: italic;">"image: '"</span> name <span style="color: #afafff; font-style: italic;">"',},"</span>))) <span style="color: #afafff; font-style: italic;">""</span> files) <span style="color: #afafff; font-style: italic;">"];"</span>)) (<span style="color: #ff5f00; font-weight: bold;">defn</span> <span style="color: #d7af00; font-weight: bold;">album-html</span> [name in-dir] (<span style="color: #ff5f00; font-weight: bold;">let</span> [images (partition 20 20 <span style="font-weight: bold; text-decoration: underline;">nil</span> (images in-dir))] (list [<span style="font-weight: bold; text-decoration: underline;">:script</span> (map-indexed (<span style="color: #ff5f00; font-weight: bold;">fn</span> [idx val] (galleria-img-json idx val)) images)] [<span style="font-weight: bold; text-decoration: underline;">:div</span> {<span style="font-weight: bold; text-decoration: underline;">:id</span> <span style="color: #afafff; font-style: italic;">"pagination"</span>}] [<span style="font-weight: bold; text-decoration: underline;">:div</span> {<span style="font-weight: bold; text-decoration: underline;">:id</span> <span style="color: #afafff; font-style: italic;">"galleria"</span>}] [<span style="font-weight: bold; text-decoration: underline;">:script</span> <span style="color: #afafff; font-style: italic;">"document.body.style.backgroundColor = \"#333\";</span> <span style="color: #afafff; font-style: italic;"> var gallery;</span> <span style="color: #afafff; font-style: italic;"> var currentPage = 0;</span> <span style="color: #afafff; font-style: italic;"> jQuery(window).load(function () {</span> <span style="color: #afafff; font-style: italic;"> var anchor = window.location.hash.substring(6);</span> <span style="color: #afafff; font-style: italic;"> if(anchor){</span> <span style="color: #afafff; font-style: italic;"> $(\"#pagination\").pagination('selectPage', parseInt(anchor));</span> <span style="color: #afafff; font-style: italic;"> }</span> <span style="color: #afafff; font-style: italic;"> });</span> <span style="color: #afafff; font-style: italic;"> $( document ).ready(function() {</span> <span style="color: #afafff; font-style: italic;"> $(function() {</span> <span style="color: #afafff; font-style: italic;"> if (\"onhashchange\" in window)</span> <span style="color: #afafff; font-style: italic;"> window.onhashchange = function () {</span> <span style="color: #afafff; font-style: italic;"> var anchor = window.location.hash.substring(6);</span> <span style="color: #afafff; font-style: italic;"> if(anchor)</span> <span style="color: #afafff; font-style: italic;"> $(\"#pagination\").pagination('selectPage', parseInt(anchor));</span> <span style="color: #afafff; font-style: italic;"> else</span> <span style="color: #afafff; font-style: italic;"> $(\"#pagination\").pagination('selectPage', 1);</span> <span style="color: #afafff; font-style: italic;"> }</span> <span style="color: #afafff; font-style: italic;"> $(\"#pagination\").pagination({</span> <span style="color: #afafff; font-style: italic;"> items: "</span> (count images) <span style="color: #afafff; font-style: italic;">",</span> <span style="color: #afafff; font-style: italic;"> itemsOnPage: 1,</span> <span style="color: #afafff; font-style: italic;"> cssStyle: 'dark-theme',</span> <span style="color: #afafff; font-style: italic;"> onPageClick:function(pageNumber, event){</span> <span style="color: #afafff; font-style: italic;"> pageNumber = pageNumber - 1;</span> <span style="color: #afafff; font-style: italic;"> if(gallery &amp;&amp; (currentPage != pageNumber)){</span> <span style="color: #afafff; font-style: italic;"> gallery.load(eval(\"data\" + pageNumber));</span> <span style="color: #afafff; font-style: italic;"> currentPage = pageNumber;</span> <span style="color: #afafff; font-style: italic;"> }</span> <span style="color: #afafff; font-style: italic;"> }</span> <span style="color: #afafff; font-style: italic;"> });</span> <span style="color: #afafff; font-style: italic;"> });</span> <span style="color: #afafff; font-style: italic;"> });</span> <span style="color: #afafff; font-style: italic;"> Galleria.loadTheme('http://photos.nakkaya.com/galleria/themes/folio/galleria.folio.min.js');</span> <span style="color: #afafff; font-style: italic;"> var dataSource = data0;</span> <span style="color: #afafff; font-style: italic;"> var anchor = window.location.hash.substring(6);</span> <span style="color: #afafff; font-style: italic;"> if(anchor){</span> <span style="color: #afafff; font-style: italic;"> currentPage = (parseInt(anchor) - 1);</span> <span style="color: #afafff; font-style: italic;"> dataSource = eval(\"data\" + currentPage);</span> <span style="color: #afafff; font-style: italic;"> }</span> <span style="color: #afafff; font-style: italic;"> Galleria.configure({</span> <span style="color: #afafff; font-style: italic;"> variation: 'dark',</span> <span style="color: #afafff; font-style: italic;"> dataSource:dataSource</span> <span style="color: #afafff; font-style: italic;"> });</span> <span style="color: #afafff; font-style: italic;"> Galleria.ready(function(){</span> <span style="color: #afafff; font-style: italic;"> gallery = this;</span> <span style="color: #afafff; font-style: italic;"> this.lazyLoadChunks(3);</span> <span style="color: #afafff; font-style: italic;"> });</span> <span style="color: #afafff; font-style: italic;"> Galleria.run('#galleria',{</span> <span style="color: #afafff; font-style: italic;"> responsive:true,</span> <span style="color: #afafff; font-style: italic;"> height:1,</span> <span style="color: #afafff; font-style: italic;"> debug:true,</span> <span style="color: #afafff; font-style: italic;"> preload:2</span> <span style="color: #afafff; font-style: italic;"> });"</span>]))) (<span style="color: #ff5f00; font-weight: bold;">defn</span> <span style="color: #d7af00; font-weight: bold;">dump-album</span> [album-name in-dir out-dir] (prep-images in-dir out-dir) (<span style="font-weight: bold; text-decoration: underline;">static.io</span>/write-out-dir (str album-name <span style="color: #afafff; font-style: italic;">"/index.html"</span>) (<span style="font-weight: bold; text-decoration: underline;">hiccup.core</span>/html [<span style="font-weight: bold; text-decoration: underline;">:html</span> [<span style="font-weight: bold; text-decoration: underline;">:head</span> [<span style="font-weight: bold; text-decoration: underline;">:title</span> (<span style="font-weight: bold; text-decoration: underline;">org.apache.commons.io.FilenameUtils</span>/<span style="color: #afd700; font-weight: bold;">getName</span> (str in-dir))] <span style="color: #008787; font-weight: bold; font-style: italic;">;;</span><span style="color: #008787; font-weight: bold; font-style: italic;">(org.apache.commons.io.FilenameUtils/getFullPathNoEndSeparator in-dir)</span> [<span style="font-weight: bold; text-decoration: underline;">:script</span> {<span style="font-weight: bold; text-decoration: underline;">:src</span> <span style="color: #afafff; font-style: italic;">"http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js"</span>}] [<span style="font-weight: bold; text-decoration: underline;">:script</span> {<span style="font-weight: bold; text-decoration: underline;">:src</span> <span style="color: #afafff; font-style: italic;">"http://photos.nakkaya.com/galleria/galleria-1.3.5.min.js"</span>}] [<span style="font-weight: bold; text-decoration: underline;">:script</span> {<span style="font-weight: bold; text-decoration: underline;">:src</span> <span style="color: #afafff; font-style: italic;">"http://photos.nakkaya.com/simplepagination/js/jquery.simplePagination.js"</span>}] [<span style="font-weight: bold; text-decoration: underline;">:link</span> {<span style="font-weight: bold; text-decoration: underline;">:href</span> <span style="color: #afafff; font-style: italic;">"http://photos.nakkaya.com/simplepagination/css/simplePagination.css"</span> <span style="font-weight: bold; text-decoration: underline;">:type</span> <span style="color: #afafff; font-style: italic;">"text/css"</span> <span style="font-weight: bold; text-decoration: underline;">:rel</span> <span style="color: #afafff; font-style: italic;">"stylesheet"</span>}]] [<span style="font-weight: bold; text-decoration: underline;">:body</span> [<span style="font-weight: bold; text-decoration: underline;">:div</span> (album-html album-name in-dir)]]]))) (<span style="color: #ff5f00; font-weight: bold;">def</span> <span style="font-weight: bold; font-style: italic;">in-dir</span> (second <span style="color: #afd700; font-weight: bold;">*command-line-args*</span>)) (<span style="color: #ff5f00; font-weight: bold;">def</span> <span style="font-weight: bold; font-style: italic;">album-name</span> (<span style="color: #afd700; font-weight: bold;">.toString</span> (<span style="font-weight: bold; text-decoration: underline;">java.util.UUID</span>/<span style="color: #afd700; font-weight: bold;">randomUUID</span>))) (set!-config <span style="font-weight: bold; text-decoration: underline;">:out-dir</span> <span style="color: #afafff; font-style: italic;">"./"</span>) (println <span style="color: #afafff; font-style: italic;">"Building "</span> album-name) (println <span style="color: #afafff; font-style: italic;">"In Dir:"</span> in-dir) (dump-album album-name (<span style="font-weight: bold; text-decoration: underline;">java.io.File.</span> in-dir) (<span style="font-weight: bold; text-decoration: underline;">java.io.File.</span> album-name)) (<span style="color: #ff5f00; font-weight: bold;">when</span> (&gt; (count <span style="color: #afd700; font-weight: bold;">*command-line-args*</span>) 2) (println <span style="color: #afafff; font-style: italic;">"Uploading..."</span>) (<span style="font-weight: bold; text-decoration: underline;">clojure.java.shell</span>/sh <span style="color: #afafff; font-style: italic;">"s3cmd"</span> <span style="color: #afafff; font-style: italic;">"sync"</span> <span style="color: #afafff; font-style: italic;">"--delete"</span> <span style="color: #afafff; font-style: italic;">"--acl-public"</span> (str album-name <span style="color: #afafff; font-style: italic;">"/"</span>) (str (nth <span style="color: #afd700; font-weight: bold;">*command-line-args*</span> 2) <span style="color: #afafff; font-style: italic;">"/"</span> album-name <span style="color: #afafff; font-style: italic;">"/"</span>))) (shutdown-agents) <span style="color: #008787; font-weight: bold; font-style: italic;">;;</span><span style="color: #008787; font-weight: bold; font-style: italic;">$('.galleria-container').height($('#galleria').height());</span> </pre> </div> Pentadactyl Configurationhttp://nakkaya.com/2014/01/26/pentadactyl-configuration/Sun, 26 Jan 2014 00:00:00 +0200<p> This is a dump of all <a href="http://5digits.org/pentadactyl/">Pentadactyl</a> related configuration and scripts so I can edit them in one place and tangle from a single file. Pentadactyl is a Firefox extension that provides a more efficient user interface for keyboard-fluent users, allowing you to browse without using a mouse. </p> <p> Disable smooth scroll, </p> <div class="org-src-container"> <pre class="src src-fundamental">set scrollsteps=1 set scrolltime=0 </pre> </div> <p> Editor, C-e invokes it in text fields, </p> <div class="org-src-container"> <pre class="src src-fundamental">set editor=<span style="color: #afafff; font-style: italic;">"emacsclient"</span> </pre> </div> <p> Show pattern matches as you type, </p> <div class="org-src-container"> <pre class="src src-fundamental">set incfind </pre> </div> <p> Highlight previous search pattern matches, </p> <div class="org-src-container"> <pre class="src src-fundamental">set hlfind </pre> </div> <p> Ignore case in search unless pattern has uppercase chars, </p> <div class="org-src-container"> <pre class="src src-fundamental">set findcase=smart </pre> </div> <p> Color Scheme, </p> <div class="org-src-container"> <pre class="src src-fundamental">colorscheme solarized-dark </pre> </div> <p> Faster Scrolling, </p> <div class="org-src-container"> <pre class="src src-fundamental">map -b j 8j map -b k 8k map -b h 8h map -b l 8l </pre> </div> <p> Use Full Zoom, </p> <div class="org-src-container"> <pre class="src src-fundamental">map -b zi ZI map -b zo ZO </pre> </div> <p> Use characters for hints, </p> <div class="org-src-container"> <pre class="src src-fundamental">set hintkeys=asdflkj hi -a Hint font-size: 9pt !important; </pre> </div> <p> Focus settings, (Let gmail mess with DOM) </p> <div class="org-src-container"> <pre class="src src-fundamental">set strictfocus=google.com:laissez-faire,'chrome:*':laissez-faire,*:despotic </pre> </div> <p> Load custom css modifications, </p> <div class="org-src-container"> <pre class="src src-fundamental">so ~/.pentadactyl/user.css </pre> </div> <p> Shortcuts to frequently used bookmarks, </p> <div class="org-src-container"> <pre class="src src-fundamental"><span style="color: #afafff; font-style: italic;">" Email current url</span> <span style="color: #afafff; font-style: italic;">command email-url :open gmail-this</span> <span style="color: #afafff; font-style: italic;">"</span> Save to org-mode Read Later Tree <span style="color: #afafff; font-style: italic;">" command read-later :open org-capture-read-later</span> </pre> </div> <p> Open link in a private tab, </p> <div class="org-src-container"> <pre class="src src-fundamental">command private-tab -nargs=+ -description <span style="color: #afafff; font-style: italic;">"Open Private Tab"</span> -javascript &lt;&lt;EOF privateTab.readyToOpenTab(true); gBrowser.addTab(<span style="color: #afafff; font-style: italic;">"about:blank"</span>); dactyl.execute(<span style="color: #afafff; font-style: italic;">":tablast"</span>); dactyl.execute(<span style="color: #afafff; font-style: italic;">":open "</span> + args); privateTab.stopToOpenTabs(); EOF </pre> </div> <p> Toggle plugins.click<sub>to</sub><sub>play</sub>, </p> <div class="org-src-container"> <pre class="src src-fundamental">command toggle-click-to-play -js &lt;&lt;EOF if(Services.prefs.getBoolPref(<span style="color: #afafff; font-style: italic;">"plugins.click_to_play"</span>)) Services.prefs.setBoolPref(<span style="color: #afafff; font-style: italic;">"plugins.click_to_play"</span>, false); else Services.prefs.setBoolPref(<span style="color: #afafff; font-style: italic;">"plugins.click_to_play"</span>, true); dactyl.execute(<span style="color: #afafff; font-style: italic;">":reload"</span>); EOF </pre> </div> <p> Convert given time to local time using wolfram alpha, </p> <div class="org-src-container"> <pre class="src src-fundamental">command local-time -nargs=+ -description <span style="color: #afafff; font-style: italic;">"Convert Date to Local Time"</span> -javascript &lt;&lt;EOF dactyl.execute(<span style="color: #afafff; font-style: italic;">":tabopen"</span>); dactyl.open(<span style="color: #afafff; font-style: italic;">"http://www.wolframalpha.com/input/?i="</span> + args + <span style="color: #afafff; font-style: italic;">" in local time"</span>); EOF </pre> </div> <p> Custom search commands, </p> <div class="org-src-container"> <pre class="src src-fundamental">command search-nakkaya -nargs=+ -description <span style="color: #afafff; font-style: italic;">"Search nakkaya.com"</span> -javascript &lt;&lt;EOF dactyl.execute(<span style="color: #afafff; font-style: italic;">":tabopen"</span>); dactyl.open(<span style="color: #afafff; font-style: italic;">"site:nakkaya.com "</span> + args); EOF command search-hackernews -nargs=+ -description <span style="color: #afafff; font-style: italic;">"Search news.ycombinator.com"</span> -javascript &lt;&lt;EOF dactyl.execute(<span style="color: #afafff; font-style: italic;">":tabopen"</span>); dactyl.open(<span style="color: #afafff; font-style: italic;">"site:news.ycombinator.com "</span> + args); EOF </pre> </div> <p> Save to org-mode Read Later Tree, </p> <div class="org-src-container"> <pre class="src src-fundamental">command read-later -description <span style="color: #afafff; font-style: italic;">"Execute emacsclient"</span> -javascript &lt;&lt;EOF var emacsClient = <span style="color: #afafff; font-style: italic;">"/Applications/Emacs.app/Contents/MacOS/bin/emacsclient"</span>; var osString = Components.classes[<span style="color: #afafff; font-style: italic;">"@mozilla.org/xre/app-info;1"</span>] .getService(Components.interfaces.nsIXULRuntime).OS; if(osString == <span style="color: #afafff; font-style: italic;">"Linux"</span>) emacsClient = <span style="color: #afafff; font-style: italic;">"/home/nakkaya/apps/emacs/bin/emacsclient"</span> var url = <span style="color: #afafff; font-style: italic;">"\"org-protocol://capture://l/"</span>+ encodeURIComponent(content.location) + <span style="color: #afafff; font-style: italic;">"/"</span>+ encodeURIComponent(content.document.title) +<span style="color: #afafff; font-style: italic;">"/"</span> + encodeURIComponent(content.window.getSelection()) + <span style="color: #afafff; font-style: italic;">"\""</span>; var command = emacsClient + <span style="color: #afafff; font-style: italic;">" "</span> + url; CommandExMode().open(<span style="color: #afafff; font-style: italic;">"!"</span> + command); EOF </pre> </div> <p> Rename tab, </p> <div class="org-src-container"> <pre class="src src-fundamental">:com tabrename -nargs=1 -literal=0 -js content.document.title = args[0]; </pre> </div> <p> GMail settings, </p> <div class="org-src-container"> <pre class="src src-fundamental"><span style="color: #afafff; font-style: italic;">" Allow GMail shortcuts</span> <span style="color: #afafff; font-style: italic;">set passkeys+=mail.google.com:jksacrqG#&lt;CR&gt;,gi,gl,gp</span> <span style="color: #afafff; font-style: italic;">"</span> Let Hint Message from X Links autocmd LocationChange mail.google.com set ht+=span.ata-asJ <span style="color: #afafff; font-style: italic;">" Let Hint Expand Collapsed Conversations</span> <span style="color: #afafff; font-style: italic;">autocmd LocationChange mail.google.com set ht+=span.adx</span> <span style="color: #afafff; font-style: italic;">"</span> Let Hint Expand Message autocmd LocationChange mail.google.com set ht+=td.gF <span style="color: #afafff; font-style: italic;">" Let Hint Expand Delete All Spam Messages</span> <span style="color: #afafff; font-style: italic;">autocmd LocationChange mail.google.com set ht+=span.x2</span> </pre> </div> <p> Auto pin mail.google.com, </p> <div class="org-src-container"> <pre class="src src-fundamental">autocmd PageLoad mail.google.com js if(!getBrowser().mCurrentTab.pinned) getBrowser().pinTab(getBrowser().mCurrentTab); autocmd PageLoad gmail.com js if(!getBrowser().mCurrentTab.pinned) getBrowser().pinTab(getBrowser().mCurrentTab); </pre> </div> <p> Auto pin git-annex tab, </p> <div class="org-src-container"> <pre class="src src-fundamental">autocmd PageLoad '127\.0\.0\.1:\d+/\?auth=' js if(!getBrowser().mCurrentTab.pinned) getBrowser().pinTab(getBrowser().mCurrentTab); </pre> </div> <p> Additional hints, </p> <div class="org-src-container"> <pre class="src src-fundamental"><span style="color: #afafff; font-style: italic;">" Hint Instagram Load More</span> <span style="color: #afafff; font-style: italic;">autocmd LocationChange instagram.com set ht+=a.button.button-grey.button-large</span> </pre> </div> <p> ~/.pentadactyl/user.css, </p> <div class="org-src-container"> <pre class="src src-fundamental">/* @-moz-document domain(<span style="color: #afafff; font-style: italic;">"www.reddit.com"</span>) { */ /* .side{ display: none !important; } */ /* .md { max-width: 100% ! important;} */ /* } */ @-moz-document domain(<span style="color: #afafff; font-style: italic;">"10.1.2.50"</span>), domain(<span style="color: #afafff; font-style: italic;">"127.0.0.1"</span>) { #jwplayer_wrapper,#media_control{width:100% !important;} #jwplayer_wrapper{height:75% !important;} #progress_slider{width:99% !important; height: 10px !important;} .ui-slider .ui-slider-handle {height: 15px !important;} } @-moz-document domain(<span style="color: #afafff; font-style: italic;">"youtube.com"</span>) { #confirmBox.yt-alert-default.yt-alert-warn{ display: none !important; } } @-moz-document domain(<span style="color: #afafff; font-style: italic;">"google.com.tr"</span>), domain(<span style="color: #afafff; font-style: italic;">"google.com"</span>), domain(<span style="color: #afafff; font-style: italic;">"google.de"</span>){ #gbzw, /* links */ #gbx3, #gbx4, /* background */ #fll, #bfl { display: none !important; } #gbq, #gbu, /* controls */ #gbx1, #gbx2 /* background */ { top: 0 !important; } /* remove google plus */ ol.gbtc { display: none ! important;} /* remove safe search button */ a#abar_button_ss.ab_button { display: none ! important;} } @-moz-document url-prefix(<span style="color: #afafff; font-style: italic;">"https://mail.google.com/"</span>){ #gbzw, /* links */ #gbx3, #gbx4 /* background */ { display: none; } #gbq, #gbu, /* controls */ #gbx1, #gbx2 /* background */ { top: 0 !important; } /* Bar container */ #gb { height: 72px !important; } /* Share pop-up content */ #gbwc.gbmwca { top: -29px; } /* remove google plus shit */ ol.gbtc { display: none ! important;} /* get rid of copy right */ div.wIFnie { display: none !important; } /* Remove people widget completely */ .nH.adC { display: none ! important; } .yPPMxf, .nH.adC, .qHcrae, .y3, .y4 { width: 0 ! important; } /* Plain-text Message Body */ /* Compose Interfaces */ .editable.LW-avf, .editable, .ii, .Ak{ font-size: 14px ! important; font-family: monospace ! important; } td.Bu.y3 { display: none !important; } } @-moz-document domain(<span style="color: #afafff; font-style: italic;">"www.facebook.com"</span>) { #rightCol{ display: none !important; } #appsNav{ display: none !important; } #pagesNav{ display: none !important; } .fbChatSidebar,#fbDockChatBuddylistNub{ display: none !important; } } @-moz-document domain(<span style="color: #afafff; font-style: italic;">"twitter.com"</span>) { div.module.trends{ display: none !important; } div.module.site-footer{ display: none !important; } div.module.wtf-module.js-wtf-module.has-content{ display: none !important; } div.global-nav{ display: none !important; } .wrapper.white { background: none !important;} } @-moz-document domain(<span style="color: #afafff; font-style: italic;">"facebook.com"</span>) { /** Set Background color for page **/ .fbIndex { background-color: #3B5998 !important } /** Hide Crap **/ .fbIndex #globalContainer #dropmenu_container, .fbIndex #globalContainer #content, .fbIndex #globalContainer #pageFooter { display: none !important } /** Center Login Bar **/ .fbIndex .loggedout_menubar_container { position: fixed !important; width: 420px !important; height: 82px !important; min-width: 0 !important; top: 50% !important; left: 50% !important; margin-top: -17px !important; margin-left: -210px !important; z-index: -1 !important; } /** Center Login form **/ .fbIndex .loggedout_menubar { width: auto !important } .fbIndex .loggedout_menubar_container .lfloat, .fbIndex .loggedout_menubar_container .rfloat { float: none !important } .fbIndex .loggedout_menubar_container .lfloat img, .fbIndex .loggedout_menubar_container .rfloat #login_form table { display: block !important; margin: 0 auto !important } .fbIndex .loggedout_menubar_container .lfloat i { display: block !important; margin: -70px auto 20px !important; } .fbIndex .loggedout_menubar_container .sp_69c1xs { display: block !important; } /** Hide Homepage Box **/ #SetAsHomepage_Callout { display: none; } /** Reset bluBar z-index **/ .fbIndex div#blueBar { z-index: 0 !important; border: none !important; box-shadow: none !important; } } @-moz-document domain(news.ycombinator.com) { p { word-break: break-all; } #non-existent-id {} #csres { display: none; } .title { font-size: 120% !important; } .subtext { font-size: 90% !important; } * { font-family: Helvetica !important; line-height: 1.4 !important; } body { padding: 10px !important; background: #F6F6EF; } body &gt; center &gt; table { width: 100% !important; } body &gt; center &gt; table &gt; tbody &gt; tr:first-child &gt; td { font-size: 120%; -moz-border-radius: 5px; -moz-box-shadow: 0 0 10px rgba(0,0,0,0.5); } .title a { font-family: Museo !important; } .title a:visited { color: #666 !important; } .comment, .comhead { font-size: 120% !important; } .title .comhead { font-size: 85% !important; } .pagetop { display: block; padding: 6px 0 4px; font-size: 110% !important; } .pagetop a { font-family: Helvetica !important; color: rgba(0,0,0,0.6) !important; font-size: 110% !important; } img[src=http\:\/\/ycombinator\.com\/images\/y18\.gif] { margin: 0 2px 0 5px; } } </pre> </div> tmux Configurationhttp://nakkaya.com/2014/01/05/tmux-configuration/Sun, 5 Jan 2014 00:00:00 +0200<p> This is a dump of all tmux related configuration and scripts so I can edit them in one place and tangle from a single file. </p> <p><img src="/images/post/tmux.png" alt="tmux configuration" width="780"/></p> <p> Start windows and panes at 1, not 0, </p> <div class="org-src-container"> <pre class="src src-fundamental">set -g base-index 1 set -g pane-base-index 1 </pre> </div> <p> Replace C-b with \, </p> <div class="org-src-container"> <pre class="src src-fundamental">unbind C-b set -g prefix '\' bind-key '\' send-prefix set-window-option -g xterm-keys on </pre> </div> <p> Setup key bindings, </p> <div class="org-src-container"> <pre class="src src-fundamental">bind-key r command-prompt -p <span style="color: #afafff; font-style: italic;">"rename window to:"</span> <span style="color: #afafff; font-style: italic;">"rename-window '%%'"</span> bind t source-file ~/.tmux-over-ssh.conf bind k confirm kill-window bind K confirm kill-server bind tab last-window # window movement / renumbering like in screen's :number bind-key m command-prompt -p <span style="color: #afafff; font-style: italic;">"move window to:"</span> <span style="color: #afafff; font-style: italic;">"swap-window -t '%%'"</span> </pre> </div> <p> Enable UTF-8, </p> <div class="org-src-container"> <pre class="src src-fundamental">setw -g utf8 on set -g status-utf8 on </pre> </div> <div class="org-src-container"> <pre class="src src-fundamental">setw -g window-status-current-format <span style="color: #afafff; font-style: italic;">"|#I:#W|"</span> </pre> </div> <p> Makes using the scroll wheel automatically switch to copy mode and scroll back the tmux scrollback buffer. </p> <div class="org-src-container"> <pre class="src src-fundamental">set -g mouse on </pre> </div> <p> Status bar, </p> <div class="org-src-container"> <pre class="src src-fundamental">set-option -g status-interval 60 set-option -g status-right-length 120 set -g status-right '#(date +<span style="color: #afafff; font-style: italic;">"%a %b %_d %H:%M"</span>) | #(hostname)' </pre> </div> <p> Create a new window, swtich to home directory and type tmux-ssh, </p> <div class="org-src-container"> <pre class="src src-fundamental">neww -n tmux-ssh send-keys -t tmux-ssh <span style="color: #afafff; font-style: italic;">"cd ~/"</span> C-m send-keys -t tmux-ssh <span style="color: #afafff; font-style: italic;">"tmux-ssh "</span> </pre> </div> <p> Create/attach a dev session. Start tmux create two windows for two emacs instances for for editing one for dired. </p> <div class="org-src-container"> <pre class="src src-sh"><span style="font-weight: bold; font-style: italic;">TERM</span>=xterm-256color tmux has-session -t dev <span style="color: #ff5f00; font-weight: bold;">if</span> [ $<span style="font-weight: bold; font-style: italic;">?</span> != 0 ] <span style="color: #ff5f00; font-weight: bold;">then</span> tmux new-session -s dev -n emacs -d tmux send-keys -t dev <span style="color: #afafff; font-style: italic;">'cd ~/'</span> C-m tmux send-keys -t dev <span style="color: #afafff; font-style: italic;">'emacs -main-instance'</span> C-m tmux new-window -n dired -t dev tmux send-keys -t dev <span style="color: #afafff; font-style: italic;">'cd ~/'</span> C-m tmux send-keys -t dev <span style="color: #afafff; font-style: italic;">'emacs'</span> C-m <span style="color: #ff5f00; font-weight: bold;">fi</span> tmux attach -t dev </pre> </div> <p> Solarized theme, </p> <div class="org-src-container"> <pre class="src src-fundamental"># default statusbar colors set-option -g status-bg colour235 #base02 set-option -g status-fg colour136 #yellow set-option -g status-attr default # default window title colors set-window-option -g window-status-fg colour244 #base0 set-window-option -g window-status-bg default #set-window-option -g window-status-attr dim # active window title colors set-window-option -g window-status-current-fg colour166 #orange set-window-option -g window-status-current-bg default #set-window-option -g window-status-current-attr bright # pane border set-option -g pane-border-fg colour235 #base02 set-option -g pane-active-border-fg colour240 #base01 # message text set-option -g message-bg colour235 #base02 set-option -g message-fg colour166 #orange # pane number display set-option -g display-panes-active-colour colour33 #blue set-option -g display-panes-colour colour166 #orange # clock set-window-option -g clock-mode-colour colour64 #green </pre> </div> SSH as a Hidden Service with Torhttp://nakkaya.com/2014/01/05/ssh-as-a-hidden-service-with-tor/Sun, 5 Jan 2014 00:00:00 +0200<p> Note to self, setup .torrc, </p> <div class="org-src-container"> <pre class="src src-conf">RunAsDaemon 1 HiddenServiceDir /home/tor/.hidden-ssh/ HiddenServicePort 22 127.0.0.1:22 </pre> </div> <p> Locate tor address, </p> <div class="org-src-container"> <pre class="src src-sh">cat ~/.hidden-ssh/hostname </pre> </div> <p> Edit rc.local so tor starts during boot, </p> <div class="org-src-container"> <pre class="src src-sh">su - tor -c <span style="color: #afafff; font-style: italic;">"/home/tor/Apps/tor/App/tor -f /home/tor/.torrc"</span> </pre> </div> <p> Edit SSH conf so it uses the SOCKS proxy for .onion addresses, </p> <div class="org-src-container"> <pre class="src src-conf">Host *.onion ProxyCommand nc -xlocalhost:9050 -X5 %h %p </pre> </div> <p> and add hosts, </p> <div class="org-src-container"> <pre class="src src-conf">Host machine.onion HostName dkflcfnvfkddjfkd.onion Port 22 </pre> </div> Parse S3 Logs with Goaccesshttp://nakkaya.com/2013/11/20/parse-s3-logs-with-goaccess/Wed, 20 Nov 2013 00:00:00 +0200<p> Note to self, create ~/.goaccessrc add S3 log format, </p> <div class="org-src-container"> <pre class="src src-conf">date_format %d/%b/%Y log_format %^ %^ [%d:%^] %h %^ %^ %^ %^ <span style="color: #afafff; font-style: italic;">"%^ %r %^"</span> %s %^ %b %^ %^ %^ <span style="color: #afafff; font-style: italic;">"%^"</span> <span style="color: #afafff; font-style: italic;">"%u"</span> %^ </pre> </div> <p> Sync log bucket to local folder, </p> <div class="org-src-container"> <pre class="src src-sh">s3cmd sync s3://logs.nakkaya.com/ ./ </pre> </div> <p> Parse yesterdays logs, </p> <div class="org-src-container"> <pre class="src src-sh">find . -name <span style="color: #afafff; font-style: italic;">"`date +%Y-%m-%d -d "yesterday"`*"</span> -exec cat {} <span style="color: #afafff; font-style: italic;">\;</span> | goaccess -a </pre> </div> <p> Parse all logs, </p> <div class="org-src-container"> <pre class="src src-sh">find . -exec cat {} <span style="color: #afafff; font-style: italic;">\;</span> | goaccess -a </pre> </div> Notes on Synchronization and Backup of $HOME using git, git-annex and mrhttp://nakkaya.com/2013/10/23/notes-on-synchronization-and-backup-of-home-using-git-git-annex-and-mr/Wed, 23 Oct 2013 00:00:00 +0300<div id="table-of-contents"> <h2>Table of Contents</h2> <div id="text-table-of-contents"> <ul> <li><a href="#sec-1">~/annex/</a> <ul> <li> <ul> <li><a href="#sec-1-0-1">~/.mrconfig</a></li> <li><a href="#sec-1-0-2">~/annex/.mrconfig</a></li> <li><a href="#sec-1-0-3">~/.bin/git-anx-drop-unused</a></li> <li><a href="#sec-1-0-4">~/.bin/git-fast-push</a></li> <li><a href="#sec-1-0-5">Mount / Unmount EncFS Volumes</a></li> <li><a href="#sec-1-0-6">Webapp</a></li> <li><a href="#sec-1-0-7">Misc</a></li> </ul> </li> </ul> </li> <li><a href="#sec-2">~/source/</a> <ul> <li> <ul> <li><a href="#sec-2-0-1">~/source/.mrconfig</a></li> </ul> </li> </ul> </li> </ul> </div> </div> <p> This is a dump of all git, git-annex and mr related configuration and scripts so I can edit them in one place. When <a href="http://orgmode.org/manual/Working-With-Source-Code.html">tangled</a>, </p> <ul class="org-ul"> <li>All mr configs will go into their respective folders. </li> <li>All Bash scripts will go into ~/.bin/ folder. </li> </ul> <p> Repository structure, </p> <ul class="org-ul"> <li>~/annex/ - git-annex repositories that are synced between computers. </li> <li>~/source/ - Git repos. </li> <li>/external - Single git-annex repo spread over multiple USB drives. Working as a Poor Mans Raid. </li> </ul> <div id="outline-container-sec-1" class="outline-2"> <h2 id="sec-1">~/annex/</h2> <div class="outline-text-2" id="text-1"> <p> Instead of having a single large annex folder synced across machines, I have split all files into 6 annexes, </p> <ul class="org-ul"> <li>documents </li> <li>music </li> <li>notes </li> <li>old-code </li> <li>photos </li> </ul> <p> This scheme makes git-annex much faster. At first I was reluctant to go with this, instead of pushing pulling single annex, now I have to deal with 6. Then I found about <a href="http://myrepos.branchable.com/">mr</a> which lets you run commands on a collection of repositories, even though there are 6 repos with mr a single command will push pull all of them. </p> <p> These annexes are shared between 3 computers (one with two full copy of all repos and two with partial copies.), all behind NAT so all clients dump data to rsync.net (GPG encrypted with separate keys.) and sync changes with a repo inside rsync.net. </p> <p> When ever I make changes to any of the repos, I just run <i>mr push</i>. It will iterate repositories with changes (new files/deletes/renames) and upload changes to and sync with rsync.net. Then when I switch machines I just do a <i>mr pull</i> which downloads all changes. </p> </div> <div id="outline-container-sec-1-0-1" class="outline-4"> <h4 id="sec-1-0-1">~/.mrconfig</h4> <div class="outline-text-4" id="text-1-0-1"> <div class="org-src-container"> <pre class="src src-conf"><span style="font-weight: bold; font-style: italic;">include</span> = cat ~/annex/.mrconfig-annex ~/source/.mrconfig-source </pre> </div> </div> </div> <div id="outline-container-sec-1-0-2" class="outline-4"> <h4 id="sec-1-0-2">~/annex/.mrconfig</h4> <div class="outline-text-4" id="text-1-0-2"> <div class="org-src-container"> <pre class="src src-conf">[<span style="font-weight: bold; text-decoration: underline;">DEFAULT</span>] <span style="font-weight: bold; font-style: italic;">git_sync</span> = git annex add .;git annex sync --content <span style="font-weight: bold; font-style: italic;">git_status</span> = git annex status <span style="font-weight: bold; font-style: italic;">git_gc</span> = git repack -ad; git gc <span style="font-weight: bold; font-style: italic;">lib</span> = <span style="font-weight: bold; text-decoration: underline;">initAnnex()</span> { git config remote.origin.annex-ignore true git annex init <span style="color: #afafff; font-style: italic;">"`hostname`"</span> git annex untrust here git annex enableremote cloud } <span style="font-weight: bold; text-decoration: underline;">fastFsChck()</span> { git annex fsck --fast --from <span style="color: #afafff; font-style: italic;">"$1"</span> } [<span style="font-weight: bold; text-decoration: underline;">annex/documents</span>] <span style="font-weight: bold; font-style: italic;">checkout</span> = git clone <span style="color: #afafff; font-style: italic;">'https://git.nakkaya.com/git/nakkaya/annex-documents.git'</span> <span style="color: #afafff; font-style: italic;">'documents'</span> cd documents/ initAnnex <span style="font-weight: bold; font-style: italic;">skip</span> = lazy <span style="font-weight: bold; font-style: italic;">fsck</span> = fastFsChck cloud fastFsChck storage-box [<span style="font-weight: bold; text-decoration: underline;">annex/notes</span>] <span style="font-weight: bold; font-style: italic;">checkout</span> = git clone <span style="color: #afafff; font-style: italic;">'https://git.nakkaya.com/git/nakkaya/annex-notes.git'</span> <span style="color: #afafff; font-style: italic;">'notes'</span> cd notes/ initAnnex git annex direct git annex get . <span style="font-weight: bold; font-style: italic;">fsck</span> = fastFsChck cloud </pre> </div> </div> </div> <div id="outline-container-sec-1-0-3" class="outline-4"> <h4 id="sec-1-0-3">~/.bin/git-anx-drop-unused</h4> <div class="outline-text-4" id="text-1-0-3"> <p> Drop all unused files by date, </p> <div class="org-src-container"> <pre class="src src-hy"><span style="color: #008787; font-weight: bold; font-style: italic;">#!/usr/bin/env hy</span> (<span style="color: #ff5f00; font-weight: bold;">import</span> <span style="color: #d7af00; font-weight: bold;"> </span>[sh [grep git perl awk ErrorReturnCode]] [re [split]] [datetime [datetime date]] [sys]) (<span style="color: #afd700; font-weight: bold;">def</span> remote (<span style="color: #ff5f00; font-weight: bold;">if</span> (<span style="color: #afd700; font-weight: bold;">&gt;=</span> (len sys.argv) 2) (<span style="color: #afd700; font-weight: bold;">second</span> sys.argv) <span style="color: #afafff; font-style: italic;">"here"</span>)) (<span style="color: #afd700; font-weight: bold;">def</span> drop-age (<span style="color: #ff5f00; font-weight: bold;">if</span> (<span style="color: #afd700; font-weight: bold;">=</span> (len sys.argv) 3) (int (<span style="color: #afd700; font-weight: bold;">nth</span> sys.argv 2)) 180)) (<span style="color: #ff5f00; font-weight: bold;">defn</span> <span style="color: #d7af00; font-weight: bold;">unused-files</span> [] (<span style="color: #ff5f00; font-weight: bold;">let</span> [[files (<span style="color: #ff5f00; font-weight: bold;">try</span> (<span style="color: #ff5f00; font-weight: bold;">-&gt;</span> (.annex git <span style="color: #afafff; font-style: italic;">"unused"</span> <span style="color: #afafff; font-style: italic;">"--from"</span> remote) (perl <span style="color: #afafff; font-style: italic;">"-ne"</span> <span style="color: #afafff; font-style: italic;">"print if /^ [0-9]+.*/"</span>) str) (<span style="color: #ff5f00; font-weight: bold;">catch</span> [e ErrorReturnCode] <span style="color: #afafff; font-style: italic;">""</span>))] [unused-files (<span style="color: #ff5f00; font-weight: bold;">-&gt;&gt;</span> files (split <span style="color: #afafff; font-style: italic;">"\n"</span>) (<span style="color: #afd700; font-weight: bold;">map</span> (<span style="color: #ff5f00; font-weight: bold;">fn</span> [x] (<span style="color: #ff5f00; font-weight: bold;">-&gt;&gt;</span> (.strip x) (split <span style="color: #afafff; font-style: italic;">" +"</span>) (<span style="color: #afd700; font-weight: bold;">take</span> 2) (<span style="color: #afd700; font-weight: bold;">map</span> (<span style="color: #ff5f00; font-weight: bold;">fn</span> [x] (.strip x)))))) (<span style="color: #afd700; font-weight: bold;">filter</span> (<span style="color: #ff5f00; font-weight: bold;">fn</span> [x] (<span style="color: #afd700; font-weight: bold;">=</span> (len x) 2))) list)]] (<span style="color: #afd700; font-weight: bold;">print</span> <span style="color: #afafff; font-style: italic;">"Unused files: "</span> (len unused-files)) unused-files)) (<span style="color: #ff5f00; font-weight: bold;">defn</span> <span style="color: #d7af00; font-weight: bold;">last-seen</span> [file] (<span style="color: #ff5f00; font-weight: bold;">let</span> [[key (<span style="color: #afd700; font-weight: bold;">second</span> file)]] (<span style="color: #ff5f00; font-weight: bold;">-&gt;&gt;</span> (git <span style="color: #afafff; font-style: italic;">"--no-pager"</span> <span style="color: #afafff; font-style: italic;">"log"</span> <span style="color: #afafff; font-style: italic;">"-1"</span> <span style="color: #afafff; font-style: italic;">"-S"</span> key <span style="color: #afafff; font-style: italic;">"--pretty=format:%at"</span>) str (split <span style="color: #afafff; font-style: italic;">"\n"</span>) (<span style="color: #afd700; font-weight: bold;">map</span> (<span style="color: #ff5f00; font-weight: bold;">fn</span> [x] (.fromtimestamp datetime (float x)))) first))) (<span style="color: #ff5f00; font-weight: bold;">defn</span> <span style="color: #d7af00; font-weight: bold;">age</span> [file] (<span style="color: #ff5f00; font-weight: bold;">let</span> [[delta (<span style="color: #afd700; font-weight: bold;">-</span> (.today datetime) (last-seen file))]] delta.days)) (<span style="color: #afd700; font-weight: bold;">print</span> <span style="color: #afafff; font-style: italic;">"Dropping "</span> remote) (<span style="color: #ff5f00; font-weight: bold;">if</span> (<span style="color: #afd700; font-weight: bold;">=</span> drop-age 0) (<span style="color: #ff5f00; font-weight: bold;">for</span> [file (unused-files)] (<span style="color: #ff5f00; font-weight: bold;">let</span> [[id (<span style="color: #afd700; font-weight: bold;">first</span> file)]] (<span style="color: #afd700; font-weight: bold;">print</span> <span style="color: #afafff; font-style: italic;">"Id "</span> id) (<span style="color: #ff5f00; font-weight: bold;">if</span> (<span style="color: #afd700; font-weight: bold;">=</span> remote <span style="color: #afafff; font-style: italic;">"here"</span>) (.annex git <span style="color: #afafff; font-style: italic;">"dropunused"</span> <span style="color: #afafff; font-style: italic;">"--force"</span> (str id)) (.annex git <span style="color: #afafff; font-style: italic;">"dropunused"</span> <span style="color: #afafff; font-style: italic;">"--force"</span> <span style="color: #afafff; font-style: italic;">"--from"</span> remote (str id))))) (<span style="color: #ff5f00; font-weight: bold;">for</span> [file (unused-files)] (<span style="color: #ff5f00; font-weight: bold;">let</span> [[id (<span style="color: #afd700; font-weight: bold;">first</span> file)] [file-age (<span style="color: #ff5f00; font-weight: bold;">try</span> (age file) (<span style="color: #ff5f00; font-weight: bold;">catch</span> [e Exception] -1))]] (<span style="color: #ff5f00; font-weight: bold;">if</span> (<span style="color: #afd700; font-weight: bold;">&gt;=</span> file-age drop-age) (<span style="color: #ff5f00; font-weight: bold;">do</span> (<span style="color: #afd700; font-weight: bold;">print</span> <span style="color: #afafff; font-style: italic;">"Id "</span> id <span style="color: #afafff; font-style: italic;">" age "</span> file-age <span style="color: #afafff; font-style: italic;">" days..."</span>) (<span style="color: #ff5f00; font-weight: bold;">if</span> (<span style="color: #afd700; font-weight: bold;">=</span> remote <span style="color: #afafff; font-style: italic;">"here"</span>) (.annex git <span style="color: #afafff; font-style: italic;">"dropunused"</span> <span style="color: #afafff; font-style: italic;">"--force"</span> (str id)) (.annex git <span style="color: #afafff; font-style: italic;">"dropunused"</span> <span style="color: #afafff; font-style: italic;">"--force"</span> <span style="color: #afafff; font-style: italic;">"--from"</span> remote (str id)))))))) </pre> </div> </div> </div> <div id="outline-container-sec-1-0-4" class="outline-4"> <h4 id="sec-1-0-4">~/.bin/git-fast-push</h4> <div class="outline-text-4" id="text-1-0-4"> <p> Custom push command. For repositories with no changes it simply returns true, for repositories with changes or new files, </p> <ul class="org-ul"> <li>If acting on a regular git repo, pushes changes to origin. </li> <li>If acting on a git annex repo, uploads changes and sync with rsync.net. </li> </ul> <div class="org-src-container"> <pre class="src src-sh"><span style="color: #008787; font-weight: bold; font-style: italic;">#</span><span style="color: #008787; font-weight: bold; font-style: italic;">/bin/bash</span> <span style="color: #d7af00; font-weight: bold;">updateAnnexHost</span>() { <span style="color: #afd700; font-weight: bold;">echo</span> <span style="color: #afafff; font-style: italic;">'Updating Remote...'</span> <span style="font-weight: bold; font-style: italic;">ORIGIN</span>=<span style="font-weight: bold;">`git config --get remote.origin.url`</span> <span style="font-weight: bold; font-style: italic;">HOST</span>=<span style="font-weight: bold;">`echo "$ORIGIN" | grep -oiP '//.*?\/' | cut -d/ -f3`</span> <span style="font-weight: bold; font-style: italic;">DIR</span>=<span style="color: #afafff; font-style: italic;">"/${ORIGIN#*//*/}"</span> <span style="color: #afd700; font-weight: bold;">echo</span> <span style="color: #afafff; font-style: italic;">"$HOST $DIR"</span> ssh $<span style="font-weight: bold; font-style: italic;">HOST</span> <span style="color: #afafff; font-style: italic;">"cd $DIR;git annex sync"</span> } <span style="color: #d7af00; font-weight: bold;">hasNoChanges</span>(){ git diff-index --quiet HEAD -- } <span style="color: #d7af00; font-weight: bold;">hasNewFiles</span>(){ <span style="color: #ff5f00; font-weight: bold;">if</span> [ <span style="font-weight: bold;">`git ls-files --exclude-standard --others| wc -l`</span> != 0 ]; <span style="color: #ff5f00; font-weight: bold;">then</span> true <span style="color: #ff5f00; font-weight: bold;">else</span> false <span style="color: #ff5f00; font-weight: bold;">fi</span> } <span style="color: #d7af00; font-weight: bold;">isRepoAhead</span>(){ <span style="color: #ff5f00; font-weight: bold;">if</span> [ <span style="font-weight: bold;">`git log origin/$(git branch | grep '*' | cut -d' ' -f2)..HEAD | wc -l`</span> != 0 ]; <span style="color: #ff5f00; font-weight: bold;">then</span> true <span style="color: #ff5f00; font-weight: bold;">else</span> false <span style="color: #ff5f00; font-weight: bold;">fi</span> } <span style="color: #008787; font-weight: bold; font-style: italic;">#</span><span style="color: #008787; font-weight: bold; font-style: italic;">handle direct annex repo</span> <span style="color: #ff5f00; font-weight: bold;">if</span> <span style="font-weight: bold;">`git config --get annex.direct`</span>; <span style="color: #ff5f00; font-weight: bold;">then</span> <span style="font-weight: bold; font-style: italic;">oldHead</span>=<span style="font-weight: bold;">`git rev-parse HEAD`</span> git annex add . git annex sync <span style="font-weight: bold; font-style: italic;">newHead</span>=<span style="font-weight: bold;">`git rev-parse HEAD`</span> <span style="color: #ff5f00; font-weight: bold;">if</span> [ <span style="color: #afafff; font-style: italic;">"$oldHead"</span> != <span style="color: #afafff; font-style: italic;">"$newHead"</span> ]; <span style="color: #ff5f00; font-weight: bold;">then</span> <span style="color: #ff5f00; font-weight: bold;">if</span> git config remote.depot.annex-uuid; <span style="color: #ff5f00; font-weight: bold;">then</span> git annex copy --to depot --not --in depot git annex sync <span style="color: #ff5f00; font-weight: bold;">else</span> git annex copy --to origin --not --in origin updateAnnexHost <span style="color: #ff5f00; font-weight: bold;">fi</span> <span style="color: #ff5f00; font-weight: bold;">fi</span> <span style="color: #ff5f00; font-weight: bold;">exit</span> <span style="color: #ff5f00; font-weight: bold;">fi</span> <span style="color: #ff5f00; font-weight: bold;">if</span> ! hasNoChanges || hasNewFiles || isRepoAhead; <span style="color: #ff5f00; font-weight: bold;">then</span> <span style="color: #008787; font-weight: bold; font-style: italic;">#</span><span style="color: #008787; font-weight: bold; font-style: italic;">handle indirect annex repo</span> <span style="color: #ff5f00; font-weight: bold;">if</span> [ -d <span style="color: #afafff; font-style: italic;">'.git/annex/'</span> ]; <span style="color: #ff5f00; font-weight: bold;">then</span> git annex add . git annex sync <span style="color: #ff5f00; font-weight: bold;">if</span> git config remote.depot.annex-uuid; <span style="color: #ff5f00; font-weight: bold;">then</span> git annex copy --to depot --not --in depot git annex sync <span style="color: #ff5f00; font-weight: bold;">else</span> git annex copy --to origin --not --in origin updateAnnexHost <span style="color: #ff5f00; font-weight: bold;">fi</span> <span style="color: #ff5f00; font-weight: bold;">exit</span> <span style="color: #008787; font-weight: bold; font-style: italic;">#</span><span style="color: #008787; font-weight: bold; font-style: italic;">handle plain git repo </span> <span style="color: #ff5f00; font-weight: bold;">else</span> git push origin master <span style="color: #ff5f00; font-weight: bold;">fi</span> <span style="color: #ff5f00; font-weight: bold;">else</span> true <span style="color: #ff5f00; font-weight: bold;">fi</span> </pre> </div> </div> </div> <div id="outline-container-sec-1-0-5" class="outline-4"> <h4 id="sec-1-0-5">Mount / Unmount EncFS Volumes</h4> <div class="outline-text-4" id="text-1-0-5"> <p> Scripts for mounting and unmounting EncFS Volumes. </p> <div class="org-src-container"> <pre class="src src-sh"><span style="color: #008787; font-weight: bold; font-style: italic;">#</span><span style="color: #008787; font-weight: bold; font-style: italic;">/bin/bash</span> <span style="font-weight: bold; font-style: italic;">CUR_DIR</span>=<span style="font-weight: bold;">`pwd`</span> <span style="color: #afd700; font-weight: bold;">cd</span> <span style="color: #afafff; font-style: italic;">"$1"</span> <span style="font-weight: bold; font-style: italic;">DIR</span>=$(<span style="font-weight: bold;">basename</span> <span style="color: #afafff; font-style: italic;">"$1"</span>) mkdir <span style="color: #afafff; font-style: italic;">"/Volumes/$DIR"</span> git annex get . git annex unlock <span style="color: #afafff; font-style: italic;">"."</span> encfs <span style="color: #afafff; font-style: italic;">"$CUR_DIR/${1}"</span> <span style="color: #afafff; font-style: italic;">"/Volumes/$DIR"</span> <span style="color: #afd700; font-weight: bold;">cd</span> $<span style="font-weight: bold; font-style: italic;">CUR_DIR</span> </pre> </div> <div class="org-src-container"> <pre class="src src-sh"><span style="color: #008787; font-weight: bold; font-style: italic;">#</span><span style="color: #008787; font-weight: bold; font-style: italic;">/bin/bash</span> <span style="font-weight: bold; font-style: italic;">CUR_DIR</span>=<span style="font-weight: bold;">`pwd`</span> <span style="font-weight: bold; font-style: italic;">DIR</span>=$(<span style="font-weight: bold;">basename</span> <span style="color: #afafff; font-style: italic;">"$1"</span>) <span style="color: #ff5f00; font-weight: bold;">if</span> umount <span style="color: #afafff; font-style: italic;">"/Volumes/$DIR"</span>; <span style="color: #ff5f00; font-weight: bold;">then</span> rm -rf <span style="color: #afafff; font-style: italic;">"/Volumes/$DIR"</span> <span style="color: #ff5f00; font-weight: bold;">fi</span> <span style="color: #afd700; font-weight: bold;">cd</span> <span style="color: #afafff; font-style: italic;">"$1"</span> git annex add . git annex add .encfs6.xml git commit -m <span style="color: #afafff; font-style: italic;">'Update'</span> <span style="color: #afd700; font-weight: bold;">cd</span> $<span style="font-weight: bold; font-style: italic;">CUR_DIR</span> </pre> </div> </div> </div> <div id="outline-container-sec-1-0-6" class="outline-4"> <h4 id="sec-1-0-6">Webapp</h4> <div class="outline-text-4" id="text-1-0-6"> <p> Create autostart file relative paths don't work so tangle one file for each OS (Linux,OS X) then mv one to correct location, </p> <div class="org-src-container"> <pre class="src src-conf">/home/nakkaya/annex/notes /home/nakkaya/annex/documents </pre> </div> <div class="org-src-container"> <pre class="src src-conf">/Users/nakkaya/annex/notes /Users/nakkaya/annex/documents </pre> </div> <p> Start asistant and webapp, </p> <div class="org-src-container"> <pre class="src src-sh">git annex assistant --autostart &amp;&amp; nohup git annex webapp </pre> </div> </div> </div> <div id="outline-container-sec-1-0-7" class="outline-4"> <h4 id="sec-1-0-7">Misc</h4> <div class="outline-text-4" id="text-1-0-7"> <p> Setup encrypted annex directory remote, </p> <div class="org-src-container"> <pre class="src src-sh">git annex initremote mobile <span style="font-weight: bold; font-style: italic;">type</span>=directory <span style="font-weight: bold; font-style: italic;">directory</span>=/path/to/annex/repo/ <span style="font-weight: bold; font-style: italic;">encryption</span>=hybrid <span style="font-weight: bold; font-style: italic;">keyid</span>=ID <span style="font-weight: bold; font-style: italic;">embedcreds</span>=yes </pre> </div> <p> Setup encrypted annex S3 remote in EU (Ireland) (eu-west-1), </p> <div class="org-src-container"> <pre class="src src-sh"><span style="color: #afd700; font-weight: bold;">export</span> <span style="font-weight: bold; font-style: italic;">AWS_ACCESS_KEY_ID</span>=<span style="color: #afafff; font-style: italic;">"KID"</span> <span style="color: #afd700; font-weight: bold;">export</span> <span style="font-weight: bold; font-style: italic;">AWS_SECRET_ACCESS_KEY</span>=<span style="color: #afafff; font-style: italic;">"SKEY"</span> git annex initremote cloud <span style="font-weight: bold; font-style: italic;">type</span>=S3 <span style="font-weight: bold; font-style: italic;">encryption</span>=hybrid <span style="font-weight: bold; font-style: italic;">keyid</span>=ID <span style="font-weight: bold; font-style: italic;">embedcreds</span>=yes <span style="font-weight: bold; font-style: italic;">datacenter</span>=eu-west-1 <span style="font-weight: bold; font-style: italic;">chunk</span>=250MiB git setup-bitbucket git config remote.origin.annex-ignore true </pre> </div> <p> Setup encrypted annex S3 remote in Google Cloud Storage, </p> <div class="org-src-container"> <pre class="src src-sh">git annex initremote cloud <span style="font-weight: bold; font-style: italic;">type</span>=S3 <span style="font-weight: bold; font-style: italic;">encryption</span>=hybrid <span style="font-weight: bold; font-style: italic;">keyid</span>=ID <span style="font-weight: bold; font-style: italic;">embedcreds</span>=yes <span style="font-weight: bold; font-style: italic;">host</span>=storage.googleapis.com <span style="font-weight: bold; font-style: italic;">port</span>=80 <span style="font-weight: bold; font-style: italic;">chunk</span>=250MiB </pre> </div> <p> Setup encrypted annex rsync remote, </p> <div class="org-src-container"> <pre class="src src-sh">git annex initremote depot <span style="font-weight: bold; font-style: italic;">type</span>=rsync <span style="font-weight: bold; font-style: italic;">encryption</span>=hybrid <span style="font-weight: bold; font-style: italic;">rsyncurl</span>=rsync:annex/repo/ <span style="font-weight: bold; font-style: italic;">keyid</span>=ID </pre> </div> </div> </div> </div> <div id="outline-container-sec-2" class="outline-2"> <h2 id="sec-2">~/source/</h2> <div class="outline-text-2" id="text-2"> </div><div id="outline-container-sec-2-0-1" class="outline-4"> <h4 id="sec-2-0-1">~/source/.mrconfig</h4> <div class="outline-text-4" id="text-2-0-1"> <p> Git Repos, </p> <div class="org-src-container"> <pre class="src src-conf">[<span style="font-weight: bold; text-decoration: underline;">DEFAULT</span>] <span style="font-weight: bold; font-style: italic;">git_pull</span> = git pull origin master <span style="font-weight: bold; font-style: italic;">git_push</span> = git fast-push <span style="font-weight: bold; font-style: italic;">git_status</span> = git status --short <span style="font-weight: bold; font-style: italic;">sync</span> = git pull &amp;&amp; git push [<span style="font-weight: bold; text-decoration: underline;">source/latte</span>] <span style="font-weight: bold; font-style: italic;">checkout</span> = git clone <span style="color: #afafff; font-style: italic;">'https://git.nakkaya.com/git/nakkaya/latte.git'</span> <span style="color: #afafff; font-style: italic;">'latte'</span> <span style="font-weight: bold; font-style: italic;">skip</span>=lazy [<span style="font-weight: bold; text-decoration: underline;">source/alter-ego</span>] <span style="font-weight: bold; font-style: italic;">checkout</span> = git clone <span style="color: #afafff; font-style: italic;">'git@github.com:nakkaya/alter-ego.git'</span> <span style="color: #afafff; font-style: italic;">'alter-ego'</span> <span style="font-weight: bold; font-style: italic;">skip</span>=lazy [<span style="font-weight: bold; text-decoration: underline;">source/ardrone</span>] <span style="font-weight: bold; font-style: italic;">checkout</span> = git clone <span style="color: #afafff; font-style: italic;">'git@github.com:nakkaya/ardrone.git'</span> <span style="color: #afafff; font-style: italic;">'ardrone'</span> <span style="font-weight: bold; font-style: italic;">skip</span>=lazy [<span style="font-weight: bold; text-decoration: underline;">source/clodiuno</span>] <span style="font-weight: bold; font-style: italic;">checkout</span> = git clone <span style="color: #afafff; font-style: italic;">'git@github.com:nakkaya/clodiuno.git'</span> <span style="color: #afafff; font-style: italic;">'clodiuno'</span> <span style="font-weight: bold; font-style: italic;">skip</span>=lazy [<span style="font-weight: bold; text-decoration: underline;">source/easy-dns</span>] <span style="font-weight: bold; font-style: italic;">checkout</span> = git clone <span style="color: #afafff; font-style: italic;">'git@github.com:nakkaya/easy-dns.git'</span> <span style="color: #afafff; font-style: italic;">'easy-dns'</span> <span style="font-weight: bold; font-style: italic;">skip</span>=lazy [<span style="font-weight: bold; text-decoration: underline;">source/emacs</span>] <span style="font-weight: bold; font-style: italic;">checkout</span> = git clone <span style="color: #afafff; font-style: italic;">'git@github.com:nakkaya/emacs.git'</span> <span style="color: #afafff; font-style: italic;">'emacs'</span> cd emacs git submodule init git submodule update [<span style="font-weight: bold; text-decoration: underline;">source/inbox-feed</span>] <span style="font-weight: bold; font-style: italic;">checkout</span> = git clone <span style="color: #afafff; font-style: italic;">'git@github.com:nakkaya/inbox-feed.git'</span> <span style="color: #afafff; font-style: italic;">'inbox-feed'</span> <span style="font-weight: bold; font-style: italic;">skip</span>=lazy [<span style="font-weight: bold; text-decoration: underline;">source/nakkaya.com</span>] <span style="font-weight: bold; font-style: italic;">checkout</span> = git clone <span style="color: #afafff; font-style: italic;">'git@github.com:nakkaya/nakkaya.com.git'</span> <span style="color: #afafff; font-style: italic;">'nakkaya.com'</span> <span style="font-weight: bold; font-style: italic;">skip</span>=lazy [<span style="font-weight: bold; text-decoration: underline;">source/net-eval</span>] <span style="font-weight: bold; font-style: italic;">checkout</span> = git clone <span style="color: #afafff; font-style: italic;">'git@github.com:nakkaya/net-eval.git'</span> <span style="color: #afafff; font-style: italic;">'net-eval'</span> <span style="font-weight: bold; font-style: italic;">skip</span>=lazy [<span style="font-weight: bold; text-decoration: underline;">source/neu-islanders</span>] <span style="font-weight: bold; font-style: italic;">checkout</span> = git clone <span style="color: #afafff; font-style: italic;">'https://git.nakkaya.com/git/nakkaya/neu-islanders.git'</span> <span style="color: #afafff; font-style: italic;">'neu-islanders'</span> <span style="font-weight: bold; font-style: italic;">skip</span>=lazy [<span style="font-weight: bold; text-decoration: underline;">source/static</span>] <span style="font-weight: bold; font-style: italic;">checkout</span> = git clone <span style="color: #afafff; font-style: italic;">'git@github.com:nakkaya/static.git'</span> <span style="color: #afafff; font-style: italic;">'static'</span> <span style="font-weight: bold; font-style: italic;">skip</span>=lazy [<span style="font-weight: bold; text-decoration: underline;">source/vector-2d</span>] <span style="font-weight: bold; font-style: italic;">checkout</span> = git clone <span style="color: #afafff; font-style: italic;">'git@github.com:nakkaya/vector-2d.git'</span> <span style="color: #afafff; font-style: italic;">'vector-2d'</span> <span style="font-weight: bold; font-style: italic;">skip</span>=lazy [<span style="font-weight: bold; text-decoration: underline;">source/doganilic.com</span>] <span style="font-weight: bold; font-style: italic;">checkout</span> = git clone <span style="color: #afafff; font-style: italic;">'https://git.nakkaya.com/git/nakkaya/doganilic.com.git'</span> <span style="color: #afafff; font-style: italic;">'doganilic.com'</span> <span style="font-weight: bold; font-style: italic;">skip</span>=lazy [<span style="font-weight: bold; text-decoration: underline;">source/ansible-docker-build</span>] <span style="font-weight: bold; font-style: italic;">checkout</span> = git clone <span style="color: #afafff; font-style: italic;">'https://git.nakkaya.com/git/nakkaya/ansible-docker-build.git'</span> <span style="color: #afafff; font-style: italic;">'ansible-docker-build'</span> <span style="font-weight: bold; font-style: italic;">skip</span>=lazy [<span style="font-weight: bold; text-decoration: underline;">source/ansible-storage</span>] <span style="font-weight: bold; font-style: italic;">checkout</span> = git clone <span style="color: #afafff; font-style: italic;">'https://git.nakkaya.com/git/nakkaya/ansible-storage.git'</span> <span style="color: #afafff; font-style: italic;">'ansible-storage'</span> <span style="font-weight: bold; font-style: italic;">skip</span>=lazy [<span style="font-weight: bold; text-decoration: underline;">source/ansible-base</span>] <span style="font-weight: bold; font-style: italic;">checkout</span> = git clone <span style="color: #afafff; font-style: italic;">'https://git.nakkaya.com/git/nakkaya/ansible-base.git'</span> <span style="color: #afafff; font-style: italic;">'ansible-base'</span> <span style="font-weight: bold; font-style: italic;">skip</span>=lazy [<span style="font-weight: bold; text-decoration: underline;">source/ansible-backup</span>] <span style="font-weight: bold; font-style: italic;">checkout</span> = git clone <span style="color: #afafff; font-style: italic;">'https://git.nakkaya.com/git/nakkaya/ansible-backup.git'</span> <span style="color: #afafff; font-style: italic;">'ansible-backup'</span> <span style="font-weight: bold; font-style: italic;">skip</span>=lazy [<span style="font-weight: bold; text-decoration: underline;">source/control-toolbox</span>] <span style="font-weight: bold; font-style: italic;">checkout</span> = git clone <span style="color: #afafff; font-style: italic;">'https://git.nakkaya.com/git/nakkaya/control-toolbox.git'</span> <span style="color: #afafff; font-style: italic;">'control-toolbox'</span> <span style="font-weight: bold; font-style: italic;">skip</span>=lazy [<span style="font-weight: bold; text-decoration: underline;">source/solarcar-tracker</span>] <span style="font-weight: bold; font-style: italic;">checkout</span> = git clone <span style="color: #afafff; font-style: italic;">'https://git.nakkaya.com/git/nakkaya/solarcar-tracker.git'</span> <span style="color: #afafff; font-style: italic;">'solarcar-tracker'</span> <span style="font-weight: bold; font-style: italic;">skip</span>=lazy [<span style="font-weight: bold; text-decoration: underline;">source/solarcar-turn-indicator</span>] <span style="font-weight: bold; font-style: italic;">checkout</span> = git clone <span style="color: #afafff; font-style: italic;">'https://git.nakkaya.com/git/nakkaya/solarcar-turn-indicator.git'</span> <span style="color: #afafff; font-style: italic;">'solarcar-turn-indicator'</span> <span style="font-weight: bold; font-style: italic;">skip</span>=lazy [<span style="font-weight: bold; text-decoration: underline;">source/ferret</span>] <span style="font-weight: bold; font-style: italic;">checkout</span> = git clone <span style="color: #afafff; font-style: italic;">'https://git.nakkaya.com/git/nakkaya/ferret.git'</span> <span style="color: #afafff; font-style: italic;">'ferret'</span> <span style="font-weight: bold; font-style: italic;">skip</span>=lazy </pre> </div> </div> </div> </div> Git SSH Verbosehttp://nakkaya.com/2013/08/26/git-ssh-debugging/Mon, 26 Aug 2013 00:00:00 +0300<p>Note to self, debugging git ssh interaction,</p> <pre><code>GIT_TRACE=2 git &lt;command&gt; </code></pre>Using Clojure with org-babel and nREPLhttp://nakkaya.com/2013/04/06/using-clojure-with-org-babel-and-nrepl/Sat, 6 Apr 2013 00:00:00 +0300<p> When I first made the switch to nREPL, I just modified the code from my from <a href="http://nakkaya.com/2010/12/12/using-clojure-with-org-babel-and-inferior-lisp/">Using Clojure with org-babel and inferior-lisp</a> post, replacing <i>lisp-eval-string</i> with <i>nrepl-interactive-eval</i>, did a quick test and assumed it was all working fine. </p> <p> Couple of days ago I had to go back and fix a literate program, that's when I figured out there are couple of problems with using nREPL with org-babel. nREPL does not respect <i>:main</i> from <i>project.clj</i> so unless the first thing you evaluate in the org file is a <i>ns</i> declaration it will evaluate all blocks in <i>user</i> namespace, to fix this we have to create a buffer local variable called <i>nrepl-buffer-ns</i> that points to the main namespace. </p> <pre class="example"> # -*- mode: org; nrepl-buffer-ns: "project.core"; -*- </pre> <p> When you try to edit the source block using C-c ' (org-edit-src-code), new buffer org-mode creates does not inherit the namespace so any expression evaluated there again goes to <i>user</i> namespace to fix this below snippet adds a hook that will grab the value of <i>nrepl-buffer-ns</i> from the base org file and set it in the edit buffer. </p> <div class="org-src-container"> <pre class="src src-emacs-lisp">(<span style="color: #ff5f00; font-weight: bold;">require</span> '<span style="font-weight: bold; text-decoration: underline;">ob</span>) (add-to-list 'org-babel-tangle-lang-exts '(<span style="color: #afafff; font-style: italic;">"clojure"</span> . <span style="color: #afafff; font-style: italic;">"clj"</span>)) (<span style="color: #ff5f00; font-weight: bold;">defvar</span> <span style="font-weight: bold; font-style: italic;">org-babel-default-header-args:clojure</span> '((<span style="color: #afd700; font-weight: bold;">:results</span> . <span style="color: #afafff; font-style: italic;">"silent"</span>))) (<span style="color: #ff5f00; font-weight: bold;">defun</span> <span style="color: #d7af00; font-weight: bold;">org-babel-execute:clojure</span> (body params) <span style="color: #afafff; font-style: italic;">"Execute a block of Clojure code with Babel."</span> (nrepl-interactive-eval body)) (add-hook 'org-src-mode-hook '(<span style="color: #ff5f00; font-weight: bold;">lambda</span> () (set (make-local-variable 'nrepl-buffer-ns) (<span style="color: #ff5f00; font-weight: bold;">with-current-buffer</span> (overlay-buffer org-edit-src-overlay) nrepl-buffer-ns)))) (<span style="color: #ff5f00; font-weight: bold;">provide</span> '<span style="font-weight: bold; text-decoration: underline;">ob-clojure</span>) </pre> </div>