<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wikidot="http://www.wikidot.com/rss-namespace">

	<channel>
		<title>Piotr Gabryjeluk blog</title>
		<link>http://piotrgabryjeluk.wikidot.com</link>
		<description>Blog, photos and developer notes of Piotr Gabryjeluk, one of Wikidot.com developers.</description>
				<copyright></copyright>
		<lastBuildDate>Fri, 10 Jul 2026 14:46:54 +0000</lastBuildDate>
		
					<item>
				<guid>http://piotrgabryjeluk.wikidot.com/blog:how-to-disable-kinetic-scrolling-on-linux</guid>
				<title>How To Disable Kinetic Scrolling On Linux</title>
				<link>http://piotrgabryjeluk.wikidot.com/blog:how-to-disable-kinetic-scrolling-on-linux</link>
				<description>

&lt;p&gt;I spent more time than I wished searching for how to disable kinetic scrolling on Linux. Here&#039;s the spell:&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=2462&amp;amp;amp;size=small&amp;amp;amp;timestamp=1783694814&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Tue, 14 Feb 2017 04:44:11 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>I spent more time than I wished searching for how to disable kinetic scrolling on Linux. Here's the spell:</p> <div class="code"> <pre><code>$ synclient CoastingSpeed=0</code></pre></div> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=2462&amp;amp;size=small&amp;amp;timestamp=1783694814" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotrgabryjeluk.wikidot.com/blog:monitoring-freezer-temperature</guid>
				<title>Monitoring Freezer Temperature</title>
				<link>http://piotrgabryjeluk.wikidot.com/blog:monitoring-freezer-temperature</link>
				<description>

