<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Geek Ideas</title>
	<atom:link href="http://blog.jasondonenfeld.com/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.jasondonenfeld.com</link>
	<description>{{{ ZX2C4 }}}</description>
	<lastBuildDate>Mon, 08 Mar 2010 00:08:49 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Programming Gigs in Europe</title>
		<link>http://blog.jasondonenfeld.com/265</link>
		<comments>http://blog.jasondonenfeld.com/265#comments</comments>
		<pubDate>Mon, 08 Mar 2010 00:05:29 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Gentoo]]></category>
		<category><![CDATA[Jobs]]></category>
		<category><![CDATA[KDE]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=265</guid>
		<description><![CDATA[I&#8217;m drawn to Europe, and this summer I want to live there, especially France or Italy. Europe is also expensive, which means I have to find a job over there. The problem is, I don&#8217;t have any &#8220;connections&#8221; in the European programming world to set me up with a coding gig. Parisian CraigsList is mostly [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/265#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=265" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m drawn to Europe, and this summer I want to live there, especially France or Italy. Europe is also expensive, which means I have to find a job over there. The problem is, I don&#8217;t have any &#8220;connections&#8221; in the European programming world to set me up with a coding gig. Parisian CraigsList is mostly empty and I&#8217;m not really familiar with how folks find jobs over there. I have a damn good resume, but nobody to send it to.</p>
<p>So, I turn to the interwebs for help: <i><b>How do I find a summer coding job in Europe?</b></i> Anyone suggest any companies or individuals to contact, or know of any European coding gigs search sites? Any KDE/Qt companies based in Paris or Italy or anyplace European I should contact? I&#8217;ll be in Paris next week traveling, so perhaps I&#8217;d be able to meet some folks in person while I&#8217;m over there.</p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/265#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=265" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/265/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Trying to Leave Catch-All E-Mail Behind</title>
		<link>http://blog.jasondonenfeld.com/261</link>
		<comments>http://blog.jasondonenfeld.com/261#comments</comments>
		<pubDate>Fri, 05 Mar 2010 00:46:21 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[Gentoo]]></category>
		<category><![CDATA[KDE]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=261</guid>
		<description><![CDATA[For the last 10 years, I&#8217;ve used zx2c4.com for my e-mail, and have had it forwarded to whichever provider I was using, which most recently happens to be gmail. Ten years ago, it seemed like a good idea to have &#8220;catch-all&#8221; e-mail, whereby anything you put at zx2c4.com would be sent to me. This was [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/261#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=261" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p>For the last 10 years, I&#8217;ve used zx2c4.com for my e-mail, and have had it forwarded to whichever provider I was using, which most recently happens to be gmail. Ten years ago, it seemed like a good idea to have &#8220;catch-all&#8221; e-mail, whereby anything you put at zx2c4.com would be sent to me. This was great for a while, and on every site I would visit that required an e-mail, I&#8217;d give them a new one. JasonHatesWhenNikeDotComSpamsHim [at] zx2c4.com I would use for nike.com, and then I&#8217;d know for certain if they ever sold my e-mail address. For more serious sites, I would just use their site name or something easy to remember about their site. For personal communications, all my friends knew this quality of zx2c4.com, and would send things to anything they wanted &#8212; YouAreAGoofBall [at] zx2c4.com, for example.</p>
<p>This was all fun and games and helped filter out some spam throughout the years, but it seems like it&#8217;s time I settle down on one e-mail address. I would also like to find a different domain than zx2c4.com for personal communications that&#8217;s much easier to remember (any suggestions?). The problem is &#8211; it&#8217;s very difficult to switch away from catch-all e-mail. My initial idea was to gather up all the e-mails of individuals who have sent e-mail to something other than my main e-mail address, and automate the process with a form letter sent via SMTP that says something like &#8220;Dear joe@shmoe.com, You have sent letters to asdfasf [at] zx2c4.com, thatthang [at] zx2c4.com, jojomojito [at] zx2c4.com. Please note that starting May 1, 2010, only whatIDecide [at] zx2c4.com will be valid. Thank you, Jason&#8221;. And then painstakingly go to all of the websites with logins and change my e-mail address for every.single.solitary.one one.by.one. At first this all seemed doable.</p>
<p>But then I started investigating&#8230;. Since I started using GMail in March of 2005, <b>I have received e-mail from 1,299 different e-mail addresses on 267 different zx2c4.com e-mail addresses</b>, not to mention lost e-mail from the 5 years prior. I built this python script to give me a good layout of what&#8217;s up:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
<span style="color: #808080; font-style: italic;"># -*- coding: iso-8859-1 -*-</span>
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">imaplib</span> <span style="color: #ff7700;font-weight:bold;">import</span> IMAP4_SSL
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">optparse</span> <span style="color: #ff7700;font-weight:bold;">import</span> OptionParser
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">email</span>.<span style="color: #dc143c;">parser</span> <span style="color: #ff7700;font-weight:bold;">import</span> HeaderParser
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">email</span>.<span style="color: black;">message</span> <span style="color: #ff7700;font-weight:bold;">import</span> Message
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">email</span>.<span style="color: black;">utils</span> <span style="color: #ff7700;font-weight:bold;">import</span> getaddresses
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
	<span style="color: #dc143c;">parser</span> = OptionParser<span style="color: black;">&#40;</span>usage=<span style="color: #483d8b;">&quot;%prog --username/-u USERNAME --password/-p PASSWORD --mode/-m MODE [--domain/-d DOMAIN] [--cachedir/-c CACHEDIR]&quot;</span>, description=<span style="color: #483d8b;">&quot;Downloads gmail message headers and determines the set of all e-mail addresses on DOMAIN at which people have emailed you.&quot;</span><span style="color: black;">&#41;</span>
	<span style="color: #dc143c;">parser</span>.<span style="color: black;">add_option</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;-u&quot;</span>, <span style="color: #483d8b;">&quot;--username&quot;</span>, action=<span style="color: #483d8b;">&quot;store&quot;</span>, <span style="color: #008000;">type</span>=<span style="color: #483d8b;">&quot;string&quot;</span>, metavar=<span style="color: #483d8b;">&quot;USERNAME&quot;</span>, <span style="color: #008000;">help</span>=<span style="color: #483d8b;">&quot;Gmail username&quot;</span><span style="color: black;">&#41;</span>
	<span style="color: #dc143c;">parser</span>.<span style="color: black;">add_option</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;-p&quot;</span>, <span style="color: #483d8b;">&quot;--password&quot;</span>, action=<span style="color: #483d8b;">&quot;store&quot;</span>, <span style="color: #008000;">type</span>=<span style="color: #483d8b;">&quot;string&quot;</span>, metavar=<span style="color: #483d8b;">&quot;PASSWORD&quot;</span>, <span style="color: #008000;">help</span>=<span style="color: #483d8b;">&quot;Gmail password&quot;</span><span style="color: black;">&#41;</span>
	<span style="color: #dc143c;">parser</span>.<span style="color: black;">add_option</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;-d&quot;</span>, <span style="color: #483d8b;">&quot;--domain&quot;</span>, action=<span style="color: #483d8b;">&quot;store&quot;</span>, <span style="color: #008000;">type</span>=<span style="color: #483d8b;">&quot;string&quot;</span>, metavar=<span style="color: #483d8b;">&quot;DOMAIN&quot;</span>, <span style="color: #008000;">help</span>=<span style="color: #483d8b;">&quot;Domain name&quot;</span><span style="color: black;">&#41;</span>
	<span style="color: #dc143c;">parser</span>.<span style="color: black;">add_option</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;-c&quot;</span>, <span style="color: #483d8b;">&quot;--cachedir&quot;</span>, action=<span style="color: #483d8b;">&quot;store&quot;</span>, <span style="color: #008000;">type</span>=<span style="color: #483d8b;">&quot;string&quot;</span>, metavar=<span style="color: #483d8b;">&quot;CACHEDIR&quot;</span>, <span style="color: #008000;">help</span>=<span style="color: #483d8b;">&quot;The directory to cache fetched headers for subsequent runs&quot;</span><span style="color: black;">&#41;</span>
	<span style="color: #dc143c;">parser</span>.<span style="color: black;">add_option</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;-m&quot;</span>, <span style="color: #483d8b;">&quot;--mode&quot;</span>, action=<span style="color: #483d8b;">&quot;store&quot;</span>, <span style="color: #008000;">type</span>=<span style="color: #483d8b;">&quot;string&quot;</span>, metavar=<span style="color: #483d8b;">&quot;SENDERSFILE&quot;</span>, <span style="color: #008000;">help</span>=<span style="color: #483d8b;">&quot;If the mode is <span style="color: #000099; font-weight: bold;">\&quot;</span>to<span style="color: #000099; font-weight: bold;">\&quot;</span>, this prints a list of all the emails you've received email on. If the mode is <span style="color: #000099; font-weight: bold;">\&quot;</span>from<span style="color: #000099; font-weight: bold;">\&quot;</span> this prints a list of everyone who has sent you email. If the mode is <span style="color: #000099; font-weight: bold;">\&quot;</span>frombyto<span style="color: #000099; font-weight: bold;">\&quot;</span> this prints a list of all the addresses that have emailed you sorted by the address at which you received email. If the mode is <span style="color: #000099; font-weight: bold;">\&quot;</span>tobyfrom<span style="color: #000099; font-weight: bold;">\&quot;</span> this prints a of all the addresses you have received e-mail from sorted and duplicated by who sent the e-mail.&quot;</span><span style="color: black;">&#41;</span>
	<span style="color: black;">&#40;</span>options, args<span style="color: black;">&#41;</span> = <span style="color: #dc143c;">parser</span>.<span style="color: black;">parse_args</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">if</span> options.<span style="color: black;">username</span> == <span style="color: #008000;">None</span> <span style="color: #ff7700;font-weight:bold;">or</span> options.<span style="color: black;">password</span> == <span style="color: #008000;">None</span>:
		<span style="color: #dc143c;">parser</span>.<span style="color: black;">error</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Username and password are all required.&quot;</span><span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">if</span> options.<span style="color: black;">mode</span> <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">&quot;from&quot;</span> <span style="color: #ff7700;font-weight:bold;">and</span> options.<span style="color: black;">mode</span> <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">&quot;to&quot;</span> <span style="color: #ff7700;font-weight:bold;">and</span> options.<span style="color: black;">mode</span> <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">&quot;frombyto&quot;</span> <span style="color: #ff7700;font-weight:bold;">and</span> options.<span style="color: black;">mode</span> <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">&quot;tobyfrom&quot;</span>:
		<span style="color: #dc143c;">parser</span>.<span style="color: black;">error</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;You must specify a mode.&quot;</span><span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> options.<span style="color: black;">username</span>.<span style="color: black;">lower</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">endswith</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;@gmail.com&quot;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #ff7700;font-weight:bold;">not</span> options.<span style="color: black;">username</span>.<span style="color: black;">lower</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">endswith</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;@googlemail.com&quot;</span><span style="color: black;">&#41;</span>:
		options.<span style="color: black;">username</span> += <span style="color: #483d8b;">&quot;@gmail.com&quot;</span>
	<span style="color: #ff7700;font-weight:bold;">if</span> options.<span style="color: black;">cachedir</span> <span style="color: #66cc66;">!</span>= <span style="color: #008000;">None</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">exists</span><span style="color: black;">&#40;</span>options.<span style="color: black;">cachedir</span><span style="color: black;">&#41;</span>:
		<span style="color: #ff7700;font-weight:bold;">try</span>:
			<span style="color: #dc143c;">os</span>.<span style="color: black;">makedirs</span><span style="color: black;">&#40;</span>options.<span style="color: black;">cachedir</span><span style="color: black;">&#41;</span>
		<span style="color: #ff7700;font-weight:bold;">except</span>:
			<span style="color: #dc143c;">sys</span>.<span style="color: black;">stderr</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Could not make cache dir. Skipping cache.<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: black;">&#41;</span>
			options.<span style="color: black;">cachedir</span> = <span style="color: #008000;">None</span>
&nbsp;
	imap = IMAP4_SSL<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;imap.gmail.com&quot;</span><span style="color: black;">&#41;</span>
	imap.<span style="color: black;">login</span><span style="color: black;">&#40;</span>options.<span style="color: black;">username</span>, options.<span style="color: black;">password</span><span style="color: black;">&#41;</span>
	imap.<span style="color: #dc143c;">select</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;[Gmail]/All Mail&quot;</span>, <span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
	typ, data = imap.<span style="color: black;">search</span><span style="color: black;">&#40;</span><span style="color: #008000;">None</span>, <span style="color: #483d8b;">'ALL'</span><span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">if</span> typ <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">&quot;OK&quot;</span>:
		<span style="color: #dc143c;">sys</span>.<span style="color: black;">exit</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Could not search properly: %s&quot;</span> <span style="color: #66cc66;">%</span> typ<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
	emailAddresses = <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span>
	data = data<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">split</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
	length = <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>data<span style="color: black;">&#41;</span>
	counter = <span style="color: #ff4500;">0</span>
	<span style="color: #dc143c;">parser</span> = HeaderParser<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">for</span> num <span style="color: #ff7700;font-weight:bold;">in</span> data:
		counter += <span style="color: #ff4500;">1</span>
		<span style="color: #ff7700;font-weight:bold;">if</span> options.<span style="color: black;">cachedir</span> <span style="color: #66cc66;">!</span>= <span style="color: #008000;">None</span>:
			cachePath = <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>options.<span style="color: black;">cachedir</span>, num<span style="color: black;">&#41;</span>
		<span style="color: #ff7700;font-weight:bold;">else</span>:
			cachePath = <span style="color: #008000;">None</span>
		<span style="color: #ff7700;font-weight:bold;">if</span> cachePath <span style="color: #66cc66;">!</span>= <span style="color: #008000;">None</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">exists</span><span style="color: black;">&#40;</span>cachePath<span style="color: black;">&#41;</span>:
			message = <span style="color: #dc143c;">parser</span>.<span style="color: black;">parse</span><span style="color: black;">&#40;</span><span style="color: #008000;">open</span><span style="color: black;">&#40;</span>cachePath, <span style="color: #483d8b;">&quot;r&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
		<span style="color: #ff7700;font-weight:bold;">else</span>:
			<span style="color: #ff7700;font-weight:bold;">try</span>:
				typ, data = imap.<span style="color: black;">fetch</span><span style="color: black;">&#40;</span>num, <span style="color: #483d8b;">'(RFC822.HEADER)'</span><span style="color: black;">&#41;</span>
			<span style="color: #ff7700;font-weight:bold;">except</span>:
				<span style="color: #dc143c;">sys</span>.<span style="color: black;">stderr</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Failed to fetch ID %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> num<span style="color: black;">&#41;</span>
				<span style="color: #ff7700;font-weight:bold;">continue</span>
			<span style="color: #ff7700;font-weight:bold;">if</span> typ <span style="color: #66cc66;">!</span>= <span style="color: #483d8b;">&quot;OK&quot;</span>:
				<span style="color: #dc143c;">sys</span>.<span style="color: black;">stderr</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Failed to fetch ID %s: %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>num, typ<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
				<span style="color: #ff7700;font-weight:bold;">continue</span>
			<span style="color: #ff7700;font-weight:bold;">if</span> cachePath <span style="color: #66cc66;">!</span>= <span style="color: #008000;">None</span>:
				<span style="color: #ff7700;font-weight:bold;">try</span>:
					f = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span>cachePath, <span style="color: #483d8b;">&quot;w&quot;</span><span style="color: black;">&#41;</span>
					f.<span style="color: black;">write</span><span style="color: black;">&#40;</span>data<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
					f.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
				<span style="color: #ff7700;font-weight:bold;">except</span>:
					<span style="color: #dc143c;">sys</span>.<span style="color: black;">stderr</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Could not write cache for %s&quot;</span> <span style="color: #66cc66;">%</span> num<span style="color: black;">&#41;</span>
			message = <span style="color: #dc143c;">parser</span>.<span style="color: black;">parsestr</span><span style="color: black;">&#40;</span>data<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>, <span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
		tos = message.<span style="color: black;">get_all</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'to'</span>, <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
		ccs = message.<span style="color: black;">get_all</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'cc'</span>, <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
		resent_tos = message.<span style="color: black;">get_all</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'resent-to'</span>, <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
		resent_ccs = message.<span style="color: black;">get_all</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'resent-cc'</span>, <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
		all_recipients = getaddresses<span style="color: black;">&#40;</span>tos + ccs + resent_tos + resent_ccs<span style="color: black;">&#41;</span>
		<span style="color: #ff7700;font-weight:bold;">for</span> address <span style="color: #ff7700;font-weight:bold;">in</span> all_recipients:
			<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>address<span style="color: black;">&#41;</span> == <span style="color: #ff4500;">2</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: black;">&#40;</span>options.<span style="color: black;">domain</span> == <span style="color: #008000;">None</span> <span style="color: #ff7700;font-weight:bold;">or</span> address<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">endswith</span><span style="color: black;">&#40;</span>options.<span style="color: black;">domain</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
				to = address<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">lower</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
				fros = getaddresses<span style="color: black;">&#40;</span>message.<span style="color: black;">get_all</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'from'</span>, <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
				fro_addresses = <span style="color: #008000;">set</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
				<span style="color: #ff7700;font-weight:bold;">for</span> addr <span style="color: #ff7700;font-weight:bold;">in</span> fros:
					<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>addr<span style="color: black;">&#41;</span> == <span style="color: #ff4500;">2</span>:
						fro_addresses.<span style="color: black;">add</span><span style="color: black;">&#40;</span>addr<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>.<span style="color: black;">lower</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
				<span style="color: #ff7700;font-weight:bold;">if</span> options.<span style="color: black;">mode</span> == <span style="color: #483d8b;">&quot;to&quot;</span> <span style="color: #ff7700;font-weight:bold;">or</span> options.<span style="color: black;">mode</span> == <span style="color: #483d8b;">&quot;tobyfrom&quot;</span>:
					<span style="color: #ff7700;font-weight:bold;">if</span> to <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #ff7700;font-weight:bold;">in</span> emailAddresses:
						emailAddresses<span style="color: black;">&#91;</span>to<span style="color: black;">&#93;</span> = <span style="color: #008000;">set</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
					emailAddresses<span style="color: black;">&#91;</span>to<span style="color: black;">&#93;</span> = emailAddresses<span style="color: black;">&#91;</span>to<span style="color: black;">&#93;</span>.<span style="color: black;">union</span><span style="color: black;">&#40;</span>fro_addresses<span style="color: black;">&#41;</span>
				<span style="color: #ff7700;font-weight:bold;">elif</span> options.<span style="color: black;">mode</span> == <span style="color: #483d8b;">&quot;from&quot;</span> <span style="color: #ff7700;font-weight:bold;">or</span> options.<span style="color: black;">mode</span> == <span style="color: #483d8b;">&quot;frombyto&quot;</span>:
					<span style="color: #ff7700;font-weight:bold;">for</span> fro <span style="color: #ff7700;font-weight:bold;">in</span> fro_addresses:
						<span style="color: #ff7700;font-weight:bold;">if</span> fro <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #ff7700;font-weight:bold;">in</span> emailAddresses:
							emailAddresses<span style="color: black;">&#91;</span>fro<span style="color: black;">&#93;</span> = <span style="color: #008000;">set</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
						emailAddresses<span style="color: black;">&#91;</span>fro<span style="color: black;">&#93;</span>.<span style="color: black;">add</span><span style="color: black;">&#40;</span>to<span style="color: black;">&#41;</span>
				<span style="color: #dc143c;">sys</span>.<span style="color: black;">stderr</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;[%s of %s]: Message to %s from %s.<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>counter, length, address<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>, fro_addresses<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
		<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>all_recipients<span style="color: black;">&#41;</span> == <span style="color: #ff4500;">0</span>:
			<span style="color: #dc143c;">sys</span>.<span style="color: black;">stderr</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;[%s of %s]: Message has empty To header.<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>counter, length<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
	imap.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
	imap.<span style="color: black;">logout</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">if</span> options.<span style="color: black;">mode</span> == <span style="color: #483d8b;">&quot;to&quot;</span> <span style="color: #ff7700;font-weight:bold;">or</span> options.<span style="color: black;">mode</span> == <span style="color: #483d8b;">&quot;from&quot;</span>:
		<span style="color: #ff7700;font-weight:bold;">for</span> addr <span style="color: #ff7700;font-weight:bold;">in</span> emailAddresses.<span style="color: black;">keys</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
			<span style="color: #ff7700;font-weight:bold;">print</span> addr
	<span style="color: #ff7700;font-weight:bold;">elif</span> options.<span style="color: black;">mode</span> == <span style="color: #483d8b;">&quot;tobyfrom&quot;</span> <span style="color: #ff7700;font-weight:bold;">or</span> options.<span style="color: black;">mode</span> == <span style="color: #483d8b;">&quot;frombyto&quot;</span>:
		<span style="color: #ff7700;font-weight:bold;">for</span> to, fro <span style="color: #ff7700;font-weight:bold;">in</span> emailAddresses.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
			<span style="color: #ff7700;font-weight:bold;">print</span> to
			<span style="color: #ff7700;font-weight:bold;">for</span> f <span style="color: #ff7700;font-weight:bold;">in</span> fro:
				<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>%s&quot;</span> <span style="color: #66cc66;">%</span> f
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
	main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>The situation seems daunting. That is so many email addresses, so many senders, so many website logins to change, so many people who have to update their address books. So what do I do? What will I do? How important is it to switch away from catch-all? I might just be locked in for life.</p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/261#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=261" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/261/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Clementine: The Player I&#8217;ve Been Looking For</title>
		<link>http://blog.jasondonenfeld.com/257</link>
		<comments>http://blog.jasondonenfeld.com/257#comments</comments>
		<pubDate>Wed, 03 Mar 2010 00:59:55 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Amarok]]></category>
		<category><![CDATA[Clementine]]></category>
		<category><![CDATA[Gentoo]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[Qt]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=257</guid>
		<description><![CDATA[Clementine is a half port half rewrite of Amarok 1.4, with its kdelibs dependencies stripped and all the code updated to use Qt4. Only in its 0.1 version, it works incredibly well. I&#8217;ve been looking for something like this since Juk became crusty and Amarok became too much and Exaile seemed slow and gtkish. Clementine [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/257#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=257" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p>Clementine is a half port half rewrite of Amarok 1.4, with its kdelibs dependencies stripped and all the code updated to use Qt4. Only in its 0.1 version, it works incredibly well. I&#8217;ve been looking for something like this since Juk became crusty and Amarok became too much and Exaile seemed slow and gtkish. Clementine is my new default player.<br />
<a href="http://code.google.com/p/clementine-player/"><img src="http://blog.jasondonenfeld.com/wp-content/uploads/2010/03/Clementine.png" alt="" title="Clementine" class="aligncenter size-full wp-image-258" /></a><br />
<a href="http://znurt.org/media-sound/clementine">An ebuild</a> is already available for Gentoo.</p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/257#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=257" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/257/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Wpa_gui is Underrated</title>
		<link>http://blog.jasondonenfeld.com/248</link>
		<comments>http://blog.jasondonenfeld.com/248#comments</comments>
		<pubDate>Mon, 25 Jan 2010 21:29:02 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Gentoo]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[NetworkManager]]></category>
		<category><![CDATA[Nokia]]></category>
		<category><![CDATA[Wicd]]></category>
		<category><![CDATA[Wireless]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=248</guid>
		<description><![CDATA[A hot topic in the community is wireless management. There&#8217;s a whole lot of buzz about NetworkManager, Wicd, dbus, frontends, PolicyKit, plasmoids, and the whole modicum of dizzying names and acronyms. Let me tell you about my mobile laptop&#8217;s wifi setup and why it&#8217;s easier and slimmer than any of the classic bloat. 
I use [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/248#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=248" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p>A hot topic in the community is wireless management. There&#8217;s a whole lot of buzz about NetworkManager, Wicd, dbus, frontends, PolicyKit, plasmoids, and the whole modicum of dizzying names and acronyms. Let me tell you about my mobile laptop&#8217;s wifi setup and why it&#8217;s easier and slimmer than any of the classic bloat. </p>
<p>I use wpa_supplicant&#8217;s optional wpa_gui. It&#8217;s a tiny Qt app that has a tray icon and a command line switch to start in the tray. Wpa_supplicant is required for all modern wireless connections and is always running in the background no matter what. Wpa_gui simply connects to wpa_gui&#8217;s socket and tells it what to do. I like having wpa_gui in my system tray so that I can reconfigure wifi networks easily.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">zx2c4<span style="color: #000000; font-weight: bold;">@</span>ZX2C4-Laptop ~ $ <span style="color: #c20cb9; font-weight: bold;">cat</span> ~<span style="color: #000000; font-weight: bold;">/</span>.kde<span style="color: #000000; font-weight: bold;">/</span>Autostart<span style="color: #000000; font-weight: bold;">/</span>wpagui.sh
wpa_gui <span style="color: #660033;">-t</span></pre></div></div>

<p>And check it out:<br />
<img src="http://blog.jasondonenfeld.com/wp-content/uploads/2010/01/wpa_gui_mainscreen.png" alt="" title="Wpa_gui&#039;s Main Screen" width="370" height="442" class="aligncenter size-full wp-image-249" /><br />
A simple, somewhat ugly, but extremely functional info display. I can connect to new networks with a simple double click:<br />
<img src="http://blog.jasondonenfeld.com/wp-content/uploads/2010/01/wpa_gui_scanresults.png" alt="" title="Wpa_gui&#039;s Scan Results" width="460" height="271" class="aligncenter size-full wp-image-250" /><br />
And presto it connects to the wifi network. I can also configure all of the highly advanced encryption profiles that wpa_supplicant supports. All of this is easily accessible in my tray:<br />
<img src="http://blog.jasondonenfeld.com/wp-content/uploads/2010/01/wpa_gui_tray.png" alt="" title="Wpa_gui&#039;s Tray" width="140" height="42" class="aligncenter size-full wp-image-251" /><br />
If I did not want wpa_gui -t running all the time, I could pretty easily make this into a little quick launch plasma button, and it would start up nearly as fast, because wpa_gui is so light weight.</p>
<p>This is how I do wireless. I have never had any trouble, and I can connect to wifi networks anywhere I go with ease. It remembers the connections and the priorities that I assign, and I have not seen any system simpler or easier than this.</p>
<p>For wired networking, netplug calls my ethernet setup scripts when I plug in an ethernet cable. No tinkering required. For my cellphone internet via bluetooth, I run &#8220;pon nokia&#8221; and my ppp chatscript does all the rest. This could easily be tied to a little menu button in my launcher.</p>
<p>I&#8217;m bloat free, <i>and</i> networking dynamically on the go with my laptop does not require any advanced timely tinkering.</p>
<p>Why are you all using NM, wicd, etc instead of good ol&#8217; wpa_gui?</p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/248#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=248" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/248/feed</wfw:commentRss>
		<slash:comments>32</slash:comments>
		</item>
		<item>
		<title>Long Live Juk</title>
		<link>http://blog.jasondonenfeld.com/240</link>
		<comments>http://blog.jasondonenfeld.com/240#comments</comments>
		<pubDate>Fri, 18 Dec 2009 02:39:50 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Amarok]]></category>
		<category><![CDATA[Juk]]></category>
		<category><![CDATA[KDE]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=240</guid>
		<description><![CDATA[When I first started using Linux way back when, I had only MP3s, and Juk was the perfect simple interface for me. Then I started to acquire a good amount of AACs and seeing that m4a support was a long way from taglib, I was forced to switch to Amarok. For a while I bathed [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/240#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=240" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p>When I first started using Linux way back when, I had only MP3s, and Juk was the perfect simple interface for me. Then I started to acquire a good amount of AACs and seeing that m4a support was a long way from taglib, I was forced to switch to Amarok. For a while I bathed in Amarok&#8217;s advanced feature set, but at the end of the day, I always longed for my simple Juk interface. For a while I even used <a href="http://code.google.com/p/gogglesmm/">GogglesMM</a>, which is a wonderful project written in FOX. But alas FOX was ugly and didn&#8217;t integrate with Qt/KDE, so I&#8217;ve stayed with Amarok. <b>But finally</b> in the latest KDE SC beta, Juk supports AAC, corresponding with taglib 1.6&#8217;s optional addition! Everyone admire:<br />
<a href="http://blog.jasondonenfeld.com/wp-content/uploads/2009/12/longlivejuk.png"><img src="http://blog.jasondonenfeld.com/wp-content/uploads/2009/12/longlivejuk-450x303.png" alt="Long Live Juk!" title="Long Live Juk!" width="450" height="303" class="aligncenter size-medium wp-image-241" /></a><br />
It&#8217;s pretty and works well. I haven&#8217;t tried it out tons yet, but so far as I can tell, Juk does almost exactly what I want a music manager to do for me, or what I wanted it to do for me when I was 14 years old.</p>
<p>The system tray has issues, there&#8217;s no support for the disc number, there are some issues with the search filter and multiple fields, I haven&#8217;t tested the file renaming capabilities, collection scanning is odd, it still relies on Qt3Support, there is no shortcut handler for scrolling to the current track, and it&#8217;s got a lot of unfortunate tiny quirks. But all of this is to be expected of software that&#8217;s been basically forgotten about since KDE 3.4.</p>
<p>So after exams are over, I&#8217;m going to start investigating Juk&#8217;s codebase and seeing if it&#8217;s worth it to  whip this great player into shape for the prime. It looks promising so far, though I haven&#8217;t tested it very completely yet.</p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/240#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=240" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/240/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>New Laptop for the First Time Since 2001</title>
		<link>http://blog.jasondonenfeld.com/230</link>
		<comments>http://blog.jasondonenfeld.com/230#comments</comments>
		<pubDate>Sun, 13 Dec 2009 06:20:24 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ATI]]></category>
		<category><![CDATA[Dell]]></category>
		<category><![CDATA[eBay]]></category>
		<category><![CDATA[Gentoo]]></category>
		<category><![CDATA[KDE]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=230</guid>
		<description><![CDATA[Middle School
The last time I bought a laptop for myself was in 7th grade, 2001. I was 13 and I used all my savings to buy a $3,700 Dell Inspiron 8100 running a Pentium 3 processor with a whopping 512mb of ram, a 64mb graphics card, and a gigantic 60gb hard drive. What an incredible [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/230#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=230" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<h3>Middle School</h3>
<p>The last time I <i>bought</i> a laptop for myself was in 7th grade, 2001. I was 13 and I used all my savings to buy a $3,700 Dell Inspiron 8100 running a Pentium 3 processor with a whopping 512mb of ram, a 64mb graphics card, and a gigantic 60gb hard drive. What an incredible machine this was.</p>
<h3>eBay</h3>
<p>Finally it&#8217;s time I buy myself a new computer. I recently acquired an Alienware M17x that&#8217;s pretty high end, but I&#8217;m not a gamer, so I&#8217;m <a href="http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&#038;item=230409562381">selling it on eBay</a> and am going to use the cash to finance the purchase of a brand new Dell Studio 1747. This was my first time selling something big on eBay, and at first I screwed up quite a bit &#8212; I listed it at $2,200, which is the price I want in the end for it. No one bid (except for a Romanian scammer offering me $3,500), and a friend of mine convinced me to list it at $0.01 &#8211; one penny &#8211; with no reserve price, and let the market determine its value. I was weary, but so far the auction has gotten to $1,500, which I&#8217;m pretty pleased with. eBay is addictive though &#8212; I constantly monitor the auction to see how much I&#8217;m going to be receiving. It&#8217;s taken me over; it&#8217;s awful. I must never play the stock market for this reason. To satisfy my obsession with the bidding, I&#8217;ve hacked together in a minute a short python script running in screen that sends me a text message every time the bid increases:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urllib2</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
last = <span style="color: #ff4500;">0</span>
<span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Checking auction at %s:&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: #dc143c;">time</span>.<span style="color: black;">asctime</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>,
        page = <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&amp;item=230409562381&quot;</span><span style="color: black;">&#41;</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        index = page.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;US $&quot;</span><span style="color: black;">&#41;</span> + <span style="color: #ff4500;">4</span>
        now = <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>page<span style="color: black;">&#91;</span>index:page.<span style="color: black;">find</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;.&quot;</span>, index<span style="color: black;">&#41;</span><span style="color: black;">&#93;</span>.<span style="color: black;">replace</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;,&quot;</span>, <span style="color: #483d8b;">&quot;&quot;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">print</span> now
        <span style="color: #ff7700;font-weight:bold;">if</span> now <span style="color: #66cc66;">&gt;</span> last:
                <span style="color: #dc143c;">os</span>.<span style="color: black;">system</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;echo 'As of %s, auction is at %s' | sendmail MYTELEPHONENUMBER@txt.att.net&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span><span style="color: #dc143c;">time</span>.<span style="color: black;">asctime</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, now<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
                last = now
        <span style="color: #dc143c;">time</span>.<span style="color: black;">sleep</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">45</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Aye yie yie.</p>
<h3>The Specs</h3>
<p>But I&#8217;m quite excited about the new laptop I&#8217;ve ordered:<br />
<img src="http://i.dell.com/images/global/products/laptop_studio/laptop_studio_highlights/studio-1747-design1.jpg"><br />
The specs are:</p>
<ul>
<li>Intel Core i7 820QM 1.73GHz (3.06GHz Turbo Mode, 8MB Cache)</li>
<li>8GB ram, DDR3, 1333MHz, 2 DIMM</li>
<li>ATI Mobility Radeon HD4650 with 1GB ram</li>
<li>Two 500GB 7200rpm hard drives</li>
<li>17.3in 1920&#215;1080 Screen</li>
<li>BluRay Burner</li>
<li>4 Year CompleteCare Warranty</li>
</ul>
<p>With an awesome discount by asking the phone sales manager&#8217;s manager&#8217;s manager, this all cost before tax $2,350. Still expensive, but I&#8217;m hoping that <a href="http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&#038;item=230409562381">eBay auction</a> will mostly pay for it.</p>
<h3>The Interesting Part: Configuration</h3>
<p>So while I wait for the new machine to arrive, I have to start planning what I&#8217;m going to put on it, and how I&#8217;m going to do it.</p>
<p>It has a fast processor and a lot of ram. It seems, however, that it has more ram than processor, in a sense. What I mean is that with 8 gigs of ram, it seems like I might as well keep all programs running at all times. The problem could be though &#8211; maybe too many idle processes will gradually eat away at CPU. I&#8217;m not sure. Will it?</p>
<p>What do you think? With so much ram, I also need to decide what I&#8217;m going to do about swap/hibernation. Do I use a separate partition of 4gigs for swap? Or do I go with the swap<i>file</i> approach? Or do I not even use a swap at all, because 8gigs of ram is a lot? For hibernation, do I use what&#8217;s in 2.6.32 by default or do I patch in <a href="http://www.tuxonice.net">TuxOnIce</a>? Decisions, decisions.</p>
<p>I&#8217;ll probably go with Gentoo, because it&#8217;s customizable and I&#8217;ve used it for <i>years</i>. It has its shortcomings, however, and I&#8217;m curious about <a href="http://exherbo.org">Exherbo</a>, which claims to do what Gentoo does but better, or a customizable binary distro like Arch, or maybe even make the huge leap to an advanced popular distro like Fedora. I&#8217;ll probably just stay with Gentoo though, unless somebody can make a really good case to do otherwise. Flamewars, commence.</p>
<p>Of course, I&#8217;ll be using KDE SC 4.4 Beta 2 by the time the computer arrives. By the way, I hate adding the &#8220;SC&#8221; in there, but I think PlanetKDE would come after me if I neglected it. Branding shmanding. But anyway, KDE should fly on the new machine.</p>
<p>The wifi card supports 802.11n, but is unfortunately one of the Broadcom cards that is only supported by the hybrid-proprietary wl driver. Also, in my experience, FGLRX, ATI&#8217;s proprietary driver, outperforms RadeonHD by a long shot, so I&#8217;ll be using FGLRX too. Shucks. At least ATI&#8217;s own John Bridgman <a href="http://blog.jasondonenfeld.com/169#comment-841">has pointed us</a> to a <a href="http://launchpadlibrarian.net/32728179/xserver-xorg-backclear.patch">solution</a> for the KWin resizing compositing problem.</p>
<h3>The Big Issue: Data Organization</h3>
<p>The biggest issue, however, is what I am going to do with 1TB of hard drive space. How do I divide it up? The breakdown of the situation is this: </p>
<p><i>Storage:</i></p>
<ul>
<li>Internal 500gb</li>
<li>Internal 500gb</li>
<li>External 500gb (via USB2)</li>
<li>Online server with lots of gb (via ssh+rsync)</li>
</ul>
<p><i>Data:</i></p>
<ul>
<li>26gb of pictures (and growing)</li>
<li>67gb of music</li>
<li>2gb of code</li>
<li>1gb of documents</li>
<li>15gb of protools archives</li>
<li>10gb of goofy home videos from middle school</li>
<li>1gb of old school work</li>
<li>2gb of middle school junk archives</li>
<li>1gb of old code projects</li>
<li>300gb of downloaded junk</li>
</ul>
<p>So what are my options for all of this? First of all, which file system? I&#8217;ll probably go with ext4, because it seems like the best you can get on Linux right now. How do I organize the data? Some possible schemes are:</p>
<ul>
<li>Many operating systems on Internal1, all data on Internal2, data backed up to both Online and External</li>
<li>Linux in Internal1 along with main data (pics, docs, music, code), with downloaded junk on Internal2, and archives of old stuff on External, with important stuff backed up to Online</li>
<li>Linux in Internal1 along with main data (pics, docs, music, code), with downloaded junk and archives of old stuff on Internal2, with important stuff backed up to both Online and External</li>
<li>Use LVM to concatenate the two drives</li>
<li>Use LVM for RAID-1</li>
<li>Use LVM for RAID-0</li>
<li>Use LVM for RAID-10</li>
</ul>
<p><b>What else? What do I do here?!?</b></p>
<p>I&#8217;m really not quite sure. What do you think? What else should I be thinking about? Location of home directory? The additional power consumption of a second HD and hdparm -Y? I want to configure this system perfectly; I need all the help I can get.</p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/230#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=230" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/230/feed</wfw:commentRss>
		<slash:comments>40</slash:comments>
		</item>
		<item>
		<title>Testing out Qt for Symbian</title>
		<link>http://blog.jasondonenfeld.com/223</link>
		<comments>http://blog.jasondonenfeld.com/223#comments</comments>
		<pubDate>Sat, 05 Dec 2009 10:52:15 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[Nokia]]></category>
		<category><![CDATA[Qt]]></category>
		<category><![CDATA[Symbian]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=223</guid>
		<description><![CDATA[
Qt 4.6 was released, and Alessandro put together some awesome tutorial videos for setting up a Qt/Symbian development platform. 
The installation was not so smooth, however. I have a Nokia 6650, branded and locked down by AT&#038;T, which makes it awful. It&#8217;s filled with bloatware I can&#8217;t remove and there are all sorts of restrictions [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/223#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=223" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.youtube.com/watch?v=c95KAuorbIU" target="_blank"><img src="http://blog.jasondonenfeld.com/wp-content/uploads/2009/12/messagepoppersymbian.jpg" alt="MessagePopper on Symbian and Linux" title="MessagePopper on Symbian and Linux" class="aligncenter size-full wp-image-226" border="0"/></a></p>
<p>Qt 4.6 was released, and Alessandro put together some <a href="http://labs.trolltech.com/blogs/2009/12/03/tutorial-videos-qt-development-for-symbian/">awesome tutorial videos</a> for setting up a Qt/Symbian development platform. </p>
<p>The installation was not so smooth, however. I have a Nokia 6650, branded and locked down by AT&#038;T, which makes it awful. It&#8217;s filled with bloatware I can&#8217;t remove and there are all sorts of restrictions in the operating system, especially related to app installation. It would not let me install PIPS, which is required for OpenC and Qt, and gave me either a nasty error from Qt&#8217;s demo installer or from the standalone installer an error message like &#8220;Component already built-in. You&#8217;re screwed.&#8221; So I had to jailbreak the phone, by installing HelloCarbide to allow me to install CapsOn/Off to allow me to insert a hacked installserver.exe so that it would let me install PIPS. Whew that took a long time. Debug deployment is also broken with a message like &#8220;General OS error.&#8221; No clue. It will sometimes work if installed manually, but basically, AT&#038;T&#8217;s restrictions make development pretty rough.</p>
<p>Nevertheless, I prevailed in porting my classic Qt example app: <a href="http://git.zx2c4.com/?p=messagepopper.git">MessagePopper</a>. The only modifications were having the main window show with showMaximized() instead of show() for Q_OS_SYMBIAN and focusing a text input, because evidently if a focused widget is hidden and no other visible widget is programmatically focused, the user cannot select anything. The huge addition was adding a function call to ask Symbian for a network connection, and this required including from Qt&#8217;s FTP demo the <a href="http://git.zx2c4.com/?p=messagepopper.git;a=blob;f=sym_iap_util.h">sym_iap_util.h</a> header and <a href="http://git.zx2c4.com/?p=messagepopper.git;a=blobdiff;f=MessagePopper.pro;h=cb320f2f066546a55b7ab7ad9f53a341ed4f7038;hp=a780c73c92a370da774d7668cacb5ce40c4d50dd;hb=HEAD;hpb=fb8677daa2658e52511317511d497dfc456e4dc8">qmake pro additions</a>. Oy. I wish this part were built in to QtNetwork.</p>
<p>It worked beautifully though, and here&#8217;s a video demonstrating the app:<br />
<object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/c95KAuorbIU&#038;hl=en_US&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/c95KAuorbIU&#038;hl=en_US&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object><br />
<a href="http://www.youtube.com/watch?v=c95KAuorbIU"><b>(link to youtube original)</b></a></p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/223#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=223" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/223/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Chromium Rocks</title>
		<link>http://blog.jasondonenfeld.com/220</link>
		<comments>http://blog.jasondonenfeld.com/220#comments</comments>
		<pubDate>Sat, 24 Oct 2009 02:13:40 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Chrome]]></category>
		<category><![CDATA[Gentoo]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[KHTML]]></category>
		<category><![CDATA[Konqueror]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=220</guid>
		<description><![CDATA[I just compiled Chromium, and it rocks. The download manager is better than Firefox, the design is cleaner, the JavaScript performance is a 4 times better, and overall it just seems more solid. The web works better in it. My only complaints so far are some weird font rendering issues and a lack of extensions [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/220#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=220" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p>I just compiled Chromium, and it rocks. The download manager is better than Firefox, the design is cleaner, the JavaScript performance is a 4 times better, and overall it just seems more solid. The web works better in it. My only complaints so far are some weird font rendering issues and a lack of extensions (adblock, customize google, gmail notifier, live http headers, modify headers, open in browser, right-click-link, skipscreen, useragent switcher&#8230;). I&#8217;ll stick with Firefox until there is good extension support for Chromium.</p>
<p>I did a JS performance test of QtWebKit, KHTML, Gecko, and V8, and here are the results:<br />
<a href="http://blog.jasondonenfeld.com/wp-content/uploads/2009/10/sunspider_0_9_benchmark.png"><img src="http://blog.jasondonenfeld.com/wp-content/uploads/2009/10/sunspider_0_9_benchmark-450x239.png" alt="Sunspider Benchmark" title="Sunspider Benchmark" width="450" height="239" class="aligncenter size-medium wp-image-221" /></a></p>
<p>Evidently KHTML has <b>a lot</b> of catching up to do, per usual. </p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/220#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=220" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/220/feed</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>Hands on with the N900</title>
		<link>http://blog.jasondonenfeld.com/212</link>
		<comments>http://blog.jasondonenfeld.com/212#comments</comments>
		<pubDate>Thu, 15 Oct 2009 02:52:24 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Gentoo]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[Maemo]]></category>
		<category><![CDATA[N900]]></category>
		<category><![CDATA[Nokia]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=212</guid>
		<description><![CDATA[
I played with the N900 today at the Nokia store in NYC and was thoroughly disappointed. From reading all those fanboy posts out there, I expected the most awesome telephone ever, but instead I was presented with the following cons:

It is clunky. Really clunky. It&#8217;s very thick and does not fit into the pocket well.
The [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/212#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=212" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.jasondonenfeld.com/wp-content/uploads/2009/10/IMG_0328.jpg"><img src="http://blog.jasondonenfeld.com/wp-content/uploads/2009/10/IMG_0328-450x300.jpg" alt="Playing with the N900" title="Playing with the N900" width="450" height="300" class="aligncenter size-medium wp-image-216" /></a><br />
I played with the N900 today at the Nokia store in NYC and was thoroughly disappointed. From reading all those fanboy posts out there, I expected the most awesome telephone ever, but instead I was presented with the following cons:</p>
<ul>
<li>It is clunky. Really clunky. It&#8217;s very thick and does not fit into the pocket well.</li>
<li>The keyboard is too tiny. Maybe this just takes some getting used to, but I couldn&#8217;t do it.</li>
<li>No multi-touch. The little swirling gesture to zoom is a cop-out for a much needed multi-touch screen.</li>
<li>Unintuitive user-interface. Some things made sense, but generally operations took one too many clicks. Making phone calls should be easy and fast.</li>
<li>The user interface does not rotate.</li>
<li>The web browser is turkey slow, even for cached pages.</li>
<li>Ovi maps is uglier than GMaps, and again &#8211; no multi-touch.</li>
</ul>
<p>Oh well. I guess I&#8217;ll wait until the N900+1, especially considering that Maemo 5 will <a href="http://blog.jasondonenfeld.com/202">soon be obsolete</a>.</p>
<p>Or maybe I&#8217;m just approaching it the wrong way? I dunno. After all, it does run Linux, can run KDE, and is extremely open&#8230; but still: it&#8217;s lacking heavily in several areas.</p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/212#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=212" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/212/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Maemo 5 or Maemo 6?</title>
		<link>http://blog.jasondonenfeld.com/202</link>
		<comments>http://blog.jasondonenfeld.com/202#comments</comments>
		<pubDate>Wed, 14 Oct 2009 19:45:16 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Gentoo]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[Maemo]]></category>
		<category><![CDATA[N900]]></category>
		<category><![CDATA[Nokia]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=202</guid>
		<description><![CDATA[The N900 looks good, and later today I plan to go down to NYC&#8217;s Nokia store to investigate. However, as Ars reports, the N900 is the 4th step in a 5 step program to develop a mainstream smart phone, and Maemo 5 is last platform before Qt domination comes to Nokia.
So should I wait for [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/202#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=202" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.jasondonenfeld.com/wp-content/uploads/2009/10/n900.jpg" alt="N900" title="N900" width="200" height="116" align="right" class="alignright size-full wp-image-205" />The N900 looks good, and later today I plan to go down to NYC&#8217;s Nokia store to investigate. However, as <a href="http://arstechnica.com/open-source/news/2009/10/next-gen-nokia-linux-devices-will-get-multitouch-and-qt-ui.ars">Ars reports</a>, the N900 is the 4th step in a 5 step program to develop a mainstream smart phone, and Maemo 5 is last platform before <i>Qt domination</i> comes to Nokia.</p>
<p>So should I wait for the N900+1? $649 is a lot to shell out for a device that is running on a platform that is being retired (&#8220;moved to community support&#8221;). Besides, I&#8217;m a Qt guy, not a Gtk wizard, and any programming I do with the device will most likely be with Qt. Will Maemo 6 be available for the N900? The N900 does not, as far as I can tell, have a multi-touch screen, which means it won&#8217;t be able to use Qt 4.6+&#8217;s multi-touch gesture support.</p>
<p>On the other hand, how much longer until a Maemo 6 device is released? Probably over a year from now. I also fear, perhaps without good reason, that Maemo 6 (and perhaps even Maemo 5 &#8212; I&#8217;ll find out later today when I try it out) will have some kind of new-age high-tech web-service-enabled interface that is going to be more difficult to use than my current old school phone. I dunno.</p>
<p>So what should I do? Go for the N900/Maemo5 if it looks decent, or wait who knows how long for the N900+1/Maemo6?</p>
<p><i>PS: What&#8217;s the story with <a href="http://qt.gitorious.org/maemo-6-ui-framework/framework-technical-preview/blobs/master/src/core/duiapplication.cpp">libdui</a> or DirectUI? I can&#8217;t find much about this online.</i></p>
<p><i>PPS: Is there a future relationship between Plasma and Maemo beyond <a href="http://www.kdedevelopers.org/node/4078">neat hacks</a>?</i></p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/202#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=202" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/202/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Facebook Google Account Linking</title>
		<link>http://blog.jasondonenfeld.com/196</link>
		<comments>http://blog.jasondonenfeld.com/196#comments</comments>
		<pubDate>Tue, 06 Oct 2009 18:56:44 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[Gentoo]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Privacy]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=196</guid>
		<description><![CDATA[Facebook allows linking with my Google account so that I only have to sign into GMail to access my Facebook. Wonderful:

Except that once I try to initiate the linking, Google warns me that Facebook will have access to all of my contacts, which includes everyone I&#8217;ve ever e-mailed:

What&#8217;s the deal? I can&#8217;t find any information [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/196#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=196" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p>Facebook allows linking with my Google account so that I only have to sign into GMail to access my Facebook. Wonderful:<br />
<a href="http://blog.jasondonenfeld.com/wp-content/uploads/2009/10/facebook-link-2.png"><img src="http://blog.jasondonenfeld.com/wp-content/uploads/2009/10/facebook-link-2-450x96.png" alt="Link Google to Facebook" title="Link Google to Facebook" width="450" height="96" class="aligncenter size-medium wp-image-197" /></a><br />
Except that once I try to initiate the linking, Google warns me that Facebook will have access to all of my contacts, which includes everyone I&#8217;ve ever e-mailed:<br />
<a href="http://blog.jasondonenfeld.com/wp-content/uploads/2009/10/facebook-link.png"><img src="http://blog.jasondonenfeld.com/wp-content/uploads/2009/10/facebook-link.png" alt="Facebook wants Google contacts" title="Facebook wants Google contacts" width="379" height="447" class="aligncenter size-full wp-image-200" /></a><br />
What&#8217;s the deal? I can&#8217;t find any information about what Facebook does with this info, or if they store it, nor any privacy info about it. Why does Facebook even request this information from Google? I&#8217;d use this feature, but this is unacceptable.</p>
<p>Anyone know what&#8217;s up?</p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/196#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=196" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/196/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fast Compositing with KDE4 and FGLRX</title>
		<link>http://blog.jasondonenfeld.com/190</link>
		<comments>http://blog.jasondonenfeld.com/190#comments</comments>
		<pubDate>Tue, 08 Sep 2009 03:30:34 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ATI]]></category>
		<category><![CDATA[Gentoo]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[KWin]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=190</guid>
		<description><![CDATA[After a much heated discussion about how to fix the horrible resizing and performance bug with FGLRX and KDE4, no one knew where to start looking. The X team had to do a little digging; the KDE4 team needed to change somethings; the FGLRX warehouse needed to get their shit together and listen to the [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/190#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=190" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p>After a <a href="http://blog.jasondonenfeld.com/169">much heated discussion</a> about how to fix the horrible resizing and performance bug with FGLRX and KDE4, no one knew where to start looking. The X team had to do a little digging; the KDE4 team needed to change somethings; the FGLRX warehouse needed to get their shit together and listen to the users&#8230; bla bla bla the flame wars raged on, fingers were pointed, and nothing ever got done.</p>
<p>That is, nothing got done until a lone user piped up with a workaround. Here is what he wrote in the <a href="http://blog.jasondonenfeld.com/169#comment-404">comments</a> of that blog post:</p>
<blockquote><p>Hi, I have been pissed off by this problem a long time and assumed it was ATI’s fault. Tonight I made one last effort before ordering a Nvidia graphics card. And I was successful.</p>
<p>I am running catalyst 9.8 using a Radeon 3850 and have had this re-size/maximize problem as long as long as I have used KDE4. To solve the problem I needed to modify a file in xorg-server. in the code directory it is called ./composite/compalloc.c. Here I commented out most of a function called compNewPixmap. Everything below these lines:</p>
<p>pPixmap->screen_x = x;<br />
pPixmap->screen_y = y;</p>
<p>all the way down to (but not including) the last line:</p>
<p>return pPixmap;</p>
<p>After this I am running KDE4 with all desktop effects that I want and without any lag in resizing/maximizing.<br />
I am running Gentoo, so I just updated the xorg-server source package file and put it back into the source repository, rebuilt the manifest and emerged it again. Voila!</p></blockquote>
<p>Voila indeed. The patch he&#8217;s talking about looks like this (thanks to <a href="http://razum2um.alwaysdata.net/2009/09/08/fglrx-na-gentoo/">this Russian blog I can&#8217;t read</a>):</p>

<div class="wp_syntax"><div class="code"><pre class="diff" style="font-family:monospace;">--- composite/compalloc.c.orig  <span style="">2009</span>-09-08 02:<span style="">54</span>:<span style="">28.657143479</span> +0700                              
<span style="color: #888822;">+++ composite/compalloc.c       <span style="">2009</span>-09-08 02:<span style="">55</span>:<span style="">42.835357653</span> +0700                              </span>
<span style="color: #440088;">@@ -<span style="">484</span>,<span style="">64</span> +<span style="">484</span>,<span style="">6</span> @@                                                                             </span>
     pPixmap-&gt;screen_x = x;                                                                      
     pPixmap-&gt;screen_y = y;                                                                      
&nbsp;
<span style="color: #991111;">-    if <span style="">&#40;</span>pParent-&gt;drawable.depth == pWin-&gt;drawable.depth<span style="">&#41;</span>                                        </span>
<span style="color: #991111;">-    <span style="">&#123;</span>                                                                                           </span>
<span style="color: #991111;">-       GCPtr   pGC = GetScratchGC <span style="">&#40;</span>pWin-&gt;drawable.depth, pScreen<span style="">&#41;</span>;                              </span>
<span style="color: #991111;">-                                                                                                </span>
<span style="color: #991111;">-       /*                                                                                       </span>
<span style="color: #991111;">-        * Copy bits from the parent into the new pixmap so that it will                         </span>
<span style="color: #991111;">-        * have &quot;reasonable&quot; contents in case for background None areas.                         </span>
<span style="color: #991111;">-        */                                                                                      </span>
<span style="color: #991111;">-       if <span style="">&#40;</span>pGC<span style="">&#41;</span>                                                                                 </span>
<span style="color: #991111;">-       <span style="">&#123;</span>                                                                                        </span>
<span style="color: #991111;">-           XID val = IncludeInferiors;                                                          </span>
<span style="color: #991111;">-                                                                                                </span>
<span style="color: #991111;">-           ValidateGC<span style="">&#40;</span>&amp;pPixmap-&gt;drawable, pGC<span style="">&#41;</span>;                                                 </span>
<span style="color: #991111;">-           dixChangeGC <span style="">&#40;</span>serverClient, pGC, GCSubwindowMode, &amp;val, NULL<span style="">&#41;</span>;                        </span>
<span style="color: #991111;">-           <span style="">&#40;</span>*pGC-&gt;ops-&gt;CopyArea<span style="">&#41;</span> <span style="">&#40;</span>&amp;pParent-&gt;drawable,                                           </span>
<span style="color: #991111;">-                                  &amp;pPixmap-&gt;drawable,                                           </span>
<span style="color: #991111;">-                                  pGC,                                                          </span>
<span style="color: #991111;">-                                  x - pParent-&gt;drawable.x,                                      </span>
<span style="color: #991111;">-                                  y - pParent-&gt;drawable.y,                                      </span>
<span style="color: #991111;">-                                  w, h, <span style="">0</span>, <span style="">0</span><span style="">&#41;</span>;                                                  </span>
<span style="color: #991111;">-           FreeScratchGC <span style="">&#40;</span>pGC<span style="">&#41;</span>;                                                                 </span>
<span style="color: #991111;">-       <span style="">&#125;</span>                                                                                        </span>
<span style="color: #991111;">-    <span style="">&#125;</span>                                                                                           </span>
<span style="color: #991111;">-    else                                                                                        </span>
<span style="color: #991111;">-    <span style="">&#123;</span>                                                                                           </span>
<span style="color: #991111;">-       PictFormatPtr   pSrcFormat = compWindowFormat <span style="">&#40;</span>pParent<span style="">&#41;</span>;                                 </span>
<span style="color: #991111;">-       PictFormatPtr   pDstFormat = compWindowFormat <span style="">&#40;</span>pWin<span style="">&#41;</span>;                                    </span>
<span style="color: #991111;">-       XID             inferiors = IncludeInferiors;                                            </span>
<span style="color: #991111;">-       int             error;                                                                   </span>
<span style="color: #991111;">-                                                                                                </span>
<span style="color: #991111;">-       PicturePtr      pSrcPicture = CreatePicture <span style="">&#40;</span>None,                                       </span>
<span style="color: #991111;">-                                                    &amp;pParent-&gt;drawable,                         </span>
<span style="color: #991111;">-                                                    pSrcFormat,                                 </span>
<span style="color: #991111;">-                                                    CPSubwindowMode,                            </span>
<span style="color: #991111;">-                                                    &amp;inferiors,                                 </span>
<span style="color: #991111;">-                                                    serverClient, &amp;error<span style="">&#41;</span>;                      </span>
<span style="color: #991111;">-                                                                                                </span>
<span style="color: #991111;">-       PicturePtr      pDstPicture = CreatePicture <span style="">&#40;</span>None,                                       </span>
<span style="color: #991111;">-                                                    &amp;pPixmap-&gt;drawable,                         </span>
<span style="color: #991111;">-                                                    pDstFormat,</span>
<span style="color: #991111;">-                                                    <span style="">0</span>, <span style="">0</span>,</span>
<span style="color: #991111;">-                                                    serverClient, &amp;error<span style="">&#41;</span>;</span>
<span style="color: #991111;">-</span>
<span style="color: #991111;">-       if <span style="">&#40;</span>pSrcPicture &amp;&amp; pDstPicture<span style="">&#41;</span></span>
<span style="color: #991111;">-       <span style="">&#123;</span></span>
<span style="color: #991111;">-           CompositePicture <span style="">&#40;</span>PictOpSrc,</span>
<span style="color: #991111;">-                             pSrcPicture,</span>
<span style="color: #991111;">-                             NULL,</span>
<span style="color: #991111;">-                             pDstPicture,</span>
<span style="color: #991111;">-                             x - pParent-&gt;drawable.x,</span>
<span style="color: #991111;">-                             y - pParent-&gt;drawable.y,</span>
<span style="color: #991111;">-                             <span style="">0</span>, <span style="">0</span>, <span style="">0</span>, <span style="">0</span>, w, h<span style="">&#41;</span>;</span>
<span style="color: #991111;">-       <span style="">&#125;</span></span>
<span style="color: #991111;">-       if <span style="">&#40;</span>pSrcPicture<span style="">&#41;</span></span>
<span style="color: #991111;">-           FreePicture <span style="">&#40;</span>pSrcPicture, <span style="">0</span><span style="">&#41;</span>;</span>
<span style="color: #991111;">-       if <span style="">&#40;</span>pDstPicture<span style="">&#41;</span></span>
<span style="color: #991111;">-           FreePicture <span style="">&#40;</span>pDstPicture, <span style="">0</span><span style="">&#41;</span>;</span>
<span style="color: #991111;">-    <span style="">&#125;</span></span>
     return pPixmap;
 <span style="">&#125;</span></pre></div></div>

<p>This patch works like a charm. All of the FGLRX resizing/maximizing bugs disappear. Not only that, but things like clicking on the K menu are suddenly a lot faster&#8230; KDE4 doesn&#8217;t seem laggy and now has the performance I&#8217;ve expected all along. The effects look great, and my transparent terminal is a delight.</p>
<p>There is, however, a bit of garbage that shows up occasionally, and perhaps there&#8217;s a good use for the code that was removed in the patch. Why is it only FGLRX that benefits from removing this code? I don&#8217;t know much about XOrg internals, but I&#8217;m guessing it has to do with some sort of sometimes-required allocation that causes a readback in the FGLRX driver but not in other drivers. What&#8217;s the deal? Is fixing this problem as simple as committing this patch and then fixing the garbage error? Or is the code that was removed necessary, and really the problem lays with FGLRX? What to do at this point?</p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/190#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=190" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/190/feed</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>PulseAudio Foray</title>
		<link>http://blog.jasondonenfeld.com/188</link>
		<comments>http://blog.jasondonenfeld.com/188#comments</comments>
		<pubDate>Fri, 28 Aug 2009 19:03:03 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Gentoo]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[PulseAudio]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=188</guid>
		<description><![CDATA[I&#8217;ve taken then plunge: I just installed PulseAudio (PA) and related tools (on Gentoo). A lot of users are vehemently anti, stating numerous complications and bugs, but its potential advantages for networked audio are attractive.
Evidently KMix is supposed to support PA, but it still only shows the alsa devices. I suspect this is related to [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/188#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=188" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve taken then plunge: I just installed PulseAudio (PA) and related tools (on <a href="http://en.gentoo-wiki.com/wiki/PulseAudio">Gentoo</a>). A lot of users are vehemently anti, stating numerous complications and bugs, but its potential advantages for networked audio are attractive.</p>
<p>Evidently KMix is supposed to support PA, but it still only shows the alsa devices. I suspect this is related to when PA is loaded, and currently I do not have any user-space loader. What&#8217;s the optimal way for this to happen in KDE? An autostart entry? Symlinking some mysterious file to kde&#8217;s env directory? All the forum posts are for older KDE versions. Phonon works so far though. All the PA apps are GTK/GConf based, and aren&#8217;t very KDE friendly, and generally it seems like KDE has neglected PA support, or PA has neglected KDE support. They simply aren&#8217;t very pretty together. What are the plans for integrating KDE and PA a little bit more closely?</p>
<p>I&#8217;m using a Macbook as a print server, printing to it from my Linux box, and everything is simple because they both use CUPS. However, I&#8217;m having a bit of trouble streaming audio to it. I can&#8217;t seem to build PA on OSX, and I don&#8217;t even think OSX is officially supported by PA. <a href="http://community.livejournal.com/evan_tech/241887.html">I tried installing ESD using MacPorts and using PA&#8217;s bridge for that</a>, but it played a half a second of sound before skipping. ESD doesn&#8217;t do good latency calculations. PA supports streaming to Airport Express, so I thought I&#8217;d try out Airfoil Speakers, but unfortunately, <a href="http://getsatisfaction.com/rogueamoeba/topics/native_implementation_in_pulseaudio">Airfoil uses a different protocol</a>. So I&#8217;m not sure what to do now&#8230; How do I send PA to my Macbook?</p>
<p>PA also doesn&#8217;t work well with Skype, and I anticipate some other problems as well. What a hassle. Why the bad integration with KDE? Why the numerous bugs? Any PA tips from veteran readers?</p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/188#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=188" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/188/feed</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Subtitler in Qt</title>
		<link>http://blog.jasondonenfeld.com/179</link>
		<comments>http://blog.jasondonenfeld.com/179#comments</comments>
		<pubDate>Thu, 13 Aug 2009 18:29:43 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[AnyClip]]></category>
		<category><![CDATA[Gentoo]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[Qt]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=179</guid>
		<description><![CDATA[A certain company needed a way to easily get text-based subtitle files in a batch fashion. The DVDs were available for ripping such subtitles, but the necessary OCR work proved too time-consuming and cumbersome, even with solutions like SubRip. So, I figured that 1000s of individuals on the Internet already gladly spend their days OCRing [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/179#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=179" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p>A certain company needed a way to easily get text-based subtitle files in a batch fashion. The DVDs were available for ripping such subtitles, but the necessary OCR work proved too time-consuming and cumbersome, even with solutions like SubRip. So, I figured that 1000s of individuals on the Internet already gladly spend their days OCRing DVD subtitles into text formats, and sure enough databases like <a href="http://subscene.com" target="_blank">Subscene</a> exist. So, I built a program to wrap Subscene&#8217;s web interface, and what better way to do this is there than <a href="http://doc.trolltech.com/qtwebkit.html">QtWebKit</a>?</p>
<p><a href="http://blog.jasondonenfeld.com/wp-content/uploads/2009/08/subtitler1.jpg"><img src="http://blog.jasondonenfeld.com/wp-content/uploads/2009/08/subtitler1-450x374.jpg" alt="Subtitler&#039;s Subscene Interface" title="Subtitler&#039;s Subscene Interface" width="450" height="374" class="aligncenter size-medium wp-image-180" /></a></p>
<p>I capture the downloads by using QtWebKit&#8217;s <a href="http://doc.trolltech.com/qwebpage.html#unsupportedContent">unsupportedContent</a> signal and parse the downloads by using QNetworkAccessManager&#8217;s <a href="http://doc.trolltech.com/qnetworkaccessmanager.html#finished">finished</a> signal. I then run the zip archive through <a href="http://doc.trolltech.com/solutions/4/qtiocompressor/qtiocompressor.html">QtIOCompressor</a>&#8217;s code for unzipping zips, then extract and parse the subtitles. </p>
<p>A significant issue is that a lot of the subtitles on Subscene are from torrents that have videos which are cut off at the beginning. The solution is to shift each subtitle in the file by a constant time interval if neccessary, so I built an interface to easily see and shift timing:</p>
<p><a href="http://blog.jasondonenfeld.com/wp-content/uploads/2009/08/subtitler2.jpg"><img src="http://blog.jasondonenfeld.com/wp-content/uploads/2009/08/subtitler2-450x374.jpg" alt="Subtitler&#039;s Preview Interface" title="Subtitler&#039;s Preview Interface" width="450" height="374" class="aligncenter size-medium wp-image-181" /></a></p>
<p>As you can see, it&#8217;s possible to shift all the subtitles. Phonon made this page a breeze. One significant challenge was writing a search algorithm that would find the correct Subtitle based on a time falling in a certain range. It needed to be super speedy and designed for sequential searches. I came up with the following, which could use a bit of improvement:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="code"><pre class="cpp-qt" style="font-family:monospace;"><span style="color: #22aadd;">QString</span> SubtitleParser<span style="color: #006E28;">::</span><span style="color: #2B74C7;">subtitleAtTime</span><span style="color: #006E28;">&#40;</span>quint64 <span style="color: #2B74C7;">time</span><span style="color: #006E28;">&#41;</span>
<span style="color: #006E28;">&#123;</span>
	<span style="color: #22aadd;">QLinkedList</span><span style="color: #006E28;">&lt;</span>Subtitle<span style="color: #006E28;">&gt;::</span><span style="color: #2B74C7;">const_iterator</span> i<span style="color: #006E28;">;</span>
	<span style="color: #0057AE;">bool</span> forward <span style="color: #006E28;">=</span> true<span style="color: #006E28;">;</span>
	<span style="color: #000000; font-weight:bold;">for</span> <span style="color: #006E28;">&#40;</span>i <span style="color: #006E28;">=</span> m_searchPosition<span style="color: #006E28;">;</span> i <span style="color: #006E28;">!=</span> m_subtitles.<span style="color: #2B74C7;">constEnd</span><span style="color: #006E28;">&#40;</span><span style="color: #006E28;">&#41;</span><span style="color: #006E28;">;</span> <span style="color: #006E28;">&#41;</span> <span style="color: #006E28;">&#123;</span>
		<span style="color: #000000; font-weight:bold;">if</span> <span style="color: #006E28;">&#40;</span>i<span style="color: #006E28;">-&gt;</span><span style="color: #2B74C7;">isContainedIn</span><span style="color: #006E28;">&#40;</span><span style="color: #2B74C7;">time</span><span style="color: #006E28;">&#41;</span><span style="color: #006E28;">&#41;</span> <span style="color: #006E28;">&#123;</span>
			m_searchPosition <span style="color: #006E28;">=</span> i<span style="color: #006E28;">;</span>
			<span style="color: #000000; font-weight:bold;">return</span> i<span style="color: #006E28;">-&gt;</span><span style="color: #2B74C7;">text</span><span style="color: #006E28;">&#40;</span><span style="color: #006E28;">&#41;</span><span style="color: #006E28;">;</span>
		<span style="color: #006E28;">&#125;</span>
		<span style="color: #000000; font-weight:bold;">if</span> <span style="color: #006E28;">&#40;</span>i<span style="color: #006E28;">-&gt;</span><span style="color: #2B74C7;">isAfter</span><span style="color: #006E28;">&#40;</span><span style="color: #2B74C7;">time</span><span style="color: #006E28;">&#41;</span><span style="color: #006E28;">&#41;</span> <span style="color: #006E28;">&#123;</span>
			<span style="color: #000000; font-weight:bold;">if</span> <span style="color: #006E28;">&#40;</span>i <span style="color: #006E28;">==</span> m_subtitles.<span style="color: #2B74C7;">constBegin</span><span style="color: #006E28;">&#40;</span><span style="color: #006E28;">&#41;</span><span style="color: #006E28;">&#41;</span>
				break<span style="color: #006E28;">;</span>
			<span style="color: #006E28;">--</span>i<span style="color: #006E28;">;</span>
			forward <span style="color: #006E28;">=</span> false<span style="color: #006E28;">;</span>
		<span style="color: #006E28;">&#125;</span> <span style="color: #000000; font-weight:bold;">else</span> <span style="color: #006E28;">&#123;</span>
			<span style="color: #000000; font-weight:bold;">if</span> <span style="color: #006E28;">&#40;</span><span style="color: #006E28;">!</span>forward<span style="color: #006E28;">&#41;</span>
				break<span style="color: #006E28;">;</span>
			<span style="color: #006E28;">++</span>i<span style="color: #006E28;">;</span>
		<span style="color: #006E28;">&#125;</span>
	<span style="color: #006E28;">&#125;</span>
	<span style="color: #000000; font-weight:bold;">return</span> <span style="color: #22aadd;">QString</span><span style="color: #006E28;">&#40;</span><span style="color: #BF0303;">' '</span><span style="color: #006E28;">&#41;</span><span style="color: #006E28;">;</span>
<span style="color: #006E28;">&#125;</span></pre></td></tr></table></div>

<p>Another challenge was dealing with <a href="http://doc.trolltech.com/qwizard.html">QWizard</a> and <a href="http://doc.trolltech.com/qwizardpage.html">QWizardPage</a>, particularly issues with <a href="http://doc.trolltech.com/4.5/qwizardpage.html#registerField">fields</a> and custom buttons. The field/property system is just too cumbersome to work with; there ought to be a better way of establishing centralized data with straight up pointers. The buttons on QWizard all want to be global, so adding a custom button to a single page proved a bit hackish. It&#8217;s a cool API, but just a little bit limiting. If anyone has some suggestions, let me know.</p>
<p><strong>As always, the code is available on <a href="http://git.zx2c4.com/?p=subtitler.git;a=tree">my gitweb</a>, and I encourage you to try it out, read the code, and send me suggestions in the comments below.</strong></p>
<p>Though this was designed to work on Linux, Qt, being delightfully cross-platform, also makes it possible to run the Subtitler on OSX. Check out the OSX screencast:<br />
<object width="445" height="364"><param name="movie" value="http://www.youtube-nocookie.com/v/z7uib2DsoUw&#038;hl=en&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube-nocookie.com/v/z7uib2DsoUw&#038;hl=en&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="445" height="364"></embed></object><br />
<a href="http://www.youtube.com/watch?v=z7uib2DsoUw" target="_blank">Direct YouTube Link</a></p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/179#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=179" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/179/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Slow Window Resizing with KWin Compositing on FGLRX</title>
		<link>http://blog.jasondonenfeld.com/169</link>
		<comments>http://blog.jasondonenfeld.com/169#comments</comments>
		<pubDate>Mon, 03 Aug 2009 03:20:56 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ATI]]></category>
		<category><![CDATA[Gentoo]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[KWin]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=169</guid>
		<description><![CDATA[Update: check out this solution.
Amongst users of the proprietary ATI driver (FGLRX), it&#8217;s a well known problem that KDE4&#8217;s KWin&#8217;s desktop effects are unusable due to turtle slow window resizing. Unfortunately, bug reports and forum posts fail to come up with a clear answer as to why this happens, who is responsibility for fixing it, [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/169#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=169" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p><b>Update</b>: check out <a href="http://blog.jasondonenfeld.com/190">this solution</a>.</p>
<p>Amongst users of the proprietary ATI driver (FGLRX), it&#8217;s a well known problem that KDE4&#8217;s KWin&#8217;s desktop effects are unusable due to turtle slow window resizing. Unfortunately, bug reports and forum posts fail to come up with a clear answer as to why this happens, who is responsibility for fixing it, and which parts of the stack need to adapt for the bug. If you&#8217;re not already familiar with the problem, observe:</p>
<p><object width="445" height="364"><param name="movie" value="http://www.youtube-nocookie.com/v/UCUBMRCoXVI&#038;hl=en&#038;fs=1&#038;rel=0&#038;color1=0x234900&#038;color2=0x4e9e00&#038;border=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube-nocookie.com/v/UCUBMRCoXVI&#038;hl=en&#038;fs=1&#038;rel=0&#038;color1=0x234900&#038;color2=0x4e9e00&#038;border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="445" height="364"></embed></object><br />
<a href="http://www.youtube.com/watch?v=UCUBMRCoXVI" target="_blank">Direct YouTube Link</a></p>
<p>As you can see, the three second delay in window resizing, maximizing, and (perhaps) restoring makes compositing-enabled KWin unusable. Note that the problem still persists when disabling the &#8220;show window content while resizing&#8221; option.</p>
<p>It&#8217;s been particularly difficult to track down the route of this problem and who should be fixing it. From <a href="http://www.phoronix.com/forums/showthread.php?t=15163">a lengthy discussion on Phoronix&#8217;s Forums</a>, ATI&#8217;s &#8220;Bridgman&#8221; user acknowledges the problem but claims &#8220;It&#8217;s not a driver issue AFAIK, so not sure why we would mention it in the release notes.&#8221; He goes on to indicate that the problem was introduced during a hack to ensure KWin compatibility on Intel cards, to work around a glitch with garbage appearing on the screen, and a lengthy debate over the &#8220;107_fedora_dont_backfill_bg_none.patch&#8221; patch. Somewhere the stack was patched to support Intel cards at the expense of ATI cards, according to ATI&#8217;s &#8220;Bridgman&#8221;. </p>
<p>Over on the KDE bugzilla, we&#8217;re met with a <a href="http://bugs.kde.org/show_bug.cgi?id=165011#c14">curt response from the KWin team</a>: &#8220;Driver bug then.&#8221; The bug is marked as &#8220;RESOLVED&#8221; and &#8220;UPSTREAM&#8221;.</p>
<p>And elsewhere on the Internet, we get a helpless string of &#8220;still not fixed&#8221; messages, over on the <a href="http://ati.cchtml.com/show_bug.cgi?id=1426">unofficial FGLRX bugzilla</a>, <a href="http://www.phoronix.com/forums/showthread.php?t=14848">other Phoronix forum posts</a>, and <a href="http://bbs.archlinux.org/viewtopic.php?id=59315">distro forums</a>.</p>
<p>So I ask my readers: who is responsible for this bug and how will it be fixed? If indeed it is neither FGLRX nor KWin and the problem exists in XOrg, why has XOrg been patched to support Intel cards at the expense of ATI cards? Is there anything FGLRX or KWin could be doing to mitigate the problem? Potential workarounds? Users have complained of this problem for over a year now perhaps, but not once has leadership from anywhere offered a compelling explanation or plan for the future. What to do?</p>
<p><a href="http://blog.jasondonenfeld.com/169#respond">Leave comments</a>. The current discussion seems to be fruitful.</p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/169#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=169" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/169/feed</wfw:commentRss>
		<slash:comments>45</slash:comments>
		</item>
		<item>
		<title>AnyClip for Boxee</title>
		<link>http://blog.jasondonenfeld.com/163</link>
		<comments>http://blog.jasondonenfeld.com/163#comments</comments>
		<pubDate>Tue, 16 Jun 2009 23:22:46 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[AnyClip]]></category>
		<category><![CDATA[KDE]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=163</guid>
		<description><![CDATA[I&#8217;ve been working for AnyClip on a Boxee application. Corporate explanation:
AnyClip will launch later this year as a comprehensive library of legally-licensed scenes from Hollywood movies. While we’re still in active negotiations with the rights holders of the films, this preview-only Boxee application begins to show the potential behind tying such a powerful platform to [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/163#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=163" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working for <a href="http://www.anyclip.com">AnyClip</a> on a <a href="http://www.boxee.tv">Boxee</a> <a href="http://blog.boxee.tv/2009/06/15/anyclip-on-boxee/">application</a>. Corporate explanation:</p>
<blockquote><p>AnyClip will launch later this year as a comprehensive library of legally-licensed scenes from Hollywood movies. While we’re still in active negotiations with the rights holders of the films, this preview-only Boxee application begins to show the potential behind tying such a powerful platform to applications like Boxee. Ultimately, applications like AnyClip for Boxee will enable people to relive any moment, from any film, on any platform.</p></blockquote>
<p>I submitted it to the Boxee <a href="http://blog.boxee.tv/2009/06/15/vote-for-your-favorite-apps-rsvp-for-the-boxee-event-in-sf/">Dev Challenge</a>, and polls are open for voting. <b>Please vote for AnyClip <a href="http://poll.fm/10ma7">here</a></b>.</p>
<p><a href="http://blog.jasondonenfeld.com/wp-content/uploads/2009/06/AnyClipBoxeeApp.png"><img src="http://blog.jasondonenfeld.com/wp-content/uploads/2009/06/AnyClipBoxeeApp-450x281.png" alt="AnyClip for Boxee" title="AnyClip for Boxee" width="450" height="281" class="aligncenter size-medium wp-image-164" /></a></p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/163#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=163" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/163/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Alternate Amarok 2.1 Layouts</title>
		<link>http://blog.jasondonenfeld.com/153</link>
		<comments>http://blog.jasondonenfeld.com/153#comments</comments>
		<pubDate>Mon, 13 Apr 2009 21:18:31 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Amarok]]></category>
		<category><![CDATA[KDE]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=153</guid>
		<description><![CDATA[For those of you who long for the old Amarok 1.4 two-column layout, it is now possible to sort of simulate this behavior in Amarok 2.1 by careful dragging of splitters and customization of the playlist:

It is also (nearly) possible to emulate the layout of Juk, iTunes, Banshee, or Rhythmbox:

<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/153#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=153" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p>For those of you who long for the old Amarok 1.4 two-column layout, it is now possible to sort of simulate this behavior in Amarok 2.1 by careful dragging of splitters and customization of the playlist:<br />
<a href="http://blog.jasondonenfeld.com/wp-content/uploads/2009/04/old-amarok-layout.png"><img src="http://blog.jasondonenfeld.com/wp-content/uploads/2009/04/old-amarok-layout-450x288.png" alt="Layout of Amarok 1.4 with Amarok 2" title="Layout of Amarok 1.4 with Amarok 2" width="450" height="288" class="aligncenter size-medium wp-image-155" /></a></p>
<p>It is also (nearly) possible to emulate the layout of Juk, iTunes, Banshee, or Rhythmbox:<br />
<a href="http://blog.jasondonenfeld.com/wp-content/uploads/2009/04/amarok-itunes-layout.png"><img src="http://blog.jasondonenfeld.com/wp-content/uploads/2009/04/amarok-itunes-layout-450x306.png" alt="Amarok 2 Can Look Like Juk, iTunes, Banshee, or Rhythmbox... sort of" title="Amarok 2 Can Look Like Juk, iTunes, Banshee, or Rhythmbox... sort of" width="450" height="306" class="aligncenter size-medium wp-image-154" /></a></p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/153#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=153" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/153/feed</wfw:commentRss>
		<slash:comments>30</slash:comments>
		</item>
		<item>
		<title>Amarok Scriptable Service for ZX2C4 Music</title>
		<link>http://blog.jasondonenfeld.com/125</link>
		<comments>http://blog.jasondonenfeld.com/125#comments</comments>
		<pubDate>Mon, 13 Apr 2009 03:40:14 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Amarok]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[ZX2C4 Music]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=125</guid>
		<description><![CDATA[As promised, I&#8217;ve written in under 100 lines of JavaScript (QtScript) a service for Amarok that plugs into ZX2C4 Music (ReadMe for ZX2C4 Music, Source for ZX2C4 Music). Obligatory screenshot:

The Amarok scripting API is very slick, especially the scripted services API.
It is not now configurable and is rather inefficient because getlisting.php does not support very [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/125#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=125" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p>As promised, I&#8217;ve written in under 100 lines of JavaScript (<a href="http://doc.trolltech.com/qtscript.html">QtScript</a>) a service for <a href="http://amarok.kde.org">Amarok</a> that plugs into <a href="http://blog.jasondonenfeld.com/14">ZX2C4 Music</a> (<a href="http://git.zx2c4.com/?p=zx2c4music.git;a=blob;f=README.txt">ReadMe for ZX2C4 Music</a>, <a href="http://git.zx2c4.com/?p=zx2c4music.git;a=snapshot;h=HEAD;sf=tgz">Source for ZX2C4 Music</a>). Obligatory screenshot:<br />
<a href="http://blog.jasondonenfeld.com/wp-content/uploads/2009/04/amarok-scriptable-service.jpg"><img src="http://blog.jasondonenfeld.com/wp-content/uploads/2009/04/amarok-scriptable-service-450x300.jpg" alt="Amarok Scriptable Service for ZX2C4 Music" title="Amarok Scriptable Service for ZX2C4 Music" width="450" height="300" class="aligncenter size-medium wp-image-130" /></a><br />
The Amarok <a href="http://amarok.kde.org/wiki/Development/Scripting_HowTo_2.0">scripting API</a> is very slick, especially the <a href="http://amarok.kde.org/wiki/Development/Scripted_Services_Tutorial_2.0">scripted services API</a>.</p>
<p>It is not now configurable and is rather inefficient because getlisting.php does not support very complex queries (though I do take advantage of its sorting on lines 54-57), but this will be changed by the time I release an installable version of the script. Currently, it downloads a listing of the entire collection during the first request (lines 27-33), and then just reads from an in-memory database (multidimensional array) to query the different levels (lines 34-95). TMI: too much iteration.</p>
<p>Unfortunately there are some kinks, as Phonon often has trouble playing URLs and does not always show buffering information correctly (both gstreamer and xine backends). Look at <a href="http://git.zx2c4.com/?p=zx2c4music.git;a=blob;f=getsong.php#l65">lines 65 and below of getsong.php</a>: this should be a working HTTP streaming implementation, but Phonon doesn&#8217;t dig it, for whatever reason. Any pointers here? The same issue crops up in the <a href="http://music.zx2c4.com/desktop/">standalone qt player</a> for ZX2C4 Music. Strange. Also, I use <a href="http://doc.trolltech.com/qtextdocument.html">QTextDocument</a> to convert HTML entities back to normal text (lines 14-22), but it&#8217;s very slow. Is there a better way to be doing this? Finally, callbackData (line 73) refuses to store an array, which means I have to use a nasty splitter; this is a bug presumably. </p>
<p>For the ZX2C4 Music hackers out there, here&#8217;s the source code to play with:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">Importer.<span style="color: #660066;">loadQtBinding</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;qt.core&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Importer.<span style="color: #660066;">loadQtBinding</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;qt.network&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Importer.<span style="color: #660066;">loadQtBinding</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;qt.gui&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> ZX2C4Music<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	ScriptableServiceScript.<span style="color: #660066;">call</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;ZX2C4 Music&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">3</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;Browse ZX2C4 Music&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;The entire ZX2C4 collection, at your finger tips.&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #003366; font-weight: bold;">var</span> songs <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> delayedArgs <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">function</span> receiveDatabase<span style="color: #009900;">&#40;</span>reply<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	songs <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">eval</span><span style="color: #009900;">&#40;</span>reply<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
	<span style="color: #003366; font-weight: bold;">var</span> decoder <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> QTextDocument<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> songs.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> j <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> j <span style="color: #339933;">&lt;</span> songs<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> j<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			decoder.<span style="color: #660066;">setHtml</span><span style="color: #009900;">&#40;</span>songs<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			songs<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> decoder.<span style="color: #660066;">toPlainText</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
	onPopulate<span style="color: #009900;">&#40;</span>delayedArgs<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> delayedArgs<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> delayedArgs<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #003366; font-weight: bold;">function</span> onPopulate<span style="color: #009900;">&#40;</span>level<span style="color: #339933;">,</span> callback<span style="color: #339933;">,</span> filter<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>songs <span style="color: #339933;">==</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		delayedArgs <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span>level<span style="color: #339933;">,</span> callback<span style="color: #339933;">,</span> filter<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
		<span style="color: #003366; font-weight: bold;">new</span> Downloader<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> QUrl<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;http://music.zx2c4.com/getlisting.php?username=TOP&amp;password=SECRET&amp;language=javascript&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> receiveDatabase<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		Amarok.<span style="color: #660066;">Window</span>.<span style="color: #660066;">Statusbar</span>.<span style="color: #660066;">shortMessage</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;ZX2C4 Music collection is loading...&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">return</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>level <span style="color: #339933;">==</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #003366; font-weight: bold;">var</span> splitCallback <span style="color: #339933;">=</span> callback.<span style="color: #660066;">split</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;&amp;*/ZX2C4MUSICSPLITTER/*&amp;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #003366; font-weight: bold;">var</span> notFirst <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> songs.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>songs<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">4</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> splitCallback<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;&amp;</span> songs<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">3</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> splitCallback<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#123;</span>
				notFirst <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
				<span style="color: #003366; font-weight: bold;">var</span> <span style="color: #000066; font-weight: bold;">item</span> <span style="color: #339933;">=</span> Amarok.<span style="color: #660066;">StreamItem</span><span style="color: #339933;">;</span>
				<span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">level</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
				<span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">itemName</span> <span style="color: #339933;">=</span> songs<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
				<span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">playableUrl</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;http://music.zx2c4.com/getsong.php?username=TOP&amp;password=SECRET&amp;transcode=false&amp;hash=&quot;</span> <span style="color: #339933;">+</span> songs<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
				<span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">album</span> <span style="color: #339933;">=</span> songs<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
				<span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">artist</span> <span style="color: #339933;">=</span> songs<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
				<span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">track</span> <span style="color: #339933;">=</span> songs<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
				<span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">infoHtml</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">;</span>
				<span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">callbackData</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">;</span>
				script.<span style="color: #660066;">insertItem</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
			<span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>notFirst<span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#123;</span>
				<span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>level <span style="color: #339933;">==</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #003366; font-weight: bold;">var</span> lastAlbum<span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> songs.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>callback <span style="color: #339933;">==</span> songs<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">4</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;&amp;</span> lastAlbum <span style="color: #339933;">!=</span> songs<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">3</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#123;</span>
				lastAlbum <span style="color: #339933;">=</span> songs<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
				<span style="color: #003366; font-weight: bold;">var</span> <span style="color: #000066; font-weight: bold;">item</span> <span style="color: #339933;">=</span> Amarok.<span style="color: #660066;">StreamItem</span><span style="color: #339933;">;</span>
				<span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">level</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
				<span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">itemName</span> <span style="color: #339933;">=</span> lastAlbum<span style="color: #339933;">;</span>
				<span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">playableUrl</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">;</span>
				<span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">infoHtml</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">;</span>
				<span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">callbackData</span> <span style="color: #339933;">=</span> callback <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;&amp;*/ZX2C4MUSICSPLITTER/*&amp;&quot;</span> <span style="color: #339933;">+</span> lastAlbum<span style="color: #339933;">;</span>
				script.<span style="color: #660066;">insertItem</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>level <span style="color: #339933;">==</span> <span style="color: #CC0000;">2</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #003366; font-weight: bold;">var</span> lastArtist<span style="color: #339933;">;</span>
		<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> songs.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>lastArtist <span style="color: #339933;">!=</span> songs<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">4</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
			<span style="color: #009900;">&#123;</span>
				lastArtist <span style="color: #339933;">=</span> songs<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
				<span style="color: #003366; font-weight: bold;">var</span> <span style="color: #000066; font-weight: bold;">item</span> <span style="color: #339933;">=</span> Amarok.<span style="color: #660066;">StreamItem</span><span style="color: #339933;">;</span>
				<span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">level</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">2</span><span style="color: #339933;">;</span>
				<span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">itemName</span> <span style="color: #339933;">=</span> lastArtist<span style="color: #339933;">;</span>
				<span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">playableUrl</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">;</span>
				<span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">infoHtml</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">;</span>
				<span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">callbackData</span> <span style="color: #339933;">=</span> lastArtist<span style="color: #339933;">;</span>
				script.<span style="color: #660066;">insertItem</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
	script.<span style="color: #660066;">donePopulating</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #003366; font-weight: bold;">var</span> script <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> ZX2C4Music<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
script.<span style="color: #660066;">populate</span>.<span style="color: #660066;">connect</span><span style="color: #009900;">&#40;</span>onPopulate<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/125#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=125" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/125/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>New York City KDE Group</title>
		<link>http://blog.jasondonenfeld.com/115</link>
		<comments>http://blog.jasondonenfeld.com/115#comments</comments>
		<pubDate>Fri, 10 Apr 2009 00:37:43 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[KDE]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=115</guid>
		<description><![CDATA[At our KDE 4.2 release party, many of you voiced desire to have more frequent NYC meetings to talk about all things KDE. So, what dates work for those of you still interested?
Update: Possibly this coming week we&#8217;ll meet. Anyone know of good coffee shops in Manhattan that have wifi? Or perhaps I can procure [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/115#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=115" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p>At our KDE 4.2 release party, many of you voiced desire to have more frequent NYC meetings to talk about all things KDE. So, what dates work for those of you still interested?</p>
<p><strong>Update</strong>: Possibly this coming week we&#8217;ll meet. Anyone know of good coffee shops in Manhattan that have wifi? Or perhaps I can procure a spot in a Columbia building&#8230;</p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/115#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=115" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/115/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Finding Freelance Jobs</title>
		<link>http://blog.jasondonenfeld.com/118</link>
		<comments>http://blog.jasondonenfeld.com/118#comments</comments>
		<pubDate>Wed, 08 Apr 2009 21:26:33 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[KDE]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=118</guid>
		<description><![CDATA[Dear PlanetKDE,
I&#8217;m just a student, but I can build just about anything with code. The problem is that people in the industry disregard me because I&#8217;m young. I also doesn&#8217;t have many &#8220;contacts&#8221; or &#8220;networks&#8221; for shmoozing up. I am, however, looking for a lucrative freelance coding job for this summer.
So I&#8217;m wondering &#8211; amongst [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/118#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=118" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p>Dear PlanetKDE,</p>
<p>I&#8217;m just a student, but I can build just about anything with code. The problem is that people in the industry disregard me because I&#8217;m young. I also doesn&#8217;t have many &#8220;contacts&#8221; or &#8220;networks&#8221; for shmoozing up. I am, however, looking for a lucrative freelance coding job for this summer.</p>
<p>So I&#8217;m wondering &#8211; amongst those of you who have been in a similar predicament, how have you gone about finding programming gigs?</p>
<p>A related question: does anybody hire KDE programmers? </p>
<p>Sincerely,<br />
Unemployed</p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/118#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=118" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/118/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>WebKit in Konqueror/KDE</title>
		<link>http://blog.jasondonenfeld.com/96</link>
		<comments>http://blog.jasondonenfeld.com/96#comments</comments>
		<pubDate>Wed, 18 Feb 2009 02:40:45 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[KDE]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=96</guid>
		<description><![CDATA[Dear PlanetKDE/Lazyweb,
I am curious about the future of KHTML in the face of WebKit. Three questions come to mind:

Why does KDE use KHTML when WebKit is faster, more compatible, etc?
Why does Konqueror use KHTML as default instead of WebKit?
Will KHTML be moved out of the main tree?

As far as I can see, it is commonly [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/96#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=96" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p>Dear PlanetKDE/Lazyweb,</p>
<p>I am curious about the future of KHTML in the face of WebKit. Three questions come to mind:</p>
<ol>
<li>Why does KDE use KHTML when WebKit is faster, more compatible, etc?</li>
<li>Why does Konqueror use KHTML as default instead of WebKit?</li>
<li>Will KHTML be moved out of the main tree?</li>
</ol>
<p>As far as I can see, it is commonly accepted fact that WebKit is a faster and more compatible engine than KHTML. WebKit was ported to Qt in 4.4, and Qt 4.5 provides some critical enhancements. From these two points, the three questions above naturally follow. If the situation for KHTML was completely hopeless, then it never would have made KDE 4.0 or the present API would be converted into a wrapper for QtWebKit. But this is not the case, so presumably the KHTML team has high hopes for the project. I wonder what the team&#8217;s response is to these questions. Undoubtedly they have thought a lot about KHTML vs WebKit and find WebKit a worthwhile project. What&#8217;s the deal?</p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/96#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=96" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/96/feed</wfw:commentRss>
		<slash:comments>57</slash:comments>
		</item>
		<item>
		<title>KDE 4.2 Release in New York City</title>
		<link>http://blog.jasondonenfeld.com/80</link>
		<comments>http://blog.jasondonenfeld.com/80#comments</comments>
		<pubDate>Sun, 25 Jan 2009 23:45:12 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[KDE]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=80</guid>
		<description><![CDATA[Anybody interested in some sort of NYC release event for 4.2? If so, leave a comment and maybe if there&#8217;s enough interest we&#8217;ll organize something.
Update:
There will be a KDE 4.2 release event at the Hungarian Pastry Shop on 1030 Amsterdam Avenue (between west 110th and 111th) at 8pm on January 28th. Visit wiki information.
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/80#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=80" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p>Anybody interested in some sort of NYC release event for 4.2? If so, leave a comment and maybe if there&#8217;s enough interest we&#8217;ll organize something.</p>
<p><b>Update:</b><br />
There will be a KDE 4.2 release event at <a href="http://maps.google.com/maps?f=q&#038;source=s_q&#038;hl=en&#038;geocode=&#038;q=1030+Amsterdam+Ave+(the+Hungarian+Pastry+Shop)&#038;sll=40.808222,-73.974552&#038;sspn=0.081986,0.127888&#038;ie=UTF8&#038;ll=40.804568,-73.962557&#038;spn=0.010249,0.015986&#038;z=16&#038;iwloc=r0">the Hungarian Pastry Shop on 1030 Amsterdam Avenue (between west 110th and 111th)</a> at <b>8pm</b> on <b>January 28th</b>. Visit <a href="http://wiki.kde.org/tiki-index.php?page=KDE+4.2+Release+Party#_United_States_New_York_NY">wiki information</a>.</p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/80#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=80" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/80/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Promised Bug Fixes</title>
		<link>http://blog.jasondonenfeld.com/67</link>
		<comments>http://blog.jasondonenfeld.com/67#comments</comments>
		<pubDate>Sun, 21 Dec 2008 11:59:00 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[ZX2C4 Music]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=67</guid>
		<description><![CDATA[I just fixed four major blockers in ZX2C4 Music. I also moved the source into a public git.
Prior to the fix, only one php page could load at a time. When requesting a second php page while one was loading, the request would hang until the previous one had completed. This is not terribly problematic [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/67#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=67" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p>I just fixed four major blockers in <a href="http://blog.jasondonenfeld.com/14">ZX2C4 Music</a>. I also moved the source into a <a href="http://git.zx2c4.com/?p=zx2c4music.git">public git</a>.</p>
<p>Prior to the fix, only one php page could load at a time. When requesting a second php page while one was loading, the request would hang until the previous one had completed. This is not terribly problematic for ordinary web pages, but because I use php for file downloads, the entire web app would hang until the file had completed downloading. Bad news bears. After a lot of difficult debugging, tcpdumps, header inspects, ps aux, etc, I discovered the problem to be with session_start(). It turns out that only one session can be opened for writing at a time per session cookie, which means for a single user, php will only allow pages to write to his session one at a time. The solution was to call session_write_close() immediately after editing the last $_SESSION variable.</p>
<p>Some media players had trouble seeking in streams from the php file streamer because of bad http header range support. The sendFile() is now HTTP/1.1 compliant. Although, I&#8217;d like to add some caching support at some point.</p>
<p>Finally, and most notably, ZX2C4 Music no longer hangs when loading giant lists. It now loads 50 items at a time, and polls the location of the scrollbar every 100 milliseconds, and if it is close to the bottom, it requests the next 50 items. Polling is not ideal, but JavaScript does not have scroll events for divs. The pagination is implemented using MySQL&#8217;s LIMIT and OFFSET features. The display code took quite a bit of reworking and might still be a little buggy. Do try it out. Internet Explorer requires a special case because of its lack of support for writing to tables&#8217; innerHTML, and Microsoft <a href="https://connect.microsoft.com/IE/feedback/ViewFeedback.aspx?FeedbackID=336254">refuses</a> <a href="http://webbugtrack.blogspot.com/2007/12/bug-210-no-innerhtml-support-on-tables.html">to</a> <a href="http://alexle.net/archives/150">fix</a> <a href="http://support.microsoft.com/kb/239832">it</a>. When adding an entire list to the download basket, it takes the time to download and display every item in the query, like the old behavior, and this may introduce some bugs. For the most part though, scrolling auto-pagination support is generally pretty slick.</p>
<p>The download basket/zip feature is no longer capped at 200 songs, as it no longer needs to call an external zip program and store the zip file temporarily. In pure php, I&#8217;ve written a custom on-the-fly zip file streamer, which works a lot faster.</p>
<p>As always, if you have suggestions, leave a comment below. If you&#8217;d like to download the latest HEAD of ZX2C4 Music, you can browse the repository <a href="http://git.zx2c4.com/?p=zx2c4music.git;a=summary">here</a> or download a tar of it <a href="http://git.zx2c4.com/?p=zx2c4music.git;a=snapshot;h=HEAD;sf=tgz">here</a>. Next on the list are HTML5 &lt;audio&gt; element support for web app streaming, Amarok plugin, update script, and maybe a revamped interface. </p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/67#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=67" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/67/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Auto-Sizing Columns</title>
		<link>http://blog.jasondonenfeld.com/35</link>
		<comments>http://blog.jasondonenfeld.com/35#comments</comments>
		<pubDate>Sat, 29 Nov 2008 05:19:52 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[ZX2C4 Music]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=35</guid>
		<description><![CDATA[Here&#8217;s a curious problem I&#8217;ve come across: There are N columns in a table of width W, with each column having content that requires a maximum width of M1, M2, M3, &#8230; , MN, where M1 + M2 + M3 + &#8230; + MN &#62; W. Find an optimal size, O1, O2, O3, &#8230; , [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/35#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=35" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a curious problem I&#8217;ve come across: There are N columns in a table of width W, with each column having content that requires a maximum width of M<sub>1</sub>, M<sub>2</sub>, M<sub>3</sub>, &#8230; , M<sub>N</sub>, where M<sub>1</sub> + M<sub>2</sub> + M<sub>3</sub> + &#8230; + M<sub>N</sub> &gt; W. Find an optimal size, O<sub>1</sub>, O<sub>2</sub>, O<sub>3</sub>, &#8230; , O<sub>N</sub>, for all columns in the table, where O<sub>1</sub> + O<sub>2</sub> + O<sub>3</sub> + &#8230; + O<sub>N</sub> = W, and where for all i between 1 and N, O<sub>i</sub> / W &le; R, where R is an arbitrary ratio less than 1 and greater than 0. That is to say, optimally sized means each O<sub>i</sub> / W = min(R, M<sub>i</sub> / (M<sub>1</sub> + M<sub>2</sub> + M<sub>3</sub> + &#8230; + M<sub>N</sub>)), but when the min function chooses its first argument, the extra space, ([second argument] &#8211; [first argument]) * W, needs to be proportionally distributed to the remaining O<sub>j</sub>, where j is between 1 and N and does not equal i, and where &#8220;proportionally&#8221; means related to the proportions of M<sub>j</sub> / (M<sub>1</sub> + M<sub>2</sub> + M<sub>3</sub> + &#8230; + M<sub>N</sub>). However, proportionally distributing this excess to the remaining columns may push a remaining column&#8217;s ratio over R, which means some of that excess might further have to be redistributed.</p>
<p>The iterative approach to this problem is easy, but I am interested in determining a non-iterative solution to finding all of the O<sub>i</sub>, where I simply have a formula O<sub>i</sub> = [yada yada yada].</p>
<p>Here&#8217;s code for the iterative solution when applied to columns of a <a  href="http://doc.trolltech.com/4.4/qtreeview.html">QTreeView</a>, with N = 3 and R = .42, which is derived from my <a href="http://git.zx2c4.com/?p=zmusicplayer.git;a=blob;f=AutoSizingList.cpp">AutoSizingList class</a> of <a href="http://blog.jasondonenfeld.com/14">ZMusicPlayer</a>. It uses QTreeView&#8217;s <a href="http://doc.trolltech.com/4.4/qtreeview.html#sizeHintForColumn">sizeHintForColumn</a> to determine M<sub>i</sub>.<br />
<a href="http://blog.jasondonenfeld.com/wp-content/uploads/2008/11/autosizelist.jpg"><img src="http://blog.jasondonenfeld.com/wp-content/uploads/2008/11/autosizelist.jpg" title="AutoSizingList" width="500" height="578" class="aligncenter size-full wp-image-40" /></a><br />
So essentially, the problem is that the do-while on lines 18 and 41 should be eliminated. It is required in the first place because when proportionally redistributing the difference between the arguments of the min function (outlined in the first paragraph), the ratios of the columns receiving this extra width may exceed R, which means another iteration must be done to readjust. Anyone have a non-iterative solution? Also, to the Qt experts out there, why is the hack required on line 49?</p>
<p>I am interested both in a practical Qt approach and a mathematical approach, the latter being more interesting. Doesn&#8217;t this seem like functionality that aught to already be a part of Qt?</p>
<p><i><b>Update:</b> A conversation with a friend over AIM has produced a plain-English explanation in the form of a dialogue of the above problem.</i></p>
<div style="font-size: 7pt; font-family: monospace;">Jason: so you&#8217;re drawing a table<br />
Jason: on a piece of paper<br />
Jason: making all the lines and rows<br />
Jason: so this table happens to have 3 columns<br />
Jason: and a bunch of rows<br />
Jason: make sense?<br />
Pasternak: yes<br />
Jason: ok<br />
Jason: now each cell of the table is supposed to have some information in it<br />
Jason: different length information takes up more width in the table<br />
Jason: Rob Pasternak takes up more room than Yi Chan, for example<br />
Jason: it&#8217;s wider<br />
Jason: it has more characters<br />
Jason: right?<br />
Pasternak: yes<br />
Jason: now say that the biggest piece of data in the first column requires a width M1, the biggest in the second column requires a width M2, and in the third, M3<br />
Jason: Rob Pasternak, Yi Chan, and Salvadora Manello Envelopa Dali<br />
Jason: are the biggest pieces of data for each of the three columns respectively<br />
Pasternak: ok<br />
Jason: now let&#8217;s say you&#8217;re writing down your table on a napkin<br />
Jason: so you can only make it a certain width<br />
Jason: because the napkin is small<br />
Jason: and you&#8217;re bad at writing with tiny handwriting<br />
Pasternak: ok<br />
Jason: so you think to yourself &#8220;well, i will just make each column have its width be in the same proportion to the tiny width of the entire table as if i had tons of room to draw the table and was able to make each column have the width equal to the column&#8217;s biggest name&#8221;<br />
Jason: make sense?<br />
Pasternak: ok<br />
Pasternak: yes<br />
Jason: so a simple equation for finding how big each column would be would just to do this<br />
Jason: column1 = ( M1 / (M1 + M2 + M3) ) * tinyNapkinWidth<br />
Jason: right?<br />
Jason: and similarly for columns 2 and 3<br />
Pasternak: yeah<br />
Jason: ok so lets say you do that and then you notice that<br />
Jason: Salvadora Manello Envelopa Dali is taking up way too much space on the table<br />
Jason: so much so that the other two columns are too tiny to show any relevant information<br />
Pasternak: but i thought you said<br />
Pasternak: because each of those were the maximum<br />
Pasternak: oh wait<br />
Pasternak: i gotcha<br />
Pasternak: cause the napkin is too small to make Chan visible at the right proportions<br />
Jason: yeah<br />
Jason: even though it&#8217;s all perfectly proportioned,<br />
Pasternak: yeah<br />
Jason: Salvadora Manello Envelopa Dali is just so big that<br />
Jason: he makes Chan tiny<br />
Jason: so you think to yourself<br />
Jason: &#8220;how about i impose a maximum ratio each column may take up. I hereby declare that no column may use more than 40% of the entire width!&#8221;<br />
Jason: so, you apply the first process of column1 = ( M1 / (M1 + M2 + M3) ) * tinyNapkinWidth etc<br />
Jason: but then you say something like<br />
Jason: &#8220;if column1 is greater than 40% of tinyNapkinWidth, make column1 equal to 40% of tinyNapkinWidth&#8221;<br />
Jason: with me?<br />
Pasternak: yes<br />
Jason: so then what are you going to do with that excess width you cut off of column1?<br />
Jason: it has to go somewhere<br />
Jason: since we want to use all of the napkin width<br />
Jason: so you distribute it to the other two columns proportionally<br />
Jason: not half to one and half to the other, but in a proportion equal to the amount of data they contain<br />
Jason: seem reasonable?<br />
Pasternak: yeah but then one of them could go over 40<br />
Jason: exactly!<br />
Jason: that&#8217;s the problem<br />
Jason: so then you do the process all over again<br />
Jason: asking &#8220;does any column exceed 40%?&#8221;<br />
Jason: over and over until it&#8217;s perfect<br />
Jason: this is the iterative method<br />
Jason: i want to figure out an expression of column1,2,3 that is as simple as our original one of &#8220;column1 = ( M1 / (M1 + M2 + M3) ) * tinyNapkinWidth&#8221; but that takes into consideration our 40% restriction<br />
Jason: and doesn&#8217;t rely on iteration<br />
Pasternak: for any number of columns i assume<br />
Jason: yeah<br />
Jason: right</div>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/35#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=35" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/35/feed</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>ZX2C4 Music 0.1 Release</title>
		<link>http://blog.jasondonenfeld.com/33</link>
		<comments>http://blog.jasondonenfeld.com/33#comments</comments>
		<pubDate>Fri, 28 Nov 2008 02:32:04 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[ZX2C4 Music]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=33</guid>
		<description><![CDATA[This post is a follow up to Introducing ZX2C4 Music.
Update: source code available here.
I have just finished generalizing aspects of ZX2C4 Music so that it&#8217;s installable on a variety of different servers. I have no experience with releasing PHP apps to the general public, so I&#8217;d appreciate some feedback on the installation process. You can [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/33#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=33" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p><b>This post is a follow up to <a href="http://blog.jasondonenfeld.com/14">Introducing ZX2C4 Music</a>.</b></p>
<p><i>Update: source code available <a href="http://git.zx2c4.com/?p=zx2c4music.git;a=snapshot;h=HEAD;sf=tgz">here</a>.</i></p>
<p>I have just finished generalizing aspects of <a href="http://blog.jasondonenfeld.com/14">ZX2C4 Music</a> so that it&#8217;s installable on a variety of different servers. I have no experience with releasing PHP apps to the general public, so I&#8217;d appreciate some feedback on the installation process. You can download the tarball <a href="http://music.zx2c4.com/ZX2C4Music-0.1.tar.gz">here</a>. Be sure to read README.txt.</p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/33#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=33" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/33/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Introducing ZX2C4 Music</title>
		<link>http://blog.jasondonenfeld.com/14</link>
		<comments>http://blog.jasondonenfeld.com/14#comments</comments>
		<pubDate>Sat, 25 Oct 2008 02:24:48 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[ZX2C4 Music]]></category>

		<guid isPermaLink="false">http://blog.jasondonenfeld.com/?p=14</guid>
		<description><![CDATA[Update: source code available here.
A few months ago I switched website hosts from Netfirms to Site5, because Site5 had a good deal for a plan with unlimited bandwidth and disk space. The first thing I did was upload my entire music collection.
To access all of my music remotely via any internet-connected web browser, I wrote [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/14#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=14" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p><i>Update: source code available <a href="http://git.zx2c4.com/?p=zx2c4music.git;a=snapshot;h=HEAD;sf=tgz">here</a>.</i></p>
<p>A few months ago I switched website hosts from <a href="http://netfirms.com">Netfirms</a> to <a href="http://www.site5.com/in.php?id=58673">Site5</a>, because Site5 had a good deal for a plan with unlimited bandwidth and disk space. The first thing I did was upload my entire music collection.</p>
<p>To access all of my music remotely via any internet-connected web browser, I wrote <a href="http://music.zx2c4.com">ZX2C4 Music</a>, which is password protected to avoid <i>the law</i>, but if you&#8217;d like to view <i>the interface</i> just for curiosity, ask me in the comments section, and I&#8217;ll e-mail you a password. It uses PHP/MySQL for managing the music, hashing each file with an sha1, <a href="http://developer.kde.org/~wheeler/taglib.html">TagLib</a> for reading tags, and JavaScript/HTML as an interface:<br />
<a href="http://blog.jasondonenfeld.com/wp-content/uploads/2008/10/zx2c4music.jpg"><img src="http://blog.jasondonenfeld.com/wp-content/uploads/2008/10/zx2c4music-450x272.jpg" alt="" title="ZX2C4 Music" width="450" height="272" class="aligncenter size-medium wp-image-15" /></a><br />
Search queries are done with AJAX, and playing is done with Flash, if available; otherwise it defaults to browser plug-ins. Soon I should add HTML5&#8217;s <a href="http://www.w3schools.com/tags/html5_audio.asp">&lt;audio&gt; element</a> support. Since Flash only supports MP3, the php backend optionally transcodes non-mp3 songs on the fly by using <a href="http://ffmpeg.mplayerhq.hu/">ffmpeg</a>. Songs can be downloaded in zipped bundles by using the download basket feature. The web interface still needs some work, most notably scrolling-pagination for the song table, but it&#8217;s definitely usable. Many have pointed my attention to <a href="http://ampache.org/">Ampache</a>, but I found it too big and overwhelming. You can view the source code <a href="http://music.zx2c4.com/source.php">here</a>.</p>
<p>Of course, the next step was writing a Qt or KDE application that interfaces directly with the web backend using <a href="http://en.wikipedia.org/wiki/Phonon_(KDE)">Phonon</a>. Meet <a href="http://music.zx2c4.com/desktop">ZMusicPlayer</a>:<br />
<a href="http://music.zx2c4.com/desktop"><img src="http://blog.jasondonenfeld.com/wp-content/uploads/2008/10/zmusicplayer_streaming.png" alt="" title="ZMusicPlayer" width="500" height="463" class="aligncenter size-full wp-image-16" /></a><br />
It downloads and displays a compressed and sorted xml listing of all the songs and their sha1s. The columns of the list automatically size optimally using an <a href="http://git.zx2c4.com/?p=zmusicplayer.git;a=blob;f=AutoSizingList.cpp;hb=HEAD">awesome algorithm</a> that still needs some tweaking (why is subtracting 40 required on line 87?). Suggestions?</p>
<p>It plays the songs by passing the appropriate QUrl to Phonon, and this is where the trouble begins. The xine backend on KDE 4.1.2 just skips one song to another most of the time, and when it does miraculously play, seeking (via HTTP partial requests) is unavailable. The headers for each of the server responses for song file requests provide the appropriate parameters for HTTP seeking. Maybe this has already been fixed in trunk, but if not, I aught to investigate the problem as soon as I switch my 4.1.2 desktop completely to trunk. GStreamer with Qt 4.4 allows for proper streaming if a GStreamer HTTP plug-in is installed (gst-plugins-good includes a wrapper plugin for libsoup, which works, for those who don&#8217;t want to install the gnome vfs plugin), which is understandable. However, seeking only works for mp3 files; m4a files play but cannot seek, even though the pertinent response headers are the same for both file types. On the Windows backend, the seeking situation is hopeless, and on the OS X backend, songs do not play at all. Also, xine is the only one that emits the proper buffering signals. On some setups though, some of these problems go away. I still need to do some more thorough debugging.</p>
<p>If you&#8217;d like to download and build ZMusicPlayer, you can <a href="http://git.zx2c4.com/?p=zmusicplayer.git;a=tree">browse</a> the source, clone the repository with <code>git clone http://git.zx2c4.com/zmusicplayer.git</code>, or download a <a href="http://git.zx2c4.com/?p=zmusicplayer.git;a=snapshot;h=HEAD;sf=tgz">tarball</a>. Depending on your package setup, you may have to tinker with the includes for the phonon headers. I&#8217;d love to hear some suggestions, so leave comments below. Once I stabilize the Qt code, I&#8217;d like to develop some optional KDE extensions, particularly integration with the KDE&#8217;s keyboard shortcuts.</p>
<p>Also: I&#8217;ve switched from blogging on kdedevelopers.org to my own Wordpress blog so that anyone can post comments without requiring an approved account. So, comment away. If you wanted to comment on my first post, but were unable to, you can now comment <a href="http://blog.jasondonenfeld.com/4#comments">here</a>. To comment on this post, use the link below.</p>
<p><b>Update Oct 25, 3:31pm</b>: Several of you have e-mailed me to say that the browser hangs when loading a unfiltered giant collection. This is indeed the case, as no current browser is able to write 10,000 rows to a table in a reasonable amount of time. This is why above I speak of &#8220;scrolling-pagination&#8221;, which means that the table would load 100 or so rows at a time, and then auto-populate the remaining rows in 100 row increments every time the user scrolled to near the end. </p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/14#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=14" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/14/feed</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>That large mass has a tractor beam! That&#8217;s not a planet&#8230; that&#8217;s a deathsta&#8211;. Oh, that&#8217;s planetKDE.</title>
		<link>http://blog.jasondonenfeld.com/4</link>
		<comments>http://blog.jasondonenfeld.com/4#comments</comments>
		<pubDate>Fri, 24 Oct 2008 04:42:03 +0000</pubDate>
		<dc:creator>Jason Donenfeld</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[KDE]]></category>

		<guid isPermaLink="false">3722 at http://www.kdedevelopers.org</guid>
		<description><![CDATA[I&#8217;ve been watching the development of KDE for a while, submitting bug reports and testing trunk, and last night I made my first patch. I received an svn account and decided to start working on Amarok 2, for which I&#8217;m currently fixing this bug. But I also intend to work on other areas of KDE, [...]<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/4#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=4" width="100" height="15" style="border:0;" /></a></div>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been watching the development of KDE for a while, submitting bug reports and testing trunk, and last night I made my first <a href="http://websvn.kde.org/?view=rev&amp;revision=875009">patch</a>. I received an svn account and decided to start working on Amarok 2, for which I&#8217;m currently fixing <a href="https://bugs.kde.org/show_bug.cgi?id=173341">this bug</a>. But I also intend to work on other areas of KDE, after I poke around for a while and learn the general layout of the project. Suggestions? To begin, I think I might start investigating <a href="http://bugs.kde.org/show_bug.cgi?id=168154">this bug</a>. I also work on the <a href="http://www.arora-browser.org">Arora Browser</a>.</p>
<p>Speaking of projects, to learn more about Qt&#8217;s painting system, I wrote a program that generates the <a href="http://en.wikipedia.org/wiki/Sierpi%C5%84ski_triangle">Sierpiński triangle</a> using a <a href="http://en.wikipedia.org/wiki/Chaos_game">chaos game</a>. Pick three vertices of a triangle. Plot a point at random inside that triangle. Choose a vertex of the triangle at random and plot the midpoint between the chosen vertex and the previous point plotted. Repeat this ad infinitum and you get:<br />
<a href="http://blog.jasondonenfeld.com/wp-content/uploads/2008/10/fractal.jpg"><img src="http://blog.jasondonenfeld.com/wp-content/uploads/2008/10/fractal-450x441.jpg" alt="" title="Triangle Fractal Chaos Screenshot" width="450" height="441" class="aligncenter size-medium wp-image-9" /></a><br />
I don&#8217;t think that I&#8217;ve implemented the drawing in the most ideal way, so please leave suggestions. I opted to use a QImage instead of a QPainter, and then just fill pixels and scale. You can <a href="http://git.zx2c4.com/?p=trianglefractalchaos.git;a=tree">browse</a> the source, checkout the repository with <code>git clone http://git.zx2c4.com/trianglefractalchaos.git</code>, or download a <a href="http://git.zx2c4.com/?p=trianglefractalchaos.git;a=snapshot;h=HEAD;sf=tgz">tarball</a>.</p>
<p>Currently I&#8217;m running 4.1.2, but I plan to switch completely over to trunk in the next few weeks. Here&#8217;s my default clean desktop:<br />
<a href="http://blog.jasondonenfeld.com/wp-content/uploads/2008/10/desktop_with_notes.png"><img src="http://blog.jasondonenfeld.com/wp-content/uploads/2008/10/desktop_with_notes-450x281.png" alt="" title="Default KDE Desktop with Notes" width="450" height="281" class="aligncenter size-medium wp-image-10" /></a><br />
The large note on the left is about a few ideas for a shared-server-plan based file sharing mini-network. Maybe I&#8217;ll say more on this another time if I end up implementing it.</p>
<p>Hello planetKDE.</p>
<div class="tantan-getcomments"><a href="http://blog.jasondonenfeld.com/4#comments"><img src="http://blog.jasondonenfeld.com/wp-content/plugins/tantan/get-comments.php?p=4" width="100" height="15" style="border:0;" /></a></div>]]></content:encoded>
			<wfw:commentRss>http://blog.jasondonenfeld.com/4/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
