Nic0's Sphere 2014-06-16T23:57:06-07:00 http://www.nicosphere.net Nicolas Paris About FireMonkey Styles for Android 2014-06-17T00:00:00-07:00 http://www.nicosphere.net/about-firemonkey-styles-for-android <p>First, I have to say that I’m kind of a newbee in Delphi world… About a year at work.</p> <p>I’m just starting to play at home with the Android App possibility with Delphi. First things, I was amazed how fast it was to have a Hello world app running on my phone. I remember how painful it was to setup the environment with Eclipse. Up and running in less than 5 minutes, even if it was the first time I was using it.</p> <p>After putting few components, I was happy with some functionalities that I came up with, but, I thought it could looks better. I googled, found out about Stylebook, and soon I was looking for some <em>.style and </em>.fsf on my embacardero folder. After trying them, it seems that half of the dozen <em>.styles available wasn’t working on my Android device ( S4mini), and just 3 </em>.fsf specialized for Android, which I wasn’t so excited about the look.</p> <p>So, I googled again to find some more styles for FireMonkey. I didn’t came up with results, I found some, not free, but I won’t buy a style for a home, for fun, side project. I know most of the time, for extra stuff on Delphi, you need to pay, I understand it, even if I have an open source background.</p> <p>Did I miss something? As I said, I’m new in Delphi, I could have miss something interesting and obvious easily. Is there any cool FireMonkey styles somewhere, for free or cheap? Or should I carry on whit a kind of boring look? Any advices would be appreciated.</p> Jekyll is nice, but I sometime miss my old Wordpress 2013-09-01T00:00:00-07:00 http://www.nicosphere.net/jekyll-is-nice-but-missing-my-wordpress <p>Seems like I’m using Jekyll for a year and a half now, according to <a href="http://nicosphere.net/changes-on-this-blog/">this post</a>. I still use it, even if I’m not bloging often. Jekyll is fun. Jekyll is damn fast. Jekyll make me look like I’m awesome, well… maybe not. Anyway, here some thought about the downside of using Jekyll.</p> <p>I moved my blog a few times, and planning to move again for the new kimsufi offer. And every time, I have to reinstall Jekyll, and make it work… And even if it’s not some reinstallation, it could break with an update, already happen to me. So when I haven’t written blog post for a few months, and I want to spend an hour to write one. In fact, I have to spend an hour to fix Jekyll and another one to write the post. So, if you consider installing Jekyll for a friend or an association, you definitely should think about the maintenance of a tech that you probably be the only one to understand.</p> <p>This time, the problem was due to the UTF-8 bug. There are few issues already open in the github bugtracker. I tried few solutions listed, but it didn’t work for me. So I switched back the version of Ruby on my server. It’s not really a Jekyll bug, more due to Ruby, but I don’t care whose fault is it!</p> <p>Other thing, not that much important to me, but worth considering, is that Google didn’t liked so much the new site, and I maybe lost half of the traffic from him. I certainly done something wrong, and I don’t specially care, but if you do, consider this point carefully.</p> <p>I still enjoy using Jekyll, when it’s working, but I sometime miss my good old Wordpress…</p> Code Snippets For Delphi 2013-05-04T00:00:00-07:00 http://www.nicosphere.net/code-snippet-for-delphi <p>Like I said in the previous post, I started learning Delphi recently. So here&rsquo;s quick trick about code snippets, also knows as code templates, or live templates in the Delphi world. Code snippets are so useful that every IDE or decent text editor implements it.</p> <p>In the Deplhi&rsquo;s IDE, the shortcut to get thoses snippets is an unintuitive <code>ctrl+J</code>, or sometime <code>TAB</code> with some of theme. We find traditionnal conditions, loops, procedures, functions or even class templates. The nice things is you often append a <code>b</code> to your trigger word to get the begin/end block added to the structure. As <code>if</code>, and <code>ifb</code>.</p> <p>It&rsquo;s nice, but I wanted to learn to get my own one. What about a <code>fan</code> that would generate a <code>FreeAndNil(MyVar);</code> automaticaly ?</p> <p>Here the steps to do so.</p> <p>First, search for code template in the tool palette, or you can find it in the menu as well. The code generate for the snippet is an XML file, and easy to get on. You need to define the langage (Delphi), the break points, and it&rsquo;s important to define the delimiter, it must have some sort of default value, but I couldn&rsquo;t find it, so make sure de delimiter is define, otherwise it will not work. Remember as well to add the <code>|end|</code>, this add the last break point when pressing TAB. The manual part make sure the snippet is trigger on TAB (not sure of this one).</p> <p>So here the code to generate a <code>FreeAndNil</code> template :</p> <div class="highlight"><pre><code class="xml"><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;</span> <span class="nt">&lt;codetemplate</span> <span class="na">xmlns=</span><span class="s">&quot;http://schemas.borland.com/Delphi/2005/codetemplates&quot;</span> <span class="na">version=</span><span class="s">&quot;1.0.0&quot;</span><span class="nt">&gt;</span> <span class="nt">&lt;template</span> <span class="na">name=</span><span class="s">&quot;fan&quot;</span> <span class="na">invoke=</span><span class="s">&quot;manual&quot;</span><span class="nt">&gt;</span> <span class="nt">&lt;point</span> <span class="na">name=</span><span class="s">&quot;variable&quot;</span><span class="nt">&gt;</span> <span class="nt">&lt;text&gt;</span> MyVar <span class="nt">&lt;/text&gt;</span> <span class="nt">&lt;hint&gt;</span> Free and Nil a variable <span class="nt">&lt;/hint&gt;</span> <span class="nt">&lt;/point&gt;</span> <span class="nt">&lt;description&gt;</span> Create a FreeAndNil <span class="nt">&lt;/description&gt;</span> <span class="nt">&lt;author&gt;</span> Nicolas Paris <span class="nt">&lt;/author&gt;</span> <span class="nt">&lt;code</span> <span class="na">language=</span><span class="s">&quot;Delphi&quot;</span> <span class="na">delimiter=</span><span class="s">&quot;|&quot;</span><span class="nt">&gt;</span><span class="cp">&lt;![CDATA[</span> <span class="cp"> FreeAndNil(|variable|);|end|</span> <span class="cp"> ]]&gt;</span> <span class="nt">&lt;/code&gt;</span> <span class="nt">&lt;/template&gt;</span> <span class="nt">&lt;/codetemplate&gt;</span> </code></pre></div> <p>Well, not a big deal, some newbie stuff as I am, for other newbies. Feel free to share your snippets.</p> What's Next Here? PHP, Delphi and More... 2013-02-17T00:00:00-08:00 http://www.nicosphere.net/whats-next-here-php-delphi-and-more <p>First, I know that it&rsquo;s been a long time since I wrote anything here. I’ve been busy to get some kind of degree in programming and acquire a new job recently. So I went from a passionate developer to a paid passionate developer! I hope this will give me some new ideas to write on. Ideas about programming stuffs.</p> <p>I’ve already wrote about PHP, maybe not much, but it’s a nice language, I’ll might try to write some more about PHP. I even try to write about unit tests with PHP. I like unit tests and some might remember about the Python series about tests. I already played with PHPUnit, but it’s about <a href="https://github.com/atoum/">atoum</a>, a nice and sexy PHP unit tests framework that I’ll probably write about.</p> <p>I’ll certainly write about Delphi, this might be surprising as it’s not specially the kind of language that I use to, but I really looking forward about it, as I’m taking the learning of this new language as a challenge. The Delphi’s community isn’t really large, so it could be fun to write about it from a newbie point of view. I really can’t wait to learn that new language! I know that Delphi isn’t quite the most popular, or even the sexiest language, and it could scare the few readers that this blog have left.</p> <p>I really miss the time I use to write every week in this blog and I really hope I can change this. Maybe the choice to write only in english cause me to slow down the publication, or maybe just the willing.</p> <p>See you soon for some more technical stuff!</p> Convert a structured array of strings into a nested array for PHP 2012-11-25T00:00:00-08:00 http://www.nicosphere.net/convert-a-structured-array-of-strings-into-a-nested-array-for-php <p>It&rsquo;s a long title, I agree, but I&rsquo;ll try to explain simply what I wanted to do.</p> <p>Let&rsquo;s consider the following PHP associative array.</p> <div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span> <span class="nv">$data</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span> <span class="s1">&#39;mysql_host&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;localhost&#39;</span><span class="p">,</span> <span class="s1">&#39;mysql_db&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;mydatabase&#39;</span><span class="p">,</span> <span class="s1">&#39;mysql_password&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;mypass&#39;</span><span class="p">,</span> <span class="s1">&#39;foo&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;bar&#39;</span><span class="p">,</span> <span class="s1">&#39;some_very_long_path&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;some data&#39;</span> <span class="p">);</span> <span class="cp">?&gt;</span><span class="x"></span> </code></pre></div> <p>I want to convert to a nested array like:</p> <div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span> <span class="nv">$data</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span> <span class="s1">&#39;mysql&#39;</span> <span class="o">=&gt;</span> <span class="k">array</span><span class="p">(</span> <span class="s1">&#39;host&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;localhost&#39;</span><span class="p">,</span> <span class="s1">&#39;db&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;mydatabase&#39;</span><span class="p">,</span> <span class="s1">&#39;password&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;mypass&#39;</span> <span class="p">),</span> <span class="s1">&#39;foo&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;bar&#39;</span><span class="p">,</span> <span class="s1">&#39;some&#39;</span> <span class="o">=&gt;</span> <span class="k">array</span><span class="p">(</span> <span class="s1">&#39;very&#39;</span> <span class="o">=&gt;</span> <span class="k">array</span><span class="p">(</span> <span class="s1">&#39;long&#39;</span> <span class="o">=&gt;</span> <span class="k">array</span><span class="p">(</span> <span class="s1">&#39;path&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;some data&#39;</span> <span class="p">)</span> <span class="p">)</span> <span class="p">)</span> <span class="p">);</span> <span class="cp">?&gt;</span><span class="x"></span> </code></pre></div> <p>Ideas beyond that, is to convert the array into an YAML config, but the important part is that I can&rsquo;t assume how deeply nested will be the array. Here the corresponding YAML configuration file, for example purpose.</p> <div class="highlight"><pre><code class="yaml"><span class="l-Scalar-Plain">mysql</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">host</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">localhost</span> <span class="l-Scalar-Plain">db</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">mydatabase</span> <span class="l-Scalar-Plain">password</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">mypass</span> <span class="l-Scalar-Plain">foo</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">bar</span> <span class="l-Scalar-Plain">some</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">very</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">long</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">path</span><span class="p-Indicator">:</span> <span class="l-Scalar-Plain">some data</span> </code></pre></div> <p>So, here the solution that I came up, using a reference, to keep track of the positionning of the constructed array.</p> <div class="highlight"><pre><code class="php"><span class="cp">&lt;?php</span> <span class="k">function</span> <span class="nf">postToArray</span> <span class="p">(</span><span class="nv">$post</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$config</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span> <span class="k">foreach</span> <span class="p">(</span><span class="nv">$post</span> <span class="k">as</span> <span class="nv">$key</span> <span class="o">=&gt;</span> <span class="nv">$value</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$reference</span> <span class="o">=</span> <span class="o">&amp;</span><span class="nv">$config</span><span class="p">;</span> <span class="nv">$path</span> <span class="o">=</span> <span class="nb">explode</span><span class="p">(</span><span class="s1">&#39;_&#39;</span><span class="p">,</span> <span class="nv">$key</span><span class="p">);</span> <span class="k">for</span> <span class="p">(</span><span class="nv">$i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="nv">$i</span> <span class="o">&lt;</span> <span class="nx">sizeOf</span><span class="p">(</span><span class="nv">$path</span><span class="p">);</span> <span class="nv">$i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="nv">$i</span> <span class="o">==</span> <span class="nx">sizeOf</span><span class="p">(</span><span class="nv">$path</span><span class="p">)</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$reference</span><span class="p">[</span><span class="nv">$path</span><span class="p">[</span><span class="nv">$i</span><span class="p">]]</span> <span class="o">=</span> <span class="nv">$value</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nb">array_key_exists</span><span class="p">(</span><span class="nv">$path</span><span class="p">[</span><span class="nv">$i</span><span class="p">],</span> <span class="nv">$reference</span><span class="p">))</span> <span class="p">{</span> <span class="nv">$reference</span><span class="p">[</span><span class="nv">$path</span><span class="p">[</span><span class="nv">$i</span><span class="p">]]</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span> <span class="p">}</span> <span class="nv">$reference</span> <span class="o">=</span> <span class="o">&amp;</span><span class="nv">$reference</span><span class="p">[</span><span class="nv">$path</span><span class="p">[</span><span class="nv">$i</span><span class="p">]];</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="k">return</span> <span class="nv">$config</span><span class="p">;</span> <span class="p">}</span> <span class="cp">?&gt;</span><span class="x"></span> </code></pre></div> <p>I&rsquo;ll be more than happy if someone could point me at a better solution. Hope it could help someone else than myself.</p> <p>EDIT: thanks to Nicoon, for <a href="http://www.reddit.com/r/PHP/comments/13rau5/convert_a_structured_array_of_strings_into_a/c76ggc9">his solution on Reddit</a>, that use a recursive function, and point out that HTTP allow this already nicely.</p> Shaarli, a self hosted bookmark service 2012-08-15T00:00:00-07:00 http://www.nicosphere.net/shaarli-a-self-hosted-bookmark-service <p>I used to manage my notes with TiddlyWiki, which is absolutely nice, but with time it became more and more a link manager. So I tried to find something that fit my need, something that I could host on my server.</p> <p>I came up with <em><a href="http://sebsauvage.net/wiki/doku.php?id=php:shaarli">Shaarli</a></em>, meaning <em>share link</em>. I&rsquo;m using it for a month now, and it does what I need. The website gives a long list of features, but I wanted something simple to use, that exactly how <em>Shaarli</em>works, simply! The most surprising stuff is the storage system, a plain text file, there isn&rsquo;t any database, I wouldn&rsquo;t mind to setup some databases for this, but it has the advantage to be simpler to install. The performance doesn&rsquo;t seem to be affected, the developer use a <a href="http://sebsauvage.net/links/">11730 links</a> instance for his own needs, and still growing. Even with ten thousand links, the application seems to be fluid and fast enough.</p> <p><img src="/img/shaarli.png" alt="Shaarly screenshot" /></p> <p><em>Shaarli</em> manages private and public links, I thought that keep most of my links public could be interesting, as it&rsquo;s mostly about programming stuffs, it could interest people. So <a href="http://bkm.nicosphere.net/">here my instance of Shaarly</a>.</p> <p>Last detail, it&rsquo;s a <em>share link</em> bookmark that you can add in your favorite bar, which is some JavaScript code that pop you up a window, with metadata already added. So add a link is fast enough, and that&rsquo;s important to keep using an application like this.</p> <p>To conclude, <em>Shaarly</em> does nicely what I want, even if I haven&rsquo;t look for lots of alternative, I&rsquo;m satisfied with it. It&rsquo;s simple to use, <em>KISS</em>, and written in PHP, by a French guy. <em>Shaarly</em> absolutely worth a try.</p> Rectangular Selection With URXVT 2012-07-01T00:00:00-07:00 http://www.nicosphere.net/rectangular-selection-with-urxvt <p>Few months ago, while I was talking to some geeks at my Linux User Group, I was surprised to see that they didn&rsquo;t knew about this trick, the rectangular selection with the console URXVT.</p> <p>Maybe not important, but it could be useful, especially with IRC client, such as <em>weechat</em>. Select few lines without the nicklist or timestamps is nice when you want do some copy/paste, even if you can switch on and off the nicklist easily.</p> <p>All you have to do for the selection is press <code>Alt</code> and select in the same time with the left click of the mouse.</p> <p><img src="/img/rectangular-select-urxvt.png" alt="weechat with rectangular selection" /></p> <p>A quick blog post, for a quick trick that can comes handy</p> CGit, Nginx and Arch Linux 2012-05-06T00:00:00-07:00 http://www.nicosphere.net/cgit-nginx-and-arch-linux <p>Here&rsquo;s a quick reminder to get CGit and Nginx running together on an Arch Linux server. I assume you have already Nginx up and running.</p> <p>First, we install the require packages.</p> <div class="highlight"><pre><code class="bash">pacman -S fcgiwrap cgit </code></pre></div> <p>The default configuration values for fcgiwrap should be fine, but you can check anyway in <code>/etc/conf.d/fcgiwrap</code>.</p> <p>Here the Nginx configuration for the CGit part. <em>EDIT</em>: check the update code at the end of the post.</p> <div class="highlight"><pre><code class="nginx"><span class="k">server</span> <span class="p">{</span> <span class="kn">listen</span> <span class="mi">80</span><span class="p">;</span> <span class="kn">server_name</span> <span class="s">git.nicosphere.net</span><span class="p">;</span> <span class="kn">index</span> <span class="s">cgit.cgi</span><span class="p">;</span> <span class="kn">gzip</span> <span class="no">off</span><span class="p">;</span> <span class="kn">location</span> <span class="s">/</span> <span class="p">{</span> <span class="kn">root</span> <span class="s">/usr/share/webapps/cgit/</span><span class="p">;</span> <span class="p">}</span> <span class="kn">if</span> <span class="s">(!-f</span> <span class="nv">$request_filename</span><span class="s">)</span> <span class="p">{</span> <span class="kn">rewrite</span> <span class="s">^/([^?/]+/[^?]*)?(?:\?(.*))?</span>$ <span class="s">/cgit.cgi?url=</span><span class="nv">$1&amp;$2</span> <span class="s">last</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="k">location</span> <span class="p">~</span> <span class="sr">\.cgi$</span> <span class="p">{</span> <span class="kn">gzip</span> <span class="no">off</span><span class="p">;</span> <span class="kn">include</span> <span class="s">fastcgi_params</span><span class="p">;</span> <span class="kn">fastcgi_pass</span> <span class="n">127.0.0.1</span><span class="p">:</span><span class="mi">9001</span><span class="p">;</span> <span class="kn">fastcgi_index</span> <span class="s">cgit.cgi</span><span class="p">;</span> <span class="kn">fastcgi_param</span> <span class="s">SCRIPT_FILENAME</span> <span class="s">/usr/share/webapps/cgit/cgit.cgi</span><span class="p">;</span> <span class="kn">fastcgi_param</span> <span class="s">DOCUMENT_ROOT</span> <span class="s">/usr/share/webapps/cgit/</span><span class="p">;</span> <span class="p">}</span> <span class="k">}</span> </code></pre></div> <p>Obviously, make sure the <code>server_name</code> is setup right. The <code>SCRIPT_FILENAME</code> and <code>DOCUMENT_ROOT</code> are those used with the official Arch Linux package, it might be different if you retrieved your own tarball.</p> <p>Now, let&rsquo;s get all this running.</p> <div class="highlight"><pre><code class="bash">rc.d start fcgiwrap <span class="o">&amp;&amp;</span> rc.d restart nginx </code></pre></div> <p>Don&rsquo;t forget to add the <code>fcgiwrap</code> daemon to the corresponding <code>rc.conf</code> line, to get it working when if you restart the server.</p> <p>Once it&rsquo;s running, you might setup the <code>/etc/cgitrc</code> file as usual. You certainly want add at least the CSS file as follow:</p> <div class="highlight"><pre><code class="ini"><span class="na">css</span><span class="o">=</span><span class="s">/cgit.css</span> </code></pre></div> <p><strong>EDIT</strong>: As I wanted a basic authentication, with an exception for the <code>/pub/</code> directiory, and couldn&rsquo;t find the correct answer, I asked to <a href="http://stackoverflow.com/questions/10486340/nginx-and-auth-basic-with-cgit">StackOverflow</a>. The answer works fine for me, and even better that the previous code. For the record, here the final nginx configuration:</p> <div class="highlight"><pre><code class="nginx"><span class="k">server</span> <span class="p">{</span> <span class="kn">listen</span> <span class="mi">80</span><span class="p">;</span> <span class="kn">server_name</span> <span class="s">git.nicosphere.net</span><span class="p">;</span> <span class="kn">index</span> <span class="s">cgit.cgi</span><span class="p">;</span> <span class="kn">gzip</span> <span class="no">off</span><span class="p">;</span> <span class="kn">root</span> <span class="s">/usr/share/webapps/cgit</span><span class="p">;</span> <span class="c1"># $document_root is now set properly, and you don&#39;t need to override it</span> <span class="kn">include</span> <span class="s">fastcgi_params</span><span class="p">;</span> <span class="kn">fastcgi_param</span> <span class="s">SCRIPT_FILENAME</span> <span class="nv">$document_root/cgit.cgi</span><span class="p">;</span> <span class="kn">location</span> <span class="s">/</span> <span class="p">{</span> <span class="kn">try_files</span> <span class="nv">$uri</span> <span class="s">@cgit</span><span class="p">;</span> <span class="p">}</span> <span class="c1"># Require auth for requests sent to cgit that originated in location / </span> <span class="kn">location</span> <span class="s">@cgit</span> <span class="p">{</span> <span class="kn">auth_basic</span> <span class="s">&quot;Restricted&quot;</span><span class="p">;</span> <span class="kn">auth_basic_user_file</span> <span class="s">/srv/gitosis/.htpasswd</span><span class="p">;</span> <span class="kn">gzip</span> <span class="no">off</span><span class="p">;</span> <span class="c1"># rewrites in nginx don&#39;t match the query string</span> <span class="kn">rewrite</span> <span class="s">^/([^/]+/.*)?</span>$ <span class="s">/cgit.cgi?url=</span><span class="nv">$1</span> <span class="s">break</span><span class="p">;</span> <span class="kn">fastcgi_pass</span> <span class="n">127.0.0.1</span><span class="p">:</span><span class="mi">9001</span><span class="p">;</span> <span class="p">}</span> <span class="kn">location</span> <span class="s">^~</span> <span class="s">/pub/</span> <span class="p">{</span> <span class="kn">gzip</span> <span class="no">off</span><span class="p">;</span> <span class="kn">rewrite</span> <span class="s">^/([^/]+/.*)?</span>$ <span class="s">/cgit.cgi?url=</span><span class="nv">$1</span> <span class="s">break</span><span class="p">;</span> <span class="kn">fastcgi_pass</span> <span class="n">127.0.0.1</span><span class="p">:</span><span class="mi">9001</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div> Turses, a fork from Tyrs, ncurses Twitter client 2012-04-15T00:00:00-07:00 http://www.nicosphere.net/turses-a-fork-from-tyrs-ncurses-twitter-client <p>For background reminder, I started last year a ncurses twitter client called <a href="http://tyrs.nicosphere.net">Tyrs</a>, as it was almost the only ncurses client, some persons used it. Earlier this year, I wrote a <a href="http://www.nicosphere.net/small-projects-life-depends-on-his-owner/">blog post announcing that haven&rsquo;t enought time and motivation anymore to carry on Tyrs</a>. I was a bit frustrated, as I knew Tyrs had some bugs left, due to the late migration to the Urwid module (awesome python ncurses module by the way), and I knew that some persons was still using it.</p> <p>The good news is, Tyrs has been forked! A warm welcome to <a href="https://github.com/alejandrogomez/turses">Turses</a>!</p> <p>You might have some questions. What&rsquo;s going on? A fork isn&rsquo;t a big deal if nothing happen behind? Any new stuffs?</p> <p>A short answer could be that I&rsquo;m kind of exited about the fork. But here some more details about it.</p> <p>The fork has been initiated by <a href="https://github.com/alejandrogomez/">Alejandro Gómez</a> a few months ago after writing some patchs for Tyrs. Starting from Tyrs, he wasn&rsquo;t afraid to moves codes around, rearrange stuffs, doing some refactoring, even add some new functionalities. I must say he&rsquo;s done some good and cleaver work. So it&rsquo;s obvious that <a href="https://github.com/alejandrogomez/turses">Turses</a> isn&rsquo;t a fork <em>just to add a patch</em>, but there is a lot going on, and for the best! It might sound like a programmer side view about it, but I&rsquo;m confident about Turses future, and that&rsquo;s what&rsquo;s important for users.</p> <p>About new features, I really like the new dynamic buffer managment, meaning that you now can add or remove buffers on the fly. For example you can add a buffer of some keyword research or from a user timeline, a bit like you add or remove a channel from an IRC client. That&rsquo;s sweet! Another feature is the possibility to display two buffer at once. Let say for example, home and mentions timeline. I have to say that I haven&rsquo;t try yet, but It looks cool!</p> <p>Here the traditional screenshot, taken from the github page.</p> <p><img src="/images/turses.png" alt="screenshot" /></p> <p>So, I&rsquo;m quite happy about Turses, I really hope Alejandro will enjoy writing it, as I enjoyed writing Tyrs. If you&rsquo;re using Tyrs, or even if you don&rsquo;t, you really should give Turses a shot. And don&rsquo;t be affraid to [reports bugs][5] or even participate, as Turses is naturaly under licence GPLv3!</p> <p>I hope the best for Turses.</p> Download subtitles with Submarine 2012-03-28T00:00:00-07:00 http://www.nicosphere.net/download-subtitles-with-submarine <p>I&rsquo;m a big user of subtitles, the reason is simple, I always watch movies or series in English, even if I&rsquo;m French. To help me to understand movies, I use English subtitles. In this way, it&rsquo;s easier for me to follow the film even if I&rsquo;m tired. It also help me to learn new words.</p> <p>Like everything else, you don&rsquo;t want waste your time looking for subtitles around the web, that why software come naturally for subtitle retrieving tasks. That&rsquo;s exactly what <em>Submarine</em> does, and well.</p> <p>I have to say that I didn&rsquo;t really looked for this kind of program, only tried one, and I&rsquo;m happy about it. I found <em>Submarine</em> while I was reading one of my favorite section of the Arch Linux official forum called <a href="https://bbs.archlinux.org/viewforum.php?id=27">Community Contributons</a>, it worths looking around for some new softwares announcing, some of them has become quite famous since. Anyway, I saw <a href="https://bbs.archlinux.org/viewtopic.php?id=124138">this announcement</a> maybe a month ago of this program called <em>Submarine</em>.</p> <p>Maybe <em>Submarine</em> isn&rsquo;t perfect, or doesn&rsquo;t find every subtitles that I want, but it does a good job for sure.</p> <p>Here some through about it:</p> <ul> <li>Command line: That&rsquo;s fine, who want some GUI for this kind of program anyway?</li> <li>Two servers: Submarine try to retrieve from OpenSubtitle and Podnapisi. That&rsquo;s sounds good to me.</li> <li>Download multiple movies at once: I found it useful for series. With series like Big Bang Theory, I like to watch several episode in a row. Therefor download all subtitles at once is faster.</li> <li>Download best rated: cool feature again, that it avoid badly ranked subtitles.</li> <li>Rename to match the movie: As VLC automatically loads subtitles if it match the movie title, it saves me some time to manually set the subtitle by rename the subtitle if needed.</li> <li>Language: More for information that a feature, but it use Vala.</li> </ul> <p>If you&rsquo;re using Arch Linux, you can find it in <em>AUR</em> and install it via <code>yaourt -S submarine</code>.</p> <p>Source code can be seen <a href="https://github.com/blazt/submarine">on github</a>, and it&rsquo;s release under GPLv3. That&rsquo;s it, no much more to say but thanks to the author of <em>Submarine</em>.</p> Small project's life depends on his owner 2012-02-19T00:00:00-08:00 http://www.nicosphere.net/small-projects-life-depends-on-his-owner <p>Last year, I wrote a small program, a twitter&rsquo;s client with a ncurses interface, called <a href="http://tyrs.nicosphere.net">Tyrs</a>. It&rsquo;s a small project, but used by some persons and have some activities with bugs reports and pull requests. The problem is I&rsquo;m getting bored of the project, moved on to other personal stuffs and learning, and time isn&rsquo;t extensible. I learned from it and really enjoyed the time spend.</p> <p>I don&rsquo;t believe in Christmas, I know if I don&rsquo;t really maintain the program anymore, it will be abandoned, some dependencies releases would mess up the program or I don&rsquo;t know. This is probably a very usual problem, the owner stops maintain the program for some reason, and nobody will carry on the project.</p> <p>When I&rsquo;m saying &ldquo;small project&rdquo;, I haven&rsquo;t defined what a small project is, but in fact, I&rsquo;m sure the problem occur for much more projects that I would think, even some quite interesting and known project.</p> <p>I would love some kind of website where I could subscribe my project, to find a new owner for the project. I don&rsquo;t know if a website like that exists, or even if people would be interested for, but I know that it&rsquo;s always interesting to read through other code, it would be a good and useful way to progress.</p> <p>A short write-up, because there isn&rsquo;t so much to say about it. Of course, I have no regret for endless night spend on this project, I just hope it won&rsquo;t end like thousands of other projects, unmaintained.</p> Clint, Command Line Library for Python 2012-01-05T00:00:00-08:00 http://www.nicosphere.net/clint-command-line-library-for-python <p>This library is the kind I like, the kind which make your life easier, perfect for someone like me, who uses Python all the time. So, what can <a href="https://github.com/kennethreitz/clint">Clint</a> do for you? Well, there are a bunch of tools that might come handy when you do some command line based programming, especially quick scripts. If you use Python as your primary langage, CLI stuff is always useful.</p> <h3>Colors</h3> <p>Having some colored output can be nice, but I don&rsquo;t want to use some ncurses interface to have a nice display. A common request is for text color to be green for an expected result, and red otherwise. The highest ranked answer from <a href="http://stackoverflow.com/questions/287871/print-in-terminal-with-colors-using-python">this stackoverflow&rsquo;s question</a> gives some<code>'\033[93m'</code>, which it does the works, but isn&rsquo;t lovely, or even <em>pythonic</em>.</p> <p>Let&rsquo;s see the simplest example possible:</p> <div class="highlight"><pre><code class="python"><span class="kn">from</span> <span class="nn">clint.textui</span> <span class="kn">import</span> <span class="n">colored</span> <span class="k">print</span> <span class="n">colored</span><span class="o">.</span><span class="n">red</span><span class="p">(</span><span class="s">&#39;some warning message&#39;</span><span class="p">)</span> <span class="k">print</span> <span class="n">colored</span><span class="o">.</span><span class="n">green</span><span class="p">(</span><span class="s">&#39;nicely done!&#39;</span><span class="p">)</span> </code></pre></div> <p>How intuitive was that! At least, I don&rsquo;t need to check on the documentation every time I want a red message!</p> <p>If you only need one word in different color, it&rsquo;s as simple as a concatenation, here&rsquo;s a quick example:</p> <div class="highlight"><pre><code class="python"><span class="kn">from</span> <span class="nn">clint.textui</span> <span class="kn">import</span> <span class="n">colored</span> <span class="k">print</span> <span class="s">&#39;I love &#39;</span> <span class="o">+</span> <span class="n">colored</span><span class="o">.</span><span class="n">yellow</span><span class="p">(</span><span class="s">&#39;pyt&#39;</span><span class="p">)</span> <span class="o">+</span> <span class="n">colored</span><span class="o">.</span><span class="n">blue</span><span class="p">(</span><span class="s">&#39;hon&#39;</span><span class="p">)</span> </code></pre></div> <h3>Indentation</h3> <p>One of the main feature of Clint, is to handle nicely indentations. It even managed nested indentation, a <em>quote</em> system, allow you to set some prefix chars, like quotes in emails for example. Here a quick example:</p> <div class="highlight"><pre><code class="python"><span class="kn">from</span> <span class="nn">clint.textui</span> <span class="kn">import</span> <span class="n">colored</span><span class="p">,</span> <span class="n">indent</span><span class="p">,</span> <span class="n">puts</span> <span class="k">with</span> <span class="n">indent</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="n">quote</span><span class="o">=</span><span class="n">colored</span><span class="o">.</span><span class="n">red</span><span class="p">(</span><span class="s">&#39; &gt;&#39;</span><span class="p">)):</span> <span class="n">puts</span> <span class="p">(</span><span class="s">&#39;some random text&#39;</span><span class="p">)</span> <span class="n">puts</span> <span class="p">(</span><span class="s">&#39;another text&#39;</span><span class="p">)</span> <span class="k">with</span> <span class="n">indent</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="n">quote</span><span class="o">=</span><span class="n">colored</span><span class="o">.</span><span class="n">green</span><span class="p">(</span><span class="s">&#39; |&#39;</span><span class="p">)):</span> <span class="n">puts</span><span class="p">(</span><span class="s">&#39;some more nested identation&#39;</span><span class="p">)</span> <span class="n">puts</span><span class="p">(</span><span class="s">&#39;cool isn</span><span class="se">\&#39;</span><span class="s">t?&#39;</span><span class="p">)</span> </code></pre></div> <p>Once executed, the output gives:</p> <pre><code>&gt; some random text &gt; another text &gt; | some more nested identation &gt; | cool isn't? </code></pre> <p>Looks good without breaking a sweat!</p> <h3>Arguments</h3> <p>There are ways to handle arguments, like the module <code>argparse</code>, or even <code>sys.args</code>. However, Clint wants to be as simple and useful as possible. It allows you to make distinction between the arguments passed:</p> <ul> <li><code>args.all</code> a simple list of every arguments passed.</li> <li><code>args.flags</code> list only flags, meaning with <code>--foo</code> or <code>-f</code> passed, excluding everything else that doesn&rsquo;t contain a dash.</li> <li><code>args.files</code> this one could be very useful, it detects files in the arguments line, even with <code>*</code> wildcard. So for example you have in the directory <code>foo.py</code> and <code>bar.py</code>, entering something like <code>*.py</code> will return in the <code>args.files</code> a list with those two files.</li> <li><code>args.not_files</code> is every thing that wasn&rsquo;t detected by the above argument.</li> <li><code>args.grouped</code> help you to managed grouped arguments.</li> </ul> <p>For a redistributed program that I take time over, I would probably use <code>argparse</code>, as it&rsquo;s more common, and gives you a nice help output. But for a quick homemade script, that only need to take few arguments, I really think this could be an alternative. Either way, it worth having a look at.</p> <h3>Progress bar, files and pipes</h3> <p>Clint comes with more tools, which are easy to use. Let&rsquo;s look at a progress bar with Clint:</p> <div class="highlight"><pre><code class="python"><span class="kn">from</span> <span class="nn">time</span> <span class="kn">import</span> <span class="n">sleep</span> <span class="kn">from</span> <span class="nn">random</span> <span class="kn">import</span> <span class="n">random</span> <span class="kn">from</span> <span class="nn">clint.textui</span> <span class="kn">import</span> <span class="n">progress</span> <span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">progress</span><span class="o">.</span><span class="n">bar</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="mi">100</span><span class="p">)):</span> <span class="n">sleep</span><span class="p">(</span><span class="n">random</span><span class="p">()</span> <span class="o">*</span> <span class="mf">0.2</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">progress</span><span class="o">.</span><span class="n">dots</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="mi">100</span><span class="p">)):</span> <span class="n">sleep</span><span class="p">(</span><span class="n">random</span><span class="p">()</span> <span class="o">*</span> <span class="mf">0.2</span><span class="p">)</span> </code></pre></div> <pre><code>[######################## ] 75/100 </code></pre> <p>Clint handles pipes, eg. <code>cat foo.txt | bar.py</code>, or resources like handling files IO.</p> <h3>Documentation and Conclusion</h3> <p>This post is not a review of every possible utility that Clint has to offer, but more of a quick overview, and memo for myself. I really think Clint could come in handy from time to time. Unfortunately, there is a lack of documentation, not much more than the <a href="https://github.com/kennethreitz/clint/tree/develop/examples">README</a> from the github repository, as the <code>/doc/</code> directory doesn&rsquo;t contain much. The best place to start is to directly check <a href="https://github.com/kennethreitz/clint/tree/develop/examples">example</a> codes provides with the library.</p> <p>Another thing that could bother you is, so far, Clint only works with python 2.x. Python 3 compatibility is include in the todo list, as is documentations.<br/> <strong>Edit about Python3</strong>: Not true anymore, thanks to Kenneth Reitz, whose done a release today with Python3 support!</p> <p>I hope you enjoyed this quick review of <a href="https://github.com/kennethreitz/clint">Clint</a>. Anyway, it&rsquo;s in my toolbox now.</p> Changes on This Blog 2012-01-02T00:00:00-08:00 http://www.nicosphere.net/changes-on-this-blog <p>Since I started blogging, this is the biggest change I&rsquo;ve done. So I felt like I own you an explanation. The main reason was to separate the English content from the French one. Well, at least, it&rsquo;s what I&rsquo;m telling myself, as I know I changed the blog engine for <a href="https://github.com/mojombo/jekyll">Jekyll</a>, just because I like the way it works. I&rsquo;m aware that it might sounds unreasonable to change of CMS like that, but I&rsquo;m blogging for my pleasure, spending lots of time with, so it worth to change for a better system, that suite better my way about computers.</p> <h2>About French Content</h2> <p>First time I said in this blog that I wanted to write in english was in <a href="http://www.nicosphere.net/choix-de-la-langue-pour-un-billet-technique-2357/">this post</a>, it was more than 9 months ago. It took me some time to find the courage to do so, as I started only a couple of months ago.</p> <p>Anyway, I moved the content to <a href="http://fr.nicosphere.net">this link</a>, I had to manage some redirections, as it isn&rsquo;t a good idea to leaves 404 pages. I probably won&rsquo;t use it that much now. I certainly only publish the Hacker Weekly News series, I did think about to stop it, but I like this series, helps me to classify information, and keep track of it. So I&rsquo;ll should carry on the series on the French part of this site. So, if you still want follow the Hacker Weekly News series, you should add <a href="http://fr.nicosphere.net/feed/">this feed</a> on your reader.</p> <p>The main site, of this post, keep the same feed as before, so no need to change anything.</p> <h2>About Jekyll</h2> <p>If you never heard about <a href="https://github.com/mojombo/jekyll">Jekyll</a>, is a static website generator, the main idea is to generate the entire site in plain HTML, with obviously some JavaScript, but no server side language such as PHP. I never really liked hack into Wordpress, at the opposite to Jekyll, witch is much easier to get into. You just need some Ruby background. I hesitated with blogofile as it&rsquo;s written in Python.</p> <p>I won&rsquo;t explain why Jekyll, or any static website generator, are nice to use, there is already lots of blog post around the web.</p> <h2>About Github Pages</h2> <p>I did want try this solution, Jekyll was build to works with Github pages, the idea is simply to push on the repository, and Github does the generation of the site. The problem is Github doesn&rsquo;t allow any plugins. Fair enough, I can understand that they don&rsquo;t want any arbitrary code to be run on them server, but it loose one of the main interest of it. No plugins, no hack, no interest, simple as that. So I&rsquo;ll host myself, with some kind of rsync over ftp, seems like lftp does something like that with the mirror mode.</p> <p>I would think about Github pages if I haven&rsquo;t used a plugin to generate all my redirection.</p> <p>I still have some stuffs and improvements to take care of.</p> <p>That&rsquo;s all for now, see you soon with some real blog posts!</p> PhotoShow, Web gallery without SQL 2011-12-04T00:00:00-08:00 http://www.nicosphere.net/photoshow-web-gallery-without-sql-2558 <p>When it comes to web gallery, I usually choose <a href="http://piwigo.org/">Piwigo</a>, a safe choice for a stable PHP gallery.</p> <p>Last week, I heard about a new project, called <a href="http://www.photoshow-gallery.com/">PhotoShow</a>, a nice looking web gallery. A <a href="http://www.photoshow-gallery.com/demo/">demo website</a> is available. Here a quick functionalities review.</p> <ul> <li>Easy installation, get latest tarball on github, or simply a git clone, set two lines from the configuration file, and you are ready to go.</li> <li>Structure based on file system and directory, easy to manages and organizes photos and structures.</li> <li>Generate thumbnails and 800*600 images automatically with phpthumb.</li> <li>Two based directories, one with real photos, one with generated ones.</li> <li>Drag n' Drop to upload and manages the website.</li> <li>No SQL bases needed, it only based on the file system.</li> <li>Nice looking jQuery effects.</li> <li>Work fine without JavaScript.</li> <li>Manage public and private albums.</li> <li>Comments system.</li> </ul> <p><a href="/img/photoshow.png"><img src="/img/photoshow.png" alt="" title="photoshow" width="653" height="155" class="aligncenter size-full wp-image-2559" /></a></p> <p>First, I have to warn you that PhotoShow still on a early stage of his developpment. It seems stable enough, the project should improve quickly in a near future, with probably some new features. So perhaps it isn&rsquo;t ready for <em>production</em>, but should be fine for a personal use.</p> <p>Installation and configuration are straight forward, the easiest is use <code>git clone</code>, it would be simple to keep the gallery update with upstream by doing a <code>git pull</code>. You need to edit the <code>conf.ini</code> file, to set both photos and generated photos pathname. Once it done, you only need to answer the form to set your name/password account, and you&rsquo;re done.o</p> <div class="highlight"><pre><code class="bash">git clone https://github.com/thibaud-rohmer/PhotoShow.git </code></pre></div> <p>Some would appreciate the drag n' drop system, I personally liked the disposition of thumbnails, compact as google galleries, managed well different size to find the optimal display, allow you to quickly see every photos of an album.</p> <p>I will keep an eye on this project for sure.</p> <p>At last, the code can be found on <a href="https://github.com/thibaud-rohmer/PhotoShow">github</a>, under the GNU GPLv3.</p> Manage automatically two dictionaries with Firefox 2011-12-03T00:00:00-08:00 http://www.nicosphere.net/manage-automatically-two-dictionaries-with-firefox-2557 <p>When your native language isn&rsquo;t English, and when, like me, you spend time writing around the Internet, between comments from some news sites, blog posts and programming question-answer site, you have to deal with at least two languages, English, and whatever language you use at home. Unfortunately, I have trouble with grammar and spelling<a href="But">^1</a>. I probably have done what everyone else with bad spelling would do in this case, add to Firefox a spell checker. It does what I want, but as I write across websites, I need to switch the spell checker from French to English, certainly more often that I even notice.</p> <p>Switching of dictionaries is annoying, but not enough to really do something about it. When you&rsquo;re switching it, you think that perhaps you should try to google about it if there is any kind of shortcut or whatever would do the trick and save you some time, but you forget as soon as you switched the dictionary, and your mind focus on the answer/comment you&rsquo;re writing. Same thing for asking to some geek friends, quickly forgotten to ask, every time.</p> <p>So I&rsquo;d carry this <em>problem</em> who isn&rsquo;t really one, and by chance, I found the perfect solution for what I&rsquo;m asking for. It could be obvious to some persons, but after all, I&rsquo;m not switching of dictionary for that long time ago. The answer I found is no more that <a href="https://addons.mozilla.org/fr/firefox/addon/dictionary-switcher/">a Firefox plugin, called dictionary switcher</a>. This plugin recognize automatically the language you are taping of, and adapt the dictionary in function of it, few more options on it to do more precisely what you want. With a name link that, I could find it earlier, but the thing is I didn&rsquo;t toke time to look for.</p> <p>Short blog post, for a quick trick, maybe it could be useful to someone else.</p> The missing newsletter of Arch Linux 2011-12-02T00:00:00-08:00 http://www.nicosphere.net/the-missing-newsletter-of-arch-linux-2555 <p>Most of Linux distributions comes with newsletters, a short summary of what happen around distributions and the community himself. Interestingly enough, Arch Linux doesn&rsquo;t have anymore one, as far as I know. It wasn&rsquo;t always like this, here a quick review of what was done so far.</p> <p>y apologies if any informations was inaccurate.</p> <h2>The newsletter</h2> <p>Feb 2004 - Jul 2009</p> <p>As the Arch community is growing, some of you may never heard about this old newsletter, start with weekly issue, quickly became a twice a month release, finished as a monthly issue. The information provide was good, but as I became an Arch user around this time, I haven&rsquo;t the opportunity to read lots of them. For information, you still can read old archives on this link.</p> <p><a href="http://www.archlinux.org/static/magazine/">Arch Linux Newsletters Archives</a></p> <p>I&rsquo;m certainly not the only one, but I miss this newsletter.</p> <h2>Arch User Magazine</h2> <p>Apr 2009 - Jun 2009</p> <p>Unofficial project initiate by Ghost1227, in a paper magazine style, old issues can be grab in the same link as the Newsletters Archives. We can still read <a href="https://bbs.archlinux.org/viewtopic.php?id=68922">the bbs thread</a> for the first released issue. Three issues was made, and it will be merge with the official newsletter, as the author doesn&rsquo;t have the time to carry on the project as he wanted.</p> <h2>Arch Linux Magazine</h2> <p>Aug 2009 - Mar 2010</p> <p>The official newsletter, by Kensai, and the Arch User Magazine, by Ghost1227, will join their force together to provide a magazine available in both format html (newsletter format) and pdf (scribus/magazine format). Here is the <a href="https://bbs.archlinux.org/viewtopic.php?id=77538">bbs thread</a> for nostalgic, about the first released announce by Kensai. I proudly translate issues with others French contributors in my language back this time. Unfortunately, a lack of contribution, and certainly of time as well, ended the magazine after 4 releases. But meanwhile, Kensai left for personal reasons.</p> <h2>Rolling Release</h2> <p>Sep 2010 - May 2011 (Until now?)</p> <p><a href="http://rollingrelease.com/">Rolling Release</a> is an official website that aimed to succeed the Arch Linux agazine, as it&rsquo;s an e-zine, no need to have a regular issue, or even spend time with scribus to make a nice looking pdf. Here the <a href="https://bbs.archlinux.org/viewtopic.php?id=105236">forum announce</a> of the official launch of the site. Technically, the website look nice, allows comments. Even someone, jdarnold, started for few weeks a weekly issue on this site. The website has nice posts for a while, but hasn&rsquo;t published anything since May 2011, without any official reason that I&rsquo;m aware of, other than the lack of time I guess.</p> <h2>The missing newsletter</h2> <p>All this news was great informations, I&rsquo;m very thankful for all the time that contributors spends on this, on their own time. But what&rsquo;s now? I know what you think, <em>&ldquo;you want one? Do It Yourself!&rdquo;</em>, it&rsquo;s absolutely true if I was following Arch Linux actuality enough, and a more fluent English.</p> <p>What I do know is that this kind of initiatives often come from one man, no more, after all, Arch Linux came from a one man project as well. So, maybe if you are close to the community, following forum or mailing list, you might consider start some kind of newsletter. It doesn&rsquo;t need to be great, long, with lots informations. Few links in a paper, with a short description, a couple of tricks or applications taken from the forum, it&rsquo;s all it need to start something, I&rsquo;m sure the community would be thankful for this, well I&rsquo;ll be thankful for sure.</p> Tyrs 0.6.0, ncurses Twitter client, first release with Urwid 2011-12-01T00:00:00-08:00 http://www.nicosphere.net/tyrs-0-6-0-ncurses-twitter-client-first-release-with-urwid-2553 <p>Tyrs is a Twitter and Identi.ca client based on ncurses. This major release is the first one using the <a href="http://excess.org/urwid/">urwid</a> library. It will improve greatly the user interface.</p> <ul> <li>Edit a tweet: Previous release had a poorly way to edit tweet, I knew it, and wasn&rsquo;t especially proud of it and always wanted to do it again from scratch. With urwid, it was easier to manage it. So now, it&rsquo;s more like an IRC input bar to write tweet. We can do what we usually want, such as go back with arrow keys.</li> <li>I had feedback as the unicode wasn&rsquo;t perfect, editing a tweet with 2-bits long Chinese characters could sometime break the application. Fortunately, urwid has an excellent utf-8 support, so the overall management of unicode should be improve, and shouldn&rsquo;t be an issue anymore.</li> <li>More generally, a better display with less bugs.</li> </ul> <p>In many way the interaction with user is improve, and in many details. This release still in early stage of development of the urwid interface, this mean it&rsquo;s usable, but some functionalities aren&rsquo;t yet implements, and will be done soon. I always follow the <em>release early, release often</em> plan, and even everything isn&rsquo;t ready yet, I believe the improvement worth a release.</p> <p>Some stuff that need to be done in further releases:</p> <ul> <li>Configuration, lot of configuration was about the display, it will be the point of the next release.</li> <li>Better default shortcut, I&rsquo;m not so happy about the default shortcut, I&rsquo;ve started with some, and added while I was doing the implementation, but, I guess it could be remap in much better way, even if it customizable in the configuration file.</li> <li>Display without boxes, as I&rsquo;m not a huge fan of line, I&rsquo;ll probably do three default layout, <em>coming soon</em>.</li> <li>Few more functionalities such as lists, information about user&hellip;</li> </ul> <p>If you are using Arch Linux, the installation through the <a href="https://aur.archlinux.org/packages.php?ID=48849">AUR package</a> is easy:</p> <pre><code>yaourt -S tyrs # Or the latest git revision yaourt -S tyrs-git </code></pre> <p>You may find the latest code in the <a href="https://github.com/Nic0/tyrs">github repository</a>, and find tarballs in the <a href="http://pypi.python.org/pypi/tyrs">pypi page</a> of the project.</p> <p>I hope you&rsquo;ll enjoy it. As usually, any feedback is much appreciated.</p> HTML output screenshot with Urwid ncurses library 2011-11-30T00:00:00-08:00 http://www.nicosphere.net/html-output-screenshot-with-urwid-ncurses-library-2552 <p>Urwid is a ncurses library for Python, you may check older posts if you&rsquo;re not familiar about it. So far, we&rsquo;ve seen some useful functionalities and tricks, to run urwid, therefor, it&rsquo;s time to see something (almost) useless but geek, and in the spirit of ncurses programs, as urwid allow to take &ldquo;screenshots&rdquo; of the application, with a HTML output.</p> <p>The problem with the reference guide of urwid, it&rsquo;s that is not so easy to figure out how to get things done as we want. This corresponds to the <em>screen capture</em> part of the reference guide. But the easiest way to get started it&rsquo;s to check source code, and not the <em>real</em> code of urwid, but the code who actually generate the tutorial of urwid, they do use this functionality for this part. Check in the tarball, <code>docgen_tutorial.py</code> to get examples.</p> <p>Let&rsquo;s take our own example, based on the code we&rsquo;ve done in earlier post, for reminder, we obtain a list of item (couple title/description), in a <code>urwid.Frame</code> that allow to divide the space in three parts, header (the selected item), the body (list of the items), the footer (edit the description of current item). It was where we was last time. So let&rsquo;s add a screenshot of it.</p> <h2>The idea</h2> <p>The screenshot will be triggered by the <em>s</em> keystroke, the idea is to start over the main loop, and pass in arguments the sequence of keystroke wanted.</p> <h2>Trick about screen size</h2> <p>We need to pass in the screenshot the size of the screen. It will be a tuple <em>(y, x)</em>, it could be some random numbers, but it could be useful for the screenshot, and many other functionalities, to get the real size of the screen, and their is a variable for that.</p> <div class="highlight"><pre><code class="python"><span class="bp">self</span><span class="o">.</span><span class="n">loop</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">MainLoop</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">view</span><span class="p">,</span> <span class="n">palette</span><span class="p">,</span> <span class="n">unhandled_input</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">keystroke</span><span class="p">)</span> <span class="c">#[...]</span> <span class="c">#This variable contain the size in a tuple (x, y)</span> <span class="n">size</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">loop</span><span class="o">.</span><span class="n">screen_size</span> </code></pre></div> <h2>About the output</h2> <p>The output will come in a variable, but after every stroke we ask, their will be a screenshot, retrieve in a list, we need to choose the good one, probably the last one.</p> <h2>The screenshot code</h2> <div class="highlight"><pre><code class="python"><span class="kn">import</span> <span class="nn">urwid.html_fragment</span> <span class="c"># [...]</span> <span class="k">def</span> <span class="nf">keystroke</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">input</span><span class="p">)</span> <span class="c"># [...]</span> <span class="k">if</span> <span class="nb">input</span> <span class="ow">is</span> <span class="s">&#39;s&#39;</span><span class="p">:</span> <span class="n">init</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">html_fragment</span><span class="o">.</span><span class="n">screenshot_init</span> <span class="n">collect</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">html_fragment</span><span class="o">.</span><span class="n">screenshot_collect</span> <span class="n">init</span><span class="p">([</span><span class="bp">self</span><span class="o">.</span><span class="n">loop</span><span class="o">.</span><span class="n">screen_size</span><span class="p">],</span> <span class="p">[[</span><span class="s">&#39;down&#39;</span><span class="p">]</span><span class="o">*</span><span class="mi">3</span><span class="p">,</span> <span class="p">[</span><span class="s">&#39;enter&#39;</span><span class="p">],</span> <span class="p">[</span><span class="s">&#39;q&#39;</span><span class="p">]])</span> <span class="n">MyApp</span><span class="p">()</span> <span class="k">with</span> <span class="nb">open</span> <span class="p">(</span><span class="s">&#39;output.html&#39;</span><span class="p">,</span> <span class="s">&#39;w&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span> <span class="k">for</span> <span class="n">l</span> <span class="ow">in</span> <span class="n">collect</span><span class="p">()[</span><span class="o">-</span><span class="mi">1</span><span class="p">]:</span> <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">l</span><span class="p">)</span> </code></pre></div> <p>In this code, we prepare two functions.</p> <ul> <li><code>init</code> will be pass the sequence of keystroke, quite forward to understand.</li> <li><code>collect</code> retrieve the result, as it was said earlier, it gives a list, we want only the latest element.</li> </ul> <p>The result it place in the file <code>output.html</code> that we can see with firefox.</p> <h2>The result</h2> <pre><span style="color:#ff0000;background:#000000">selected: item 3: Cras a magna sit amet fel... </span> <span style="color:#0000ee;background:#e5e5e5"> </span><span style="color:#0000ee;background:#e5e5e5">item 0 </span><span style="color:#0000ee;background:#e5e5e5">Lorem ipsum dolor sit amet, consectetur adipiscing elit. </span> <span style="color:#0000ee;background:#e5e5e5"> </span><span style="color:#0000ee;background:#e5e5e5">item 1 </span><span style="color:#0000ee;background:#e5e5e5">Cras a magna sit amet felis fringilla lobortis. </span> <span style="color:#0000ee;background:#e5e5e5"> </span><span style="color:#0000ee;background:#e5e5e5">item 2 </span><span style="color:#0000ee;background:#e5e5e5">Sed sollicitudin, nulla id viverra pulvinar. </span> <span style="color:#0000ee;background:#e5e5e5"> </span><span style="color:#cd0000;background:#e5e5e5">item 3 </span><span style="color:#0000ee;background:#e5e5e5">Cras a magna sit amet felis fringilla lobortis. </span> <span style="color:#0000ee;background:#e5e5e5"> </span><span style="color:#0000ee;background:#e5e5e5">item 4 </span><span style="color:#0000ee;background:#e5e5e5">Lorem ipsum dolor sit amet, consectetur adipiscing elit. </span> <span style="color:#0000ee;background:#e5e5e5"> </span><span style="color:#0000ee;background:#e5e5e5">item 5 </span><span style="color:#0000ee;background:#e5e5e5">Sed sollicitudin, nulla id viverra pulvinar. </span> <span style="color:#0000ee;background:#e5e5e5"> </span><span style="color:#0000ee;background:#e5e5e5">item 6 </span><span style="color:#0000ee;background:#e5e5e5">Sed sollicitudin, nulla id viverra pulvinar. </span> <span style="color:#0000ee;background:#e5e5e5"> </span><span style="color:#0000ee;background:#e5e5e5">item 7 </span><span style="color:#0000ee;background:#e5e5e5">Lorem ipsum dolor sit amet, consectetur adipiscing elit. </span> <span style="color:#0000ee;background:#e5e5e5"> </span><span style="color:#0000ee;background:#e5e5e5">item 8 </span><span style="color:#0000ee;background:#e5e5e5">Cras a magna sit amet felis fringilla lobortis. </span> <span style="color:#0000ee;background:#e5e5e5"> </span><span style="color:#0000ee;background:#e5e5e5">item 9 </span><span style="color:#0000ee;background:#e5e5e5">Lorem ipsum dolor sit amet, consectetur adipiscing elit. </span> <span style="color:#0000ee;background:#e5e5e5"> </span><span style="color:#0000ee;background:#e5e5e5">item 10 </span><span style="color:#0000ee;background:#e5e5e5">Lorem ipsum dolor sit amet, consectetur adipiscing elit. </span> <span style="color:#0000ee;background:#e5e5e5"> </span><span style="color:#0000ee;background:#e5e5e5">item 11 </span><span style="color:#0000ee;background:#e5e5e5">Sed sollicitudin, nulla id viverra pulvinar. </span> <span style="color:#0000ee;background:#e5e5e5"> </span><span style="color:#0000ee;background:#e5e5e5">item 12 </span><span style="color:#0000ee;background:#e5e5e5">Sed sollicitudin, nulla id viverra pulvinar. </span> <span style="color:#0000ee;background:#e5e5e5"> </span><span style="color:#0000ee;background:#e5e5e5">item 13 </span><span style="color:#0000ee;background:#e5e5e5">Cras a magna sit amet felis fringilla lobortis. </span> <span style="color:#0000ee;background:#e5e5e5"> </span><span style="color:#0000ee;background:#e5e5e5">item 14 </span><span style="color:#0000ee;background:#e5e5e5">Cras a magna sit amet felis fringilla lobortis. </span> <span style="color:#0000ee;background:#e5e5e5"> </span><span style="color:#0000ee;background:#e5e5e5">item 15 </span><span style="color:#0000ee;background:#e5e5e5">Cras a magna sit amet felis fringilla lobortis. </span> <span style="color:#0000ee;background:#e5e5e5"> </span><span style="color:#0000ee;background:#e5e5e5">item 16 </span><span style="color:#0000ee;background:#e5e5e5">Sed sollicitudin, nulla id viverra pulvinar. </span> <span style="color:#0000ee;background:#e5e5e5"> </span><span style="color:#0000ee;background:#e5e5e5">item 17 </span><span style="color:#0000ee;background:#e5e5e5">Sed sollicitudin, nulla id viverra pulvinar. </span> <span style="color:#0000ee;background:#e5e5e5"> </span><span style="color:#0000ee;background:#e5e5e5">item 18 </span><span style="color:#0000ee;background:#e5e5e5">Lorem ipsum dolor sit amet, consectetur adipiscing elit. </span> <span style="color:#0000ee;background:#e5e5e5"> </span><span style="color:#0000ee;background:#e5e5e5">item 19 </span><span style="color:#0000ee;background:#e5e5e5">Lorem ipsum dolor sit amet, consectetur adipiscing elit. </span> <span style="color:#0000ee;background:#e5e5e5"> </span><span style="color:#0000ee;background:#e5e5e5">item 20 </span><span style="color:#0000ee;background:#e5e5e5">Cras a magna sit amet felis fringilla lobortis. </span> <span style="color:#0000ee;background:#e5e5e5"> </span><span style="color:#0000ee;background:#e5e5e5">item 21 </span><span style="color:#0000ee;background:#e5e5e5">Cras a magna sit amet felis fringilla lobortis. </span> <span style="color:#0000ee;background:#e5e5e5"> </span><span style="color:#0000ee;background:#e5e5e5">item 22 </span><span style="color:#0000ee;background:#e5e5e5">Sed sollicitudin, nulla id viverra pulvinar. </span> <span style="color:#0000ee;background:#e5e5e5"> </span><span style="color:#0000ee;background:#e5e5e5">item 23 </span><span style="color:#0000ee;background:#e5e5e5">Cras a magna sit amet felis fringilla lobortis. </span> </pre> <h2>The full code</h2> <div class="highlight"><pre><code class="python"><span class="kn">import</span> <span class="nn">urwid</span> <span class="kn">import</span> <span class="nn">random</span> <span class="kn">import</span> <span class="nn">urwid.html_fragment</span> <span class="k">class</span> <span class="nc">ItemWidget</span> <span class="p">(</span><span class="n">urwid</span><span class="o">.</span><span class="n">WidgetWrap</span><span class="p">):</span> <span class="k">def</span> <span class="nf">__init__</span> <span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">id</span><span class="p">,</span> <span class="n">description</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">id</span> <span class="o">=</span> <span class="nb">id</span> <span class="bp">self</span><span class="o">.</span><span class="n">title</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">Text</span><span class="p">(</span><span class="s">&#39;item </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="nb">id</span><span class="p">))</span> <span class="bp">self</span><span class="o">.</span><span class="n">description</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">Text</span><span class="p">(</span><span class="n">description</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">item</span> <span class="o">=</span> <span class="p">[</span> <span class="p">(</span><span class="s">&#39;fixed&#39;</span><span class="p">,</span> <span class="mi">15</span><span class="p">,</span> <span class="n">urwid</span><span class="o">.</span><span class="n">Padding</span><span class="p">(</span><span class="n">urwid</span><span class="o">.</span><span class="n">AttrWrap</span><span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">title</span><span class="p">,</span> <span class="s">&#39;body&#39;</span><span class="p">,</span> <span class="s">&#39;focus&#39;</span><span class="p">),</span> <span class="n">left</span><span class="o">=</span><span class="mi">2</span><span class="p">)),</span> <span class="n">urwid</span><span class="o">.</span><span class="n">AttrWrap</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">description</span><span class="p">,</span> <span class="s">&#39;body&#39;</span><span class="p">,</span> <span class="s">&#39;focus&#39;</span><span class="p">),</span> <span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">content</span> <span class="o">=</span> <span class="s">&#39;item </span><span class="si">%s</span><span class="s">: </span><span class="si">%s</span><span class="s">...&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="nb">id</span><span class="p">),</span> <span class="n">description</span><span class="p">[:</span><span class="mi">25</span><span class="p">])</span> <span class="n">w</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">Columns</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">item</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">__super</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="n">w</span><span class="p">)</span> <span class="k">def</span> <span class="nf">selectable</span> <span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">return</span> <span class="bp">True</span> <span class="k">def</span> <span class="nf">keypress</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span> <span class="k">return</span> <span class="n">key</span> <span class="k">class</span> <span class="nc">CustomEdit</span><span class="p">(</span><span class="n">urwid</span><span class="o">.</span><span class="n">Edit</span><span class="p">):</span> <span class="n">__metaclass__</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">signals</span><span class="o">.</span><span class="n">MetaSignals</span> <span class="n">signals</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;done&#39;</span><span class="p">]</span> <span class="k">def</span> <span class="nf">keypress</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span> <span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="s">&#39;enter&#39;</span><span class="p">:</span> <span class="n">urwid</span><span class="o">.</span><span class="n">emit_signal</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s">&#39;done&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_edit_text</span><span class="p">())</span> <span class="k">return</span> <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s">&#39;esc&#39;</span><span class="p">:</span> <span class="n">urwid</span><span class="o">.</span><span class="n">emit_signal</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s">&#39;done&#39;</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span> <span class="k">return</span> <span class="n">urwid</span><span class="o">.</span><span class="n">Edit</span><span class="o">.</span><span class="n">keypress</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span> <span class="k">class</span> <span class="nc">MyApp</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">palette</span> <span class="o">=</span> <span class="p">[</span> <span class="p">(</span><span class="s">&#39;body&#39;</span><span class="p">,</span><span class="s">&#39;dark blue&#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;standout&#39;</span><span class="p">),</span> <span class="p">(</span><span class="s">&#39;focus&#39;</span><span class="p">,</span><span class="s">&#39;dark red&#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;standout&#39;</span><span class="p">),</span> <span class="p">(</span><span class="s">&#39;head&#39;</span><span class="p">,</span><span class="s">&#39;light red&#39;</span><span class="p">,</span> <span class="s">&#39;black&#39;</span><span class="p">),</span> <span class="p">]</span> <span class="n">lorem</span> <span class="o">=</span> <span class="p">[</span> <span class="s">&#39;Lorem ipsum dolor sit amet, consectetur adipiscing elit.&#39;</span><span class="p">,</span> <span class="s">&#39;Sed sollicitudin, nulla id viverra pulvinar.&#39;</span><span class="p">,</span> <span class="s">&#39;Cras a magna sit amet felis fringilla lobortis.&#39;</span><span class="p">,</span> <span class="p">]</span> <span class="n">items</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">100</span><span class="p">):</span> <span class="n">item</span> <span class="o">=</span> <span class="n">ItemWidget</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">random</span><span class="o">.</span><span class="n">choice</span><span class="p">(</span><span class="n">lorem</span><span class="p">))</span> <span class="n">items</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">item</span><span class="p">)</span> <span class="n">header</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">AttrMap</span><span class="p">(</span><span class="n">urwid</span><span class="o">.</span><span class="n">Text</span><span class="p">(</span><span class="s">&#39;selected:&#39;</span><span class="p">),</span> <span class="s">&#39;head&#39;</span><span class="p">)</span> <span class="n">walker</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">SimpleListWalker</span><span class="p">(</span><span class="n">items</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">listbox</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">ListBox</span><span class="p">(</span><span class="n">walker</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">view</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">Frame</span><span class="p">(</span><span class="n">urwid</span><span class="o">.</span><span class="n">AttrWrap</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">listbox</span><span class="p">,</span> <span class="s">&#39;body&#39;</span><span class="p">),</span> <span class="n">header</span><span class="o">=</span><span class="n">header</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">loop</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">MainLoop</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">view</span><span class="p">,</span> <span class="n">palette</span><span class="p">,</span> <span class="n">unhandled_input</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">keystroke</span><span class="p">)</span> <span class="n">urwid</span><span class="o">.</span><span class="n">connect_signal</span><span class="p">(</span><span class="n">walker</span><span class="p">,</span> <span class="s">&#39;modified&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">update</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">loop</span><span class="o">.</span><span class="n">run</span><span class="p">()</span> <span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">focus</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">listbox</span><span class="o">.</span><span class="n">get_focus</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">content</span> <span class="bp">self</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="n">set_header</span><span class="p">(</span><span class="n">urwid</span><span class="o">.</span><span class="n">AttrWrap</span><span class="p">(</span><span class="n">urwid</span><span class="o">.</span><span class="n">Text</span><span class="p">(</span><span class="s">&#39;selected: </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="n">focus</span><span class="p">)),</span> <span class="s">&#39;head&#39;</span><span class="p">))</span> <span class="k">def</span> <span class="nf">keystroke</span> <span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">input</span><span class="p">):</span> <span class="k">if</span> <span class="nb">input</span> <span class="ow">in</span> <span class="p">(</span><span class="s">&#39;q&#39;</span><span class="p">,</span> <span class="s">&#39;Q&#39;</span><span class="p">):</span> <span class="k">raise</span> <span class="n">urwid</span><span class="o">.</span><span class="n">ExitMainLoop</span><span class="p">()</span> <span class="k">if</span> <span class="nb">input</span> <span class="ow">is</span> <span class="s">&#39;enter&#39;</span><span class="p">:</span> <span class="n">focus</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">listbox</span><span class="o">.</span><span class="n">get_focus</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">content</span> <span class="bp">self</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="n">set_header</span><span class="p">(</span><span class="n">urwid</span><span class="o">.</span><span class="n">AttrWrap</span><span class="p">(</span><span class="n">urwid</span><span class="o">.</span><span class="n">Text</span><span class="p">(</span><span class="s">&#39;selected: </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="n">focus</span><span class="p">)),</span> <span class="s">&#39;head&#39;</span><span class="p">))</span> <span class="k">if</span> <span class="nb">input</span> <span class="o">==</span> <span class="s">&#39;e&#39;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">edit</span><span class="p">()</span> <span class="k">if</span> <span class="nb">input</span> <span class="ow">is</span> <span class="s">&#39;s&#39;</span><span class="p">:</span> <span class="n">init</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">html_fragment</span><span class="o">.</span><span class="n">screenshot_init</span> <span class="n">collect</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">html_fragment</span><span class="o">.</span><span class="n">screenshot_collect</span> <span class="n">init</span><span class="p">([</span><span class="bp">self</span><span class="o">.</span><span class="n">loop</span><span class="o">.</span><span class="n">screen_size</span><span class="p">],</span> <span class="p">[[</span><span class="s">&#39;down&#39;</span><span class="p">]</span><span class="o">*</span><span class="mi">3</span><span class="p">,</span> <span class="p">[</span><span class="s">&#39;enter&#39;</span><span class="p">],</span> <span class="p">[</span><span class="s">&#39;q&#39;</span><span class="p">]])</span> <span class="n">MyApp</span><span class="p">()</span> <span class="k">with</span> <span class="nb">open</span> <span class="p">(</span><span class="s">&#39;output.html&#39;</span><span class="p">,</span> <span class="s">&#39;w&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span> <span class="k">for</span> <span class="n">l</span> <span class="ow">in</span> <span class="n">collect</span><span class="p">()[</span><span class="o">-</span><span class="mi">1</span><span class="p">]:</span> <span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">l</span><span class="p">)</span> <span class="k">def</span> <span class="nf">edit</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">foot</span> <span class="o">=</span> <span class="n">CustomEdit</span><span class="p">(</span><span class="s">&#39; &gt;&gt; &#39;</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="n">set_footer</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">foot</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="n">set_focus</span><span class="p">(</span><span class="s">&#39;footer&#39;</span><span class="p">)</span> <span class="n">urwid</span><span class="o">.</span><span class="n">connect_signal</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">foot</span><span class="p">,</span> <span class="s">&#39;done&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">edit_done</span><span class="p">)</span> <span class="k">def</span> <span class="nf">edit_done</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">content</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="n">set_focus</span><span class="p">(</span><span class="s">&#39;body&#39;</span><span class="p">)</span> <span class="n">urwid</span><span class="o">.</span><span class="n">disconnect_signal</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">foot</span><span class="p">,</span> <span class="s">&#39;done&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">edit_done</span><span class="p">)</span> <span class="k">if</span> <span class="n">content</span><span class="p">:</span> <span class="n">focus</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">listbox</span><span class="o">.</span><span class="n">get_focus</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span> <span class="n">focus</span><span class="o">.</span><span class="n">description</span><span class="o">.</span><span class="n">set_text</span><span class="p">(</span><span class="n">content</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="n">set_footer</span><span class="p">(</span><span class="bp">None</span><span class="p">)</span> <span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span> <span class="n">MyApp</span><span class="p">()</span> </code></pre></div> Several colored string with Urwid 2011-11-23T00:00:00-08:00 http://www.nicosphere.net/several-colored-string-with-urwid-2546 <p>OK, this one is an easy and quick stuff, that I&rsquo;m almost ashame to share. But the thing is, I search for it, and I wasn&rsquo;t even sure where to look at it. The reason I put it here is because I trying to put together some trick about urwid, stuff I spend some time to looking for, even if it isn&rsquo;t so much time. If someone need it, he should find it easily here.</p> <p>The idea is to highlight some worlds in a string. The answer was right in the front of me from the start! As it was shown in the <code>tour.py</code>, the very first script in the official tutorial.</p> <div class="highlight"><pre><code class="python"><span class="n">palette</span> <span class="o">=</span> <span class="p">[</span> <span class="p">(</span><span class="s">&#39;main&#39;</span><span class="p">,</span> <span class="s">&#39;dark blue&#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">),</span> <span class="p">(</span><span class="s">&#39;hl&#39;</span><span class="p">,</span> <span class="s">&#39;dark red&#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">)</span> <span class="p">]</span> <span class="n">txt</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">AttrWrap</span><span class="p">(</span><span class="n">urwid</span><span class="o">.</span><span class="n">Text</span><span class="p">([</span> <span class="s">&quot;Some random text, with an &quot;</span><span class="p">,</span> <span class="p">(</span><span class="s">&#39;hl&#39;</span><span class="p">,</span> <span class="s">&quot;IMPORTANT &quot;</span><span class="p">),</span> <span class="s">&quot;word. Other boring stuff.&quot;</span> <span class="p">]),</span> <span class="s">&#39;main&#39;</span><span class="p">)</span> </code></pre></div> <p>This short example, witch is only a part of a code of course, shows a string with the <code>main</code> color, with the <em>IMPORTANT</em> word colored with the <code>hl</code> attribute. It only a list, with a tuple for different colors, color attribute first.</p> <p>As I said, it isn&rsquo;t a very exalting post, just a quick trick.</p> Footer Edit with Urwid, IRC-Client-like input 2011-11-23T00:00:00-08:00 http://www.nicosphere.net/footer-edit-with-urwid-irc-client-like-input-2547 <p>We start with the code from <a href="http://www.nicosphere.net/selectable-list-with-urwid-for-python-2542/">Selectable List with Urwid for Python</a>, check before the <a href="http://www.nicosphere.net/signals-with-urwid-for-python-2545/">Signals with Urwid for Python</a> for a small involvement of the code, for handling signals.</p> <p>So far, we have a selectable list containing two items each (title and description). We can go through it with up and down key arrows, and select one of them with the <em>enter</em> key. We use <em>urwid.Frame</em> witch give us an useful layout divided in three parts, <em>header</em>, <em>body</em> and <em>footer</em>. In the last post, we used the header to display the selected item, the body to display the list, and the footer wasn&rsquo;t used at all.</p> <p>Now, what we want is to use the footer for an <em>Edit</em> widget, exactly like ncurses IRC-client such as IRSSI or weechat. When we will press the <code>e</code> key (for edit) an input widget will appear, taking place at the footer, once validate, with <em>enter</em>, or abort with <em>escape</em> the output will replace the description of the current selected item.</p> <p>In the following screenshot, the list was generated with random description. the 4th item was replaced with this editing process, and we&rsquo;re about to replace the 5th item as well. It may seem not a big deal, but it still a good exercise to gain practice with urwid.</p> <p><a href="/img/urwid-edit.png"><img src="/img/urwid-edit-300x120.png" alt="Urwid Edit" title="urwid-edit" width="300" height="120" class="size-medium wp-image-2548" /></a></p> <p>Let&rsquo;s talk about the code. <strong>The full code is at the end of the post</strong>.</p> <ul> <li><em>ItemWidget</em>: is almost the same as before, it used to create an item for the list, it was only change in order to set the description part, here the changing part.</li> </ul> <div class="highlight"><pre><code class="python"><span class="bp">self</span><span class="o">.</span><span class="n">description</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">Text</span><span class="p">(</span><span class="n">description</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">item</span> <span class="o">=</span> <span class="p">[</span> <span class="p">(</span><span class="s">&#39;fixed&#39;</span><span class="p">,</span> <span class="mi">15</span><span class="p">,</span> <span class="n">urwid</span><span class="o">.</span><span class="n">Padding</span><span class="p">(</span><span class="n">urwid</span><span class="o">.</span><span class="n">AttrWrap</span><span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">title</span><span class="p">,</span> <span class="s">&#39;body&#39;</span><span class="p">,</span> <span class="s">&#39;focus&#39;</span><span class="p">),</span> <span class="n">left</span><span class="o">=</span><span class="mi">2</span><span class="p">)),</span> <span class="n">urwid</span><span class="o">.</span><span class="n">AttrWrap</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">description</span><span class="p">,</span> <span class="s">&#39;body&#39;</span><span class="p">,</span> <span class="s">&#39;focus&#39;</span><span class="p">),</span> <span class="p">]</span> </code></pre></div> <ul> <li><em>CustomEdit</em>: inheritance of the <em>Edit</em> widget, it will emit a signal <em>done</em> once finish editing, and will give an argument to the callback, the content of the editing, or <em>None</em> if it was abort with the <em>escape</em> key. If neither keys is pressed, the key is return and managed by the normal <em>Edit</em> widget.</li> </ul> <div class="highlight"><pre><code class="python"><span class="k">class</span> <span class="nc">CustomEdit</span><span class="p">(</span><span class="n">urwid</span><span class="o">.</span><span class="n">Edit</span><span class="p">):</span> <span class="n">__metaclass__</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">signals</span><span class="o">.</span><span class="n">MetaSignals</span> <span class="n">signals</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;done&#39;</span><span class="p">]</span> <span class="k">def</span> <span class="nf">keypress</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span> <span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="s">&#39;enter&#39;</span><span class="p">:</span> <span class="n">urwid</span><span class="o">.</span><span class="n">emit_signal</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s">&#39;done&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_edit_text</span><span class="p">())</span> <span class="k">return</span> <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s">&#39;esc&#39;</span><span class="p">:</span> <span class="n">urwid</span><span class="o">.</span><span class="n">emit_signal</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s">&#39;done&#39;</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span> <span class="k">return</span> <span class="n">urwid</span><span class="o">.</span><span class="n">Edit</span><span class="o">.</span><span class="n">keypress</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span> </code></pre></div> <ul> <li><em>MyApp</em>: I moved the code in a class, most of the code is the same except for the last two method.</li> </ul> <p>The <em>edit</em> method is directly call when the <code>e</code> key is pressed. It only create a <em>CustomEdit</em> object, that would be set to the footer, but we need to specified to the frame (<em>view</em>) that the footer have the focus now, otherwise it would not be editable. At last, we connect the signal, to treat the content once the edit is done.</p> <div class="highlight"><pre><code class="python"> <span class="k">def</span> <span class="nf">edit</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">foot</span> <span class="o">=</span> <span class="n">CustomEdit</span><span class="p">(</span><span class="s">&#39; &gt;&gt; &#39;</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="n">set_footer</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">foot</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="n">set_focus</span><span class="p">(</span><span class="s">&#39;footer&#39;</span><span class="p">)</span> <span class="n">urwid</span><span class="o">.</span><span class="n">connect_signal</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">foot</span><span class="p">,</span> <span class="s">&#39;done&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">edit_done</span><span class="p">)</span> </code></pre></div> <p>Once the edit is done, the <em>edit_done</em> function is called as a callback, with the content. Then we modify the content of the description in the list. And set back to <em>None</em> the footer, as we don&rsquo;t want anything display anymore.</p> <div class="highlight"><pre><code class="python"> <span class="k">def</span> <span class="nf">edit_done</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">content</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="n">set_focus</span><span class="p">(</span><span class="s">&#39;body&#39;</span><span class="p">)</span> <span class="n">urwid</span><span class="o">.</span><span class="n">disconnect_signal</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">foot</span><span class="p">,</span> <span class="s">&#39;done&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">edit_done</span><span class="p">)</span> <span class="k">if</span> <span class="n">content</span><span class="p">:</span> <span class="n">focus</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">listbox</span><span class="o">.</span><span class="n">get_focus</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span> <span class="n">focus</span><span class="o">.</span><span class="n">description</span><span class="o">.</span><span class="n">set_text</span><span class="p">(</span><span class="n">content</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="n">set_footer</span><span class="p">(</span><span class="bp">None</span><span class="p">)</span> </code></pre></div> <p>That&rsquo;s it, in this example this code is used to manage a list, but it could be used for a large set of applications.</p> <p>Here the full code:</p> <div class="highlight"><pre><code class="python"><span class="kn">import</span> <span class="nn">urwid</span> <span class="kn">import</span> <span class="nn">random</span> <span class="kn">import</span> <span class="nn">urwid.html_fragment</span> <span class="k">class</span> <span class="nc">ItemWidget</span> <span class="p">(</span><span class="n">urwid</span><span class="o">.</span><span class="n">WidgetWrap</span><span class="p">):</span> <span class="k">def</span> <span class="nf">__init__</span> <span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">id</span><span class="p">,</span> <span class="n">description</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">id</span> <span class="o">=</span> <span class="nb">id</span> <span class="bp">self</span><span class="o">.</span><span class="n">title</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">Text</span><span class="p">(</span><span class="s">&#39;item </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="nb">id</span><span class="p">))</span> <span class="bp">self</span><span class="o">.</span><span class="n">description</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">Text</span><span class="p">(</span><span class="n">description</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">item</span> <span class="o">=</span> <span class="p">[</span> <span class="p">(</span><span class="s">&#39;fixed&#39;</span><span class="p">,</span> <span class="mi">15</span><span class="p">,</span> <span class="n">urwid</span><span class="o">.</span><span class="n">Padding</span><span class="p">(</span><span class="n">urwid</span><span class="o">.</span><span class="n">AttrWrap</span><span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">title</span><span class="p">,</span> <span class="s">&#39;body&#39;</span><span class="p">,</span> <span class="s">&#39;focus&#39;</span><span class="p">),</span> <span class="n">left</span><span class="o">=</span><span class="mi">2</span><span class="p">)),</span> <span class="n">urwid</span><span class="o">.</span><span class="n">AttrWrap</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">description</span><span class="p">,</span> <span class="s">&#39;body&#39;</span><span class="p">,</span> <span class="s">&#39;focus&#39;</span><span class="p">),</span> <span class="p">]</span> <span class="bp">self</span><span class="o">.</span><span class="n">content</span> <span class="o">=</span> <span class="s">&#39;item </span><span class="si">%s</span><span class="s">: </span><span class="si">%s</span><span class="s">...&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="nb">id</span><span class="p">),</span> <span class="n">description</span><span class="p">[:</span><span class="mi">25</span><span class="p">])</span> <span class="n">w</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">Columns</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">item</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">__super</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="n">w</span><span class="p">)</span> <span class="k">def</span> <span class="nf">selectable</span> <span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">return</span> <span class="bp">True</span> <span class="k">def</span> <span class="nf">keypress</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span> <span class="k">return</span> <span class="n">key</span> <span class="k">class</span> <span class="nc">CustomEdit</span><span class="p">(</span><span class="n">urwid</span><span class="o">.</span><span class="n">Edit</span><span class="p">):</span> <span class="n">__metaclass__</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">signals</span><span class="o">.</span><span class="n">MetaSignals</span> <span class="n">signals</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;done&#39;</span><span class="p">]</span> <span class="k">def</span> <span class="nf">keypress</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span> <span class="k">if</span> <span class="n">key</span> <span class="o">==</span> <span class="s">&#39;enter&#39;</span><span class="p">:</span> <span class="n">urwid</span><span class="o">.</span><span class="n">emit_signal</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s">&#39;done&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_edit_text</span><span class="p">())</span> <span class="k">return</span> <span class="k">elif</span> <span class="n">key</span> <span class="o">==</span> <span class="s">&#39;esc&#39;</span><span class="p">:</span> <span class="n">urwid</span><span class="o">.</span><span class="n">emit_signal</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s">&#39;done&#39;</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span> <span class="k">return</span> <span class="n">urwid</span><span class="o">.</span><span class="n">Edit</span><span class="o">.</span><span class="n">keypress</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span> <span class="k">class</span> <span class="nc">MyApp</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">palette</span> <span class="o">=</span> <span class="p">[</span> <span class="p">(</span><span class="s">&#39;body&#39;</span><span class="p">,</span><span class="s">&#39;dark blue&#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;standout&#39;</span><span class="p">),</span> <span class="p">(</span><span class="s">&#39;focus&#39;</span><span class="p">,</span><span class="s">&#39;dark red&#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;standout&#39;</span><span class="p">),</span> <span class="p">(</span><span class="s">&#39;head&#39;</span><span class="p">,</span><span class="s">&#39;light red&#39;</span><span class="p">,</span> <span class="s">&#39;black&#39;</span><span class="p">),</span> <span class="p">]</span> <span class="n">lorem</span> <span class="o">=</span> <span class="p">[</span> <span class="s">&#39;Lorem ipsum dolor sit amet, consectetur adipiscing elit.&#39;</span><span class="p">,</span> <span class="s">&#39;Sed sollicitudin, nulla id viverra pulvinar.&#39;</span><span class="p">,</span> <span class="s">&#39;Cras a magna sit amet felis fringilla lobortis.&#39;</span><span class="p">,</span> <span class="p">]</span> <span class="n">items</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">100</span><span class="p">):</span> <span class="n">item</span> <span class="o">=</span> <span class="n">ItemWidget</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">random</span><span class="o">.</span><span class="n">choice</span><span class="p">(</span><span class="n">lorem</span><span class="p">))</span> <span class="n">items</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">item</span><span class="p">)</span> <span class="n">header</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">AttrMap</span><span class="p">(</span><span class="n">urwid</span><span class="o">.</span><span class="n">Text</span><span class="p">(</span><span class="s">&#39;selected:&#39;</span><span class="p">),</span> <span class="s">&#39;head&#39;</span><span class="p">)</span> <span class="n">walker</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">SimpleListWalker</span><span class="p">(</span><span class="n">items</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">listbox</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">ListBox</span><span class="p">(</span><span class="n">walker</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">view</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">Frame</span><span class="p">(</span><span class="n">urwid</span><span class="o">.</span><span class="n">AttrWrap</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">listbox</span><span class="p">,</span> <span class="s">&#39;body&#39;</span><span class="p">),</span> <span class="n">header</span><span class="o">=</span><span class="n">header</span><span class="p">)</span> <span class="n">loop</span> <span class="o">=</span> <span class="n">urwid</span><span class="o">.</span><span class="n">MainLoop</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">view</span><span class="p">,</span> <span class="n">palette</span><span class="p">,</span> <span class="n">unhandled_input</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">keystroke</span><span class="p">)</span> <span class="n">urwid</span><span class="o">.</span><span class="n">connect_signal</span><span class="p">(</span><span class="n">walker</span><span class="p">,</span> <span class="s">&#39;modified&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">update</span><span class="p">)</span> <span class="n">loop</span><span class="o">.</span><span class="n">run</span><span class="p">()</span> <span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">focus</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">listbox</span><span class="o">.</span><span class="n">get_focus</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">content</span> <span class="bp">self</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="n">set_header</span><span class="p">(</span><span class="n">urwid</span><span class="o">.</span><span class="n">AttrWrap</span><span class="p">(</span><span class="n">urwid</span><span class="o">.</span><span class="n">Text</span><span class="p">(</span><span class="s">&#39;selected: </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="n">focus</span><span class="p">)),</span> <span class="s">&#39;head&#39;</span><span class="p">))</span> <span class="k">def</span> <span class="nf">keystroke</span> <span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">input</span><span class="p">):</span> <span class="k">if</span> <span class="nb">input</span> <span class="ow">in</span> <span class="p">(</span><span class="s">&#39;q&#39;</span><span class="p">,</span> <span class="s">&#39;Q&#39;</span><span class="p">):</span> <span class="k">raise</span> <span class="n">urwid</span><span class="o">.</span><span class="n">ExitMainLoop</span><span class="p">()</span> <span class="k">if</span> <span class="nb">input</span> <span class="ow">is</span> <span class="s">&#39;enter&#39;</span><span class="p">:</span> <span class="n">focus</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">listbox</span><span class="o">.</span><span class="n">get_focus</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">content</span> <span class="bp">self</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="n">set_header</span><span class="p">(</span><span class="n">urwid</span><span class="o">.</span><span class="n">AttrWrap</span><span class="p">(</span><span class="n">urwid</span><span class="o">.</span><span class="n">Text</span><span class="p">(</span><span class="s">&#39;selected: </span><span class="si">%s</span><span class="s">&#39;</span> <span class="o">%</span> <span class="nb">str</span><span class="p">(</span><span class="n">focus</span><span class="p">)),</span> <span class="s">&#39;head&#39;</span><span class="p">))</span> <span class="k">if</span> <span class="nb">input</span> <span class="o">==</span> <span class="s">&#39;e&#39;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">edit</span><span class="p">()</span> <span class="k">def</span> <span class="nf">edit</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">foot</span> <span class="o">=</span> <span class="n">CustomEdit</span><span class="p">(</span><span class="s">&#39; &gt;&gt; &#39;</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="n">set_footer</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">foot</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="n">set_focus</span><span class="p">(</span><span class="s">&#39;footer&#39;</span><span class="p">)</span> <span class="n">urwid</span><span class="o">.</span><span class="n">connect_signal</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">foot</span><span class="p">,</span> <span class="s">&#39;done&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">edit_done</span><span class="p">)</span> <span class="k">def</span> <span class="nf">edit_done</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">content</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="n">set_focus</span><span class="p">(</span><span class="s">&#39;body&#39;</span><span class="p">)</span> <span class="n">urwid</span><span class="o">.</span><span class="n">disconnect_signal</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">foot</span><span class="p">,</span> <span class="s">&#39;done&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">edit_done</span><span class="p">)</span> <span class="k">if</span> <span class="n">content</span><span class="p">:</span> <span class="n">focus</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">listbox</span><span class="o">.</span><span class="n">get_focus</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span> <span class="n">focus</span><span class="o">.</span><span class="n">description</span><span class="o">.</span><span class="n">set_text</span><span class="p">(</span><span class="n">content</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">view</span><span class="o">.</span><span class="n">set_footer</span><span class="p">(</span><span class="bp">None</span><span class="p">)</span> <span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">&#39;__main__&#39;</span><span class="p">:</span> <span class="n">MyApp</span><span class="p">()</span> </code></pre></div> <p>Hope it can help someone.</p>