&lt;p&gt;For some time we&#039;ve had suspicions the freezer in our apartment doesn&#039;t work correctly. Recently my wife reached to it to get some ice cubes but found water in the form instead. That clearly meant the temperature was over the freezing point and stayed there for some time. She put a thermometer on the fridge, put the sensor into the freezer and started watching the readings. The temperature reached around -20°C and stayed there, fluctuating between -15°C and -20°C.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=2462&amp;amp;amp;size=small&amp;amp;amp;timestamp=1783694814&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Sun, 25 Sep 2016 22:11:15 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>For some time we've had suspicions the freezer in our apartment doesn't work correctly. Recently my wife reached to it to get some ice cubes but found water in the form instead. That clearly meant the temperature was over the freezing point and stayed there for some time. She put a thermometer on the fridge, put the sensor into the freezer and started watching the readings. The temperature reached around -20°C and stayed there, fluctuating between -15°C and -20°C.</p> <h1><span>The webcam reader</span></h1> <p>I decided, it's time to record the temperature, so I brought the laptop, adjusted the screen angle, set the brightness to max and took a shot from the webcam to see if the thermometer is in the view of the camera:</p> <div class="code"> <pre><code>mplayer tv:// -vo png -frames 3</code></pre></div> <p>This takes 3 frames from the webcam and saves them as PNG files: 00000001.png, 00000002.png, and 00000003.png. If you wonder why I need 3 frames, the first one is always under- or overexposed and out of focus, the second is usually OK and the third is almost always good (as for a webcam), so long story short, I'm giving some time to the camera to auto-adjust its settings.</p> <p>Here's a script that does just a bit more than that:</p> <div class="code"> <pre><code>#!/bin/bash set -e export DISPLAY=:0 curdate=`date +%x-%X | sed 's/[\.:]//g'` outpng=/home/quake/git/thermonitor/out/&quot;$curdate&quot;.png tmppng=/home/quake/git/thermonitor/tmp/00000005.png mkdir -p /home/quake/git/thermonitor/out/ /home/quake/git/thermonitor/tmp cd /home/quake/git/thermonitor/tmp # White background ristretto ../white.png &amp; # Wake screen xte &quot;mousemove 100 100&quot; sleep 0.2 xte &quot;mousemove 99 99&quot; # Dump screen mplayer tv:// -vo png -frames 5 -noconsolecontrols cp &quot;$tmppng&quot; &quot;$outpng&quot; echo &quot;$outpng&quot; kill $!</code></pre></div> <p>It's very hacky, but here are the big parts:</p> <ul> <li><tt>set -e</tt> makes the script stop if any of the commands in it fail</li> <li><tt>export DISPLAY=:0</tt> selects the default X display, so I can run the command from an SSH shell</li> <li>Then we have some hard-coded paths to <tt>tmp</tt> and <tt>out</tt> directories</li> <li><tt>ristretto ./white.png &amp;</tt> starts a image-viewer and shows a <tt>white.png</tt> file which is a big all-white file. This makes the screen display enough white, so the LCD thermometer is properly lit</li> <li>I use <tt>xte</tt> to move the mouse around: this blocks the automatic screen dimming, so the screen continues to be 100% bright</li> <li>Then we have the <tt>mplayer</tt> command from before, just changed to 5 frames (just to be sure) and <tt>-noconsolecontrols</tt>. <tt>mplayer</tt> kind of hangs when you start it without a proper terminal on stdin, unless you pass this option</li> <li>Then I copy the 5th frame to the output file, which has the current date and the time in its path</li> <li>Finally I close the ristretto process I opened before</li> </ul> <p>I run this command in a while loop like that:</p> <div class="code"> <pre><code>while sleep 28 ; do ./dup.sh ; done</code></pre></div> <p><tt>./dup.sh</tt> takes around 2 seconds, so I have about 2 photos a minute.</p> <p>I put that to a screen session.</p> <p>Now in the <tt>out</tt> directory I serve the files using Python HTTP server:</p> <div class="code"> <pre><code>python -m SimpleHTTPServer</code></pre></div> <p>This starts an HTTP server on port 8000 and serves all the files and creates an index of them when requesting /.</p> <h1><span>The processing</span></h1> <p>How easier to copy the HTTP-exposed files than using a plain-old <tt>wget</tt> command?</p> <div class="code"> <pre><code>wget -r http://dell:8000/</code></pre></div> <p>This creates directory <tt>dell:8000</tt> and downloads all the PNG files to it.</p> <p>Once you have that directory you may later want to update it with only the newer files:</p> <div class="code"> <pre><code>rm dell\:8000/index.html wget -nc -r http://dell:8000/</code></pre></div> <p>The <tt>-nc</tt> switch makes <tt>wget</tt> ignore files that are already there. We explicitly remove the <tt>index.html</tt> so it downloads a new list (that includes newer files).</p> <p>I wanted to make a program that gets a photo of the 7-segment display and reads it producing a number that along with the date could be used to graph the temperature over time.</p> <p>First, let's use ImageMagick to:</p> <ul> <li>crop the picture to only the interesting part: the OUT reading</li> <li>shear the picture to make the LCD segments vertical and horizontal, not skewed</li> <li>bump contrast/gamma to remove the noise</li> <li>auto-adjust the visual properties of the picture so it's more consistent across different times (like night vs day)</li> <li>make it black and white &#8212; turned out it works best if I only use the Green channel, R and B turned out more noisy than G.</li> <li>resize to as small size as needed &#8212; for easier and faster processing</li> </ul> <p>Here's the actual command:</p> <div class="code"> <pre><code>convert $file_in -gamma 1.5 -auto-level -brightness-contrast 35x80 -shear -14x0 -crop 260x70+320+227 -channel Green -separate -resize 40x20 $file_out</code></pre></div> <p>Input image:</p> <img src="http://piotrgabryjeluk.wdfiles.com/local--files/blog:monitoring-freezer-temperature/input.png" alt="input.png" class="image" /> <p>Output image:</p> <img src="http://piotrgabryjeluk.wdfiles.com/local--files/blog:monitoring-freezer-temperature/output.png" alt="output.png" class="image" /> <p>Zoomed in:</p> <img src="http://piotrgabryjeluk.wdfiles.com/local--files/blog:monitoring-freezer-temperature/output-scaled.png" alt="output-scaled.png" class="image" /> <p>You can see the bottom segment is not really visible, but that's OK, all the digits can be properly read without that segment being visible, so we'll only consider the 6 segments that we can easily read.</p> <p>Now comes the meat, the Python program reading the file and returning the temperature:</p> <div class="code"> <div class="hl-main"> <pre><span class="hl-comment">#!/usr/bin/env python</span><span class="hl-code"> </span><span class="hl-comment">#encoding: utf-8</span><span class="hl-code"> </span><span class="hl-reserved">from</span><span class="hl-code"> </span><span class="hl-identifier">PIL</span><span class="hl-code"> </span><span class="hl-reserved">import</span><span class="hl-code"> </span><span class="hl-identifier">Image</span><span class="hl-code"> </span><span class="hl-comment"># Points that hold each segment:</span><span class="hl-code"> </span><span class="hl-comment"># d1 is the first digit</span><span class="hl-code"> </span><span class="hl-identifier">d1_sA</span><span class="hl-code"> = </span><span class="hl-brackets">[(</span><span class="hl-number">12</span><span class="hl-code">,</span><span class="hl-number">1</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">13</span><span class="hl-code">,</span><span class="hl-number">1</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">14</span><span class="hl-code">,</span><span class="hl-number">1</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">15</span><span class="hl-code">,</span><span class="hl-number">1</span><span class="hl-brackets">)]</span><span class="hl-code"> </span><span class="hl-identifier">d1_sB</span><span class="hl-code"> = </span><span class="hl-brackets">[(</span><span class="hl-number">18</span><span class="hl-code">,</span><span class="hl-number">2</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">18</span><span class="hl-code">,</span><span class="hl-number">3</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">18</span><span class="hl-code">,</span><span class="hl-number">4</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">18</span><span class="hl-code">,</span><span class="hl-number">5</span><span class="hl-brackets">)]</span><span class="hl-code"> </span><span class="hl-identifier">d1_sC</span><span class="hl-code"> = </span><span class="hl-brackets">[(</span><span class="hl-number">18</span><span class="hl-code">,</span><span class="hl-number">8</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">18</span><span class="hl-code">,</span><span class="hl-number">9</span><span class="hl-brackets">)]</span><span class="hl-code"> </span><span class="hl-identifier">d1_sE</span><span class="hl-code"> = </span><span class="hl-brackets">[(</span><span class="hl-number">11</span><span class="hl-code">,</span><span class="hl-number">8</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">12</span><span class="hl-code">,</span><span class="hl-number">9</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">11</span><span class="hl-code">,</span><span class="hl-number">9</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">12</span><span class="hl-code">,</span><span class="hl-number">8</span><span class="hl-brackets">)]</span><span class="hl-code"> </span><span class="hl-comment"># Don't need this, as we only ever have 1 and 2 in the first place</span><span class="hl-code"> </span><span class="hl-identifier">d1_sF</span><span class="hl-code"> = </span><span class="hl-brackets">[]</span><span class="hl-code"> </span><span class="hl-identifier">d1_sG</span><span class="hl-code"> = </span><span class="hl-brackets">[(</span><span class="hl-number">13</span><span class="hl-code">,</span><span class="hl-number">7</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">14</span><span class="hl-code">,</span><span class="hl-number">7</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">15</span><span class="hl-code">,</span><span class="hl-number">7</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">16</span><span class="hl-code">,</span><span class="hl-number">7</span><span class="hl-brackets">)]</span><span class="hl-code"> </span><span class="hl-comment"># d2 is the second digit</span><span class="hl-code"> </span><span class="hl-identifier">d2_sA</span><span class="hl-code"> = </span><span class="hl-brackets">[(</span><span class="hl-number">24</span><span class="hl-code">,</span><span class="hl-number">1</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">25</span><span class="hl-code">,</span><span class="hl-number">1</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">26</span><span class="hl-code">,</span><span class="hl-number">1</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">27</span><span class="hl-code">,</span><span class="hl-number">1</span><span class="hl-brackets">)]</span><span class="hl-code"> </span><span class="hl-identifier">d2_sB</span><span class="hl-code"> = </span><span class="hl-brackets">[(</span><span class="hl-number">29</span><span class="hl-code">,</span><span class="hl-number">2</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">29</span><span class="hl-code">,</span><span class="hl-number">3</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">29</span><span class="hl-code">,</span><span class="hl-number">4</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">29</span><span class="hl-code">,</span><span class="hl-number">5</span><span class="hl-brackets">)]</span><span class="hl-code"> </span><span class="hl-identifier">d2_sC</span><span class="hl-code"> = </span><span class="hl-brackets">[(</span><span class="hl-number">29</span><span class="hl-code">,</span><span class="hl-number">8</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">29</span><span class="hl-code">,</span><span class="hl-number">9</span><span class="hl-brackets">)]</span><span class="hl-code"> </span><span class="hl-identifier">d2_sE</span><span class="hl-code"> = </span><span class="hl-brackets">[(</span><span class="hl-number">22</span><span class="hl-code">,</span><span class="hl-number">8</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">22</span><span class="hl-code">,</span><span class="hl-number">9</span><span class="hl-brackets">)]</span><span class="hl-code"> </span><span class="hl-identifier">d2_sF</span><span class="hl-code"> = </span><span class="hl-brackets">[(</span><span class="hl-number">22</span><span class="hl-code">,</span><span class="hl-number">2</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">22</span><span class="hl-code">,</span><span class="hl-number">3</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">22</span><span class="hl-code">,</span><span class="hl-number">4</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">22</span><span class="hl-code">,</span><span class="hl-number">5</span><span class="hl-brackets">)]</span><span class="hl-code"> </span><span class="hl-identifier">d2_sG</span><span class="hl-code"> = </span><span class="hl-brackets">[(</span><span class="hl-number">24</span><span class="hl-code">,</span><span class="hl-number">6</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">25</span><span class="hl-code">,</span><span class="hl-number">6</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">26</span><span class="hl-code">,</span><span class="hl-number">6</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">24</span><span class="hl-code">,</span><span class="hl-number">7</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">25</span><span class="hl-code">,</span><span class="hl-number">7</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">26</span><span class="hl-code">,</span><span class="hl-number">7</span><span class="hl-brackets">)]</span><span class="hl-code"> </span><span class="hl-comment"># d3 is the small digit (first after the decimal point)</span><span class="hl-code"> </span><span class="hl-identifier">d3_sA</span><span class="hl-code"> = </span><span class="hl-brackets">[(</span><span class="hl-number">35</span><span class="hl-code">,</span><span class="hl-number">4</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">36</span><span class="hl-code">,</span><span class="hl-number">4</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">37</span><span class="hl-code">,</span><span class="hl-number">4</span><span class="hl-brackets">)]</span><span class="hl-code"> </span><span class="hl-identifier">d3_sB</span><span class="hl-code"> = </span><span class="hl-brackets">[(</span><span class="hl-number">38</span><span class="hl-code">,</span><span class="hl-number">5</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">38</span><span class="hl-code">,</span><span class="hl-number">6</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">38</span><span class="hl-code">,</span><span class="hl-number">7</span><span class="hl-brackets">)]</span><span class="hl-code"> </span><span class="hl-identifier">d3_sC</span><span class="hl-code"> = </span><span class="hl-brackets">[(</span><span class="hl-number">38</span><span class="hl-code">,</span><span class="hl-number">9</span><span class="hl-brackets">)]</span><span class="hl-code"> </span><span class="hl-identifier">d3_sE</span><span class="hl-code"> = </span><span class="hl-brackets">[(</span><span class="hl-number">34</span><span class="hl-code">,</span><span class="hl-number">9</span><span class="hl-brackets">)]</span><span class="hl-code"> </span><span class="hl-identifier">d3_sF</span><span class="hl-code"> = </span><span class="hl-brackets">[(</span><span class="hl-number">34</span><span class="hl-code">,</span><span class="hl-number">5</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">34</span><span class="hl-code">,</span><span class="hl-number">6</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">34</span><span class="hl-code">,</span><span class="hl-number">7</span><span class="hl-brackets">)]</span><span class="hl-code"> </span><span class="hl-identifier">d3_sG</span><span class="hl-code"> = </span><span class="hl-brackets">[(</span><span class="hl-number">35</span><span class="hl-code">,</span><span class="hl-number">8</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">36</span><span class="hl-code">,</span><span class="hl-number">8</span><span class="hl-brackets">)]</span><span class="hl-code"> </span><span class="hl-comment"># Now the tricky part, for each segment I define a threshold below which I consider it &quot;lit&quot;</span><span class="hl-code"> </span><span class="hl-comment"># 0 means completely black, 255 is white.</span><span class="hl-code"> </span><span class="hl-comment"># Because of uneven lighting, for each segment (and digit, but we ignore that) the value is different.</span><span class="hl-code"> </span><span class="hl-identifier">tA</span><span class="hl-code"> = </span><span class="hl-number">200</span><span class="hl-code"> </span><span class="hl-identifier">tB</span><span class="hl-code"> = </span><span class="hl-number">170</span><span class="hl-code"> </span><span class="hl-identifier">tC</span><span class="hl-code"> = </span><span class="hl-number">120</span><span class="hl-code"> </span><span class="hl-identifier">tE</span><span class="hl-code"> = </span><span class="hl-number">115</span><span class="hl-code"> </span><span class="hl-identifier">tF</span><span class="hl-code"> = </span><span class="hl-number">140</span><span class="hl-code"> </span><span class="hl-identifier">tG</span><span class="hl-code"> = </span><span class="hl-number">170</span><span class="hl-code"> </span><span class="hl-comment"># A threshold for the &quot;-&quot; sign</span><span class="hl-code"> </span><span class="hl-identifier">tSIGN</span><span class="hl-code"> = </span><span class="hl-number">200</span><span class="hl-code"> </span><span class="hl-comment"># All of those were obviously updated on the go to match the files</span><span class="hl-code"> </span><span class="hl-comment"># A nice debugging function that prints which segments the code considers lit</span><span class="hl-code"> </span><span class="hl-comment"># Also if you wondered what A, B, C, E, F, G meant, here's the schematic:</span><span class="hl-code"> </span><span class="hl-reserved">def</span><span class="hl-code"> </span><span class="hl-identifier">print_digit</span><span class="hl-brackets">(</span><span class="hl-identifier">segs</span><span class="hl-brackets">)</span><span class="hl-code">: </span><span class="hl-comment"># Only print this if there's a second argument to the script passed</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-builtin">len</span><span class="hl-brackets">(</span><span class="hl-identifier">sys</span><span class="hl-code">.</span><span class="hl-identifier">argv</span><span class="hl-brackets">)</span><span class="hl-code"> == </span><span class="hl-number">2</span><span class="hl-code">: </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-reserved">print</span><span class="hl-code"> </span><span class="hl-quotes">'''</span><span class="hl-string"> {A}{A} {A}{A} {F} {B} {F} {B} {F} {B} {G}{G} {G}{G} {E} {C} {E} {C} {E} {C} </span><span class="hl-quotes">'''</span><span class="hl-code">.</span><span class="hl-identifier">format</span><span class="hl-brackets">(</span><span class="hl-code"> </span><span class="hl-identifier">A</span><span class="hl-code">=</span><span class="hl-quotes">'</span><span class="hl-string">###</span><span class="hl-quotes">'</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-quotes">'</span><span class="hl-string">A</span><span class="hl-quotes">'</span><span class="hl-code"> </span><span class="hl-reserved">in</span><span class="hl-code"> </span><span class="hl-identifier">segs</span><span class="hl-code"> </span><span class="hl-reserved">else</span><span class="hl-code"> </span><span class="hl-quotes">'</span><span class="hl-string"> </span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-identifier">B</span><span class="hl-code">=</span><span class="hl-quotes">'</span><span class="hl-string">###</span><span class="hl-quotes">'</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-quotes">'</span><span class="hl-string">B</span><span class="hl-quotes">'</span><span class="hl-code"> </span><span class="hl-reserved">in</span><span class="hl-code"> </span><span class="hl-identifier">segs</span><span class="hl-code"> </span><span class="hl-reserved">else</span><span class="hl-code"> </span><span class="hl-quotes">'</span><span class="hl-string"> </span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-identifier">C</span><span class="hl-code">=</span><span class="hl-quotes">'</span><span class="hl-string">###</span><span class="hl-quotes">'</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-quotes">'</span><span class="hl-string">C</span><span class="hl-quotes">'</span><span class="hl-code"> </span><span class="hl-reserved">in</span><span class="hl-code"> </span><span class="hl-identifier">segs</span><span class="hl-code"> </span><span class="hl-reserved">else</span><span class="hl-code"> </span><span class="hl-quotes">'</span><span class="hl-string"> </span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-identifier">E</span><span class="hl-code">=</span><span class="hl-quotes">'</span><span class="hl-string">###</span><span class="hl-quotes">'</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-quotes">'</span><span class="hl-string">E</span><span class="hl-quotes">'</span><span class="hl-code"> </span><span class="hl-reserved">in</span><span class="hl-code"> </span><span class="hl-identifier">segs</span><span class="hl-code"> </span><span class="hl-reserved">else</span><span class="hl-code"> </span><span class="hl-quotes">'</span><span class="hl-string"> </span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-identifier">F</span><span class="hl-code">=</span><span class="hl-quotes">'</span><span class="hl-string">###</span><span class="hl-quotes">'</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-quotes">'</span><span class="hl-string">F</span><span class="hl-quotes">'</span><span class="hl-code"> </span><span class="hl-reserved">in</span><span class="hl-code"> </span><span class="hl-identifier">segs</span><span class="hl-code"> </span><span class="hl-reserved">else</span><span class="hl-code"> </span><span class="hl-quotes">'</span><span class="hl-string"> </span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-identifier">G</span><span class="hl-code">=</span><span class="hl-quotes">'</span><span class="hl-string">###</span><span class="hl-quotes">'</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-quotes">'</span><span class="hl-string">G</span><span class="hl-quotes">'</span><span class="hl-code"> </span><span class="hl-reserved">in</span><span class="hl-code"> </span><span class="hl-identifier">segs</span><span class="hl-code"> </span><span class="hl-reserved">else</span><span class="hl-code"> </span><span class="hl-quotes">'</span><span class="hl-string"> </span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-comment"># This doesn't do anything spectacular, just passes the coordinates for each of the segments and the average value of the first 9 pixels of the image: (0,0) - (3,3)</span><span class="hl-code"> </span><span class="hl-reserved">def</span><span class="hl-code"> </span><span class="hl-identifier">read_digit</span><span class="hl-brackets">(</span><span class="hl-identifier">im</span><span class="hl-code">, </span><span class="hl-identifier">pointsA</span><span class="hl-code">, </span><span class="hl-identifier">pointsB</span><span class="hl-code">, </span><span class="hl-identifier">pointsC</span><span class="hl-code">, </span><span class="hl-identifier">pointsE</span><span class="hl-code">, </span><span class="hl-identifier">pointsF</span><span class="hl-code">, </span><span class="hl-identifier">pointsG</span><span class="hl-code">, </span><span class="hl-identifier">avg9px</span><span class="hl-brackets">)</span><span class="hl-code">: </span><span class="hl-identifier">segs</span><span class="hl-code"> = </span><span class="hl-quotes">''</span><span class="hl-code"> </span><span class="hl-identifier">segs</span><span class="hl-code"> += </span><span class="hl-quotes">'</span><span class="hl-string">A</span><span class="hl-quotes">'</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-identifier">read_segment</span><span class="hl-brackets">(</span><span class="hl-identifier">im</span><span class="hl-code">, </span><span class="hl-identifier">pointsA</span><span class="hl-code">, </span><span class="hl-identifier">tA</span><span class="hl-code">-</span><span class="hl-identifier">avg9px</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-reserved">else</span><span class="hl-code"> </span><span class="hl-quotes">''</span><span class="hl-code"> </span><span class="hl-identifier">segs</span><span class="hl-code"> += </span><span class="hl-quotes">'</span><span class="hl-string">B</span><span class="hl-quotes">'</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-identifier">read_segment</span><span class="hl-brackets">(</span><span class="hl-identifier">im</span><span class="hl-code">, </span><span class="hl-identifier">pointsB</span><span class="hl-code">, </span><span class="hl-identifier">tB</span><span class="hl-code">-</span><span class="hl-identifier">avg9px</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-reserved">else</span><span class="hl-code"> </span><span class="hl-quotes">''</span><span class="hl-code"> </span><span class="hl-identifier">segs</span><span class="hl-code"> += </span><span class="hl-quotes">'</span><span class="hl-string">C</span><span class="hl-quotes">'</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-identifier">read_segment</span><span class="hl-brackets">(</span><span class="hl-identifier">im</span><span class="hl-code">, </span><span class="hl-identifier">pointsC</span><span class="hl-code">, </span><span class="hl-identifier">tC</span><span class="hl-code">-</span><span class="hl-identifier">avg9px</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-reserved">else</span><span class="hl-code"> </span><span class="hl-quotes">''</span><span class="hl-code"> </span><span class="hl-identifier">segs</span><span class="hl-code"> += </span><span class="hl-quotes">'</span><span class="hl-string">E</span><span class="hl-quotes">'</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-identifier">read_segment</span><span class="hl-brackets">(</span><span class="hl-identifier">im</span><span class="hl-code">, </span><span class="hl-identifier">pointsE</span><span class="hl-code">, </span><span class="hl-identifier">tE</span><span class="hl-code">-</span><span class="hl-identifier">avg9px</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-reserved">else</span><span class="hl-code"> </span><span class="hl-quotes">''</span><span class="hl-code"> </span><span class="hl-identifier">segs</span><span class="hl-code"> += </span><span class="hl-quotes">'</span><span class="hl-string">F</span><span class="hl-quotes">'</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-identifier">read_segment</span><span class="hl-brackets">(</span><span class="hl-identifier">im</span><span class="hl-code">, </span><span class="hl-identifier">pointsF</span><span class="hl-code">, </span><span class="hl-identifier">tF</span><span class="hl-code">-</span><span class="hl-identifier">avg9px</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-reserved">else</span><span class="hl-code"> </span><span class="hl-quotes">''</span><span class="hl-code"> </span><span class="hl-identifier">segs</span><span class="hl-code"> += </span><span class="hl-quotes">'</span><span class="hl-string">G</span><span class="hl-quotes">'</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-identifier">read_segment</span><span class="hl-brackets">(</span><span class="hl-identifier">im</span><span class="hl-code">, </span><span class="hl-identifier">pointsG</span><span class="hl-code">, </span><span class="hl-identifier">tG</span><span class="hl-code">-</span><span class="hl-identifier">avg9px</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-reserved">else</span><span class="hl-code"> </span><span class="hl-quotes">''</span><span class="hl-code"> </span><span class="hl-identifier">print_digit</span><span class="hl-brackets">(</span><span class="hl-identifier">segs</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-comment"># A list of all digits and their representation on the 7-segment display:</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-identifier">segs</span><span class="hl-code"> == </span><span class="hl-quotes">'</span><span class="hl-string">ABCEF</span><span class="hl-quotes">'</span><span class="hl-code">: </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-number">0</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-identifier">segs</span><span class="hl-code"> == </span><span class="hl-quotes">'</span><span class="hl-string">BC</span><span class="hl-quotes">'</span><span class="hl-code">: </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-number">1</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-identifier">segs</span><span class="hl-code"> == </span><span class="hl-quotes">'</span><span class="hl-string">ABEG</span><span class="hl-quotes">'</span><span class="hl-code">: </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-number">2</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-identifier">segs</span><span class="hl-code"> == </span><span class="hl-quotes">'</span><span class="hl-string">ABCG</span><span class="hl-quotes">'</span><span class="hl-code">: </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-number">3</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-identifier">segs</span><span class="hl-code"> == </span><span class="hl-quotes">'</span><span class="hl-string">BCFG</span><span class="hl-quotes">'</span><span class="hl-code">: </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-number">4</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-identifier">segs</span><span class="hl-code"> == </span><span class="hl-quotes">'</span><span class="hl-string">ACFG</span><span class="hl-quotes">'</span><span class="hl-code">: </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-number">5</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-identifier">segs</span><span class="hl-code"> == </span><span class="hl-quotes">'</span><span class="hl-string">ACEFG</span><span class="hl-quotes">'</span><span class="hl-code">: </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-number">6</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-identifier">segs</span><span class="hl-code"> == </span><span class="hl-quotes">'</span><span class="hl-string">ABC</span><span class="hl-quotes">'</span><span class="hl-code">: </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-number">7</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-identifier">segs</span><span class="hl-code"> == </span><span class="hl-quotes">'</span><span class="hl-string">ABCEFG</span><span class="hl-quotes">'</span><span class="hl-code">: </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-number">8</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-identifier">segs</span><span class="hl-code"> == </span><span class="hl-quotes">'</span><span class="hl-string">ABCFG</span><span class="hl-quotes">'</span><span class="hl-code">: </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-number">9</span><span class="hl-code"> </span><span class="hl-comment"># A special case for the first digit, it doesn't display &quot;0&quot;, just doesn't display any segments</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-identifier">segs</span><span class="hl-code"> == </span><span class="hl-quotes">''</span><span class="hl-code">: </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-number">0</span><span class="hl-code"> </span><span class="hl-comment"># The function that takes the PIL image object, gets a list of (x,y) coordinates</span><span class="hl-code"> </span><span class="hl-comment"># and checks if the average value of them is smaller than the threshold passed: segment &quot;on&quot;</span><span class="hl-code"> </span><span class="hl-comment"># For 0 points passed it returns False: segment &quot;off&quot;</span><span class="hl-code"> </span><span class="hl-reserved">def</span><span class="hl-code"> </span><span class="hl-identifier">read_segment</span><span class="hl-brackets">(</span><span class="hl-identifier">im</span><span class="hl-code">, </span><span class="hl-identifier">points</span><span class="hl-code">, </span><span class="hl-identifier">threshold</span><span class="hl-code">=</span><span class="hl-number">128</span><span class="hl-brackets">)</span><span class="hl-code">: </span><span class="hl-identifier">val</span><span class="hl-code"> = </span><span class="hl-number">0</span><span class="hl-code"> </span><span class="hl-reserved">for</span><span class="hl-code"> </span><span class="hl-identifier">point</span><span class="hl-code"> </span><span class="hl-reserved">in</span><span class="hl-code"> </span><span class="hl-identifier">points</span><span class="hl-code">: </span><span class="hl-identifier">val</span><span class="hl-code"> += </span><span class="hl-identifier">im</span><span class="hl-code">.</span><span class="hl-identifier">getpixel</span><span class="hl-brackets">(</span><span class="hl-identifier">point</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-identifier">val</span><span class="hl-code"> &lt; </span><span class="hl-identifier">threshold</span><span class="hl-code"> * </span><span class="hl-builtin">len</span><span class="hl-brackets">(</span><span class="hl-identifier">points</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-comment"># Nothing interesting in here, just for printing the date from the file name</span><span class="hl-code"> </span><span class="hl-reserved">def</span><span class="hl-code"> </span><span class="hl-identifier">get_date</span><span class="hl-brackets">(</span><span class="hl-identifier">file_name</span><span class="hl-brackets">)</span><span class="hl-code">: </span><span class="hl-identifier">time_str</span><span class="hl-code"> = </span><span class="hl-identifier">file_name</span><span class="hl-code">.</span><span class="hl-identifier">split</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">-</span><span class="hl-quotes">'</span><span class="hl-brackets">)[</span><span class="hl-code">-</span><span class="hl-number">1</span><span class="hl-brackets">]</span><span class="hl-code">.</span><span class="hl-identifier">replace</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">.png</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">''</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-identifier">d1</span><span class="hl-code">, </span><span class="hl-identifier">d2</span><span class="hl-code">, </span><span class="hl-identifier">m1</span><span class="hl-code">, </span><span class="hl-identifier">m2</span><span class="hl-code">, </span><span class="hl-identifier">y1</span><span class="hl-code">, </span><span class="hl-identifier">y2</span><span class="hl-code">, </span><span class="hl-identifier">y3</span><span class="hl-code">, </span><span class="hl-identifier">y4</span><span class="hl-code"> = </span><span class="hl-identifier">file_name</span><span class="hl-code">.</span><span class="hl-identifier">split</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">/</span><span class="hl-quotes">'</span><span class="hl-brackets">)[</span><span class="hl-code">-</span><span class="hl-number">1</span><span class="hl-brackets">]</span><span class="hl-code">.</span><span class="hl-identifier">split</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">-</span><span class="hl-quotes">'</span><span class="hl-brackets">)[</span><span class="hl-number">0</span><span class="hl-brackets">]</span><span class="hl-code"> </span><span class="hl-reserved">return</span><span class="hl-code"> </span><span class="hl-quotes">'</span><span class="hl-string">{}{}/{}{}/{}{}{}{} </span><span class="hl-quotes">'</span><span class="hl-code">.</span><span class="hl-identifier">format</span><span class="hl-brackets">(</span><span class="hl-identifier">m1</span><span class="hl-code">, </span><span class="hl-identifier">m2</span><span class="hl-code">, </span><span class="hl-identifier">d1</span><span class="hl-code">, </span><span class="hl-identifier">d2</span><span class="hl-code">, </span><span class="hl-identifier">y1</span><span class="hl-code">, </span><span class="hl-identifier">y2</span><span class="hl-code">, </span><span class="hl-identifier">y3</span><span class="hl-code">, </span><span class="hl-identifier">y4</span><span class="hl-brackets">)</span><span class="hl-code"> + </span><span class="hl-quotes">'</span><span class="hl-string">{}{}:{}{}:{}{}</span><span class="hl-quotes">'</span><span class="hl-code">.</span><span class="hl-identifier">format</span><span class="hl-brackets">(</span><span class="hl-code">*</span><span class="hl-builtin">list</span><span class="hl-brackets">(</span><span class="hl-identifier">time_str</span><span class="hl-brackets">))</span><span class="hl-code"> </span><span class="hl-comment"># A bunch of imports in the middle of the file</span><span class="hl-code"> </span><span class="hl-comment"># Don't do that at home ;-)</span><span class="hl-code"> </span><span class="hl-reserved">import</span><span class="hl-code"> </span><span class="hl-identifier">sys</span><span class="hl-code"> </span><span class="hl-reserved">import</span><span class="hl-code"> </span><span class="hl-identifier">subprocess</span><span class="hl-code"> </span><span class="hl-comment"># This will be for example: pngs/dell\:8000/24092016-101055.png</span><span class="hl-code"> </span><span class="hl-identifier">file_in</span><span class="hl-code"> = </span><span class="hl-identifier">sys</span><span class="hl-code">.</span><span class="hl-identifier">argv</span><span class="hl-brackets">[</span><span class="hl-number">1</span><span class="hl-brackets">]</span><span class="hl-code"> </span><span class="hl-comment"># And this: processed-pngs/dell\:8000/24092016-101055.png</span><span class="hl-code"> </span><span class="hl-identifier">file_out</span><span class="hl-code"> = </span><span class="hl-quotes">'</span><span class="hl-string">processed-</span><span class="hl-quotes">'</span><span class="hl-code"> + </span><span class="hl-identifier">file_in</span><span class="hl-code"> </span><span class="hl-comment"># Calling the ImageMagick as discussed in the article</span><span class="hl-code"> </span><span class="hl-identifier">subprocess</span><span class="hl-code">.</span><span class="hl-identifier">check_call</span><span class="hl-brackets">([</span><span class="hl-quotes">'</span><span class="hl-string">convert</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-identifier">file_in</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">-gamma</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">1.5</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">-auto-level</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">-brightness-contrast</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">35x80</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">-shear</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">-14x0</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">-crop</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">260x70+320+227</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">-channel</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">Green</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">-separate</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">-resize</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">40x20</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-identifier">file_out</span><span class="hl-brackets">])</span><span class="hl-code"> </span><span class="hl-comment"># Reading what it created</span><span class="hl-code"> </span><span class="hl-identifier">im</span><span class="hl-code">=</span><span class="hl-identifier">Image</span><span class="hl-code">.</span><span class="hl-builtin">open</span><span class="hl-brackets">(</span><span class="hl-identifier">file_out</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-comment"># Now a thing I added at some point later.</span><span class="hl-code"> </span><span class="hl-comment"># Because of different lighting throughout the day and because the ImageMagick command</span><span class="hl-code"> </span><span class="hl-comment"># above was not good compensating for it (in spite of auto-level and high contrast)</span><span class="hl-code"> </span><span class="hl-comment"># some of the images were darker than the others. In most images (the ideal scenario for the code)</span><span class="hl-code"> </span><span class="hl-comment"># the first 9 pixels of the image (0,0) to (3,3) were just white (or very close), but in those darker</span><span class="hl-code"> </span><span class="hl-comment"># images the whole image was darker and I used the first 9 pixels to detect how much darker</span><span class="hl-code"> </span><span class="hl-identifier">first9px</span><span class="hl-code"> = </span><span class="hl-identifier">im</span><span class="hl-code">.</span><span class="hl-identifier">getpixel</span><span class="hl-brackets">((</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-brackets">))</span><span class="hl-code"> + </span><span class="hl-identifier">im</span><span class="hl-code">.</span><span class="hl-identifier">getpixel</span><span class="hl-brackets">((</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">1</span><span class="hl-brackets">))</span><span class="hl-code"> + </span><span class="hl-identifier">im</span><span class="hl-code">.</span><span class="hl-identifier">getpixel</span><span class="hl-brackets">((</span><span class="hl-number">0</span><span class="hl-code">,</span><span class="hl-number">2</span><span class="hl-brackets">))</span><span class="hl-code"> \ + </span><span class="hl-identifier">im</span><span class="hl-code">.</span><span class="hl-identifier">getpixel</span><span class="hl-brackets">((</span><span class="hl-number">1</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-brackets">))</span><span class="hl-code"> + </span><span class="hl-identifier">im</span><span class="hl-code">.</span><span class="hl-identifier">getpixel</span><span class="hl-brackets">((</span><span class="hl-number">1</span><span class="hl-code">,</span><span class="hl-number">1</span><span class="hl-brackets">))</span><span class="hl-code"> + </span><span class="hl-identifier">im</span><span class="hl-code">.</span><span class="hl-identifier">getpixel</span><span class="hl-brackets">((</span><span class="hl-number">1</span><span class="hl-code">,</span><span class="hl-number">2</span><span class="hl-brackets">))</span><span class="hl-code"> \ + </span><span class="hl-identifier">im</span><span class="hl-code">.</span><span class="hl-identifier">getpixel</span><span class="hl-brackets">((</span><span class="hl-number">2</span><span class="hl-code">,</span><span class="hl-number">0</span><span class="hl-brackets">))</span><span class="hl-code"> + </span><span class="hl-identifier">im</span><span class="hl-code">.</span><span class="hl-identifier">getpixel</span><span class="hl-brackets">((</span><span class="hl-number">2</span><span class="hl-code">,</span><span class="hl-number">1</span><span class="hl-brackets">))</span><span class="hl-code"> + </span><span class="hl-identifier">im</span><span class="hl-code">.</span><span class="hl-identifier">getpixel</span><span class="hl-brackets">((</span><span class="hl-number">2</span><span class="hl-code">,</span><span class="hl-number">2</span><span class="hl-brackets">))</span><span class="hl-code"> </span><span class="hl-comment"># This is the compensation, for most of the images it's 0 or very few, but for darker images, it's more</span><span class="hl-code"> </span><span class="hl-identifier">avg9px</span><span class="hl-code"> = </span><span class="hl-number">255</span><span class="hl-code">-</span><span class="hl-identifier">first9px</span><span class="hl-code">/</span><span class="hl-number">9</span><span class="hl-code"> </span><span class="hl-identifier">num</span><span class="hl-code"> = </span><span class="hl-quotes">'</span><span class="hl-string">{}{}{}.{}</span><span class="hl-quotes">'</span><span class="hl-code">.</span><span class="hl-identifier">format</span><span class="hl-brackets">(</span><span class="hl-code"> </span><span class="hl-quotes">'</span><span class="hl-string">-</span><span class="hl-quotes">'</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-identifier">read_segment</span><span class="hl-brackets">(</span><span class="hl-identifier">im</span><span class="hl-code">, </span><span class="hl-brackets">[(</span><span class="hl-number">2</span><span class="hl-code">,</span><span class="hl-number">6</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">3</span><span class="hl-code">,</span><span class="hl-number">6</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">(</span><span class="hl-number">4</span><span class="hl-code">,</span><span class="hl-number">6</span><span class="hl-brackets">)]</span><span class="hl-code">, </span><span class="hl-identifier">tSIGN</span><span class="hl-code">-</span><span class="hl-identifier">avg9px</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-reserved">else</span><span class="hl-code"> </span><span class="hl-quotes">'</span><span class="hl-string">+</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-identifier">read_digit</span><span class="hl-brackets">(</span><span class="hl-identifier">im</span><span class="hl-code">, </span><span class="hl-identifier">d1_sA</span><span class="hl-code">, </span><span class="hl-identifier">d1_sB</span><span class="hl-code">, </span><span class="hl-identifier">d1_sC</span><span class="hl-code">, </span><span class="hl-identifier">d1_sE</span><span class="hl-code">, </span><span class="hl-identifier">d1_sF</span><span class="hl-code">, </span><span class="hl-identifier">d1_sG</span><span class="hl-code">, </span><span class="hl-identifier">avg9px</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-identifier">read_digit</span><span class="hl-brackets">(</span><span class="hl-identifier">im</span><span class="hl-code">, </span><span class="hl-identifier">d2_sA</span><span class="hl-code">, </span><span class="hl-identifier">d2_sB</span><span class="hl-code">, </span><span class="hl-identifier">d2_sC</span><span class="hl-code">, </span><span class="hl-identifier">d2_sE</span><span class="hl-code">, </span><span class="hl-identifier">d2_sF</span><span class="hl-code">, </span><span class="hl-identifier">d2_sG</span><span class="hl-code">, </span><span class="hl-identifier">avg9px</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-identifier">read_digit</span><span class="hl-brackets">(</span><span class="hl-identifier">im</span><span class="hl-code">, </span><span class="hl-identifier">d3_sA</span><span class="hl-code">, </span><span class="hl-identifier">d3_sB</span><span class="hl-code">, </span><span class="hl-identifier">d3_sC</span><span class="hl-code">, </span><span class="hl-identifier">d3_sE</span><span class="hl-code">, </span><span class="hl-identifier">d3_sF</span><span class="hl-code">, </span><span class="hl-identifier">d3_sG</span><span class="hl-code">, </span><span class="hl-identifier">avg9px</span><span class="hl-brackets">)</span><span class="hl-code">, </span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-quotes">'</span><span class="hl-string">None</span><span class="hl-quotes">'</span><span class="hl-code"> </span><span class="hl-reserved">not</span><span class="hl-code"> </span><span class="hl-reserved">in</span><span class="hl-code"> </span><span class="hl-identifier">num</span><span class="hl-code">: </span><span class="hl-reserved">print</span><span class="hl-code"> </span><span class="hl-identifier">get_date</span><span class="hl-brackets">(</span><span class="hl-identifier">file_in</span><span class="hl-brackets">)</span><span class="hl-code"> + </span><span class="hl-quotes">'</span><span class="hl-special">\t</span><span class="hl-quotes">'</span><span class="hl-code"> + </span><span class="hl-identifier">num</span><span class="hl-code"> </span><span class="hl-comment"># If there's a second argument to the script passed, show the original image for comparison</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-code"> </span><span class="hl-builtin">len</span><span class="hl-brackets">(</span><span class="hl-identifier">sys</span><span class="hl-code">.</span><span class="hl-identifier">argv</span><span class="hl-brackets">)</span><span class="hl-code"> &gt; </span><span class="hl-number">2</span><span class="hl-code">: </span><span class="hl-identifier">Image</span><span class="hl-code">.</span><span class="hl-builtin">open</span><span class="hl-brackets">(</span><span class="hl-identifier">file_in</span><span class="hl-brackets">)</span><span class="hl-code">.</span><span class="hl-identifier">show</span><span class="hl-brackets">()</span></pre></div> </div> <p>Even though this script is so simple, after tweaking the thresholds, most of the files were recognized correctly, those that weren't had one or more non-recognized digits, so they were easy to filter out. For over 1-day worth of images, only 2 or 3 minutes had a missing reading.</p> <p>I loaded the data to LibreOffice and generated this pretty graph:</p> <img src="http://piotrgabryjeluk.wdfiles.com/local--files/blog:monitoring-freezer-temperature/graph.jpg" style="width: 100%" alt="graph.jpg" class="image" /> <h1><span>Timelapse video</span></h1> <p>Another approach visualizing the data was to create a video.</p> <p>The plan:</p> <ul> <li>Annotate the images with the recorded time</li> <li>Compose the video from single frames, putting 60 frames per a second of the resulting video</li> </ul> <p>60 frames a second with roughly 2 frames captured a minutes means a day of recording is compressed to:</p> <div class="code"> <pre><code>2 frames a minute * 60 minutes an hour * 24 hours a day = 2880 frames 2880 frames / 60 frames a second = 48 seconds</code></pre></div> <p>This makes is &quot;viewable&quot;. 60 FPS (versus 30 FPS at higher speed) means you can pause at any time and read the crisp time and temperature.</p> <p>Here's the annotate part:</p> <div class="code"> <div class="hl-main"> <pre><span class="hl-comment">#!/usr/bin/env python</span><span class="hl-code"> </span><span class="hl-reserved">import</span><span class="hl-code"> </span><span class="hl-identifier">sys</span><span class="hl-code"> </span><span class="hl-reserved">import</span><span class="hl-code"> </span><span class="hl-identifier">subprocess</span><span class="hl-code"> </span><span class="hl-identifier">path_in</span><span class="hl-code"> = </span><span class="hl-identifier">sys</span><span class="hl-code">.</span><span class="hl-identifier">argv</span><span class="hl-brackets">[</span><span class="hl-number">1</span><span class="hl-brackets">]</span><span class="hl-code"> </span><span class="hl-identifier">path_out</span><span class="hl-code"> = </span><span class="hl-identifier">sys</span><span class="hl-code">.</span><span class="hl-identifier">argv</span><span class="hl-brackets">[</span><span class="hl-number">2</span><span class="hl-brackets">]</span><span class="hl-code"> </span><span class="hl-identifier">date</span><span class="hl-code">, </span><span class="hl-identifier">time</span><span class="hl-code"> = </span><span class="hl-identifier">path_in</span><span class="hl-code">.</span><span class="hl-identifier">replace</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">.png</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">''</span><span class="hl-brackets">)</span><span class="hl-code">.</span><span class="hl-identifier">split</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">/</span><span class="hl-quotes">'</span><span class="hl-brackets">)[</span><span class="hl-code">-</span><span class="hl-number">1</span><span class="hl-brackets">]</span><span class="hl-code">.</span><span class="hl-identifier">split</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">-</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-identifier">D1</span><span class="hl-code">, </span><span class="hl-identifier">D2</span><span class="hl-code">, </span><span class="hl-identifier">M1</span><span class="hl-code">, </span><span class="hl-identifier">M2</span><span class="hl-code">, </span><span class="hl-identifier">Y1</span><span class="hl-code">, </span><span class="hl-identifier">Y2</span><span class="hl-code">, </span><span class="hl-identifier">Y3</span><span class="hl-code">, </span><span class="hl-identifier">Y4</span><span class="hl-code"> = </span><span class="hl-identifier">date</span><span class="hl-code"> </span><span class="hl-identifier">h1</span><span class="hl-code">, </span><span class="hl-identifier">h2</span><span class="hl-code">, </span><span class="hl-identifier">m1</span><span class="hl-code">, </span><span class="hl-identifier">m2</span><span class="hl-code">, </span><span class="hl-identifier">s1</span><span class="hl-code">, </span><span class="hl-identifier">s2</span><span class="hl-code"> = </span><span class="hl-identifier">time</span><span class="hl-code"> </span><span class="hl-identifier">label</span><span class="hl-code"> = </span><span class="hl-quotes">'</span><span class="hl-string">{}{}/{}{}/{}{}{}{} {}{}:{}{}:{}{}</span><span class="hl-special">\\</span><span class="hl-string">n</span><span class="hl-quotes">'</span><span class="hl-code">.</span><span class="hl-identifier">format</span><span class="hl-brackets">(</span><span class="hl-identifier">M1</span><span class="hl-code">, </span><span class="hl-identifier">M2</span><span class="hl-code">, </span><span class="hl-identifier">D1</span><span class="hl-code">, </span><span class="hl-identifier">D2</span><span class="hl-code">, </span><span class="hl-identifier">Y1</span><span class="hl-code">, </span><span class="hl-identifier">Y2</span><span class="hl-code">, </span><span class="hl-identifier">Y3</span><span class="hl-code">, </span><span class="hl-identifier">Y4</span><span class="hl-code">, </span><span class="hl-identifier">h1</span><span class="hl-code">, </span><span class="hl-identifier">h2</span><span class="hl-code">, </span><span class="hl-identifier">m1</span><span class="hl-code">, </span><span class="hl-identifier">m2</span><span class="hl-code">, </span><span class="hl-identifier">s1</span><span class="hl-code">, </span><span class="hl-identifier">s2</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-identifier">subprocess</span><span class="hl-code">.</span><span class="hl-identifier">check_call</span><span class="hl-brackets">([</span><span class="hl-code"> </span><span class="hl-quotes">'</span><span class="hl-string">convert</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-identifier">path_in</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">-gravity</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">south</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">-pointsize</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">45</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">-font</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">FreeMono</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">-annotate</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">0</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-identifier">label</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">-fill</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">'</span><span class="hl-string">black</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-identifier">path_out</span><span class="hl-code"> </span><span class="hl-brackets">])</span></pre></div> </div> <p>Here's the result:</p> <img src="http://piotrgabryjeluk.wdfiles.com/local--files/blog:monitoring-freezer-temperature/annotated.png" alt="annotated.png" class="image" /> <p>Running this in a loop, 16 images at a time:</p> <div class="code"> <pre><code>#!/bin/bash i=0 for file_in in dell*/*.png; do file_out=&quot;`printf &quot;labeled/%06d.png&quot; $i`&quot; echo ./add-labels.py &quot;$file_in&quot; &quot;$file_out&quot; i=$((i+1)) done | parallel -j 16</code></pre></div> <p>In addition to annotatig the image it also names them as 000001.png, 000002.png etc, which makes it easy for <tt>avconv</tt> to convert them to a video:</p> <div class="code"> <pre><code>avconv -fflags +genpts -r 60 -i labeled/%06d.png -r 60 temperature.mkv</code></pre></div> <p>And here's the video:</p> <p><iframe width="640" height="480" src="https://www.youtube.com/embed/DL9_sbdHlhU" frameborder="0" allowfullscreen="allowfullscreen"></iframe></p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=2462&amp;amp;size=small&amp;amp;timestamp=1783694814" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotrgabryjeluk.wikidot.com/blog:work-around-buggy-soundcard</guid>
				<title>Working around a buggy sound card</title>
				<link>http://piotrgabryjeluk.wikidot.com/blog:work-around-buggy-soundcard</link>
				<description>

