<?xml version="1.0" encoding="UTF-8"?>
<feed
  xmlns="http://www.w3.org/2005/Atom"
  xmlns:thr="http://purl.org/syndication/thread/1.0"
  xml:lang="en"
   >
  <title type="text">All Unkept</title>
  <subtitle type="text"></subtitle>

  <updated>2013-05-24T11:16:23Z</updated>
  <generator uri="http://blogofile.com/">Blogofile</generator>

  <link rel="alternate" type="text/html" href="http://lukeplant.me.uk/blog" />
  <id>http://lukeplant.me.uk/blog/feed/atom/</id>
  <link rel="self" type="application/atom+xml" href="http://lukeplant.me.uk/blog/feed/atom/" />
  <entry>
    <author>
      <name></name>
      <uri>http://lukeplant.me.uk/blog</uri>
    </author>
    <title type="html"><![CDATA[KTimeTracker replacement - TimeCult]]></title>
    <link rel="alternate" type="text/html" href="http://lukeplant.me.uk/blog/posts/ktimetracker-replacement-timecult/" />
    <id>http://lukeplant.me.uk/blog/posts/ktimetracker-replacement-timecult/</id>
    <updated>2012-02-24T17:57:32Z</updated>
    <published>2012-02-24T17:57:32Z</published>
    <category scheme="http://lukeplant.me.uk/blog" term="Python" />
    <category scheme="http://lukeplant.me.uk/blog" term="KDE" />
    <category scheme="http://lukeplant.me.uk/blog" term="Linux" />
    <summary type="html"><![CDATA[KTimeTracker replacement - TimeCult]]></summary>
    <content type="html" xml:base="http://lukeplant.me.uk/blog/posts/ktimetracker-replacement-timecult/"><![CDATA[<div class="document">
<p>For a long time I haven't been able to find a decent replacement or alternative to KTimeTracker. But I've now succeeded: <a class="reference external" href="http://timecult.wordpress.com/">TimeCult</a>.</p>
<p>It is <a class="reference external" href="https://github.com/dyadix/TimeCult/issues/1">currently lacking an installer for Linux</a>, but it can be <a class="reference external" href="http://xmemory.tompium.com/2011/10/get-timecult-running-on-linux.html">made to work with Linux easily</a>.</p>
<p>I also found that it uses a very easy-to-deciper XML format, and, with the help of <a class="reference external" href="http://pypi.python.org/pypi/vobject">vobject</a>, the KTimeTracker ical files are only slightly harder to figure out, so I created a Python <a class="reference external" href="https://gist.github.com/1901236">script</a> that will do the conversion.</p>
<p>Use the script like this:</p>
<pre class="literal-block">
./ics_to_timecult.py ~/.kde/share/apps/ktimetracker/ktimetracker.ics &gt; out.tmt
</pre>
<p>It's here for reference - dependencies are vobject and elementtree:</p>
<pre class="code python literal-block">
<span class="c">#!/usr/bin/env python</span>
<span class="c"># Quick and dirty script to convert ktimetracker.ics files</span>
<span class="c"># into TimeCult files.</span>

<span class="kn">import</span> <span class="nn">os.path</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="kn">import</span> <span class="nn">uuid</span>

<span class="kn">import</span> <span class="nn">elementtree.ElementTree</span> <span class="kn">as</span> <span class="nn">ET</span>
<span class="kn">import</span> <span class="nn">vobject</span>


<span class="c"># Structures to store the tree of data. Use native Python data types, and</span>
<span class="c"># convert to what TimeCult expects when we 'render'</span>

<span class="k">class</span> <span class="nc">Struct</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="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">__dict__</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">kwargs</span><span class="p">)</span>


<span class="k">class</span> <span class="nc">TimeCult</span><span class="p">(</span><span class="n">Struct</span><span class="p">):</span>
    <span class="c"># &lt;timecult&gt;</span>
    <span class="c"># Eventual attributes:</span>
    <span class="c">#  name</span>
    <span class="c">#  projectTree</span>
    <span class="c">#  timeLog</span>

    <span class="k">def</span> <span class="nf">toXML</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">root</span> <span class="o">=</span> <span class="n">ET</span><span class="o">.</span><span class="n">XML</span><span class="p">(</span><span class="s">'&lt;timecult appVersion=&quot;0.12&quot; fileVersion=&quot;10&quot; /&gt;'</span><span class="p">)</span>
        <span class="n">root</span><span class="o">.</span><span class="n">attrib</span><span class="p">[</span><span class="s">'uuid'</span><span class="p">]</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">uuid</span><span class="o">.</span><span class="n">uuid1</span><span class="p">())</span>
        <span class="n">root</span><span class="o">.</span><span class="n">attrib</span><span class="p">[</span><span class="s">'name'</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span>
        <span class="n">pt</span> <span class="o">=</span> <span class="n">ET</span><span class="o">.</span><span class="n">Element</span><span class="p">(</span><span class="s">'projectTree'</span><span class="p">)</span>
        <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">projectTree</span><span class="p">:</span>
            <span class="n">pt</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">n</span><span class="o">.</span><span class="n">toXML</span><span class="p">())</span>
        <span class="n">root</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">pt</span><span class="p">)</span>
        <span class="n">tl</span> <span class="o">=</span> <span class="n">ET</span><span class="o">.</span><span class="n">Element</span><span class="p">(</span><span class="s">'timeLog'</span><span class="p">)</span>
        <span class="k">for</span> <span class="n">tr</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">timeLog</span><span class="p">:</span>
            <span class="n">tl</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">tr</span><span class="o">.</span><span class="n">toXML</span><span class="p">())</span>
        <span class="n">root</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">tl</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">root</span>

<span class="k">class</span> <span class="nc">Node</span><span class="p">(</span><span class="n">Struct</span><span class="p">):</span>
    <span class="c"># &lt;project&gt; and &lt;task&gt;</span>
    <span class="c"># Eventually will have these attributes:</span>
    <span class="c">#  vtodo</span>
    <span class="c">#  summary</span>
    <span class="c">#  uid</span>
    <span class="c">#  created</span>
    <span class="c">#  parent</span>
    <span class="c">#  children</span>
    <span class="c">#  type = &quot;project|task&quot;</span>
    <span class="c">#  finished</span>
    <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="s">&quot;&lt;Node: uid=</span><span class="si">%s</span><span class="s"> summary=</span><span class="si">%r</span><span class="s">, parent=</span><span class="si">%r</span><span class="s">&gt;&quot;</span> <span class="o">%</span> <span class="p">(</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">uid</span><span class="p">,</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">summary</span><span class="p">,</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">summary</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">parent</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span> <span class="k">else</span> <span class="bp">None</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">toXML</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">e</span> <span class="o">=</span> <span class="n">ET</span><span class="o">.</span><span class="n">Element</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">type</span><span class="p">)</span>
        <span class="n">e</span><span class="o">.</span><span class="n">attrib</span><span class="p">[</span><span class="s">'id'</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">id</span>
        <span class="n">e</span><span class="o">.</span><span class="n">attrib</span><span class="p">[</span><span class="s">'name'</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">summary</span>
        <span class="n">e</span><span class="o">.</span><span class="n">attrib</span><span class="p">[</span><span class="s">'created'</span><span class="p">]</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">mktime</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">created</span><span class="o">.</span><span class="n">timetuple</span><span class="p">())</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">))</span>
        <span class="k">if</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="s">&quot;task&quot;</span><span class="p">):</span>
            <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">children</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span>
            <span class="n">e</span><span class="o">.</span><span class="n">attrib</span><span class="p">[</span><span class="s">'status'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'finished'</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">finished</span> <span class="k">else</span> <span class="s">'inProgress'</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">children</span><span class="p">:</span>
                <span class="n">e</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">c</span><span class="o">.</span><span class="n">toXML</span><span class="p">())</span>
        <span class="k">return</span> <span class="n">e</span>

<span class="k">class</span> <span class="nc">TimeRec</span><span class="p">(</span><span class="n">Struct</span><span class="p">):</span>
    <span class="c"># &lt;timerec&gt;</span>
    <span class="c"># Eventual attributes:</span>
    <span class="c">#  startTime  # datetime</span>
    <span class="c">#  duration   # seconds</span>
    <span class="c">#  task       # Node</span>
    <span class="k">def</span> <span class="nf">toXML</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">e</span> <span class="o">=</span> <span class="n">ET</span><span class="o">.</span><span class="n">Element</span><span class="p">(</span><span class="s">&quot;timeRec&quot;</span><span class="p">)</span>
        <span class="n">e</span><span class="o">.</span><span class="n">attrib</span><span class="p">[</span><span class="s">'taskId'</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">taskId</span>
        <span class="n">e</span><span class="o">.</span><span class="n">attrib</span><span class="p">[</span><span class="s">'startTime'</span><span class="p">]</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">mktime</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">startTime</span><span class="o">.</span><span class="n">timetuple</span><span class="p">())</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">))</span>
        <span class="n">e</span><span class="o">.</span><span class="n">attrib</span><span class="p">[</span><span class="s">'duration'</span><span class="p">]</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">duration</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">))</span>
        <span class="n">e</span><span class="o">.</span><span class="n">attrib</span><span class="p">[</span><span class="s">'notes'</span><span class="p">]</span> <span class="o">=</span> <span class="s">&quot;&quot;</span>
        <span class="k">return</span> <span class="n">e</span>

<span class="k">def</span> <span class="nf">convert</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span>
    <span class="n">f</span> <span class="o">=</span> <span class="n">vobject</span><span class="o">.</span><span class="n">readOne</span><span class="p">(</span><span class="nb">file</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>

    <span class="c"># First parse Todos</span>
    <span class="n">nodes</span> <span class="o">=</span> <span class="p">{}</span>
    <span class="k">for</span> <span class="n">vtodo</span> <span class="ow">in</span> <span class="n">f</span><span class="o">.</span><span class="n">vtodo_list</span><span class="p">:</span>
        <span class="n">n</span> <span class="o">=</span> <span class="n">Node</span><span class="p">(</span><span class="n">vtodo</span> <span class="o">=</span> <span class="n">vtodo</span><span class="p">,</span>
                 <span class="n">uid</span><span class="o">=</span><span class="n">vtodo</span><span class="o">.</span><span class="n">uid</span><span class="o">.</span><span class="n">value</span><span class="p">,</span>
                 <span class="n">summary</span><span class="o">=</span><span class="n">vtodo</span><span class="o">.</span><span class="n">summary</span><span class="o">.</span><span class="n">value</span><span class="p">,</span>
                 <span class="n">created</span><span class="o">=</span><span class="n">vtodo</span><span class="o">.</span><span class="n">created</span><span class="o">.</span><span class="n">value</span><span class="p">,</span>
                 <span class="n">finished</span><span class="o">=</span><span class="n">vtodo</span><span class="o">.</span><span class="n">contents</span><span class="p">[</span><span class="s">'percent-complete'</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">value</span> <span class="o">==</span> <span class="s">&quot;100&quot;</span>
                 <span class="p">)</span>
        <span class="n">nodes</span><span class="p">[</span><span class="n">n</span><span class="o">.</span><span class="n">uid</span><span class="p">]</span> <span class="o">=</span> <span class="n">n</span>

    <span class="n">children</span> <span class="o">=</span> <span class="p">{}</span>
    <span class="k">for</span> <span class="n">uid</span><span class="p">,</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">nodes</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
        <span class="n">vtodo</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">vtodo</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">related_uid</span> <span class="o">=</span> <span class="n">vtodo</span><span class="o">.</span><span class="n">contents</span><span class="p">[</span><span class="s">'related-to'</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">value</span>
            <span class="n">node</span><span class="o">.</span><span class="n">parent</span> <span class="o">=</span> <span class="n">nodes</span><span class="p">[</span><span class="n">related_uid</span><span class="p">]</span>
            <span class="n">children</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="n">related_uid</span><span class="p">,</span> <span class="p">[])</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">node</span><span class="p">)</span>
        <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
            <span class="n">node</span><span class="o">.</span><span class="n">parent</span> <span class="o">=</span> <span class="bp">None</span>

    <span class="k">for</span> <span class="n">uid</span><span class="p">,</span> <span class="n">node</span> <span class="ow">in</span> <span class="n">nodes</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
        <span class="n">node</span><span class="o">.</span><span class="n">children</span> <span class="o">=</span> <span class="n">children</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">uid</span><span class="p">,</span> <span class="p">[])</span>
        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">children</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
            <span class="n">node</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="s">&quot;task&quot;</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">node</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="s">&quot;project&quot;</span>



    <span class="n">autouid</span> <span class="o">=</span> <span class="mi">0</span> <span class="c"># For newly created Tasks</span>

    <span class="c"># Now find the time information in the ICS file</span>
    <span class="n">time_log</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="k">for</span> <span class="n">vevent</span> <span class="ow">in</span> <span class="n">f</span><span class="o">.</span><span class="n">vevent_list</span><span class="p">:</span>
        <span class="n">related_uid</span> <span class="o">=</span> <span class="n">vevent</span><span class="o">.</span><span class="n">contents</span><span class="p">[</span><span class="s">'related-to'</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">value</span>
        <span class="n">task</span> <span class="o">=</span> <span class="n">nodes</span><span class="p">[</span><span class="n">related_uid</span><span class="p">]</span>
        <span class="k">if</span> <span class="n">task</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="s">&quot;project&quot;</span><span class="p">:</span>
            <span class="c"># TimeCult can only cope with time events being against 'leaf' nodes</span>
            <span class="c"># in the tree. So we need to adjust and create an additional leaf</span>
            <span class="n">project</span> <span class="o">=</span> <span class="n">task</span>
            <span class="n">undefined_l</span> <span class="o">=</span> <span class="p">[</span><span class="n">t</span> <span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">project</span><span class="o">.</span><span class="n">children</span> <span class="k">if</span> <span class="n">t</span><span class="o">.</span><span class="n">uid</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">'autouid'</span><span class="p">)]</span>
            <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">undefined_l</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
                <span class="n">task</span> <span class="o">=</span> <span class="n">undefined_l</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">task</span> <span class="o">=</span> <span class="n">Node</span><span class="p">(</span><span class="n">uid</span><span class="o">=</span><span class="s">'autouid-</span><span class="si">%d</span><span class="s">'</span> <span class="o">%</span> <span class="n">autouid</span><span class="p">,</span>
                            <span class="n">summary</span><span class="o">=</span><span class="s">'other'</span><span class="p">,</span>
                            <span class="n">parent</span><span class="o">=</span><span class="n">project</span><span class="p">,</span>
                            <span class="nb">type</span><span class="o">=</span><span class="s">&quot;task&quot;</span><span class="p">,</span>
                            <span class="n">created</span><span class="o">=</span><span class="n">project</span><span class="o">.</span><span class="n">created</span><span class="p">,</span>
                            <span class="n">finished</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span>
                            <span class="n">children</span><span class="o">=</span><span class="p">[])</span>
                <span class="n">autouid</span> <span class="o">+=</span> <span class="mi">1</span>
                <span class="n">nodes</span><span class="p">[</span><span class="n">task</span><span class="o">.</span><span class="n">uid</span><span class="p">]</span> <span class="o">=</span> <span class="n">task</span>
                <span class="n">project</span><span class="o">.</span><span class="n">children</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">task</span><span class="p">)</span>

        <span class="n">dtstart</span> <span class="o">=</span> <span class="n">vevent</span><span class="o">.</span><span class="n">dtstart</span><span class="o">.</span><span class="n">value</span>
        <span class="n">dtend</span> <span class="o">=</span> <span class="n">vevent</span><span class="o">.</span><span class="n">dtend</span><span class="o">.</span><span class="n">value</span>
        <span class="k">if</span> <span class="n">dtstart</span><span class="o">.</span><span class="n">tzinfo</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
            <span class="n">dtstart</span> <span class="o">=</span> <span class="n">dtstart</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">tzinfo</span><span class="o">=</span><span class="n">dtend</span><span class="o">.</span><span class="n">tzinfo</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">dtend</span><span class="o">.</span><span class="n">tzinfo</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span>
            <span class="n">dtend</span> <span class="o">=</span> <span class="n">dtend</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">tzinfo</span><span class="o">=</span><span class="n">dtstart</span><span class="o">.</span><span class="n">tzinfo</span><span class="p">)</span>
        <span class="n">time_rec</span> <span class="o">=</span> <span class="n">TimeRec</span><span class="p">(</span><span class="n">startTime</span><span class="o">=</span><span class="n">dtstart</span><span class="p">,</span>
                           <span class="n">duration</span><span class="o">=</span><span class="p">(</span><span class="n">dtend</span> <span class="o">-</span> <span class="n">dtstart</span><span class="p">)</span><span class="o">.</span><span class="n">total_seconds</span><span class="p">(),</span>
                           <span class="n">task</span><span class="o">=</span><span class="n">task</span><span class="p">)</span>
        <span class="n">time_log</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">time_rec</span><span class="p">)</span>

    <span class="c"># Now need to assign IDs</span>
    <span class="n">taskId</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="k">for</span> <span class="n">u</span><span class="p">,</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">nodes</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
        <span class="n">taskId</span> <span class="o">+=</span> <span class="mi">1</span>
        <span class="n">n</span><span class="o">.</span><span class="n">id</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">taskId</span><span class="p">)</span>

    <span class="k">for</span> <span class="n">tr</span> <span class="ow">in</span> <span class="n">time_log</span><span class="p">:</span>
        <span class="n">tr</span><span class="o">.</span><span class="n">taskId</span> <span class="o">=</span> <span class="n">tr</span><span class="o">.</span><span class="n">task</span><span class="o">.</span><span class="n">id</span>

    <span class="k">return</span> <span class="n">TimeCult</span><span class="p">(</span>
        <span class="n">name</span><span class="o">=</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">filename</span><span class="p">),</span>
        <span class="n">projectTree</span><span class="o">=</span><span class="p">[</span><span class="n">n</span> <span class="k">for</span> <span class="n">u</span><span class="p">,</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">nodes</span><span class="o">.</span><span class="n">items</span><span class="p">()</span> <span class="k">if</span> <span class="n">n</span><span class="o">.</span><span class="n">parent</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">],</span>
        <span class="n">timeLog</span><span class="o">=</span><span class="n">time_log</span><span class="p">)</span>


<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">'__main__'</span><span class="p">:</span>
    <span class="n">filename</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
    <span class="n">timecult</span> <span class="o">=</span> <span class="n">convert</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
    <span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">write</span><span class="p">(</span>
        <span class="sd">&quot;&quot;&quot;&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&quot;&quot;&quot;</span> <span class="o">+</span>
        <span class="n">ET</span><span class="o">.</span><span class="n">tostring</span><span class="p">(</span><span class="n">timecult</span><span class="o">.</span><span class="n">toXML</span><span class="p">()))</span>
</pre>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://lukeplant.me.uk/blog</uri>
    </author>
    <title type="html"><![CDATA[Leaving KDE]]></title>
    <link rel="alternate" type="text/html" href="http://lukeplant.me.uk/blog/posts/leaving-kde/" />
    <id>http://lukeplant.me.uk/blog/posts/leaving-kde/</id>
    <updated>2010-06-17T01:57:39Z</updated>
    <published>2010-06-17T01:57:39Z</published>
    <category scheme="http://lukeplant.me.uk/blog" term="KDE" />
    <category scheme="http://lukeplant.me.uk/blog" term="Rants" />
    <category scheme="http://lukeplant.me.uk/blog" term="Linux" />
    <summary type="html"><![CDATA[Leaving KDE]]></summary>
    <content type="html" xml:base="http://lukeplant.me.uk/blog/posts/leaving-kde/"><![CDATA[<div class="document">
<p>After being a loyal fan of KDE for a long time, I've just switched to GNOME.</p>
<p>I'm afraid to say that since the KDE 4 series, I've been unable to recommend
KDE to anyone.  With KDE 4.0 to 4.3, that was due to general crashiness,
brokenness and bugs that are at the level of <em>embarrassing</em> — when a bug is
obvious enough and significant enough that a new user would be shocked to find it and I would have a hard time explaining how I could use software that is clearly inferior to whatever they were using before (usually Windows).</p>
<p>With KDE 4.4, most desktop instability has been ironed out, but it has been
replaced by problems that mean I can no longer stomach or risk staying with
KDE for myself, let alone recommend it to anyone else.  The final straw was
that the framework for storing PIM data (Akondai) is turning out no better
than <a class="reference external" href="http://lukeplant.me.uk/blog/posts/a-plea-to-kde-developers/">I feared</a> and is
‘losing’ some of my data.</p>
<p>I found that <a class="reference external" href="https://bugs.kde.org/show_bug.cgi?id=232773">some things added to the address book ‘never’
actually end up in the file they are supposed to be stored in</a>.  I've added an e-mail
address for a contact, and it appears to have added fine in KAddressBook.
The data persists even across reboots etc., so it isn't ‘lost’ in one sense.
Usually, the data appears in my std.vcf after a few seconds.  In this case,
however, four days later it still hasn't appeared in std.vcf.  That counts
as close enough to ‘never’ in my book, so it is fair to say it is ‘lost’.
This has happened intermittently since KDE 4.4.1.</p>
<p>One additional result of this is that KMail never sees that address — at the
moment it seems that it looks only in std.vcf, not Akonadi (and this is
probably the only reason I found the bug in the first place).  That's a
pain, but the more serious problem is that my data is just not where it is
supposed to be.  If I need to backup and restore, I imagine it would be
possible for that to succeed, if the Akonadi data was backed-up and restored
along with the underlying data.  But if you get that bit wrong, I can only
imagine a world of pain and subtle data corruption.  It is completely
unacceptable that my data is being stored in “my data files + completely
opaque Akonadi database” rather than just “my data files”.</p>
<p>Another bug is that <a class="reference external" href="https://bugs.kde.org/show_bug.cgi?id=232774">the Google contacts Akonadi plugin also loses data in a
serious way</a>, making it far
worse than useless.  The nature of this bug makes me think that either there
is a significant bug in the Akonadi framework, or that the framework API
made it is easy to get this wrong — both of which are worrying.</p>
<p>These bugs are on top my general concerns with the framework — it has always
been painful to work with, and the fact that it is even <strong>visible</strong> is a
major failing — the software layer it replaced was, after all, completely
invisible, just as it should have been.</p>
<p>From what I can tell, migration of KMail to Akonadi is going ahead at full
pace and will be mandatory soon.  My contact data is modest (500 Kb), so I
have been able to cope with moving it around and fixing some problems,
including some data loss and mistakes caused, I think, by the above bugs,
since backups are quick.  But my e-mail data is 2.5 Gb, and detecting
problems or errors is going to be massively harder.  I'm not willing to risk
my e-mail data with Akonadi, so I need a new e-mail client.</p>
<p>It turns out that Evolution works for me.  It stores data in mbox files,
which isn't my preferred (1 file per e-mail, like maildir or MH, is nicer
for various purposes), but it is a standard format, and since my backup tool
is 'diff' based it will still cope efficiently with it.  It even integrates
with Google contacts out of the box, and the calendar app integrates with
Google calendar, while allowing me to work offline.  This is what Akonadi is
supposed to offer one day, and I wish them the best of luck with that.  But
for now I'm going to stick with a system that prioritises the safety of my
data, and that I know works.  Evolution has a few significant niggles, but I
think I can live with them.</p>
<p>That leaves me with the choice of desktop.  Using programs from one desktop
suite generally is faster and easier and looks nicer.  I had already dropped
Konqueror for Chrome (Konqueror has fallen far too far behind these days),
and GNOME equivalents to most KDE apps work well enough — like
Empathy/Pidgin.  That tips the balance over to GNOME — and I can still use
apps like k3b for specialist work when I need them.</p>
<p>Most of my reasons for leaving GNOME in the first place (about 7 years ago I
think) have been resolved.  GNOME apps like Nautilus and Evolution are no
longer as excuciatingly slow and bloated as they used to be (and I don't
think it is just that my computer got faster), and actually feel quite
snappy most of the time.  In some cases they definitely outperform the
equivalent KDE default app (e.g. Eye of GNOME is very fast and works very
nicely, doing 90% of what I used Gwenview for before, but much faster).
Generally GNOME is much snappier as a desktop — it takes only about 5
seconds to start after I've logged in, which is <em>much</em> faster than KDE.</p>
<p>So I'm using Ubuntu's GNOME desktop, and I no longer have plasma and all the
plasmoids.  To be honest, I don't think I'm missing them.  I have all the
panel applets I need, and they are well designed and work properly.
Proliferation of plasmoids is like the proliferation of apps on Apple app
store — most of them are not worth having, and having to search through to
find the ones that are is an anti-feature (not to mention that the new
horizontal applet picker in KDE 4.4, which replaced the vertical one in KDE
4.3, is just awful — I don't understand how such a major regression happened).</p>
<p>I certainly won't shed a tear over Nepomuk/Strigi.  After <strong>weeks</strong> of it constant disk activity as they attempted to index my files, they never seemed to do anything useful. They have been replaced by Tracker, which works very well, and very quickly, and without being a huge resource hog. It does not update immediately when I add new files, but it is fast enough to know that when I really want to find something in a real situation, it is likely to be in the index already.  And it isn't the massive resource hog that Nepomuk was.</p>
<p>First experience with Ubuntu's GNOME has thrown up some problems.  Here are some niggles I've been able to fix/solve:</p>
<ul class="simple">
<li>PulseAudio - this breaks lots of things, especially games, and provides no
added benefit.  But <a class="reference external" href="http://art.ubuntuforums.org/showpost.php?p=9297829&amp;postcount=146">it can be removed</a>.
Perhaps the Ubuntu guys will remove it in future, or make it easier to
remove.  Lots of people and programs seem to have problems with it, it's
very difficult to see what value it is adding for most people.</li>
<li>To turn off desktop effects quickly (for better performance games)
- either: install fusion-icon (use &quot;fusion-icon -n&quot; as the command)
- or, to do it automatically for fullscreen games, set this option to true: /apps/compiz/general/screen0/options/unredirect_fullscreen_windows</li>
<li>To turn off screen locking on resume - there is setting is in gconf,
search for 'lock'.</li>
</ul>
<p>And here are some that are still bothering me a bit:</p>
<ul class="simple">
<li>Reading new e-mails with keyboard only - it's a bit buggy/confusing with Evolution.</li>
<li>Some options are hidden away in gconf, so it's difficult to know if it is
possible to change things.</li>
<li>GNOME has less configurability in general, or harder to get to it,
especially for creating new keyboard shortcuts.</li>
<li>Compiz doesn't always seem to obey or understand all metacity options
(e.g.  shortcut for fullscreen-ing windows), so it sometimes confusing
working out what is going on.</li>
<li>The GNOME file dialog boxes have improved a little bit since I was last using GNOME, but haven't begun to close the gap on KDE's far superior ones.</li>
</ul>
<p>But there are some niggles which are no longer there due to the switch from
KDE.  Overall, things are similar at this level.</p>
<p>To conclude, I think the KDE developers were far too ambitious with the KDE 4 series.  The cost has been that the only supported versions of KDE are ones that you cannot recommend to anyone, and that is a critical mistake in a competitive environment.  Meanwhile, GNOME has massively improved in speed and has incrementally added features that people actually need, instead of creating large frameworks that may or may not be robust and useful one day.</p>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://lukeplant.me.uk/blog</uri>
    </author>
    <title type="html"><![CDATA[Linux and calendars - bad combination...]]></title>
    <link rel="alternate" type="text/html" href="http://lukeplant.me.uk/blog/posts/linux-and-calendars-bad-combination/" />
    <id>http://lukeplant.me.uk/blog/posts/linux-and-calendars-bad-combination/</id>
    <updated>2010-03-23T13:22:49Z</updated>
    <published>2010-03-23T13:22:49Z</published>
    <category scheme="http://lukeplant.me.uk/blog" term="KDE" />
    <category scheme="http://lukeplant.me.uk/blog" term="Rants" />
    <category scheme="http://lukeplant.me.uk/blog" term="Linux" />
    <summary type="html"><![CDATA[Linux and calendars - bad combination...]]></summary>
    <content type="html" xml:base="http://lukeplant.me.uk/blog/posts/linux-and-calendars-bad-combination/"><![CDATA[<div class="document">
<p>So, I'd like to be able to access my sync the calendar on my computer with other devices, like my BlackBerry Curve.  This is 2010 right?</p>
<ul class="simple">
<li>I already blogged the <a class="reference external" href="http://lukeplant.me.uk/blog/posts/blackberry-curve-kde-pim-sync-on-kubuntu-karmic-fail/">failure to sync directly</a>. Let's not go there.</li>
<li>How about just syncing KOrganizer with Google, and syncing the BlackBerry with Google?  I already have some calendars on Google, and that works fine.  But now for my main calender:<ul>
<li>I tried GCalDaemon, but found that it <a class="reference external" href="https://sourceforge.net/tracker/?func=detail&amp;aid=2844153&amp;group_id=184382&amp;atid=909032">ignores/deletes all recurring events on your calendar</a>.  Which is pretty evil.</li>
<li>There is Akonadi... Given how hopelessly buggy Akonadi is for syncing contacts to Google (like, if Google has more than one e-mail for a contact, none of them are transferred, and worse), I'm not very hopeful about this (and I'm using most recent KDE 4.4.1).  But I'll try anyway...<ul>
<li>The whole experience is fraught with bugs and confusion.  You click 'Add' and things aren't added, you click 'Remove' and they don't disappear, or only after some indefinite period of time (I've waited 30 seconds, is it just broken or should I carry on waiting?).  You close the Akonadi configuration and open it again, or restart the server, and items have appeared, and other things that you didn't ask for.  A lot seems to go on asynchronously, which might be a good idea, but you get the impression you are attempting to communicate with a forgetful, deaf, sleepy, indecisive, incompetent idiot.  I have eventually managed to add a Google calendar resource, but it says &quot;Failed getting last updated event&quot;, and nothing appears on my calendar.</li>
</ul>
</li>
</ul>
</li>
<li>OK, let's try Evolution calendar.  At first it didn't work, then it seemed to work a bit better, but trying to modify events returns &quot;Unknown error&quot;, and now it refuses to show the calendar at all.</li>
<li>OK, let's just try using Google calendar, importing all my existing calendar data, ditching any hope of using a local calendar app.  But Google doesn't like my calendar file - &quot;Failed to import events: Processing error during upload.&quot;</li>
</ul>
<p>Epic fail.  Bad day.</p>
<hr class="docutils" />
<p>Update: in the last case, I discovered after some investigation that Google doesn't like the 'VTIMEZONE' sections in my calendar file.  Removing them allows the import to succeed (although it still produces an error message, and I'm guessing it might have lost some time information on summer events though, not sure).</p>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://lukeplant.me.uk/blog</uri>
    </author>
    <title type="html"><![CDATA[Blackberry Curve ↔ KDE-PIM sync on Kubuntu Karmic. FAIL]]></title>
    <link rel="alternate" type="text/html" href="http://lukeplant.me.uk/blog/posts/blackberry-curve-kde-pim-sync-on-kubuntu-karmic-fail/" />
    <id>http://lukeplant.me.uk/blog/posts/blackberry-curve-kde-pim-sync-on-kubuntu-karmic-fail/</id>
    <updated>2010-02-11T17:07:58Z</updated>
    <published>2010-02-11T17:07:58Z</published>
    <category scheme="http://lukeplant.me.uk/blog" term="KDE" />
    <category scheme="http://lukeplant.me.uk/blog" term="Linux" />
    <summary type="html"><![CDATA[Blackberry Curve ↔ KDE-PIM sync on Kubuntu Karmic. FAIL]]></summary>
    <content type="html" xml:base="http://lukeplant.me.uk/blog/posts/blackberry-curve-kde-pim-sync-on-kubuntu-karmic-fail/"><![CDATA[<div class="document">
<p>For the sake of anyone else who might want to know about this in advance, I'll blog my failure.</p>
<p>I tried with Kubuntu Karmic, and the following steps:</p>
<ol class="arabic">
<li><p class="first">Install the necessary packages:</p>
<pre class="code bash literal-block">
sudo aptitude install opensync-plugin-kdepim opensyncutils barrybackup-gui barry-util opensync-plugin-barry
</pre>
</li>
<li><p class="first">Plug in the Blackberry, and choose &quot;Mass storage&quot; mode on the Blackberry.</p>
</li>
<li><p class="first">Set up permissions to allow a non-root user to access the device.  I added the file <tt class="docutils literal"><span class="pre">/etc/udev/rules.d/040-devices.rules</span></tt>, with the following contents:</p>
<pre class="literal-block">
BUS==&quot;usb&quot;, SYSFS{idVendor}==&quot;0fca&quot;, SYSFS{idProduct}==&quot;8004&quot;, GROUP=&quot;admin&quot;
</pre>
<p>The above line gives permissions to all users of group 'admin', which includes my normal user.  The numbers &quot;0fca&quot; and &quot;8004&quot; are device numbers obtainable from <tt class="docutils literal">lsusb</tt>:</p>
<pre class="code bash literal-block">
lsusb | grep <span class="s2">&quot;Research In Motion&quot;</span>
</pre>
<p>Result:</p>
<pre class="code bash literal-block">
Bus 002 Device 008: ID 0fca:8004 Research In Motion, Ltd.
</pre>
<p>You will need to unplug the Blackberry and plug back in after this step.</p>
</li>
<li><p class="first">Check you can access the Blackberry.</p>
<pre class="code bash literal-block">
btool -t
</pre>
<p>This should list a series of databases on the Blackberry</p>
</li>
<li><p class="first">Back up the current contents:</p>
<pre class="code bash literal-block">
barrybackup
</pre>
<p>Note the pin for later, and follow the prompts to backup the Blackberry data.</p>
</li>
<li><p class="first">Back up your KDE-PIM data, in case of any corruption, duplicate elements etc. (It happened to me!).</p>
</li>
<li><p class="first">Create a msynctool configuration for doing the synchronisation.</p>
<pre class="code bash literal-block">
msynctool --addgroup Blackberry
msynctool --addmember Blackberry barry-sync
msynctool --addmember Blackberry kdepim-sync
msynctool --showgroup Blackberry
</pre>
<p>The final command should show the first member as missing configuration. Do the following</p>
<pre class="code bash literal-block">
msynctool --configure Blackberry 1
</pre>
<p>and insert your pin in the relevant place.</p>
</li>
<li><p class="first">Moment of truth.  Close KOrganizer and KMail, then:</p>
<pre class="code bash literal-block">
msynctool --sync Blackberry
</pre>
</li>
</ol>
<p>I came across the following major bugs:</p>
<ul class="simple">
<li>Syncing never completes, and I have to press Ctrl-C to abort.</li>
<li>When I try to sync a second/third time, I end up with lots of duplicates on my computer, caused by items from the Blackberry being copied back.  I'm not sure if they are to do with the unclean abort, or the following symptoms:
* 'All day events'.  A duplicate appears with the start time set to '0:00'
* Daylight savings problems - for summer events, a duplicate appears 1 hour different from the original
* Items from my Google calendar (which is a read only calendar) got copied back to my main calendar.</li>
<li>Each time I attempt to sync, duplicate events and contacts build up on the Blackberry as well.</li>
<li>Using barrybackup to restore to a clean state with the backup made previously fails with lots of errors.  By removing some items in <tt class="docutils literal"><span class="pre">~/.barry/backup/&lt;pin&gt;/config</span></tt>, I've got it to apparently succeed, but the contacts and calendar on the Blackberry are not cleared out, which is the point of the exercise.
* There is a way to clear calendar/contacts on the Blackberry.  Go to Calendar -&gt; Menu -&gt; Options.  Type RSET.  The calendar will be cleared (though it says nothing).  Repeat for contacts.  This time you will get a prompt about clearing.  Clearing out the msynctool database is also a good idea to keep further attempts  clean and fast.</li>
</ul>
<p>In the end, a one-time, one-way sync is all that I have been able to achieve.  That is quite disappointing, since none of the web pages I found before deciding on a Blackberry mentioned any problems like these.</p>
<p>I tried upgrading all the barry packages from 0.14 to 0.16, but got lots more errors - when trying to send data to the Blackberry I just got &quot;Timeout in usb_bulk_read&quot; blah blah and do data was actually sent.</p>
<p>Sources:</p>
<ul class="simple">
<li><a class="reference external" href="http://forums.debian.net/viewtopic.php?t=20424">Contacts, sms messages and files from and to mobile phone</a></li>
<li><a class="reference external" href="http://www.linux.com/news/embedded-mobile/mids/8210-syncing-your-blackberry-on-linux">Syncing your BlackBerry on Linux</a></li>
</ul>
</div>
]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://lukeplant.me.uk/blog</uri>
    </author>
    <title type="html"><![CDATA[A plea to KDE developers]]></title>
    <link rel="alternate" type="text/html" href="http://lukeplant.me.uk/blog/posts/a-plea-to-kde-developers/" />
    <id>http://lukeplant.me.uk/blog/posts/a-plea-to-kde-developers/</id>
    <updated>2009-09-23T13:15:33Z</updated>
    <published>2009-09-23T13:15:33Z</published>
    <category scheme="http://lukeplant.me.uk/blog" term="KDE" />
    <category scheme="http://lukeplant.me.uk/blog" term="Rants" />
    <summary type="html"><![CDATA[A plea to KDE developers]]></summary>
    <content type="html" xml:base="http://lukeplant.me.uk/blog/posts/a-plea-to-kde-developers/"><![CDATA[
<div class="document">


<p>I recently upgraded to KDE 4.3.1 (from KDE 4.2.something).  As seems to be par
for the course for the KDE 4 series, I then waded through nearly a dozen
bugs/crashes/regressions for the next day, filing bugs where I had the energy.
This has got pretty old, and fills me with no confidence about the future of
KDE — the stable desktop I'm hoping for still hasn't materialised.</p>
<p>But there is one thing about KDE 4 that <strong>terrifies</strong> me, and this post is an
attempt to get the KDE devs to change their approach before it's too late.</p>
<p>KDE 4.2 attempted to migrate some of my data to Akonadi, the new framework for
storing PIM data.  There were a bunch of ways in which Akonadi did not provide
the features that previously existed (can't have multiple writable calendars in
KOrganizer, Kopete address book link didn't work...), so I had to ditch it.
Thankfully this was not hard (though the whole experience would have been
extremely confusing to Joe User).</p>
<p>I was prepared to give KDE 4.3 another shot on this front (after carefully
backing up my data).  I cleared out any remnants of previous Akonadi data, and
the settings which told it not to do the migration.</p>
<p>The results were pretty disappointing:</p>
<ul>
<li>
<p class="first">First, there was an initial setup process.  This failed.  Unfortunately, the
popup simply disappeared before I could note down the error message.  It was
something to do with creating an agent.  Did the process crash, or was it
supposed to just disappear like that?</p>
</li>
<li>
<p class="first">Then, for individual applications, the migrations all partly failed.  Again,
the popups telling me what was happening, including the error, just
disappeared after a short delay.  The error was something about a timeout when
creating an instance of an agent.  Did the process crash?  Did the agent
instance get created eventually, so the process could continue successfully?
I've no idea. I can't even file an bug without the error message.</p>
<p>Even while the popup remained, there was no indication of what I should do
about the error, if anything.</p>
<p>So I'm guessing all the migrations failed — my applications don't seem to be
migrated to using Akonadi at all.</p>
</li>
</ul>
<p>Why does this worry me so much?  Well, I can cope with an unstable desktop.  It's
a pain, it means I can't recommend KDE to anyone I know in it's current state,
but usually I can work around the pain points.  Plasma restarts itself, so
although it is still pretty crashy (far more than the Windows shell, for
instance, has ever been in my experience), I don't have to worry about it too
much.</p>
<p>But Akonadi is a different matter.  It is the proposed framework for handling
all PIM data — all my e-mails, calendars and address book.  This data is
<strong>extremely</strong> important to me.  Akonadi is clearly not up to the job of handling
it — if their migration tool can fail like this, and fail with worrying errors
about timeouts (which actually suggests the migration process is
<em>non-deterministic</em> — it's going to depend on how fast/busy your computer is),
it's clearly far from ready.  It's not getting better, it's getting worse — this
time the migration failed completely, and I'm not even able to check whether
it's up to feature parity with non-Akonadi methods.</p>
<p>Even worse than this, is that either the KDE developers:</p>
<ul class="simple">
<li>think it's OK to start migrating to an alpha-quality framework for handling
user's data.  To me, this is appalling.  Desktop eye-candy in exchange for a
bit of instability is one thing, but my data is entirely different.</li>
<li>or, they are unaware that Akonadi is not there yet.  This is just as
worrying.</li>
</ul>
<p>Akonadi seems like an overly ambitious project.  If you look at its <a class="reference external" href="http://pim.kde.org/akonadi/">home page</a>, the diagram includes the idea that other
desktop apps, outside of KDE, will use Akonadi as a backend for all their data.
To me, this seems extremely unlikely and is a tell-tail sign of developers
getting ideas that are just too big.</p>
<p>So, what do I propose?</p>
<p>Simply this: ditch Akonadi.  Yes, I mean that.  KDE 4 seems to lack a BDFL who
is willing to say "this is not working, time to pull the plug".  Mark
Shuttleworth did that with a pet project of his when the developers got
<a class="reference external" href="http://www.markshuttleworth.com/archives/4">distracted with shiny geek toys</a>.
Windows Vista ditched the killer feature of Vista, their WinFS filesystem,
because it just wasn't ready. But it seems there is no-one in KDE who can make
these kind of decisions.  The major obstacle is egos and pride — after all that
work has gone in for years, can we ditch a big feature like that?  Yes, you can,
and you should, for the sake of your users and the future of KDE.  Of course,
you can just move it to an experimental branch and come back to it for KDE
5/6/7, but <strong>please</strong> do not turn it on until it's ready.</p>
<p>Akonadi is one instance of a bigger problem in KDE — grandiose ‘we'll fix
everything but it will take us five years’ schemes that are prioritised over
things users actually want, and could be implemented soon.</p>
<p>For example, I want desktop search and fast e-mail search.  After all, this is
2009, right?  Is it so much to ask for a decent way of searching all the files
on my computer, and fast full text search for my e-mails? If I used Mac or Vista
or Google docs &amp; Gmail, I would have had this years ago.  Instead of that, KDE
gives us: Nepomuk.  The usefulness of Nepomuk completely escapes me.  Even
though it includes Strigi indexing (which indexes all your files, though it can
be a big pain to get working), there is no decent interface for searching those
files. (No KRunner is not a decent interface).  Currently, turning Nepomuk off
has exactly one consequence — it makes my computer much more responsive and
saves me 3 Gb of disk space.  AFAICS, there are no applications which make good
use of Nepomuk.  I think there is tagging in Dolphin, but:</p>
<ul class="simple">
<li>There is no interface for searching tags!  What kind of idiots do you take us
for? Going round tagging files in the hope that one day we'll be able to make
use of all that effort because someone actually implemented a UI?</li>
<li>I don't want to manually tag files anyway, I want a decent desktop search
tool!</li>
</ul>
<p>Other applications that need tagging are better off implementing their own
solution, and then extracting a simple KTagging library which can be shared.</p>
<p>Nepomuk isn't as bad as Akonadi at the moment — it's useless, but I can turn it
off, and it doesn't threaten my data.  But even then, all the effort that is
going into Nepomuk could be directed into manageable, achievable goals of
providing features that users will be able to make use of.</p>
<p>Please, KDE devs, stop the big grandiose schemes.  Stop doing anything that
would threaten my data.  I've been a loyal fan — pushed to the limits by the KDE
4 series, I'll admit — but if you foist Akonadi on me in anything like it's
current state, I'm taking all my data and going.  I don't yet know where I'll
go.  I might go back to GNOME after a <em>long</em> time.  It still sucks IMO, and I'm
not sure how I'm going find replacements for KMail (very nice despite no fast
full-text search), KOrganizer, Amarok, k3b etc. KDE currently has the lion's
share of the best Linux apps.  But it doesn't really deserve them at the moment,
and it's going to lose all but its most stubborn and loyal users at the current
rate.</p>
<p>If you got this far, thanks for bothering to read this.  I know the KDE
developers have got a lot of flack for KDE 4, and I have held back for a long
time, but some of the criticisms are deserved, and you do need to listen
occasionally...</p>
</div>

]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://lukeplant.me.uk/blog</uri>
    </author>
    <title type="html"><![CDATA[Amarok 2 can corrupt MP3 files]]></title>
    <link rel="alternate" type="text/html" href="http://lukeplant.me.uk/blog/posts/amarok-2-can-corrupt-mp3-files/" />
    <id>http://lukeplant.me.uk/blog/posts/amarok-2-can-corrupt-mp3-files/</id>
    <updated>2009-04-23T01:18:10Z</updated>
    <published>2009-04-23T01:18:10Z</published>
    <category scheme="http://lukeplant.me.uk/blog" term="KDE" />
    <category scheme="http://lukeplant.me.uk/blog" term="Music" />
    <category scheme="http://lukeplant.me.uk/blog" term="Rants" />
    <summary type="html"><![CDATA[Amarok 2 can corrupt MP3 files]]></summary>
    <content type="html" xml:base="http://lukeplant.me.uk/blog/posts/amarok-2-can-corrupt-mp3-files/"><![CDATA[
<p>I've found that Amarok 2 is really not ready to be used...</p>

<p>In terms of interface, it's not that bad, and I'm much happier than most people with the changes from Amarok 1.4, and I've been giving it a fair try.</p>

<p>I was annoyed that it provides a UI for putting albums into 'Various Artists', or removing then, but then forgets everything you've done next time you open the program when it rescans the collection.  But I could live with that for the time being.</p>

<p>The fact that it clips the beginning off some tracks for some unknown reason is also really annoying (it clips 1.2 seconds off the beginning of one of my favourite tracks; Dragon Player, another KDE4 apps, also does it, but no other media players do so).</p>

<p>But it has started doing things that mean I just don't trust it with my MP3s any more:</p>

<p>Certain tracks start appearing with seemingly random album and artist names in the playlist (picked from other tracks in my collect), though they have the correct song title and play the correct song.  If I right click and select 'Edit track details', the same wrong details appear (so if I were to press save, the wrong details would be saved back to the file).  If, in the collection pane, I go to the album the track ought to be in, it is missing.  I don't know how to find it again, except in the file browser.  However, if I look at the same file in any other player or ID3 tag editor, the correct info appears.  Somehow Amarok is not reading the info from the file itself, but from some other source which is corrupt.</p>

<p>This means that editing any track details in Amarok is now dodgy, since if I go to edit one detail, I can't be sure that other details will be supplied correctly, and when I save I could save Amarok's corrupt data to the file.</p>

<p>Perhaps purging the collection completely might help, but I'm not sure how to do it, and I don't really want to lose all the album covers etc.</p>

<p>I guess I should file a bug, but I've filed so many recently, and this is one I don't know how to reproduce, and it's fairly pointless filing it — as a developer myself, I know that, with the best will in the world, this kind of bug will eventually just get WORKSFORME.</p>


<p>Before, I couldn't trust Amarok to actually play tracks correctly, and now can't trust Amarok to show my collection so that I can find songs and albums, and I certainly can't trust it to manage the MP3 files.</p>

<p>Fairly damning I'm afraid.  I'm posting this as a warning to others, Amarok could be corrupting the metadata in your MP3s...</p>

<p>Should I try upgrading to Amarok 2.1? Or do I just give up now and go back to mocp?</p>

]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://lukeplant.me.uk/blog</uri>
    </author>
    <title type="html"><![CDATA[Konsole/Yakuake and drag/drop]]></title>
    <link rel="alternate" type="text/html" href="http://lukeplant.me.uk/blog/posts/konsole-yakuake-and-drag-drop/" />
    <id>http://lukeplant.me.uk/blog/posts/konsole-yakuake-and-drag-drop/</id>
    <updated>2008-05-10T01:50:14Z</updated>
    <published>2008-05-10T01:50:14Z</published>
    <category scheme="http://lukeplant.me.uk/blog" term="KDE" />
    <summary type="html"><![CDATA[Konsole/Yakuake and drag/drop]]></summary>
    <content type="html" xml:base="http://lukeplant.me.uk/blog/posts/konsole-yakuake-and-drag-drop/"><![CDATA[
<p>You can drag and drop files onto a Konsole (or Yakuake) terminal session, and it works -- the file is copied to your current directory!  That is pretty cool.  I just had the situation when I needed to copy a file from an email (in KMail) into the current directory I was in, and I was very chuffed that the drag and drop operation I instinctively went for worked just as planned.  It pops up a little menu so you can choose between 'Paste' (the filename) 'cp', 'cd', 'ln' and 'mv'.</p>

]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://lukeplant.me.uk/blog</uri>
    </author>
    <title type="html"><![CDATA[Personal wiki and desktop integration]]></title>
    <link rel="alternate" type="text/html" href="http://lukeplant.me.uk/blog/posts/personal-wiki-and-desktop-integration/" />
    <id>http://lukeplant.me.uk/blog/posts/personal-wiki-and-desktop-integration/</id>
    <updated>2008-02-23T21:12:57Z</updated>
    <published>2008-02-23T21:12:57Z</published>
    <category scheme="http://lukeplant.me.uk/blog" term="Python" />
    <category scheme="http://lukeplant.me.uk/blog" term="KDE" />
    <category scheme="http://lukeplant.me.uk/blog" term="Linux" />
    <summary type="html"><![CDATA[Personal wiki and desktop integration]]></summary>
    <content type="html" xml:base="http://lukeplant.me.uk/blog/posts/personal-wiki-and-desktop-integration/"><![CDATA[
<P>
Like many people, I find it easier to find stuff on the web than on my own machine.  This post is about some of my attempts to remedy that.  You probably need to be a developer or that way inclined to get the most out of some of the solutions I've got here.  Stuff to download is at the bottom.
</P>
<H2 id="Searchtool">Search tool<A class="anchor" href="#Searchtool" title="Link to this section"> §</A></H2>
<P>
Obviously, first of all there is a need for a decent desktop search tool.  On Linux, your main options are:
</P>
<UL><LI><A class="ext-link" href="http://desktop.google.com/linux/"><SPAN class="icon">Google desktop search</SPAN></A>
<UL><LI>Main problem: it stops it's initial index after 100,000 documents.  I've got far more than that, and it means it never actually reaches my mail.  Typical crippleware.  This is useless for me.  
</LI></UL></LI><LI><A class="ext-link" href="http://beagle-project.org/"><SPAN class="icon">Beagle</SPAN></A>
<UL><LI>Main problem:  it will decide to thrash your disk and/or CPU and crash.  For me, runaway CPU usage and crashing made this completely useless.  It might be 99% of the way to being brilliant, but until these things are sorted out, it is a 100% waste of time.
</LI></UL></LI><LI><A class="ext-link" href="http://strigi.sourceforge.net/"><SPAN class="icon">Strigi</SPAN></A>
<UL><LI>Minor problem:  the GUIs suck
</LI><LI>Minor problem:  it indexes too much, sometimes.
</LI><LI>Main problem: after indexing about 300,000 documents, Strigi dies on me and refuses to do anything useful at all.  I don't know what causes it to choke, but it, too, is 100% useless AFAIC.  Maybe it's fixed now, but I've got bored of filing bugs and compiling from source just to find out it still doesn't work.
</LI></UL></LI><LI><A class="ext-link" href="http://www.gnome.org/projects/tracker/"><SPAN class="icon">MetaTracker</SPAN></A>, or Tracker for short.
<UL><LI>It can't search zip files etc. like Strigi can, which is a shame.
</LI><LI>It doesn't yet index my emails (KMail) -- it only does evolution.
</LI><LI>But I actually find this tool useful, .  It doesn't thrash my disk, it has a simple but effective GUI, as well as command line tools, it integrates <I>reasonably</I> well into KDE, and it also has a nice tagging facility.
</LI></UL></LI></UL><P>
   
</P>
<H2 id="TaggingandKonqueror">Tagging and Konqueror<A class="anchor" href="#TaggingandKonqueror" title="Link to this section"> §</A></H2>
<P>
Adding tags to files needs to be easy to do if it's going to happen.  MetaTracker provides the <TT>tracker-tag</TT> program which works well, but it is command line.  So I've written a small GUI wrapper that integrates into Konqueror via a service menu.  If you tag more than one file at once (by selecting a few files in Konqueror), it is in bulk tag mode, where it pops up an input box and simple adds the space-separated tags you enter to all the files.  
</P>
<P>
In single file mode, it does something slightly different.  It will first query the file for any existing tags, adding them to the default text that is in the input box, so that you can remove tags as well as add new ones.  It will also add a suggestion for an 'ID' tag -- based on the filename, with punctuation replaced by hyphens, and with 'ID-' prepended.  The idea is that I edit this and make it into something that will uniquely identify that file.  For example, a file "bible reading schedule.pdf" ends up with the tag ID-bible-reading-schedule-pdf, but "rest-quickref2.html" I will expand to "ID-restructured-text-quickref-html", and in some cases I would have to include something else that will distinguish it.
</P>
<P>
The nice thing about these tags is that MetaTracker will keep track of them <STRONG>even if I move or rename the file</STRONG>.  I'm not entirely sure how it does this (I think it uses inotify).  But it works, and that's all I care about for now.
</P>
<H3 id="Migrating">Migrating<A class="anchor" href="#Migrating" title="Link to this section"> §</A></H3>
<P>
It may be that strigi / Nepomuk will mature and become useful.  When they do, I can dump the tag database from MetaTracker pretty easily, and should be able to import into strigi.  Changing the tools/scripts I've developed to use a different metadata database should be pretty simple.
</P>
<H2 id="Personalwiki">Personal wiki<A class="anchor" href="#Personalwiki" title="Link to this section"> §</A></H2>
<P>
On top of this, there are other things that file systems are just not very helpful for organising.  Hierarchy works pretty well for about half my stuff (development work in particular).  But notes and things I like to jot down often get lost on my disk -- there are multiple places that some things belong, and some belong nowhere at all.
</P>
<P>
I decided that a personal wiki would be the best way forward for this.  However, I then had to choose a wiki -- thankfully the <A class="ext-link" href="http://www.wikimatrix.org/"><SPAN class="icon">WikiMatrix</SPAN></A> helps a lot.  I had tried the <A class="ext-link" href="http://www.instiki.org/show/HomePage"><SPAN class="icon">Instiki</SPAN></A> wiki.  But it turns out that Ruby on Rails <I>does</I> suck as much as they say -- the instiki process would sit there at about 50Mb for a while, but then decide that it would <A class="ext-link" href="http://rubyforge.org/tracker/index.php?func=detail&amp;aid=18185&amp;group_id=186&amp;atid=783"><SPAN class="icon">use up all my memory</SPAN></A>.  (Other people have noticed the same behaviour). So I wasted some time with that, and I don't think I'll be trying Ruby on Rails soon if this is the kind of thing I can expect.  
</P>
<P>
But anyway, WikiMatrix helped me find the <A class="ext-link" href="http://trac.edgewall.org/"><SPAN class="icon">Trac</SPAN></A> wiki.  Though I've used Trac a lot before, I hadn't thought of this option, as it is a wiki that is geared towards software projects, not general things.  However, I've discovered it is ideal for me:
</P>
<UL><LI>You can very easily turn off all the stuff you don't want, and then those components just disappear from the interface, exactly like they should.
</LI><LI>It has all the help you need built in.
</LI><LI>Nice GUI for administering it -- you need to use the command line UI for the first few steps, and you need to use htdigest to set up a password file, which some people might find tricky, but as a developer I'm right at home with that kind of thing.
</LI><LI>It is written in Python, and it seems to be very well written too.
</LI><LI>It uses SQlite (can use other databases), so it easy to query from outside if necessary.
</LI><LI>It comes with a built in server -- very little setup, easy to run as a normal user.
</LI><LI>It has a plugin architecture with <A class="ext-link" href="http://trac.edgewall.org/wiki/PluginList"><SPAN class="icon">lots of good plugins</SPAN></A>, and you can easily write your own.
</LI></UL><P>
This has allowed me to bring lots of bits and pieces into one place, and organise them as loosely or tightly as I want. The <A class="ext-link" href="http://trac-hacks.org/wiki/TagsPlugin"><SPAN class="icon">TagsPlugin</SPAN></A> for Trac makes this particularly convenient.  The wiki is actually pretty nice for composing blog posts too -- it can do all the code highlighting I want, and I can just copy the output HTML into my blog when it's ready.
</P>
<H2 id="Combiningwikianddesktop">Combining wiki and desktop<A class="anchor" href="#Combiningwikianddesktop" title="Link to this section"> §</A></H2>
<P>
The final problem is integrating wiki and other files.  Obviously, I have many documents that are much better managed outside a wiki.  It would be nice to be able to refer to these easily.  And by writing some Trac plugins, this is actually pretty easy.  I can now write things like this:
</P>
<PRE class="wiki">  file:ID-bible-reading-schedule-pdf
</PRE><P>
in my wiki and it turns into a <TT>file:///</TT> link to the right document.  In Konqueror, this works really well -- right clicking on the link brings up the same context menu that I would get in file browsing mode, so everything is available to me right there from the wiki page.  I can also do a search:
</P>
<PRE class="wiki">  [[MetaTrackerSearch(programming languages,web)]]
</PRE><P>
This will returns links to all files containing the text "programming languages" and "web", nicely formatted in a table.  Or I can do a tag search like this:
</P>
<PRE class="wiki">  [[MetaTrackerTagSearch(sermon)]]
</PRE><P>
to return all my sermons.
</P>
<H2 id="Further">Further<A class="anchor" href="#Further" title="Link to this section"> §</A></H2>
<P>
I've created a very simple Trac plugin for creating <A class="ext-link" href="http://lukeplant.me.uk/kio-sword/"><SPAN class="icon">KioSword</SPAN></A> links, which works nicely for embedding links to Bible passages.  I've got some ideas for further integrating different parts of my desktop.  One thing I'd like to do is produce a database of my sermons and bible studies, the texts they are on, when and where I've preached them etc.  A private Django app using the Django admin would probably work exceedingly well, and be very little work.  A simple export routine could produce a wiki page that could be 'included' into my wiki (using a Trac macro).  It could also export an read only ICal file which can be displayed in Kontact.  So many cool ideas, so little time...
</P>
<H2 id="Downloadlinks">Download links<A class="anchor" href="#Downloadlinks" title="Link to this section"> §</A></H2>
<UL><LI><A class="ext-link" href="http://trac-hacks.org/wiki/MetaTrackerPluginMacro"><SPAN class="icon">MetaTrackerPluginMacro</SPAN></A>
</LI></UL><UL><LI><A class="ext-link" href="http://files.lukeplant.fastmail.fm/public/tracker_tag_file"><SPAN class="icon">tracker_tag_file</SPAN></A> <BR>
Install this by putting it in your path somewhere (e.g. ~/bin, if that is on your PATH) <BR>
It requires:
<UL><LI>kdialog (present on all KDE installations)
</LI><LI>setClipboard -- a little utility to set the clipboard with the contents of the tags just added, for convenience only, see below.<BR>
</LI></UL></LI></UL><UL><LI><A class="ext-link" href="http://files.lukeplant.fastmail.fm/public/setClipboard"><SPAN class="icon">setClipboard</SPAN></A>
</LI></UL><UL><LI><A class="ext-link" href="http://files.lukeplant.fastmail.fm/public/tagfile.desktop"><SPAN class="icon">tagfile.desktop</SPAN></A> <BR>
Install into ~/.kde/share/apps/konqueror/servicemenus/
</LI></UL>

]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://lukeplant.me.uk/blog</uri>
    </author>
    <title type="html"><![CDATA[Gutsy woes]]></title>
    <link rel="alternate" type="text/html" href="http://lukeplant.me.uk/blog/posts/gutsy-woes/" />
    <id>http://lukeplant.me.uk/blog/posts/gutsy-woes/</id>
    <updated>2007-10-15T13:59:32Z</updated>
    <published>2007-10-15T13:59:32Z</published>
    <category scheme="http://lukeplant.me.uk/blog" term="KDE" />
    <category scheme="http://lukeplant.me.uk/blog" term="Rants" />
    <category scheme="http://lukeplant.me.uk/blog" term="Linux" />
    <summary type="html"><![CDATA[Gutsy woes]]></summary>
    <content type="html" xml:base="http://lukeplant.me.uk/blog/posts/gutsy-woes/"><![CDATA[
<p>I upgraded to Gutsy RC last week, and I've really had nothing but trouble,
and submitted lots of <a
href="https://bugs.launchpad.net/~l-plant-98">bugs</a> (which is what you
are supposed to do with a release candidate, but with only a few days left
to go, I'm wondering how many of these are really gonna get fixed in
time).  Some of these may be particularly related to Kubuntu/KDE, and some
might be due to not having a clean install, I don't know.</p>

<ul>
<li><a href="https://bugs.launchpad.net/ubuntu/+bug/152133">The upgrade
tool failed</a> -- in fact I've never <em>ever</em> had a 'dist-upgrade' go
smoothly, despite the advertising.  In my case after the tool failed, I had
to manually do 'aptitude dist-upgrade' <strong>3 times</strong> before
everything was finally sorted out.  Dist-upgrading is simply not for
novices.  I guess the problem is that people do it so infrequently, and test
cases are so massively time consuming to set up, that it is never properly
tested in the real world.</li>

<li>The <a
href="https://bugs.launchpad.net/ubuntu/+source/linux-restricted-modules-2.6.20/+bug/95956">Ubuntu-packaged
nVidia drivers disappear every time I reboot</a>.  It means I either have to
use the open source 'nv' driver (and no accelerated graphics), or X fails to
start and I have to manually reinstall a package.</li>

<li>Even when I get the nVidia drivers it working, I still have <a
href="https://bugs.launchpad.net/bugs/71913">X crashing on me
when using Compiz</a>.  It only happens when I'm doing lots of
things at once -- some changes in window activity at the same time as doing
something in the background that is disk and CPU intensive (e.g. installing
software).  But this is still unacceptable for a default option.</li>

<li>Compiz-fusion itself is quite nice (I've found a combination of plugins
that works very nicely, giving me a nicely animated 2x4 desktop, plus 'Expo'
and nice Alt-Tab mechanisms, with all my normal shortcuts for moving windows
around).  However, KDE integration is pretty bad -- whether I use the 'KDEWM'
environment setting to start Compiz, or put something in ~/.kde/Autostart, I
end up with lots of problems: <a
href="https://bugs.launchpad.net/ubuntu/+source/compiz/+bug/145878">the KDE window decorator dies
at startup</a>, and <a
href="https://bugs.launchpad.net/ubuntu/+source/compiz/+bug/129801">randomly dies at other times too</a>;
some windows that appear at startup, especially the prompt for the KDE
Wallet, don't actually ever appear; using KDEWM, the 'Alt-F1', 'Alt-F2' KDE
shortcuts don't work.  The only safe method I've found is to do a manual 'compiz
--replace' after my session is completely restored.</li>

<li><a href="https://bugs.launchpad.net/ubuntu/+bug/152325">KControl and
KInfoCenter were empty</a> -- thankfully the fix isn't too hard</li>

<li>My Input Actions (KHotkeys) were <a
href="https://bugs.launchpad.net/ubuntu/+source/meta-kde/+bug/152190">wiped
out</a> (thankfully the relevant config file was not emptied, and 
eventually by trial and error I found a workaround)</li>

<li><a
href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1778330&amp;group_id=954&amp;atid=100954">BibleTime
crashes when you change an option for module display</a>, which is a real
killer for me.</a>  It also <a href="https://sourceforge.net/tracker/index.php?func=detail&amp;aid=1778328&group_id=954&amp;atid=100954">crashes/fails when you try to add/change side-by-side Bible translations to a window</a>, which is equally painful.</ul>

<p>What's left of the advertised benefits of Kubuntu Gutsy?  Well, there is
Dolphin -- but I already had that before.  There is 'Restricted Drivers
Manager' -- great, except that it completely failed with the nVidia drivers
as described above.  There is a newer version of strigi, but is no better
than it has been in the past -- it is alpha quality software really (things like the daemon refusing to stop etc, dying randomly, and the interface being
extremely basic compared to Beagle.  Actually, it currently dies whenever I
tell it start indexing, so it is basically useless.  And this problem reoccurs after purging the indexes and starting again, after indexing about 300,000 documents).</p>

<p>Then there is GDebi, which is quite nice, but I'm not likely to use it
often.  Amarok 1.4.7 is included in Gutsy but I was using that anyway from
the backports repository (using <a
href="https://help.ubuntu.com/community/UbuntuBackports#head-0b2a1029f552e385c1af0dc485bf14bcc4ebd5bc">apt
pinning to ensure I only got the packages I deliberated upgraded</a>). There
is also the enterprise version of KDE PIM, which I imagine is quite good for
some people, but the only thing it brought me was a <a
href="https://bugs.launchpad.net/ubuntu/+source/kdepim/+bug/152883">bug in
which events are not updated in the calendar</a>.  Finally, the OpenOffice
suite has been updated to version 2.3, which may well have some genuine
improvements - I haven't used it enough to tell.</p>

<p>There was one really good thing -- 'Suspend' actually works on this
non-laptop computer, for the first time.  At least, it worked when using the
normal 'nv' video driver---it didn't with the nVidia driver.  I'm not
hopeful that it will even if I get nVidia drivers properly sorted out. 
Which means that I'll either be choosing between the ability to have 3D
accelerated graphics, and being able to suspend.</p>

<p>In conclusion --- there is nothing so far in Kubuntu Gutsy that I would
have upgraded for.  If the bugs above aren't fixed soon, then I would definitely
be far better off with Feisty, but I'm still hopeful that the guys at Ubuntu may
be able to get some of these sorted out.</p>

<p>UPDATE: Ubuntu 7.10 is upon us, and none of the above are addressed.  I'm wondering how difficult it is to downgrade...</p>

<p>UPDATE 2: Although nothing has really been addressed, I've discovered how to get <a href="https://help.ubuntu.com/community/NvidiaLaptopBinaryDriverSuspend">'Hibernate' and 'Suspend' working with nVidia drivers</a>.  Since I'm no longer rebooting, aand not even having to log in again, this has alleviated some of the problems.</p>

<p>UPDATE 3: Thanks to help on a bug report, I got my nVidia modules to stop disappearing, result!  Some genius also got BibleTime fixed up (had to compile from source, but it was worth it).  X crashing got worse -- twice in 10 minutes yesterday -- so I've abandoned it again until the bug is fixed.  But my system is basically all working now, and both Hibernate and Suspend now work perfectly, which is a real time/power saver, so I'm happy again :-)</p>

]]></content>
  </entry>
  <entry>
    <author>
      <name></name>
      <uri>http://lukeplant.me.uk/blog</uri>
    </author>
    <title type="html"><![CDATA[Fixing Facebook in Konqueror]]></title>
    <link rel="alternate" type="text/html" href="http://lukeplant.me.uk/blog/posts/fixing-facebook-in-konqueror/" />
    <id>http://lukeplant.me.uk/blog/posts/fixing-facebook-in-konqueror/</id>
    <updated>2007-09-02T21:29:38Z</updated>
    <published>2007-09-02T21:29:38Z</published>
    <category scheme="http://lukeplant.me.uk/blog" term="KDE" />
    <summary type="html"><![CDATA[Fixing Facebook in Konqueror]]></summary>
    <content type="html" xml:base="http://lukeplant.me.uk/blog/posts/fixing-facebook-in-konqueror/"><![CDATA[
<p>I got fed up waiting for Facebook to fix their website that <a href="http://lukeplant.me.uk/blog.php?id=1107301675"> recently broke in Konqueror</a>, so I did it myself.  I was correct in thinking that the problem was just this line of code:</p>

<pre>
delete Object.prototype.eval;
</pre>

<p>...which seems to serve no purpose in other browsers, but deletes the global 'eval' function in Konqueror (as you would expect from the ECMA 262, Edition 3 specification).  Konqueror doesn't have a GreaseMonkey equivalent (yet), so here is a quick summary of how to do an equivalent hack.</p>

<ul>
<li>Install <a href="http://www.privoxy.org/">privoxy</a>:
<pre class="shell">
wajig install privoxy
</pre>
(assumes you are using Debian/Ubuntu and have <a href="http://www.togaware.com/linux/survivor/Wajig_Packages.html">wajig</a> installed).<br/><br/>
<p>NB: Privoxy does all kinds of other web filtering by default.  If you don't like that, as I don't, just truncate the original config 'action' files:</p>
<pre class="shell">
cd /etc/privoxy/
sudo rm *.action
sudo touch global.action default.action standard.action user.action
</pre>
</li>

<li>Configure Konqueror to use 127.0.0.1, port 8118 as the HTTP proxy (use 'Manually specify the proxy settings' and press 'Setup').</li>
<li>Configure Privoxy to redirect one javascript file to a different version that removes the offending line of code, by adding the following lines to /etc/privoxy/user.action:
<pre>
{ +redirect{http://lukeplant.me.uk/privoxy/facebook/base.js} }
 static.ak.facebook.com/js/base.js
</pre>
<p>(of course, this will break as soon as Facebook update this file).</p>
<li>Check that privoxy and the redirect are working by going to: <br/><a href="http://config.privoxy.org/show-url-info?url=http%3A%2F%2Fstatic.ak.facebook.com%2Fjs%2Fbase.js">http://config.privoxy.org/show-url-info?url=http%3A%2F%2Fstatic.ak.facebook.com%2Fjs%2Fbase.js</a><br/>
You are looking for a line that says:<br/>
<b>+redirect {http://lukeplant.me.uk/privoxy/facebook/base.js}</b> <br/>

</li>
</ul>

<p>Assuming it all worked, you should now have a functional Facebook again! (I do, anyway)</p>

<p>For performance, in Konqueror configuration you can add 'static.ak.facebook.com' as the only domain to go through the proxy (you have to enable a check box and add the domain to a list, it's fairly obvious in the GUI).  You should do this <em>after</em> you have checked it is all working, as otherwise even the <b>config.privoxy.org</b> address that we used for checking won't be redirected to the proxy, and will instead go to a page on the real internet telling you that your privoxy setup isn't working.</p>

]]></content>
  </entry>
</feed>
