| CARVIEW |
Select Language
HTTP/2 200
server: nginx
date: Sat, 27 Dec 2025 16:21:47 GMT
content-type: text/xml
last-modified: Sun, 27 Apr 2025 09:51:47 GMT
etag: W/"680dfe33-7a292"
content-encoding: gzip
still don't have a title https://venthur.de/ 2025-01-12T16:00:00+01:00 Bastian Venthur's Blog Investigating the popularity of Python build backends over time (II) 2025-01-12T16:00:00+01:00 2025-01-12T16:00:00+01:00 Bastian Venthur tag:venthur.de,2025-01-12:/2025-01-12-build-backends.html Last year, I analyzed the popularity of build backends used in pyproject.toml files over time. This post is the update for 2024. <p><a href="2024-01-26-build-backends.html">Last year</a>, I analyzed the popularity of build backends used in
<code>pyproject.toml</code> files over time. This post is the update for 2024.</p>
<h2>Analysis</h2>
<p>Like last year, I’m using <a href="https://tomforb.es/">Tom Forbes’</a> fantastic <a href="https://py-code.org/datasets#metadata">dataset</a>
containing information about every file within every release uploaded to
<a href="https://pypi.org">PyPI</a>. To get the current dataset, I followed the <a href="https://github.com/venthur/pypi-analyze">same
process</a> as in <a href="2024-01-26-build-backends.html">last year’s analysis</a>, so I won’t repeat
all the details here. Instead, I’ll highlight the main steps:</p>
<ul>
<li>Download the parquet files from the <a href="https://py-code.org/datasets#metadata">dataset</a></li>
<li>Use <a href="https://duckdb.org/">DuckDB</a> to query the parquet files, extracting the project name,
upload date, the <code>pyproject.toml</code> file, and its hash for each upload</li>
<li>Download each <code>pyproject.toml</code> file and extract the build backend. To avoid
redundant downloads, I stored a mapping of the file hash and their respective
build backend</li>
</ul>
<p>Downloading all the parquet files took roughly a week due to <a href="https://github.com/">GitHub’s</a>
rate limiting. <a href="https://tomforb.es/">Tom</a> suggested leveraging the Git v2 protocol to
<a href="https://git-scm.com/docs/protocol-v2#_fetch">fetch</a> the data directly. This approach could bypass rate limiting and
complete the download of all <code>pyproject.toml</code> files in just 20 minutes(!).
However, I couldn’t find sufficient documentation that would help me to
implement this method, so this will have to wait until next year’s analysis.</p>
<p>Once all the data is downloaded, I perform some preprocessing:</p>
<ul>
<li>Grouped the top 4 build backends by their absolute number of uploads and
categorized the remaining ones as “other”</li>
<li>Binned upload dates into quarters to reduce clutter in the resulting graphs</li>
</ul>
<h2>Results</h2>
<p>I modified the plots a bit from last year to make them easier to read. Most
notably, I binned the data into quarters to make the plots less noisy, and
secondly, I stopped stacking the relative distribution plots to make the
percentages directly readable.</p>
<p>The first plot shows the absolute number of uploads (in thousands) by quarter
and build backend.</p>
<p><a href="images/2025-absolute.png"><img alt="Absolute distribution of build backends by quarter" src="images/2025-absolute.png" title="Absolute distribution of build backends by quarter"></a></p>
<p>The second plot shows the relative distribution of build backends by quarter.</p>
<p><a href="images/2025-relative.png"><img alt="Relative distribution of build backends by quarter" src="images/2025-relative.png" title="Relative distribution of build backends by quarter"></a></p>
<p>In 2024, we observe that:</p>
<ul>
<li><a href="https://setuptools.pypa.io/">Setuptools</a> continues to grow in absolute numbers and remains around the
50% mark in relative distribution</li>
<li><a href="https://python-poetry.org/">Poetry</a> maintains a 30% relative distribution, but the trend has been
declining since 2024-Q3. Preliminary data for 2025-Q1 (not shown here)
supports this, suggesting that Poetry might be surpassed by <a href="https://hatch.pypa.io/">Hatch</a> in
2025, which showed a remarkable growth last year.</li>
<li><a href="https://flit.pypa.io/">Flit</a> is the only build backend in this analysis whose absolute and
relative numbers decreased in 2024. With a 5% relative distribution, it
underlines the dominance of Setuptools, Poetry, and Hatch over the remaining
build backends.</li>
</ul>
<p>The script for downloading and analyzing the data is available in my <a href="https://github.com/venthur/pypi-analyze">GitHub
repository</a>. If someone has insights or examples on implementing
the Git v2 protocol to download the <code>pyproject.toml</code> file given the repository
URL and its hash, I’d love to hear from you!</p> New python-debianbts in experimental 2024-05-08T15:00:00+02:00 2024-05-08T15:00:00+02:00 Bastian Venthur tag:venthur.de,2024-05-08:/2024-05-08-new-python-debianbts-in-experimental.html Thanks to Peter De Wachter, python-debianbts no longer depends on an external SOAP library <p><a href="2024-04-20-wsdl-for-debbugs.html">Last month</a>, I asked for help migrating <a href="https://github.com/venthur/python-debianbts">python-debianbts</a> to zeep, a
SOAP library that would replace the now unmaintained pysimplesoap. The main
blocker was the lack of a proper WSDL file provided by Debian’s BTS software,
debbugs.</p>
<p><strong>Peter De Wachter</strong> pointed out other issues with debbugs’ SOAP implementation
and provided a <a href="https://github.com/venthur/python-debianbts/pull/60">patch</a> that solves the whole issue by removing the dependency
on an external SOAP library altogether by implementing the required bits of the
SOAP protocol directly in python-debianbts. The new version is completely
backwards compatible, and the test suites of python-debianbts <strong>and</strong> reportbug
are still passing.</p>
<p>Apparently, while working on this patch, Peter also uncovered an issue with the
type hints defined in Python’s <code>xml.etree</code> module, for which he also provided a
<a href="https://github.com/python/typeshed/pull/11841">patch</a>. Really great work!</p>
<p>I’ve uploaded the new version to Debian/experimental for now to get some
exposure and feedback, before uploading it to unstable.</p>
<p>Peter, thank you very much for your support, I really appreciate it!</p> Help needed: creating a WSDL file to interact with debbugs 2024-04-20T14:00:00+02:00 2024-04-20T14:00:00+02:00 Bastian Venthur tag:venthur.de,2024-04-20:/2024-04-20-wsdl-for-debbugs.html I need help from someone with experience in SOAP and debbugs to create a WSDL file for Debian's Bug Tracking System <p>I am upstream and <a href="https://packages.debian.org/sid/python3-debianbts">Debian package</a> maintainer of
<a href="https://github.com/venthur/python-debianbts">python-debianbts</a>, which is a Python library that allows for
querying Debian’s Bug Tracking System (BTS). python-debianbts is used by
reportbug, the standard tool to report bugs in Debian, and therefore the glue
between the reportbug and the BTS.</p>
<p><a href="https://en.wikipedia.org/wiki/Debbugs">debbugs</a>, the software that powers Debian’s BTS, provides a <a href="https://en.wikipedia.org/wiki/SOAP">SOAP</a>
interface for querying the BTS. Unfortunately, SOAP is not a very popular
protocol anymore, and I’m facing the second migration to another underlying
SOAP library as they continue to become unmaintained over time. <a href="https://github.com/mvantellingen/python-zeep">Zeep</a>, the
library I’m currently considering, requires a <a href="https://en.wikipedia.org/wiki/Web_Services_Description_Language">WSDL</a> file in order to work
with a SOAP service, however, debbugs does not provide one. Since I’m not
familiar with WSDL, I need help from someone who can create a WSDL file for
debbugs, so I can migrate python-debianbts away from <a href="https://github.com/pysimplesoap/pysimplesoap">pysimplesoap</a> to zeep.</p>
<h2>How did we get here?</h2>
<p>Back in the olden days, reportbug was querying the BTS by <a href="2007-03-01-decoupling-presentation-from-logic.html">parsing its HTML
output</a>. While this worked, it tightly coupled the user-facing
presentation of the BTS with critical functionality of the bug reporting tool.
The setup was fragile, prone to breakage, and did not allow changing anything
in the BTS frontend for fear of breaking reportbug itself.</p>
<p>In 2007, I started to work on <a href="2007-03-07-a-screencast-is-worth-a-thousand-pictures.html">reportbug-ng</a>, a user-friendly alternative
to reportbug, targeted at users not comfortable using the command line. Early
on, I decided to use the BTS’ SOAP interface instead of parsing HTML like
reportbug did. 2008, I extracted the code that dealt with the BTS into a
separate Python library, and after some collaboration with the reportbug
maintainers, reportbug adopted python-debianbts in 2011 and has used it ever
since.</p>
<p>2015, I was working on <a href="2015-08-18-please-help-to-port-python-debianbts-to-python3.html">porting python-debianbts to Python 3</a>.
During that process, it turned out that its major dependency, SoapPy was pretty
much unmaintained for years and blocking the Python3 transition. <a href="2015-10-13-thanks.html">Thanks to the
help of Gaetano Guerriero</a>, who ported python-debianbts to
pysimplesoap, the migration was unblocked and could proceed.</p>
<p>In 2024, almost ten years later, pysimplesoap seems to be unmaintained as well,
and I have to look again for alternatives. The most promising one right now
seems to be <a href="https://github.com/mvantellingen/python-zeep">zeep</a>. Unfortunately, zeep requires a WSDL file for working with
a SOAP service, which debbugs does not provide.</p>
<h2>How can you help?</h2>
<p>reportbug (and thus python-debianbts) is used by thousands of users and I have
a certain responsibility to keep things working properly. Since I simply don’t
know enough about WSDL to create such a file for debbugs myself, I’m looking
for someone who can help me with this task.</p>
<p>If you’re familiar with SOAP, WSDL and optionally debbugs, please <a href="mailto:venthur@debian.org">get in
touch</a> with me. I don’t speak Pearl, so I’m not
really able to read debbugs code, but I do know some things about the SOAP
requests and replies due to my work on python-debianbts, so I’m sure we can
work something out.</p>
<p>There is a <a href="https://git.savannah.gnu.org/cgit/emacs/elpa.git/plain/Debbugs.wsdl?h=externals/debbugs">WSDL file</a> for a debbugs version used by <a href="https://www.gnu.org/">GNU</a>, but I
don’t think it’s official and it currently does not work with zeep. It may be a
good starting point, though.</p>
<h2>The future of debbugs’ API</h2>
<p>While we can probably continue to support debbugs’ SOAP interface for a while,
I don’t think it’s very sustainable in the long run. A simpler, well documented
REST API that returns JSON seems more appropriate nowadays. The queries and
replies that debbugs currently supports are simple enough to design a REST API
with JSON around it. The benefit would be less complex libraries on the client
side and probably easier maintainability on the server side as well. debbugs’
maintainer seemed to be in agreement with this idea <a href="https://lists.debian.org/debian-debbugs/2018/12/msg00001.html">back in
2018</a>. I created an attempt to define a <a href="https://github.com/venthur/debbugs-proposal/blob/master/yaml-unresolved/swagger.yaml">new API</a>
(<a href="https://app.swaggerhub.com/apis-docs/venthur/debbugs/1.0.0">HTML render</a>), but somehow we got stuck and no progress has been
made since then. I’m still happy to help shaping such an API for debbugs, but I
can’t really implement anything in debbugs itself, as it is written in Perl,
which I’m not familiar with.</p> Investigating popularity of Python build backends over time 2024-01-26T19:00:00+01:00 2024-01-26T19:00:00+01:00 Bastian Venthur tag:venthur.de,2024-01-26:/2024-01-26-build-backends.html Inspired by a Mastodon post, I wanted to investigate how the popularity of build backends used in pyproject.toml files evolved since the introduction of PEP-0517 in 2015. <p>Inspired by a <a href="https://framapiaf.org/@fcodvpt/111533565837454708">Mastodon
post</a> by Françoise Conil,
who investigated the current popularity of build backends used in
<code>pyproject.toml</code> files, I wanted to investigate how the popularity of build
backends used in <code>pyproject.toml</code> files evolved over the years since the
introduction of <a href="https://peps.python.org/pep-0517/">PEP-0517</a> in 2015.</p>
<h2>Getting the data</h2>
<p><a href="https://tomforb.es/">Tom Forbes</a> provides a huge
<a href="https://py-code.org/datasets#metadata">dataset</a> that contains information
about every file within every release uploaded to <a href="https://pypi.org">PyPI</a>. To
get the current dataset, we can use:</p>
<div class="codehilite"><pre><span></span><code>curl<span class="w"> </span>-L<span class="w"> </span>--remote-name-all<span class="w"> </span><span class="k">$(</span>curl<span class="w"> </span>-L<span class="w"> </span><span class="s2">"https://github.com/pypi-data/data/raw/main/links/dataset.txt"</span><span class="k">)</span>
</code></pre></div>
<p>This will download approximately 30GB of parquet files, providing detailed
information about each file included in a PyPI upload, including:</p>
<ol>
<li>project name, version and release date</li>
<li>file path, size and line count</li>
<li>hash of the file</li>
</ol>
<p>The dataset does not contain the actual files themselves though, more on that
in a moment.</p>
<h2>Querying the dataset using duckdb</h2>
<p>We can now use <a href="https://duckdb.org/">duckdb</a> to query the parquet files directly. Let’s look into
the schema first:</p>
<div class="codehilite"><pre><span></span><code><span class="k">describe</span><span class="w"> </span><span class="k">select</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">from</span><span class="w"> </span><span class="s1">'*.parquet'</span><span class="p">;</span>
<span class="err">┌─────────────────┬─────────────┬─────────┐</span>
<span class="err">│</span><span class="w"> </span><span class="k">column_name</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="n">column_type</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="k">null</span><span class="w"> </span><span class="err">│</span>
<span class="err">│</span><span class="w"> </span><span class="nb">varchar</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="nb">varchar</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="nb">varchar</span><span class="w"> </span><span class="err">│</span>
<span class="err">├─────────────────┼─────────────┼─────────┤</span>
<span class="err">│</span><span class="w"> </span><span class="n">project_name</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="nb">VARCHAR</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="n">YES</span><span class="w"> </span><span class="err">│</span>
<span class="err">│</span><span class="w"> </span><span class="n">project_version</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="nb">VARCHAR</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="n">YES</span><span class="w"> </span><span class="err">│</span>
<span class="err">│</span><span class="w"> </span><span class="n">project_release</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="nb">VARCHAR</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="n">YES</span><span class="w"> </span><span class="err">│</span>
<span class="err">│</span><span class="w"> </span><span class="n">uploaded_on</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="k">TIMESTAMP</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="n">YES</span><span class="w"> </span><span class="err">│</span>
<span class="err">│</span><span class="w"> </span><span class="n">path</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="nb">VARCHAR</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="n">YES</span><span class="w"> </span><span class="err">│</span>
<span class="err">│</span><span class="w"> </span><span class="n">archive_path</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="nb">VARCHAR</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="n">YES</span><span class="w"> </span><span class="err">│</span>
<span class="err">│</span><span class="w"> </span><span class="k">size</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="n">UBIGINT</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="n">YES</span><span class="w"> </span><span class="err">│</span>
<span class="err">│</span><span class="w"> </span><span class="n">hash</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="nb">BLOB</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="n">YES</span><span class="w"> </span><span class="err">│</span>
<span class="err">│</span><span class="w"> </span><span class="n">skip_reason</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="nb">VARCHAR</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="n">YES</span><span class="w"> </span><span class="err">│</span>
<span class="err">│</span><span class="w"> </span><span class="n">lines</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="n">UBIGINT</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="n">YES</span><span class="w"> </span><span class="err">│</span>
<span class="err">│</span><span class="w"> </span><span class="n">repository</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="n">UINTEGER</span><span class="w"> </span><span class="err">│</span><span class="w"> </span><span class="n">YES</span><span class="w"> </span><span class="err">│</span>
<span class="err">├─────────────────┴─────────────┴─────────┤</span>
<span class="err">│</span><span class="w"> </span><span class="mi">11</span><span class="w"> </span><span class="k">rows</span><span class="w"> </span><span class="mi">6</span><span class="w"> </span><span class="n">columns</span><span class="w"> </span><span class="err">│</span>
<span class="err">└─────────────────────────────────────────┘</span>
</code></pre></div>
<p>From all files mentioned in the dataset, we only care about <code>pyproject.toml</code>
files that are in the project’s root directory. Since we’ll still have to
download the actual files, we need to get the <code>path</code> and the <code>repository</code> to
construct the corresponding URL to the mirror that contains all files in a
bunch of huge git repositories. Some files are not available on the mirrors; to
skip these, we only take files where the <code>skip_reason</code> is empty. We also care
about the timestamp of the upload (<code>uploaded_on</code>) and the <code>hash</code> to avoid
processing identical files twice:</p>
<div class="codehilite"><pre><span></span><code><span class="k">select</span>
<span class="w"> </span><span class="n">path</span><span class="p">,</span>
<span class="w"> </span><span class="n">hash</span><span class="p">,</span>
<span class="w"> </span><span class="n">uploaded_on</span><span class="p">,</span>
<span class="w"> </span><span class="n">repository</span>
<span class="k">from</span><span class="w"> </span><span class="s1">'*.parquet'</span>
<span class="k">where</span>
<span class="w"> </span><span class="n">skip_reason</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="s1">''</span><span class="w"> </span><span class="k">and</span>
<span class="w"> </span><span class="k">lower</span><span class="p">(</span><span class="n">string_split</span><span class="p">(</span><span class="n">path</span><span class="p">,</span><span class="w"> </span><span class="s1">'/'</span><span class="p">)[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="s1">'pyproject.toml'</span><span class="w"> </span><span class="k">and</span>
<span class="w"> </span><span class="n">len</span><span class="p">(</span><span class="n">string_split</span><span class="p">(</span><span class="n">path</span><span class="p">,</span><span class="w"> </span><span class="s1">'/'</span><span class="p">))</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">5</span>
<span class="k">order</span><span class="w"> </span><span class="k">by</span><span class="w"> </span><span class="n">uploaded_on</span><span class="w"> </span><span class="k">desc</span>
</code></pre></div>
<p>This query runs for a few minutes on my laptop and returns ~1.2M rows.</p>
<h2>Getting the actual files</h2>
<p>Using the <code>repository</code> and <code>path</code>, we can now construct an URL from which we
can fetch the actual file for further processing:</p>
<div class="codehilite"><pre><span></span><code><span class="n">url</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"https://raw.githubusercontent.com/pypi-data/pypi-mirror-</span><span class="si">{</span><span class="n">repository</span><span class="si">}</span><span class="s2">/code/</span><span class="si">{</span><span class="n">path</span><span class="si">}</span><span class="s2">"</span>
</code></pre></div>
<p>We can download the individual <code>pyproject.toml</code> files and parse them to read
the <code>build-backend</code> into a dictionary mapping the file-<code>hash</code> to the build
backend. Downloads on <a href="https://github.com/">GitHub</a> are rate-limited, so downloading 1.2M files
will take a couple of days. By skipping files with a hash we’ve already
processed, we can avoid downloading the same file more than once, cutting the
required downloads by circa 50%.</p>
<h2>Results</h2>
<p>Assuming the data is complete and my analysis is sound, these are the findings:</p>
<p>There is a surprising amount of build backends in use, but the overall amount
of uploads per build backend decreases quickly, with a long tail of single
uploads:</p>
<div class="codehilite"><pre><span></span><code><span class="o">>>></span> <span class="n">results</span><span class="o">.</span><span class="n">backend</span><span class="o">.</span><span class="n">value_counts</span><span class="p">()</span>
<span class="n">backend</span>
<span class="n">setuptools</span> <span class="mi">701550</span>
<span class="n">poetry</span> <span class="mi">380830</span>
<span class="n">hatchling</span> <span class="mi">56917</span>
<span class="n">flit</span> <span class="mi">36223</span>
<span class="n">pdm</span> <span class="mi">11437</span>
<span class="n">maturin</span> <span class="mi">9796</span>
<span class="n">jupyter</span> <span class="mi">1707</span>
<span class="n">mesonpy</span> <span class="mi">625</span>
<span class="n">scikit</span> <span class="mi">556</span>
<span class="o">...</span>
<span class="n">postry</span> <span class="mi">1</span>
<span class="n">tree</span> <span class="mi">1</span>
<span class="n">setuptoos</span> <span class="mi">1</span>
<span class="n">neuron</span> <span class="mi">1</span>
<span class="n">avalon</span> <span class="mi">1</span>
<span class="n">maturimaturinn</span> <span class="mi">1</span>
<span class="n">jsonpath</span> <span class="mi">1</span>
<span class="n">ha</span> <span class="mi">1</span>
<span class="n">pyo3</span> <span class="mi">1</span>
<span class="n">Name</span><span class="p">:</span> <span class="n">count</span><span class="p">,</span> <span class="n">Length</span><span class="p">:</span> <span class="mi">73</span><span class="p">,</span> <span class="n">dtype</span><span class="p">:</span> <span class="n">int64</span>
</code></pre></div>
<p>We pick only the top 4 build backends, and group the remaining ones (including
<a href="https://pdm-project.org/latest/">PDM</a> and <a href="https://www.maturin.rs/">Maturin</a>) into “other” so they are accounted for as well.</p>
<p>The following plot shows the relative distribution of build backends over time.
Each bin represents a time span of 28 days. I chose 28 days to reduce visual
clutter. Within each bin, the height of the bars corresponds to the relative
proportion of uploads during that time interval:</p>
<p><a href="images/2024-relative.png"><img alt="Relative distribution of build backends over time" src="images/2024-relative.png" title="Relative distribution of build backends over time"></a></p>
<p>Looking at the right side of the plot, we see the current distribution. It
confirms Françoise’s findings about the <strong>current</strong> popularity of build
backends:</p>
<ul>
<li>Setuptools: ~50%</li>
<li>Poetry: ~33%</li>
<li>Hatch: ~10%</li>
<li>Flit: ~3%</li>
<li>Other: ~4%</li>
</ul>
<p>Between 2018 and 2020 the graph exhibits significant fluctuations, due to the
relatively low amount uploads utizing <code>pyproject.toml</code> files. During that early
period, <a href="https://flit.pypa.io/">Flit</a> started as the most popular build backend, but was eventually
displaced by <a href="https://setuptools.pypa.io/">Setuptools</a> and <a href="https://python-poetry.org/">Poetry</a>.</p>
<p>Between 2020 and 2020, the overall usage of <code>pyproject.toml</code> files increased
significantly. By the end of 2022, the share of <a href="https://setuptools.pypa.io/">Setuptools</a> peaked at 70%.</p>
<p>After 2020, other build backends experienced a gradual rise in popularity.
Amongh these, <a href="https://hatch.pypa.io/">Hatch</a> emerged as a notable contender, steadily gaining
traction and ultimately stabilizing at 10%.</p>
<p>We can also look into the absolute distribution of build backends over time:</p>
<p><a href="images/2024-absolute.png"><img alt="Absolute distribution of build backends over time" src="images/2024-absolute.png" title="Absolute distribution of build backends over time"></a></p>
<p>The plot shows that Setuptools has the strongest growth trajectory, surpassing
all other build backends. Poetry and Hatch are growing at a comparable rate,
but since Hatch started roughly 4 years after Poetry, it’s lagging behind in
popularity. Despite not being among the most widely used backends anymore, Flit
maintains a steady and consistent growth pattern, indicating its enduring
relevance in the Python packaging landscape.</p>
<p>The script for downloading and analyzing the data can be found in my <a href="https://github.com/venthur/pypi-analyze">GitHub
repository</a>. It contains the results of the duckb query (so you
don’t have to download the full dataset) and the pickled dictionary, mapping
the file hashes to the build backends, saving you days for downloading and
analyzing the <code>pyproject.toml</code> files yourself.</p> dotenv-cli update 2023-07-01T15:00:00+02:00 2023-07-01T15:00:00+02:00 Bastian Venthur tag:venthur.de,2023-07-01:/2023-07-01-dotenv-cli-update.html dotenv-cli now ues exec on POSIX systems to create new processes <p>Thanks to <a href="https://github.com/venthur/dotenv-cli/pull/31">Nicholas Guriev</a>,
<a href="https://github.com/venthur/dotenv-cli">dotenv-cli</a> now uses <code>exec</code> instead of <code>popen</code> to create the new process on
<code>POSIX</code> systems.</p>
<p>As a <a href="2019-05-12-dotenv-cli.html">refresher</a>, dotenv-cli is a package that
provides the <code>dotenv</code> command. <code>dotenv</code> reads the <code>.env</code> file from the current
directory, puts the contents in the environment variables, and executes the
given command with the extra environment variables set.</p>
<p><code>dotenv</code> comes in handy if you follow the <a href="https://12factor.net/config">12 factor app</a>
methodology or just need to run a program locally with specific environment
variables set.</p>
<p>With this new change, when you call </p>
<div class="codehilite"><pre><span></span><code>dotenv<span class="w"> </span>my_awesome_tool
</code></pre></div>
<p>instead of forking a new process for <code>my_awesome_tool</code>, effectively creating a
child process of <code>dotenv</code>, <code>dotenv</code> now uses <code>exec</code> to “become” the new
process. This is a bit cleaner, as there is no longer a <code>dotenv</code>-process
running that you don’t actually care about, and less-error prone when trying to
send signals such as <code>SIGTERM</code> to the processes that runs <code>my_awesome_tool</code>.</p>
<p>Unfortunately, <code>exec</code> does not work properly under Windows, so here we still
fall back to using <code>popen</code>.</p>
<p>This new feature is available in version 3.2.0 which is available on <a href="https://pypi.org/project/dotenv-cli/">PyPI</a>
and <a href="https://packages.debian.org/sid/python3-dotenv-cli">debian/unstable</a>.</p> Blag 2.0 released 2023-06-17T16:00:00+02:00 2023-06-17T16:00:00+02:00 Bastian Venthur tag:venthur.de,2023-06-17:/2023-06-17-blag.html I released a major update on blag, which introduces a few backwards incompatible changes and many improvements. <p>A few days ago, I released a major update on <a href="https://github.com/venthur/blag">blag</a>, my blog-aware
static-site generator, which introduces a few backwards-incompatible changes
and many improvements over the old version.</p>
<h2>Good-looking default theme</h2>
<p>The old bare-bones default theme has been replaced with a good-looking one,
based on the one used on <a href="https://venthur.de">this blog</a>:</p>
<p><img alt="Blag Screenshot" src="images/blag.png"></p>
<p>It comes with a light- and dark theme that switches automatically based on the
browser setting, as well as fitting light- and dark syntax highlighting themes
for code blocks.</p>
<h2>Improved <code>quickstart</code></h2>
<p>The <code>blag quickstart</code> command has been improved. Additionally to generating the
configuration, it now also populates the working directory with the
<code>templates</code>-, <code>static</code>- and <code>content</code> directories, containing the updated
default theme and a few content pages to get you started.</p>
<h2>No internal fallback templates anymore</h2>
<p>Related to the changes in <code>quickstart</code>, the internal fallback template has been
removed, and blag now completely relies on the templates in the local
<code>templates</code> directory. This makes it more transparent for the user what is
happening while simplifying blag’s internal logic.</p>
<p>However, this is a backwards incompatible change! In the case of a missing
template, the user will be warned with a hint on how to obtain the missing
template.</p>
<h2>Index and archive are now separate</h2>
<p>Previously, the front-page would always show the archive of <strong>all</strong> articles.
This is not very useful when your blog contains more than a few dozen articles.
With blag 2.0, the previous <code>archive</code> has been split into <code>index</code> and
<code>archive</code>, where <code>index</code> is the front-page showing only the most recent 15
articles by default and linking to the <code>archive</code> which shows all articles.
There’s also two corresponding templates in the <code>templates</code> directory.</p>
<h2>Miscellaneous</h2>
<ul>
<li>Various dependencies have been updated.</li>
<li>blag’s <a href="https://blag.readthedocs.io">documentation</a> has been migrated from <a href="https://www.sphinx-doc.org/">Sphinx</a> to <a href="https://www.mkdocs.org/">MkDocs</a>,
which is a bit more lightweight and easier to maintain</li>
<li>A packaging <a href="https://github.com/venthur/blag/issues/103">issue</a> has been fixed, where the <code>tests/conftest.py</code> was
missing in the source distribution</li>
</ul>
<p>Blag 2.0 is available on <a href="https://pypi.org/project/blag/">pypi</a>, <a href="https://packages.debian.org/sid/blag">debian/unstable</a> and <a href="https://github.com/venthur/blag">github</a></p> The State of Python Packaging in 2022 2022-12-18T20:00:00+01:00 2022-12-18T20:00:00+01:00 Bastian Venthur tag:venthur.de,2022-12-18:/2022-12-18-python-packaging.html Every year, I revisit the current best practices for Python packaging. This is my summary for 2022. <p>Every year or so, I revisit the current best practices for Python packaging.
<a href="2021-06-26-python-packaging.html">This</a> was my summary for 2021 – here’s the update for 2022.</p>
<h2>PyPA</h2>
<p><a href="https://www.pypa.io/en/latest/">PyPA</a> is still the place to go for information, best practices and tutorials
for packaging Python projects. My only criticism from last year, namely that
PyPA was heavily biased towards their own tooling (e.g. <code>pipenv</code>), has been
addressed: the <a href="https://packaging.python.org/guides/tool-recommendations">tool recommendations</a> section lists now several tools
for the same purpose with their own ones not necessarily being the first
anymore.</p>
<h2>setup.py, setup.cfg, requirements.txt, Pipfile, pyproject.toml – oh my!</h2>
<p>This is the reason why I’m revisiting the documentation every year, to see
what’s the current way to go. Good progress has been made since last year:</p>
<h3>Bye setup.py and setup.cfg – hello pyproject.toml</h3>
<p><code>pyproject.toml</code> finally got mature enough to replace <code>setup.py</code> and
<code>setup.cfg</code> in most cases. Recent versions of <code>setuptools</code> and <code>pip</code> now fully
support <code>pyproject.toml</code> and even PyPA’s packaging tutorial completely switched
their example project from away <code>setup.py</code> towards <code>pyproject.toml</code>, making it
an official recommendation.</p>
<p>So, now you can replace your <code>setup.py</code> with <code>pyproject.toml</code>. If you had
already some kind of declarative configuration in <code>setup.cfg</code> you can move that
as well into <code>pyproject.toml</code>. Most tools, like <code>pypy</code> or <code>pytest</code> also support
configuration in <code>pyproject.toml</code> (flake8 being a notable exception…) so
there’s no reason to keep <code>setup.cfg</code> around anymore. Actually, if you migrate
to <code>pyproject.toml</code> it is best to do it properly and remove <code>setup.py</code> and
<code>setup.cfg</code> as <code>setuptools</code> behaves a bit buggy when building a package that
has either of them and the <code>pyproject.toml</code>.</p>
<h3>requirements.txt</h3>
<p><code>requirements.txt</code> are still needed if you develop a “deployable” application
(vs. a library) and want to provide <em>pinned</em> dependencies, i.e. with the
specific versions that you’ve tested your application with. Usually, the list
of requirements in <code>requirements.txt</code> is the same as defined in
<code>pyproject.toml</code>, but with pinned versions.</p>
<h3>Pipfile + Pipfile.lock</h3>
<p>I still do completely ignore <code>Pipfile</code> and <code>Pipfile.lock</code> as they are only
supported by <code>pipenv</code> and not backed by any standard.</p>
<h2>Summary</h2>
<p>The major change this year was the proper support of <code>pyproject.toml</code>. I am
slowly replacing all <code>setup.py</code> and <code>setup.cfg</code> in my projects with
<code>pyproject.toml</code> and haven’t discovered any issues yet. Even packaging those
packages as Debian packages is well-supported by Debian’s tooling.</p>
<p>I’m still running a quite boring stack based on <code>pyproject.toml</code> and
<code>requirements.txt</code>, ignoring more advanced tools like <code>poetry</code> or such for
dependency management. My build-system defined in <code>pyproject.toml</code> requires
<code>setuptools</code> and I’m using <a href="https://github.com/pypa/build">build</a> for building and <a href="https://github.com/pypa/twine">twine</a> for uploading.</p>
<p>Since PyPA changed the packaging tutorial towards <code>pyproject.toml</code> and away
from <code>setup.py</code>, I think we will slowly see <code>setup.py</code> and <code>setup.cfg</code> go away
over the years. Speaking of PyPA, I’m happy that they changed their attitude
towards a more unbiased recommendation of tooling.</p> Mastodon 2022-11-12T17:00:00+01:00 2022-11-12T17:00:00+01:00 Bastian Venthur tag:venthur.de,2022-11-12:/2022-11-12-mastodon.html Due to recent events around Twitter, I finally decided to give Mastodon a try. <p>Due to recent events around Twitter, I finally decided to give <a href="https://joinmastodon.org">Mastodon</a> a
try. Naturally, I find the idea of an open and decentralized platform much more
appealing than the privately owned walled gardens that became so hugely popular
in the past two decades. I’m curious whether Mastodon can keep up the momentum
of the last two weeks and eventually establish itself as an alternative to
Twitter. On that note, I think it will be interesting to see how well
moderation of hate speech etc. works- and scales on Mastodon. I believe that
Twitter, Facebook and the likes, spend a significant amount of resources on
content moderation, so this may become a huge headache for Mastodon instance
admins when it gets more popular.</p>
<h3>Choosing an Instance</h3>
<p>For no particular reason, I went with the <a href="https://mastodon.social">mastodon.social</a> instance, so my
handle is <a href="https://mastodon.social/@venthur">@venthur@mastodon.social</a>. After my first steps, I realized that
choosing the instance <em>does</em> have an impact, particularly if you follow the
local timeline. <a href="https://mastodon.social">mastodon.social</a> is currently one of the biggest instances
and therefore the local timeline is <em>very</em> busy and the topics naturally very
random. Maybe I’ll try out a more specialized instance such as <a href="https://fosstodon.org/about">fosstodon</a> at
some point – one of the awesome features of Mastodon is that it actually
supports the migration of accounts between instances!</p>
<p>I wonder if there are plans to have an official Debian instance?</p>
<h3>First Impressions</h3>
<p>So far I’m quite happy with Mastodon. There’s good quality content and I
already found a few people that I was following on Twitter here on Mastodon
too. Interestingly, some of them actually are more active on Mastodon than on
Twitter. But truth to be told: many of them do cross-post on both mediums, and
most of the people I follow on Twitter are not on Mastodon yet.</p>
<p>I do like the concepts of the local- and federated timelines, although they are
quite busy.</p>
<p>I like that you can set the language of your (individual) toots which allows
users to filter their timelines for languages. In practice, this does not work
so well yet, and I still see a lot of different languages in my local and
federated timelines. I assume the problem is that people just forget to set the
language of their toots so the default language is used. This problem should be
easily solvable in the frontend by “guessing” the language once a few words
have been typed.</p>
<p>I also like the idea that you can follow hashtags, although for me the results
were mixed. I tried to follow <code>#debian</code> and <code>#python</code> and got a <em>lot</em> of toots
that were not really relevant for me in the case of <code>#python</code> I got quite
spammed with job ads so I had to unfollow it again.</p>
<p>Unfollwing a hashtag is not very intuitive, as the tags are not in your list of
people you follow, so you have to find the page of the hashtag itself (e.g.
<a href="https://mastodon.social/tags/debian">#debian</a>) and unfollow from there.</p>
<p>You see, there are some rough edges here and there, but I find the overall
experience much more enjoyable than Twitter.</p>
<h3>Debian Folks in the Fediverse?</h3>
<p>Which brings me to: are there any Debian Developers or -Maintainers out there
to follow in the <a href="https://en.wikipedia.org/wiki/Fediverse">fediverse</a>? I found most of the ones I’m following on
Twitter, but I’m sure there’s more hiding out there.</p> Keychron keyboards fixed on Linux 2022-08-01T22:00:00+02:00 2022-08-01T22:00:00+02:00 Bastian Venthur tag:venthur.de,2022-08-01:/2022-08-01-keychron-keyboards-fixed-on-linux.html Since Linux 5.19, the Function keys of Keychron keyboards are finally working out of the box. <p><a href="2021-04-30-keychron-c1-on-linux.html">Last year</a>, I wrote about on how to get my
buggy Keychron C1 keyboard working properly on Linux by setting a kernel module
parameter. Afterwards, I <a href="https://lore.kernel.org/all/f82dd7a1-a5c6-b651-846c-29f6df9436af@redhat.com/">contacted</a> Hans de Goede since he was the last
one that contributed a major patch to the relevant kernel module. After some
debugging, it turned out that the Keychron keyboards are indeed misbehaving
when set to Windows mode. Almost a year later, <a href="https://lore.kernel.org/all/20220505191221.36172-2-bryancain3@gmail.com/">Bryan Cain</a> provided a
patch fixing the behavior, which has now been <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/diff/drivers/hid/hid-apple.c?id=v5.19&id2=v5.18">merged</a> to the Linux kernel in
5.19.</p>
<p>Thank you, Hans and Bryan!</p> blag is now available in Debian 2022-06-18T18:00:00+02:00 2022-06-18T18:00:00+02:00 Bastian Venthur tag:venthur.de,2022-06-18:/2022-06-18-blag-in-debian.html After a year I finally got around creating a Debian package for blag. <p><a href="2021-03-24-blogging.html">Last year</a>, I wrote my own blog-aware static site generator in
Python. I called it “<a href="https://github.com/venthur/blag">blag</a>” – named after the <a href="https://blog.xkcd.com/">blag</a> of the
webcomic xkcd. Now I finally got around packaging- and uploading blag to
Debian. It passed the <a href="https://ftp-master.debian.org/new.html">NEW queue</a> and is now part of the distribution. That
means if you’re using Debian, you can install it via:</p>
<div class="codehilite"><pre><span></span><code>sudo<span class="w"> </span>aptitude<span class="w"> </span>install<span class="w"> </span>blag
</code></pre></div>
<p>Ubuntu will probably follow soon. For every other system, blag is also
<a href="https://pypi.org/project/blag/">available on PyPI</a>:</p>
<div class="codehilite"><pre><span></span><code>pip<span class="w"> </span>install<span class="w"> </span>blag
</code></pre></div>
<p>To get started, you can</p>
<div class="codehilite"><pre><span></span><code>mkdir<span class="w"> </span>blog<span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nb">cd</span><span class="w"> </span>blog
blag<span class="w"> </span>quickstart<span class="w"> </span><span class="c1"># fill out some info</span>
nvim<span class="w"> </span>content/hello-world.md<span class="w"> </span><span class="c1"># write some content</span>
blag<span class="w"> </span>build<span class="w"> </span><span class="c1"># build the website</span>
</code></pre></div>
<p>Blag is aware of <strong>articles</strong> and <strong>pages</strong>: the difference is that articles
are part of the blog and will be added to the atom feed, the archive and
aggregated in the tag pages. Pages are just rendered out to HTML. Articles and
pages can be freely mixed in the <code>content</code> directory, what differentiates an
article from a page is the existence of the <code>dade</code> metadata element:</p>
<div class="codehilite"><pre><span></span><code>title: My first article
description: Short description of the article
date: 2022-06-18 23:00
tags: blogging, markdown
<span class="gu">## Hello World!</span>
Lorem ipsum.
[...]
</code></pre></div>
<p>blag also comes with a dev-server that rebuilds the website automatically on
every change detected, you can start it using:</p>
<div class="codehilite"><pre><span></span><code>blag<span class="w"> </span>serve
</code></pre></div>
<p>The default theme looks quite ugly, and you probably want to create your own
styling to make it more beautiful. The process is not very difficult if you’re
familiar with <a href="https://jinja.palletsprojects.com">jinja</a> templating. Help on that can be found in the
“Templating” section of the online <a href="https://blag.readthedocs.io">documentation</a>, the offline
version in the <code>blag-doc</code> package, or the man page, respectively.</p>
<p>Speaking of the <code>blag-doc</code> package: packaging it was surprisingly tricky, and
it also took me a lot of trial and error to realize that <code>dh_sphinxdocs</code> alone
does <strong>not</strong> automatically put the generated html output into the appropriate
package, you rather have to list them in the <code>package.docs</code>-file (i.e.
<code>blag-doc.docs</code>) so <code>dh_installdocs</code> can install them properly.</p> Managing dotfiles with GNU Stow 2021-12-19T14:00:00+01:00 2021-12-19T14:00:00+01:00 Bastian Venthur tag:venthur.de,2021-12-19:/2021-12-19-managing-dotfiles-with-stow.html How to use GNU Stow to manage the symlinks to the dotfile repository. <p>Many developers manage their user-specific application configuration – also
known as dotfiles – in a version control system such as <a href="https://git-scm.com/">git</a>. This allows
for keeping track of changes and synchronizing the dotfiles across different
machines. Searching on github, you’ll find <a href="https://github.com/search?q=dotfiles">thousands of dotfile
repositories</a>.</p>
<p>As your dotfiles are sprinkled all over your home directory, managing them in
a single repository is not trivial, i.e. how do you make sure that your
<code>.bashrc</code>, <code>.tmux.conf</code>, etc. that life in your dotfile repository appear in
the proper places in your home directory? The most common solution is to use
<a href="https://en.wikipedia.org/wiki/Symbolic_link">symlinks</a> so that the <code>.tmux.conf</code> in your home directory is just a symlink
pointing to the appropriate file in your dotfile repository:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>ls<span class="w"> </span>-l<span class="w"> </span>~/.tmux.conf
lrwxrwxrwx<span class="w"> </span><span class="m">1</span><span class="w"> </span>venthur<span class="w"> </span>venthur<span class="w"> </span><span class="m">34</span><span class="w"> </span><span class="m">18</span>.<span class="w"> </span>Dez<span class="w"> </span><span class="m">22</span>:53<span class="w"> </span>/home/venthur/.tmux.conf<span class="w"> </span>-><span class="w"> </span>git/dotfiles/tmux/.tmux.conf
</code></pre></div>
<p>This leads immediately to another problem: how do you manage the symlinks? For
the longest time I just manually maintained the symlinks on the various
machines, but this approach does not scale well with the number of dotfiles
and machines you’re using this repository on. Often, people write their own
shell scripts that help them with the maintenance of the symlinks, but at
least the solutions I’ve seen so far did not convince me.</p>
<p>Last year I stumbled upon <a href="https://www.gnu.org/software/stow/">GNU Stow</a>, an unpretentious little tool that
does not reveal at first sight how useful it would be for the job. The
description on the website says:</p>
<blockquote>
<p>GNU Stow is a symlink farm manager which takes distinct packages of software
and/or data located in separate directories on the filesystem, and makes
them appear to be installed in the same place.</p>
</blockquote>
<p>Right.</p>
<h2>How does it work?</h2>
<p>In <code>stow</code>’s terminology, a <strong>package</strong> is a set of files and directories that
need to be “installed” in a particular directory structure. The <strong>target
directory</strong> is the root of the tree in which the package appear to be
installed.</p>
<p>When you “stow” a package, <code>stow</code> creates symlinks in the target directory
that point <strong>into</strong> the package.</p>
<p>Let’s say I have my dotfiles repository in <code>~/git/dotfiles/</code>. Within this
repository, I have a <code>tmux</code> <strong>package</strong>, containing the <code>.tmux.conf</code> dotfile:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span><span class="nb">pwd</span>
/home/venthur/git/dotfiles
$<span class="w"> </span>find<span class="w"> </span>tmux
tmux<span class="w"> </span><span class="c1"># the package</span>
tmux/.tmux.conf<span class="w"> </span><span class="c1"># the dotfile</span>
</code></pre></div>
<p>The <strong>target directory</strong> is my home directory, as this is where the symlinks
need to be created. I can now stow the <code>tmux</code> package into the target
directory like so:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>stow<span class="w"> </span>--target<span class="o">=</span>/home/venthur<span class="w"> </span>tmux
</code></pre></div>
<p>and <code>stow</code> will create the appropriate symlinks to the contents of the package
into the target directory:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>ls<span class="w"> </span>-l<span class="w"> </span>~/.tmux.conf
lrwxrwxrwx<span class="w"> </span><span class="m">1</span><span class="w"> </span>venthur<span class="w"> </span>venthur<span class="w"> </span><span class="m">34</span><span class="w"> </span><span class="m">2</span>.<span class="w"> </span>Jun<span class="w"> </span><span class="m">2021</span><span class="w"> </span>/home/venthur/.tmux.conf<span class="w"> </span>-><span class="w"> </span>git/dotfiles/tmux/.tmux.conf
</code></pre></div>
<p>Note that the name of the package (i.e. the name of the directory) does not
matter as <code>stow</code> points the symlinks <strong>into</strong> the package, so you can choose
it freely. I usually use the name of the program that the configuration
belongs to as the package name.</p>
<p>Your package can also contain several files or even a complex directory
structure. Let’s look at the configuration for neovim, which lives below
<code>~/.config/nvim/</code>:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span><span class="nb">pwd</span>
/home/venthur/git/dotfiles
$<span class="w"> </span>find<span class="w"> </span>neovim
neovim
neovim/.config
neovim/.config/nvim
neovim/.config/nvim/init.vim
$<span class="w"> </span>stow<span class="w"> </span>--target<span class="o">=</span>/home/venthur<span class="w"> </span>neovim
$<span class="w"> </span>ls<span class="w"> </span>-l<span class="w"> </span>~/.config/nvim
lrwxrwxrwx<span class="w"> </span><span class="m">1</span><span class="w"> </span>venthur<span class="w"> </span>venthur<span class="w"> </span><span class="m">41</span><span class="w"> </span><span class="m">2</span>.<span class="w"> </span>Jun<span class="w"> </span><span class="m">2021</span><span class="w"> </span>/home/venthur/.config/nvim<span class="w"> </span>-><span class="w"> </span>../git/dotfiles/neovim/.config/nvim
</code></pre></div>
<p>At this point we should mention that the target directory for my dotfiles will
always be my home directory, so the contents of the packages are either the
configuration files or the directory structure as they live in my home
directory.</p>
<h2>Deleting a package from the parent directory</h2>
<p>You can also remove (unstow) a package from the target directory again, using
the <code>--delete</code> parameter:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>ls<span class="w"> </span>-l<span class="w"> </span>~/.tmux.conf
lrwxrwxrwx<span class="w"> </span><span class="m">1</span><span class="w"> </span>venthur<span class="w"> </span>venthur<span class="w"> </span><span class="m">34</span><span class="w"> </span><span class="m">18</span>.<span class="w"> </span>Dez<span class="w"> </span><span class="m">22</span>:53<span class="w"> </span>/home/venthur/.tmux.conf<span class="w"> </span>-><span class="w"> </span>git/dotfiles/tmux/.tmux.conf
$<span class="w"> </span>stow<span class="w"> </span>--target<span class="o">=</span>/home/venthur<span class="w"> </span>--delete<span class="w"> </span>tmux/
$<span class="w"> </span>ls<span class="w"> </span>-l<span class="w"> </span>~/.tmux.conf
ls:<span class="w"> </span>cannot<span class="w"> </span>access<span class="w"> </span><span class="s1">'/home/venthur/.tmux.conf'</span>:<span class="w"> </span>No<span class="w"> </span>such<span class="w"> </span>file<span class="w"> </span>or<span class="w"> </span>directory
</code></pre></div>
<h2>Stowing several packages at once</h2>
<p>Since your dotfile repository will likely contain more than one package, it
makes sense to combine the individual <code>stow</code> commands into one, so instead of
stowing everything individually,</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>stow<span class="w"> </span>--target<span class="o">=</span>/home/venthur<span class="w"> </span>tmux
$<span class="w"> </span>stow<span class="w"> </span>--target<span class="o">=</span>/home/venthur<span class="w"> </span>vim
$<span class="w"> </span>stow<span class="w"> </span>--target<span class="o">=</span>/home/venthur<span class="w"> </span>neovim
</code></pre></div>
<p>you can stow everything at once:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>stow<span class="w"> </span>--target<span class="o">=</span>/home/venthur<span class="w"> </span>*/
</code></pre></div>
<p>Note that I use <code>*/</code> instead of <code>*</code> to match all directories (i.e. packages),
since my dotfiles repository also contains a <code>README.md</code> and a <code>makefile</code>.</p>
<h2>Putting it all together</h2>
<p><a href="https://github.com/venthur/dotfiles">My dotfiles</a> repository contains a <code>makefile</code> that allows me to
create/update or delete all symlinks at once:</p>
<div class="codehilite"><pre><span></span><code><span class="nf">all</span><span class="o">:</span>
<span class="w"> </span>stow<span class="w"> </span>--verbose<span class="w"> </span>--target<span class="o">=</span><span class="nv">$$</span>HOME<span class="w"> </span>--restow<span class="w"> </span>*/
<span class="nf">delete</span><span class="o">:</span>
<span class="w"> </span>stow<span class="w"> </span>--verbose<span class="w"> </span>--target<span class="o">=</span><span class="nv">$$</span>HOME<span class="w"> </span>--delete<span class="w"> </span>*/
</code></pre></div>
<p>The <code>--restow</code> parameter tells <code>stow</code> to unstow the packages first before
stowing them again, which is useful for pruning obsolete symlinks from the
target directory.</p>
<p>Et voilà! Whenever I make a change in my dotfiles repository that involves
creating or deleting a dotfile (or a package), I simply call:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>make
</code></pre></div>
<p>and everything is updated. To delete all dotfile-related symlinks from this
machine, I simply run:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>make<span class="w"> </span>delete
</code></pre></div> The State of Python Packaging in 2021 2021-06-26T14:00:00+02:00 2021-06-26T14:00:00+02:00 Bastian Venthur tag:venthur.de,2021-06-26:/2021-06-26-python-packaging.html Every year, I revisit the current best practices for Python packaging. This is my 2021 edition. <p>Every year or so, I revisit the current best practices for Python packaging.
I.e. the way you’re supposed to distribute your Python packages. The main
source is <a href="https://packaging.python.org/">packaging.python.org</a> where the official packaging guidelines
are. It is worth noting that the way you’re supposed to package your Python
applications is <em>not</em> defined by Python or its maintainers, but rather
delegated to a separate entity, the <a href="https://www.pypa.io/en/latest/">Python Packaging Authority (PyPA)</a>.</p>
<h2>PyPA</h2>
<p>PyPA does an excellent job providing us with information, best practices and
tutorials regarding Python packaging. However, there’s <em>one</em> thing that
irritates me every single time I revisit the page and that is the misleading
recommendation of their <em>own</em> tool <a href="https://pipenv.pypa.io">pipenv</a>.</p>
<p>Quoting from the <a href="https://packaging.python.org/guides/tool-recommendations">tool recommendations</a> section of the packaging
guidelines:</p>
<blockquote>
<p>Use Pipenv to manage library dependencies when developing Python
applications. See Managing Application Dependencies for more details on
using pipenv.</p>
</blockquote>
<p><a href="https://www.pypa.io/en/latest/">PyPA</a> recommends <a href="https://pipenv.pypa.io">pipenv</a> as the <em>standard</em> tool for dependency
management, at least <a href="https://web.archive.org/web/20180504100940/https://packaging.python.org/guides/tool-recommendations/">since 2018</a>. A bold statement, given that
<code>pipenv</code> only started in 2017, so the Python community cannot have had not
enough time to standardize on the workflow around that tool. There have been
no releases of <code>pipenv</code> between 2018-11 and 2020-04, that’s 1.5 years for the
<em>standard</em> tool. In the past, <code>pipenv</code> also hasn’t been shy in pushing
breaking changes in a fast-paced manner.</p>
<p>PyPA still advertises <code>pipenv</code> all over the place and only mentions <a href="https://python-poetry.org">poetry</a>
a couple of times, although <code>poetry</code> seems to be the more mature product. I
understand that <code>pipenv</code> lives under the umbrella of PyPA, but I still expect
objectiveness when it comes to tool recommendation. Instead of making such
claims, they should provide a list of competing tools and provide a fair
feature comparison.</p>
<h2>Distributions</h2>
<p>You would expect exactly one distribution for Python packages, but here in
Python land, we have several ones. The most popular ones being <a href="https://pypi.org/">PyPI</a> – the
official one – and <a href="https://www.anaconda.com/">Anaconda</a>. Anaconda is more geared towards
data-scientists. The main selling point for Anaconda back then was that it
provided pre-compiled binaries. This was especially useful for data-science
related packages which depend on libatlas, -lapack, -openblas, etc. and need
to be compiled for the target system. This problem has mostly been solved with
the wide adoption of <a href="https://pythonwheels.com/">wheels</a>, but you still encounter some source-only
uploads to PyPI that require you to build stuff locally on <code>pip install</code>.</p>
<p>Of course there’s also the Python packages distributed by the Operating
System, Debian in my case. While I was a firm believer in <em>only</em> using those
packages provided by the OS in the very past, I moved to the opposite end of
the spectrum throughout the years, and am <em>only</em> using the minimal packages
provided by Debian to bootstrap my virtual environments (i.e. <code>pip</code>,
<code>setuptools</code> and <code>wheel</code>). The main reason is outdated or missing libraries,
which is expected – Debian cannot hope to keep up with all the upstream
changes in the ecosystem, and that is by design and fine. However, with the
recent upgrade of <a href="https://www.python.org/dev/peps/pep-0513/">manylinux</a>, even the <code>pip</code> provided by Debian/unstable
was too outdated, so you basically had to <code>pip install --upgrade pip</code> for a
while otherwise you’d end up compiling every package you’d try to install via
<code>pip</code>.</p>
<p>So I’m sticking to the official PyPI distribution wherever possible. However,
compared to the Debian distribution it feels immature. In my opinion, there
should be compiled wheels for all packages available that need it, built and
provided by PyPI. Currently, the wheels provided are the ones uploaded by the
upstream maintainers. This is not enough, as they usually build wheels only
for one platform. Sometimes they don’t upload wheels in the first place,
relying on the users to compile during install.</p>
<p>Then you have <a href="https://www.python.org/dev/peps/pep-0513/">manylinux</a>, an excellent idea to create some common ground
for a portable Linux build distribution. However, sometimes when a new version
of manylinux is released some upstream maintainers immediately start
supporting <em>only</em> that version, breaking a lot of systems.</p>
<p>A setup similar to Debian’s where the authors only do a source-upload and the
wheels are compiled on PyPI infrastructure for all available platforms, is
probably the way to go.</p>
<h2>setup.py, setup.cfg, requirements.txt, Pipfile, pyproject.toml – oh my!</h2>
<p>This is the part I’m revisiting the documentation every year, to see what’s
the current way to go.</p>
<p>The main point of packaging your Python application is to define the package’s
meta data and (build-) dependencies.</p>
<h3>setup.py + requirements.txt</h3>
<p>For the longest time, the <code>setup.py</code> and <code>requirements.txt</code> were (and, spoiler
alert: still is) the backbone of your packaging efforts. In <code>setup.py</code> you
define the meta data of your package, including its dependencies.</p>
<p>If your project is a deployable application (vs. a library) you’ll very often
provide an additional <code>requirements.txt</code> with <em>pinned</em> dependencies. Usually
the list of requirements is the same as defined in <code>setup.py</code> but with pinned
versions. The reason why you avoid version pinning in <code>setup.py</code> is that it
would interfere with other pinned dependencies from other dependencies you try
to install.</p>
<h3>setup.cfg</h3>
<p><code>setup.cfg</code> is a configuration file that is used by many standard tools in the
Python ecosystem. Its format is ini-style and each tools’ configuration lives
in its own stanza. Since 2016 <a href="https://setuptools.readthedocs.io/en/latest/userguide/declarative_config.html">setuptools supports</a> configuring
<code>setup()</code> using <code>setup.cfg</code> files. This was exciting news back then, however,
it does not completely replace the <code>setup.py</code> file. While you can move most of
the <code>setup.py</code> configuration into <code>setup.cfg</code>, you’ll still have to provide
that file with an empty <code>setup()</code> in order to allow for editable <code>pip</code>
installs. In my opinion, that makes this feature useless and I rather stick to
<code>setup.py</code> with a properly populated <code>setup()</code> until that file can be
<em>completely</em> replaced with something else.</p>
<h3>Pipfile + Pipflie.lock</h3>
<p><a href="https://github.com/pypa/pipfile"><code>Pipfile</code> and <code>Pipfile.lock</code></a> are supposed to replace
<code>requirements.txt</code> some day. So far they are not supported by <code>pip</code> or
mentioned in any <a href="https://www.python.org/dev/peps/">PEP</a>. I think only <code>pipenv</code> supports them, so I’d ignore
them for now.</p>
<h3>pyproject.toml</h3>
<p><a href="https://www.python.org/dev/peps/pep-0518/">PEP 518</a> introduces the <code>pyproject.toml</code> file as a way to specify
build requirements for your project. <a href="https://www.python.org/dev/peps/pep-0621/">PEP 621</a> defines how to store
project meta data in it.</p>
<p><code>pip</code> and <code>setuptools</code> support <code>pyproject.toml</code> to some extent, but not to a
point where it completely replaces <code>setup.py</code> yet. Many of Python’s standard
tools allow already for configuration in <code>pyproject.toml</code> so it seems this
file will slowly replace the <code>setup.cfg</code> and probably <code>setup.py</code> and
<code>requirements.txt</code> as well. But we’re not there yet.</p>
<p><code>poetry</code> has an interesting approach: it will allow you to write everything
into <code>pyproject.toml</code> and <em>generate</em> a <code>setup.py</code> for you at build-time, so it
can be uploaded to PyPI.</p>
<p>Ironically, Python settled for the TOML file format here, although there is
currently no support for reading TOML files in Python’s standard library.</p>
<h2>Summary</h2>
<p>While some alternatives exist, in 2021 I still stick to <code>setup.py</code> and
<code>requirements.txt</code> to define the meta data and dependencies of my projects.
Regarding the tooling, <code>pip</code> and <code>twine</code> are sufficient and do their job just
fine. Alternatives like <code>pipenv</code> and <code>poetry</code> exist. The scope of <code>poetry</code>
seems to be better aligned with my expectations, and it seems the more mature
project compared to <code>pipenv</code> but in any case I’ll ignore both of them until I
revisit this issue in 2022.</p>
<h2>Closing Thoughts</h2>
<p>While the packaging in Python has improved a lot in the last years, I’m still
somewhat put off how such a core aspect of a programming language is treated
within Python. With some jealousy, I look over to the folks at Rust and how
they seemed to get this aspect right from the start.</p>
<p>What would in my opinion improve the situation?</p>
<ul>
<li>Source only uploads and building of weels for all platforms on PyPI
infrastructure – this way we could have wheels everywhere and remove the
need to compile anything in <code>pip install</code></li>
<li>Standard tooling: <code>pip</code> has been and still is the tool of choice for
packaging in Python. For some time now, you also need <code>twine</code> in order to
upload your packages. <code>setup.py upload</code> still exists, but hasn’t worked for
months on my machines. It would be great to have something that improves the
virtualenv handling and dependency management. We do have some tools with
overlapping use-cases, like <code>poetry</code> and <code>pipenv</code>. <code>pipenv</code> is heavily
advertised and an actual PyPA project, but it feels immature in terms of
scope, release history (and emojis!) compared to <code>poetry</code>. <code>poetry</code> is
gaining a lot of traction, but it is apparently not receiving much love from
PyPA, which brings me to:</li>
<li>Unbiased tool recommendations. I don’t understand why PyPA is trying so hard
to make us believe <code>pipenv</code> would be the standard tool for Python packaging.
Instead of making such claims, please provide a list of competitors and
provide a fair feature comparison. PyPA is providing great packaging
tutorials and is a valuable source of information around this topic. But
when it comes to the tool recommendations, I do challenge PyPA’s
objectiveness.</li>
</ul> Getting the Function keys of a Keychron working on Linux 2021-04-30T18:00:00+02:00 2021-04-30T18:00:00+02:00 Bastian Venthur tag:venthur.de,2021-04-30:/2021-04-30-keychron-c1-on-linux.html The Keychron C1 (and other Keychron models) do not work properly on Linux: the Function keys are not accessible at all, here's how to fix them. <p>Having destroyed the third Cherry Stream keyboard in 4 years, I wanted to try a
more substantial keyboard for a change. After some research I decided that I
want a mechanical, wired, tenkeyless keyboard without any fancy LEDs.</p>
<p>At the end I settled for a <a href="https://www.keychron.com/products/keychron-c1-wired-mechanical-keyboard">Keychron C1</a> with red switches. It meets all
requirements, looks very nice and the price is reasonable.</p>
<h2>Surprise!</h2>
<p>After the keyboard was delivered, I connected it to my Debian machine and was
unpleasantly surprised to notice that the Function-keys did <em>not work at all</em>.
The keyboard shares the Multimedia keys with the F-keys and you have an <code>fn</code>
key that supposedly switches between the two modes, like you’re used to on a
laptop. On Linux, however you cannot access the F-keys at all: pressing <code>fn
+ F1</code> or <code>F1</code> makes no difference, you’ll always get the Multimedia key.
Switching the keyboard between “Windows” and “Mac” mode makes no difference
either, in both modes the F-keys are not accessible.</p>
<p>Apparently Keychron is aware of the problem, because the quick start manual
tells you:</p>
<blockquote>
<p>“We have a Linux user group on facebook. Please search “Keychron Linux Group”
on facebook. So you can better experience with our keyboard.”</p>
</blockquote>
<p>Customer support at its finest!</p>
<p>So at this point you should probably just send the keyboard back, get the
refund and buy a proper one with functioning F-keys.</p>
<h2>The fix</h2>
<p>Test if this command fixes the issue and enables the <code>Fn +</code> F-key-combos:</p>
<div class="codehilite"><pre><span></span><code><span class="c1"># as root:</span>
<span class="nb">echo</span><span class="w"> </span><span class="m">2</span><span class="w"> </span>><span class="w"> </span>/sys/module/hid_apple/parameters/fnmode
</code></pre></div>
<p>Depending on the mode the keyboard is in, you should now be able to use the
F-keys by simply pressing them, and the Multimedia keys by pressing <code>fn +</code>
F-key (or the other way round). To switch the default mode of the F-keys to
Function- or Multimedia-mode, press and hold <code>fn + X + L</code> for 4 seconds.</p>
<p>If everything works as expected, you can make the change permanent by creating
the file <code>/etc/modprobe.d/hid_apple.conf</code> and adding the line:</p>
<div class="codehilite"><pre><span></span><code>options hid_apple fnmode=2
</code></pre></div>
<p>and running</p>
<div class="codehilite"><pre><span></span><code># as root
update-initramfs -u -k all
</code></pre></div>
<p>This works regardless if the keyboard is in Windows- or Mac-mode, and that
might hint at the problem: in both cases the Linux thinks you’re connecting a
Mac keyboard.</p>
<h2>The rant</h2>
<p>Although the fix was not very hard to find and apply, this experience still
leaves a foul taste. I naively assumed the problem of having a properly
functioning keyboard that simply works when you plug it in, has been thoroughly
solved by 2021.</p>
<p>To make it worse, I assume Keychron must be aware of the problem because the
other Keychron models have the <a href="https://www.google.com/search?q=keychron+linux+function+keys">same issue</a>! But instead of fixing it
on their end, they forward you to a facebook “community” and expect you to
somehow fix it yourself.</p>
<p>So dear Keychron, you do make really beautiful keyboards! But before you
release your <em>next</em> model with the same bug, maybe invest a bit on fixing the
basics? I see that your keyboards support firmware updates for Windows and Mac
– maybe you can talk to the folks over at the <a href="https://fwupd.org/">Linux Vendor Firmware
Service</a> and support Linux as well? Maybe you can even fix this annoying
bug for the keyboards you’ve already sold? I found it really cute that you sent
different keycaps for Windows and Mac setups – a few disappointed Linux users
might accept an apology in form of a Linux cap…</p>
<h2>Update (2022-08)</h2>
<p>Starting with version 5.19, Linux comes with a <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/diff/drivers/hid/hid-apple.c?id=v5.19&id2=v5.18">fix</a> for the Keychron
keyboards, so all models should work as expected out of the box. The relevant
<a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=fa33382c7f74a1444f90f324007da1431d7180b2">commit message</a> says:</p>
<blockquote>
<p>Keychron’s C-series and K-series of keyboards copy the vendor and product IDs
of an Apple keyboard, but only behave like that device when set to “Mac”
mode. In “Windows” mode, the Fn key doesn’t generate a scancode, so it’s
impossible to use the F1-F12 keys when fnmode is set to its default value of
1.</p>
<p>To fix this, make fnmode default to the new value of 3, which behaves like
fnmode=2 for Keychron keyboards and like fnmode=1 for actual Apple keyboards.
This way, Keychron devices are fully usable in both “Windows” and “Mac”
modes, while behavior is unchanged for everything else.</p>
</blockquote> Writing Makefiles for Python Projects 2021-03-31T16:00:00+02:00 2021-03-31T16:00:00+02:00 Bastian Venthur tag:venthur.de,2021-03-31:/2021-03-31-python-makefiles.html Exploring two different strategies for using Makefiles in Python projects <p>I’m a big fan of <a href="https://www.gnu.org/software/make/manual/make.html">Makefiles</a>. Almost all <a href="https://github.com/venthur">my side projects</a> are
using them, and I’ve been advocating their usage at work too.</p>
<p><code>Makefiles</code> give your contributors an entry point on how to do certain things
like, building, testing, deploying. And if done correctly, they can massively
simplify your CI/CD pipeline scripts as they can often just stupidly call the
respective <code>make</code> targets. Most importantly, they are a very convenient
shortcut for you as a developer as well.</p>
<p>For Python projects, where I’m almost always using <a href="https://docs.python.org/3/tutorial/venv.html">virtual
environments</a>, I’ve been using two different strategies for <code>Makefiles</code>:</p>
<ol>
<li>assuming that <code>make</code> is executed inside the virtual environment</li>
<li>wrapping all virtual environment calls inside <code>make</code></li>
</ol>
<p>Both strategies have their pros and cons.</p>
<h2>Assuming <code>make</code> is executed inside the venv</h2>
<p>Let’s have a look at a very simple <code>Makefile</code> that allows for building,
testing and releasing a Python project:</p>
<div class="codehilite"><pre><span></span><code><span class="nf">all</span><span class="o">:</span><span class="w"> </span><span class="n">lint</span> <span class="n">test</span>
<span class="nf">.PHONY</span><span class="o">:</span><span class="w"> </span><span class="n">test</span>
<span class="nf">test</span><span class="o">:</span>
<span class="w"> </span>pytest
<span class="nf">.PHONY</span><span class="o">:</span><span class="w"> </span><span class="n">lint</span>
<span class="nf">lint</span><span class="o">:</span>
<span class="w"> </span>flake8
<span class="nf">.PHONY</span><span class="o">:</span><span class="w"> </span><span class="n">release</span>
<span class="nf">release</span><span class="o">:</span>
<span class="w"> </span>python3<span class="w"> </span>setup.py<span class="w"> </span>sdist<span class="w"> </span>bdist_wheel<span class="w"> </span>upload
<span class="nf">clean</span><span class="o">:</span>
<span class="w"> </span>find<span class="w"> </span>.<span class="w"> </span>-type<span class="w"> </span>f<span class="w"> </span>-name<span class="w"> </span>*.pyc<span class="w"> </span>-delete
<span class="w"> </span>find<span class="w"> </span>.<span class="w"> </span>-type<span class="w"> </span>d<span class="w"> </span>-name<span class="w"> </span>__pycache__<span class="w"> </span>-delete
</code></pre></div>
<p>This is straightforward and a potential contributor immediately knows the
entry points to your project.</p>
<p>Assuming there is a venv installed already, you have to activate it first and
run the <code>make</code> commands afterwards:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>.<span class="w"> </span>venv/bin/activate
$<span class="w"> </span>make<span class="w"> </span><span class="nb">test</span>
</code></pre></div>
<p>The downside is of course, that you have to activate the venv for every new
shell. Which can get a bit annoying when you spawn a new terminal in <code>tmux</code> or
put <code>vim</code> into the background to run <code>make</code>.</p>
<p>Activating the venv inside make will not work, as each recipe runs in its own
shell, moreover each command in each recipe runs in its own shell too. There
are workarounds for the latter, i.e. using the <code>.ONESHELL</code> flag, but that does
not solve the issue of a new shell in each recipe.</p>
<h2>Wrapping the venv calls inside <code>make</code></h2>
<p>The second approach mitigates for the issue of activating the venv altogether.
I’ve borrowed this idea mostly from <a href="https://github.com/sio/Makefile.venv">makefile.venv</a> and simplified it a lot
for my needs.</p>
<div class="codehilite"><pre><span></span><code><span class="c"># system python interpreter. used only to create virtual environment</span>
<span class="nv">PY</span><span class="w"> </span><span class="o">=</span><span class="w"> </span>python3
<span class="nv">VENV</span><span class="w"> </span><span class="o">=</span><span class="w"> </span>venv
<span class="nv">BIN</span><span class="o">=</span><span class="k">$(</span>VENV<span class="k">)</span>/bin
<span class="c"># make it work on windows too</span>
<span class="cp">ifeq ($(OS), Windows_NT)</span>
<span class="w"> </span><span class="nv">BIN</span><span class="o">=</span><span class="k">$(</span>VENV<span class="k">)</span>/Scripts
<span class="w"> </span><span class="nv">PY</span><span class="o">=</span>python
<span class="cp">endif</span>
<span class="nf">all</span><span class="o">:</span><span class="w"> </span><span class="n">lint</span> <span class="n">test</span>
<span class="nf">$(VENV)</span><span class="o">:</span><span class="w"> </span><span class="n">requirements</span>.<span class="n">txt</span> <span class="n">requirements</span>-<span class="n">dev</span>.<span class="n">txt</span> <span class="n">setup</span>.<span class="n">py</span>
<span class="w"> </span><span class="k">$(</span>PY<span class="k">)</span><span class="w"> </span>-m<span class="w"> </span>venv<span class="w"> </span><span class="k">$(</span>VENV<span class="k">)</span>
<span class="w"> </span><span class="k">$(</span>BIN<span class="k">)</span>/pip<span class="w"> </span>install<span class="w"> </span>--upgrade<span class="w"> </span>-r<span class="w"> </span>requirements.txt
<span class="w"> </span><span class="k">$(</span>BIN<span class="k">)</span>/pip<span class="w"> </span>install<span class="w"> </span>--upgrade<span class="w"> </span>-r<span class="w"> </span>requirements-dev.txt
<span class="w"> </span><span class="k">$(</span>BIN<span class="k">)</span>/pip<span class="w"> </span>install<span class="w"> </span>-e<span class="w"> </span>.
<span class="w"> </span>touch<span class="w"> </span><span class="k">$(</span>VENV<span class="k">)</span>
<span class="nf">.PHONY</span><span class="o">:</span><span class="w"> </span><span class="n">test</span>
<span class="nf">test</span><span class="o">:</span><span class="w"> </span><span class="k">$(</span><span class="nv">VENV</span><span class="k">)</span>
<span class="w"> </span><span class="k">$(</span>BIN<span class="k">)</span>/pytest
<span class="nf">.PHONY</span><span class="o">:</span><span class="w"> </span><span class="n">lint</span>
<span class="nf">lint</span><span class="o">:</span><span class="w"> </span><span class="k">$(</span><span class="nv">VENV</span><span class="k">)</span>
<span class="w"> </span><span class="k">$(</span>BIN<span class="k">)</span>/flake8
<span class="nf">.PHONY</span><span class="o">:</span><span class="w"> </span><span class="n">release</span>
<span class="nf">release</span><span class="o">:</span><span class="w"> </span><span class="k">$(</span><span class="nv">VENV</span><span class="k">)</span>
<span class="w"> </span><span class="k">$(</span>BIN<span class="k">)</span>/python<span class="w"> </span>setup.py<span class="w"> </span>sdist<span class="w"> </span>bdist_wheel<span class="w"> </span>upload
<span class="nf">clean</span><span class="o">:</span>
<span class="w"> </span>rm<span class="w"> </span>-rf<span class="w"> </span><span class="k">$(</span>VENV<span class="k">)</span>
<span class="w"> </span>find<span class="w"> </span>.<span class="w"> </span>-type<span class="w"> </span>f<span class="w"> </span>-name<span class="w"> </span>*.pyc<span class="w"> </span>-delete
<span class="w"> </span>find<span class="w"> </span>.<span class="w"> </span>-type<span class="w"> </span>d<span class="w"> </span>-name<span class="w"> </span>__pycache__<span class="w"> </span>-delete
</code></pre></div>
<p>The equivalent <code>Makefile</code> now looks immediately more complicated. So let’s
break it down.</p>
<p>Instead of calling just calling <code>pytest</code>, <code>flake8</code> and <code>python</code> assuming the
venv is already activated or all dependencies are installed on the system
directly, we <em>explicitly</em> call the ones from the venv by prefixing the command
with the path to the venv’s <code>bin</code> directory. To ensure the venv exists, each
of the recipes is depending on the <code>$(VENV)</code> target, which ensures we always
have an up-to-date venv installed.</p>
<p>This works, because the <code>. venv/bin/activate</code>-script basically just does the
same: it puts the venv before anything else in your <code>PATH</code>, therefore each
call to <code>python</code>, etc. will find the one installed in the venv first.</p>
<p>While the <code>Makefile</code> is a bit more complicated, we now can just call</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>make<span class="w"> </span><span class="nb">test</span>
</code></pre></div>
<p>and don’t deal with venvs directly any more (well, for those simple cases at
least…). If you don’t need to support Windows, you can remove the
appropriate block and the <code>Makefile</code> looks relatively tame, even for people
that don’t use <code>make</code> very often.</p>
<h2>Which one is better?</h2>
<p>I think the second approach is more convenient. I’ve used the first approach
happily for years and only learned quite recently about the second one. I
haven’t really noticed any downsides yet, but I do realize that almost all
Python projects with <code>Makefiles</code> I’ve checked out, seem to prefer the first
approach. I wonder why that is?</p> Perfection is Achieved When There is Nothing Left to Take Away 2021-03-24T23:00:00+01:00 2021-03-24T23:00:00+01:00 Bastian Venthur tag:venthur.de,2021-03-24:/2021-03-24-blogging.html In 14 years since starting this blog, I changed the software several times, with each iteration simplifying requirements and setup. <p>In 14 years since starting this blog, I changed the software several times,
with each iteration simplifying requirements and setup.</p>
<h2>Wordpress</h2>
<p>In 2007, I <a href="2007-01-23-hello-world-2.html">started blogging</a>. Back then I used a self-hosted
<a href="https://wordpress.org/">Wordpress</a> instance, running on my server. I was never really comfortable
with the technology stack involved: a <a href="https://www.php.net/">programming language</a> I didn’t
speak, a <a href="https://www.mysql.com/">DB</a> I had little experience with, a relatively heavy setup
and of course, the occasional security issues related to that setup. All that
just to have a somewhat dynamic website with <a href="https://en.wikipedia.org/wiki/Pingback">pingbacks</a> and
comments generated by your visitors… <strong>totally worth it and exciting
times</strong>! You wrote something to the “lazyweb” department and people would
<em>actually</em> comment with useful advice!</p>
<p>Then came the spammers. First, it was just a little, and you could easily
fight it off with the <a href="https://wordpress.org/plugins/akismet/">askimet</a> plugin. Over the years, however the
spam-to-useful-comments-ratio shifted to ridiculous levels and the comment
section itself became a burden. Hosting the comments on a separate platform
like <a href="https://disqus.com/">disqus</a> was not an option for me, so I finally turned the comments
off.</p>
<p>Without the need for a comment section, the whole idea of storing mostly
textual content in a DB just to have it served as a website, suddenly seemed
like overkill and an unnecessary security risk. So I started looking for
alternatives.</p>
<p>I wanted to maintain my content as plain text files. Text files are cool
because they are future proof, portable and can be managed in git.
Consequently, I was searching for a static site generator.</p>
<h2>Pelican</h2>
<p>Around 2016 I finally migrated away from Wordpress to <a href="https://getpelican.com/">Pelican</a>. Pelican met
all my requirements. I could store my content as plain Markdown files in a git
repository. Pelican is written in Python, a language with which I’m very
comfortable with. Pelican deals with blog posts and “pages” (i.e. non blog
articles) and most importantly: Pelican just generates static HTML. So all
that’s required on the server side is a simple web server.</p>
<p>Conveniently, it also comes with an importer that allowed me to export the
content of my old Wordpress instance straight into Markdown files.</p>
<p>Migrating to Pelican was a huge relieve: I finally had a all my content as
plain text in a git repository, my server was a lot more secure without the
Wordpress instance running and removing MySQL freed up a lot of resources on
that machine.</p>
<h2>blag</h2>
<p>Fast forward to 2021. While I was quite happy with Pelican, it still had too
many features I don’t need. My blogging experience can be stripped down to a
bunch of Markdown files that serve either as articles or pages, some static
files, some templating for a decent design and an Atom feed. Particularly, I
do not need pages/articles in multiple languages, a plugin system, support for
multiple authors and tons of settings.</p>
<p>So I did what every self-respecting nerd would do: I wrote my own site
generator. Not to write something <em>better</em> than Pelican, but rather something
<em>lesser</em>. Something that does less while still being functionally adequate.</p>
<p>I called the result “<a href="https://github.com/venthur/blag">blag</a>”, named after the <a href="https://blog.xkcd.com/">blag of the webcomic
xkcd</a>. blag is a blog-aware, static site generator written in
Python. It supports the basic features you’d expect from a blog, like an
archive, tags and an <a href="https://tools.ietf.org/html/rfc4287">Atom</a> feed. It converts Markdown (with fenced code
blocks) and supports <a href="https://jinja.palletsprojects.com">Jinja2</a> templating.</p>
<p>With this setup I’m quite happy for now. Maybe sometime there will be a
simpler RSS/Atom-successor that does not <em>require</em> site-specific metadata
(i.e. only stuff that can be generated from the articles themselves), so I
could get rid of blag’s only required configuration.</p> Installing Debian on a Thinkpad T14s 2021-02-10T21:00:00+01:00 2021-02-10T21:00:00+01:00 Bastian Venthur tag:venthur.de,2021-02-10:/2021-02-10-installing-debian-on-a-thinkpad-t14s.html Due to non-free firmware it is still difficult to install Debian on recent hardware. <p>Recently, I got a new work laptop. I opted for Lenovo’s Thinkpad T14s that
comes with AMD’s Ryzen 7 PRO 4750U Processor. Once everything is installed, it
works like a charm: all hardware is supported and works out of the box with
Debian. However, the tricky part is actually <strong>installing</strong> Debian onto that
machine: The laptop lacks a standard Ethernet port and comes with Intel’s
Wi-Fi 6 AX200 module. So if you don’t happen to have a docking station or an
Ethernet adapter available during install, you’ll have to install everything
over WiFi. The WiFi module, however requires non-free firmware and this is
where the fun starts.</p>
<p>First, I downloaded an official <a href="https://www.debian.org/distrib/netinst">netinst</a> image and copied it onto a USB
drive. Halfway through the installation, it complained that firmware for the
WiFi module was missing, and I was stuck as I couldn’t continue the
installation without network access.</p>
<p>Ok, then – missing non-free firmware it is. The <a href="https://wiki.debian.org/Firmware">wiki</a> suggests using an
<strong>unofficial</strong> image instead, as it supposedly contains “<strong>all</strong> non-free
firmware packages directly”.</p>
<p>So I tried an unofficial <a href="https://cdimage.debian.org/images/unofficial/non-free/images-including-firmware/">netinst image with non-free
firmware</a>. That also did not work, with the same error as
above: the required firmware was missing. I checked the image later and
actually couldn’t find the non-free firmware either. Hum.</p>
<p>In the end, I had to prepare a <strong>second</strong> USB drive with the firmware
downloaded from <a href="https://cdimage.debian.org/cdimage/unofficial/non-free/firmware/testing/current/">here</a>. I unpacked the firmware into <code>/firmware</code> on
the second USB. The installer checks at some point during the installation for
firmware installed on other removable media and (hopefully) finds it. In my
case it did, and I finally could install everything.</p>
<p>I’m quite happy with the laptop, but I have to admit how incredibly difficult
it still is to install Debian on recent hardware. As a Debian Developer, I do
understand Debian’s position on non-free firmware, on the other hand however,
a less technical person would probably have given up at some point and just
installed some other Operating System.</p>
<p><strong>Update (2022-01-10):</strong> As someone suggested to me, an easier solution to
ensure internet access is to simply connect your cellphone via USB to the
laptop and use tethering.</p> Dear Apple, 2021-01-11T22:00:00+01:00 2021-01-11T22:00:00+01:00 Bastian Venthur tag:venthur.de,2021-01-11:/2021-01-11-dear-apple.html Like Android, Apple should allow other apps like Signal to become the default SMS/MMS app on iOS. <p>In the light of WhatsApp’s recent move to <a href="https://www.whatsapp.com/legal/updates/key-updates-eea">enforce new Privacy
Agreements</a> onto its users, alternative messenger services like
<a href="https://www.signal.org">Signal</a> are currently gaining some more momentum.</p>
<p>While this sounds good, it is hard to believe that this will be more than a
dent in WhatsApp’s user base. WhatsApp is way too ubiquitous, and the whole
point of using such a service for most users is to use the one that everyone
is using. Unfortunately.</p>
<p>Convincing WhatsApp users to additionally install Signal is hard: they already
have SMS for the few people that are not using WhatsApp, now expecting them to
install a <strong>third</strong> app for the same purpose seems ridiculous.</p>
<p>Android mitigates this problem a lot by <a href="https://support.signal.org/hc/en-us/articles/360007321171-Can-I-send-SMS-MMS-with-Signal-#android_sms">allowing</a> to make other
apps – like Signal – the <strong>default SMS/MMS</strong> app on the phone. Suddenly
people are able to use Signal for SMS/MMS and Signal messages transparently.
Signal is smart enough to figure out if the conversation partner is using
Signal and enables encryption, video calls and other features. If not, it just
falls back to plain old SMS. All in the same app, very convenient for the
user!</p>
<p>I don’t really get why the same thing is <a href="https://support.signal.org/hc/en-us/articles/360007321171-Can-I-send-SMS-MMS-with-Signal-#ios_sms">not possible</a> on iOS? Apple
is well known for taking things like privacy and security for its users
seriously, and this seems like a low-hanging fruit. So dear Apple, wouldn’t
now be a good time to team up with WhatsApp-alternatives like Signal to help
the users to make the right choice?</p> Creating Beautiful Github Streaks 2020-12-30T00:00:00+01:00 2020-12-30T00:00:00+01:00 Bastian Venthur tag:venthur.de,2020-12-30:/2020-12-30-streak.html How to generate git commits in the past to create beautiful github streaks. <p>Github streaks are a pretty fun and harmless way of visualizing your
contributions on github or gitlab. Some people use them to brag a little, some
companies use them to check out potential candidates. It’s all good as long as
everyone is aware how easily you can manipulate them.</p>
<p>In order to “fake” a commit date in the past, you have to set the
<code>GIT_AUTHOR_DATE</code> and <code>GIT_COMMITTER_DATE</code> environment variables on <code>git
commit</code> – both, RFC 2822 and ISO 8601 formats are accepted (for more info see
<a href="https://git-scm.com/book/en/v2/Git-Basics-Viewing-the-Commit-History">here</a>).</p>
<p>When generating hundreds of commits, the <code>--allow-empty</code> flag is very useful,
as we don’t have to actually change the source tree in order to generate a
commit.</p>
<p>So the command to generate a fake commit looks like this:</p>
<div class="codehilite"><pre><span></span><code><span class="nv">GIT_AUTHOR_DATE</span><span class="o">=</span><span class="s2">"</span><span class="nv">$TIMESTAMP</span><span class="s2">"</span><span class="w"> </span><span class="nv">GIT_COMMITTER_DATE</span><span class="o">=</span><span class="s2">"</span><span class="nv">$TIMESTAMP</span><span class="s2">"</span><span class="w"> </span>git<span class="w"> </span>commit<span class="w"> </span>--allow-empty<span class="w"> </span>-m<span class="w"> </span><span class="s2">"</span><span class="nv">$TIMESTAMP</span><span class="s2">"</span>
</code></pre></div>
<p>execute it on an empty git repository and push to github or gitlab and you’ll
se the result after some time.</p>
<p>To automate this, I wrote me a little python script (<a href="https://github.com/venthur/streak">github</a>,
<a href="https://pypi.org/project/python-streak/">pypi</a>). You can simply install it via:</p>
<div class="codehilite"><pre><span></span><code>pip<span class="w"> </span>install<span class="w"> </span>python-streak
</code></pre></div>
<p>and run it with:</p>
<div class="codehilite"><pre><span></span><code>streak
</code></pre></div>
<p>in an empty git repository. By default, streak will create 3 commits per day
with a probability of ~71% per commit for 100 years, starting from 1980-05-09.
These parameters can be tuned with:</p>
<ul>
<li><code>--start START</code>: Beginning of the commits (Format: YYYY-MM-DD)</li>
<li><code>--end END</code>: End of the commits (Format: YYYY-MM-DD)</li>
<li><code>--max MAX</code>: Maximum number of commits per day.</li>
<li><code>--proba PROBA</code>: Probability for a commit to happen.</li>
</ul>
<p>Generating a few commits per day for the range of 10 years, took roughly 2
minutes on my computer, and man was I a busy beaver in the 80s!</p>
<p><img alt="Streak 1989" src="/images/streak.png" title="The Great Streak of 1989"></p>
<p>I know, I’m for sure not the first one to discover this kind of thing, but it
was a fun afternoon project anyways!</p> Introducing Noir 2019-08-24T00:00:00+02:00 2019-08-24T00:00:00+02:00 Bastian Venthur tag:venthur.de,2019-08-24:/2019-08-24-introducing-noir.html noir is a drop-in replacement for black, with the default line length set to 79 characters. <h2>tl;dr</h2>
<p><a href="https://github.com/venthur/noir">Noir</a> is a drop-in replacement for <a href="https://github.com/psf/black">Black</a> (the uncompromising
code formatter), with the default line length set to <a href="https://www.python.org/dev/peps/pep-0008/">PEP-8</a>’s preferred
79 characters. If you want to use it, just replace <code>black</code> with <code>noir</code> in your
<code>requirements.txt</code> and/or <code>setup.py</code> and you’re good to go.</p>
<p>Black is a Python code formatter that reformats your code to make it more
<a href="https://www.python.org/dev/peps/pep-0008/">PEP-8</a> compliant. It implements a subset of PEP-8, most notably it
deliberately ignores PEP-8’s suggestion for a line length of 79 characters and
defaults to a length of 88. I find the decision and the
<a href="https://github.com/psf/black#line-length">reasoning</a> behind that somewhat arbitrary. PEP-8 is a good
standard and there’s a lot of value in having a style guide that is generally
accepted and has a lot of tooling to support it.</p>
<p>When <a href="https://github.com/psf/black/issues/498">people</a> <a href="https://github.com/psf/black/issues/855">ask</a> to change Black’s default line length to
79, the issue is usually closed with a reference to the reasoning in the
<code>README</code>. But Black’s developers are at least aware of this controversial
decision, as Black’s <em>only</em> option that allows to configure the (otherwise
uncompromising) code formatter, is in fact the line length.</p>
<p>Apart from that, Black is a good formatter that’s gaining more and more
popularity. And, of course, the developers have every right to follow their
own taste. However, since Black is licensed under the terms of the <a href="https://opensource.org/licenses/MIT">MIT
license</a>, I tried to see what needs to be done in order to fix the line
length issue.</p>
<h2>Step 1: Changing the Default</h2>
<p><a href="https://github.com/venthur/noir/commit/f322b60072774a098c4b84eaebaa7e349fc7d251">This</a> is the easiest part. You only have to change the
<code>DEFAULT_LINE_LENGTH</code> value in <code>black.py</code> from <code>88</code> to <code>79</code>, and black works
as expected. Bonus points for doing the same in <code>black.vim</code> and
<code>pyproject.toml</code>, but not strictly necessary.</p>
<h2>Step 2a: Fixing the Tests</h2>
<p>Now comes the <a href="https://github.com/venthur/noir/commit/b5f6ecf51adfa90751e8a7fbc139081e7f676a48">fun part</a>. Black has an extensive test suite and
suddenly a lot of tests are failing because the fixtures that compare the
unformatted input with the expected, formatted output were written with a line
length of 88 characters in mind. To make it more interesting the expected
output comes in two forms: (1) as normal reformatted Python code (which is
rather easy to fix) and (2) as a <a href="https://en.wikipedia.org/wiki/Diff">diff</a> between the input and the
expected output. The latter was really painful to fix – although I’m very
much used to reading diffs, I don’t usually write them.</p>
<h2>Step 2b: Fixing the Tests</h2>
<p>After all fixtures were updated, some tests were still failing. And it turned
out that Black is running itself on its own source code as part of its test
suite, making the tests fail if Black’s code does not conform to Black’s
coding standards. While this is a genius idea, it meant that I had to reformat
Black’s code to match the new 79 characters line length, generating a <a href="https://github.com/venthur/noir/commit/b87e2b66833f39aa109e92daab5f859021125ab6">giant
diff</a>, that is functionally unrelated to the fix I wanted to make but
now part of the fix anyway. This of course makes the whole patch horrible to
maintain if you plan to follow along upstream’s <code>master</code> branch.</p>
<h2>Step 3: Publish</h2>
<p>Since we already got this far, why not publish the fixed version of Black? To
my surprise the name <a href="https://pypi.org/project/noir/">noir</a> was still available on PyPi, so I
<a href="https://github.com/venthur/noir/commit/2d854112a2d11d34b12ab7fe65361826dc01bc65">renamed</a> my version of Black to Noir and uploaded it to PyPi.</p>
<p>You can install it via:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>pip<span class="w"> </span>install<span class="w"> </span>noir
</code></pre></div>
<p>Since I didn’t change anything else, this is literally a drop-in replacement
for Black. All you have to do is replace <code>black</code> with <code>noir</code> in your
<code>requirements.txt</code> and/or <code>setup.py</code> and you’re good to go. The script that
executes Black is still called <code>black</code> and the server is still called
<code>blackd</code>.</p>
<h2>Outlook</h2>
<p>While this was a fun exercise, the question remains what to do with it. I’ll
try to follow upstream and update my patch whenever a new version will come
out. As new versions of Black are released only a handful of times a year,
this might be feasible.</p>
<p>Depending on how painful it is to maintain the patch for the tests, I might
either drop the tests altogether, relying on upstream’s tests passing on their
side and just maintaining the trivial patch from Step 1: Changing the
<code>DEFAULT_LINE_LENGTH</code>. The latter can probably be automated somehow using
github actions – and I’ll probably look into that at some point.</p>
<p>Best case scenario, of course, would be if Python changes its recommended line
length to 88 and I wouldn’t have to maintain noir in the first place :)</p> Dotenv CLI 2019-05-12T00:00:00+02:00 2019-05-12T00:00:00+02:00 Bastian Venthur tag:venthur.de,2019-05-12:/2019-05-12-dotenv-cli.html dotenv-cli is a Python package that provides the dotenv command. <p>As a small weekend project I wrote my own <a href="https://github.com/venthur/dotenv-cli"><code>dotenv</code> CLI</a>.
Dotenv-CLI is a simple package that provides the <code>dotenv</code> command. It reads
the <code>.env</code> file from the current directory puts the contents in the
environment and executes the given command.</p>
<p>Example <code>.env</code> file:</p>
<div class="codehilite"><pre><span></span><code><span class="nv">BASIC</span><span class="o">=</span>basic<span class="w"> </span>basic
<span class="nb">export</span><span class="w"> </span><span class="nv">EXPORT</span><span class="o">=</span>foo
<span class="nv">EMPTY</span><span class="o">=</span>
<span class="nv">INNER_QUOTES</span><span class="o">=</span>this<span class="w"> </span><span class="s1">'is'</span><span class="w"> </span>a<span class="w"> </span><span class="nb">test</span>
<span class="nv">INNER_QUOTES2</span><span class="o">=</span>this<span class="w"> </span><span class="s2">"is"</span><span class="w"> </span>a<span class="w"> </span><span class="nb">test</span>
<span class="nv">TRIM_WHITESPACE</span><span class="o">=</span><span class="w"> </span>foo
<span class="nv">KEEP_WHITESPACE</span><span class="o">=</span><span class="s2">" foo "</span>
<span class="nv">MULTILINE</span><span class="o">=</span><span class="s2">"multi\nline"</span>
<span class="c1"># some comment</span>
</code></pre></div>
<p>becomes:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>dotenv<span class="w"> </span>env
<span class="nv">BASIC</span><span class="o">=</span>basic<span class="w"> </span>basic
<span class="nv">EXPORT</span><span class="o">=</span>foo
<span class="nv">EMPTY</span><span class="o">=</span>
<span class="nv">INNER_QUOTES</span><span class="o">=</span>this<span class="w"> </span><span class="s1">'is'</span><span class="w"> </span>a<span class="w"> </span><span class="nb">test</span>
<span class="nv">INNER_QUOTES2</span><span class="o">=</span>this<span class="w"> </span><span class="s2">"is"</span><span class="w"> </span>a<span class="w"> </span><span class="nb">test</span>
<span class="nv">TRIM_WHITESPACE</span><span class="o">=</span>foo
<span class="nv">KEEP_WHITESPACE</span><span class="o">=</span><span class="w"> </span>foo
<span class="nv">MULTILINE</span><span class="o">=</span>multi
line
</code></pre></div>
<p>where <code>env</code> is a simple command that outputs the current environment
variables. A <code>dotenv</code> CLI comes in handy if you follow the <a href="https://12factor.net/config">12 factor
app</a> methodology or just need to run a program locally with
specific environment variables set.</p>
<p>While <a href="https://github.com/venthur/dotenv-cli">dotenv-cli</a> is certainly not the first <code>dotenv</code>
implementation, this one is written in Python and has no external dependencies
except Python itself. It also provides a bash completion, so you can prefix
any command with <code>dotenv</code> while still be able to use completion:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>dotenv<span class="w"> </span>make<span class="w"> </span><TAB>
all<span class="w"> </span>clean<span class="w"> </span>docs<span class="w"> </span>lint<span class="w"> </span>release<span class="w"> </span><span class="nb">test</span>
</code></pre></div>
<p>Since there’s also some other popular shells out there and I already struggled
writing the simple bash completion script, it would be very nice if some more
experienced <code>zsh</code>-, <code>fish</code>-, etc.- users could help me out in providing
completions for them as well.</p>
<p><code>dotenv-cli</code> is available on Debian and Ubuntu:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>apt-get<span class="w"> </span>install<span class="w"> </span>python3-dotenv-cli
</code></pre></div>
<p>and on PyPi as well:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>pip<span class="w"> </span>install<span class="w"> </span>dotenv-cli
</code></pre></div> Orphaning reportbug-ng 2018-12-28T00:00:00+01:00 2018-12-28T00:00:00+01:00 Bastian Venthur tag:venthur.de,2018-12-28:/2018-12-28-orphaning-rng.html After several years without development, it is time to say goodbye to reportbug-ng. <p>After more than two years without an update, I’ve decided to discontinue
developing <a href="https://github.com/venthur/reportbug-ng">reportbug-ng</a> and <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=917557">orphaned</a> the Debian
package. Since reportbug is a more than adequate alternative and
reportbug-ng’s popcon value is relatively low, it’s probably the best to just
remove the package from the archive.</p>
<p>I <a href="2007-03-07-a-screencast-is-worth-a-thousand-pictures.html">started developing</a> reportbug-ng 11 years ago as a user-friendly
alternative to Debian’s standard reportbug. Not only did it come with a nice
GUI that allowed for easy searching and filtering of existing bugs, it also
queried our bug tracking system (BTS) using its SOAP interface. Back then,
reportbug used to parse the human readable HTML from the website to get the
same information.</p>
<p>A couple of years later Debian’s reportbug <a href="2009-03-25-reportbug-finally-has-a-gui.html">got a GUI too</a> and
became a lot more novice-friendly.</p>
<p>At some point <a href="https://alioth-lists-archive.debian.net/pipermail/reportbug-maint/2008-July/000277.html">I asked the reportbug team</a> if they’d be interested in
moving away from parsing the BTS’ HTML and using the SOAP interface too. They
agreed and I started separating the BTS related part of the code into a
separate Python module called <a href="https://github.com/venthur/python-debianbts">python-debianbts</a>. A few
years later, in August 2011, reportbug 6.0 started to use python-debianbts for
querying the BTS.</p>
<p>It has been a fun ride, but it’s time to acknowledge that reportbug-ng has
outlived its usefulness and I’m not willing to maintain that Qt based GUI
anymore. I still continue to maintain python-debianbts, though.</p> Introducing Litestats 2018-10-13T00:00:00+02:00 2018-10-13T00:00:00+02:00 Bastian Venthur tag:venthur.de,2018-10-13:/2018-10-13-litestats.html litestats is a tool that converts Python's profiler output into a sqlite3 database for easier exploration and analysis. <p>Profiling in Python has always been easy, however, analyzing the profiler’s
output not so much. After the profile has been created you can use Python’s
<code>pstats</code> module but it feels quite clumsy and not really empowering. For
Python 2 there has been <a href="https://www.vrplumber.com/programming/runsnakerun/">RunSnakeRun</a>, a very convenient tool for analyzing
the profiler output, unfortunately that tool hasn’t been updated since 2014. I
recently <a href="https://github.com/venthur/snakerunner">ported</a> it to Python3 and wxPython4 but I’m probably
not going to maintain that code properly as I’m not very comfortable with
wxPython.</p>
<p>I still wanted something nicer than <code>pstats</code> for profiling so I wrote
<a href="https://github.com/venthur/litestats">litestats</a>. Litestats is a simple command line tool that takes the output of
the Python profiler and transforms the data into a sqlite3 database. You can
now easily analyze the profiler output using <code>sqlite</code> on the command line, the
<code>sqlitebrowser</code> for a graphical interface or use the data base as the
foundation of your very own tooling around the analysis.</p>
<h2>How does it work?</h2>
<p>Litestats reads the dump of the profiler and creates a normalized data base
with tree tables:</p>
<ul>
<li><code>functions</code>: contains each function (callers and callees) with filename,
line number and function name</li>
<li><code>stats</code> contains the statistics (primitive/total calls, total/cumulative
time) for all functions</li>
<li><code>calls</code> a caller-callee mapping</li>
</ul>
<p>While this provides an exact representation of the dump, those tables would be
cumbersome to use. So litestats additionally creates three views emulating
<code>pstats</code> <code>print_stats()</code>, <code>print_callers()</code> and <code>print_callees()</code>
functionality:</p>
<ul>
<li><code>pstats</code></li>
<li><code>callers</code></li>
<li><code>callees</code></li>
</ul>
<h2>Installation</h2>
<p>Litestats has <strong>no requirements</strong> other than Python itself and is available on
<a href="https://pypi.org/project/litestats/">PyPI</a>:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>pip<span class="w"> </span>install<span class="w"> </span>litestats
</code></pre></div>
<h2>Usage</h2>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span><span class="c1"># run the profiler and dump the output</span>
$<span class="w"> </span>python3<span class="w"> </span>-m<span class="w"> </span>cProfile<span class="w"> </span>-o<span class="w"> </span>example.prof<span class="w"> </span>example.py
$<span class="w"> </span><span class="c1"># convert dump to sqlite3 db</span>
$<span class="w"> </span>litestats<span class="w"> </span>example.prof
$<span class="w"> </span><span class="c1"># example.prof.sqlite created</span>
</code></pre></div>
<p>You can now use the sqlite3 data base to investigate the profiler dump:</p>
<div class="codehilite"><pre><span></span><code><span class="n">sqlite</span><span class="o">></span><span class="w"> </span><span class="k">select</span><span class="w"> </span><span class="o">*</span>
<span class="w"> </span><span class="p">...</span><span class="o">></span><span class="w"> </span><span class="k">from</span><span class="w"> </span><span class="n">pstats</span>
<span class="w"> </span><span class="p">...</span><span class="o">></span><span class="w"> </span><span class="k">order</span><span class="w"> </span><span class="k">by</span><span class="w"> </span><span class="n">cumtime</span><span class="w"> </span><span class="k">desc</span>
<span class="w"> </span><span class="p">...</span><span class="o">></span><span class="w"> </span><span class="k">limit</span><span class="w"> </span><span class="mi">20</span><span class="p">;</span>
<span class="n">ncalls</span><span class="w"> </span><span class="n">tottime</span><span class="w"> </span><span class="n">ttpercall</span><span class="w"> </span><span class="n">cumtime</span><span class="w"> </span><span class="n">ctpercall</span><span class="w"> </span><span class="n">filename</span><span class="p">:</span><span class="n">lineno</span><span class="p">(</span><span class="k">function</span><span class="p">)</span>
<span class="c1">---------- ---------- -------------------- ---------- ---------- ------------------------------------</span>
<span class="mi">18</span><span class="o">/</span><span class="mi">1</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">000161</span><span class="w"> </span><span class="mi">8</span><span class="p">.</span><span class="mi">94444444444444</span><span class="n">e</span><span class="o">-</span><span class="mi">06</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">067797</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">067797</span><span class="w"> </span><span class="o">~</span><span class="p">:</span><span class="mi">0</span><span class="p">(</span><span class="o"><</span><span class="n">built</span><span class="o">-</span><span class="k">in</span><span class="w"> </span><span class="k">method</span><span class="w"> </span><span class="n">builtins</span><span class="p">.</span><span class="k">exec</span><span class="o">></span><span class="p">)</span>
<span class="mi">1</span><span class="w"> </span><span class="mi">1</span><span class="p">.</span><span class="mi">0</span><span class="n">e</span><span class="o">-</span><span class="mi">06</span><span class="w"> </span><span class="mi">1</span><span class="p">.</span><span class="mi">0</span><span class="n">e</span><span class="o">-</span><span class="mi">06</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">067755</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">067755</span><span class="w"> </span><span class="o"><</span><span class="n">string</span><span class="o">></span><span class="p">:</span><span class="mi">1</span><span class="p">(</span><span class="o"><</span><span class="n">module</span><span class="o">></span><span class="p">)</span>
<span class="mi">1</span><span class="w"> </span><span class="mi">4</span><span class="p">.</span><span class="mi">0</span><span class="n">e</span><span class="o">-</span><span class="mi">06</span><span class="w"> </span><span class="mi">4</span><span class="p">.</span><span class="mi">0</span><span class="n">e</span><span class="o">-</span><span class="mi">06</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">067754</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">067754</span><span class="w"> </span><span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">python3</span><span class="p">.</span><span class="mi">7</span><span class="o">/</span><span class="n">runpy</span><span class="p">.</span><span class="n">py</span><span class="p">:</span><span class="mi">195</span><span class="p">(</span><span class="n">run_</span>
<span class="mi">1</span><span class="w"> </span><span class="mi">6</span><span class="p">.</span><span class="mi">0</span><span class="n">e</span><span class="o">-</span><span class="mi">06</span><span class="w"> </span><span class="mi">6</span><span class="p">.</span><span class="mi">0</span><span class="n">e</span><span class="o">-</span><span class="mi">06</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">066135</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">066135</span><span class="w"> </span><span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="n">lib</span><span class="o">/</span><span class="n">python3</span><span class="p">.</span><span class="mi">7</span><span class="o">/</span><span class="n">runpy</span><span class="p">.</span><span class="n">py</span><span class="p">:</span><span class="mi">62</span><span class="p">(</span><span class="n">_run_</span>
<span class="mi">1</span><span class="w"> </span><span class="mi">1</span><span class="p">.</span><span class="mi">1</span><span class="n">e</span><span class="o">-</span><span class="mi">05</span><span class="w"> </span><span class="mi">1</span><span class="p">.</span><span class="mi">1</span><span class="n">e</span><span class="o">-</span><span class="mi">05</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">066113</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">066113</span><span class="w"> </span><span class="o">/</span><span class="n">home</span><span class="o">/</span><span class="n">venthur</span><span class="o">/</span><span class="n">Documents</span><span class="o">/</span><span class="n">projects</span><span class="o">/</span><span class="n">lit</span>
<span class="mi">1</span><span class="w"> </span><span class="mi">6</span><span class="p">.</span><span class="mi">6</span><span class="n">e</span><span class="o">-</span><span class="mi">05</span><span class="w"> </span><span class="mi">6</span><span class="p">.</span><span class="mi">6</span><span class="n">e</span><span class="o">-</span><span class="mi">05</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">055152</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">055152</span><span class="w"> </span><span class="o">/</span><span class="n">home</span><span class="o">/</span><span class="n">venthur</span><span class="o">/</span><span class="n">Documents</span><span class="o">/</span><span class="n">projects</span><span class="o">/</span><span class="n">lit</span>
<span class="mi">1</span><span class="w"> </span><span class="mi">4</span><span class="p">.</span><span class="mi">1</span><span class="n">e</span><span class="o">-</span><span class="mi">05</span><span class="w"> </span><span class="mi">4</span><span class="p">.</span><span class="mi">1</span><span class="n">e</span><span class="o">-</span><span class="mi">05</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">0549</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">0549</span><span class="w"> </span><span class="o">/</span><span class="n">home</span><span class="o">/</span><span class="n">venthur</span><span class="o">/</span><span class="n">Documents</span><span class="o">/</span><span class="n">projects</span><span class="o">/</span><span class="n">lit</span>
<span class="mi">1</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">050196</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">050196</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">050196</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">050196</span><span class="w"> </span><span class="o">~</span><span class="p">:</span><span class="mi">0</span><span class="p">(</span><span class="o"><</span><span class="k">method</span><span class="w"> </span><span class="s1">'executescript'</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="s1">'sqli</span>
<span class="s1">20/3 8.9e-05 4.45e-06 0.011064 0.003688 <frozen importlib._bootstrap>:978(_f</span>
<span class="s1">20/3 4.8e-05 2.4e-06 0.011005 0.00366833 <frozen importlib._bootstrap>:948(_f</span>
<span class="s1">20/3 7.5e-05 3.75e-06 0.01083 0.00361 <frozen importlib._bootstrap>:663(_l</span>
<span class="s1">15/3 3.5e-05 2.33333333333333e-06 0.01073 0.00357666 <frozen importlib._bootstrap_externa</span>
<span class="s1">29/5 2.5e-05 8.62068965517241e-07 0.010215 0.002043 <frozen importlib._bootstrap>:211(_c</span>
<span class="s1">3 6.0e-06 2.0e-06 0.010087 0.00336233 ~:0(<built-in method builtins.__impo</span>
<span class="s1">28/6 9.0e-06 3.21428571428571e-07 0.008977 0.00149616 <frozen importlib._bootstrap>:1009(_</span>
<span class="s1">1 9.0e-06 9.0e-06 0.00841 0.00841 /home/venthur/Documents/projects/lit</span>
<span class="s1">16 0.000138 8.625e-06 0.004802 0.00030012 <frozen importlib._bootstrap_externa</span>
<span class="s1">1 4.5e-05 4.5e-05 0.004143 0.004143 /usr/lib/python3.7/logging/__init__.</span>
<span class="s1">1 0.004038 0.004038 0.004038 0.004038 ~:0(<method '</span><span class="k">commit</span><span class="s1">' of '</span><span class="n">sqlite3</span><span class="p">.</span><span class="n">Con</span>
<span class="mi">13</span><span class="w"> </span><span class="mi">3</span><span class="p">.</span><span class="mi">3</span><span class="n">e</span><span class="o">-</span><span class="mi">05</span><span class="w"> </span><span class="mi">2</span><span class="p">.</span><span class="mi">53846153846154</span><span class="n">e</span><span class="o">-</span><span class="mi">06</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">002368</span><span class="w"> </span><span class="mi">0</span><span class="p">.</span><span class="mi">00018215</span><span class="w"> </span><span class="o"><</span><span class="n">frozen</span><span class="w"> </span><span class="n">importlib</span><span class="p">.</span><span class="n">_bootstrap_externa</span>
</code></pre></div> Syncing Exchange Server with Thunderbird 60 (again) 2018-09-02T00:00:00+02:00 2018-09-02T00:00:00+02:00 Bastian Venthur tag:venthur.de,2018-09-02:/2018-09-02-thunderbird-ews.html Syncing Exchange Server with Thunderbird 60 (again) <p>A couple weeks ago Mozilla Thunderbird <a href="https://www.thunderbird.net/en-US/thunderbird/60.0/releasenotes/">released version 60</a> and a lot
of extensions became incompatible. Amongst them <a href="https://github.com/ExchangeCalendar/exchangecalendar">Exchange Calendar</a>, an
extension that allows to sync calendars, tasks and contacts with a Microsoft
Exchange Server. That extension has served me well over the last years in my
job where we have to use the Exchange Server. Unfortunately it seems that the
extension will not be continued anymore, and I had to search for something
else.</p>
<p>After trying out some alternatives, I found the extension <a href="https://addons.thunderbird.net/en-US/thunderbird/addon/tbsync/">TbSync</a>. It
it uses Exchange Active Sync instead of EWS, so there are currently some
limitations with accessing shared calendars and contacts but for everything
else it works quite nice. Also the author is actively maintaining it and
working on <a href="https://github.com/jobisoft/EWS-4-TbSync">EWS support</a> as well.</p> Thanks! 2015-10-13T14:41:00+02:00 2015-10-13T14:41:00+02:00 Bastian Venthur tag:venthur.de,2015-10-13:/2015-10-13-thanks.html Thanks! <p>Two months ago I
<a href="2015-08-18-please-help-to-port-python-debianbts-to-python3.html">asked</a> for
help porting <a href="https://github.com/venthur/python-debianbts">python-debianbts</a>,
to Python3. Python-debianbts is a tiny little library that allows for querying
Debian’s bug tracking system. Since Debian’s reportbug depends on it, the
library is installed on ca 80% of the Debian installations. The main blocker
back then was that python-debianbts depended on SOAPpy which was not available
for Python3. So before we could port python-debianbts to Python3 we had to
migrate from SOAPpy to pysimplesoap – a daunting task given the beast that
SOAP is.</p>
<p>Fortunately, <a href="https://github.com/gaetano-guerriero">Gaetano Guerriero</a> heard
my call and helped <strong>a lot</strong>. First he migrated python-debianbts to
pysimplesoap. Then, he ported python-debianbts to Python3 and now he is still
busy fixing bugs and providing me with pull requests. I’m very satisfied with
the outcome. His pull requests are very high-quality and come usually with the
appropriate unit tests included. While he is doing the major grunt work, I
merely do some occasional nitpicking and uploading to Debian/unstable.</p>
<p>Thank you very much Gaetano! If you ever come to Berlin, please drop me a note
so I can invite you to a beer or two.</p> Please Help to Port python-debianbts to Python3 2015-08-18T13:07:00+02:00 2015-08-18T13:07:00+02:00 Bastian Venthur tag:venthur.de,2015-08-18:/2015-08-18-please-help-to-port-python-debianbts-to-python3.html Please Help to Port python-debianbts to Python3 <p>Dear Lazyweb,</p>
<p>I’m currently trying to find a way to port
<a href="https://tracker.debian.org/pkg/python-debianbts">python-debianbts</a> to
Python3. Debian’s standard bugreport tool
<a href="https://tracker.debian.org/pkg/reportbug">reportbug</a> depends on
python-debianbts and can thus not convert to Python3 if python-debianbts does
not as well. Unfortunately python-debianbts depends on
<a href="https://tracker.debian.org/pkg/python-soappy">SoapPy</a> for parsing the Debian
bugtracker’s responses, and that library is not ported to Python3 yet, and
probably never will.</p>
<p>I’m planning to replace SoapPy with
<a href="https://tracker.debian.org/pkg/python-pysimplesoap">pysimplesoap</a> which is
available for Python2 and Python3. Unfortunately
<a href="https://www.debian.org/Bugs/">debbugs</a> does not support
<a href="https://en.wikipedia.org/wiki/Web_Services_Description_Language">WSDL</a> which
makes parsing of the replies extremely painful and error-prone. I wonder if
there is a SOAP/Python expert out there who’d be willing to give some
assistance in porting python-reportbug to pysimplesoap? python-reportbug’s
<a href="https://github.com/venthur/python-debianbts">repository</a> is on GitHub and
patches are very welcome.</p>
<p>Since <a href="https://en.wikipedia.org/wiki/SOAP">SOAP</a> is quite a beast and debbugs
uses it for read-only purposes only, another attractive solution would be to
replace/augment debbugs’ API with something much more simple, like
<a href="https://en.wikipedia.org/wiki/JSON">JSON</a>. That would make parsing extremely
easy as many programming languages including Python support JSON without any
external libraries. In theory this could be quite easy but requires some
serious Perl skills.</p> General Resolution is not required 2014-11-19T09:21:00+01:00 2014-11-19T09:21:00+01:00 Bastian Venthur tag:venthur.de,2014-11-19:/2014-11-19-general-resolution-is-not-required.html General Resolution is not required <p>The result for the <a href="https://www.debian.org/vote/2014/vote_003">General
Resolution</a> about the init system
coupling is out and the result is, not quite surprisingly, “General Resolution
is not required”.</p>
<p>When skimming over -devel or -private from time to time, one easily gets the
impression that we are all a bunch of zealots, all too eager for fighting.
People argue in the worst possible ways. People make bold statements about the
future of Debian if solution X is preferred over Y. People call each other
names. People leave the project.</p>
<p>At some point you realize, we’re not <em>all</em> a bunch of zealots, it is usually
only the same small subset of people always involved in those discussions.
It’s reassuring that we still seem to have a <em>silent majority</em> in Debian that,
without much fuss, just do what they can to make Debian better. In this sense:
A General Resolution is not required.</p> What are the most popular .vimrc options? 2013-09-11T10:21:00+02:00 2013-09-11T10:21:00+02:00 Bastian Venthur tag:venthur.de,2013-09-11:/2013-09-11-what-are-the-most-popular-vimrc-options.html What are the most popular .vimrc options? <p>Hi always wondered what the most popular options are, you usually find in
<code>.vimrc</code> files. So I downloaded <strong>155</strong> <code>.vimrc</code> files from the net (mostly
from <a href="https://dotfiles.org">dotfiles.org</a> and
<a href="https://github.com">github.com</a>), and wrote a little
<a href="https://gist.github.com/venthur/6521228">script</a> which counts the number of
times an option has been set. Since most options come in normal- and shortcut
form, I mapped the shortcuts to the long version whenever I recognized them.</p>
<p>So without further ado, here are the most popular <code>.vimrc</code> options (without
values!). The number specifies the number of times this option has been set.
The most popular option is on the bottom:</p>
<blockquote>
<p>10 tselect<br>
10 dictionary<br>
10 runtimepath<br>
11 mousehide<br>
11 t_vb<br>
11 foldlevel<br>
11 foldopen<br>
12 suffixes<br>
12 matchtime<br>
12 fileencoding<br>
13 modelines<br>
13 wrap<br>
14 sidescrolloff<br>
14 clipboard<br>
14 lines<br>
14 novisualbell<br>
15 linebreak<br>
15 cursorline<br>
15 fileformats<br>
15 columns<br>
15 cindent<br>
16 undolevels<br>
16 shiftround<br>
16 lazyredraw<br>
16 completeopt<br>
18 modeline<br>
18 whichwrap<br>
18 comments<br>
18 wildignore<br>
19 list<br>
19 autowrite<br>
19 foldcolumn<br>
19 grepprg<br>
19 titlestring<br>
20 autoread<br>
20 title<br>
21 foldenable<br>
21 cmdheight<br>
22 pastetoggle<br>
23 formatoptions<br>
23 fileencodings<br>
24 tags<br>
24 directory<br>
25 ttyfast<br>
26 termencoding<br>
26 complete<br>
27 nohlsearch<br>
27 noerrorbells<br>
27 visualbell<br>
28 shortmess<br>
30 showmode<br>
31 wildmode<br>
32 t_Co<br>
32 listchars<br>
32 backupdir<br>
34 hidden<br>
34 backup<br>
35 smarttab<br>
35 foldmethod<br>
36 viminfo<br>
36 textwidth<br>
37 scrolloff<br>
37 nobackup<br>
41 nowrap<br>
44 encoding<br>
47 guifont<br>
51 guioptions<br>
53 smartcase<br>
54 wildmenu<br>
57 smartindent<br>
60 mouse<br>
63 background<br>
64 softtabstop<br>
66 history<br>
70 showmatch<br>
72 ignorecase<br>
74 showcmd<br>
74 laststatus<br>
79 number<br>
82 hlsearch<br>
91 statusline<br>
94 expandtab<br>
94 ruler<br>
96 autoindent<br>
96 backspace<br>
99 tabstop<br>
109 incsearch<br>
114 shiftwidth<br>
124 nocompatible</p>
<p>Out of 155 .vimrcs</p>
</blockquote>
<p>Fun fact: <code>nocompatible</code> is the most popular, but also most <strong>useless</strong> one.
The fact that you have an <code>.vimrc</code> automatically implies the <code>nocompatible</code>
mode in vim.</p> How to get the most precise time, comparable between processes in Python? 2013-05-15T11:49:00+02:00 2013-05-15T11:49:00+02:00 Bastian Venthur tag:venthur.de,2013-05-15:/2013-05-15-how-to-get-the-most-precise-time-comparable-between-processes-in-python.html How to get the most precise time, comparable between processes in Python? <p>Let’s consider the following scenario: I have two Python processes receiving
the same events and I have to measure the delay between when process A
received the event and when process B received it, as precisely as possible
(i.e. less than 1ms).</p>
<p>Using Python 2.7 and a Unix system you can use the <code>time.time</code> method which
provides the time in seconds since Epoch and has a typical resolution of a
fraction of a ms on Unix. You can use it on different processes and still
compare the results, since both processes receive the time since Epoch, a
defined and fixed time in the past.</p>
<p>On Windows time.time also provides the time since Epoch, but the resolution is
in the range of 10ms, which is not suitable for my application.</p>
<p>There is also <code>time.clock</code> which is super precise on Windows, and much less
precise on Unix. The mayor drawback is that it returns the time since the
process started or since the first call of <code>time.clock</code> <em>within that
processes</em>. This means you cannot compare the results of <code>time.clock</code> between
two processes as they are not calibrated to a common t-zero.</p>
<p>I had high hopes for Python 3.3 where the <code>time</code> module was revamped and I was
reading about <code>time.monotonic</code> and <code>time.perf_counter</code>. Especially
<code>time.perf_counter</code> looked like it would suit my needs as the
<a href="https://www.python.org/dev/peps/pep-0418/">documentation</a> said it provides
the highest available resolution for the system and was “system-wide”, in
contrast to for example the new <code>time.process_time</code> which was “process_wide”.
Unfortunately it turned out that <code>time.perf_counter</code> acts similar to
<code>time.clock</code> on Python 2.7 as it provides you with the time since the process
started or the first time the method was called <em>within the process</em>. The
results of <code>time.monotonic</code> are comparable between processes, but again not
precise enough on Windows.</p>
<p>Here is a small script which demonstrates how the times provided by
<code>time.clock</code> and <code>time.perf_counter</code> are not comparable between processes. It
starts two processes and lets both of them print out the output of the timer
to stdout. In the output the times should be monotonically increasing. Since I
let process 2 sleep for one second before calling the timer method for the
first time, the output of this process is usually one second smaller when
using <code>time.clock</code> or <code>time.perf_counter</code>.</p>
<div class="codehilite"><pre><span></span><code><span class="ch">#!/usr/bin/env python</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">multiprocessing</span><span class="w"> </span><span class="kn">import</span> <span class="n">Process</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">time</span>
<span class="n">timers</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'clock'</span><span class="p">,</span> <span class="s1">'time'</span><span class="p">,</span> <span class="s1">'monotonic'</span><span class="p">,</span> <span class="s1">'perf_counter'</span><span class="p">]</span>
<span class="k">def</span><span class="w"> </span><span class="nf">proc</span><span class="p">(</span><span class="n">timer</span><span class="p">):</span>
<span class="n">timer</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">time</span><span class="p">,</span> <span class="n">timer</span><span class="p">)</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</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">3</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'P2 </span><span class="si">{time}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">time</span><span class="o">=</span><span class="n">timer</span><span class="p">()))</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span>
<span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">timers</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Using </span><span class="si">{timer}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">timer</span><span class="o">=</span><span class="n">t</span><span class="p">))</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">Process</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">proc</span><span class="p">,</span> <span class="n">args</span><span class="o">=</span><span class="p">(</span><span class="n">t</span><span class="p">,))</span>
<span class="n">timer</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">time</span><span class="p">,</span> <span class="n">t</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">start</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">3</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'P1 </span><span class="si">{time}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">time</span><span class="o">=</span><span class="n">timer</span><span class="p">()))</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">p</span><span class="o">.</span><span class="n">join</span><span class="p">()</span>
</code></pre></div>
<p>The result when running on Windows with Python 3.3:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>python<span class="w"> </span>timertest.py
Using<span class="w"> </span>clock
P1<span class="w"> </span><span class="m">6</span>.146032526480321e-06
P1<span class="w"> </span><span class="m">0</span>.9926582847820045
P2<span class="w"> </span><span class="m">2</span>.9612702173041547e-05
P1<span class="w"> </span><span class="m">1</span>.9941743992602412
P2<span class="w"> </span><span class="m">1</span>.0008579302676737
P2<span class="w"> </span><span class="m">2</span>.0022709590185346
Using<span class="w"> </span><span class="nb">time</span>
P1<span class="w"> </span><span class="m">1368614235</span>.509732
P1<span class="w"> </span><span class="m">1368614236</span>.511172
P2<span class="w"> </span><span class="m">1368614236</span>.601301
P1<span class="w"> </span><span class="m">1368614237</span>.512612
P2<span class="w"> </span><span class="m">1368614237</span>.602741
P2<span class="w"> </span><span class="m">1368614238</span>.604181
Using<span class="w"> </span>monotonic
P1<span class="w"> </span><span class="m">484</span>.636
P1<span class="w"> </span><span class="m">485</span>.63800000000003
P2<span class="w"> </span><span class="m">485</span>.738
P1<span class="w"> </span><span class="m">486</span>.639
P2<span class="w"> </span><span class="m">486</span>.73900000000003
P2<span class="w"> </span><span class="m">487</span>.741
Using<span class="w"> </span>perf_counter
P1<span class="w"> </span><span class="m">12</span>.390910576623565
P1<span class="w"> </span><span class="m">13</span>.39050745276285
P2<span class="w"> </span><span class="m">7</span>.542858100680394e-06
P1<span class="w"> </span><span class="m">14</span>.39190763071843
P2<span class="w"> </span><span class="m">1</span>.0014012954160376
P2<span class="w"> </span><span class="m">2</span>.0041399116368144
</code></pre></div>
<p>So as far as I see it, there is no way of getting comparable times between two
processes on Windows with more precision than 10ms. Is that correct or am I
missing something?</p> Wee! Wheezy is out (better late than never) 2013-05-11T10:57:00+02:00 2013-05-11T10:57:00+02:00 Bastian Venthur tag:venthur.de,2013-05-11:/2013-05-11-wee-wheezy-is-out-better-late-than-never.html Wee! Wheezy is out (better late than never) <p>Last week we <a href="https://lists.debian.org/debian-announce/2013/msg00002.html">released
Wheezy</a>, roughly
two years after our last release Squeeze.</p>
<p>I’d like to thank all the contributors in- and outside of Debian for your fine
work! Every single contribution – no matter how big or small – summed up to
the wonderful release we finished last week. Without you this release would
not have been possible. Keep up the good work guys and make Jessie rock even
harder!</p>
<p>PS: It is very nice to see once again fresh packages rolling into unstable and
spending some time fixing broken dependencies :)</p> Synchronizing Google Mail Contacts with Thunderbird 2013-01-30T12:37:00+01:00 2013-01-30T12:37:00+01:00 Bastian Venthur tag:venthur.de,2013-01-30:/2013-01-30-synchronizing-google-mail-contacts-with-thunderbird.html Synchronizing Google Mail Contacts with Thunderbird <p>Dear Lazyweb,</p>
<p>can anyone recommend a good Thunderbird extension which allows for
synchronizing the address book with Google mail? So far I tried <a href="https://addons.mozilla.org/en-us/thunderbird/addon/google-contacts/">Google
Contacts</a>,
but something went wrong with the syncing and some contacts where deleted on
both sides. To avoid this problem, one can use Google Contacts in read-only
mode (it will only fetch contacts from Google, but never write to it) but then
you have to import new Thunderbird contacts to Google mail manually.</p>
<p>Google introduced
<a href="https://googleblog.blogspot.de/2012/12/winter-cleaning.html">CardDav</a> in
December 2012, which allows for syncing of contacts, but since Thunderbird’s
development is apparently on hold this is probably not gonna be supported
out-of-the-box. There are some other extensions for Thunderbird, but since
synchronization is hard and a lot more complicated than: “replace newer
version with older one” I’m looking for something mature and well tested.</p>
<p>Before someone suggests it, I know Evolution has this feature built-in. I gave
it a try last week and found so many other grave bugs with the calendar and
newsgroups that Evolution is simply unfit for my needs. I really like
Thunderbird and want to stick with it for a few more years until I have to
look for something else.</p>
<p>Yours truly,</p>
<p>Basti</p> Shiny new iPod Nano 6G... fffffffuuuuuuuuuuuu 2013-01-08T11:59:00+01:00 2013-01-08T11:59:00+01:00 Bastian Venthur tag:venthur.de,2013-01-08:/2013-01-08-shiny-new-ipod-nano-6g-fffffffuuuuuuuuuuuu.html Shiny new iPod Nano 6G... fffffffuuuuuuuuuuuu <p>So I got an <a href="https://en.wikipedia.org/wiki/IPod_Nano">iPod Nano (6th
generation)</a> for Christmas this year,
just in time since my trusty old iPod Mini started beg for retirement after
almost 8 years of usage.</p>
<p>Since my old iPod was working like a charm all those years I expected a smooth
sailing when I plugged in my new iPod Nano. Gnome recognized it correctly and
mounted the device. The iPod showed up in
<a href="https://projects.gnome.org/rhythmbox/">Rhythmbox</a> as I was used to and I
started to fill it with some music. Everything worked as expected: Rhythmbox
copied the music to the iPod without complaining and after unmounting the iPod
and starting it – it was emtpy. Whait, what? Why is it empty? Didn’t I
just… So I tried again, and again with the same result.</p>
<p>Half an hour later I found out that
<a href="https://www.gtkpod.org/wiki/Libgpod">libgpod</a> (the iPod “driver” for Linux)
supports all iPods <strong>except</strong> the iPod Nano 6G. Bummer. Apparently
<a href="https://apple.com">Apple</a> changed the algorithm to calculate the checksums of
the files on the device and since that algorithm is unknown you cannot
successfully write on it with free software.</p>
<p>That means technically this device is unusable for Linux users since iTunes
doesn’t run on Linux. However, there seems to be a way to use the iPod Nano
with libgpod if you are trusting <a href="https://franck78.ath.cx/">this guy</a> and
willing to use his binary (only!) file with libgpod (which I am not). And
somehow the guys over at <a href="https://www.spotify.com/">Spotify</a> managed to get
the iPod Nano running in their <a href="https://www.spotify.com/de/download/previews/">Linux
client</a> but they don’t provide
the code either.</p>
<p>Being already more than two years old, I don’t have much hope that the iPod
Nano will work on Linux with libgpod in the foreseeable future. On the bright
side I can say the device is not totally useless as it comes with FM radio…</p> Introducing The Art of Asking 2012-11-02T09:29:00+01:00 2012-11-02T09:29:00+01:00 Bastian Venthur tag:venthur.de,2012-11-02:/2012-11-02-introducing-the-art-of-asking.html Introducing The Art of Asking <p>Since October 2011 my flatmate and I where quite busy realizing a little pet
project of ours called <a href="https://theartofasking.com">The Art of Asking</a>. The
ultimate goal is to visualize the world’s opinion in an intuitive fashion and
make it easy for everyone to play around with the data.</p>
<p>The idea behind The Art of Asking is that users submit interesting questions
which are answered by users around the world. But instead of showing only the
boring result, we want to provide interesting insights and statistics about
the answers given.</p>
<p>For now the users can see the results of the question visualized by
geographical regions. For example on the page for the question <a href="https://theartofasking.com/question/wjucdg6k">‘How are you
today?’</a> you can see the
interactive map with the pie chart. The map shows the average/dominating
answer for each continent encoded by color, and the pie chart the distribution
of the different answers for that region. If you move the mouse over a
continent the pie chart updates and shows the distribution of answers for that
continent. You can also click to zoom into the map to see the same for
countries and regions. This allows you to investigate how the answers are
distributed around the world.</p>
<p><img alt="" src="/images/taoa1.png" title="The Art of Asking Screenshot"></p>
<p>This is already quite nice and fancy to play around with, but of course we
want much more. Right now we’re working on a feature which will users allow to
<em>combine</em> two arbitrary questions and see how the answers are related. This
doesn’t sound like much, but it is <strong>very</strong> addictive to crawl through the
list of questions and find interesting correlations. Here is a little plot how
it could look like (the data is from the actual data base of answers).</p>
<p><img alt="" src="/images/gay_marrigage_vs_fashion.png" title="Support of gay marriage vs Importance of fashion"></p>
<p>For each possible combination of answers it shows the percentage of people who
answered in that combination. Of course those plots only make sense when
enough users answered for both questions you want to compare which is right
now not very often the case, so I guess we’ll roll out that feature sometime
later when we have more data. But we have lots of ideas and are working on
further ways to investigate the answers. Obviously one low hanging fruit for
example would be the distribution of the answers over time.</p>
<p>We’ve been working for over a year now on this project in our spare time and
we built it more or less from scratch. I wrote a small
<a href="https://en.wikipedia.org/wiki/Web_Server_Gateway_Interface">WSGI</a> framework
in <a href="https://python.org">Python</a> and on top of that the WSGI application which
runs the site. We use <a href="https://www.mongodb.org/">MongoDB</a> for the storage of
the data, <a href="https://projects.unbit.it/uwsgi/">uWSGI</a> and
<a href="https://nginx.org/">nginx</a> for the server,
<a href="https://jinja.pocoo.org/docs/">Jinja2</a> and
<a href="https://twitter.github.com/bootstrap/">Bootstrap</a> for the HTML and
<a href="https://d3js.org/">D3.js</a> for the visualization of the data, where
<a href="https://www.user.tu-berlin.de/fazli/">Maci</a> did a wonderful job realizing the
interactive map and charts.</p>
<p>We’re running this site since July 2012 now and are already quite satisfied
with the number of users, and the quality of the questions. But of course we
could always use more (especially more answers). So if you want to try it out,
go to <a href="https://theartofasking.com">theartofasking.com</a> and fill out the blank
spots on the map! We’re happy about every answer and question we can get and
are eager to hear your suggestions.</p> Give Camp Berlin looking for volunteers 2012-10-26T15:05:00+02:00 2012-10-26T15:05:00+02:00 Bastian Venthur tag:venthur.de,2012-10-26:/2012-10-26-give-camp-berlin-looking-for-volunteers.html Give Camp Berlin looking for volunteers <p>My friend Martijn from <a href="https://talentspender.org">Talentspender</a> is
co-organizing a Give Camp in Berlin. They are looking for IT professionals and
designers who want to spend one weekend of their time to support non-profit
organizations to solve a specific problem at the Give Camp. It is for a good
cause and there is no further commitment after the Camp. Plus you will be
provided with free food and drinks. So if you are interested and happen to be
in <strong>Berlin between 30. November and 02. December 2012</strong> have a look at their
<a href="https://berlin.givecamp.de/en">website</a> and
<a href="https://berlin.givecamp.de/tech-registration/">register</a> for the GiveCamp.</p>
<p>Quoting from their flyer:</p>
<blockquote>
<p>A GiveCamp is a weekend-long event where technology professionals donate
their time to provide custom solutions for non-profit organizations.
Voluntarily, without further commitment and for a good cause: the long-term
strengthening of the organizations.</p>
<p><strong>How does it work?</strong></p>
<ul>
<li>Teamwork of experts during one weekend, with regular input from the NPOs</li>
<li>Clearly defined projects, to be completed at the GiveCamp</li>
<li>Young professionals mentored by experienced experts</li>
<li>Meals and drinks are provided</li>
</ul>
<p><strong>Who are we looking for?</strong></p>
<ol>
<li>Software developers, database administrators, designers and entrepreneurs</li>
<li>From students to senior experts</li>
<li>Team players with enthusiasm for interdisciplinary projects</li>
</ol>
</blockquote> Awesome Firefox Campaign 2012-08-30T20:07:00+02:00 2012-08-30T20:07:00+02:00 Bastian Venthur tag:venthur.de,2012-08-30:/2012-08-30-awesome-firefox-campaign.html Awesome Firefox Campaign <p>Gil writes about the awesome <a href="https://gil.badall.net/2012/08/29/red-pandas-are-taking-over-alexanderplatz/">Firefox ad
campaign</a>
running currently in Berlin Alexanderplatz. Good stuff!</p> Happy Birthday Debian! 2012-08-16T08:27:00+02:00 2012-08-16T08:27:00+02:00 Bastian Venthur tag:venthur.de,2012-08-16:/2012-08-16-happy-birthday-debian-3.html Happy Birthday Debian! <p>19 Years and still rocking! Huge thanks to all contributors for making this
happen and a happy birthday Debian!</p> Usability of git-http-backend with self signed SSL certificates 2012-08-03T09:29:00+02:00 2012-08-03T09:29:00+02:00 Bastian Venthur tag:venthur.de,2012-08-03:/2012-08-03-usability-of-git-http-backend-with-self-signed-ssl-certificates.html Usability of git-http-backend with self signed SSL certificates <p>Why makes it git so hard to use a self signed SSL certificate in conjunction
with the https protocol?</p>
<p>At work we have a server for shared git repositories. For some reasons we
can’t use the ssh protocoll to acces the repositories so we looked into the
<a href="https://www.kernel.org/pub/software/scm/git/docs/git-http-backend.html">git-http-backend</a>.
So far so good but we want it encrypted, of course. So we used SSL with our
self signed certificate:</p>
<div class="codehilite"><pre><span></span><code><span class="nv">git</span><span class="w"> </span><span class="nv">clone</span><span class="w"> </span><span class="nv">https</span>:<span class="o">//</span><span class="nv">git</span>.<span class="nv">example</span>.<span class="nv">com</span><span class="o">/</span><span class="nv">public</span>
<span class="nv">Cloning</span><span class="w"> </span><span class="nv">into</span><span class="w"> </span><span class="s1">'public'</span>...
<span class="nv">error</span>:<span class="w"> </span><span class="nv">server</span><span class="w"> </span><span class="nv">certificate</span><span class="w"> </span><span class="nv">verification</span><span class="w"> </span><span class="nv">failed</span>.
<span class="nv">CAfile</span>:<span class="w"> </span><span class="o">/</span><span class="nv">etc</span><span class="o">/</span><span class="nv">ssl</span><span class="o">/</span><span class="nv">certs</span><span class="o">/</span><span class="nv">ca</span><span class="o">-</span><span class="nv">certificates</span>.<span class="nv">crt</span>
<span class="nv">CRLfile</span>:<span class="w"> </span><span class="nv">none</span>
<span class="k">while</span><span class="w"> </span><span class="nv">accessing</span><span class="w"> </span><span class="nv">https</span>:<span class="o">//</span><span class="nv">git</span>.<span class="nv">example</span>.<span class="nv">com</span><span class="o">/</span><span class="nv">public</span><span class="o">/</span><span class="nv">info</span><span class="o">/</span><span class="nv">refs</span><span class="w"> </span><span class="nv">fatal</span>:<span class="w"> </span><span class="nv">HTTP</span><span class="w"> </span><span class="nv">request</span><span class="w"> </span><span class="nv">failed</span>`
</code></pre></div>
<p>Huh? Looking deeper into the problem it turns out that git uses
<a href="https://curl.haxx.se/">curl</a> for the http(s) transport and curl refuses to
work with SSL certificates it cannot verify.</p>
<p>Ok, that’s not a bad thing. To circumvent that you can either set an
environment variable (<code>GIT_SSL_NO_VERIFY=1</code>) to make curl ignore the
verification or install the certificate on your machine. The first option is
not very attractive on the long term as you’d have to do it on every operation
with the remote server, the second one is not very attractive when dealing
with multiple developers working on different operating systems. You’ll have
to explain to them how to install the certificate on their machine, and that
has to be done every time a new developer joins the team, yada, yada.</p>
<p>There is also an option in git (<code>http.sslverify</code>) you can set where you can
tell git to ignore the verification of the SSL certificate for that
repository. The thing is you still have to set the environment variable on the
first clone and then you have to tell git to permanently ignore this issue for
that repository with the configuration option – a lot of stuff to remember.
Heck, looking on the interwebs I see may of the people with that problem
suggesting to shut of SSL cert verification permanently by setting it
<strong>globally</strong>.</p>
<p>I really wonder why git cannot simply tell the user that the SSL certificate
cannot be verified and if you want to accept it permanently, temporarily or
not. Every browser does that. Right now it just quits with an error and leaves
the user with a cryptic error.</p>
<p>On the other side, when using git with a server providing the repositories via
ssh. Git simply asks if you want to accept the key when you access the server
for the first time and never bothers you again.</p> Suggestions for a Graphics Tablet? 2012-07-26T10:02:00+02:00 2012-07-26T10:02:00+02:00 Bastian Venthur tag:venthur.de,2012-07-26:/2012-07-26-suggestions-for-a-graphics-tablet.html Suggestions for a Graphics Tablet? <p>Dear Lazyweb,</p>
<p>I’m looking for a good graphics tablet. I’ll mainly use it for post processing
DSLR photos with <a href="https://rawtherapee.com/">Raw Therapee</a>, Bibble, and
<a href="https://www.gimp.org/">Gimp</a>. It should be cheaper than 200 EUR and must work
with Debian/Sid (of course). I’d rather not have to install any fancy drivers,
it should work out of the box.</p>
<p>Any suggestions?</p> .inputrc 2012-06-26T14:46:00+02:00 2012-06-26T14:46:00+02:00 Bastian Venthur tag:venthur.de,2012-06-26:/2012-06-26-inputrc.html .inputrc <p>A few days ago I found <a href="https://blog.sanctum.geek.nz/lazier-tab-completion/">this
blog</a> explaining how to
improve the tab completion by tinkering with your .inputrc.</p>
<p>The magic lines are:</p>
<div class="codehilite"><pre><span></span><code><span class="nv">set</span><span class="w"> </span><span class="k">show</span><span class="o">-</span><span class="nv">all</span><span class="o">-</span><span class="k">if</span><span class="o">-</span><span class="nv">ambiguous</span><span class="w"> </span><span class="nv">on</span>
<span class="nv">set</span><span class="w"> </span><span class="nv">completion</span><span class="o">-</span><span class="nv">ignore</span><span class="o">-</span><span class="nv">case</span><span class="w"> </span><span class="nv">on</span>
<span class="nv">set</span><span class="w"> </span><span class="nv">completion</span><span class="o">-</span><span class="nv">map</span><span class="o">-</span><span class="nv">case</span><span class="w"> </span><span class="nv">on</span>
</code></pre></div>
<p>Last two lines make tab-completion ignore case, hyphens, underscores, the
first one spares you one tab when more than one match was found. Very neat! I
would have never found out, since there wasn’t even an .inputrc in my home
directory.</p>
<p>Do you know any other cool .inputrc-tricks?</p> Can aptitude show older versions of packages if available in /var/cache/apt/archives? 2012-02-09T11:10:00+01:00 2012-02-09T11:10:00+01:00 Bastian Venthur tag:venthur.de,2012-02-09:/2012-02-09-can-aptitude-show-older-versions-of-packages-if-available-in-varcacheaptarchives.html Can aptitude show older versions of packages if available in /var/cache/apt/archives? <p>Dear Lazyweb,</p>
<p>is it possible to tell aptitude to show older versions of a package next to
the currently available one if it is still present in
<code>/var/cache/apt/archives</code>? Like it does when you use unstable and experimental
side by side? I know that aptitude does not really support downgrades of
packages, but showing those packages directly in aptitude if available in the
cache is a lot easier than searching them in the file system and installing
them manually, especially if you don’t know where they hide.</p> Helping awstats to correctly interpret lighttpd's log format 2012-01-26T11:53:00+01:00 2012-01-26T11:53:00+01:00 Bastian Venthur tag:venthur.de,2012-01-26:/2012-01-26-helping-awstats-to-correctly-interpret-lighttpds-log-format.html Helping awstats to correctly interpret lighttpd's log format <p>Note to self:</p>
<p>when configuring awstats using lighttpd logfiles, you have to use the
following log format:</p>
<div class="codehilite"><pre><span></span><code>LogFormat="%host %virtualname %logname %time1 %methodurl %code %bytesd %refererquot %uaquot"
</code></pre></div>
<p>neither 1 nor 4 will work correctly.</p> How to get a list of manually installed packages (and remove the other ones) 2011-12-13T23:31:00+01:00 2011-12-13T23:31:00+01:00 Bastian Venthur tag:venthur.de,2011-12-13:/2011-12-13-how-to-get-a-list-of-manually-installed-packages.html How to get a list of manually installed packages (and remove the other ones) <h2>The Good</h2>
<p>Every other year or so I feel the need to clean up my Debian system and remove
the installed packages I’m not interested in anymore. I remember there was a
nice aptitude pattern to search for packages which I have <em>manually</em> installed
(i.e. which were not installed to satisfy a dependency). Ideally I would then
go through the (presumably short) list of packages and remove the ones I don’t
need any more.</p>
<p>Since I always forget the aptitude pattern to search for those packages, I
google for something like “list of manually installed packages” and find a
solution like: <code>aptitude search ‘~i !~M’</code>. Although this solution is not
wrong, it is not quite what I was looking for. Sure, it will find you all
packages which are installed and not installed to satisfy a dependency, but it
also contains packages of priorities: required, important and standard which
you usually don’t want to deinstall. So the actual solution should also
exclude those packages.</p>
<div class="codehilite"><pre><span></span><code>aptitude<span class="w"> </span>search<span class="w"> </span><span class="s1">'~i !~M !~pstandard !~pimportant !~prequired'</span>
</code></pre></div>
<p>The above line will do the trick and present you a list of packages which are:
installed and not dragged in to satisfy a dependency and not of priority
standard, important or required.</p>
<p>If you where only interested in the solution of the quest of getting a list of
all manually installed packages you can stop reading here.</p>
<h2>The Bad</h2>
<p>If you’re running your system for longer than, say, a few weeks you will
probably notice that the list is <em>very</em> long and contains much more packages
than you actually installed manually. You will probably notice a lot of libs
and other packages in this list and wonder why they aren’t marked <code>auto</code> as
they should since you didn’t install them on purpose. Unfortunately I don’t
have an answer for that question. I’m using aptitude exclusively to install
packages and rely on the fact that aptitude does install the dependencies
automatically and more importantly: also removes them if not needed any more.
But it seems like something is broken in aptitude (or somewhere else) and
packages simply lose their <code>auto</code> status instead of being removed and thus
stay on your system forever if you don’t manually clean your system.</p>
<h2>The Ugly</h2>
<p>To solve that issue I started aptitude and filtered the package tree with the
above pattern (press <code>l</code> in aptitude and enter <code>~i !~M !~pstandard
!~pimportant !~prequired</code>). Now the package view shows only packages which are
safe to remove since they are not of of priority standard or higher and
manually installed by you. Now I navigate with the cursor to the list of
installed packages an mark all of them as <code>auto</code> by pressing <code>M</code>. For each
package in this list, aptitude will try to find an installed package which
depends on that package and mark that package <code>auto</code>. The remaining packages
which no other packages depend on, aptitude will mark for deletion. If you now
press <code>g</code> one time, aptitude will show you which packages will be removed. I
then go through that list and mark every single of the remaining packages I
really want on my system with <code>+</code> as manually installed. After I’m done I
proceed by pressing <code>g</code> again which will remove all remaining packages. In my
case nearly 600 packages (1GB) where removed.</p>
<h2>Bugreport!</h2>
<p>I assume there is a bug in aptitude or some related package which sometimes(!)
removes a packages <code>auto</code> status instead of removing it. Unfortunately I did
not find a way to reproduce that (except that it obviously <em>does</em> happen). If
someone could find a way to reproduce that problem, one could fill a bugreport
and help to get that bug fixed. Right now, a Debian system suffers (like many
other operating systems) from a slow but steadily growing bloat of installed
software. In my case 600 packages with 1GB accumulated over one or two years.</p> No sound with Gnome 3 and pulseaudio? 2011-11-16T08:43:00+01:00 2011-11-16T08:43:00+01:00 Bastian Venthur tag:venthur.de,2011-11-16:/2011-11-16-no-sound-with-gnome-3-and-pulseaudio.html No sound with Gnome 3 and pulseaudio? <p>Dear Lazyweb,</p>
<p>I recently switched from KDE to Gnome 3 and I am so far very happy with the
decision. One thing that bothers me since then is that the sound does not work
when restarting the computer or waking it up from suspend. After a while I
figured that a simple <code>sudo killall pulseaudio</code> fixes the problem – but only
until the next reboot. Has anyone a hint what the problem could be/ I found
quite a few similar problem descriptions on the internet but with no
satisfying solutions so far.</p> Speech Recognition Software 2011-10-05T12:10:00+02:00 2011-10-05T12:10:00+02:00 Bastian Venthur tag:venthur.de,2011-10-05:/2011-10-05-speech-recognition-software.html Speech Recognition Software <p>Dear Lazyweb,</p>
<p>Having broke my elbow last week, I’m experiencing serious trouble typing with
only one hand on the computer. I know that there is speech to text software,
but I was never really interested in that – until now of course. Is there any
good software available on Linux you can recommend?</p> KDE4's annoying taskbar 2011-08-25T09:12:00+02:00 2011-08-25T09:12:00+02:00 Bastian Venthur tag:venthur.de,2011-08-25:/2011-08-25-kde4s-annoying-taskbar.html KDE4's annoying taskbar <p>Dear Lazyweb,</p>
<p>since KDE4 is in unstable, the taskbar behaves very annoyingly when working
with two monitors with different resolutions. I have a laptop. When I’m at
work, I put it into a docking station which is connected to a huge monitor.
I’m not working with dualhead or something, I’m just using the huge monitor at
work and the laptop’s screen at home.</p>
<p>I always want the taskbar to be <em>maximized</em>. The problem is, that KDE’s
taskbar fails to adjust the size of the taskbar correctly: Starting KDE at
work, the taskbar is always too small (as wide as the laptop’s monitor) and my
first task is to maximize the taskbar. Starting KDE when I’m back home, the
taskbar is too wide (as wide as the external monitor’s size) for the smaller
monitor and I have to (ironically) maximize it again to fit on the now smaller
monitor.</p>
<p>Note that I’m not using suspend or something. I’m booting the laptop with the
big screen connected or not.</p>
<p>I also had that problem with KDE3, but that was fixed upstream long time ago.
Has anyone a solution how to avoid this problem?</p> Happy Birthday Debian! 2011-08-17T11:25:00+02:00 2011-08-17T11:25:00+02:00 Bastian Venthur tag:venthur.de,2011-08-17:/2011-08-17-happy-birthday-debian-2.html Happy Birthday Debian! <p><a href="https://www.debian.org/News/2011/20110816">18 Years</a> and still rocking!</p> Not coming to DebConf 2011-06-30T10:22:00+02:00 2011-06-30T10:22:00+02:00 Bastian Venthur tag:venthur.de,2011-06-30:/2011-06-30-not-coming-to-debconf.html Not coming to DebConf <p>Unfortunately Debian cannot sponsor my trip to Banja Luka this year and it’s
too expensive to pay it from my own budget. Thus I just cancelled my
attendance for the conference. I’m very sad, since my first DebConf last year
in NY was a lot of fun and I was really looking forward to see you guys again
this year.</p>
<p>I wish you a lot of fun anyways. Have a productive and fun conference!</p> I'm going to DebConf11 2011-05-30T09:27:00+02:00 2011-05-30T09:27:00+02:00 Bastian Venthur tag:venthur.de,2011-05-30:/2011-05-30-im-going-to-debconf11.html I'm going to DebConf11 <p>Weee! After the excellent experience last year in New York, I couldn’t resist
:)</p>
<p>See you all in Banja Luka!</p> Installing Dropbox in Debian/Sid 2011-04-28T20:07:00+02:00 2011-04-28T20:07:00+02:00 Bastian Venthur tag:venthur.de,2011-04-28:/2011-04-28-installing-dropbox-in-debiansid.html Installing Dropbox in Debian/Sid <p>A few months ago dropbox was a Debian packge in non-free. Recently I noticed
that there are several new versions available and tried to notifiy the
maintainer and ask him to update the package. But unfortunately it looks like
the package is not available any more (<a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=610300">Here’s
why</a>).</p>
<p>However getting Dropbox is quite easy if you know what to do.</p>
<p>The obvious choice would be to go to <a href="https://dropbox.com">dropbox.com</a> and
download either the source package and compile it yourself or try to install
the precompiled Ubuntu packages. The first option is not really an option for
most users and the second one does currently not work on Debian/Sid (aka
unstable).</p>
<p>However, there is an easy solution: on the download page search for the CLI
script (currently it is named dropbox.py) Download that and run it with
<code>python dropbox.py start -i</code>. That will download the propritary binaries into
<code>~/.dropbox-dist</code>. Now go into that folder and start <code>dropboxd</code>. There you go,
you have a fully working systray app for dropbox.</p>
<p>Depending on your desktop environment you might want to put <code>dropboxd</code> in your
“autostart”. So you don’t have to start the daemon every time you login. And
that’s it.</p>
<p>It is not really ideal, since a Debian package would be much better for
updates, security, yada yada, but it’s still better than nothing.</p> Introducing python-ardrone 2011-04-20T14:47:00+02:00 2011-04-20T14:47:00+02:00 Bastian Venthur tag:venthur.de,2011-04-20:/2011-04-20-introducing-python-ardrone.html Introducing python-ardrone <p><img alt="Flying AR.Drone" src="/images/2011-04-15_10-41-55-small.jpg" title="AR.Drone"></p>
<p>The last weeks I spend quite a lot of time hacking on a Python library for the
<a href="https://ardrone.parrot.com/">AR.Drone</a>. The AR.Drone is a nice toy for nerds.
You connect to it via WIFI and soon you’ll realize that it has 4 ports open.
Reading the specs you’ll find, that on one port it listens for AT-Commands
with which you can remote control the drone, on the other two ports it waits
for an incoming package which will trigger the drone to send the navdata
(speed, angles, battery status, etc) and the video stream. Heck, you can even
telnet into the drone…</p>
<p>Unfortunately it comes without a proper software to control the drone, only an
iPhone app (w/o iPhone of course). But given the documentation, it should be
easy to write your own. While getting the beast to fly was relatively easy,
decoding the “almost”-jpg-video-stream was not. Almost-jpg, since the images
the drone sends are more or less jpg with a <em>small</em> difference which makes it
impossible to decode them using standard multi-media libraries. Anyways, the
format is documented and implementing a decoder was not that hard. The tricky
part was to get the framerates from unacceptable 0.5 FPS to 12-22 FPS – the
whole decoder is written in Python. I’m cheating a bit by using
<a href="https://psyco.sourceforge.net/">psyco</a>, but the code in arvideo.py is heavily
optimized to minimize calculations and to please psyco.</p>
<p>In the code is also a small demo app which uses <a href="https://pygame.org/">Pygame</a>
to display the video stream and allows to control the AR.Drone with the
keyboard. It should be ready-to-use as soon as you are connected to the drone
via WIFI.</p>
<p>The git repository is <a href="https://github.com/venthur/python-ardrone">here</a>, the
license is MIT. Suggestions and patches are welcome.</p>
<p><a href="https://youtu.be/EmQOEX9a3tM">Here</a> is a video of the drone flying through the
office.</p> Dear Lazyweb 2011-04-06T10:31:00+02:00 2011-04-06T10:31:00+02:00 Bastian Venthur tag:venthur.de,2011-04-06:/2011-04-06-dear-lazyweb-2.html Dear Lazyweb <p>After todays or yesterdays daily package update (Sid) several kernel modules,
namely <code>thinkpad_acpi</code>, <code>snd-hda-intel</code> and probably others are not loaded
automatically anymore. So my <a href="2008-11-25-lenovo-t500-shiny-new-laptop.html">Thinkpad
T500</a> had no support for audio and
several power management functions anymore. Once I found out that the missing
kernel modules where the problem, the fix was easy: just add the corresponding
module names to <code>/etc/modules</code> to enforce loading of the modules. But I wonder
what caused the sudden change? Why are the modules not loaded automatically
anymore? I usually update my Sid packages every morning so some package update
from yesterday or today might have caused this. Looking at the packages which
where updated, I found nothing suspicious. Has anyone an idea at which package
I should look?</p>
<p><strong>Update:</strong> <a href="https://bugs.debian.org/620995">Looks</a> like the problem was
related to the recent update of <code>base-files</code> to version 6.2 which introduced
the new <code>/run</code> directory in combination with udev. Downgrading <code>base-files</code> to
version 6.1 (via
<a href="https://snapshot.debian.org/package/base-files/6.1/#base-files_6.1">snapshot.debian.org</a>)
fixed the problem.</p> Summer School: Advanced Scientific Programming in Python 2011-03-01T16:03:00+01:00 2011-03-01T16:03:00+01:00 Bastian Venthur tag:venthur.de,2011-03-01:/2011-03-01-summer-school-advanced-scientific-programming-in-python.html Summer School: Advanced Scientific Programming in Python <p>Once again, there will be another round of the Summer School “Advanced
Scientific Programming in Python”. This year in St. Andrews, UK.</p>
<p>Quoting from the <a href="https://python.g-node.org/wiki/">official announcement</a>:</p>
<blockquote>
<p>Scientists spend more and more time writing, maintaining, and debugging
software. While techniques for doing this efficiently have evolved, only few
scientists actually use them. As a result, instead of doing their research,
they spend far too much time writing deficient code and reinventing the
wheel. In this course we will present a selection of advanced programming
techniques, incorporating theoretical lectures and practical exercises
tailored to the needs of a programming scientist. New skills will be tested
in a real programming project: we will team up to develop an entertaining
scientific computer game.</p>
<p>We use the Python programming language for the entire course. Python works
as a simple programming language for beginners, but more importantly, it
also works great in scientific simulations and data analysis. We show how
clean language design, ease of extensibility, and the great wealth of open
source libraries for scientific computing and data visualization are driving
Python to become a standard tool for the programming scientist.</p>
<p>This school is targeted at PhD students and Post-docs from all areas of
science. Competence in Python or in another language such as Java, C/C++,
MATLAB, or Mathematica is absolutely required. Basic knowledge of Python is
assumed. Participants without any prior experience with Python should work
through the proposed introductory materials before the course.</p>
</blockquote>
<p>You can apply on-line at <a href="https://python.g-node.org">https://python.g-node.org</a></p>
<p>Applications must be submitted before May 29, 2011. Notifications of
acceptance will be sent by June 19, 2011.</p>
<p>No fee is charged but participants should take care of travel, living, and
accommodation expenses. Candidates will be selected on the basis of their
profile. Places are limited: acceptance rate in past editions was around 30%.
Prerequisites: You are supposed to know the basics of Python to participate in
the lectures. Please consult the website for a list of introductory material.</p>
<p>If you’re a scientist and interested in Python, I cannot recommend this summer
school highly enough. The Summer School is always fun, the faculty members are
very nice and always willing to help and answer questions. The balance between
lectures and exercises is in my opinion very good, and you’ll learn a lot
about Python during the week. The highlight of every Python School is always
the Pac Man tournament, where groups of students will implement their own Pac
Man agent (in Python) and compete against the other agents in a tournament
‘till the bitter end!</p>
<p>The students of the previous editions were usually very happy during and after
the School. Speaking of happiness, since no fee is charged for the Summer
School, you’ll have more money left over to invest into the excellent Scottish
pubs!</p> Squeeze 2011-02-06T11:31:00+01:00 2011-02-06T11:31:00+01:00 Bastian Venthur tag:venthur.de,2011-02-06:/2011-02-06-squeeze.html Squeeze <p>Tonight Squeeze was released! Along with the release came a redesign of our
<a href="https://debian.org">website</a> and <a href="https://planet.debian.org">planet</a>. Nice!
I’m particularly happy that we’ll see lots of fresh software and updates in
unstable again, now that it is not frozen anymore.</p>
<p>Thanks to all contributors. Keep up the good work!</p> Canon IXUS 130 2010-12-30T01:30:00+01:00 2010-12-30T01:30:00+01:00 Bastian Venthur tag:venthur.de,2010-12-30:/2010-12-30-canon-ixus-130.html Canon IXUS 130 <p>Dear Lazyweb,</p>
<p>Today I bought me a Canon IXUS 130 and was quite disappointed to see that it
couldn’t properly connect to my Debian/Sid machine via USB. Apparenty the
camera is not recognized as a USB Mass Storage Device but utilizes
<a href="https://en.wikipedia.org/wiki/Picture_Transfer_Protocol">PTP</a>. I upgraded to
libgphoto2 (2.4.10.1-3) from experimental and added a proper udev rule with
vendor- and product-id but it did not help. Is there anything more I can try?</p>
<p><strong>Update:</strong> Accessing the camera actually works, even with ligbphoto2 (2.4.6)
from unstable. I can access the camera with gphoto2 and download pictures (but
not with KDE’s filemanager). My problem was that I had
<a href="https://projects.gnome.org/rhythmbox/">rhythmbox</a> running and the camera was
automatically mounted by it as a media device. When KDE’s filemanager or
gphoto2 tried to access the camera I got an error like: <em>(‘Could not lock the
device’): Camera is already in use.</em>, which is probably also a bug. Closing
rhythmbox solved the issue and I was able to download images with gphoto2.</p> Google Summer of Code 2010 Mentor Summit Report 2010-10-25T22:09:00+02:00 2010-10-25T22:09:00+02:00 Bastian Venthur tag:venthur.de,2010-10-25:/2010-10-25-google-summer-of-code-2010-mentor-summit-report.html Google Summer of Code 2010 Mentor Summit Report <p>As requested by our beloved leader, here’s my report on this year’s Google
Summer of Code 2010 Mentor Summit. The summit took place in Google’s HQ in
Mountain View, California and was what they call an “unconference”. In the
beginning of the unconference the attendees had 10 minutes to write down
proposals for a session and put them on a huge white board. After that, every
attendee voted for the sessions in which he was interested by putting a small
sticker on the proposal. This way we could evaluate the interest on a specific
topic and schedule the sessions to the differently sized rooms according to
their interest. Neat trick!</p>
<p>The the rest of the summit was basically like a conference: we had 11 tracks
filled with 5-6 sessions per day, which ran from 10:00 to 17:30. Google
provided shuttle buses from our wonderful hotel to the googleplex in the
morning and back to the hotel in the evening. The hotel was very nice, it was
equipped a swimming pool and a hot tub (both outside), which was extensively
used in the morning and of course during the night. Speaking of the night,
Google sponsored Thai food in the first night and ye olde Pizza and Beer in
the second. Some of the attendees brought their keyboard, guitar, bass and
electric clarinet, and where playing some sweet ass Jazz and Pop (on special
request…).</p>
<p>The sessions itself where not quite what I expected. I expected some proper
talks about specific topics, but it was more like and open discussion round
where everyone was invited to participate. For some topics it worked pretty
well, for others not. It was still totally worth coming, since you meet a lot
of like minded people and there is plenty stuff to talk about.</p>
<p>Of course I was very exited to see the googleplex. And the rumors are true:
the googleplex seems to be a very nice place to work. They provide free
breakfast, lunch and dinner for their employees. They have micro kitchens
everywhere where you can grab free snacks and beverages. There are lot’s of
toys lying around, they have bicycles everywhere on the campus which you can
just grab to move from one building to another. There is a dinosaur on the
yard, a spaceship over the stairwell and lots of other things (testing on the
toilet, anyone?), and we have probably only seen a small fraction, since we
were not allowed to leave the restricted areas for the unconference.</p>
<p>Despite the horrible yet lag (leaving Germany on Friday morning and leaving
San Francisco on Sunday night), I’m glad I was able to attend to the summit
and can only recommend aspiring mentors and students to participate to the
next summer of code!</p> Introducing python-popcon 2010-10-16T17:10:00+02:00 2010-10-16T17:10:00+02:00 Bastian Venthur tag:venthur.de,2010-10-16:/2010-10-16-introducing-python-popcon.html Introducing python-popcon <p><a href="https://github.com/venthur/python-popcon">Python-popcon</a> is a small Python
library which allows to query Debian’s popcon database. The usage is very
trivial:</p>
<div class="codehilite"><pre><span></span><code><span class="o">>>></span> <span class="kn">import</span><span class="w"> </span><span class="nn">popcon</span>
<span class="o">>>></span> <span class="n">popcon</span><span class="o">.</span><span class="n">package</span><span class="p">(</span><span class="s1">'python-popcon'</span><span class="p">)</span>
<span class="p">{</span><span class="s1">'python-popcon'</span><span class="p">:</span> <span class="mi">2</span><span class="p">}</span>
<span class="o">>>></span> <span class="n">popcon</span><span class="o">.</span><span class="n">package</span><span class="p">(</span><span class="s1">'icedove'</span><span class="p">,</span> <span class="s1">'iceweasel'</span><span class="p">)</span>
<span class="p">{</span><span class="s1">'icedove'</span><span class="p">:</span> <span class="mi">12140</span><span class="p">,</span> <span class="s1">'iceweasel'</span><span class="p">:</span> <span class="mi">45666</span><span class="p">}</span>
<span class="o">>>></span> <span class="n">popcon</span><span class="o">.</span><span class="n">package</span><span class="p">(</span><span class="s1">'foobarbaz'</span><span class="p">)</span>
<span class="p">{}</span>
</code></pre></div>
<p>You can call the <code>package</code> method with an arbitrary number of package names
and it will return a dictionary with <code>package name : popcon value</code> mappings
for all packages found. If a package is not found in the popcon database it
will not be in the resulting dictionary or if it was the only package in the
method call, the method will return an empty dictionary. The popcon value is
the number of installations according to Debian’s Popularity Contest service.</p>
<p>There is also a second method which gives some more information</p>
<div class="codehilite"><pre><span></span><code><span class="o">>>></span> <span class="n">popcon</span><span class="o">.</span><span class="n">package_raw</span><span class="p">(</span><span class="s1">'icedove'</span><span class="p">,</span> <span class="s1">'iceweasel'</span><span class="p">)</span>
<span class="p">{</span><span class="s1">'icedove'</span><span class="p">:</span> <span class="p">[</span><span class="mi">8065</span><span class="p">,</span> <span class="mi">2195</span><span class="p">,</span> <span class="mi">1879</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span> <span class="s1">'iceweasel'</span><span class="p">:</span> <span class="p">[</span><span class="mi">27857</span><span class="p">,</span> <span class="mi">10681</span><span class="p">,</span> <span class="mi">7120</span><span class="p">,</span> <span class="mi">8</span><span class="p">]}</span>
</code></pre></div>
<p>It returns a list of <code>[vote, old, recent, no-files]</code> for the given package.</p>
<p>How does it work? Upon a query, popcon downloads
https://popcon.debian.org/all-popcon-results.txt.gz, extracts and parses the
file and returns the desired information. Since downloading and extraction
this file is expensive, it saves the file and tries to re-use it is not older
than 7 days. So while the first call of one of the above methods can take a
few seconds, the result will appear almost instantaneously for the next week
until the cache file expired.</p>
<p>That’s it, no rocket science but a convenient way to get popcon information
from within python. The package python-popcon is available in Debian/Sid for a
few days.</p> Weird Konsole Split 2010-09-21T22:13:00+02:00 2010-09-21T22:13:00+02:00 Bastian Venthur tag:venthur.de,2010-09-21:/2010-09-21-weird-konsole-split.html Weird Konsole Split <p>Can someone explain me the purpose of (KDE’s) konsole’s ability to split?</p>
<p><img alt="" src="/images/konsole-split.png" title="konsole-split"></p>
<p>You can split horizontally or(!) vertically but the resulting terminals are
just mirroring the activity of the first one. What is the usecase for that?</p>
<p><a href="https://extragear.kde.org/apps/yakuake/">Yakuake</a> does splitting right. You
can split several times horizontally and vertically and the resulting
terminals are independent. You can also switch the focus of the terminals
easily via keystrokes which makes yakuake an invaluable tool when working on
the terminal under KDE.</p>
<p><img alt="" src="/images/konsole-split2.png" title="konsole-split2"></p>
<p>So what’s the point of konsole’s variant of splitting?</p> Happy Birthday Debian! 2010-08-16T18:25:00+02:00 2010-08-16T18:25:00+02:00 Bastian Venthur tag:venthur.de,2010-08-16:/2010-08-16-happy-birthday-debian.html Happy Birthday Debian! <p><img alt="" src="/images/birthdaylolcat.jpg" title="Happy Birthday Debian!"></p>
<p>17 years… I guess the puberty is almost a thing of the past and you’re
getting all grown up and stuff. You certainly changed for the better in the
last years. Ok, a few rough edges here and there but overall a quite
impressive development. You’re already forking regularly and even your
offspring is quite handsome. No wonders with those genes if you ask me.</p>
<p>Thanks to <a href="https://en.wikipedia.org/wiki/Ian_Murdock">Ian</a> for starting
probably the best Linux distribution out there. I hope you are proud of what
you’ve started (I certainly was when I met you <a href="2008-05-31-linuxtag-2008.html">two years
ago</a>) and someone is killing a few beers with you
right now.</p>
<p>Also big thanks to all the Debian Developers, Maintainers and contributors for
making Debian what it is today. Keep up the good work!</p> Goodbye DebConf10 2010-08-09T18:28:00+02:00 2010-08-09T18:28:00+02:00 Bastian Venthur tag:venthur.de,2010-08-09:/2010-08-09-goodbye-debconf10.html Goodbye DebConf10 <p>DebConf was really an awesome conference. I’m happy that I have finally met so
many of the fellow Debian people I only knew from the mailing lists or planet.
There where lot’s of interesting talks, the hacklabs where always busy, and
the overall atmosphere was very good. Now that I’m back in Berlin, I’m already
missing it – I’m by the way also missing my luggage which is apparently still
at the JFK airport.</p>
<p>This was my first DebConf, but definitively not my last. I encourage people
who never made it to DebConf: Get your butt up and register for the next
conference! You don’t know what you’re missing. If money is an issue: there is
a sponsoring which you can apply for and chances are good that you’ll get at
least partially sponsored.</p>
<p>Big thanks to all the volunteers who helped to organize and run this
conference and to SPI for sponsoring my trip, food and accommodation!</p>
<p>I’m looking forward seeing some of you again in three weeks at Steve’s place
in Cambridge for a nice BBQ and the rest of you next year in Bosnia and
Herzegovina!</p> Debconf: Day 2 2010-08-02T04:28:00+02:00 2010-08-02T04:28:00+02:00 Bastian Venthur tag:venthur.de,2010-08-02:/2010-08-02-debconf-day-2.html Debconf: Day 2 <p><img alt="" src="/images/interesting-cat.jpg" title="interesting-cat"></p>
<p>Second day in the big city and after the obligatory pancakes, scrambled eggs
and bacon breakfast, I spend almost the entire day in the hacklab fixing the
<a href="https://wiki.debian.org/DebbugsSoapInterface">documentation</a> for the debbugs
SOAP interface. Thanks to Don I think I finally have the <code>get_status</code> part at
an accurate state. Accordingly I was very busy making changes in
<a href="https://github.com/venthur/python-debianbts">python-debianbts</a> which uses the
SOAP interface to query the BTS. Some Bugreport attributes disappeared, others
got their data type fixed, Unittests where added and docstrings updated.
Finally I uploaded the new version to unstable.</p>
<p>Between that mess I met a lot of nice people, and heard a talk whose slides
consisted almost entirely of <a href="https://icanhascheezburger.com/">lolcat images</a>
– which was of course awesome! I definitively have to try that in one of my
next scientific talks.</p>
<p>Hopefully tomorrow I’ll find some time to actually prepare my talk.</p> linen and towels 2010-07-30T10:36:00+02:00 2010-07-30T10:36:00+02:00 Bastian Venthur tag:venthur.de,2010-07-30:/2010-07-30-linen-and-towels.html linen and towels <p>Dear lazyweb or someone who is already in NY,</p>
<p>do I have to bring my own bed linen and towels or are they provided by
Furnald? I couldn’t find the information on the website. I guess I have to
bring that stuff since it is not really a hotel, right?</p> I'm going to DebConf10 2010-07-13T21:43:00+02:00 2010-07-13T21:43:00+02:00 Bastian Venthur tag:venthur.de,2010-07-13:/2010-07-13-im-going-to-debconf10.html I'm going to DebConf10 <p><img alt="" src="/images/im_going_to_debconf10.png" title="im_going_to_debconf10"></p>
<p>Awesome! Thanks to all the sponsors and all the people helping to organize
this year’s DebConf for making it happen!</p>
<p>See you soon in New York City!</p> I may go to Debconf 10 2010-05-30T17:38:00+02:00 2010-05-30T17:38:00+02:00 Bastian Venthur tag:venthur.de,2010-05-30:/2010-05-30-i-may-go-to-debconf-10.html I may go to Debconf 10 <p>Today I received a mail from the DebConf Travel Sponsorship Team and they
informed me that I may get partially (or fully) sponsored. Ok that’s a bit
vague for now, but that also means that I <em>may</em> come to Debconf 10 – yeah!</p>
<p>I also applied for this Debconf Newbies thingy, as this will be the first
DebConf for me, but unfortunately there where too many applicants and not
enough money and they had to decline my request.</p> Github announces SVN support 2010-05-05T09:09:00+02:00 2010-05-05T09:09:00+02:00 Bastian Venthur tag:venthur.de,2010-05-05:/2010-05-05-github-announces-svn-support.html Github announces SVN support <p>This is freakin’ awesome! It is now possible to <a href="https://github.com/blog/626-announcing-svn-support">checkout
from-</a> and <a href="https://github.com/blog/644-subversion-write-support">commit
to</a> git repositories on
github with SVN.</p>
<p>This just made my day. This could also mean that this SVN support may later be
added into official git (like the CVS emulation), allowing the early movers to
use git also on the repository side while staying backwards compatible with
the rest who is still using SVN on the client side. Currently it’s more the
other way ‘round, the wherever SVN is used, git users have to resort to
git-svn.</p> Running Gnome Applets in KDE 2010-05-05T08:32:00+02:00 2010-05-05T08:32:00+02:00 Bastian Venthur tag:venthur.de,2010-05-05:/2010-05-05-running-gnome-applets-in-kde.html Running Gnome Applets in KDE <p>Dear Lazyweb,</p>
<p>does anyone know how to run gnome applets in KDE? I’m talking about
<a href="https://packages.debian.org/byzanz">byzanz</a> which is a software to record
your desktop in an animated gif, ogg or Flash format. It provides a command
line and a gnome applet, which apparently <em>only</em> works under Gnome. Is there a
workaround to make gnome applets run under KDE as well?</p> Debbugs RW-SOAP API Project in GSoC 2010 2010-04-09T10:31:00+02:00 2010-04-09T10:31:00+02:00 Bastian Venthur tag:venthur.de,2010-04-09:/2010-04-09-debbugs-rw-soap-api-project-in-gsoc-2010.html Debbugs RW-SOAP API Project in GSoC 2010 <p><img alt="Google Summer of Code 2010" src="/images/gsoc2010_300x267px.jpg" title="gsoc2010"></p>
<p>This year again, I’m <a href="https://wiki.debian.org/SummerOfCode2010/DebbugsAPI">proposing a
project</a> for this year’s
Summer of Code. Very much like my last year’s proposal, it is about adding
submit- and manipulation capabilities to <a href="https://wiki.debian.org/DebbugsSoapInterface">debbugs’ SOAP
interface</a>. The idea for this
project is to <em>add</em> another way to communicate with our bug tracking system
than email. Since we already have a read-only SOAP interface, it seems natural
to add write-capabilities. Libraries like
<a href="https://packages.qa.debian.org/p/python-debianbts.html">python-debianbts</a>
would adopt those features and end user applications like
<a href="https://packages.qa.debian.org/r/reportbug.html">reportbug</a> or
<a href="https://packages.qa.debian.org/r/reportbug-ng.html">reportbug-ng</a> could use
it to enhance usability.</p>
<p>One student has already applied. Others are also very
<a href="https://wiki.debian.org/SummerOfCode2010/DebbugsAPI">welcome</a> – but be
quick, the deadline for student applications is April 9th at 19:00 UTC.</p> apt-get update slow when LANG != C? 2010-03-29T09:31:00+02:00 2010-03-29T09:31:00+02:00 Bastian Venthur tag:venthur.de,2010-03-29:/2010-03-29-apt-get-update-slow-when-lang-c.html apt-get update slow when LANG != C? <p>For a few weeks now, aptitude is <em>really</em> slow updating the package list –
downloading the lists is actually fast as normal but it always waits for a
<em>minute</em> or so with a <code>99% [Warten auf Kopfzeilen]</code> (Waiting for headers)
message. I tried apt-get update – same problem.</p>
<p>Now the funny thing is: <code>LANG=C apt-get update</code> or<code>LANG=C aptitude -u</code> works
just fine! I also tested with <code>LANG=de_DE</code>, <code>it_IT</code>, <code>fr_FR</code> and even <code>en_US</code>
– always slow, so it looks it always occurs when <code>LANG</code> is not set to C?</p>
<p>Anyone else noticed this problem? I skimmed through the bug reports of apt,
but didn’t find a similar bug.</p>
<p><strong>Update:</strong> Looks like google-chrome is the problem! Commenting out the
content of <code>/etc/apt/sources.list.d/google-chrome.list</code>, as Jaime suggested in
the comments, everything worked fine again.</p> Reportbug-ng can now hide closed bugs 2010-02-21T17:30:00+01:00 2010-02-21T17:30:00+01:00 Bastian Venthur tag:venthur.de,2010-02-21:/2010-02-21-reportbug-ng-can-now-hide-closed-bugs.html Reportbug-ng can now hide closed bugs <p>Today I finally found the reason why the table in reportbug-ng was not always
sorted correctly. The fix was trivial and I’m happy it’s finally corrected. As
<a href="2010-02-18-reportbug-ng-now-supports-complex-queries.html">announced</a> last
week, reportbug-ng now also can optionally hide closed bugs, which makes
reportbug-ng together with the complex queries a great tool for finding easy
NMU candidates.</p>
<p>To play around with those new features, I also did 5 lazy NMUs today. Most of
them where fixes for FTBFS/RC bugs which had already a patch in the BTS.</p> Reportbug-ng now supports complex queries 2010-02-18T21:54:00+01:00 2010-02-18T21:54:00+01:00 Bastian Venthur tag:venthur.de,2010-02-18:/2010-02-18-reportbug-ng-now-supports-complex-queries.html Reportbug-ng now supports complex queries <p>Until today you could only use reportbug-ng to query the
<a href="https://bugs.debian.org/">BTS</a> with simple queries like “packagename”,
“bugnumber”, “tag:patch”, etc. But the BTS actually supports composite queries
like “severity:grave tag:patch” which returns bugreports with severity grave
and a patch. The underlying Python library
<a href="https://github.com/venthur/python-debianbts">python-debianbts</a> also supported
this right from the start, but reportbug-ng did not make use of it.</p>
<p>Last weekend I finally had the time to fix that and the result is on it’s way
to unstable.</p>
<p>Composite queries provide a very convenient way to find cheap NMU candidates:
the query <code>"severity:critical severity:grave severity:serious tag:patch"</code> will
return release critical bugs which have a patch. Now you can just go through
this list, pick an open bug, test the patch and do what’s necessary to release
Squeeze in time.</p>
<p>Next item on my list is an option to hide closed bugs, maybe next weekend.</p> Links not opening in Thunderbird 3? 2010-02-17T16:42:00+01:00 2010-02-17T16:42:00+01:00 Bastian Venthur tag:venthur.de,2010-02-17:/2010-02-17-links-not-opening-in-thunderbird-3.html Links not opening in Thunderbird 3? <p>If you’re using KDE and upgraded to Thunderbird 3 lately you might have the
problem that links in <a href="https://bugs.debian.org/566819">emails don’t open in a browser
anymore</a>. For my case that happened even
without a user visible error message.</p>
<p>If that sounds familiar for you, check the error console
(Tools/Error-Console). If there is an error like:</p>
<div class="codehilite"><pre><span></span><code><span class="n">Error</span><span class="p">:</span><span class="w"> </span><span class="n">uncaught</span><span class="w"> </span><span class="n">exception</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="n">Exception</span><span class="o">...</span><span class="w"> </span><span class="s2">"Component returned failure</span>
<span class="n">code</span><span class="p">:</span><span class="w"> </span><span class="mh">0x80004005</span><span class="w"> </span><span class="p">(</span><span class="n">NS_ERROR_FAILURE</span><span class="p">)</span>
<span class="p">[</span><span class="n">nsIExternalProtocolService</span><span class="o">.</span><span class="n">loadUrl</span><span class="p">]</span><span class="s2">" nsresult: "</span><span class="mh">0x80004005</span>
<span class="p">(</span><span class="n">NS_ERROR_FAILURE</span><span class="p">)</span><span class="s2">" location: "</span><span class="n">JS</span><span class="w"> </span><span class="n">frame</span><span class="w"> </span><span class="p">::</span>
<span class="n">chrome</span><span class="p">:</span><span class="o">//</span><span class="n">communicator</span><span class="o">/</span><span class="n">content</span><span class="o">/</span><span class="n">contentAreaClick</span><span class="o">.</span><span class="n">js</span><span class="w"> </span><span class="p">::</span><span class="w"> </span><span class="n">openLinkExternally</span>
<span class="p">::</span><span class="w"> </span><span class="n">line</span><span class="w"> </span><span class="mi">188</span><span class="s2">" data: no]</span>
</code></pre></div>
<p>Then Thunderbird just (silently) fails to launch the browser. Guido pointed me
to gconftool. <code>gconftool -R / | grep url-handlers</code> told me that some
components of gnome still had Firefox configured as http-handler (which is
strange since it was rebranded to iceweasel ages ago). Resetting them solved
the problem for me.</p>
<p>The sad part of the story: x-www-browser, sensible-browser and KDE’s http
handler where all correctly configured and pointed to iceweasel. All
applications behaved correctly only Icedove used a (for me) hidden setting
pointing to firefox.</p> Query Google Scholar using Python 2010-01-27T17:45:00+01:00 2010-01-27T17:45:00+01:00 Bastian Venthur tag:venthur.de,2010-01-27:/2010-01-27-query-google-scholar-using-python.html Query Google Scholar using Python <p>In desperate need to organize my collection of scientific papers, I had a look
at various tools which could help me organizing them. Probably one of the best
out there is <a href="https://www.mendeley.com/">Mendeley</a>. Mendeley seems to be a
very good tool to keep your massive collection of pdfs under control.
Unfortunately a very basic function, namely looking up a newly imported paper
in <a href="https://scholar.google.com/">Google Scholar</a> to get attributes like:
Authors, Year, etc. right, is bundled with a Mendeley account. I guess that’s
their way of forcing the user to participate to their community stuff, since
without the Google Scholar lookup Mendeley is pretty useless unless you want
to fill all the attributes manually.</p>
<p>So I decided to write my own tool to make the lookup. Unfortunately Google
does not really want to give away that precious data: they don’t provide an
API and even block certain User-Agents from accessing the page. Then, there is
also the problem of scraping the results page to get the right data.</p>
<p>The first problem can be trivially solved by setting a common User-Agent
string, the second one can be elegantly circumvented by using the bibtex files
provided in the search results. The bibtex entries are however only showed if
you enabled them in the settings, which are stored in a cookie. After a few
tries, I figured that the <code>CF</code> attribute (citation format?) controls which
bibliography format should be offered in the results page and <code>CF=4</code>
corresponds to bibtex. Generating a fake cookie is easy, but you have to know
what must be included. In this case it looks like a 16 digit hex as ID and the
CF attribute is sufficient. The <code>ID</code> is probably supposed to be <em>your</em> id, but
a randomly generated one also works like a charm.</p>
<p>The resulting cookie looks like this: <code>GSP=ID=762a112b5c765732:CF=4</code></p>
<p>All you have to do now is to query Google Scholar using the user string and
the cookie:</p>
<div class="codehilite"><pre><span></span><code><span class="o">...</span>
<span class="c1"># fake google id (looks like it is a 16 elements hex)</span>
<span class="n">google_id</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">md5</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">random</span><span class="o">.</span><span class="n">random</span><span class="p">()))</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()[:</span><span class="mi">16</span><span class="p">]</span>
<span class="n">GOOGLE_SCHOLAR_URL</span> <span class="o">=</span> <span class="s2">"https://scholar.google.com"</span>
<span class="n">HEADERS</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'User-Agent'</span> <span class="p">:</span> <span class="s1">'Mozilla/5.0'</span><span class="p">,</span>
<span class="s1">'Cookie'</span> <span class="p">:</span> <span class="s1">'GSP=ID=</span><span class="si">%s</span><span class="s1">:CF=4'</span> <span class="o">%</span> <span class="n">google_id</span> <span class="p">}</span>
<span class="k">def</span><span class="w"> </span><span class="nf">query</span><span class="p">(</span><span class="n">searchstr</span><span class="p">):</span>
<span class="w"> </span><span class="sd">"""Return a list of bibtex items."""</span>
<span class="n">searchstr</span> <span class="o">=</span> <span class="s1">'/scholar?q='</span><span class="o">+</span><span class="n">urllib2</span><span class="o">.</span><span class="n">quote</span><span class="p">(</span><span class="n">searchstr</span><span class="p">)</span>
<span class="n">url</span> <span class="o">=</span> <span class="n">GOOGLE_SCHOLAR_URL</span> <span class="o">+</span> <span class="n">searchstr</span>
<span class="n">request</span> <span class="o">=</span> <span class="n">urllib2</span><span class="o">.</span><span class="n">Request</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">headers</span><span class="o">=</span><span class="n">HEADERS</span><span class="p">)</span>
<span class="n">response</span> <span class="o">=</span> <span class="n">urllib2</span><span class="o">.</span><span class="n">urlopen</span><span class="p">(</span><span class="n">request</span><span class="p">)</span>
<span class="n">html</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="c1"># grab the bibtex links</span>
<span class="o">...</span>
</code></pre></div>
<p>And Google Scholar will offer you links to the bibtex files of the results.
Getting those links is easy since they all start with <code>"/scholar.bib"</code>. Just
search for those and download the targets.</p>
<p>The complete code is available on
<a href="https://github.com/venthur/gscholar">github</a>. It can be used as a python
library or a standalone application, you just call it like this: <code>gscolar
"some author or title"</code> and it will print the first ten results in bibtex to
stdout.</p> How to find packages installed/updated yesterday? 2010-01-26T10:14:00+01:00 2010-01-26T10:14:00+01:00 Bastian Venthur tag:venthur.de,2010-01-26:/2010-01-26-how-to-find-packages-installedupdated-yesterday.html How to find packages installed/updated yesterday? <p>Dear Lazyweb,</p>
<p>since yesterday’s daily update, my laptop runs <em>really</em> sluggish. Is there a
way to list all packages which where updated or installed yesterday to track
down the problem?</p> git bisect, ccache, cowbuilder 2010-01-09T16:15:00+01:00 2010-01-09T16:15:00+01:00 Bastian Venthur tag:venthur.de,2010-01-09:/2010-01-09-git-bisect-ccache-cowbuilder.html git bisect, ccache, cowbuilder <p><a href="https://www.kernel.org/pub/software/scm/git/docs/git-bisect.html">Git
bisect</a>,
<a href="https://ccache.samba.org/">ccache</a> and
<a href="https://packages.debian.org/search?keywords=cowbuilder">cowbuilder</a>: a
combination made in heaven! Tracking down a commit which introduced an <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=564415">ugly
bug</a> with those
tools was a breeze.</p>
<p>Git bisect is very useful finding a commit which introduced a bug very
quickly, ccache massively reduces compiling time. Compiling icedove
(thunderbird) on my laptop using cowbuilder takes roughly 30 minutes. Using
cowbuilder with ccache, it only takes 10 minutes, where most of the time is
spent setting up the build environment.</p> 1984 2010-01-05T11:58:00+01:00 2010-01-05T11:58:00+01:00 Bastian Venthur tag:venthur.de,2010-01-05:/2010-01-05-1984.html 1984 <p>One idiot <a href="https://en.wikipedia.org/wiki/Northwest_Airlines_Flight_253">ignites a
bomb</a>, others
immediately scream for <a href="https://en.wikipedia.org/wiki/Security_scan">security
scanners</a>. Apparently Terrorism
works pretty well for countries with increased security needs.</p> Printing 2009-12-08T17:26:00+01:00 2009-12-08T17:26:00+01:00 Bastian Venthur tag:venthur.de,2009-12-08:/2009-12-08-printing.html Printing <p>Funny coincidence that David
<a href="https://www.davidpashley.com/blog/linux/printer-conversation">writes</a> how well
Linux and Printers go together for 12 years, while it is apparently
<a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=558755">impossible</a> to
print something with CUPS in unstable since a week ;)</p> The sorry state of Python in Debian 2009-12-02T10:45:00+01:00 2009-12-02T10:45:00+01:00 Bastian Venthur tag:venthur.de,2009-12-02:/2009-12-02-the-sorry-state-of-python-in-debian.html The sorry state of Python in Debian <p>Looking at the
<a href="https://lists.debian.org/debian-devel/2009/12/msg00024.html">sorry</a> state of
Python in Debian, makes me wonder if we shouldn’t enforce team maintainance of
packages above a certain popularity/importance/whatever threshold. People
worked hard in the last months to fix any bugs that would prevent Python2.6 to
land in unstable and yet nothing happens. Time passes by and we will
eventually end up with Squeeze having a horribly outdated Python version.</p> My eyes! The goggles, they do nothing! 2009-11-23T10:26:00+01:00 2009-11-23T10:26:00+01:00 Bastian Venthur tag:venthur.de,2009-11-23:/2009-11-23-my-eyes-the-goggles-they-do-nothing.html My eyes! The goggles, they do nothing! <p>Dear Lazyweb,</p>
<p>do you know how to theme Tk apps? In the default setting, Tk apps running on
my KDE4 desktop, cause spontanous eye cancer:</p>
<p><img alt="Default Tk theme." src="/images/tkeyecancer.png" title="tkeyecancer"></p>
<p>there must be a way to theme them to look like the Qt or at least GTK apps, or
not?</p> Bundesverdienstkreuz for Matthias Ettrich 2009-11-07T16:11:00+01:00 2009-11-07T16:11:00+01:00 Bastian Venthur tag:venthur.de,2009-11-07:/2009-11-07-bundesverdienstkreuz-for-matthias-ettrich.html Bundesverdienstkreuz for Matthias Ettrich <p><a href="https://en.wikipedia.org/wiki/Matthias_Ettrich">Matthias Ettrich</a>, the
founder of KDE
<a href="https://www.berlin.de/landespressestelle/archiv/2009/11/04/144882/">earned</a>
the Bundesverdienstkreuz (<a href="https://en.wikipedia.org/wiki/Federal_Cross_of_Merit">Federal Cross of
Merit</a>) last Friday for
his engagement in open source. How cool is that?</p>
<p>Congratulations Matthias and thank you (and all the others) for the K Desktop
Environment!</p> Python2.6 Blockers 2009-11-07T13:42:00+01:00 2009-11-07T13:42:00+01:00 Bastian Venthur tag:venthur.de,2009-11-07:/2009-11-07-python26-blockers.html Python2.6 Blockers <p>Today’s work: 5 lazy NMUs (thanks again Kumar). Leaves us with only <em>five</em>
open <a href="https://bugs.debian.org/cgi-bin/pkgreport.cgi?users=debian-python@lists.debian.org;tag=python2.6">python2.6
blockers</a>
to fix and a whopping 62 of closed ones.</p> reportbug-ng has localization support again 2009-10-25T18:58:00+01:00 2009-10-25T18:58:00+01:00 Bastian Venthur tag:venthur.de,2009-10-25:/2009-10-25-reportbug-ng-has-localization-support-again.html reportbug-ng has localization support again <p>After having ported reportbug-ng from PyQt3 to PyQt4 <a href="2008-07-13-porting-rng-to-qt4.html">over a year
ago</a>, reportbug-ng lost it’s localization,
since the gettext based translations where incompatible with Qt4’s translation
system.</p>
<p>This weekend I finally had the time to have a closer look at this problem. To
make a long story short: I have ported the gettext based system to Qt4’s
system. All the old .po files where converted to .ts files, but almost all
strings are marked as “obsolete” so that they don’t appear in the translated
program. But since they are still available in the .ts file, it is easy to get
the translations up-to-date. So far only English and German are complete, but
eventually other translations will be added.</p>
<p>PyQt4 makes it by the way <em>really</em> hard to get non-Qt strings translated.</p> Amarok going downhill 2009-10-20T17:13:00+02:00 2009-10-20T17:13:00+02:00 Bastian Venthur tag:venthur.de,2009-10-20:/2009-10-20-amarok-going-downhill.html Amarok going downhill <p>Amarok 2.2 is probably the only audio application on the market
<em><a href="https://bugs.debian.org/540203">unable</a></em> connect properly to the IPod. It is
<a href="https://ubuntuforums.org/showthread.php?t=1151706">impossible</a> to copy
podcasts within Amarok to the IPod since Amarok 2.x. This functionality simply
disappeared during the 1.x to 2.x version jump. You can download and listen to
podcasts, you can connect your IPod, but you cannot drag the podcast to the
IPod.</p>
<p>A few weeks ago you could help yourself if you know where Amarok stores the
podcasts (<code>~/.kde/share/apps/amarok/podcasts</code>): just navigate to this
directory and drag the audio file to the IPod, but looks this rake was also
disabled within the last versions, since Amarok now only segfaults if you dare
to do this.</p>
<p>Great.</p> Python 2.6 Transition 2009-10-17T15:45:00+02:00 2009-10-17T15:45:00+02:00 Bastian Venthur tag:venthur.de,2009-10-17:/2009-10-17-python-26-transition.html Python 2.6 Transition <p>Today I NMUed over a dozen of Python packages with <a href="https://bugs.debian.org/cgi-bin/pkgreport.cgi?users=debian-python@lists.debian.org;tag=python2.6">bugs which blocked the
Python 2.6
transition</a>.</p>
<p>I really want to thank <strong>Kumar Appaiah</strong> for his work. He provided patches for
<em>all</em> the bugs I NMUed today and <em>lots</em> more. I really did not much more than
applying, testing and uploading his patches, but Kumar probably invested days
of labor to create the patches and test them. Thanks to his effort, the number
of 2.6-blockers shrinked considerably so that we now have like ~15 open
blockers and ~50 closed ones!</p> python-debianbts 1.0 uploaded to unstable 2009-10-10T20:36:00+02:00 2009-10-10T20:36:00+02:00 Bastian Venthur tag:venthur.de,2009-10-10:/2009-10-10-python-debianbts-10-uploaded-to-unstable.html python-debianbts 1.0 uploaded to unstable <p>Today I was working all day on
<a href="https://github.com/venthur/python-debianbts">python-debianbts</a> 1.0 and
uploaded it to unstable a few minutes ago. This version breaks backwards
compatibility with previous versions. I removed lots of unneeded old cruft
like the HTMLStripper class needed ages ago when I was still using HTML
instead of debbugs’ SOAP interface.</p>
<p>A new method <code>get_usertag(email, *tags)</code> was introduced. It returns a dict
containing usertag-buglist mappings. If tags are given the dict is limited to
matching tags, otherwise all available tags of the given user are returned:</p>
<div class="codehilite"><pre><span></span><code><span class="n">In</span> <span class="p">[</span><span class="mi">1</span><span class="p">]:</span> <span class="kn">import</span><span class="w"> </span><span class="nn">debianbts</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="nn">bts</span>
<span class="n">In</span> <span class="p">[</span><span class="mi">2</span><span class="p">]:</span> <span class="n">bts</span><span class="o">.</span><span class="n">get_usertag</span><span class="p">(</span><span class="s2">"debian-python@lists.debian.org"</span><span class="p">)</span>
<span class="n">Out</span><span class="p">[</span><span class="mi">2</span><span class="p">]:</span>
<span class="p">{</span><span class="s1">'dist-packages'</span><span class="p">:</span> <span class="p">[</span><span class="mi">547838</span><span class="p">,</span> <span class="mi">547832</span><span class="p">,</span> <span class="o">...</span><span class="p">,</span> <span class="mi">547858</span><span class="p">],</span>
<span class="s1">'dpmt-todo'</span><span class="p">:</span> <span class="p">[</span><span class="mi">332913</span><span class="p">],</span>
<span class="s1">'policy'</span><span class="p">:</span> <span class="p">[</span><span class="mi">373301</span><span class="p">,</span> <span class="mi">373302</span><span class="p">,</span> <span class="o">...</span><span class="p">,</span> <span class="mi">377089</span><span class="p">],</span>
<span class="s1">'python-oldnum'</span><span class="p">:</span> <span class="p">[</span><span class="mi">478467</span><span class="p">,</span> <span class="mi">478442</span><span class="p">,</span> <span class="o">...</span><span class="p">,</span> <span class="mi">478441</span><span class="p">],</span>
<span class="s1">'python2.1'</span><span class="p">:</span> <span class="p">[</span><span class="mi">351108</span><span class="p">,</span> <span class="mi">351110</span><span class="p">,</span> <span class="o">...</span><span class="p">,</span> <span class="mi">351131</span><span class="p">],</span>
<span class="s1">'python2.2'</span><span class="p">:</span> <span class="p">[</span><span class="mi">351108</span><span class="p">,</span> <span class="mi">351109</span><span class="p">,</span> <span class="o">...</span><span class="p">,</span> <span class="mi">351161</span><span class="p">],</span>
<span class="s1">'python2.6'</span><span class="p">:</span> <span class="p">[</span><span class="mi">547838</span><span class="p">,</span> <span class="mi">547832</span><span class="p">,</span> <span class="o">...</span> <span class="mi">547858</span><span class="p">]}</span>
<span class="n">In</span> <span class="p">[</span><span class="mi">3</span><span class="p">]:</span> <span class="n">bts</span><span class="o">.</span><span class="n">get_usertag</span><span class="p">(</span><span class="s2">"debian-python@lists.debian.org"</span><span class="p">,</span> <span class="s2">"python2.1"</span><span class="p">,</span> <span class="s2">"python2.2"</span><span class="p">)</span>
<span class="n">Out</span><span class="p">[</span><span class="mi">3</span><span class="p">]:</span>
<span class="p">{</span><span class="s1">'python2.1'</span><span class="p">:</span> <span class="p">[</span><span class="mi">351108</span><span class="p">,</span> <span class="mi">351110</span><span class="p">,</span> <span class="o">...</span><span class="p">,</span> <span class="mi">351131</span><span class="p">],</span>
<span class="s1">'python2.2'</span><span class="p">:</span> <span class="p">[</span><span class="mi">351108</span><span class="p">,</span> <span class="mi">351109</span><span class="p">,</span> <span class="o">...</span><span class="p">,</span> <span class="mi">351161</span><span class="p">]}</span>
</code></pre></div>
<p><code>get_bug_log(nr)</code> now returns a list of dicts with the keys: <code>header</code>
(string), <code>body</code> (string), <code>msg_num</code> (int) and <code>attachments</code> (list). Before
1.0 it returned a list of Buglog objects.</p>
<p>The Bugreport class now supports every information provided by the SOAP
interface. I tried to stay as close as possible to the data SOAP provides, so
I renamed existing attributes (like Bugreport.nr which is not supported by
SOAP but is now <code>Bugreport.bug_num</code>) and also added the quirky ones like: <code>id</code>
and <code>bug_nr</code>, <code>found</code> and <code>found_versions</code>, <code>keywords</code> and <code>tags</code>, <code>fixed</code> and
<code>fixed_date</code> which always seem to provide the same data.</p>
<p>Instead of the Bugreport.value() method which provided a number representing
the openness (in terms of: open, closed and archived) and urgency (like:
grave, important, …) to make bugreports sortable by their status, the
Bugreport class now has a <code>__cmp__</code> method which makes bugreports comparable.
The more open and urgent a bug is, the greater it is. Openness always beats
urgency (eg: an open whishlist bug is greater than a closed grave one).</p>
<p>While pre 1.0 versions of python-debianbts more or less served the needs of
<a href="https://github.com/venthur/reportbug-ng">reportbug-ng</a>, it now tries to stay
as close as possible to the data provided by SOAP. As a result many parts of
reportbug-ng had to be fixed for the new version. I hope this makes
python-debianbts more attractive for other projects dealing with Debian’s bug
tracker. As always: python-debianbts is on
<a href="https://github.com/venthur/python-debianbts">github</a> and forks, patches or
other kinds of collaboration are very welcome.</p>
<p>For the curious here a litte quickstart. it shows how to get all important
bugs from reportbug-ng and prints out the bugnumber and summary:</p>
<div class="codehilite"><pre><span></span><code><span class="c1"># Get all important bugs of reportbug-ng (returns a list of integers)</span>
<span class="n">bugnrlist</span> <span class="o">=</span> <span class="n">bts</span><span class="o">.</span><span class="n">get_bugs</span><span class="p">(</span><span class="s2">"package"</span><span class="p">,</span> <span class="s2">"reportbug-ng"</span><span class="p">,</span> <span class="s2">"severity"</span><span class="p">,</span> <span class="s2">"important"</span><span class="p">)</span>
<span class="n">bugnrlist</span>
<span class="p">[</span><span class="mi">548871</span><span class="p">,</span> <span class="mi">439203</span><span class="p">,</span> <span class="mi">542759</span><span class="p">]</span>
<span class="c1"># Get the actual bugreports (returns a list of Bugreport-objects)</span>
<span class="n">bugs</span> <span class="o">=</span> <span class="n">bts</span><span class="o">.</span><span class="n">get_status</span><span class="p">(</span><span class="n">bugnrlist</span><span class="p">)</span>
<span class="k">for</span> <span class="n">bug</span> <span class="ow">in</span> <span class="n">bugs</span><span class="p">:</span> <span class="nb">print</span> <span class="n">bug</span><span class="o">.</span><span class="n">bug_num</span><span class="p">,</span> <span class="n">bug</span><span class="o">.</span><span class="n">subject</span>
<span class="o">....</span><span class="p">:</span>
<span class="mi">542759</span> <span class="p">[</span><span class="n">reportbug</span><span class="o">-</span><span class="n">ng</span><span class="p">]</span> <span class="n">Erroneously</span> <span class="n">reports</span> <span class="n">nothing</span> <span class="ow">or</span> <span class="n">repeats</span> <span class="n">previous</span> <span class="n">package</span><span class="s1">'s report</span>
<span class="mi">439203</span> <span class="n">Doesn</span><span class="s1">'t give any explanations of the severities and what they mean</span>
<span class="mi">548871</span> <span class="n">reportbug</span><span class="o">-</span><span class="n">ng</span><span class="p">:</span> <span class="n">does</span> <span class="ow">not</span> <span class="n">check</span> <span class="k">for</span> <span class="n">newer</span> <span class="n">versions</span> <span class="n">before</span> <span class="n">reporting</span> <span class="n">a</span> <span class="n">bug</span>
</code></pre></div> Please help to complete python-debianbts 2009-09-20T15:29:00+02:00 2009-09-20T15:29:00+02:00 Bastian Venthur tag:venthur.de,2009-09-20:/2009-09-20-please-help-to-complete-python-debianbts.html Please help to complete python-debianbts <p>I’m currently working on an updated version of
<a href="https://packages.debian.org/search?keywords=python-debianbts">python-debianbts</a>
a Python interface to Debian’s Bugtracker. The goal is to equip the Bugreport
class with all available attributes delivered by the SOAP interface. The
problem is, that for some attributes it is not quite clear what data they
provide and in which datatype they are wrapped. For example the <code>mergedwith</code>
attribute should be a list of bugnumbers, but it seems to be a single Integer
when merged with one bug and an empty String when the bug is not merged at
all. Some attributes have an ambiguous name and it’s hard to guess what they
mean, for example there is an <code>id</code> and a <code>bug_nr</code> and both seem to contain the
same information.</p>
<p>There is a <a href="https://github.com/venthur/python-debianbts/tree/complete-support">git
branch</a> for
this task and a <a href="https://wiki.debian.org/DebbugsSoapInterface">wiki page</a>
collecting all available information. If you have some experience with SOAP,
our BTS and some time to kill, your help would be appreciated.</p> Github 2009-09-19T15:57:00+02:00 2009-09-19T15:57:00+02:00 Bastian Venthur tag:venthur.de,2009-09-19:/2009-09-19-github.html Github <p><a href="https://github.com/venthur/reportbug-ng">Reportbug-ng</a> and
<a href="https://github.com/venthur/python-debianbts">python-debianbts</a> are now on
github. Many thanks to the alioth team who provided this service before.</p> Gridengine and Qlogin Zombies 2009-09-12T11:38:00+02:00 2009-09-12T11:38:00+02:00 Bastian Venthur tag:venthur.de,2009-09-12:/2009-09-12-gridengine-and-qlogin-zombies.html Gridengine and Qlogin Zombies <p>Dear Lazyweb,</p>
<p>we’re using <a href="https://gridengine.sunsource.net/">gridengine</a> 6.2 on our cluster
system at work. On this system we have a queue for interactive jobs. The queue
has a fixed number of slots. If someone wants to start an interactive session
and no free slots are available the interactive job cannot start otherwise it
will consume one slot during the session and free it again after the user quit
the interactive session.</p>
<p>Unfortunately, if the user forgets to quit the interactive session properly
(e.g. by entering “quit” in the terminal) and just closes the terminal, the
interactive session becomes a zombie. The user cannot use this session
anymore, but the process is still running and thus blocking a slot. Since it
happens quite often that users fail to quit the interactive session properly,
the free slots are used up pretty soon and no one can start new interactive
sessions anymore – quite a nice bug in the gridengine software (available in
Debian/Lenny by the way…)</p>
<p>You can see that those processes are still running using ps and qstat. The
question is: how can I effectively search for those processes and kill them?
Gridengine does not seem to be aware of those zombies and the user might run
other interactive jobs in parallel which must not be killed. So how does one
find the zombies and kill them reliably?</p> Package Completion for Rng 2009-08-03T19:11:00+02:00 2009-08-03T19:11:00+02:00 Bastian Venthur tag:venthur.de,2009-08-03:/2009-08-03-package-completion-for-rng.html Package Completion for Rng <p>Today, I finally found the time to apply a patch contributed by <em>Daniel
Schaal</em> to reportbug-ng. Among two minor fixes it brings a huge usability
improvement: <em>package completion</em>. Whenever you type something to the input
field rng suggests package names matching that prefix:</p>
<p><img alt="" src="/images/rng-package-completion.png" title="rng-package-completion"></p>
<p>That should make bug reporting against packages with cryptic names like
libraries a lot easier. Thank you very much Daniel!</p> SO_REUSEADDR 2009-07-22T10:39:00+02:00 2009-07-22T10:39:00+02:00 Bastian Venthur tag:venthur.de,2009-07-22:/2009-07-22-so_reuseaddr.html SO_REUSEADDR <p>Dear Lazyweb,</p>
<p>I have a simple test application where a TCP/IP server listens for incoming
connections, reads the data and closes the connection again and a client which
opens connections to the server and sends a package and closes the connection
as fast as it can:</p>
<p>The server looks like this:</p>
<div class="codehilite"><pre><span></span><code><span class="n">sock</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">)</span>
<span class="n">sock</span><span class="o">.</span><span class="n">setsockopt</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">SOL_SOCKET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SO_REUSEADDR</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">sock</span><span class="o">.</span><span class="n">setblocking</span><span class="p">(</span><span class="kc">False</span><span class="p">)</span>
<span class="n">sock</span><span class="o">.</span><span class="n">bind</span><span class="p">((</span><span class="s2">""</span><span class="p">,</span> <span class="mi">12347</span><span class="p">))</span>
<span class="n">sock</span><span class="o">.</span><span class="n">listen</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">slist</span> <span class="o">=</span> <span class="p">[</span><span class="n">sock</span><span class="p">]</span>
<span class="c1"># use select to poll the sockets</span>
<span class="k">while</span> <span class="mi">1</span><span class="p">:</span>
<span class="n">l</span> <span class="o">=</span> <span class="n">select</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="n">slist</span><span class="p">,</span> <span class="p">[],</span> <span class="p">[])</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">l</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span>
<span class="n">conn</span><span class="p">,</span> <span class="n">addr</span> <span class="o">=</span> <span class="n">i</span><span class="o">.</span><span class="n">accept</span><span class="p">()</span>
<span class="n">data</span> <span class="o">=</span> <span class="s2">""</span>
<span class="k">while</span> <span class="mi">1</span><span class="p">:</span>
<span class="n">tmp</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">1024</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">tmp</span><span class="p">:</span>
<span class="k">break</span>
<span class="n">data</span> <span class="o">+=</span> <span class="n">tmp</span>
<span class="n">conn</span><span class="o">.</span><span class="n">shutdown</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">SHUT_RDWR</span><span class="p">)</span>
<span class="n">conn</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</code></pre></div>
<p>The Client:</p>
<div class="codehilite"><pre><span></span><code><span class="c1"># Open a connection, send data and close the connection as fast as possible</span>
<span class="k">while</span> <span class="mi">1</span><span class="p">:</span>
<span class="n">sock</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">)</span>
<span class="n">sock</span><span class="o">.</span><span class="n">connect</span><span class="p">((</span><span class="s2">""</span><span class="p">,</span> <span class="mi">12347</span><span class="p">))</span>
<span class="n">sock</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="s2">"foo"</span><span class="p">)</span>
<span class="n">sock</span><span class="o">.</span><span class="n">shutdown</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">SHUT_RDWR</span><span class="p">)</span>
<span class="n">sock</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</code></pre></div>
<p>The Problem with this application: After roughly 25.000 Iterations the client
quits with a friendly:</p>
<blockquote>
<p>error: (99, ‘Cannot assign requested address’)</p>
</blockquote>
<p>Netstat shows the problem: roughly 25.000 of these ones:</p>
<div class="codehilite"><pre><span></span><code>...
tcp 0 0 localhost:56946 localhost:12347 TIME_WAIT
tcp 0 0 localhost:47163 localhost:12347 TIME_WAIT
tcp 0 0 localhost:42758 localhost:12347 TIME_WAIT
...
</code></pre></div>
<p>I’m not a TCP/IP expert but I thought <code>SO_REUSEADDR</code> is supposed to address
this problem by allowing to reuse those as-good-as-closed connections in
<code>TIME_WAIT</code> state, or not? So why does it fail in my test application?</p> Debconf 11 in Berlin? 2009-06-03T10:43:00+02:00 2009-06-03T10:43:00+02:00 Bastian Venthur tag:venthur.de,2009-06-03:/2009-06-03-debconf-11-in-berlin.html Debconf 11 in Berlin? <p>This is just a quick note for everyone who is interested: Yesterday we had a
small meeting discussing the plan to bring Debconf 11 to Berlin, Germany.
There will be an official meeting regarding this topic at this year’s
LinuxTag. The meeting will probably take place on Friday the 26th of June at a
conference room. Everyone is invited to join the discussion.</p>
<p>PS: I also have a shiny new key, the fingerprint is <code>8795 AF2E 4A1A 4EFB A068
A449 8E88 9544 D985 000D</code>. The old key will be revoked in a couple of months.</p> LinuxTag 2009 2009-05-05T08:35:00+02:00 2009-05-05T08:35:00+02:00 Bastian Venthur tag:venthur.de,2009-05-05:/2009-05-05-linuxtag-2009.html LinuxTag 2009 <p><a href="https://nion.modprobe.de/blog/">Nion</a> just reminded me of this year’s
LinuxTag. Although I certainly won’t have the time to help at the booth every
day as in the last years, I hope I can manage to work there at least for one
or two days.</p>
<p>If you want to help at our booth (you <em>don’t</em> have to be a Debian Developer),
<a href="https://wiki.debian.org/DebianEventsDe/2009/LinuxTag">join us</a>! It’s fun and
a great way to get in touch with other like minded people and your help is
really appreciated.</p> Using rng for bug triaging 2009-04-18T12:08:00+02:00 2009-04-18T12:08:00+02:00 Bastian Venthur tag:venthur.de,2009-04-18:/2009-04-18-using-rng-for-bug-triaging.html Using rng for bug triaging <p>Reportbug-NG’s ability to filter and sort bugreports in various ways can
greatly help triaging bugreports after a certain criterion.</p>
<p>In this example I use the bugs of the KDE team, because they have quite a lot
of bugs and are currently on a bug triage.</p>
<p>Two releases ago I tried to help them cleaning their BTS from obsolete
bugeports. My tactic back then was to find bugreports where no action has been
taken for a long time. I noticed that there was no easy way to find such bugs
since neither reportbug nor the BTS allowed to sort the bugs this way, so
finding the candidates I searched for was very cumbersome.</p>
<p>So let’s try to find those bugs with rng: To get all bugs belonging to the KDE
team start rng with the maintainer as argument:</p>
<div class="codehilite"><pre><span></span><code>rng<span class="w"> </span>debian-qt-kde@lists.debian.org
</code></pre></div>
<p>After rng started you see a table with all bugreports against the packages of
the KDE team. To find potentially solved or unreproducible bugs, click on the
last column header to sort the list by the date of the <em>last action</em>. The date
of the last action is the date where the bugreport received it’s last mail
(including control@b.d.o mails). You will see that there are quite a lot bugs
which haven’t been touched for more than two years. Many of them don’t have a
unreproducible or moreinfo tag. If you want to help the KDE team, you can now
start trying to reproduce the bug. If that’s not possible you can tag them
with moreinfo and unreproducible. If there is no reply in roughly one month or
so it’s probably safe to close this bug.</p>
<p>To quickly find a lot of other candidates to close one can use the filter of
rng. Just enter moreinfo in the filter and the table will reduce to all
bugreports containing this word or tag. Now you can again sort this list by
date of last action and you will see quite a lot bugs bugs where more info was
requested but no action took place for more than one year. Those need to be
inspected, but probably quite a few of them are safe to close.</p>
<p>This example shows how filtering and sorting can greatly help to find certain
bugs and support bug triaging. But please: don’t carelessly close very old
bugs! Read the reports and try to reproduce them, find matching bugreports in
upstream’s BTS and ask the submitter if in doubt.</p> Migrating a project from one SVN repository to another using git-svn 2009-04-08T15:13:00+02:00 2009-04-08T15:13:00+02:00 Bastian Venthur tag:venthur.de,2009-04-08:/2009-04-08-migrating-a-project-from-one-svn-repository-to-another-using-git-svn.html Migrating a project from one SVN repository to another using git-svn <p>… sounds probably like a stupid idea since you could just copy the
repository from the old to the new location, but in this case we don’t have
direct access to the repositories, only accounts with commit-access. Ahh, and
we want to preserve the complete history, of course.</p>
<p>Ok, the plan is to use git-svn to get a copy of the old SVN repository,
complete with history and then apply each commit to the new location:</p>
<h2>Getting the old repository</h2>
<div class="codehilite"><pre><span></span><code>git<span class="w"> </span>svn<span class="w"> </span>clone<span class="w"> </span>https://old/repo/
<span class="nb">cd</span><span class="w"> </span>repo
</code></pre></div>
<h2>Removing the traces of the old repository</h2>
<p>Now we have a git repository containing the complete history of the old SVN
repository. That git repository is connected to the old SVN repository via
git-svn. In order to commit it to the new repository we have to remove the
traces of git-svn:</p>
<div class="codehilite"><pre><span></span><code><span class="c1"># Remove the remote branch</span>
git<span class="w"> </span>branch<span class="w"> </span>-rD<span class="w"> </span>git-svn
<span class="c1"># Remove the rest</span>
rm<span class="w"> </span>-rf<span class="w"> </span>.git/svn/
</code></pre></div>
<p>Edit <em>.git/config</em> and remove the <code>svn-remote</code> stanza</p>
<h2>Commiting into the new repository</h2>
<p>Now that we can connect our git repository to the new SVN location and commit
all the stuff:</p>
<div class="codehilite"><pre><span></span><code><span class="c1"># Create the new repository directory if necessary</span>
svn<span class="w"> </span>mkdir<span class="w"> </span>https://new/repo/
<span class="c1"># Init, fetch, rebase and commit:</span>
git<span class="w"> </span>svn<span class="w"> </span>init<span class="w"> </span>https://new/repo
git<span class="w"> </span>svn<span class="w"> </span>fetch
git<span class="w"> </span>rebase<span class="w"> </span>git-svn
git<span class="w"> </span>svn<span class="w"> </span>dcommit
</code></pre></div>
<p>Maybe not the most elegant solution but it works. The new repository contains
everything from the old one, only the commit dates are messed up.</p> Reportbug finally has a GUI! 2009-03-25T18:22:00+01:00 2009-03-25T18:22:00+01:00 Bastian Venthur tag:venthur.de,2009-03-25:/2009-03-25-reportbug-finally-has-a-gui.html Reportbug finally has a GUI! <p>It’s good to see that reportbug 4 finally has a graphical user interface –
it’s GTK, but nobody’s perfect :)</p>
<p>Anyways, I’m really glad to see reportbug aiming to improve it’s usability.</p>
<p>Reportbug finally shows all the bugreports for a package in a list which is
easily filterable. So when you’re confronted with a huge list of bugreports
but searching for a specific problem, you can just enter a few letters in the
filter and the buglist will shrink immediately. This missing feature was
basically the most important reason why I developed reportbug-ng: Users are
expected to don’t report bugs which are already filed against a package, but
the main tool which was used back then to report the bugs didn’t make this
task trivial. Now it does and it’s a good thing!</p>
<p><img alt="reportbug and reportbug-ng" src="/images/reportbug-rng.png" title="reportbug-rng"></p>
<p>Compared to reportbug-ng, reportbug shows the bugreports of a package in a
tree-view, while rng shows them in a table-view. The difference is that
reportbug could theoretically group serveral bugs together, like merged bugs.
It currently only uses this feature to group bugs of the same severity and
status. Rng does that by coloring the lines. Unfortunately in reportbug all
nodes are <em>collapsed</em> by default, which is not very usable since you have to
expand every node in order to see all bugreports. This costs the user several
clicks in order to see all bugreports.</p>
<p>It’s also not possible to sort the bugs via the columns of the table, e.g.
sort by date of last action which I think is a huge feature in order to
quickly find certain kind of bugs (old bugs, bugs sorted by date of last
activity) – but that’s probably easy to fix.</p>
<p>Another good news is that Reportbug now brings it’s own editor so the user is
not forced anymore to use an console based- and maybe unfamiliar editor to
compose his bugreport. This is a huge step forward regarding usability. It
also moves the concept of <em>writing a mail to the BTS</em> a bit more away from the
user which is a good thing. Maybe the BTS will support an <a href="https://wiki.debian.org/SummerOfCode2009/DebbugsRWSOAP">alternative
way</a> to receive
bugreports in the future so mail clients may become superfluous for reporting
bugs.</p>
<p>Under the hood reportbug still parses the HTML from https://bugs.debian.org/
go gain the bugreport instead of the BTS’ SOAP interface. This coupling is of
course <a href="2007-06-27-what-does-it-take-to-break-rng.html">dangerous</a> since even
the smallest change in the BTS webdesign could break reportbug. But SOAP
support is already on the todo list of reportbug’s devs. I can only encourage
this step, when reportbug-ng moved away from HTML-parsing to SOAP the actual
amount of work it took was much less then I thought, I think it took me just
one or two days and as a result there is
<a href="https://packages.qa.debian.org/p/python-debianbts.html">python-debianbts</a>
which provides a bridge between the SOAP interface and Python.</p>
<p>In summary I think this is an important improvement for reportbug. There are
still some minor issues like the welcome screen always showing, the nodes
collapsed by default and the columns not beeing sortable but those are small
issues and easy to fix. I’m very happy to see this improvement, since it will
motivate the not so tech-savvy folks to report bugs, and more bugreports will
ultimately lead to a better distribution.</p>
<p>Good work guys!</p> git-svn branch 2009-02-27T20:08:00+01:00 2009-02-27T20:08:00+01:00 Bastian Venthur tag:venthur.de,2009-02-27:/2009-02-27-git-svn-branch.html git-svn branch <p>Dear Lazyweb,</p>
<p>how do I push a local git branch to a new svn branch? The other way round is
quite easy and well documented but I didn’t find a single document describing
what I want to do.</p>
<p>I’m working with an svn repository with standard layout. I use git-svn to be
able to use git locally. Until now I’ve always had my master branch reflect
the svn’s trunk. For every new feature, I created a local git branch, merged
with the master branch when I was done and dcommit’ed it to the svn’s trunk.
But now I need to publish an experimental feature which should not yet go into
the trunk so I have to publish my local git branch to an svn branch.</p>
<p>I tried <code>git-svn branch foo</code> in the local git branch and it created a svn
branch/foo for me but not from the current git branch but from the current
master (remote/trunk). That’s of course not what I wanted, I wanted to push
the current branch where I’m in and have it linked to the remote svn branch.</p>
<p>Neither the manpage of git-svn nor some documentation in the web helped me. I
even found a <a href="https://www.amitu.com/blog/2008/march/git-svn-whys-and-hows/">pretty detailed
document</a> which
describes each and every aspect of git-svn but unfortunately not mine.</p>
<p>Is this use case so unusual that no one else uses git-svn this way or is it my
weak git-FU?</p> Lenny 2009-02-15T16:39:00+01:00 2009-02-15T16:39:00+01:00 Bastian Venthur tag:venthur.de,2009-02-15:/2009-02-15-lenny.html Lenny <p>Today Lenny was finally released. According to <a href="https://bugs.debian.org/release-critical/">this
page</a> with roughly 120 open release
critical bugs. That’s quite a big number according to our standards, but still
a good and necessary compromise. Thanks for everyone involved, good work
everyone!</p>
<p>I’m very happy that the release didn’t take quite as long as I predicted.
Three or four more months of Sid being frozen would probably have meant more
people playing with semi-supported mixtures of unstable and experimental
packages and more migration towards other distributions with more current
software packages. So I’m very happy to see over a hundred new packages
uploaded to unstable already and roughly 700 new release critical bugs opened
:)</p> Valentine's Day! 2009-02-02T00:04:00+01:00 2009-02-02T00:04:00+01:00 Bastian Venthur tag:venthur.de,2009-02-02:/2009-02-02-valentines-day.html Valentine's Day! <p>According to <a href="https://lists.debian.org/debian-devel-announce/2009/02/msg00000.html">this
message</a>
on -devel-announce, Lenny <em>might</em> release on this year’s Valentine’s Day which
happens to be in two weeks.</p>
<p>These are absolutely fantastic news! Can’t wait to comment out the
experimental lines in my sources.list and see some <a href="https://kde.org/">fresh</a>
(and <a href="https://www.x.org/">badly</a> <a href="https://kernel.org/">needed</a>) packages in
unstable again.</p> Nice(r) console fonts 2009-01-10T14:05:00+01:00 2009-01-10T14:05:00+01:00 Bastian Venthur tag:venthur.de,2009-01-10:/2009-01-10-nicer-console-fonts.html Nice(r) console fonts <p>Ever wanted to get a nicer console font than the default one delivered with
Debian?</p>
<p>First you need to get a nice font. I chose console-terminus:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>aptitude<span class="w"> </span>install<span class="w"> </span>console-terminus
</code></pre></div>
<p>that alone won’t change anything but install a whole bunch of new fonts into
<code>/usr/share/consolefonts/</code>. To enable one of them, you have to edit
<code>/etc/console-tools/config</code>:</p>
<div class="codehilite"><pre><span></span><code>set SCREEN_FONT=Uni3-Terminus16
</code></pre></div>
<p>Optional: comment out the following lines with <code>SCREEN_FONT_vc*</code>, so every
terminal will have the same settings.</p>
<p>To test the new font:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>/etc/init.d/console-screen.sh<span class="w"> </span>start
</code></pre></div>
<p>The new font kicks in at the second half of the boot process, which is fixable
but sufficient for me. I think the new font is much easier to the eyes than
the default one, especially on big monitors with high resolutions.</p> How many bugs have you fixed today? 2008-12-16T14:54:00+01:00 2008-12-16T14:54:00+01:00 Bastian Venthur tag:venthur.de,2008-12-16:/2008-12-16-how-many-bugs-have-you-fixed-today.html How many bugs have you fixed today? <p>That is the sledgehammer argument people bring up when others dare to
criticize the current release process.</p>
<p>I think this question is nonsense. While the bug-fix rate was more or less the
same since the last two releases, it looks like in this release we simply
started the freeze with much more open RC-bugs than before (~3 times more
RC-bugs than with Etch). So it was <em>foreseeable</em> that the freeze would take
longer this time. We can’t solve the problem by trying to fix bugs faster,
we’ve tried it several times with mediocre success. That doesn’t mean we
shouldn’t keep up fixing bugs, but we should probably accept that a certain
number of people can only fix a certain number of bugs in a given time. In our
case roughly <em>30 RC-bugs per month</em>.</p>
<p>So what’s the point of asking how many RC-bugs one has fixed? Does that mean
only those are allowed to make suggestions, who fixed an RC bug? That pressure
doesn’t help anyone. I believe unstable being frozen for several months is a
very important problem which can have drastic consequences regarding the
number of our users, and we will not solve it by suggesting to fix our bugs
faster.</p> Lenny Release General Resolution 2008-12-14T12:34:00+01:00 2008-12-14T12:34:00+01:00 Bastian Venthur tag:venthur.de,2008-12-14:/2008-12-14-lenny-release-general-resolution.html Lenny Release General Resolution <p>I agree, this <a href="https://www.debian.org/vote/2008/vote_003">vote</a> is one of the
worst formulated I can remember. I think votes should be as easy as possible
to understand, so that the voter is absolutely clear about what he’s going to
vote. The current vote is the perfect example how <em>not</em> to design such a vote.
Reading and understanding the ballot is very exhausting, the wording sounds
polemic and given the options, it somehow feels like a trap.</p>
<p>Example: The first option is “Reaffirm the social contract”. Sounds nice, of
course we want that, but in the footnotes it says</p>
<blockquote>
<p>[…] we will delay the release of Lenny until such point that the
work to free the operating system is complete (to the best of our
knowledge as of 1 November 2008).</p>
</blockquote>
<p>So you’re actually voting on delaying the release of Lenny until some
technical details are cleared. This is really crap, why not name the option
“Delay Lenny until foo” in the first place? I guess to motivate people a bit
more to rank this option above all others.</p>
<p>I’m very disappointed. Next vote, fever options and clearer wording please.</p> Lenny's release date III 2008-12-09T16:07:00+01:00 2008-12-09T16:07:00+01:00 Bastian Venthur tag:venthur.de,2008-12-09:/2008-12-09-lennys-release-date-iii.html Lenny's release date III <p>Two months since my <a href="2008-10-07-lennys-release-date.html">last status update</a> of
my <a href="2008-08-01-my-guess-for-lennys-release-date.html">initial guess for Lenny’s release
date</a>, time for an update:</p>
<p><img alt="My guess for Lenny's release III" src="/images/release-guess-3.png"></p>
<p>I don’t know what the current “official” release target for Lenny is, but I
still think we’re heading towards Spring/Summer 2009.</p>
<p>The last <a href="https://lists.debian.org/debian-devel-announce/2008/10/msg00000.html">related mail on
-devel-announce</a>
is from October 2008 from Alexander who hopes that we’ll release Lenny at
least by the end of 2008. I’ve read an article with an interview with Steve
McIntyre <a href="https://www.theregister.co.uk/2008/10/10/debian_lenny_late/">somewhere on The
Register</a> where
he said:</p>
<blockquote>
<p>“Bastian’s being a little bit pessimistic based on the data he’s
looking at, but as far as I know, he hasn’t spoken to any of the
release team. As far as Lenny goes, we’re ‘almost’ there,” he told The
Register.</p>
</blockquote>
<p>That interview was in the beginning of October.</p>
<p>It doesn’t bother me too much, that we release late. What bothers me is that
we don’t <em>correct</em> our estimated release dates even when it’s <em>obvious</em> that
there is no way we will release in time. It’s really sad that we keep our
users in the dark about the fact that we can’t release in time until it’s
already too late.</p>
<p>I believe many users would appreciate if we’d honestly say: We don’t know when
we release, but currently we have x RC bugs open and looking at the last
releases we think it will take roughly n months to fix them and release,
instead of the good old “We release when it’s ready”.</p>
<p>Another important point: Unstable is frozen for almost <em>five months</em> now. If
you buy a <a href="2008-11-25-lenovo-t500-shiny-new-laptop.html">current laptop</a>,
chances are hight that it might not fully work with Debian “bleeding edge”
unstable, since it’s horrible outdated. Some of the newer stuff can be
obtained from experimental if you’re brave enough, but if you’re not, unstable
is getting more and more unattractive compared to other distribution’s current
versions. This is really something we should try to fix after we released
Lenny.</p> Lenovo T500 (shiny new laptop) 2008-11-25T17:36:00+01:00 2008-11-25T17:36:00+01:00 Bastian Venthur tag:venthur.de,2008-11-25:/2008-11-25-lenovo-t500-shiny-new-laptop.html Lenovo T500 (shiny new laptop) <p>Yesterday I exchanged my “old” Thinkpad T60 with a shiny new T500. This time I
ordered a Thinkpad with integrated Intel graphics since it’s supposed to be
way better supported than the graphic chips from ATI or NVIDIA under Linux.
And of course it is supposed to be much more silent.</p>
<p>I don’t regret this decision so far, the new T500 is barely hearable even
under heavy load.</p>
<h2>Debian</h2>
<p>I installed Debian unstable (aka. frozen for waaayy to long) without a
problem. Sound worked out of the box, graphics worked somewhat. The kernel
automatically loaded the correct modules but I had to tell Xorg that I want
the “intel” driver instead of Vesa. Unfortunately Xorg’s intel driver in
unstable is already too old to allow me to use an external monitor via the
docking station’s DVI port, so I had to to upgrade to Xorg from experimental,
which is not very cool since this is the machine I depend on at work.</p>
<p>Wifi also doesn’t work, since the the driver and firmware available in
unstable are outdated. Suspend to RAM works sometimes, but most of the time
the laptop refuses to wake up properly so I have to shut it down.</p>
<p>I’ve not yet tested if bluetooth and Wimax works.</p>
<p>So currently the T500 is usable under unstable but without external monitor
and without Wifi. If you are brave enough to use packages from experimental,
you get your external monitor to work but still don’t have Wifi. Suspend to
RAM does not work reliably.</p>
<p>The T500 should probably work fine with Lenny but of course without external
Monitor and Wifi support.</p>
<h2>Vista</h2>
<p>After I’ve installed Debian and moved my /home from the old laptop to my new
baby, I noticed that silly “Windows Vista” sticker on my laptop. Of course I
tried to remove that thing, which I regretted painfully.</p>
<p>After I’ve successfully removed the sticker – which was surprisingly hard –
some glue remained on the surface of the laptop. No problem I thought, nothing
some nail polish remover can’t handle. Unfortunately it only smeared the glue
but did not resolve it as I had expected. So I’ve tried perfume, water, soap,
rubber, tape and solvent for several <em>hours</em>, but was not able to remove the
glue at all. All I achieved was to smear the compact but thick chunk of glue
to a very thin but much more distributed layer of this nasty glue on my
laptop. Now it looks like a 5x5cm square of dirt on top of my laptop – not
sure if removing the Vista sticker was worth it.</p> rm -rf / 2008-11-10T11:14:00+01:00 2008-11-10T11:14:00+01:00 Bastian Venthur tag:venthur.de,2008-11-10:/2008-11-10-rm-rf.html rm -rf / <p>… does not work. At least not today on a Debian/Sid system. Looks like there
are some things, not even root is allowed to do:</p>
<div class="codehilite"><pre><span></span><code><span class="n">root</span><span class="nv">@sid</span><span class="err">:</span><span class="o">~</span><span class="err">#</span><span class="w"> </span><span class="n">rm</span><span class="w"> </span><span class="o">-</span><span class="n">rf</span><span class="w"> </span><span class="o">/</span>
<span class="nl">rm</span><span class="p">:</span><span class="w"> </span><span class="n">cannot</span><span class="w"> </span><span class="n">remove</span><span class="w"> </span><span class="n">root</span><span class="w"> </span><span class="n">directory</span><span class="w"> </span><span class="err">‘</span><span class="o">/</span><span class="err">'</span>
</code></pre></div>
<p>If you’re curious what happens when you wipe your disk on a running system:</p>
<div class="codehilite"><pre><span></span><code><span class="n">root</span><span class="nv">@sid</span><span class="err">:</span><span class="o">~</span><span class="err">#</span><span class="w"> </span><span class="n">cd</span><span class="w"> </span><span class="o">/</span>
<span class="n">root</span><span class="nv">@sid</span><span class="err">:</span><span class="o">/</span><span class="err">#</span><span class="w"> </span><span class="n">rm</span><span class="w"> </span><span class="o">-</span><span class="n">rf</span><span class="w"> </span><span class="o">*</span><span class="err">`</span>
</code></pre></div>
<p>does the trick.</p>
<p><strong>Update:</strong> That’s with plain rm not safe-rm.</p>
<p><strong>Update 2:</strong> I looked through the code of <code>rm.c</code> to find that <code>/</code> is
protected by default – as a simple <code>rm --help</code> also shows:</p>
<div class="codehilite"><pre><span></span><code><span class="err">$</span><span class="w"> </span><span class="n">rm</span><span class="w"> </span><span class="c1">--help Usage: rm [OPTION]... FILE...</span>
<span class="n">Remove</span><span class="w"> </span><span class="p">(</span><span class="n">unlink</span><span class="p">)</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="k">FILE</span><span class="p">(</span><span class="n">s</span><span class="p">).</span>
<span class="o">[</span><span class="n">...</span><span class="o">]</span>
<span class="c1">--no-preserve-root do not treat `/' specially</span>
<span class="c1">--preserve-root do not remove `/' (default)</span>
</code></pre></div> Tags 2008-10-11T20:29:00+02:00 2008-10-11T20:29:00+02:00 Bastian Venthur tag:venthur.de,2008-10-11:/2008-10-11-tags.html Tags <p>Version 1.2 of reportbug-ng now shows the tags of a bug if available. This was
long overdue. Now you can for example, quickly search your bugs for the ones
with the moreinfo-tag set and sort the resulting list by the date of the last
action. This should give you a quick overview of bugs which may need some
action (eg. another reminder to the submitter) or can potentially be safely
closed.</p>
<p><img alt="rng-tags.png" src="/images/rng-tags.png"></p>
<p>In the next step I’ll improve the filter of rng and add a context menu which
will allow to manipulate the tags of one or more bugreports and send all the
changes in a single mail to control@bugs.debian.org.</p> Lenny's release date 2008-10-07T14:07:00+02:00 2008-10-07T14:07:00+02:00 Bastian Venthur tag:venthur.de,2008-10-07:/2008-10-07-lennys-release-date.html Lenny's release date <p>Today, an <a href="https://www.heise.de/newsticker/Debian-5-0-soll-noch-in-diesem-Jahr-fertig-werden--/meldung/117018">article at heise
online</a>
claimed, that Lenny is supposed to ship this year, quoting <a href="https://blog.schmehl.info//2008/10/07#releasing-lenny">Alexander’s blog
entry</a>. While I can’t
find a single word in Alexander’s article claiming that we’ll release this
year, I’m pretty sorry that just after we failed the first deadline which was
obviously too “optimistic”, we get another one which is too short.</p>
<p><a href="2008-08-01-my-guess-for-lennys-release-date.html">Two month’s ago</a> I created a
pretty simple estimation regarding Lenny’s release by looking at the
rc-bugfix-rate of the last two releases and applying them to the current
number of rc-bugs. As a result it looked more likely that we release Lenny in
<em>June 2009</em> than in September 2008. Until now, my guess for Lenny’s release
still holds, at least the updated rc-graph lies perfectly on the line I’ve
created two months ago.</p>
<p><img alt="rc-graph2.png" src="/images/rc-graph2.png"></p>
<p>While I wish that we’ll release Lenny as soon as possible, I hope that someone
will clarify the proposed release date to the media and this time with a more
defensive deadline. Some people might actually trust our estimation (I know
this sounds silly). And even if everyone <em>knows</em> that Debian notoriously
releases too late – we could at least try to propose more realistic dates and
update them regularly. Just two weeks ago I still read and heard in the media
that Debian will release Lenny in September although it was clear at this
point that this is impossible.</p> Gettext and QT4? 2008-09-14T14:04:00+02:00 2008-09-14T14:04:00+02:00 Bastian Venthur tag:venthur.de,2008-09-14:/2008-09-14-gettext-and-qt4.html Gettext and QT4? <p>Dear Lazyweb,</p>
<p>do you know how to translate QT4 applications with gettext? Looks like QT4 now
uses it’s own mechanism (lupdate -> .ts -> linguist -> .ts -> lrelease -> .qm)
for translating strings, which makes things a bit complicated if the rest of
your application (the non GUI part) still uses gettext.</p>
<p>The background is – as some of you may have noticed – that rng’s GUI isn’t
properly translated anymore since the switch from QT3 to QT4. I don’t know if
I just should adopt QT4’s translation mechanism, but for now it would be very
nice if I just could use my .po files for the QT4 stuff.</p> Finally, a Debian Live CD 2008-08-28T11:05:00+02:00 2008-08-28T11:05:00+02:00 Bastian Venthur tag:venthur.de,2008-08-28:/2008-08-28-finally-a-debian-live-cd.html Finally, a Debian Live CD <p>That was just about time. In the last two Linux Tag events people asked us for
Live-CDs and we had to explain why we don’t have any, while most other distros
have. Now we finally can offer a <a href="https://cdimage.debian.org/cdimage/lenny_live_beta1/">Debian
Live-CD</a>. Still beta,
but a huge improvement.</p>
<p>Thanks Debian Live team!</p> What is group x in /etc/group for and should I be a member? 2008-08-03T20:53:00+02:00 2008-08-03T20:53:00+02:00 Bastian Venthur tag:venthur.de,2008-08-03:/2008-08-03-what-is-group-x-in-etcgroup-for-and-should-i-be-a-member.html What is group x in /etc/group for and should I be a member? <p>A few days ago I noticed that suspend to RAM didn’t work anymore on my T60
running sid. By chance I stumbled upon
<a href="https://bugs.debian.org/484248">#484248</a> which explains that the user now has
to be in the <code>powerdev</code> group to be able to suspend the machine.</p>
<p>If I hadn’t found this information, I would have had no idea what to change to
make me able to suspend my machine again.</p>
<p>Shouldn’t we have a central list somewhere in <code>/usr/share/doc</code> explaining all
the different groups and what they mean? Most of the times the package a group
belongs to already explains what the meaning of this group is, but if you
<em>don’t know</em> the package, you’re pretty much screwed.</p>
<p>I’m not saying, we already have too many groups, but a list with all the
important groups and what they’re for would be a huge usability improvement.
We can’t expect the user to find that information for every group alone.</p> My guess for Lenny's release date 2008-08-01T11:58:00+02:00 2008-08-01T11:58:00+02:00 Bastian Venthur tag:venthur.de,2008-08-01:/2008-08-01-my-guess-for-lennys-release-date.html My guess for Lenny's release date <p>Looking at the <a href="https://bugs.debian.org/release-critical/">current number of release-critical
bugs</a>, my guess for the actual
release date of Lenny is: around June 2009.</p>
<p><img alt="rc-graph.png" src="/images/rc-graph.png"></p>
<p>The blue lines have exactly the same angle, the greenish line marks the
planned release date.</p>
<p>I know that’s not exactly scientific, but let’s see how close I am.</p>
<p>The blue graph marks by the way the number of release-critical bugs in
<em>stable</em>.</p> Rng 1.0 in unstable 2008-07-19T15:30:00+02:00 2008-07-19T15:30:00+02:00 Bastian Venthur tag:venthur.de,2008-07-19:/2008-07-19-rng-10-in-unstable.html Rng 1.0 in unstable <p>I’ve finished the porting of <a href="https://reportbug-ng.alioth.debian.org/">rng</a>
from qt3 to qt4 and uploaded it to unstable. It has some minor regressions
compared to the qt3 version, like the localization of the qt4 widgets which
isn’t working yet and that the column which sorts the table isn’t saved and
restored properly on startup, but it closes many other bugs and <em>it doesn’t
crash anymore</em>.</p>
<p>The new version doesn’t bring so much new features so far, but since it’s
using much of the stuff which came with QT4, like the QTableModel and the
QWebView, it runs much faster in many cases, e.g. when sorting or filtering
the table.</p>
<p>Ah, and last but but not least: thanks to WebKit rng even passes
<a href="https://acid1.acidtests.org/">acid1</a> and <a href="https://acid2.acidtests.org/">acid2</a>.
Doesn’t yet pass <a href="https://acid3.acidtests.org/">acid3</a> but I guess someone is
already working on it :)</p>
<p><img alt="rng passing acid2" src="/images/rng-acid2.png"></p> Porting rng to QT4 2008-07-13T23:40:00+02:00 2008-07-13T23:40:00+02:00 Bastian Venthur tag:venthur.de,2008-07-13:/2008-07-13-porting-rng-to-qt4.html Porting rng to QT4 <p>Today I was busy porting reportbug-ng to QT4. One really cool thing I noticed
is the new QWebView widget, which is the main widget of the QWebKit module. It
works surprisingly easy compared to the good old QTextBrowser of QT3 – now
you can just throw an URL at it and it will render the page nicely complete
with CSS, images, etc.</p>
<p>Here’s the obligatory screenshot:</p>
<p><img alt="reportbug-ng qt4" src="/images/rng-qt4.png"></p>
<p>as you can see, the bugreport looks much better than in the old version of
rng. WebKit does a really good job rendering the HTML, I think the fonts look
even smoother than under firefox.</p>
<p>To ease the transition to from QT3 to QT4 I’ve extracted all the Debian BTS
specific stuff to
<a href="https://packages.debian.org/sid/python-debianbts">python-debianbts</a> and
uploaded it to unstable. Rng uses it to query our Bug Tracking System via it’s
SOAP interface and get the data in Python’s native data types.</p>
<p>There is still the problem with rng (QT3) crashing when showing bugreports.
I’ve investigated the problem a bit and found out that it is not rng’s fault
but <a href="https://bugs.debian.org/490340">probably a problem with python-qt3</a> or
one of it’s underlying libs. QTextBrowser causes segfaults in nearly 50% of
the cases where you try to render html from a different thread: here’s an easy
way to reproduce:</p>
<div class="codehilite"><pre><span></span><code><span class="c1"># crash.py</span>
<span class="c1"># Usage: python crash.py "some text"</span>
<span class="c1"># python crash.py "some evil html"</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">qt</span><span class="w"> </span><span class="kn">import</span> <span class="o">*</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">sys</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">threading</span>
<span class="k">class</span><span class="w"> </span><span class="nc">Form</span><span class="p">(</span><span class="n">QMainWindow</span><span class="p">):</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">parent</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span><span class="n">name</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span><span class="n">fl</span> <span class="o">=</span> <span class="mi">0</span><span class="p">):</span>
<span class="n">QMainWindow</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">parent</span><span class="p">,</span><span class="n">name</span><span class="p">,</span><span class="n">fl</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">browser</span> <span class="o">=</span> <span class="n">QTextBrowser</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">"browser"</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">setCentralWidget</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">browser</span><span class="p">)</span>
<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span> <span class="o"><</span> <span class="mi">2</span><span class="p">:</span>
<span class="nb">print</span> <span class="s1">'Usage: </span><span class="si">%s</span><span class="s1"> "some text"'</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">0</span><span class="p">]</span>
<span class="n">sys</span><span class="o">.</span><span class="n">exit</span><span class="p">()</span>
<span class="n">s</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</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="c1"># setup qt stuff with a browser</span>
<span class="n">app</span> <span class="o">=</span> <span class="n">QApplication</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span>
<span class="n">app</span><span class="o">.</span><span class="n">connect</span><span class="p">(</span><span class="n">app</span><span class="p">,</span> <span class="n">SIGNAL</span><span class="p">(</span><span class="s2">"lastWindowClosed()"</span><span class="p">),</span> <span class="n">app</span><span class="p">,</span> <span class="n">SLOT</span><span class="p">(</span><span class="s2">"quit()"</span><span class="p">))</span>
<span class="n">form</span> <span class="o">=</span> <span class="n">Form</span><span class="p">()</span>
<span class="n">app</span><span class="o">.</span><span class="n">setMainWidget</span><span class="p">(</span><span class="n">form</span><span class="p">)</span>
<span class="n">form</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
<span class="c1"># start a different thread and try to set the text in the browser</span>
<span class="c1"># we wait 1.0 second -- just to make sure the change happens after the</span>
<span class="c1"># start of app.exec_loop() below</span>
<span class="n">t</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Timer</span><span class="p">(</span><span class="mf">1.0</span><span class="p">,</span> <span class="n">form</span><span class="o">.</span><span class="n">browser</span><span class="o">.</span><span class="n">setText</span><span class="p">,</span> <span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="p">))</span>
<span class="n">t</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
<span class="n">app</span><span class="o">.</span><span class="n">exec_loop</span><span class="p">()</span>
</code></pre></div>
<p>QWebView doesn’t seem to have this problem, the QT4 version of rng didn’t
crash a single time.</p>
<p>I’m not quite ready with the porting to QT4, and since I’ll be quite busy
during the next weeks I suppose it will take a few weeks until the new version
will be updated to unstable.</p> Maximize vs Maximize to Preferred Size 2008-07-11T18:00:00+02:00 2008-07-11T18:00:00+02:00 Bastian Venthur tag:venthur.de,2008-07-11:/2008-07-11-maximize-vs-maximize-to-preferred-size.html Maximize vs Maximize to Preferred Size <p>In times where screen resolutions of 1600x… and above are becoming more and
more common, I wonder if the maximize window button which enlarges a window to
take all the available space on the desktop is still as useful as it used to
be.</p>
<p>I noticed that some (if not all, I’m not a Mac user) applications on Mac only
maximize their windows depending on the content of the window. For example if
you maximize the window of your word processor, the window becomes only as
wide as necessary to make the whole page visible. This doesn’t just look
better on very large monitors, it is also more usable than a simple maximize
since it doesn’t unnecessarily hide other windows.</p>
<p>Is there a window manager for Linux which does something similar, or better:
is something like this possible with KDE? I know that QT widgets have a
“preferred size” – shouldn’t it be possible to have a maximize to preferred
size button? It’s surely not useful for every application, but may
applications only need a quite small main window and look very ugly when
maximized.</p> Segfaults Everywhere 2008-07-07T21:09:00+02:00 2008-07-07T21:09:00+02:00 Bastian Venthur tag:venthur.de,2008-07-07:/2008-07-07-segfaults-everywhere.html Segfaults Everywhere <p>Dear Lazyweb,</p>
<p>A few weeks ago rng started to show some segfaulty behavior. I’ve absolutely
no idea what’s going on, since Python code usually doesn’t segfault. I guess
the problem lies in the qt3-bindings rng uses – does someone know how to
verify this?</p>
<p>There is a <a href="https://bugs.debian.org/486212">backtrace</a> which seems to show
that the problem lies somewhere in <code>/usr/lib/python2.5/site-packages/qt.so</code>
but I’m not entirely sure how to interpret that.</p> Tab Completion in Python's Interactive Mode 2008-07-06T22:15:00+02:00 2008-07-06T22:15:00+02:00 Bastian Venthur tag:venthur.de,2008-07-06:/2008-07-06-tab-completion-in-pythons-interactive-mode.html Tab Completion in Python's Interactive Mode <p>While browsing the python docs, I accidentally stumbled upon
<a href="https://docs.python.org/lib/module-rlcompleter.html">this</a> today. It
describes how to get Tab completion in Python’s interactive shell:</p>
<ol>
<li>Create a <code>~/.pythonrc</code> file with the following content:</li>
</ol>
<div class="codehilite"><pre><span></span><code><span class="k">try</span><span class="p">:</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">readline</span>
<span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
<span class="nb">print</span> <span class="s2">"Module readline not available."</span>
<span class="k">else</span><span class="p">:</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">rlcompleter</span>
<span class="n">readline</span><span class="o">.</span><span class="n">parse_and_bind</span><span class="p">(</span><span class="s2">"tab: complete"</span><span class="p">)</span>
</code></pre></div>
<ol>
<li>Put this somewhere in your <code>~/.bashrc</code></li>
</ol>
<div class="codehilite"><pre><span></span><code><span class="nb">export</span><span class="w"> </span><span class="nv">PYTHONSTARTUP</span><span class="o">=</span>~/.pythonrc
</code></pre></div>
<p>The <code>.pythonrc</code> will be executed every time the Python interpreter is started
but not when it executes a script.</p>
<p>How does it look like?</p>
<div class="codehilite"><pre><span></span><code><span class="err">$</span> <span class="n">python</span>
<span class="n">Python</span> <span class="mf">2.5.2</span> <span class="p">(</span><span class="n">r252</span><span class="p">:</span><span class="mi">60911</span><span class="p">,</span> <span class="n">Jun</span> <span class="mi">25</span> <span class="mi">2008</span><span class="p">,</span> <span class="mi">17</span><span class="p">:</span><span class="mi">58</span><span class="p">:</span><span class="mi">32</span><span class="p">)</span>
<span class="p">[</span><span class="n">GCC</span> <span class="mf">4.3.1</span><span class="p">]</span> <span class="n">on</span> <span class="n">linux2</span>
<span class="n">Type</span> <span class="s2">"help"</span><span class="p">,</span> <span class="s2">"copyright"</span><span class="p">,</span> <span class="s2">"credits"</span> <span class="ow">or</span> <span class="s2">"license"</span> <span class="k">for</span> <span class="n">more</span> <span class="n">information</span><span class="o">.</span>
<span class="o">>>></span> <span class="n">l</span> <span class="o">=</span> <span class="p">[]</span>
<span class="o">>>></span> <span class="n">l</span><span class="o">.</span>
<span class="n">l</span><span class="o">.</span><span class="fm">__add__</span> <span class="n">l</span><span class="o">.</span><span class="n">__getslice__</span> <span class="n">l</span><span class="o">.</span><span class="fm">__ne__</span> <span class="n">l</span><span class="o">.</span><span class="n">append</span>
<span class="n">l</span><span class="o">.</span><span class="vm">__class__</span> <span class="n">l</span><span class="o">.</span><span class="fm">__gt__</span> <span class="n">l</span><span class="o">.</span><span class="fm">__new__</span> <span class="n">l</span><span class="o">.</span><span class="n">count</span>
<span class="n">l</span><span class="o">.</span><span class="fm">__contains__</span> <span class="n">l</span><span class="o">.</span><span class="fm">__hash__</span> <span class="n">l</span><span class="o">.</span><span class="n">__reduce__</span> <span class="n">l</span><span class="o">.</span><span class="n">extend</span>
<span class="n">l</span><span class="o">.</span><span class="fm">__delattr__</span> <span class="n">l</span><span class="o">.</span><span class="fm">__iadd__</span> <span class="n">l</span><span class="o">.</span><span class="n">__reduce_ex__</span> <span class="n">l</span><span class="o">.</span><span class="n">index</span>
<span class="n">l</span><span class="o">.</span><span class="fm">__delitem__</span> <span class="n">l</span><span class="o">.</span><span class="fm">__imul__</span> <span class="n">l</span><span class="o">.</span><span class="fm">__repr__</span> <span class="n">l</span><span class="o">.</span><span class="n">insert</span>
<span class="n">l</span><span class="o">.</span><span class="n">__delslice__</span> <span class="n">l</span><span class="o">.</span><span class="fm">__init__</span> <span class="n">l</span><span class="o">.</span><span class="fm">__reversed__</span> <span class="n">l</span><span class="o">.</span><span class="n">pop</span>
<span class="n">l</span><span class="o">.</span><span class="vm">__doc__</span> <span class="n">l</span><span class="o">.</span><span class="fm">__iter__</span> <span class="n">l</span><span class="o">.</span><span class="fm">__rmul__</span> <span class="n">l</span><span class="o">.</span><span class="n">remove</span>
<span class="n">l</span><span class="o">.</span><span class="fm">__eq__</span> <span class="n">l</span><span class="o">.</span><span class="fm">__le__</span> <span class="n">l</span><span class="o">.</span><span class="fm">__setattr__</span> <span class="n">l</span><span class="o">.</span><span class="n">reverse</span>
<span class="n">l</span><span class="o">.</span><span class="fm">__ge__</span> <span class="n">l</span><span class="o">.</span><span class="fm">__len__</span> <span class="n">l</span><span class="o">.</span><span class="fm">__setitem__</span> <span class="n">l</span><span class="o">.</span><span class="n">sort</span>
<span class="n">l</span><span class="o">.</span><span class="fm">__getattribute__</span> <span class="n">l</span><span class="o">.</span><span class="fm">__lt__</span> <span class="n">l</span><span class="o">.</span><span class="n">__setslice__</span>
<span class="n">l</span><span class="o">.</span><span class="fm">__getitem__</span> <span class="n">l</span><span class="o">.</span><span class="fm">__mul__</span> <span class="n">l</span><span class="o">.</span><span class="fm">__str__</span>
<span class="o">>>></span> <span class="n">l</span><span class="o">.</span>
</code></pre></div>
<p>Very cool! Why is this hidden so deep in the docs and not enabled by default?</p> Linux Action Show 2008-07-03T13:35:00+02:00 2008-07-03T13:35:00+02:00 Bastian Venthur tag:venthur.de,2008-07-03:/2008-07-03-linux-action-show.html Linux Action Show <p><a href="https://mjr.towers.org.uk/writing/reflections/End_of_LugRadio_.html">MJ Ray</a>
noticed that LugRadio is going to end soon and asks for alternatives. I’d
recommend to give <a href="https://www.jupiterbroadcasting.com/?cat=4">Linux Action
Show</a> a try. I’ve always preferred
it over LugRadio. It is funny, informative and not quite as vulgar as
LugRadio.</p> Lenny won't ship rng 2008-06-09T15:43:00+02:00 2008-06-09T15:43:00+02:00 Bastian Venthur tag:venthur.de,2008-06-09:/2008-06-09-lenny-wont-ship-rng.html Lenny won't ship rng <p>Philipp
<a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=422085#198">thinks</a>, the
fact that rng is not using the information in /usr/share/bug renders rng
“unfit for release” and upgraded the corresponding bugreport from wishlist to
<em>serious</em>. Moreover: since I dared to downgrade the report back to wishlist
<a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=422085#205">he decided</a> to
remove rng from testing and block it until the bug is fixed.</p>
<p>I don’t want to heat the debate about this bug again, but Philipp’s decision
seems arbitrary for me and I wonder if the same standard is applied to every
other Debian package. I mean, rng has no release critical defects. It just
does not use the aforementioned scripts as additional information in
bugreports – does this really render the software “unfit for release”? For
example: In Etch we shipped a famous email client with a known bug which lead
reproducibly to loss of emails on IMAP accounts, just because removing the
program, or one of it’s components was not possible in the remaining time.</p> actual file size does not match size in .changes 2008-06-04T20:26:00+02:00 2008-06-04T20:26:00+02:00 Bastian Venthur tag:venthur.de,2008-06-04:/2008-06-04-actual-file-size-does-not-match-size-in-changes.html actual file size does not match size in .changes <p>Beh! Looks like it is currently <a href="https://bugs.debian.org/474949">not possible</a>
to use debsign from <em>etch</em> to sign packages built in a <em>sid</em> cowbuilder
environment.</p>
<p><strong>Update:</strong> Adam just pointed out that this was already announced on
debian-devel-announce. He proposed to get an updated version of devscripts
from etch-backports.</p>
<p>I wonder if we shouldn’t provide a fixed version of devscripts in etch
<em>officially</em>, just in case someone who maintains packages actually *erm*
uses it.</p> Linuxtag 2008 2008-05-31T18:52:00+02:00 2008-05-31T18:52:00+02:00 Bastian Venthur tag:venthur.de,2008-05-31:/2008-05-31-linuxtag-2008.html Linuxtag 2008 <p>Linuxtag 2008 is over. Like <a href="2007-05-30-linuxtag.html">last year’s Linuxtag</a>, it
was a very nice event. We had a lot of visitors, answered a lot more questions
and sold many t-shirts, posters and stickers at our eee-pc *cough* Debian
booth. It was also very nice to meet some other people from Debian – one of
the rare moments in life where I can feel really young again… sorry guys :P</p>
<p>Of course there were many interesting talks and booths from other projects at
this year’s Linuxtag. After Nico’s and my yearly Linuxtag raid, I had like a
dozen different ball pens, a t-shirt, a handful of cookies, and many many
gummy bears.</p>
<p>Unlike last year, this year we had no Debian Day – but guess who showed up at
our booth yesterday:</p>
<p><img alt="Ian Murdock and Bastian Venthur at Linuxtag
2008" src="/images/ian_and_basti.jpg"></p>
<p>that’s right, <a href="https://ianmurdock.com/">Ian Murdock</a> himself! I was so nervous
to meet him, that I almost forgot to ask for a picture.</p>
<p>Apropos showing up at our booth: although we where fairly good manned at our
booth, we felt that a few more helpers wouldn’t have hurt. We (the staff from
this year’s Debian booth) just want to say, that you don’t have to be a Debian
Developer / Maintainer or whatever to help at our booth. If you’re an
enthusiastic Debian user and can spare some time, you’re very welcome. The
tickets for the staff are usually free, so don’t hesitate to ask if you can
help next year!</p> 4 months and 10 days without any new Debian developer... 2008-04-15T21:57:00+02:00 2008-04-15T21:57:00+02:00 Bastian Venthur tag:venthur.de,2008-04-15:/2008-04-15-4-months-and-10-days-without-any-new-debian-developer.html 4 months and 10 days without any new Debian developer... <p>I sadly agree with <a href="https://www.lucas-nussbaum.net/blog/?p=286">Lucas</a>. Waiting
several months after you finished all the tests until your account gets
finally created is really frustrating and demotivating. In my opinion this is
just a lack of manpower and seemingly no one who dares to step in to solve
this problem. Why again don’t we just throw a few more people at this problem?</p> Happy Birthday rng! 2008-03-27T16:45:00+01:00 2008-03-27T16:45:00+01:00 Bastian Venthur tag:venthur.de,2008-03-27:/2008-03-27-happy-birthday-rng.html Happy Birthday rng! <p>Hmm, better late then never, I guess. One year and two weeks ago,
<a href="https://reportbug-ng.alioth.debian.org/">reportbug-ng</a> was initially uploaded
to Debian unstable. Happy birthday rng! I wish you a lot of
<a href="https://reportbug-ng.alioth.debian.org/ponies.html">ponies</a> in the next year!</p> The Eagle has Landed 2008-03-13T10:50:00+01:00 2008-03-13T10:50:00+01:00 Bastian Venthur tag:venthur.de,2008-03-13:/2008-03-13-the-eagle-has-landed.html The Eagle has Landed <p>Yesterday, I submitted my diploma thesis (one day before the deadline –
yay!), so I will hopefully have much more time to work on my Debian packages
again.</p> Good Python IDE 2008-02-16T16:20:00+01:00 2008-02-16T16:20:00+01:00 Bastian Venthur tag:venthur.de,2008-02-16:/2008-02-16-good-python-ide.html Good Python IDE <p><a href="https://www.philkern.de/weblog/en/debian/python_ide_wanted.html">Philipp</a>
asked for a good Python IDE. I’d recommend
<a href="https://pydev.sourceforge.net/">Pydev</a>, which is a plugin for Eclipse and
works really well. I use it exclusively when coding in Python, and I’m very
happy with it.</p>
<p>Unfortunately the eclipse version in unstable is not the current one, so you
can’t use the latest Pydev version, but even the latest one which is working
with eclipse 3.2.x works well enough.</p> Juten Rutsch ins neue Jahr! 2007-12-31T11:34:00+01:00 2007-12-31T11:34:00+01:00 Bastian Venthur tag:venthur.de,2007-12-31:/2007-12-31-juten-rutsch-ins-neue-jahr.html Juten Rutsch ins neue Jahr! <p>Happy new year everyone!</p>
<p><em>NP: Moby – Jam for the Ladies (Nevins Club Blaster mix)</em></p> Merry Christmas everyone! 2007-12-24T00:52:00+01:00 2007-12-24T00:52:00+01:00 Bastian Venthur tag:venthur.de,2007-12-24:/2007-12-24-merry-christmas-everyone.html Merry Christmas everyone! <p>Since it’s already that time of the year again, merry Christmas everyone! I
hope you’re able to spend the holidays with the ones you love and enjoy a
merry, merry Christmas! Have fun everyone!</p>
<p>BTW: Am I the only one who really hates this freakin’ “Last Christmas”-song by
WHAM!? Why the heck do the radio stations here in Germany have to have this
crap on A-rotation every end of the year? This year I really tried to avoid
this song by not hearing radio or watching music television. But I made a
major mistake: I went to the Christmas fair… guess what the first song was,
I heard when I arrived? Thank god there was enough mulled wine around to ease
my pain :)</p>
<p><em>NP: Thomas D - Liebeslied</em></p> On #422085 and #417256 2007-12-18T01:03:00+01:00 2007-12-18T01:03:00+01:00 Bastian Venthur tag:venthur.de,2007-12-18:/2007-12-18-on-422085-and-417256.html On #422085 and #417256 <p>Since I received a terrifying amount of insults via mail for not implementing
<a href="https://bugs.debian.org/422085">this feature request</a> after my <a href="2007-12-08-want-to-get-money-for-nothing-and-chicks-for-free-too.html">last blog
entry</a>,
where I asked for help developing rng, I’d like to make my position about this
issue clear.</p>
<p>Why I was opposed to implement it:</p>
<ol>
<li>I <em>personally</em> hated that some packages sent a <em>huge</em> amount of unrelated
info with every bugreport for this package, even if it’s not meaningful for
this bugreport. I made a quick check against my favorite package with a
very long output and thought (and still think) that this info is not even
relevant for the majority of bugreports of this package. So I thought it
was not too much to ask, to write the reporter a friendly mail to post the
output of this script, if it’s really needed.</li>
<li>I was <em>personally</em> very annoyed by packages with very long presubj text,
which I doubt anyone reads anyway. Since I don’t want rng to be annoying to
the users, I decided to leave that feature away. An implementation of this
feature would mean to pop up a window with some text the user should read
before continuing to report the bug. I don’t like popups and don’t want rng
to make use of them.</li>
<li>I’m definitely opposed to a feature which will pop up a <em>terminal</em> where a
user has to do something before he can proceed reporting a bug. Sorry, but
this won’t happen in rng. I might consider such a thing if it could be
scripted to use QT or even GTK but a terminal popping up in a GUI
application is a no-go for me, sorry.</li>
<li>I was <em>personally</em> very annoyed by some of the reactions on this bugreport.
Since we’re all volunteers and stuff and this feature is maybe a
nice-to-have but definitely not a must-have, I decided to put this issue
very low on my to do list.</li>
</ol>
<p>However, I agree that the stuff in /usr/share/bug isn’t completely useless.
The opposite is true, it makes the life of maintainers easier and rng should
make use of it where possible.</p>
<p>So what can we do now? Maybe we can start all over and discuss this issue in a
more friendly and constructive way?</p>
<p>Here’s my offer: rng will support bugscripts, but it will not feature a
terminal popping up asking a user questions. I’m developing a GUI application
and a popping up terminal is not very GUI’ish for me. What can we do about
this? Is there a way to implement this?</p>
<p>Supporting presubj might be okay too, but I don’t want rng to be annoying.
Popups are annoying and having to read the same stuff again and again when
reporting multiple times on the same package is annoying too. Maybe rng could
spawn a pop up with a checkbox “Don’t show this text again when reporting a
bug against this package”? Maybe we could have an option in the (not yet
implemented) preferences window where we could suppress those messages
completely?</p>
<p>And please, don’t use abusive language or even insults when contacting me
about this issue. My rng-time is currently very limited and my motivation to
work especially on this issue is already very low. We’re speaking here about a
fully optional feature. Providing the output of some scripts or having to read
a presubj is helpful, but <em>not</em> mandatory when reporting a bug. So please, be
nice! I really don’t need all that stress right now.</p> Want to get money for nothing and chicks for free, too? 2007-12-08T15:49:00+01:00 2007-12-08T15:49:00+01:00 Bastian Venthur tag:venthur.de,2007-12-08:/2007-12-08-want-to-get-money-for-nothing-and-chicks-for-free-too.html Want to get money for nothing and chicks for free, too? <p>Is anyone out there interested in helping me developing
<a href="https://reportbug-ng.alioth.debian.org/">reportbug-ng</a>? I’m currently very
busy with my diploma thesis and can’t spend as much time on my pet bug
reporting tool as I’d like to spend. The package itself has some small bugs,
is not yet <a href="https://reportbug-ng.alioth.debian.org/dev.html">feature
complete</a>, but in a fairly
good shape and quite popular too.</p>
<p>If you’re interested you should have experience with python, QT and maybe some
SOAP-skills. You <em>don’t</em> have to be a Debian Developer or -Maintainer!</p>
<p>I haven’t done this before so I don’t know that the best practice for such a
situation is. I’m currently thinking of something like:</p>
<ol>
<li>First you send me patches, which I’ll review, apply and upload</li>
<li>After a while you get write access to the BZR repo</li>
<li>Finally become co-maintainer of the package if you want</li>
</ol>
<p>Interested? Then write me a mail to: venthur at debian org.</p>
<p>Oh, and please don’t write if you just want to get your
<a href="https://bugs.debian.org/422085">pet-bug-which-I-still-refuse-to-fix</a> fixed.</p>
<p>PS: If you prefer guys over chicks, you’re welcome too ;)</p> Forcing win32-loader to use i386? 2007-12-04T19:19:00+01:00 2007-12-04T19:19:00+01:00 Bastian Venthur tag:venthur.de,2007-12-04:/2007-12-04-forcing-win32-loader-to-use-i368.html Forcing win32-loader to use i386? <p>Dear Lazyweb,</p>
<p>I’m happily using the win32-loader from
<a href="https://goodbye-microsoft.com">goodbye-microsoft.com</a> to install Debian/Etch
on several Lenovo X61s subnotebooks which don’t have a DVD drive but a running
XP preinstalled. The installer correctly detects a 64bit architecture and
therefore installs AMD64. Unfortunately I want to run i386 on those machines.
Is there a way to force a specific arch for the win32-loader?</p>
<p><strong>Edit:</strong> Of course I already tried to install Debian from an USB stick on
those machines, but the Debian installer refuses to work at the point where
it’s unable to find the DVD/CD drive on the subnotebooks without one. I’ve
tried netinst and businesscard, none of them worked from USB for me. Any
hints?</p> Time-lapse-video-with-your-webcam mini HOWTO 2007-11-27T17:46:00+01:00 2007-11-27T17:46:00+01:00 Bastian Venthur tag:venthur.de,2007-11-27:/2007-11-27-time-lapse-video-with-your-webcam-mini-howto.html Time-lapse-video-with-your-webcam mini HOWTO <p>I bought me a cheapo webcam the other day and the first thing (meh… actually
the second. The first thing I had to do was obviously getting this little
piece of plastic working…) I wanted to do was making a time-lapse video of
me working on my diploma thesis or something. With a little help from google
and the friendly folks at debian-user-german I finally got it working.</p>
<p><img alt="snapshot.jpg" src="/images/snapshot.jpg"></p>
<p>What you need: <code>camserv</code>, <code>wget</code> and <code>mencoder</code>.</p>
<p>Assuming you have your webcam working with v4l, camserv will provide snapshots
of your cam via <code>https://localhost:9192</code>, so the following script will make a
snapshot every second until you kill it:</p>
<div class="codehilite"><pre><span></span><code><span class="ch">#!/bin/sh</span>
<span class="k">while</span><span class="w"> </span><span class="o">[</span><span class="w"> </span><span class="m">1</span><span class="w"> </span><span class="o">]</span><span class="p">;</span><span class="w"> </span><span class="k">do</span>
<span class="w"> </span>wget<span class="w"> </span>https://localhost:9192<span class="w"> </span>-O<span class="w"> </span><span class="sb">`</span>date<span class="w"> </span>+%s<span class="sb">`</span>.jpg<span class="w"> </span>-q
<span class="w"> </span>sleep<span class="w"> </span>1s
<span class="k">done</span>
</code></pre></div>
<p>Let it run for several hours and then create the movie with the following
script:</p>
<div class="codehilite"><pre><span></span><code><span class="ch">#!/bin/sh</span>
mencoder<span class="w"> </span><span class="s2">"mf://*.jpg"</span><span class="w"> </span>-mf<span class="w"> </span><span class="nv">fps</span><span class="o">=</span><span class="m">25</span><span class="w"> </span>-o<span class="w"> </span>output.avi<span class="w"> </span>-ovc<span class="w"> </span>lavc<span class="w"> </span>-lavcopts<span class="w"> </span><span class="nv">vcodec</span><span class="o">=</span>mpeg4:mbd<span class="o">=</span><span class="m">2</span>:trell<span class="o">=</span>yes:v4mv<span class="o">=</span>yes
</code></pre></div>
<p>Hint: coding, juggling and even sleeping at your desk looks cool in time-lapse
- eating or singing your favorite songs while listening to them does not :P</p>
<p>I recorded myself for ca 12 hours and the resulting video was like 130 megs
large. The result looks pretty funny, but since there was a lot of the
not-so-cool-looking eating and singing stuff in there, I’m afraid I can’t even
show it to my closest friends ;)</p>
<p>Hint for users having problems getting proper images from camserv: I had to
change <code>max_frames</code> value to 1 in the <code>[socket]</code> section of
<code>/etc/camserv/camserv.cfg</code> to get proper single images via wget.</p>
<p>I find the camserv solution to get the images from the webcam rather
suboptimal, has anyone a smarter solution?</p>
<p><em>NP: Gianna Nannini - Bello e impossibile</em></p> (Almost) Back 2007-10-16T11:27:00+02:00 2007-10-16T11:27:00+02:00 Bastian Venthur tag:venthur.de,2007-10-16:/2007-10-16-almost-back.html (Almost) Back <p>Due some drastic changes in my personal life, I wasn’t very active in the last
two months. Now things are getting normal again, and I’m looking forward
working on <a href="https://reportbug-ng.alioth.debian.org/">rng</a> and my <a href="https://qa.debian.org/developer.php?login=venthur">other
packages</a> again.</p>
<p>Sorry for all the unanswered mails, I’ll need some time to clear the backlog.</p>
<p>I’m currently working on my diploma thesis so my Debian related activity level
won’t be as high as it was two months ago. But it should be at least high
enough to keep the packages in a good shape.</p> Deserializing SOAP replies with ZSI? 2007-08-20T18:29:00+02:00 2007-08-20T18:29:00+02:00 Bastian Venthur tag:venthur.de,2007-08-20:/2007-08-20-deserializing-soap-replies-with-zsi.html Deserializing SOAP replies with ZSI? <p>Dear Lazyweb,</p>
<p>what is the most elegant way to read a SOAP reply containing a complex type
into an object using <a href="https://pywebsvcs.sourceforge.net/">ZSI</a>? I’ve read the
<a href="https://pywebsvcs.sourceforge.net/zsi_v2_0_0.html">documentation</a> several
times and I guess there is an elegant way to solve this, but I still don’t get
it.</p>
<p>I <em>guess</em> it should work like this:</p>
<ul>
<li>Define a class Bugreport</li>
<li>Define Bugreport’s
<a href="https://pywebsvcs.sourceforge.net/zsi.html#SECTION007000000000000000000">typecode</a></li>
<li>Parse (how?) the SOAP reply containing bugreport-data into a Bugreport
object</li>
</ul>
<p>What I’m currently doing with soappy in
<a href="https://reportbug-ng.alioth.debian.org/">rng</a> is rather crude: I take the
SOAP response which is a dictionary holding many interesting facts about a bug
report, take those elements I’m interested in and copy them into a bug report
object. Not very elegant, but it works.</p>
<p>While I’m moving away from soappy to ZSI I’d like to implement the
deserializion the ZSI way. Unfortunately I don’t understand their examples. So
please Lazyweb, is there any ZSI expert out there who can provide a
minimalistic example?</p> Howto setup a print server for Windows (and others) using CUPS and zeroconf 2007-08-17T12:03:00+02:00 2007-08-17T12:03:00+02:00 Bastian Venthur tag:venthur.de,2007-08-17:/2007-08-17-howto-setup-a-print-server-for-windows-and-others-using-cups-and-zeroconf.html Howto setup a print server for Windows (and others) using CUPS and zeroconf <p>Now that CUPS 1.3 has built in
<a href="https://en.wikipedia.org/wiki/Zeroconf">zeroconf</a> support, it is easier than
ever to provide print service to Windows machines. You don’t even need
<a href="https://samba.org">Samba</a> anymore.</p>
<p>Here’s a quick way to setup a CUPS print server and a Windows client:</p>
<h2>On the server side</h2>
<p>First you need to install CUPS 1.3 or higher on your print server and setup
the printer (the web interface makes this task dead easy).</p>
<p>Zeroconf isn’t enabled by default so you have to browse the CUPS admin page
(https://localhost:631/admin if you’re running it on localhost) and enable the
“Share published printers connected to this system” option. “Change Settings”
will restart CUPS and your printer should be instantly visible to
zeroconf-aware applications in the local network.</p>
<p>If you can’t or don’t want to use the web interface (which is the easiest way
though), you can edit <code>/etc/cups/cupsd.conf</code> and replace the line</p>
<p><code>Listen localhost:631</code></p>
<p>with</p>
<p><code>Port 631</code></p>
<p>and add the line</p>
<p><code>BrowseAddress @LOCAL</code></p>
<p>Now save the changes and restart CUPS and you’re done.</p>
<h2>On the client side</h2>
<p>Since most Linux distributions and MacOS support zeroconf out of the box, I’ll
just explain how to setup the Windows client.</p>
<p>On the Windows side you’ll need to install <a href="https://www.apple.com/support/downloads/bonjourforwindows.html">Bonjour for
Windows</a> which
is freely available on <a href="https://apple.com">apple.com</a>.</p>
<p>Bonjour for Windows will enable Multicast DNS (mDNS) and DNS based Service
Discovery (DNS-SD) on your Windows machine. Once it is installed, you can
start the printer helper application provided by bonjour which will guide you
through the process of installing the network printer. The only problem here
was that although it correctly identified my printer, it only let me chose
between a generic postscript and a PCL driver. Both were not working correctly
so I had to manually change the driver for this printer to HP LaserJet 4 Plus
(which is my printer) after the setup via the printer properties, where all
other printer drivers where available again.</p>
<p>That’s it! Now you should be able to print on every zeroconf aware operating
system connected to your network. Oh, one final warning: With this setup,
<em>everybody</em> in the LAN will be able to print without prior authentication.
This should be what you want in most cases when running a home LAN or a small
business LAN anyways, but it’s certainly not so cool when strangers have
access to your network.</p>
<p>The whole setup process took like 15 minutes today. I remember me a few years
ago, not being very experienced with Samba and CUPS wasting a whole weekend to
achieve the same result. Thanks apple for making life a bit easier again!</p> My top 5 Firefox/Thunderbird annoyances 2007-08-15T12:57:00+02:00 2007-08-15T12:57:00+02:00 Bastian Venthur tag:venthur.de,2007-08-15:/2007-08-15-my-top-5-firefoxthunderbird-annoyances.html My top 5 Firefox/Thunderbird annoyances <p>Firefox is constantly gaining marked share (especially here in Europe) and
it’s little not-yet-so-popular brother Thunderbird is evolving too. While I’m
happy that they’re contributing their part to bring Free Software to the
masses, I’m concerned that the quality of their software (especially Firefox
under Linux) has decreased in the last months.</p>
<p>Here are my top 5 annoyances for Firefox and Thunderbird. Some of them only
apply to Debian’s version others are more visible on my fairly old and “slow”
(1.5GHz/512MiB) Laptop than on current and therefor faster machines:</p>
<h2>Firefox</h2>
<ul>
<li>Firefox seems to have a <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=362569">massive
problem</a> with font
kerning. Sometimes text is hardly readable since several letters seem to
share the same one-letter space. And marking messed up text like this gives
funny results:
<img alt="" src="https://people.debian.org/~venthur/stuff/2007-08-firefox-kerningbug.gif"></li>
<li>When visiting pages with a fixed background image like
<a href="https://linuxactionshow.com/">this</a>, scrolling the page down causes massive
CPU load and very slow scrolling even on fairly fast computers. Konqueror
seems to handle pages like this much better.</li>
<li>When reloading all tabs at once in a session and you have many (read: more
than say, 6) tabs open, Firefox takes all the available CPU resources and
pretty much becomes unresponsive until all tabs are loaded.</li>
<li>Firefox literary freezes while loading very large pages (combine this with
the previous annoyance for funny results)</li>
<li>I still haven’t figured out why Firefox on my laptop (correctly) wants to
launch kpdf when I open a .pdf while Firefox on my desktop seems to prefer
xpdf. I’ve checked all the available options on both systems and wasn’t able
to find the difference in the configuration.</li>
</ul>
<h2>Thunderbird</h2>
<ul>
<li>The most annoying bug in Thunderbird is Debian specific: it doesn’t open
links in a browser anymore <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=425790">for
months</a>. Since you
have to change some non-obvious configuration to fix this, I assume this is
the default behavior for many users out there which are now forced to
copy-paste links to their browser.</li>
<li>Like most other mail clients Thunderbird is also able to manage contacts.
But it lacks two important features:</li>
<li>No im/export of <a href="https://en.wikipedia.org/wiki/Vcard">vcard</a>: Hmm? Even
outlook can do that and vcard is pretty much standard for storing contact
information platform independent.</li>
<li>No birthdays associated to contacts: Superb! When combining the Mozilla
calendar application with Thunderbird you cannot just import all the
birthdays from your contacts (which are stored as vcards of course), no
you have to separately create those events which then of course are
totally unrelated to the persons in your roster.</li>
<li>The “search entire message” feature in the search box does absolutely
nothing when searching in newsgroups. Why is it enabled then? Or: why does
it <em>pretend</em> to do something by hiding all threads when entering something,
suggesting no match was found?</li>
<li>Wasn’t Thunderbird 1.x able to work with RSS feeds? <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=428421">What
happened</a> to this
feature in Thunderbird 2.x?</li>
<li><a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=425336">What happened</a> to
Thunderbird’s icon?</li>
</ul>
<p>While I’m still happy with Thunderbird (or Iceddove as we call it here) I’m
really searching for an alternative to Firefox (Iceweasel). Unfortunately
there is currently no alternative available which fits all my needs. Firefox
has two extensions no other browser seems to provide and without which I
wouldn’t want to work anymore (I wonder if that was a proper English
sentence…):</p>
<ul>
<li><a href="https://addons.mozilla.org/de/firefox/addon/2410">Foxmarks Bookmark
Synchronizer</a>: which
allows me to store my bookmarks on my (that’s right, not just foxmark’s)
server to keep it in sync with all my Firefoxes on various places and
machines.</li>
<li><a href="https://addons.mozilla.org/de/firefox/addon/10">Adblock</a> + <a href="https://addons.mozilla.org/de/firefox/addon/1136">Filterset.G
Updater</a>: which keeps me
mostly ad-free and automatically supplies me with the newest filter set
rules.</li>
</ul>
<p>While other browsers have some ad-blocking functionality too, they all seem to
lack the filter set updater. The next best alternatives are
<a href="https://www.konqueror.org/">Konqueror</a> and
<a href="https://www.gnome.org/projects/epiphany/">Epiphany</a> but besides the lack of
the above features every one of them has it’s own little quirks which doesn’t
really motivate me to make the switch yet. But Konqueror is making progress
and I’m really looking forward to KDE4 which will hopefully bring a usable web
browser so I can finally get rid of Firefox.</p>
<p><strong>Update:</strong> Ooops, I nearly forgot my favorite pet annoyance of Firefox under
Linux: Why does it have to insult the user’s eyes with this ugly toolkit when
drawing check boxes, line edits, buttons etc? Firefox under Windows paints
stuff like that according to Windows’ current theme, Konqueror under Linux as
well, but what does Firefox for years?</p>
<p><img alt="" src="https://people.debian.org/~venthur/stuff/2007-08-firefox-widgets.png"></p> Rng and others temporary broken 2007-08-10T12:02:00+02:00 2007-08-10T12:02:00+02:00 Bastian Venthur tag:venthur.de,2007-08-10:/2007-08-10-rng-and-others-temporary-broken.html Rng and others temporary broken <p>Just a short note to let you know that due a change in
<a href="https://packages.debian.org/debbugs">debbugs’</a> SOAP interface several
applications including
<a href="https://packages.debian.org/apt-listbugs">apt-listbugs</a> and
<a href="https://reportbug-ng.alioth.debian.org/">rng</a> are temporary broken. The
change was not too dramatic and I suppose the problem will be fixed shortly.
Meanwhile you can use <a href="https://packages.debian.org/reportbug">reportbug</a> which
is not affected, since it still uses the HTML interface.</p>
<p><strong>Update:</strong> Don fixed the problem and everything should be working as usual
again.</p> Implement two features and get the third for free! 2007-08-03T13:48:00+02:00 2007-08-03T13:48:00+02:00 Bastian Venthur tag:venthur.de,2007-08-03:/2007-08-03-implement-two-features-and-get-the-third-for-free.html Implement two features and get the third for free! <p>Today I’ve implemented a feature which was long overdue: making the table
sortable by the available table headers. The second feature I’ve added is that
every bug report now has it’s “Last Action” date. While both features are
useful for themselves, combining both result in a very handy bug triaging
tool.</p>
<p><img alt="screenshot.png" src="/images/screenshot.png"></p>
<p>A few months ago when I was trying to help the KDE team on their bug triage,
I’ve missed the feature to sort bugs by their date of the last action in our
BTS since I’ve noticed that many of the very old bugs (last action-, not bug
number wise) where already fixed or could be closed for other obvious reasons.
The problem was just to find all those “stale bugs”. I was able to close
dozens of old bug reports but it took much more time to find them, than to
decide whether they’re still active or not. And since I hadn’t the tools
available to find the “easy targets” on a quick way, I gave up after a few
days.</p>
<p>Today it’s just as easy as firing up rng and let it search for all bug reports
belonging to the qt-kde team:</p>
<p><code>rng debian-qt-kde@lists.debian.org</code></p>
<p>and sorting the resulting list by last action… sweet!</p>
<p>The package was just uploaded and should be available tomorrow.</p>
<p><strong>Update:</strong> Don pointed out that you can get the ordering in the web interface
too by appending <code>ordering=age</code> to the URL. Neat.</p> On Debian Maintainers 2007-07-26T09:44:00+02:00 2007-07-26T09:44:00+02:00 Bastian Venthur tag:venthur.de,2007-07-26:/2007-07-26-on-debian-maintainers.html On Debian Maintainers <p>When voting on the current <a href="https://lists.debian.org/debian-devel-announce/2007/07/msg00009.html">Debian Maintainers General
Resolution</a>,
I think it’s worth to think about the following questions: What is the
difference between a Debian Maintainer and a Debian Developer? Who is
interested in becoming a Debian Maintainer and <em>not</em> a Debian Developer and
why? Will this Debian Maintainer class really improve the situation for New
Maintainers?</p>
<p>I suppose most of our New Maintainers will aim to become a Debian Maintainer
just to bridge the time until they’re full Debian Developers. And I predict
that this is also the major target audience for this new Debian Maintainers
class. Some people said on -vote that there are people actually interested in
becoming a Debian Maintainer and <em>not</em> a Debian Developer. Personally I find
their reasons questionable, but after all I suppose there won’t be many people
going this route. On the other side, I don’t see how this new class enhances
the situation for the New Maintainers. Now they not only wait for the
Application Manager, Front Desk and Debian Account Managers – No, now they
will also search for someone who advocates them to become a Debian Maintainer
and have to wait for their key being added to the Debian Maintainers keyring.</p>
<p>So my question is: If this General Resolution mainly helps New Maintainers,
why must it be so complicated? Why another class of contributers, all those
complicated rules to set it up and this additional layer of bureaucracy? Why
don’t we aim for something simple, like improving our New Maintainer process.
<a href="https://lists.debian.org/debian-vote/2007/07/msg00008.html">I would rather
see</a> some of those
Debian Maintainer rights granted to New Maintainers after a certain point in
their New Maintainer career, but not in this complicated and overengineered
way the Debian Maintainer class proposes.</p> Small web calendar sought 2007-07-22T15:20:00+02:00 2007-07-22T15:20:00+02:00 Bastian Venthur tag:venthur.de,2007-07-22:/2007-07-22-small-web-calendar-sought.html Small web calendar sought <p>Dear Lazyweb,</p>
<p>does anyone know a <em>small web calendar</em> which has a web frontend and <em>does not
rely on a database server</em>? It should save it’s data directly into <a href="https://de.wikipedia.org/wiki/ICalendar">.ical (or
.ics)</a> files so I can fetch and alter
them with a desktop calendar application too.</p>
<p>I don’t need fancy features like multi user support or the ability to publish
calendars, I just want do see and edit my calendar/todo stuff when I’m not at
home and have the .ical saved on a centralized (my) server to make it
available for desktop calendar software.</p>
<p>For privacy reasons it has to run on my own server.</p> Improved filtering for rng 2007-07-18T15:18:00+02:00 2007-07-18T15:18:00+02:00 Bastian Venthur tag:venthur.de,2007-07-18:/2007-07-18-improved-filtering-for-rng.html Improved filtering for rng <p>I’ve just uploaded a new version of
<a href="https://reportbug-ng.alioth.debian.org/">reportbug-ng</a> including an Italian
and a Hebrew <a href="https://reportbug-ng.alioth.debian.org/ponies.html">pony</a> and a
cool enhancement to the buglist filter: Now the filter doesn’t try to match
the whole string anymore but splits the input by whitespaces and tries to
match <em>all words</em>. Now you can even exclude words by prepending a leading
minus to it.</p>
<p>The Syntax for the filter is: <code>[-]keyword [[-]keyword2] ...</code></p>
<p>Multiple keywords are separated by whitespaces and can have a leading minus. A
leading minus means “exclude” the whitespaces represent the logical AND.</p>
<p>Some Examples:</p>
<ul>
<li><code>foo bar -baz</code> means all bugs containing the words foo, bar and not baz</li>
<li><code>outstanding -wishlist</code> means all bugs which are outstanding and not
wishlist</li>
<li><code>-resolved</code> will show all open bugs</li>
</ul>
<p>Please note the the filter does look <em>into</em> the actual bugreports (the
fulltext), it currently tries to match against the packagename, the bugnumber,
the summary, the status and the severity.</p>
<p>The best thing about this new filter? It’s not even slower than the old one,
the only delay you’ll notice is when filtering packages with a huge amount of
bugs (like wnpp) and even there the filter just needs a fraction of a second.
The delay of a few secons comes acutally from the QTable when I remove all the
rows not matching the filter. <code>QTable.hideRow(int)</code> and <code>-showRow(int)</code> seem
to be very expensive even when I temporary disable all graphic updates for
this widget during this operation. If someone knows a trick to circumvent
this, please tell me (you may get a pony…).</p>
<p>This feature isn’t spectacular, but it should make filtering big buglists a
lot easier.</p> Reportbug-NG finally in testing! 2007-07-08T19:57:00+02:00 2007-07-08T19:57:00+02:00 Bastian Venthur tag:venthur.de,2007-07-08:/2007-07-08-reportbug-ng-finally-in-testing.html Reportbug-NG finally in testing! <p>Waiting ten days for rng to slip into testing, I had enough time to stuff the
next version with new features and small bugfixes. The most interesting ones
are:</p>
<ul>
<li>Added SOAP support and enabled it by default. Feel free to mess around with
the look and feel of our BTS, rng doesn’t depend on it anymore.</li>
<li>Support for WNPP bugs. Well, you could use rng to file WNPP bugs before, but
now rng actively supports you with a nice template for ITP and RFP reports.</li>
<li>Mayor user interface overhaul. <img alt="rng.png" src="/images/rng.png"></li>
<li>Use freedesktop.org’s xdg-utils to decide which browser to use to open URLs.
This should allow rng to open the browser you set as default in your desktop
environment.</li>
</ul>
<p>In totally unrelated news, I finally managed to master <a href="https://en.wikipedia.org/wiki/Rubenstein%27s_revenge">Rubenstein’s
Revenge</a>.</p> Python, os.fork(), webbrowser and debbugs 2007-07-01T13:20:00+02:00 2007-07-01T13:20:00+02:00 Bastian Venthur tag:venthur.de,2007-07-01:/2007-07-01-python-osfork-webbrowser-and-debbugs.html Python, os.fork(), webbrowser and debbugs <p><a href="https://grmontesino.blogspot.com/2007/06/python-osfork-and-gsoc.html">Gustavo</a>
writes about python, it’s webbrowser module, os.fork and parsing bugreports
from our BTS via html. This all sound very familiar, so here are some hints
from me:</p>
<ul>
<li>You don’t have to fork a new process just to call a browser, try threading
instead: <code>thread.start_new_thread(webbrowser.open, (url,))</code>. No need to
clean up the child process after it has finished, just call
<code>start_new_thread</code> with the function and it’s parameters and forget it.</li>
<li>Python’s webbrowser module is nice, but it often fails to find the right
browser. The problem is to find the <em>users</em> (read: not the system’s) default
browser across the different desktop environments. <em>xdg-open</em> from the
package <em>xdg-utils</em> (from freedesktop.org) seems to do a very good job.
~~Rng doesn’t use it yet, but I’m definitely planning to replace the
webbrowser call with xdg-open.~~ Rng uses it and falls back to python’s
webbrowser.open()-call if xdg-open failed.</li>
<li>If your project suffers from changes in the html code of our BTS, try SOAP
instead. It provides all the infos in machine readable format and also comes
with backwards compatibility: the namespace for debbug’s SOAP interface is
<code>Debbugs/SOAP</code> which always calls the latest versions of the remote
functions. But you can also use <code>Debbugs/SOAP/V1</code> (Version 1 currently
matches <code>Debbugs/SOAP</code>). This will ensure that changes in debbugs SOAP
interface don’t affect your implementation.</li>
</ul> What does it take to break rng? 2007-06-27T11:10:00+02:00 2007-06-27T11:10:00+02:00 Bastian Venthur tag:venthur.de,2007-06-27:/2007-06-27-what-does-it-take-to-break-rng.html What does it take to break rng? <p>Actually just a small change in the html code of our BTS. The problem was easy
to fix and the new version is already uploaded, but this shows again how
fragile the connection between BTS’ html output and rng is. I’ve heard other
tools where affected too – just one reason more to switch to SOAP as soon as
possible.</p>
<p>An unfortunate side effect of today’s upload: In the last weeks I tried very
hard to finally get rng into testing by not uploading as often as I wanted to.
The problem aren’t RC bugs, but archs like SPARC or ARM which seem to have
problems keeping up with the build queue. Being of priority <em>extra</em> doesn’t
help very much, since packages with higher priorities (like: all other
packages but rng) always jump the queue. Unfortunately my request to fix the
<em>override disparity</em> I filed two weeks ago wasn’t processed yet and the only
one who could fix this is currently on vacation. In fact
<a href="https://ftp-master.debian.org/">others</a> could fix this too, but it looks like
they’re on vacation too. I guess I’ll just exclude both archs in one of the
next uploads until things run smoother again.</p>
<p>But not everything is dark: with the current upload, a Dutch, a Frech, a
Norwegian and a Polish pony found a <a href="https://reportbug-ng.alioth.debian.org/ponies.html">new
home</a>.</p>
<p><strong>Update:</strong> Looks like the override disparity has been fixed. Whoever fixed
this, thank you! Rng should be available on <em>all</em> our archs by tomorrow and in
testing in 10 days!</p> Ponies! 2007-06-22T21:33:00+02:00 2007-06-22T21:33:00+02:00 Bastian Venthur tag:venthur.de,2007-06-22:/2007-06-22-ponies.html Ponies! <p><img alt="pony.gif" src="/images/pony.gif"></p>
<p>As <a href="2007-06-22-localizing-reportbug-ng-ii.html">promised</a>, everyone who sends in
a new translation for reportbug-ng gets a
<a href="https://reportbug-ng.alioth.debian.org/ponies.html">pony</a>. Just send a new
translation and the picture of your favorite pony. If you don’t send a pony,
you’ll get one from me.</p> Localizing reportbug-ng (II) 2007-06-22T09:06:00+02:00 2007-06-22T09:06:00+02:00 Bastian Venthur tag:venthur.de,2007-06-22:/2007-06-22-localizing-reportbug-ng-ii.html Localizing reportbug-ng (II) <p>A month ago I
<a href="2007-05-27-please-help-to-localize-reportbug-ng.html">asked</a> for help to
localize <a href="https://reportbug-ng.alioth.debian.org/">reportbug-ng</a>. To my
surprise translations came in pretty quick. Junichi Uekawa was the first one,
he sent his Japanese translation only a <em>few hours</em> after my request for help.</p>
<p>Currently we have rng translated into the following languages: Catalan, Czech,
English, German, Japanese, Spanish and Swedish. Thanks David Planella,
Miroslav Kure, Junichi Uekawa, Javier Fernández-Sanguino Peña and Daniel
Nylander for your translations!</p>
<p>But that’s not enough. If your language is missing, please consider
translating rng to your language. Just take the source of the current version
in unstable, grab the .pot and translate it. There isn’t really that much text
to translate. The .pot contains only 42 messages and most of them are very
short.</p>
<p>When you’re done, please file a l10n+patch bug against rng with the
translation attached. I’ll include your translation as soon as possible, thank
you in the changelog and will probably name my first pony after you ;)</p>
<p>Thanks!</p> 1 Kilobyte = 1000 ± 24 bytes 2007-06-12T21:28:00+02:00 2007-06-12T21:28:00+02:00 Bastian Venthur tag:venthur.de,2007-06-12:/2007-06-12-1-kilobyte-1000--c2-b1-24-bytes.html 1 Kilobyte = 1000 ± 24 bytes <p>Could you exactly say how big your hard disk has to be at least when the
vendor claims it’s 500 Gigabytes big? Do you know how many bytes a file has
when the filemanager says 2 Megabytes? Do you know what your DSL-provider
actually means with 2 Megabit per second?</p>
<p>Experienced users surely can since they <em>know</em> the meaning of “Kilobyte”
depends on the context. Sometimes it’s 1000 bytes, sometimes it’s 1024.</p>
<p>Non technical users will tend to assume that a 1 Kilobyte is 1000 bytes (which
is correct, since k is the SI prefix for kilo) while users with technical
background will tend to assume (depending on the context of course) it’s 1024.</p>
<p>There is <a href="https://en.wikipedia.org/wiki/Binary_prefix">a solution</a> for this
ambiguity, but unfortunately it doesn’t come for free: First, it <em>sounds
really stupid</em> (kibi-what?) and second it will <em>add an extra character</em> (kB ->
kiB) and we all know how stuffed our 80 column terminals already are nowadays.</p>
<p>If you have better arguments against the binary prefix notation please, join
the <a href="https://lists.debian.org/debian-devel/2007/06/msg00500.html">discussion</a>.
Personally I’d find it very cool if we could use SI prefixes where we mean n
* 10^3 and binary prefixes where we mean n * 2^10 in Debian <em>consistently</em>.</p> Rebuilding the Archive Using Cowbuilder (II) 2007-06-06T11:11:00+02:00 2007-06-06T11:11:00+02:00 Bastian Venthur tag:venthur.de,2007-06-06:/2007-06-06-rebuilding-the-archive-using-cowbuilder-ii.html Rebuilding the Archive Using Cowbuilder (II) <p>A few months ago I wrote a script to <a href="2007-02-20-rebuilding-the-archive-using-cowbuilder.html">rebuild the archive using
cowbuilder</a> This script
had a subtle bug: If you where running a sid machine and wanted to rebuild
testing, the script would fetch the sources from sid (via apt-get source) and
build this package in a testing environment.</p>
<p>Thanks to <a href="https://info.comodo.priv.at/">Gregor Herrmann</a> (Currently
unassigned
<a href="https://nm.debian.org/nmstatus.php?email=gregor%2Bdebian%40comodo.priv.at">NM</a>
with ~180 packages in the archive!) this bug is fixed now and it should be
possible to rebuild the archive correctly for every host/build-environment
combo.</p>
<p>To rebuild the archive, just <a href="https://people.debian.org/~venthur/stuff/2007-06-rebuild/">get the
scripts</a> and</p>
<div class="codehilite"><pre><span></span><code><span class="n">sudo</span><span class="w"> </span><span class="n">aptitude</span><span class="w"> </span><span class="n">install</span><span class="w"> </span><span class="n">cowdancer</span><span class="w"> </span><span class="n">grep</span><span class="o">-</span><span class="n">dctrl</span>
<span class="n">sudo</span><span class="w"> </span><span class="n">cowbuilder</span><span class="w"> </span><span class="o">--</span><span class="n">create</span><span class="w"> </span><span class="o">--</span><span class="n">distribution</span><span class="w"> </span><span class="n">lenny</span><span class="w"> </span><span class="o">--</span><span class="n">basepath</span><span class="w"> </span><span class="o">/</span><span class="k">var</span><span class="o">/</span><span class="n">cache</span><span class="o">/</span><span class="n">pbuilder</span><span class="o">/</span><span class="n">testing</span><span class="o">-</span><span class="n">base</span><span class="o">.</span><span class="n">cow</span>
<span class="o">./</span><span class="n">getlist</span><span class="w"> </span><span class="n">lenny</span><span class="w"> </span><span class="c1"># get the list of packages</span>
<span class="o">./</span><span class="n">buildall</span><span class="w"> </span><span class="n">list</span><span class="o">.</span><span class="n">lenny</span><span class="o">.</span><span class="n">i386</span><span class="w"> </span><span class="n">lenny</span><span class="w"> </span><span class="c1"># build all packages in list.lenny.i386 in a lenny environment</span>
</code></pre></div>
<p>Thanks Gregor for your patches and good luck with your NM process!</p> LinuxTag 2007-05-30T21:58:00+02:00 2007-05-30T21:58:00+02:00 Bastian Venthur tag:venthur.de,2007-05-30:/2007-05-30-linuxtag.html LinuxTag <p>My first day at LinuxTag is over. I’m a bit tired, but the day was nice. We
had many visitors at our booth and some nice conversations. We sold a few
t-shirts and gave a way a <em>lot</em> of Debian DVDs. Unfortunately there was also a
high demand on Live CDs which we couldn’t fulfill since we still don’t have
official Live images.</p>
<p>Last but not least, it was very nice to meet some other Debian Developers.
Unfortunately I can’t attend at our booth tomorrow, but I’m already looking
forward to Friday (Debian Day!).</p> Please help to localize reportbug-ng 2007-05-27T16:37:00+02:00 2007-05-27T16:37:00+02:00 Bastian Venthur tag:venthur.de,2007-05-27:/2007-05-27-please-help-to-localize-reportbug-ng.html Please help to localize reportbug-ng <p>I’ve just uploaded a new version of
<a href="https://reportbug-ng.alioth.debian.org/">reportbug-ng</a>. The biggest change in
this release is the new <em>reportbug-ng.pot</em> file which contains some work for
our brave localization teams.</p>
<p>I’ve already translated rng into German, so rng is now available in German and
English. If you want your mother language to appear in this list, please grab
the .pot, translate it and file a l10n+patch bug against reportbug-ng with the
translation attached.</p>
<p>Thanks!</p> Using zeroconf to resolve local hostnames 2007-05-25T14:22:00+02:00 2007-05-25T14:22:00+02:00 Bastian Venthur tag:venthur.de,2007-05-25:/2007-05-25-using-zeroconf-to-resolve-local-hostnames.html Using zeroconf to resolve local hostnames <p>If you bought one of those cheap WLAN-routers which provides a DHCP server but
no DNS (why again?), you probably miss the feature to access your hosts in the
LAN by their name, right?</p>
<p>If you’re running a fairly recent Linux distribution (yes, Etch works too),
just try to ping them with the <a href="https://en.wikipedia.org/wiki/.local"><em>.local</em> DNS
suffix</a>, like <em>phoibe.local</em> or
<em>hades.local</em>. If that doesn’t work, check if <em>avahi-daemon</em> is installed on
the machines you want to resolve. If not (which is unlikely on recent desktop
machines), just install it and your machine will be available via
<em>hostname.local</em>.</p>
<p>I wasn’t aware that I would ever need this “zeroconf crap” until I replaced my
rusty old Dell Optiplex GXa router with a less energy consuming and much more
silent Linksys WRT54G. Unfortunately I bought Version 7 which only comes with
2MB flash and is therefore not supported by <a href="https://openwrt.org/">openwrt</a>.
So without my precious <a href="https://en.wikipedia.org/wiki/Dnsmasq">dnsmasq</a> on my
router, I was suddenly blind in my own LAN – and very thankful to find out
that <a href="https://en.wikipedia.org/wiki/Zeroconf">zeroconf</a> already took care of
my problem.</p> 4GB RAM on a T60? 2007-05-14T18:50:00+02:00 2007-05-14T18:50:00+02:00 Bastian Venthur tag:venthur.de,2007-05-14:/2007-05-14-4gb-ram-on-a-t60.html 4GB RAM on a T60? <p>Dear Lazyweb,</p>
<p>at work we have bought some of those shiny new ThinkPad T60s with 64Bit. Some
of them have 4GB RAM installed, but unfortunately those with 4GB only seem to
have 3GB available under Debian/Etch/AMD64.</p>
<p>Since those laptops are running on AMD64 kernels, they should work with >= 3GB
RAM out of the box, right? Unfortunately they don’t and
<a href="https://www.thinkwiki.org/wiki/Category:T60">thinkwiki</a> says:</p>
<blockquote>
<p>Note: While you can install 4GB of memory, the chipset in the T60 supports a
maximum of 3GB usable memory.</p>
</blockquote>
<p>while the BIOS correctly shows the full amount of installed RAM!</p>
<p>So my question is: Has anyone out there a T60 running successfully with 4GB
RAM or is it really a chipset constraint?</p> Last chance for LinuxTag 2007 2007-05-04T08:24:00+02:00 2007-05-04T08:24:00+02:00 Bastian Venthur tag:venthur.de,2007-05-04:/2007-05-04-last-chance-for-linuxtag-2007.html Last chance for LinuxTag 2007 <p>Alexander Wirt
<a href="https://lists.debian.org/debian-events-eu/2007/05/msg00009.html">posted</a> the
following request on <a href="https://lists.debian.org/debian-events-eu/">-events-eu</a>.
Since I fear it won’t get the attention it deserves, I’m quoting his request
here again.</p>
<blockquote>
<p>Hi,</p>
<p>unfortunatly there weren’t enough talks submitted for the Debian Day that I
have to cancel it until there won’t be some new submissions in the next few
hours.</p>
<p>So if you want to have a debian day, please submit a talk via the VCC
(https://www.linuxtag.org/vcc/). Otherwise it will be canceled.</p>
<p>Alex</p>
</blockquote>
<p><strong>Update:</strong> Mission accomplished. Looks like a few talks were submitted just
in time to save the (Debian) day.</p> Making cool panoramic pictures with hugin 2007-04-25T18:13:00+02:00 2007-04-25T18:13:00+02:00 Bastian Venthur tag:venthur.de,2007-04-25:/2007-04-25-making-cool-panoramic-pictures-with-hugin.html Making cool panoramic pictures with hugin <p>Thanks <a href="https://0pointer.de/blog">Lennart</a> for mentioning
<a href="https://hugin.sourceforge.net/">Hugin</a>! This is a really cool piece of
software, allowing you to assemble a mosaic of photographs into a complete
panorama.</p>
<p><img alt="panorama-640.jpg" src="/images/panorama-640.jpg"></p>
<p>I’ve created this 180 degrees panorama from 16 photos taken out of my window
(3 rows: 6 + 6 + 4). The original picture is huge: 5000-something pixels wide
and high and approximately 22Megs (jpg) fat.</p>
<p>If you want to test it yourself just <code>aptitude install hugin</code> and make sure to
get <em>enblend</em> from somewhere else (eg,
<a href="https://debian-multimedia.org">debian-multimedia.org</a>). If you don’t install
enblend you don’t lose functionality, but the output will be of much lower
quality. Thanks Florent Bayle for packaging hugin and Christian Marillat for
packaging enblend!</p> New queries for reportbug-ng 2007-04-23T17:52:00+02:00 2007-04-23T17:52:00+02:00 Bastian Venthur tag:venthur.de,2007-04-23:/2007-04-23-new-queries-for-reportbug-ng.html New queries for reportbug-ng <p>Instead of the boring “package” queries,
<a href="https://reportbug-ng.alioth.debian.org/">rng</a> used to support ‘till now, rng
now supports all the queries our BTS supports:</p>
<ul>
<li><code>package</code>: Returns all the bugs belonging to the PACKAGE</li>
<li><code>bugnumber</code>: Returns the bug with BUGNUMBER and loads it into the built in
browser immediately</li>
<li><code>maintainer@foo.bar</code>: Returns all the bugs assigned to MAINTAINER</li>
<li><code>src:package</code>: Returns all the bugs belonging to the SOURCEPACKAGE</li>
<li><code>from:submitter@foo.bar</code>: Returns all the bugs filed by SUBMITTER</li>
<li><code>severity:foo</code>: Returns all the bugs of SEVERITY. Warning this list is
probably very long. Recognized are the values: critical, grave, serious,
important, normal, minor and wishlist</li>
<li><code>tag:bar</code>: Returns all the bugs marked with TAG</li>
</ul>
<p>Those queries are available on the command line too and behave exacly as if
entered in the program: The syntax is: <code>rng [QUERY]</code>, where query is one of
the above (and <code>rng</code> a convenient shortcut to <code>reportbug-ng</code>).</p>
<p>An example: if you start <code>rng from:venthur@debian.org</code>, you’ll get the full
list of all bugreports I’ve ever reported. Now you can filter the list to find
all bugreports I’ve filed against, say: qgo… voila. It doesn’t get any
easier than that, does it?</p>
<p>Those new queries and a few changes under the hood required quite a lot of
refactoring in the code and I’m somewhat scared that I’ve introduced some new
bugs. So I guess I should stop releasing so often (or for at least 10 days so
rng can finally enter testing) and use the time to start writing some unit
tests.</p> Reportbug-NG migrated from SVN to BZR 2007-04-20T12:48:00+02:00 2007-04-20T12:48:00+02:00 Bastian Venthur tag:venthur.de,2007-04-20:/2007-04-20-reportbug-ng-migrated-from-svn-to-bzr.html Reportbug-NG migrated from SVN to BZR <p>The migration was rather easy</p>
<div class="codehilite"><pre><span></span><code><span class="n">sudo</span><span class="w"> </span><span class="n">aptitude</span><span class="w"> </span><span class="n">install</span><span class="w"> </span><span class="n">bzr</span><span class="o">-</span><span class="n">svn</span>
<span class="err">#</span><span class="w"> </span><span class="n">patch</span><span class="w"> </span><span class="p">(</span><span class="n">see</span><span class="w"> </span><span class="n">below</span><span class="p">)</span>
<span class="n">bzr</span><span class="w"> </span><span class="n">branch</span><span class="w"> </span><span class="nl">svn</span><span class="p">:</span><span class="o">//</span><span class="n">svn</span><span class="p">.</span><span class="n">debian</span><span class="p">.</span><span class="n">org</span><span class="o">/</span><span class="n">reportbug</span><span class="o">-</span><span class="n">ng</span><span class="w"> </span><span class="err">#</span><span class="w"> </span><span class="n">That</span><span class="err">'</span><span class="n">s</span><span class="w"> </span><span class="nf">right</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="n">branch</span><span class="w"> </span><span class="n">directly</span><span class="w"> </span><span class="k">from</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">SVN</span><span class="w"> </span><span class="n">repo</span><span class="err">!</span>
<span class="err">#</span><span class="w"> </span><span class="k">ignore</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">error</span>
<span class="n">bzr</span><span class="w"> </span><span class="n">push</span><span class="w"> </span><span class="c1">--use-existing-dir sftp://venthur@bzr.debian.org/bzr/reportbug-ng</span>
</code></pre></div>
<p>To get your own branch:</p>
<div class="codehilite"><pre><span></span><code>bzr branch https://bzr.debian.org/bzr/reportbug-ng/
</code></pre></div>
<p>Bzr-svn really makes it easy to migrate from svn to bzr… well, in theory. In
practice we have <a href="https://bugs.debian.org/415721">#415721</a>, but fortunately
there is an easy workaround. Just temporarily apply this trivial patch:</p>
<div class="codehilite"><pre><span></span><code><span class="gd">--- /usr/share/pycentral/bzr-svn/site-packages/bzrlib/plugins/svn/__init__.py 2007-04-20 09:30:00.000000000 +0200</span>
<span class="gi">+++ /usr/share/pycentral/bzr-svn/site-packages/bzrlib/plugins/svn/__init__.py.new 2007-04-20 09:30:24.000000000 +0200</span>
<span class="gu">@@ -23,7 +23,7 @@ import bzrlib`</span>
__version__ = '0.2.0'
<span class="gd">-required_bzr_version = (0,13)</span>
<span class="gi">+#required_bzr_version = (0,13)</span>
def check_bzrlib_version(desired):
"""Check that bzrlib is compatible.
</code></pre></div>
<p>and life is good again.</p>
<p>The reason why I switched from a centralized to a distributed RCS was that I
really like the option to do (small) local checkins and just do the “real”
checkin when the work is done. In terms of BZR it means <em>commits</em> to my local
branch for smaller changes and <em>pushes</em> back to the mainline for every major
change. Oh, and it’s also nice always having the full repository data locally
stored.</p>
<p>My requirements for the RCS were: it should be easy to use (no steep learning
curve), well tested and somewhat mainstream. BZR fits quite well, especially
since Ubuntu heavily relies on it for their launchpad stuff.</p>
<p>PS: Thanks to the <a href="https://alioth.debian.org">alioth</a> team for creating the
BZR repository so quickly, it just took like 1 minute.</p> What about a contest for the next debian.org theme? 2007-04-18T20:53:00+02:00 2007-04-18T20:53:00+02:00 Bastian Venthur tag:venthur.de,2007-04-18:/2007-04-18-what-about-a-contest-for-the-next-debianorg-theme.html What about a contest for the next debian.org theme? <p>Currently there is a
<a href="https://lists.debian.org/debian-www/2007/04/msg00249.html">discussion</a> about
a new theme for <a href="https://debian.org">debian.org</a> going on on
<a href="https://lists.debian.org/debian-www/">-www</a>. Some people presented their
ideas and build some mockups while others commented them.</p>
<p>I strongly suggest to let some professional designers and other (not
necessarily Debian related) talented people create some mockups, to avoid
moving from one outdated and rusty design to the next.</p>
<p>I wonder if we couldn’t open up the process a bit by starting some kind of
contest. Skilled webdesigners could create some mockups and we could collect
all those and let a vote decide which one to keep.</p> How long does it take to turn a feature into a bug? 2007-04-17T20:06:00+02:00 2007-04-17T20:06:00+02:00 Bastian Venthur tag:venthur.de,2007-04-17:/2007-04-17-how-long-does-it-take-to-turn-a-feature-into-a-bug.html How long does it take to turn a feature into a bug? <p>Looking at the current spam attack at our <a href="https://bugs.debian.org">BTS</a> I
wonder how long it’ll take ‘till the feature that our BTS is controllable via
mail becomes a pain in the ass because of the spam.</p>
<p>I’m sure we have some spamfilter and some brave people controlling it, since
in the last time it was relative quiet and spam free. But the current attack
makes me think if we couldn’t raise the barrier for spam somehow. Not sure how
to achieve that though.</p> Since More and More People Are Referencing to wiki.debian.org... 2007-04-15T19:02:00+02:00 2007-04-15T19:02:00+02:00 Bastian Venthur tag:venthur.de,2007-04-15:/2007-04-15-since-more-and-more-people-are-referencing-to-wikidebianorg.html Since More and More People Are Referencing to wiki.debian.org... <p>shouldn’t we finally move away from this ugly MoinMoin theme? It’s not only
the most ugly and spartan theme one could imagine (it even beats our main <a href="https://debian.org">web
presence</a> in ugliness) – it does not even try to comply
with some corporate design. The only things that remind me that I’m actually
surfing a <em>Debian</em> related site are the URL and the words “Debian Wiki” on the
top left. (There is a chance that the link-colors match the Debian-Red too,
but I’m slightly colorblind, so I’m not sure)</p>
<p>MoinMoin can do better. Please look at <a href="https://wiki.ubuntu.com/">Ubun…</a>
oops I mean <a href="https://bazaar-vcs.org/">bazaar’s homepage</a>, they’re using
MoinMoin too and it looks much more appealing than our wiki.</p> Reportbug-NG, Now With Fancy Colors 2007-03-28T11:51:00+02:00 2007-03-28T11:51:00+02:00 Bastian Venthur tag:venthur.de,2007-03-28:/2007-03-28-reportbug-ng-now-with-fancy-colors.html Reportbug-NG, Now With Fancy Colors <p>After a few hours of hacking I got <a href="https://bugs.debian.org/416132">#416132</a>
closed and am proud to say that we finally have <em>fancy colors</em> enabled in
<a href="https://reportbug-ng.alioth.debian.org/">Reportbug-NG</a>.</p>
<p><img alt="" src="images/reportbug-ng.gif"></p>
<p>I’m also very proud to say that yesterday – exactly 3 weeks after I wrote the
first line of R-NG – R-NG received it’s 100th
<a href="https://popcon.debian.org/">popcon</a> submission! Thanks to all of you who
tested and reported bugs and wishes.</p>
<p>Some of the next goals I’ve currently in mind are</p>
<ul>
<li>Porting R-NG from qt3 to qt4</li>
<li>Include some advanced BTS-features for developers like tagging, reassigning,
merging, etc.</li>
</ul> Dear SoC enthusiasts, 2007-03-22T16:17:00+01:00 2007-03-22T16:17:00+01:00 Bastian Venthur tag:venthur.de,2007-03-22:/2007-03-22-dear-soc-enthusiasts.html Dear SoC enthusiasts, <p>please stop writing mails asking me whether I’d like to mentor your
yet-another-reportbug-alternative project.</p>
<p>It’s not that I’m opposed to the idea of rewriting reportbug(-ng) for gtk or
as a webapp – really. I just don’t see why your project needs to be part of
SoC.</p>
<p>I know working for/with google is kinda sexy nowadays and as a student you can
even get some money – but be honest: what was <em>Debian’s</em> benefit of <a href="https://wiki.debian.org/SummerOfCode2006">last
year’s SoC projects</a>? My question
which of last year’s projects failed and which succeeded is <a href="https://lists.debian.org/debian-project/2007/03/msg00122.html">still
unanswered</a>. So
no, I’m not yet jumping on this bandwagon everybody seems to be so exited
about.</p>
<p>Don’t get me wrong: I don’t hate google or the SoC, I’m just not convinced of
the success of our last year’s projects, plus I don’t think we need such an
event to write useful tools for Debian.</p>
<p><em>NP: The Beatles – Happiness Is a Warm Gun</em></p> Thanks Lazyweb, 2007-03-20T15:00:00+01:00 2007-03-20T15:00:00+01:00 Bastian Venthur tag:venthur.de,2007-03-20:/2007-03-20-thanks-lazyweb.html Thanks Lazyweb, <p>I received quite a few answers on my <a href="2007-03-19-dear-lazyweb.html">request for
help</a> yesterday. Thanks to you guys and gals,
<a href="https://reportbug-ng.alioth.debian.org/">Reportbug-NG</a> now also supports
Opera, KMail, Pine and <a href="https://mail.google.com/">GoogleMail</a> (yes I know,
that’s crazy).</p> Dear Lazyweb, 2007-03-19T19:43:00+01:00 2007-03-19T19:43:00+01:00 Bastian Venthur tag:venthur.de,2007-03-19:/2007-03-19-dear-lazyweb.html Dear Lazyweb, <p>Icedove, Iceape, Evolution, Sylpheed, Sylpheed-Claws and Mutt.</p>
<p>Is your favorite mail client missing? Does your mail client accept URLs in
mailto-format? If yes, please drop me a note containing the name of your mail
client, if it needs a terminal (like mutt) and an example call which starts
the client with address, subject an body already filled in.</p>
<p>Examples:</p>
<ul>
<li>Icedove (needs no terminal)<br>
<code>icedove "mailto:mail@example.com?subject=foosubject&body=foobody"</code></li>
<li>Sylpheed (needs no terminal)<br>
<code>sylpheed --compose "mailto:mail@example.com?subject=foosubject&body=foobody"</code></li>
</ul>
<p>I’ll use this data to include more clients in
<a href="https://reportbug-ng.alioth.debian.org/">Reportbug-NG</a>. Please double-check
if your mail client really supports mailto-URLs with subject and body. KMail
for instance accepts such a parameter but <a href="https://bugs.debian.org/415454">silently drops subject and
body</a>.</p> Reportbug-NG in Unstable 2007-03-11T15:52:00+01:00 2007-03-11T15:52:00+01:00 Bastian Venthur tag:venthur.de,2007-03-11:/2007-03-11-reportbug-ng-in-unstable.html Reportbug-NG in Unstable <p>Just a few minutes ago <a href="https://reportbug-ng.alioth.debian.org/">reportbug-ng</a>
was accepted and should be available in unstable tomorrow (For the impatient:
you can already get it from <a href="https://incoming.debian.org/">incoming</a>).</p>
<p><img alt="" src="images/reportbug-ng.gif"></p>
<p>If you can spare some time please test it and send me suggestions, bugreports
and stuff.</p> Reportbug-NG at Alioth 2007-03-08T17:46:00+01:00 2007-03-08T17:46:00+01:00 Bastian Venthur tag:venthur.de,2007-03-08:/2007-03-08-reportbug-ng-at-alioth.html Reportbug-NG at Alioth <p>Yesterday <a href="2007-03-07-a-screencast-is-worth-a-thousand-pictures.html">I
mentioned</a> a small
project of mine called reportbug-ng. The feedback so far was very positive.
Looks like quite a few people out there would like to see a desktop version of
reportbug.</p>
<p>Since I’ve already received a few patches via email, I decided to move the
project to alioth so contributers can easily keep track of the changes.</p>
<p>So here it is: the <a href="https://reportbug-ng.alioth.debian.org/">official homepage</a>
and teh almighty <a href="svn://svn.debian.org/reportbug-ng">SVN repository</a>.</p>
<p>Comments and contributions are very welcome! (Hint, hint: The source-tree also
contains a TODO list. Once all the points under “urgend” are processed, I’ll
consider uploading it to Debian.)</p> A Screencast is Worth a Thousand Pictures 2007-03-07T16:14:00+01:00 2007-03-07T16:14:00+01:00 Bastian Venthur tag:venthur.de,2007-03-07:/2007-03-07-a-screencast-is-worth-a-thousand-pictures.html A Screencast is Worth a Thousand Pictures <p><img alt="" src="images/reportbug-ng.gif"></p>
<p>It’s still in a very early stage (I’ve started coding it yesterday), but it’s
basic functionality is already there: You can query the BTS, filter the list
of bugreports in realtime by typing something and view the full bugreports in
HTML. You can even provide additional information for existing bugs or create
new bugreports. It currently only supports icedove and mutt as mailclient but
adding other clients is very easy.</p>
<p>This tool is not designed to replace <em>reportbug</em>, it rather aims for the
newbie users feeling uncomfortable typing their mails in vi and would rather
have something to point and click. Maybe I can merge the code with reportbug,
but after a quick look at it’s code it seems that this will not be as easy as
I thought in the beginning.</p>
<p>The code is available
<a href="https://debian.org/~venthur/stuff/2007-03-reportbug/reportbug-ng.tar.gz">here</a>.
You’ll need python-qt3 to run it.</p>
<p><strong>Update:</strong> The screencast was created with
<a href="https://packages.qa.debian.org/b/byzanz.html">byzanz</a> via</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>byzanz-record<span class="w"> </span>-c<span class="w"> </span>-l<span class="w"> </span>-d<span class="w"> </span><span class="m">45</span><span class="w"> </span>reportbug-ng.gif
</code></pre></div>
<p>Hint: Best to switch the desktop resolution to something like 800x600 before
recording – resizing the gif afterwards is very expensive (cpu- and memory
wise).</p> Etch Won't Ship Wordpress 2007-03-07T01:09:00+01:00 2007-03-07T01:09:00+01:00 Bastian Venthur tag:venthur.de,2007-03-07:/2007-03-07-etch-wont-ship-wordpress.html Etch Won't Ship Wordpress <p>So the security team <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=413269">decided to kick Wordpress from
Etch</a> since they
assume it won’t be sanely maintainable over the course of 30-36 months. This
practice surprises me a bit, especially since upstream plans to support the
2.0.x series until 2010 and the package is currently very well maintained by
Kai Hendry.</p>
<p>So what’s the problem? Is it manpower? I guess not, since <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=413269#44">Kai even
offered</a> to
provide security updated packages when they become available, which was
rejected with a friendly “<a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=413269#54">EOD for
me.</a>”.</p>
<p>Anyway, since my blog will become unsupported soon, I need to switch to
something else. So dear lazyweb, what is the next best alternative to WP
available in Etch? I need good comment spam protection and an option to import
my old wordpress entries.</p> Pimp My Boot Process (III) 2007-03-02T00:52:00+01:00 2007-03-02T00:52:00+01:00 Bastian Venthur tag:venthur.de,2007-03-02:/2007-03-02-pimp-my-boot-process-iii.html Pimp My Boot Process (III) <p>Short version:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>aptitude<span class="w"> </span>install<span class="w"> </span>desktop-base<span class="w"> </span>splashy<span class="w"> </span>splashy-themes
$<span class="w"> </span>sudo<span class="w"> </span>splashy_config<span class="w"> </span>--set-theme<span class="w"> </span>debian-moreblue
$<span class="w"> </span>sudo<span class="w"> </span>vim<span class="w"> </span>/boot/grub/menu.lst
</code></pre></div>
<div class="codehilite"><pre><span></span><code><span class="k">[...]</span>
<span class="na">timeout 3</span>
<span class="na">hiddenmenu</span>
<span class="k">[...]</span>
<span class="c1"># defoptions=quiet splash</span>
<span class="k">[...]</span>
</code></pre></div>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>update-grub
</code></pre></div>
<p>Long version:</p>
<p><a href="2007-02-10-pimp-my-boot-process-ii.html">A few weeks ago</a> I tried to improve
the visual appearance of my boot process using <em>usplash</em> and a matching <em>grub</em>
splash theme.</p>
<p>It took me quite a while to create my first very own usplash theme and it was
a rather complicated affair (Thanks to Petter Reinholdtsen for his patch which
lead to my first working prototype). Since creating usplash themes is rather
tricky and not really suitable for the average user I decided to switch to
<em>splashy</em>. Splashy has many advantages above usplash like a very easy way to
create themes, support of high resolution images and many themes already
available in Debian.</p>
<p>So here is my current solution for a nice bootup:</p>
<p>First I installed <em>desktop-base</em> in order to get the nice <em>moreblue</em> KDM
theme:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>aptitude<span class="w"> </span>install<span class="w"> </span>desktop-base
</code></pre></div>
<p>Then I installed <em>splashy</em> and <em>splashy-themes</em> in order to get a theme
matching KDM’s <em>moreblue</em> theme:</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>aptitude<span class="w"> </span>install<span class="w"> </span>splashy<span class="w"> </span>splashy-themes
$<span class="w"> </span>sudo<span class="w"> </span>splashy_config<span class="w"> </span>--set-theme<span class="w"> </span>debian-moreblue
</code></pre></div>
<p>Since grub has only rudimentary support for theming, I decided to remove the
boot menu completely. Most of the time I’ll boot the first kernel in the list
anyway and you still have <code>$timeout</code> seconds to press Escape in order to bring
the menu back.</p>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>vim<span class="w"> </span>/boot/grub/menu.lst
</code></pre></div>
<div class="codehilite"><pre><span></span><code><span class="k">[...]</span>
<span class="na">timeout 3</span>
<span class="na">hiddenmenu</span>
<span class="k">[...]</span>
<span class="c1"># defoptions=quiet splash</span>
<span class="k">[...]</span>
</code></pre></div>
<div class="codehilite"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>update-grub
</code></pre></div>
<p>The result looks quite cool and gives my boot process a polished an clean
look. It’s still not perfect since splashy’s theme does not match exactly
KDM’s theme and KDM flicks in an other wallpaper before it starts and after
the login, but it’s good enough for now.</p> Decoupling Presentation from Logic 2007-03-01T11:43:00+01:00 2007-03-01T11:43:00+01:00 Bastian Venthur tag:venthur.de,2007-03-01:/2007-03-01-decoupling-presentation-from-logic.html Decoupling Presentation from Logic <p>Reading <a href="https://www.debian.org/vote/2007/platforms/sho">Sam’s platform</a>, I
applaud his plans to sex up our <a href="https://debian.org">web appearance</a> which is
IMHO overdue.</p>
<p>While redesigning our website shouldn’t be much of a technical problem,
redesigning our <a href="https://bugs.debian.org">BTS</a> could become one:</p>
<p>I noticed that <em>reportbug</em> and <em>bts</em> are basically querying the BTS via HTTP
as a user would, grepping the source of the html-reply for the information
they need afterwards. While this works pretty good in most situations it has
the major drawback that those tools unnecessarily depend on the presentation
of the BTS, making it harder to redesign it.</p>
<p>A possible and easy to implement solution would be to allow a special
parameter in the URL-request which triggers an answer in a machine readable
format (like flatfile or XML) rather than a human readable. This would also
have the additional benefit of saving bandwidth and computation power.</p> Rebuilding the Archive Using Cowbuilder 2007-02-20T12:23:00+01:00 2007-02-20T12:23:00+01:00 Bastian Venthur tag:venthur.de,2007-02-20:/2007-02-20-rebuilding-the-archive-using-cowbuilder.html Rebuilding the Archive Using Cowbuilder <p>Did you ever want to rebuild the archive, but setting up this whole
wanna-build/sbuild/buildd stuff somewhat scared you? Then this small script
might be for you. All you need is cowbuilder, the rights to build inside a
cowbuilder environment and <a href="https://people.debian.org/~venthur/stuff/2007-02-rebuild/rebuild.tar.gz">this
script</a>.</p>
<p>When you call it with a list of packages as argument it will build every
package in a clean cowbuilder environment, saving the buildlog
<code>(succeeded-$package or failed-$package)</code> and cleaning up the rest afterwards.</p>
<p>To speed up things you can run several instances of this script concurrently
– lockfiles will prevent the script from building the same package more than
once.</p>
<p>It is even safe to kill the script and restart it later. It will automatically
skip all packages where a logfile <code>(succeded|failed)-$package</code> already exists.
All you have to do after you killed the script is to remove the lockfile in
the <code>LOGDIR</code> and the <code>$package-directory</code> in the <code>BUILDDIR</code>.</p>
<div class="codehilite"><pre><span></span><code><span class="ch">#!/bin/sh</span>
<span class="c1"># Version: 2007-02-20</span>
<span class="nv">LIST</span><span class="o">=</span><span class="nv">$1</span>
<span class="nv">LOGDIR</span><span class="o">=</span><span class="k">$(</span><span class="nb">pwd</span><span class="k">)</span>/<span class="s2">"logs"</span>
<span class="nv">BUILDDIR</span><span class="o">=</span><span class="k">$(</span><span class="nb">pwd</span><span class="k">)</span>/<span class="s2">"build"</span>
<span class="nv">BASEPATH</span><span class="o">=</span><span class="s2">"/var/cache/pbuilder/base-testing.cow"</span>
<span class="k">function</span><span class="w"> </span>build<span class="w"> </span><span class="o">{</span>
<span class="w"> </span><span class="nv">PACKAGE</span><span class="o">=</span><span class="nv">$1</span>
<span class="w"> </span>mkdir<span class="w"> </span>-p<span class="w"> </span><span class="nv">$BUILDDIR</span>/<span class="nv">$PACKAGE</span>
<span class="w"> </span><span class="nb">cd</span><span class="w"> </span><span class="nv">$BUILDDIR</span>/<span class="nv">$PACKAGE</span>
<span class="w"> </span>apt-get<span class="w"> </span><span class="nb">source</span><span class="w"> </span><span class="nv">$PACKAGE</span><span class="w"> </span><span class="p">&</span>><span class="w"> </span>/dev/null
<span class="w"> </span><span class="nb">cd</span><span class="w"> </span><span class="k">$(</span>find<span class="w"> </span>.<span class="w"> </span>-type<span class="w"> </span>d<span class="w"> </span>!<span class="w"> </span>-name<span class="w"> </span>.<span class="k">)</span>
<span class="w"> </span>pdebuild<span class="w"> </span>--pbuilder<span class="w"> </span>cowbuilder<span class="w"> </span>--use-pdebuild-internal<span class="w"> </span>--buildresult<span class="w"> </span>..<span class="w"> </span>--<span class="w"> </span>--basepath<span class="w"> </span><span class="nv">$BASEPATH</span><span class="w"> </span><span class="p">&</span>><span class="w"> </span><span class="nv">$LOGDIR</span>/.<span class="nv">$PACKAGE</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="o">[</span><span class="w"> </span><span class="nv">$?</span><span class="w"> </span>-eq<span class="w"> </span><span class="m">0</span><span class="w"> </span><span class="o">]</span><span class="p">;</span><span class="w"> </span><span class="k">then</span>
<span class="w"> </span>mv<span class="w"> </span><span class="nv">$LOGDIR</span>/.<span class="nv">$PACKAGE</span><span class="w"> </span><span class="nv">$LOGDIR</span>/succeeded-<span class="nv">$PACKAGE</span>
<span class="w"> </span><span class="k">else</span>
<span class="w"> </span>mv<span class="w"> </span><span class="nv">$LOGDIR</span>/.<span class="nv">$PACKAGE</span><span class="w"> </span><span class="nv">$LOGDIR</span>/failed-<span class="nv">$PACKAGE</span>
<span class="w"> </span><span class="k">fi</span>
<span class="w"> </span><span class="nb">cd</span><span class="w"> </span><span class="nv">$BUILDDIR</span>
<span class="w"> </span>rm<span class="w"> </span>-rf<span class="w"> </span><span class="nv">$PACKAGE</span>
<span class="o">}</span>
<span class="o">[</span><span class="w"> </span>-d<span class="w"> </span><span class="nv">$LOGDIR</span><span class="w"> </span><span class="o">]</span><span class="w"> </span><span class="o">||</span><span class="w"> </span>mkdir<span class="w"> </span><span class="nv">$LOGDIR</span>
<span class="k">if</span><span class="w"> </span><span class="o">[</span><span class="w"> </span>!<span class="w"> </span>-e<span class="w"> </span><span class="nv">$LIST</span><span class="w"> </span><span class="o">]</span><span class="p">;</span><span class="w"> </span><span class="k">then</span>
<span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="s2">"No Buildlist given."</span>
<span class="w"> </span><span class="nb">exit</span><span class="w"> </span><span class="m">1</span>
<span class="k">fi</span>
<span class="k">while</span><span class="w"> </span><span class="nb">read</span><span class="w"> </span>package<span class="p">;</span><span class="w"> </span><span class="k">do</span>
<span class="w"> </span><span class="c1"># Create Lockfile (ln -s is atomic and fails if link already exists)</span>
<span class="w"> </span>ln<span class="w"> </span>-s<span class="w"> </span><span class="nv">$package</span><span class="w"> </span><span class="nv">$LOGDIR</span>/.<span class="nv">$package</span>.lock<span class="w"> </span><span class="m">2</span>><span class="w"> </span>/dev/null<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="k">continue</span>
<span class="w"> </span><span class="c1"># Build the package if not already built</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="o">[</span><span class="w"> </span>!<span class="w"> </span>-e<span class="w"> </span><span class="nv">$LOGDIR</span>/succeeded-<span class="nv">$package</span><span class="w"> </span>-a<span class="w"> </span>!<span class="w"> </span>-e<span class="w"> </span><span class="nv">$LOGDIR</span>/failed-<span class="nv">$package</span><span class="w"> </span><span class="o">]</span><span class="p">;</span><span class="w"> </span><span class="k">then</span>
<span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="k">$(</span>date<span class="w"> </span>+%F<span class="se">\ </span>%T<span class="k">)</span><span class="w"> </span>Building<span class="w"> </span><span class="nv">$package</span>...
<span class="w"> </span>build<span class="w"> </span><span class="nv">$package</span>
<span class="w"> </span><span class="k">fi</span>
<span class="w"> </span><span class="c1"># Remove Lockfile</span>
<span class="w"> </span>rm<span class="w"> </span>-f<span class="w"> </span><span class="nv">$LOGDIR</span>/.<span class="nv">$package</span>.lock
<span class="k">done</span><span class="w"> </span><<span class="w"> </span><span class="nv">$LIST</span>
</code></pre></div>
<p>I know my bash scripting skills are shitty, so please send patches after
you laughed ;)</p>
<p>I’m currently running two instances concurrently for 3 days on my Pentium
2,4GHz HT box and have rebuilt ~70% of the testing archive so far.</p>
<p>It would be cool to distribute the rebuilt across a few computers via ssh, so
that they’re all building on the same list but using their own cowbuilders. It
should be sufficient if all computers shared the same <code>LOGDIR</code> across the
network, but I’m not sure how to do this. NFS does not the trick since it
cannot guarantee the atomicity of the ln-command.</p> DPL 2007, Current Candidates 2007-02-14T13:36:00+01:00 2007-02-14T13:36:00+01:00 Bastian Venthur tag:venthur.de,2007-02-14:/2007-02-14-dpl-2007-current-candidates.html DPL 2007, Current Candidates <p>For those who don’t follow -vote regularly, it seems like we have currently
four official nominations for this year’s DPL vote:</p>
<ul>
<li><a href="https://lists.debian.org/debian-vote/2007/02/msg00002.html">Gustavo Franco</a></li>
<li><a href="https://lists.debian.org/debian-vote/2007/02/msg00003.html">Sven Luther</a></li>
<li><a href="https://lists.debian.org/debian-vote/2007/02/msg00004.html">Wouter Verhelst</a></li>
<li><a href="https://lists.debian.org/debian-vote/2007/02/msg00037.html">Aigars Mahinovs</a></li>
</ul>
<p>and two pending ones:</p>
<ul>
<li>Raphaël Hertzog (undecided)</li>
<li>Sam Hocevar (unofficial)</li>
</ul>
<p>A totally unrelated note: If you want to get really frustrated and angry but
don’t feel like participating in Debian’s infamous flamefests – try to learn
to juggle a 5 ball cascade. This will keep you busy for several months without
getting on everybody’s (well, everybody but your neighbor’s) nerves.</p>
<p><strong>Update:</strong> Ooops, I forgot Wouter – thanks
<a href="https://blog.schmehl.info/Debian/dpl-2007-1">Alexander</a>.</p> Pimp My Boot Process (II) 2007-02-10T14:59:00+01:00 2007-02-10T14:59:00+01:00 Bastian Venthur tag:venthur.de,2007-02-10:/2007-02-10-pimp-my-boot-process-ii.html Pimp My Boot Process (II) <p>I’m still working on a grub/usplash splashscreen in order to <a href="2007-01-25-pimp-my-boot-process.html">pimp my boot
process</a>.</p>
<p>Let’s see what we have:</p>
<p><img alt="" src="/images/screenshot_debian_grubsplash.png"></p>
<p>Creating the grub image is rather easy. What’s obviously missing here is the
correct position and color of the text stuff.</p>
<p><img alt="" src="/images/screenshot_debian_usplash.png"></p>
<p>Creating a working splash image for usplash was kinda tricky. I tried several
HOWTOs which took a long time since I had to reboot in order to test the
result. Unfortunately every attempt I made resulted in either a blank screen
or the default fallback splash.</p>
<p>As a last resort I took the source of debian-edu-artwork which has a working
usplash, replaced their image with mine and rebuild the package. I don’t know
yet why, but it worked.</p>
<p>I plan to create package with combined grub/usplash(/xDM) artwork and several
alternative themes, but since our usplash version is <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=397970">lagging
behind</a> upstreams I
think I’ll wait until we catched up again. The new version is not backwards
compatible with the old one and the new one as quite a lot new cool features
like:</p>
<ul>
<li>scripts which help to create splashscreens</li>
<li>support of 256 colors (currently 16)</li>
<li>support of different resolutions (currently 640x480 is hardcoded)</li>
</ul>
<p>which make it a lot easier to create good looking splash screens.</p> Number concerning the next release: 104 2007-02-09T19:04:00+01:00 2007-02-09T19:04:00+01:00 Bastian Venthur tag:venthur.de,2007-02-09:/2007-02-09-number-concerning-the-next-release-104.html Number concerning the next release: 104 <p>Looks like we’ve not made much progress in the last month. Many bugs where
closed but unfortunately many new bugs where opened as well. <a href="2007-01-30-number-concerning-the-next-release-116.html">Last
time</a> I tried to
motivate you to fix a few RC bugs, let’s try a different approach:</p>
<p>*Ahem*</p>
<p>I don’t have to remind you that…
<img alt="" src="/images/debian_god_kills_a_kitten.jpg"></p> First Candidate 2007-02-06T14:57:00+01:00 2007-02-06T14:57:00+01:00 Bastian Venthur tag:venthur.de,2007-02-06:/2007-02-06-first-candidate.html First Candidate <p><a href="https://sam.zoy.org/blog/2007-02-06-just-a-little-bit">Looks</a> like we found
our first ~~victim~~ candidate for this year’s DPL election.</p> RC Bug Triage 2007-02-01T14:54:00+01:00 2007-02-01T14:54:00+01:00 Bastian Venthur tag:venthur.de,2007-02-01:/2007-02-01-rc-bug-triage.html RC Bug Triage <p>In the last three days I made 15 NMUs, fixing 11 RC- and 4 l10n-bugs.</p>
<p>I noticed that some maintainers were not aware that one of their packages had
an open RC bug from the mails I received afterwards. So please double check
your QA package for open RC bugs and fix them if you can.</p>
<p>If you have some spare time please go to the <a href="https://bts.turmzimmer.net/details.php">unofficial RC-bugs
page</a> and check the bugs which are
older than 7 days and affect etch and sid. We’re currently in a <a href="https://lists.debian.org/debian-devel-announce/2006/09/msg00020.html">permanent
BSP</a>
till etch is out, so 0-day NMUs are allowed.</p>
<p>If you are an NM or no maintainer at all, you still can help by providing
patches, submitting them to the BTS and <a href="https://www.debian.org/Bugs/server-control">tagging the
bug</a> with “patch”. Someone will
upload ASAP and might even thank you in the corresponding changelog entry.</p> Random Firefox Tweaks 2007-01-30T23:32:00+01:00 2007-01-30T23:32:00+01:00 Bastian Venthur tag:venthur.de,2007-01-30:/2007-01-30-random-firefox-tweaks.html Random Firefox Tweaks <p>The following options have to be changed or added in about:config. Those
tweaks can of course be achieved through extensions, but by setting them
directly you can abandon some extensions and hopefully conserve some memory.</p>
<p>In order to open a bookmark-folder with mid-click in tabs without overwriting
the current tabs change:</p>
<div class="codehilite"><pre><span></span><code><span class="n">browser</span><span class="o">.</span><span class="n">tabs</span><span class="o">.</span><span class="n">loadFolderAndReplace</span><span class="o">=</span><span class="bp">false</span>
</code></pre></div>
<p>To remove the close buttons on the tabs (they still can be closed by
mid-clicking on them):</p>
<div class="codehilite"><pre><span></span><code>browser.tabs.closeButtons=2
</code></pre></div>
<p>Enable the spellchecker for inputfields and textareas (default is textareas
only):</p>
<div class="codehilite"><pre><span></span><code>layout.spellcheckDefault=2
</code></pre></div>
<p>To override the useragent string:</p>
<div class="codehilite"><pre><span></span><code>general.useragent.override=foobrowser
</code></pre></div>
<p>And the last one really made my day: Open lastfm://-links directly in amarok:</p>
<div class="codehilite"><pre><span></span><code>network.protocol-handler.app.lastfm=amarok network.protocol-handler.external.lastfm=true
</code></pre></div>
<p>BTW: Shouldn’t firef*cough* iceweasel open the composer of your mailclient
when clicking on mailto-links?</p> Number concerning the next release: 116 2007-01-30T11:55:00+01:00 2007-01-30T11:55:00+01:00 Bastian Venthur tag:venthur.de,2007-01-30:/2007-01-30-number-concerning-the-next-release-116.html Number concerning the next release: 116 <p>Looks like our RC counter is heading into the wrong direction. Two years ago
– when our RC counter was as high as now – it took approximately three
months from there to the release. So…</p>
<p><img alt="" src="/images/unclesam_rc_bugs.png"></p> Using My Favorite Mailclient When Reporting Bugs 2007-01-27T22:12:00+01:00 2007-01-27T22:12:00+01:00 Bastian Venthur tag:venthur.de,2007-01-27:/2007-01-27-using-my-favorite-mailclient-when-reporting-bugs.html Using My Favorite Mailclient When Reporting Bugs <p>Dear Lazyweb,</p>
<p>is there an option in reportbug allowing me to use Thunderbird (KMail, foo,
…) to write the bugreport? I’m currently using vim, but Thunderbird’s spell
checker is much more convenient to use and copy-pasting from KDE into vim is
not working very well, making it cumbersome to attach backtraces and stuff.</p> Pimp My Boot Process 2007-01-25T12:38:00+01:00 2007-01-25T12:38:00+01:00 Bastian Venthur tag:venthur.de,2007-01-25:/2007-01-25-pimp-my-boot-process.html Pimp My Boot Process <p>I’ve tested Ubuntu the other day and I must say I was really impressed how
polished the boot process looked. Ubuntu uses the same image as grub splash
and as usplash image. This has the nice effect that there is no visible switch
between grub and usplash. I don’t remember if they even used the same image
for the login as well, but it would surely improve the boot experience even
further.</p>
<p>Since we have grub and usplash in our repository too, I thought it would be
nice to create something similar for Debian. Creating an image and preparing
it for grub is not that hard but <a href="https://help.ubuntu.com/community/USplashCustomizationHowto">creating something suitable for
usplash</a> actually
is a problem.</p>
<p>First obstacle: usplash uses certain defined colors from the palette of the
splash to draw stuff like text, background and progress bar, so you almost
certainly have to re-arrange the position of the colors in the palette of the
image manually. Second: installing the image is not exactly user-friendly. You
have to create a .c-file from the .png. Compile it to a .so. and regenerate
the initramfs in order to activate the theme…</p>
<p>While second part is not that hard and can be done by a script, the first
problem (re-arranging the color palette entries) seems kinda unsolvable for me
and my limited Gimp skills.</p>
<p>So does anyone know a tool which allows to create a usplash theme painlessly?</p>
<p>I think it would be nice to have some grub/usplash theme packs in our
repositories. While it’s certainly uninteresting for servers it surely adds
some extra fun for our desktop users.</p> Allow myself to introduce.......... myself! 2007-01-23T20:36:00+01:00 2007-01-23T20:36:00+01:00 Bastian Venthur tag:venthur.de,2007-01-23:/2007-01-23-allow-myself-to-introduce-myself.html Allow myself to introduce.......... myself! <p>Ok then, this is my first serious blog entry. To break the ice, maybe an
introduction would be appropriate: My name is Bastian Venthur I’m currently 26
years old and live in Berlin, Germany. I’m studying computer science at the
<a href="https://www.inf.fu-berlin.de">Freie Universität Berlin</a> and I am Debian
Developer since October 2006.</p>
<p>I maintain a few
<a href="https://qa.debian.org/developer.php?login=venthur">packages</a>, mostly KDE
related and am quite active in <a href="https://bugs.debian.org/cgi-bin/pkgreport.cgi?submitter=venthur%40debian.org">reporting
bugs</a>.</p>
<p>One of my current hobbies is to juggle. I started a few months ago and already
master some neat tricks like Mills Mess, Over the Head and the famous four
ball Async Fountain.</p> Hello World! 2007-01-23T20:06:00+01:00 2007-01-23T20:06:00+01:00 Bastian Venthur tag:venthur.de,2007-01-23:/2007-01-23-hello-world-2.html Hello World! <p>First post.</p>