&lt;p&gt;I found the laptop I bought recently has a weird thing with its soundcard. It plays music OK, it also allows you to change the mixer levels, nothing special, but when you try changing mixer setting while the music is playing the music starts getting choppy and the process handling the mixer tend to freeze. Also you cannot pause the music, sometimes it repeats the same sample over and over and it gets very annoying.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=2462&amp;amp;amp;size=small&amp;amp;amp;timestamp=1783694814&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Tue, 02 Dec 2014 23:34:29 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>I found the laptop I bought recently has a weird thing with its soundcard. It plays music OK, it also allows you to change the mixer levels, nothing special, but when you try changing mixer setting while the music is playing the music starts getting choppy and the process handling the mixer tend to freeze. Also you cannot pause the music, sometimes it repeats the same sample over and over and it gets very annoying.</p> <div class="content-separator" style="display: none:"></div> <p>My approach to this issue was to use PulseAudio software mixer capabilities, so the hardware mixer is never adjusted (other than for the initial setup).</p> <h1><span>Step 1. Getting PulseAudio to use the software mixer</span></h1> <p>I found no good documentation on this other than PulseAudio uses <em>paths</em> to convert the desired volume to the hardware mixer settings and if it lacks the ability to do so it would turn the volume up/down using software. Reading between the lines I realized if I remove the <em>paths</em> I will get what I want. Just do this and restart pulseaudio and you'll have PulseAudio doing all the mixing in software:</p> <div class="code"> <pre><code>sudo mv /usr/share/pulseaudio/alsa-mixer/paths /usr/share/pulseaudio/alsa-mixer/paths.bak</code></pre></div> <h2><span>Verifying it works</span></h2> <p>Open two terminal windows. In each of them open alsamixer. Both should display very simple controls and say Card: PulseAudio. Use F6 to switch to the real card in one of the windows. Usually the cards have plethora of controls, so should yours.</p> <p>Now change the output volume in the alsamixer still saying &quot;Card: PulseAudio&quot;. If the volume reported by the other alsamixer does not change, it works as expected!</p> <p>If you now rename the paths directory back and restart the pulseaudio process, updating the PulseAudio volume should update the real device volume as well.</p> <h1><span>Step 2. Integrating this with XFCE (or other DE)</span></h1> <p>The way xfce4 handles the volume is two-fold:</p> <ul> <li>There's a xfce4-volumed daemon. It only controls the key bindings. It binds volume up, volume down and mute keys to control the real device controls</li> <li>There's a panel applet called &quot;Audio Mixer&quot; that shows the current volume level and lets you change the volume as well.</li> </ul> <p>Both component are optional and both seem to not work with PulseAudio (even through PulseAudio ALSA emulation which tricks alsamixer for instance).</p> <p>We're going to overcome this problem by replacing these components with two other programs.</p> <h2><span><a href="https://github.com/fernandotcl/pa-applet">pa-applet</a></span></h2> <p>pa-applet will replace the &quot;Audio Mixer&quot; applet. The difference is the pa-applet docks to the systray, so is not XFCE-specific. The downside is we don't have control over the specific position of the icon, all we know is it will appear in the systray (so don't forget to have the systray applet added to the panel).</p> <p>In order to install this software you need to clone the source, and run ./autogen.sh, ./configure, make, sudo make install. You will get information about deps missing, for instance:</p> <div class="code"> <pre><code>configure: error: Package requirements (glib-2.0) were not met: No package 'glib-2.0' found</code></pre></div> <p>You need to find the proper *-dev package for each unmet dependency (for this one it will be libglib2.0-dev).</p> <p>I came across one additional problem. The software seems not updated after some GTK+ 3 updates and it uses a deprecated function. Because the code is configured in a way that every warning stops the compilation, it wouldn't let you compile the code unless you open the src/Makefile file and then find and remove the -Werror flag from it.</p> <h2><span><a href="https://launchpad.net/xfce4-volumed-pulse">xfce4-volumed-pulse</a></span></h2> <p>This part will take care of binding the media keys to the pulse audio controls (rather than to the sound card controls).</p> <p>You need to download the tar package, untar it, ./configure, make, sudo make install. It also requires quite a few libs to be installed, but I didn't found any issues when compiling.</p> <h2><span>Hooking this up together</span></h2> <p>Since I didn't need the original xfce4-volume anymore I decided to remove it:</p> <div class="code"> <pre><code>apt-get remove xfce4-volumed</code></pre></div> <p>But because XFCE will try to launch this anyway on each start, I decided to take advantage of it and replace it with a script:</p> <div class="code"> <pre><code>#!/bin/bash /usr/local/bin/xfce4-volumed-pulse /usr/local/bin/pa-applet</code></pre></div> <p>Add the executable bit, restart the laptop and all should be working correctly at this moment.</p> <h1><span>Setting the hw mixer controls</span></h1> <p>Since PulseAudio won't update the hw controls after you follow up this little howto, it's quite important to set all the important channels to 100% (or other number up to your taste). The way to update the hw controls was described before.</p> <p>Open the terminal, type alsamixer and hit F6. This will give the list of ALSA devices besides the PulseAudio emulation, your real sound cards should display as well. Choose the right one and you should be given access to tweak the real card controls.</p> <p>Note if you removed the PulseAudio paths, the PulseAudio controls wouldn't update when you tweak the hw controls.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=2462&amp;amp;size=small&amp;amp;timestamp=1783694814" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotrgabryjeluk.wikidot.com/blog:share-screen-over-http-and-mjpeg</guid>
				<title>Share screen over HTTP and M-JPEG</title>
				<link>http://piotrgabryjeluk.wikidot.com/blog:share-screen-over-http-and-mjpeg</link>
				<description>

&lt;p&gt;Here&#039;s a script to share your screen in a way that you can use a simple web browser to see it:&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=2462&amp;amp;amp;size=small&amp;amp;amp;timestamp=1783694814&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Mon, 13 Oct 2014 20:14:05 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Here's a script to share your screen in a way that you can use a simple web browser to see it:</p> <div class="code"> <pre><code>#!/bin/bash fps=5 bitrate=15000 port=8080 transcode=&quot;transcode{vcodec=MJPG,vb=$bitrate}&quot; http='http{mime=multipart/x-mixed-replace}' std=&quot;standard{access=$http,mux=mpjpeg,dst=:$port}&quot; sout=&quot;#$transcode:$std&quot; cvlc -q screen:// &quot;:screen-fps=$fps&quot; --sout &quot;$sout&quot;</code></pre></div> <p>Connect using a browser pointed to <a href="http://localhost:8080/">http://localhost:8080/</a></p> <p>Opera seems to work the best for that stream. If you don't set the zoom at 100% if will flicker a bit though.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=2462&amp;amp;size=small&amp;amp;timestamp=1783694814" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotrgabryjeluk.wikidot.com/blog:cups-and-easy-printer-sharing</guid>
				<title>Cups And Easy Printer Sharing</title>
				<link>http://piotrgabryjeluk.wikidot.com/blog:cups-and-easy-printer-sharing</link>
				<description>

&lt;p&gt;Today I decided I want to share an USB printer via CUPS. This has always been fun and easy thing to do.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=2462&amp;amp;amp;size=small&amp;amp;amp;timestamp=1783694814&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Tue, 22 Apr 2014 20:53:10 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Today I decided I want to share an USB printer via CUPS. This has always been fun and easy thing to do.</p> <p>After spending some time figuring out why this doesn't work out of the box, I learned most of the tutorials are not right about one thing. They claim to share the network in the same (sub)network you don't need any special configuration on the client. That's wrong. You need to install cups-browsed package on the client:</p> <div class="code"> <pre><code>sudo apt-get install cups-browsed</code></pre></div> <p>Then you just wait 30 seconds and you're remote printers should appear in <a href="http://localhost:631/printers">http://localhost:631/printers</a></p> <p>If you want to print from a different network (or your stupid router doesn't bridge Wifi and Ethernet networks) you may need to add a line like that:</p> <div class="code"> <pre><code>BrowsePoll server-name</code></pre></div> <p>to the <tt>/etc/cups/cups-browsed.conf</tt> file.</p> <p>An update: actually BrowsePoll server-name doesn't seem to work. I needed to replace the server name with the server IP address.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=2462&amp;amp;size=small&amp;amp;timestamp=1783694814" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotrgabryjeluk.wikidot.com/blog:flash-i-silverlight</guid>
				<title>Flash I Silverlight</title>
				<link>http://piotrgabryjeluk.wikidot.com/blog:flash-i-silverlight</link>
				<description>

&lt;p&gt;Z Flashem do niedawna było całkiem nieźle. Wsparcie dla Linuksa było. Paczki w apcie były. W miarę działało. Silverlight był gorszy. Niby był moonlight, ale nigdy nie działał akurat z tymi stronami co się chciało.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=2462&amp;amp;amp;size=small&amp;amp;amp;timestamp=1783694814&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Sun, 16 Mar 2014 20:18:47 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Z Flashem do niedawna było całkiem nieźle. Wsparcie dla Linuksa było. Paczki w apcie były. W miarę działało. Silverlight był gorszy. Niby był moonlight, ale nigdy nie działał akurat z tymi stronami co się chciało.</p> <p>Teraz Flash na Linuksa dostępny jest tylko w wersji 11. Jak chcesz wersję 12, to musisz mieć Chrome'a. Można jakimś hakiem wyciągnąć z Chrome'a samą wtyczkę i wrzucić do Chromium, ale to już trochę bez sensu.</p> <p>Natomiast o Moonlighcie to już chyba wszyscy zapomnieli. Przekierowanie ze strony Microsoftu (gdzie kierują strony &quot;brak wtyczki) prowadzi do 404-ki, w apcie susza, w sumie nie wiadomo co robić.</p> <p>Ale dzisiaj odkryłem rozwiązanie obu problemów. Nazywa się ono <a href="http://fds-team.de/cms/pipelight-installation.html">pipelight</a>. Jest to sprytna biblioteka instalująca Windowsowe wtyczki do przeglądarek jako wtyczki do przeglądarek na Linuksie, np. Firefoksa. Korzysta to z wine'a i sprawdziłem, że działa. Zarówno Silverlight jak i Flash 12 odtąd działa elegancko. Przynajmniej do oglądania filmów i transmisji na żywo. Obsługa kamerki w tej &quot;wersji&quot; Flasha nie działa.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=2462&amp;amp;size=small&amp;amp;timestamp=1783694814" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotrgabryjeluk.wikidot.com/blog:useful-oneliner</guid>
				<title>Useful oneliner to set your DNS to Google</title>
				<link>http://piotrgabryjeluk.wikidot.com/blog:useful-oneliner</link>
				<description>

&lt;p&gt;This thing eases things a lot when you deal with crappy internet connection (airport, AirBNB etc).&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=2462&amp;amp;amp;size=small&amp;amp;amp;timestamp=1783694814&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Wed, 12 Feb 2014 18:11:43 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>This thing eases things a lot when you deal with crappy internet connection (airport, AirBNB etc).</p> <div class="code"> <pre><code>#!/bin/bash echo nameserver 8.8.8.8 | sudo tee /etc/resolv.conf &gt; /dev/null</code></pre></div> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=2462&amp;amp;size=small&amp;amp;timestamp=1783694814" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotrgabryjeluk.wikidot.com/blog:ad-filtering-on-adroid-phones</guid>
				<title>Ad Filtering On Adroid Phones</title>
				<link>http://piotrgabryjeluk.wikidot.com/blog:ad-filtering-on-adroid-phones</link>
				<description>

&lt;p&gt;Recently I installed a &lt;a href=&quot;http://forum.xda-developers.com/showthread.php?t=1403113&quot;&gt;CM9-based Ice Cream Sandwitch ROM&lt;/a&gt; on my HTC Desire and it&#039;s cool, but I found one thing extremely frustrating: the ads. They are everywhere and slow things down. I haven&#039;t noticed them before, because I always used AdAway (and AdFree before that), but with this ROM those ad blockers refused to work.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=2462&amp;amp;amp;size=small&amp;amp;amp;timestamp=1783694814&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Fri, 06 Apr 2012 21:44:43 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Recently I installed a <a href="http://forum.xda-developers.com/showthread.php?t=1403113">CM9-based Ice Cream Sandwitch ROM</a> on my HTC Desire and it's cool, but I found one thing extremely frustrating: the ads. They are everywhere and slow things down. I haven't noticed them before, because I always used AdAway (and AdFree before that), but with this ROM those ad blockers refused to work.</p> <p>The problem seems to be the /system/etc/hosts file is real file on flash filesystem and if modified it can be only as big as 2 kilobytes, so regular host-based ad-blocking can't be used here. For some reason creating symbolic link to /data also fails.</p> <p>I though the ad blocking can be done differently &#8212; by DNS server. If we can't put much to /etc/hosts file, let's set up a DNS server (say dnsmasq) that reads the hosts-to-be-blocked file and returns 127.0.0.1 for them and act as a proxy-DNS server for every other domain. But there was problem in settings DNS server in Android settings. It seems the ROM has hardcoded OpenDNS servers and you can only override this per each WiFi network. No way to do this for 3G.</p> <p>But then I found, the ROM comes with iptables executable (possibly from busybox, haven't really checked) and more interestingly iptables-capable kernel. After a bit of trial and error (and Google searching) I found commands to redirect all DNS traffic comming from the phone to one predefined server:</p> <div class="code"> <pre><code>iptables -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to-destination 87.118.110.215 iptables -t nat -A OUTPUT -p tcp --dport 53 -j DNAT --to-destination 87.118.110.215</code></pre></div> <p>The shell throws out one-line TODO (implement getprotobyname) errors but this is harmless to us. This is effective untill you flush iptables (with iptables -t nat -F) or reboot the phone.</p> <p>At first I wanted to set up the ad-blocking DNS server myself, but I said, hey, someone just had to do it. I wasn't wrong, there were at least two relevant Google results for this: <a href="http://www.adbarricade.com/">AdBarricade</a> and <a href="http://www.fooldns.com/fooldns-community/english-version/">FoolDNS</a>. So you need to choose one and you're set.</p> <p>But how do you compare those two? I mentioned I used AdAway and AdFree before and their block lists are very good (personal opinion), so I decided to download the hosts file generated by AdAway (it has the option to generate the hosts file anywhere, not just in plain /etc/hosts), shuffle it a bit and for top 1000 hosts check whether AdBarricade or FoolDNS block them. The results were:</p> <p>FoolDNS (87.118.110.215): 744/1000 hosts blocked<br /> AdBarricade (74.53.155.162): 234/1000 hosts blocked</p> <p>For our purpose (measure by how many of AdAway-listed hosts are blocked) FoolDNS is a winner. That's why 87.118.110.215 was used in the iptables scripts above.</p> <p>Once we have our DNS-based iptables-powered ad filtering, we may want to make it persistent. BCM ROM has a script that's called during boot process, it's /etc/boot.d/99bash and we can just append two abovementioned lines to it, to make the boot process run them each time the phone boots.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=2462&amp;amp;size=small&amp;amp;timestamp=1783694814" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotrgabryjeluk.wikidot.com/blog:za-to-xubuntu</guid>
				<title>Za to Xubuntu...</title>
				<link>http://piotrgabryjeluk.wikidot.com/blog:za-to-xubuntu</link>
				<description>

&lt;p&gt;W &lt;a href=&quot;http://piotrgabryjeluk.wikidot.com/blog:ubuntu-idzie-wedlug-mnie-w-zlym-kierunku&quot;&gt;poprzednim poście&lt;/a&gt; pisałem o tym jak Ubuntu idzie w złą stronę. I cały czas tak myślę. Dodajmy do tego co pisałem ostatnio, że Ubuntu próbuje się skupić na wszystkim i wszystkich. Już nie wystarczy robić dobrej dystrybucji dla desktopów i laptopów (co i tak już zepsuli). Teraz Ubuntu będzie planuje rozwijać Ubuntu na telewizory, smartfony no i (niestety) serwery.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=2462&amp;amp;amp;size=small&amp;amp;amp;timestamp=1783694814&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Thu, 15 Mar 2012 18:59:48 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>W <a href="http://piotrgabryjeluk.wikidot.com/blog:ubuntu-idzie-wedlug-mnie-w-zlym-kierunku">poprzednim poście</a> pisałem o tym jak Ubuntu idzie w złą stronę. I cały czas tak myślę. Dodajmy do tego co pisałem ostatnio, że Ubuntu próbuje się skupić na wszystkim i wszystkich. Już nie wystarczy robić dobrej dystrybucji dla desktopów i laptopów (co i tak już zepsuli). Teraz Ubuntu będzie planuje rozwijać Ubuntu na telewizory, smartfony no i (niestety) serwery.</p> <div class="content-separator" style="display: none:"></div> <p>Jakiś czas temu zauważyłem, że dzielę z Linusem Torvaldsem odczucia dotyczące środowisk graficznych. Podobnie jak on, byłem wielkim fanem KDE 3, potem GNOME 2. Wynalazki takie jak KDE 4, Gnome 3, Gnome Shell czy Unity nie przypadały mi do gustu. Obecnie środowiskiem graficznym, które uznaję za sensowne (podobnie jak Linus) jest XFCE, którego byłem fanem (i użytkownikiem) od dłuższego czasu.</p> <p>Korzystając z okazji i chęci eksperymentowania, zainstalowałem ostatnio Xubuntu Precise w wersji beta1 i ku mojemu zdziwieniu całość sprawuje się świetnie. Korzystam z szyfrowania katalogu domowego, a mimo wszystko całość zasuwa jak dziki skurczybyk.</p> <p>Miałem problem z nieładowaniem się pulpitu po zalogowaniu, ale po wymianie lightdm na gdm już jest OK.</p> <p>Dodam, że korzystam z doka, który nazywa się &quot;Docky&quot; (wywodzącego się z Gnome-Do, lecz teraz jest osobnym projektem), który też robi kawał dobrej roboty.</p> <p>Podsumowując: cały świat Linuksowy jednak nie zapomniał się w holizmie i są wciąż projekty skupiające się na tym, co powinny robić. I ja to bardzo doceniam. I nie potrzebuję mieć jednej firmy, która dostarczy mi cały system, gdzie absolutnie wszystko będzie do siebie podobne i pasujące. Nie żebym nie chciał, ale to po prostu niemożliwe. Wystarczy, że do każdej rzeczy, którą robię wybiorę sobie jakiś komponent, który mi pasuje, a komunikacja między nimi nie będzie sprawiać problemów.</p> <p>Filozoficzne myśli ostatnio się mnie trzymają. I wiem, że sporo ludzi docenia to co ja, więc fajnie było się tą myślą podzielić publicznie.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=2462&amp;amp;size=small&amp;amp;timestamp=1783694814" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotrgabryjeluk.wikidot.com/blog:ubuntu-idzie-wedlug-mnie-w-zlym-kierunku</guid>
				<title>Ubuntu idzie (według mnie) w złym kierunku</title>
				<link>http://piotrgabryjeluk.wikidot.com/blog:ubuntu-idzie-wedlug-mnie-w-zlym-kierunku</link>
				<description>

&lt;p&gt;Dzisiejsza notka będzie wielce narzekająca i pewnie nic nie wnosząca do Waszego życia, ale zauważyłem, że wiele osób ma podobne odczucia, do moich, więc postanowiłem się podzielić swoimi przemyśleniami.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=2462&amp;amp;amp;size=small&amp;amp;amp;timestamp=1783694814&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Mon, 06 Feb 2012 22:31:33 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p>Dzisiejsza notka będzie wielce narzekająca i pewnie nic nie wnosząca do Waszego życia, ale zauważyłem, że wiele osób ma podobne odczucia, do moich, więc postanowiłem się podzielić swoimi przemyśleniami.</p> <div class="content-separator" style="display: none:"></div> <p>Jakiś czas temu Ubuntu postanowiło postawić na Unity &#8212; nowoczesne środowisko graficzne z ultra fajnym dokiem jak i wyszukiwarką programów, które miało być hitem dla tzw. zwykłego użytkownika.</p> <p>Niestety całe to Unity, pomimo kilku fajnych rzeczy, po prostu nie sprawdza się. I o ile wszystkie pomysły w teorii są bardzo fajne (np. dock a'la Mac OS) to w praktyce są zrealizowane po prostu źle.</p> <p>Mam wrażenie, że nikt tego nie testował, ponieważ, kiedy pierwszy raz zetknąłem się z tym środowiskiem (a było już ono w Ubuntu w wersji wydanej, nie żadne alfa-bety) to miało mnóstwo błędów.</p> <p>Najgorsze jest chyba jednak to, że poczyniono w jakimś wyższym celu mnóstwo założeń, jak chyba najbardziej kontrowersyjne, że dock będzie po lewej stronie i nie da się go przesunąć. Można się do tego przyzwyczaić? Można. O ile się korzysta z jednego ekranu. Jako power-user korzystam od dłuższego czasu z dwóch monitorów i ustawiałem je zawsze sobie w pionie: laptop (bo lubię pisać na jego klawiaturze) i nad nim duży &quot;główny&quot; monitor.</p> <p>Z jakiegoś powodu pionowe ułożenie monitorów w Unity nie jest dobrze wspierane: a to nie da się przenieść okienka, a to maksymalizacja działa nie tak jak trzeba, a to po jakiejś operacji na oknie, wywalają się dekoracje okien, a to restartuje się Xorg. Pięknie! No to ułóżmy monitory w poziomie. Ale moment, przecież dok będzie zawsze po lewej stronie. Tylko na którym monitorze? Mam nadzieję, że na lewym. No ale wolałbym mieć mały monitor po lewej stronie, a dok na większym. Ok, dało się ustawić, tylko teraz znowu nie można przenosić okienek na mały monitor. Brrrrr. Najbardziej dostosowywalny i dostępny system na świecie (GNU/Linux) właśnie rządzi układem monitorów na moim biurku. Świetnie!</p> <p>Ale do rzeczy. W ostatniej wersji Ubuntu (którą instalowałem moim rodzicom) jak się okazało w ogóle nie przewidziano sesji &quot;Ubuntu classic &#8212; no effects&quot;). Środowisko GNOME trzeba doinstalować ręcznie. Po raz kolejny gratulacje.</p> <p>Powiem głośno: <strong>Unity NIE jest jeszcze użyteczne dla normalnego użytkownika</strong>. Jest nieintuicyjne i przeczy wszystkim przyzwyczajeniom użytkowników. Interfejs jest nieczytelny. Nawet dla ludzi niestykających się dotąd z komputerami. GNOME czy XFCE jest bardziej zrozumiały niż to Unity.</p> <p>Następna rzecz. Ekipa Ubuntu testuje obecnie mechanizm przeszukiwania menu aplikacji. Zamiast kliknąć menu &quot;Edycja&quot; a następnie &quot;Skopiuj&quot;, będziemy mogli nacisnąć Alt, napisać &quot;Skopiuj&quot; i dostaniemy listę akcji dostępnych przez menu aplikacji z tekstem &quot;Skopiuj&quot; w tym &quot;Edycja &gt; Skopiuj&quot;. Jakże przydatne, prawda? Idealnie wpisuje się to w trend upraszczania aplikacji, tak, aby aplikacja mając trzy guzikami i jedno menu rozwijane z czterema następnymi akcjami była jak najbardziej zrozumiała i użyteczna. Na pewno w gąszczu tych 7-miu akcji będę wolał nacisnąć Alt i wpisać co chcę zrobić zastanawiając się jeszcze, czy mam napisać to po polsku, czy po angielsku i czy użyć słowa &quot;Wydrukuj&quot;, czy &quot;Drukuj&quot; (bo jeszcze tłumacze się nie dogadali jakiego aspektu używać).</p> <p>Pewnie zastanawiacie się jaką bym widział przyszłość dla Ubuntu, gdybym nim kierował? Na pewno nie, ale i tak napiszę. Ubuntu nie powinno na siłę tworzyć jakichś nowych ULTRA-innowacyjnych rozwiązań, które pewnie są w zamierzeniu dobre, ale zrozumiemy to dopiero, gdy zaimplementuje je np. Apple. Ubuntu powinno właśnie dobierać to co już istnieje, filtrować i ulepszać. Powinno położyć kres niedopracowanym projektom jak Unity czy GNOME 3 i przeznaczać kasę i czas deweloperów na szlifowanie UI, tak aby korzystanie z Linuksa było naprawdę proste dla zwykłego użytkownika.</p> <p>Istnieją też ciekawe wyzwania (no bo tamto wyżej przyznam brzmi nudnie). Ubuntu mogłoby zaoferować możliwość uruchamiania aplikacji Androidowych. Byłby to super ruch, powieważ wtedy Ubuntu stałoby się idealnym systemem na wszelakie tablety, netbooki i inne mini-komputery.</p> <p>Wyobraź sobie: możesz sobie korzystać z Androidowych aplikacji, a kiedy trzeba uruchamiasz sobie najnormalniejszego Gedita, Eclipse'a, Pidgina czy Firefoksa, drukujesz na normalnej drukarce przez USB, wystawiasz serwer FTP albo grasz w Open Arenę.</p> <p>Technicznie odpalanie Androidowych aplikacji na Linuksie jest możliwe, nawet całkiem. Wystarczy uruchomić wirtualną maszynę DalvikVM a w niej aplikacje APK. Aby działały, trzeba dostarczyć implementację biblioteki standardowej Androida (np. metody interfejsu użytkownika). Można nawet się pokusić o obsługę JNI (czyli APK-ów z fragmentami skompilowanymi do kodu natywnego) z wykorzystaniem QEmu i scratchboksa, aby móc swobodnie mieszać kod dla ARM i x86/amd64.</p> <p>Skoro się da, to czemu nikt tego nie zrobił? Nikomu się nie chce? A może ktoś jest zbyt zadufany i nie będzie robił takich ustępstw w stronę &quot;wrogiej&quot; technologii? Nie mi oceniać. Mi tylko żal, wiedząc, że rozwiązanie jest tuż za rogiem, że nikomu na tym nie zależy.</p> <p>Na koniec w związku z tym, że narzekam na domyślnie skonfigurowane Ubuntu podam jak wygląda (na dzień dzisiejszy) Ubuntu, które poleciłbym z czystym sercem znajomym:</p> <ul> <li>Baza: Xubuntu, czyli Ubuntu z XFCE zamiast Unity</li> <li>Przeglądarka: Firefox (bo Chrome jest zbyt Google'owy)</li> <li>Klient poczty: Claws-mail (ewentualnie Thunderbird)</li> <li>Komunikator: Pidgin (żaden Empathy nie ma szans dorównać prostotą i po prostu dobrością Pidgina) + wtyczka libnotify do ładnych dymków z wiadomościami</li> <li>Panel: mały panel XFCE z godziną i systrayem (czytaj o tym później)</li> <li>Panel2: Docky z listą aplikacji (polecam bardzo ten dok) a'la Unity, ale zrobiony mniej inwazyjnie, no i można go przesuwać :P</li> <li>Docky potrafi komunikować zdarzenia takie jak przyjście nowego maila, albo nowej wiadomości, jeśli tylko aplikacja ustawi swojemu oknu hinta &quot;URGENT&quot;. W claws-mailu jak i w pidginie są do tego odpowiednie ustawienia bądź wtyczki</li> </ul> <p>Taki system działa naprawdę miodnie, jest szybciutki i zrozumiały dla normalnego usera. Jednocześnie nie zmusza go do zrozumienia jakichś skomplikowanych konceptów i po prostu działa. I tak powinno wyglądać Ubuntu.</p> <p>Boli mnie konieczność posiadania systraya. Uważam, że jego funkcjonalność <strong>da się</strong> wkomponować w dok (który już potrafi łączyć pasek ze skrótami do aplikacji z listą uruchomionych aplikacji).</p> <p>Zarówno Unity jak i Docky (i inne doki też) potrafią wyświetlać na ikonce danej aplikacji np. ilość nieprzeczytanych wiadomości, jak również wyświetlać customowe opcje w menu ikonki w doku. Jeden i drugi ma do tego specjalne API i to jest bardzo słabe, bo wymaga instalowania dodatku bądź do doku, bądź do aplikacji, a przecież nie o to chodzi.</p> <p>Nie od tego jest FreeDesktop.org, żeby każdy programik robił swoje API. Jest potrzeba takiego API &#8212; trzeba je ustalić, choćby jakiegoś drafcika, żeby już było wiadomo w jaką stronę to wszystko zmierza, a nie czekać aż już będzie ich 10 (w dowolnie wybranym systemie pozycyjnym). Jest API do śmietnika, jest do miniaturek, niech będzie też do menu doka.</p> <p>I tak powinno działać Ubuntu. Powinno patrzyć co jest potrzebne, żeby standardowy Linuksowy desktop był bardziej użyteczny i to urzeczywistniać. Pracując z FDO i wypracowując standardowe rozwiązania zamiast narzucać swoje.</p> <p>Amen.</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=2462&amp;amp;size=small&amp;amp;timestamp=1783694814" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
					<item>
				<guid>http://piotrgabryjeluk.wikidot.com/blog:qt-4-7-and-qtwebkit-2-0-debian-packages-for-arm</guid>
				<title>Qt 4.7 and QtWebKit 2.0 Debian packages for ARM</title>
				<link>http://piotrgabryjeluk.wikidot.com/blog:qt-4-7-and-qtwebkit-2-0-debian-packages-for-arm</link>
				<description>

&lt;p&gt;&lt;a href=&quot;http://packages.debian.org/source/experimental/qt4-x11&quot;&gt;Qt 4.7 beta2&lt;/a&gt; and &lt;a href=&quot;http://packages.debian.org/source/experimental/qtwebkit&quot;&gt;QtWebKit 2.0 beta (weekly build)&lt;/a&gt;] are available in Debian experimental repository, but not for all architectures. Most notably the packages are missing for ARM architecture.&lt;/p&gt;
&lt;p&gt;by &lt;span class=&quot;printuser avatarhover&quot;&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;&lt;img class=&quot;small&quot; src=&quot;http://www.wikidot.com/avatar.php?userid=2462&amp;amp;amp;size=small&amp;amp;amp;timestamp=1783694814&quot; alt=&quot;Gabrys&quot; style=&quot;background-image:url(http://www.wikidot.com/userkarma.php?u=2462)&quot; /&gt;&lt;/a&gt;&lt;a href=&quot;http://www.wikidot.com/user:info/gabrys&quot;  &gt;Gabrys&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
</description>
				<pubDate>Thu, 29 Jul 2010 18:30:30 +0000</pubDate>
												<content:encoded>
					<![CDATA[
						 <p><a href="http://packages.debian.org/source/experimental/qt4-x11">Qt 4.7 beta2</a> and <a href="http://packages.debian.org/source/experimental/qtwebkit">QtWebKit 2.0 beta (weekly build)</a>] are available in Debian experimental repository, but not for all architectures. Most notably the packages are missing for ARM architecture.</p> <div class="content-separator" style="display: none:"></div> <p>It's worth noting, that libqt4-webkit is no longer a valid package in experimental, but is a transitional package to pull libqtwebkit4, so now QtWebKit and Qt versions are quite independent. You can use Qt 4.6 or 4.7 with the QtWebKit 2.0.</p> <p>I needed QtWebKit 2.0 on ARM, so I built it from deb-src. It went OK with no modifications of the source package.</p> <p>When it comes to Qt's 4.7 beta release I needed to patch it slightly, to disable precompiled headers (for some reason, after generating them, they were not found by installation), &#8212;fast configure flag (not sure if this is needed) and I needed to tweak src/core/io/io.pri file, because for some reason <tt>linux-* {}</tt> section of qmake file was not properly applied. Also to properly compile stuff, I added Qt3 support.</p> <p>My full diff to sources downloaded with <tt>apt-get -t experimental source qt4-x11</tt></p> <div class="code"> <div class="hl-main"> <pre><span class="hl-var">diff -ur original/qt4-x11-4.7.0~beta2/debian/rules modified/qt4-x11-4.7.0~beta2/debian/rules</span><span class="hl-default"> </span><span class="hl-reserved">--- original/qt4-x11-4.7.0~beta2/debian/rules 2010-07-29 18:27:41.000000000 +0000</span><span class="hl-default"> </span><span class="hl-reserved">+++ modified/qt4-x11-4.7.0~beta2/debian/rules 2010-07-29 18:27:52.000000000 +0000</span><span class="hl-default"> </span><span class="hl-code">@@ -89,7 +89,9 @@</span><span class="hl-default"> -demosdir &quot;/usr/lib/qt4/demos&quot; \ -examplesdir &quot;/usr/lib/qt4/examples&quot; \ -opensource \ </span><span class="hl-quotes">- -fast \</span><span class="hl-default"> </span><span class="hl-string">+ -no-fast \</span><span class="hl-default"> </span><span class="hl-string">+ -no-pch \</span><span class="hl-default"> </span><span class="hl-string">+ -qt3support \</span><span class="hl-default"> -plugin-sql-mysql \ -plugin-sql-odbc \ -plugin-sql-psql \ </span><span class="hl-var">diff -ur original/qt4-x11-4.7.0~beta2/src/corelib/io/io.pri modified/qt4-x11-4.7.0~beta2/src/corelib/io/io.pri</span><span class="hl-default"> </span><span class="hl-reserved">--- original/qt4-x11-4.7.0~beta2/src/corelib/io/io.pri 2010-07-29 18:28:09.000000000 +0000</span><span class="hl-default"> </span><span class="hl-reserved">+++ modified/qt4-x11-4.7.0~beta2/src/corelib/io/io.pri 2010-07-29 18:28:17.000000000 +0000</span><span class="hl-default"> </span><span class="hl-code">@@ -74,7 +74,6 @@</span><span class="hl-default"> SOURCES += io/qsettings_mac.cpp io/qfilesystemwatcher_fsevents.cpp } </span><span class="hl-quotes">- linux-*:!symbian {</span><span class="hl-default"> SOURCES += \ io/qfilesystemwatcher_inotify.cpp \ io/qfilesystemwatcher_dnotify.cpp </span><span class="hl-code">@@ -82,7 +81,6 @@</span><span class="hl-default"> HEADERS += \ io/qfilesystemwatcher_inotify_p.h \ io/qfilesystemwatcher_dnotify_p.h </span><span class="hl-quotes">- }</span><span class="hl-default"> freebsd-*|macx-*|darwin-*|openbsd-*:{ SOURCES += io/qfilesystemwatcher_kqueue.cpp</span></pre></div> </div> <p>You can find all of the compiled debs here:</p> <p>by <span class="printuser avatarhover"><a href="http://www.wikidot.com/user:info/gabrys" ><img class="small" src="http://www.wikidot.com/avatar.php?userid=2462&amp;amp;size=small&amp;amp;timestamp=1783694814" alt="Gabrys" style="background-image:url(http://www.wikidot.com/userkarma.php?u=2462)" /></a><a href="http://www.wikidot.com/user:info/gabrys" >Gabrys</a></span></p> 
				 	]]>
				</content:encoded>							</item>
				</channel>
</rss>