<?xml version="1.0" encoding="utf-8" ?>

<rss version="2.0" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/"
   >
<channel>
    <title>WaveSpace - Software</title>
    <link>http://wavespace.info/</link>
    <description>Guy Mac's Personal Blog</description>
    <dc:language>en</dc:language>
    <generator>Serendipity 1.0.3 - http://www.s9y.org/</generator>
    <pubDate>Sun, 22 Mar 2009 23:59:30 GMT</pubDate>

    <image>
        <url>http://wavespace.info/templates/default/img/s9y_banner_small.png</url>
        <title>RSS: WaveSpace - Software - Guy Mac's Personal Blog</title>
        <link>http://wavespace.info/</link>
        <width>100</width>
        <height>21</height>
    </image>

<item>
    <title>You Have A Hack</title>
    <link>http://wavespace.info/archives/311-You-Have-A-Hack.html</link>
            <category>Software</category>
    
    <comments>http://wavespace.info/archives/311-You-Have-A-Hack.html#comments</comments>
    <wfw:comment>http://wavespace.info/wfwcomment.php?cid=311</wfw:comment>

    <slash:comments>1</slash:comments>
    <wfw:commentRss>http://wavespace.info/rss.php?version=2.0&amp;type=comments&amp;cid=311</wfw:commentRss>
    

    <author>nospam@example.com (Guy McArthur)</author>
    <content:encoded>
    &lt;p&gt;I&#039;ve spent my evenings this week tracking down a website hack. It&#039;s not on this server, but on another some friends and I maintain. A message came in on the trouble ticket system, &quot;you have a hack&quot;. Someone had noticed pages full of links to &quot;blue pill&quot; sites stuck up on our site. I volunteered to look into it. I&#039;ve had to do this sort of forensic/detective work a few times in the past; it&#039;s pretty fun and challenging.
&lt;/p&gt;
&lt;p&gt;The first clue was that the files were all owned by the web server process, indicating a high likelihood that a vulnerability in the web site had been exploited (as opposed to some other type of hack masquerading as a web sploit). The second clue was that there was a zip file, plus all the files had the same timestamp, indicating that they were extracted from the zip (versus uploaded individually). That meant that the hacker had been able to execute code on our server. Arbitrary code execution is a severe vulnerability, it means the hacker can pretty much do anything (limited only by the privileges of the web server process). 
&lt;/p&gt;
&lt;p&gt;This all pointed to &lt;a href=&quot;http://php.net/&quot;&gt;PHP&lt;/a&gt;. There&#039;s a ton of PHP code on this system. PHP itself was notoriously crackable early on, but by about age ten they&#039;d rooted out all the major security flaws (it&#039;s still a case study in how not to design, or grow, a programming language). But since PHP has such a low barrier to entry, the code that web programmers write with it is often flawed.&lt;/p&gt;
&lt;p&gt;We&#039;re using third-party software like mediawiki (wiki system), vbulletin (forums), gallery (images) and wordpress (blogging). Some of those have a pretty bad track record, and I&#039;m looking at wordpress when I say that. And there&#039;s a variety of WP vintages on this system. But there&#039;s also a lot of custom code written by people I don&#039;t even know, with a variety of skill and attention to security concerns. But there&#039;s also some legacy Perl CGI code, some of it written by me, that could be at fault....
&lt;/p&gt; &lt;br /&gt;&lt;a href=&quot;http://wavespace.info/archives/311-You-Have-A-Hack.html#extended&quot;&gt;Continue reading &quot;You Have A Hack&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Thu, 19 Mar 2009 22:39:27 -0400</pubDate>
    <guid isPermaLink="false">http://wavespace.info/archives/311-guid.html</guid>
    
</item>
<item>
    <title>Quicktime In KDE3</title>
    <link>http://wavespace.info/archives/306-Quicktime-In-KDE3.html</link>
            <category>Software</category>
    
    <comments>http://wavespace.info/archives/306-Quicktime-In-KDE3.html#comments</comments>
    <wfw:comment>http://wavespace.info/wfwcomment.php?cid=306</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://wavespace.info/rss.php?version=2.0&amp;type=comments&amp;cid=306</wfw:commentRss>
    

    <author>nospam@example.com (Guy McArthur)</author>
    <content:encoded>
    &lt;p&gt;The problem: &lt;a href=&quot;http://trailers.apple.com/&quot;&gt;Apple movie trailers&lt;/a&gt; won&#039;t play on your KDE3 Linux web browser (such as Firefox on Kubuntu 8.04). The solution: get the &lt;a href=&quot;https://launchpad.net/ubuntu/hardy/i386/mozilla-mplayer/3.55-1ubuntu1~hardy1&quot;&gt;backport of mozilla-mplayer&lt;/a&gt;. Of course, you could upgrade to the latest Kubuntu, 8.10, but then you&#039;re forced to switch to the KDE 4 desktop, and I&#039;m not going there... yet (maybe in a few more releases).
&lt;/p&gt;
&lt;p&gt;Figuring out the problem took a little while, viewing the source of a typical trailer page and digging around in the JavaScript. Google searches turned up sub-optimal solutions. The issue turns out to be a browser detection JavaScript that Apple is using, and the fact that the older version of the mozilla-mplayer plugin advertises itself as quicktime &quot;6 / 7&quot; compatible (the script needs to see &quot;7&quot; as the first character).
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Fri, 06 Feb 2009 00:19:28 -0500</pubDate>
    <guid isPermaLink="false">http://wavespace.info/archives/306-guid.html</guid>
    
</item>
<item>
    <title>Firefox Steps Up</title>
    <link>http://wavespace.info/archives/295-Firefox-Steps-Up.html</link>
            <category>Software</category>
    
    <comments>http://wavespace.info/archives/295-Firefox-Steps-Up.html#comments</comments>
    <wfw:comment>http://wavespace.info/wfwcomment.php?cid=295</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://wavespace.info/rss.php?version=2.0&amp;type=comments&amp;cid=295</wfw:commentRss>
    

    <author>nospam@example.com (Guy McArthur)</author>
    <content:encoded>
    &lt;p&gt;A new browser release (Firefox 3.1 beta 2), big whoop, right? But Firefox is charging ahead, leading the way to a better web. Here&#039;s some of the new features that will be important to web designers, developers and even the average surfer.
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Embedded fonts and text-shadowing styles. Maybe designers will finally stop rendering text in images? I won&#039;t hold my breath, but it&#039;s nice to know the capability is there.&lt;/li&gt;
&lt;li&gt;Inline, in-browser audio and video without plugins (part of the HTML5 spec), using the free/open Ogg format. I suspect Apple and Microsoft will &quot;embrace and extend&quot; this, but it could mean that finally, finally (after a decade or more) there will be at least one video format that all platforms support.&lt;/li&gt;
&lt;li&gt;Support for &lt;tt&gt;n-th child&lt;/tt&gt; CSS selectors, a cleaner way to do things like render table rows with alternating colors (I can&#039;t tell you how many times I&#039;ve inserted a new row and had to change all the &quot;evens&quot; to &quot;odd&quot; and vice versa).&lt;/li&gt;
&lt;li&gt;A new, even faster JavaScript JIT compiler/interpreter (the one in 3.0 was itself a big improvement). Also a threading capability for JavaScript. This will enable smoother running, more fully-featured web applications.&lt;/li&gt;
&lt;li&gt;Geolocation, now you can grant sites permission to use/track your location. (Uh, might want to be careful with that one).&lt;/li&gt;
&lt;li&gt;Better security for AJAX (cross-site authorization control) and a JSON parse method, a secure way to load data and prevent code injection.&lt;/li&gt;
&lt;li&gt;Switchable &#039;private browsing&#039; mode... which they suggest is useful for hiding your online xmas shopping from your spouse (!).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
There&#039;s more, that&#039;s just the stuff that seemed significant to me. I think Safari and Internet Explorer are working on, or already have implemented, some of this stuff, and there&#039;s a new Opera browser in the works too. This reminds me of the long-lost days of yore, when browser competition fostered innovation. This difference this time is that they all seem committed to common baseline standards.
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Wed, 10 Dec 2008 00:21:32 -0500</pubDate>
    <guid isPermaLink="false">http://wavespace.info/archives/295-guid.html</guid>
    
</item>
<item>
    <title>There Is Only XUL</title>
    <link>http://wavespace.info/archives/288-There-Is-Only-XUL.html</link>
            <category>Software</category>
    
    <comments>http://wavespace.info/archives/288-There-Is-Only-XUL.html#comments</comments>
    <wfw:comment>http://wavespace.info/wfwcomment.php?cid=288</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://wavespace.info/rss.php?version=2.0&amp;type=comments&amp;cid=288</wfw:commentRss>
    

    <author>nospam@example.com (Guy McArthur)</author>
    <content:encoded>
    &lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en/XUL_Reference&quot;&gt;XUL&lt;/a&gt; is an application framework from Mozilla (Firefox and Thunderbird are XUL applications with C++ extensions). I recently learned that you can &lt;a href=&quot;http://developer.mozilla.org/En/Code_snippets:Running_applications&quot;&gt;run command-line programs&lt;/a&gt; from within script sections of XUL, which makes it significantly more useful for me. Of course, there are security restrictions; the XUL file needs to load from a local file (or be signed).
&lt;/p&gt;
&lt;p&gt;What I really like about it is that the UI is declarative, you can just type it up, preview it in the browser and hit reload to see changes. With the error console and other developer tools, you can use the same development tools and techniques from the web. Add the flexibility of JavaScript and you&#039;ve got a really powerful base. There are some issues with particular 3rd party JavaScript libraries (such as jQuery), but it&#039;s not a big stumbling block.
&lt;/p&gt;
&lt;p&gt;Here is a toy application, yet another Twitter client. You&#039;d run it with (for instance) &lt;tt&gt;firefox -chrome test.xul&lt;/tt&gt;. If it executed commands, it would need a line that said &lt;tt&gt;netscape.security.PrivilegeManager.enablePrivilege (&quot;UniversalXPConnect&quot;);&lt;/tt&gt; (the example does output with AJAX instead).&lt;/p&gt;
&lt;pre&gt;
&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;&amp;lt;?xml&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; version=&quot;1.0&quot;&lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;&amp;lt;?xml-stylesheet&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; href=&quot;chrome://global/skin/&quot; type=&quot;text/css&quot;&lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;?&amp;gt;&lt;/span&gt;

&lt;span style=&quot;font-style: italic;color: #808080;&quot;&gt;&amp;lt;!--&lt;/span&gt;

&lt;span style=&quot;font-style: italic;color: #808080;&quot;&gt;    Twitter updater implemented in XUL&lt;/span&gt;

&lt;span style=&quot;font-style: italic;color: #808080;&quot;&gt;--&amp;gt;&lt;/span&gt;
&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;&amp;lt;window&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;    id=&lt;/span&gt;&lt;span style=&quot;color: #aa0000;&quot;&gt;&quot;win&quot;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;    title=&lt;/span&gt;&lt;span style=&quot;color: #aa0000;&quot;&gt;&quot;XUL Twitter&quot;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;    orient=&lt;/span&gt;&lt;span style=&quot;color: #aa0000;&quot;&gt;&quot;vertical&quot;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;    xmlns=&lt;/span&gt;&lt;span style=&quot;color: #aa0000;&quot;&gt;&quot;http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul&quot;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;    onload=&lt;/span&gt;&lt;span style=&quot;color: #aa0000;&quot;&gt;&quot;updateLabel()&quot;&lt;/span&gt;
&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; max = &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;140&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; uid = &lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;guymac&#039;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; pwd = &lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;******&#039;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; twitUpdate = &lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;http://twitter.com/statuses/update.xml&#039;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; twitCloser = &lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;http://twitter.com/account/end_session&#039;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;;&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; updateLabel()&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        {&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; lbl = &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;document&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.getElementById(&lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;lbl&#039;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;);&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; txt = &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;document&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.getElementById(&lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;txt&#039;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;);&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; rem = max - txt.textLength;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            lbl.textContent = rem + &lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt; char&#039;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; + (rem &amp;gt; &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; ? &lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;s&#039;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; : &lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;&#039;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; ) + &lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt; remaining&#039;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            txt.disabled = !(rem &amp;gt;= &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;);&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        }&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;function&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; postTweet()&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        {&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; lbl = &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;document&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.getElementById(&lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;lbl&#039;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;);&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;try&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            {&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;                &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; req = &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; XMLHttpRequest();&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;                req.&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;open&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&quot;POST&quot;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, twitUpdate, &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, uid, pwd);&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;                req.setRequestHeader(&lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;Content-Type&#039;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;application/x-www-form-urlencoded&#039;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;);&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;                req.send(&lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;status=&#039;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; + &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;document&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.getElementById(&lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;txt&#039;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;);&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;                &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; (req.&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;status&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; != &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;200&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;throw&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; req.statusText;&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;                lbl.textContent = &lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;Twitter Updated!&#039;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            }&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;catch&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; (ex)&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            {&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;                lbl.textContent = &lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;Update failed (&#039;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; + ex + &lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&#039;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;; &lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            }&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;  req = &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; XMLHttpRequest();&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            req.&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;open&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&quot;GET&quot;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, twitCloser, &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, uid, pwd);&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            req.send(null);&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        }&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;&amp;lt;textbox&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;        id=&lt;/span&gt;&lt;span style=&quot;color: #aa0000;&quot;&gt;&quot;txt&quot;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;        maxlength=&lt;/span&gt;&lt;span style=&quot;color: #aa0000;&quot;&gt;&quot;140&quot;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;        size=&lt;/span&gt;&lt;span style=&quot;color: #aa0000;&quot;&gt;&quot;140&quot;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;        multiline=&lt;/span&gt;&lt;span style=&quot;color: #aa0000;&quot;&gt;&quot;true&quot;&lt;/span&gt;
&lt;span style=&quot;color: #008000;&quot;&gt;        oninput=&lt;/span&gt;&lt;span style=&quot;color: #aa0000;&quot;&gt;&quot;updateLabel()&quot;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;/&amp;gt;&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;&amp;lt;label&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt; id=&lt;/span&gt;&lt;span style=&quot;color: #aa0000;&quot;&gt;&quot;lbl&quot;&lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;/&amp;gt;&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;&amp;lt;hbox&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;&amp;lt;button&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt; label=&lt;/span&gt;&lt;span style=&quot;color: #aa0000;&quot;&gt;&quot;Post&quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt; oncommand=&lt;/span&gt;&lt;span style=&quot;color: #aa0000;&quot;&gt;&quot;postTweet()&quot;&lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;&amp;lt;button&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt; label=&lt;/span&gt;&lt;span style=&quot;color: #aa0000;&quot;&gt;&quot;Close&quot;&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt; oncommand=&lt;/span&gt;&lt;span style=&quot;color: #aa0000;&quot;&gt;&quot;window.close()&quot;&lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;&amp;lt;/hbox&amp;gt;&lt;/span&gt;

&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;&amp;lt;/window&amp;gt;&lt;/span&gt;
&lt;/pre&gt; 
    </content:encoded>

    <pubDate>Wed, 29 Oct 2008 21:43:45 -0400</pubDate>
    <guid isPermaLink="false">http://wavespace.info/archives/288-guid.html</guid>
    
</item>
<item>
    <title>A Python Twitter Widget</title>
    <link>http://wavespace.info/archives/271-A-Python-Twitter-Widget.html</link>
            <category>Software</category>
    
    <comments>http://wavespace.info/archives/271-A-Python-Twitter-Widget.html#comments</comments>
    <wfw:comment>http://wavespace.info/wfwcomment.php?cid=271</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://wavespace.info/rss.php?version=2.0&amp;type=comments&amp;cid=271</wfw:commentRss>
    

    <author>nospam@example.com (Guy McArthur)</author>
    <content:encoded>
    &lt;p&gt;A few weeks back, I posted a couple of &lt;a href=&quot;http://wavespace.info/archives/257-GUI-Shell-Scripts.html&quot;&gt;examples&lt;/a&gt; of trivial (but graphical) Twitter clients. Here&#039;s a slightly more featured example, which uses the PyQt library to hook into the powerful cross-platform &lt;a href=&quot;http://doc.trolltech.com/4.0/&quot;&gt;Qt&lt;/a&gt; toolkit from Python.
&lt;/p&gt;
&lt;img alt=&quot;PyQt4 Twitter Client&quot; src=&quot;http://wavespace.info/images/ptwitter.png&quot; style=&quot;align:left&quot;/&gt;
&lt;p&gt;Here&#039;s a screenshot. It shows how many characters you have remaining, and disables posting if the character count is over the limit. Below is the code. To run on a Debian system you&#039;d install the &lt;tt&gt;python-qt4&lt;/tt&gt; and &lt;tt&gt;python-httplib2&lt;/tt&gt; packages. I think it is a good example that for simple applications, the Python-Qt framework is pretty nice, though in lines of code, it would probably be about the same in Java (and probably less in JavaFX). Another nice thing is that you can put together the UI with &lt;a href=&quot;http://trolltech.com/products/qt/features/tools/designer&quot;&gt;Qt Designer&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;Zetcode&#039;s &lt;a href=&quot;http://zetcode.com/tutorials/pyqt4/&quot;&gt;PyQt4 tutorial&lt;/a&gt; and the official &lt;a href=&quot;http://www.riverbankcomputing.com/software/pyqt/intro&quot;&gt;PyQt documentation&lt;/a&gt; were indispensable.
&lt;/p&gt;
&lt;pre&gt;
&lt;span style=&quot;font-style: italic;color: #808080;&quot;&gt;#!/usr/bin/python&lt;/span&gt;

&lt;span style=&quot;color: #ff00ff;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; sys, urllib, httplib2&lt;/span&gt;
&lt;span style=&quot;color: #ff00ff;&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; PyQt4 &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; QtCore, QtGui&lt;/span&gt;

&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; PTwitter&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;QtGui.QWidget&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;):&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;max&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;140&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;    uid &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;guymac&#039;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;    pwd &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;********&#039;&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;    twitUpdate &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;http://twitter.com/statuses/update.xml&#039;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;    twitCloser &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;http://twitter.com/account/end_session&#039;&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; postTweet&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;):&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        mesg &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.txt.toPlainText&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;()&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        post &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; urllib.urlencode&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;({&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;status&#039;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; mesg &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;})&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;try&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;:&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            http &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; httplib2.Http&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;()&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;font-style: italic;color: #808080;&quot;&gt;# override the default (no exceptions, status in response)&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            http.force_exception_to_status_code &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;False&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;            http.add_credentials&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.uid, &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.pwd&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;            resp, content &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; http.request&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.twitUpdate, &lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;POST&#039;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, post&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; resp &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;and&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; resp.status &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;200&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;:&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;                &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.lbl.setText&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;Twitter updated!&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;:&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;                &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;raise&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; httplib2.HttpLib2Error, &lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;No response&#039;&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;except&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; httplib2.HttpLib2Error, ex&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;:&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; ex&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.lbl.setText&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ex.__str__&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;())&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;        http.request&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.twitCloser&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; updateLabel&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;):&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.txt.toPlainText&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.size&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;()&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.lbl.setText&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;%d&lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt; char(s) remaining&#039;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;max&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;))&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;font-style: italic;color: #808080;&quot;&gt;# disable the post button if chars &amp;gt; max&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.pb1.setEnabled&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;max&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; __init__&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;):&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        QtGui.QWidget.__init__&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;font-style: italic;color: #808080;&quot;&gt;# Button to post&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.pb1 &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; QtGui.QPushButton&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;Post&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;font-style: italic;color: #808080;&quot;&gt;# Button to close&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.pb2 &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; QtGui.QPushButton&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;Close&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;font-style: italic;color: #808080;&quot;&gt;# TextField for input&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.txt &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; QtGui.QTextEdit&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;()&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;font-style: italic;color: #808080;&quot;&gt;# Label to show characters remaining&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.lbl &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; QtGui.QLabel&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;()&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;        tab &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; QtGui.QGridLayout&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;()&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        tab.setSpacing&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;        tab.addWidget&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.txt, &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        tab.addWidget&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.lbl, &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        tab.addWidget&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.pb1, &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        tab.addWidget&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.pb2, &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.setLayout&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;tab&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.setWindowTitle&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;PyQt4 Twitter&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.updateLabel&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;()&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;font-style: italic;color: #808080;&quot;&gt;# connect text change to number of chars message&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.connect&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.txt, QtCore.SIGNAL&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;textChanged()&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;,&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.updateLabel&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;font-style: italic;color: #808080;&quot;&gt;# connect post click to send message&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.connect&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.pb1, QtCore.SIGNAL&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;clicked()&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;,&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.postTweet&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&lt;/span&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;font-style: italic;color: #808080;&quot;&gt;# connect close click to quit&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.connect&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.pb2, QtCore.SIGNAL&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;clicked()&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;,&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;            QtGui.qApp, QtCore.SLOT&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;quit()&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;))&lt;/span&gt;

&lt;span style=&quot;font-style: italic;color: #808080;&quot;&gt;# application&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;app &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; QtGui.QApplication&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;sys.argv&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&lt;/span&gt;

&lt;span style=&quot;font-style: italic;color: #808080;&quot;&gt;# window&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;win &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; PTwitter&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;()&lt;/span&gt;

&lt;span style=&quot;font-style: italic;color: #808080;&quot;&gt;# display&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;win.show&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;()&lt;/span&gt;

&lt;span style=&quot;font-style: italic;color: #808080;&quot;&gt;# execute&lt;/span&gt;
&lt;span style=&quot;color: #000000;&quot;&gt;sys.&lt;/span&gt;&lt;span style=&quot;color: #800000;&quot;&gt;exit&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;app.exec_&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;())&lt;/span&gt;
&lt;/pre&gt; 
    </content:encoded>

    <pubDate>Thu, 04 Sep 2008 00:12:04 -0400</pubDate>
    <guid isPermaLink="false">http://wavespace.info/archives/271-guid.html</guid>
    
</item>
<item>
    <title>Python and the Python Cookbook</title>
    <link>http://wavespace.info/archives/269-Python-and-the-Python-Cookbook.html</link>
            <category>Software</category>
    
    <comments>http://wavespace.info/archives/269-Python-and-the-Python-Cookbook.html#comments</comments>
    <wfw:comment>http://wavespace.info/wfwcomment.php?cid=269</wfw:comment>

    <slash:comments>12</slash:comments>
    <wfw:commentRss>http://wavespace.info/rss.php?version=2.0&amp;type=comments&amp;cid=269</wfw:commentRss>
    

    <author>nospam@example.com (Guy McArthur)</author>
    <content:encoded>
    &lt;p&gt;I&#039;m disappointed with O&#039;Reilly&#039;s &lt;a href=&quot;http://oreilly.com/catalog/9780596007973/&quot;&gt;&lt;i&gt;Python Cookbook (Second Edition)&lt;/i&gt;&lt;/a&gt;. It&#039;s unfortunate because I&#039;ve found their &quot;Cookbooks&quot; for other languages to be A) a good way to pick up the fundamentals while B) learn recipes for common programming tasks. The Python Cookbook skimps on the language fundamentals while, despite its huge bulk, having few recipes for task types that I can imagine needing to know.
&lt;/p&gt;
&lt;p&gt;For instance, there are no examples of an XPath API, which I&#039;d consider indispensable. One of the first things I wanted to do was take the Netflix Queue XHTML and simply extract the titles. I dug up &lt;a href=&quot;http://www.jroller.com/guymac/date/20041005&quot;&gt;some old Java code&lt;/a&gt; to do it.
&lt;/p&gt;
&lt;p&gt;The chapter on XML doesn&#039;t even have any examples of creating XML! And every Python example I&#039;ve seen so far does it by simply spitting out strings. Where are the equivalents of StAX, DOM, JDOM, or (wishful thinking) E4X?
&lt;/p&gt;
&lt;p&gt;I appreciate Python&#039;s attempt to be clean, consistent, and object-oriented... in marked contrast to Perl&#039;s hodge-podge gumbo of pre-OOP stuff like C, Bourne shell, and so on. But the OOP chapter is just bizarre, full of things that I&#039;ve never needed to worry about in Java.
&lt;/p&gt;
&lt;p&gt;The chapters on network and web programming don&#039;t show how to post to a web server or do authentication. The online &lt;a href=&quot;http://docs.python.org/lib/lib.html&quot;&gt;library reference&lt;/a&gt; is useful, but very short on complete examples. I could go on, but suffice it to say that without Google searches, I wouldn&#039;t have gotten very far with Python.
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Wed, 03 Sep 2008 23:04:33 -0400</pubDate>
    <guid isPermaLink="false">http://wavespace.info/archives/269-guid.html</guid>
    
</item>
<item>
    <title>What A Twit!</title>
    <link>http://wavespace.info/archives/265-What-A-Twit!.html</link>
            <category>Software</category>
    
    <comments>http://wavespace.info/archives/265-What-A-Twit!.html#comments</comments>
    <wfw:comment>http://wavespace.info/wfwcomment.php?cid=265</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://wavespace.info/rss.php?version=2.0&amp;type=comments&amp;cid=265</wfw:commentRss>
    

    <author>nospam@example.com (Guy McArthur)</author>
    <content:encoded>
    &lt;p&gt;So I figured out a &lt;a href=&quot;http://twitter.com/guymac&quot;&gt;reason to use twitter&lt;/a&gt;. No, not publishing random thoughts--anything worth a tweet is too infrequent. And not describing my daily whereabouts--there&#039;s little utility in that. What I&#039;m doing instead is a fitness activity log. Not that anyone will care, but it does a) provide me a log which is useful for training and b) give some extra motivation vis-&amp;#224;-vis the mere possibility that my friends and co-workers might check it out.
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Sat, 02 Aug 2008 03:09:18 -0400</pubDate>
    <guid isPermaLink="false">http://wavespace.info/archives/265-guid.html</guid>
    
</item>
<item>
    <title>GUI Shell Scripts</title>
    <link>http://wavespace.info/archives/257-GUI-Shell-Scripts.html</link>
            <category>Software</category>
    
    <comments>http://wavespace.info/archives/257-GUI-Shell-Scripts.html#comments</comments>
    <wfw:comment>http://wavespace.info/wfwcomment.php?cid=257</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://wavespace.info/rss.php?version=2.0&amp;type=comments&amp;cid=257</wfw:commentRss>
    

    <author>nospam@example.com (Guy McArthur)</author>
    <content:encoded>
    &lt;p&gt;Hook graphical widgets to shell scripts and you have a powerful but under-utilized class of applications. Systems programmers are typically writing code that does not need user interaction. Software developers are typically writing larger-scale programs in languages with rich widget libraries. But the domain in between does have some important uses, for instance small-scale programs that need input from non-technical operators, or need to alert them as tasks succeed (or fail).
&lt;/p&gt;
&lt;p&gt;I was reminded of this the other day when looking for a really simple &lt;a href=&quot;http://twitter.com/&quot;&gt;Twitter&lt;/a&gt; client, just something I could click from the desktop or taskbar, input a string of text and be done. The one I found was a single-line shell script that used &lt;a href=&quot;http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs&quot;&gt;kdialog&lt;/a&gt;. I added a line to catch errors. Here is the complete script.
&lt;/p&gt;
&lt;p&gt;&lt;tt&gt;
&lt;span style=&quot;font-style: italic;color: #808080;&quot;&gt;#!/bin/bash&lt;/span&gt;&lt;br/&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;curl -u username:password -s -F &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;status=&lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #cc00cc;&quot;&gt;kdialog&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; --inputbox &lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;what are you doing right now?&#039;&lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; http://twitter.com/statuses/update.xml http://twitter.com/account/end_session&lt;/span&gt;&lt;br/&gt;

&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #880088;&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #008000;&quot;&gt;$?&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; != 0&lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #880088;&quot;&gt; ]&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;then&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #cc00cc;&quot;&gt;kdialog&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; --error &lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;Twitter could not be updated&#039;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;; &lt;/span&gt;&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;fi&lt;/span&gt;
&lt;/tt&gt;
&lt;/p&gt;

&lt;p&gt;The next day I happened to read about a Python module that provides similar functionality for Mac OS X; it&#039;s called &lt;a href=&quot;http://www.oreillynet.com/onlamp/blog/2008/03/pymotw_easydialogs.html&quot;&gt;EasyDialogs&lt;/a&gt;. So I made a Mac version (my first real Python program). Here it is.
&lt;/p&gt;

&lt;p&gt;&lt;tt&gt;
&lt;span style=&quot;font-style: italic;color: #808080;&quot;&gt;#!/usr/bin/pythonw&lt;/span&gt;&lt;br/&gt;

&lt;span style=&quot;color: #ff00ff;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; EasyDialogs&lt;/span&gt;&lt;br/&gt;
&lt;span style=&quot;color: #ff00ff;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; os&lt;/span&gt;&lt;br/&gt;

&lt;span style=&quot;color: #000000;&quot;&gt;ret &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; os.system&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;curl -u username:password -s -F status=&quot;&#039;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; EasyDialogs.AskString&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;What are you doing right now?&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;&quot; http://twitter.com/statuses/update.xml http://twitter.com/account/end_session&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&lt;/span&gt;&lt;br/&gt;

&lt;span style=&quot;font-weight: bold;color: #000000;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; ret&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;:&lt;/span&gt;&lt;br/&gt;
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;span style=&quot;color: #000000;&quot;&gt;    EasyDialogs.Message&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #dd0000;&quot;&gt;&#039;Twitter could not be updated.&#039;&lt;/span&gt;&lt;span style=&quot;color: #ff00ff;&quot;&gt;)&lt;/span&gt;
&lt;/tt&gt;&lt;/p&gt;

&lt;p&gt;Either can be made executable and linked from the dock/taskbar for quick launch. Check out the tutorials for &lt;a href=&quot;http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs&quot;&gt;kdialog&lt;/a&gt; or &lt;a href=&quot;http://www.oreillynet.com/onlamp/blog/2008/03/pymotw_easydialogs.html&quot;&gt;EasyDialog&lt;/a&gt; for a better idea of what the possibilities are (complete with many graphical examples) using the standard widgets such as file choosers, checkboxes, etc.
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Sun, 27 Jul 2008 04:08:00 -0400</pubDate>
    <guid isPermaLink="false">http://wavespace.info/archives/257-guid.html</guid>
    
</item>
<item>
    <title>The Hardy Heron</title>
    <link>http://wavespace.info/archives/250-The-Hardy-Heron.html</link>
            <category>Software</category>
    
    <comments>http://wavespace.info/archives/250-The-Hardy-Heron.html#comments</comments>
    <wfw:comment>http://wavespace.info/wfwcomment.php?cid=250</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://wavespace.info/rss.php?version=2.0&amp;type=comments&amp;cid=250</wfw:commentRss>
    

    <author>nospam@example.com (Guy McArthur)</author>
    <content:encoded>
    &lt;p&gt;Last week I upgraded my laptop to the latest and greatest version of Linux, Kubuntu 8.04 (code-named the Hardy Heron; each new version of Ubuntu alphabetically increments an alliterative adjective and animal).
&lt;/p&gt;

&lt;a href=&quot;http://wavespace.info/images/kubuntu0804-1.png&quot;&gt;&lt;img src=&quot;http://wavespace.info/images/kubuntu0804-1.450x281.png&quot; width=&quot;450&quot; height=&quot;281&quot;/&gt;&lt;/a&gt;

&lt;p&gt;The only issue was that when resuming from hibernation, the screen resolution would change. I filed a bug report and asked a question on a Ubuntu support page. The response was pretty quick... if I had been checking my email! The simple fix was removing a package obsoleted by the new version of X Windows. 
&lt;/p&gt;

&lt;p&gt;I&#039;m not brave enough to try the new KDE (and, apparently, neither are the Kubuntu developers, it&#039;s still optional). KDE 3.5 with a few tweaks is just about perfect IMHO, and still leagues ahead of OS X or Vista, at least in terms of functionality. The screencap shows a feature that has yet to be built into other OS&#039;s, the ability to drag-n-drop with &lt;tt&gt;sftp://&lt;/tt&gt; locations, which I find vital for website management.
&lt;/p&gt;

&lt;p&gt;There&#039;s cool and useful features like this all over the place. It&#039;s a near perfect OS!&lt;/p&gt; 
    </content:encoded>

    <pubDate>Thu, 10 Jul 2008 02:20:32 -0400</pubDate>
    <guid isPermaLink="false">http://wavespace.info/archives/250-guid.html</guid>
    
</item>
<item>
    <title>GUI Scripts?</title>
    <link>http://wavespace.info/archives/218-GUI-Scripts.html</link>
            <category>Software</category>
    
    <comments>http://wavespace.info/archives/218-GUI-Scripts.html#comments</comments>
    <wfw:comment>http://wavespace.info/wfwcomment.php?cid=218</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://wavespace.info/rss.php?version=2.0&amp;type=comments&amp;cid=218</wfw:commentRss>
    

    <author>nospam@example.com (Guy McArthur)</author>
    <content:encoded>
    &lt;p&gt;I&#039;m looking for a lightweight scripting language that can run from the command-line or desktop and with a rich set of standard widgets. Here&#039;s the catch: it should be a &lt;em&gt;modern&lt;/em&gt; language like JavaScript/ActionScript/ECMAScript.  It sounds simple, but I&#039;m not finding anything.
&lt;/p&gt;
&lt;p&gt;A long time ago I whipped up a Tcl/tK application; the language was weird and I don&#039;t want to go down that road again. Even further back, I made a small utility in REXX which was also kind of frustrating. I&#039;ve done a little Applescripting, which is truly bizarre if you&#039;re doing anything more than driving existing applications. 
&lt;/p&gt;
&lt;p&gt;Hopefully, this would run on any UNIX/Linux that has the interpreter installed. But if it&#039;s just OS X or just Linux it would be a good start.
&lt;/p&gt;
&lt;p&gt;It would also use be ideal if it used many of the same mechanisms that I&#039;m familiar with as a web developer. Events fired from the user interface and such. An API to manipulate the user interface such as the Document Object Model, or libraries that layer on top of the DOM to make it less verbose to work with.
&lt;/p&gt;
&lt;p&gt;
So, ideally the UI would be rendered in HTML, but communication would not be through a web server. The script would not be in a &quot;sandbox&quot;, so could run with all the privileges of the user. So you&#039;d have a standard UNIX script starting with the shebang (&lt;tt&gt;#!&lt;/tt&gt;), a pile of interpreted code, and a graphical user interface.
&lt;/p&gt;
&lt;p&gt;Here are the things I know of that come close to fitting the bill.
&lt;/p&gt; &lt;br /&gt;&lt;a href=&quot;http://wavespace.info/archives/218-GUI-Scripts.html#extended&quot;&gt;Continue reading &quot;GUI Scripts?&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Tue, 01 Apr 2008 21:37:55 -0400</pubDate>
    <guid isPermaLink="false">http://wavespace.info/archives/218-guid.html</guid>
    
</item>
<item>
    <title>Instant Slideshow</title>
    <link>http://wavespace.info/archives/185-Instant-Slideshow.html</link>
            <category>Software</category>
    
    <comments>http://wavespace.info/archives/185-Instant-Slideshow.html#comments</comments>
    <wfw:comment>http://wavespace.info/wfwcomment.php?cid=185</wfw:comment>

    <slash:comments>1</slash:comments>
    <wfw:commentRss>http://wavespace.info/rss.php?version=2.0&amp;type=comments&amp;cid=185</wfw:commentRss>
    

    <author>nospam@example.com (Guy McArthur)</author>
    <content:encoded>
    &lt;p&gt;I&#039;ve re-written this simple utility a number of times over the years, this is the latest incarnation. It lets you instantly view a slideshow of the images in a folder on a web folder. All you have to do is copy the file into the directory. Only images within that directory can be viewed, so it is safe (can&#039;t be used to get info about other directories).
&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;a href=&quot;http://guymcarthur.com/photos/punaluu/size640/&quot;&gt;An example of what I&#039;m talking about&lt;/a&gt;.&lt;/dt&gt;
&lt;dd&gt;All of the functionality is contained within a single file. It uses JavaScript to control the slideshow and PHP to build it.&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&quot;http://guymcarthur.com/resources/php/index.php.html&quot;&gt;Syntax-highlighted source code&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Copy and paste the text into a file called &lt;tt&gt;index.php&lt;/tt&gt; in the folder. Or...&lt;/dd&gt;
&lt;dt&gt;&lt;a href=&quot;http://guymcarthur.com/resources/php/index.php.txt&quot;&gt;Raw source code&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;Save this as a file called &lt;tt&gt;index.php&lt;/tt&gt; in the folder. Finally, open the URL to the folder in a browser. &lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;It&#039;s dead simple, but sure is handy.
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Fri, 04 Jan 2008 16:28:29 -0500</pubDate>
    <guid isPermaLink="false">http://wavespace.info/archives/185-guid.html</guid>
    <category>gallery</category>
<category>php</category>
<category>slides</category>
<category>slideshow</category>

</item>
<item>
    <title>The End of Self-Signed Certificates?</title>
    <link>http://wavespace.info/archives/184-The-End-of-Self-Signed-Certificates.html</link>
            <category>Software</category>
    
    <comments>http://wavespace.info/archives/184-The-End-of-Self-Signed-Certificates.html#comments</comments>
    <wfw:comment>http://wavespace.info/wfwcomment.php?cid=184</wfw:comment>

    <slash:comments>3</slash:comments>
    <wfw:commentRss>http://wavespace.info/rss.php?version=2.0&amp;type=comments&amp;cid=184</wfw:commentRss>
    

    <author>nospam@example.com (Guy McArthur)</author>
    <content:encoded>
    &lt;p&gt;Instead of paying $100 per year (typically) for a secure certificate, many websites use a &quot;self-signed&quot; certificate, meaning that one of the big network agencies hasn&#039;t vouched for their credentials. The benefit to the web developer (and to users) is that a secure (encrypted) web connection can be created. The downside is that the user will be prompted upon a first visit to accept the certificate, and the risk that the site and its certificate might be fraudulent. This risk is minimal for low-profile sites (who may not have the money for a certificate) who have little risk of being spoofed via spam emails for instance. Some examples [from my own web dev experience] would be webmail for a small non-profit or a protected wiki for a small to medium sized science team. In these cases, users can be informed in advance of what to expect on the first visit, and one can be reasonably sure that hackers have not set up sites with similar URLs and content to trap the unwary.
&lt;/p&gt;
&lt;p&gt;And, for what it&#039;s worth, self-signed certs are not significantly less secure or less risky than normal certificates. A hacker can obtain a minty-fresh cert for a spoof site just as easily as a legitimate site--it just means the hacker was willing to part with $100 (or whatever it is) in pursuit of far more valuable rewards. [&lt;b&gt;Update:&lt;/b&gt; This was just plain wrong, as indicated by the comment below, self-signed certs are only as secure as the method used to distribute them.]
&lt;/p&gt;
&lt;p&gt;
But I just noticed in the new Firefox (3.0 beta 2 for Mac), that accepting a self-signed certificate is now a four-step process with messages designed to scare you away from accepting such a cert. Read the rest of this entry for screenshots. I think this will be sufficient to dissuade many users from accepting a self-signed cert, no matter what they have been told up-front.
&lt;/p&gt; &lt;br /&gt;&lt;a href=&quot;http://wavespace.info/archives/184-The-End-of-Self-Signed-Certificates.html#extended&quot;&gt;Continue reading &quot;The End of Self-Signed Certificates?&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Thu, 03 Jan 2008 19:07:14 -0500</pubDate>
    <guid isPermaLink="false">http://wavespace.info/archives/184-guid.html</guid>
    
</item>
<item>
    <title>Is Safe Surfing Possible?</title>
    <link>http://wavespace.info/archives/180-Is-Safe-Surfing-Possible.html</link>
            <category>Software</category>
    
    <comments>http://wavespace.info/archives/180-Is-Safe-Surfing-Possible.html#comments</comments>
    <wfw:comment>http://wavespace.info/wfwcomment.php?cid=180</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://wavespace.info/rss.php?version=2.0&amp;type=comments&amp;cid=180</wfw:commentRss>
    

    <author>nospam@example.com (Guy McArthur)</author>
    <content:encoded>
    &lt;p&gt;
Have you ever done the following?
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Logged in to a web site, let&#039;s say for the sake of example, any web-based email service&lt;/li&gt;
&lt;li&gt;While still logged in, visited another site, perhaps just clicking on a link in an email, or viewing an HTML email&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
Now, you have just opened the doors wide for an attack. A malicious script could (for instance) grab your email or do anything else the programming interface (the web API) of the site you are logged into, allows. &lt;a href=&quot;http://www.davidairey.com/google-gmail-security-hijack/&quot;&gt;This chilling story&lt;/a&gt; indicates the extent of your vulnerability. A script used the GMail API to insert a rule that forwarded all email concerning domain names to a site hijacker.  The hijacker then sent an email to a domain registrar, and quickly and easily had control of the person&#039;s business web site. Most likely the exploit was a script uploaded to a web forum or other insecure page, where upon it attempted the same for everyone who viewed that page. It could even be in an image tag in a HTML spam email--no action required on the victims part.
&lt;/p&gt;
&lt;p&gt;
I&#039;ve known about this style of attack (now called a XSRF or cross-site request forgery) for many years. How do you ensure that a request coming in is legitimate? After all, it is the web, legitimate use could be coming in from any Internet Protocol address. One barricade that can be placed in the way of hackers is to use what is called the referrer or &quot;HTTP referer&quot; (mis-spelled in the original specification). This is information that the web browser provides indicating which &lt;b&gt;URL&lt;/b&gt; the request came from. For example, only Google URLs should be accessing GMail settings. 
&lt;/p&gt;
&lt;p&gt;
This information however can be spoofed, for example by writing a program that emulates a browser (and this is much easier than it may sound to the non-programmer). A larger problem is then distributing the program so that victims inadvertently use it, which is where well-known techniques of code injection such as viruses come into play. Even simpler is to use a Flash applet stuck on a web page, which you will probably not even be aware of running when you stumble over it. But apparently Google&#039;s GMail did not have even this low barricade, allowing simple scripts to directly access the settings (of any GMail user who was currently logged in while being subjected to the evil script).&lt;/p&gt;

&lt;p&gt;So, the question is, is there any way to safely browse? After all, banking, shopping, and many forms of communicating now take place primarily via the web.&lt;/p&gt;
 &lt;br /&gt;&lt;a href=&quot;http://wavespace.info/archives/180-Is-Safe-Surfing-Possible.html#extended&quot;&gt;Continue reading &quot;Is Safe Surfing Possible?&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Fri, 28 Dec 2007 13:23:07 -0500</pubDate>
    <guid isPermaLink="false">http://wavespace.info/archives/180-guid.html</guid>
    <category>hacking</category>
<category>http</category>
<category>web</category>
<category>webmail</category>

</item>
<item>
    <title>One Dozen Mac Annoyances</title>
    <link>http://wavespace.info/archives/170-One-Dozen-Mac-Annoyances.html</link>
            <category>Software</category>
    
    <comments>http://wavespace.info/archives/170-One-Dozen-Mac-Annoyances.html#comments</comments>
    <wfw:comment>http://wavespace.info/wfwcomment.php?cid=170</wfw:comment>

    <slash:comments>3</slash:comments>
    <wfw:commentRss>http://wavespace.info/rss.php?version=2.0&amp;type=comments&amp;cid=170</wfw:commentRss>
    

    <author>nospam@example.com (Guy McArthur)</author>
    <content:encoded>
    &lt;p&gt;
Here&#039;s my top-12 list of Mac annoyances, things that suck about Mac OS X. I bought a Mac Mini in the fall of 2005, a 1.2 GHz model with 512 MB of RAM. Around the same time my work machine became a G5 quad (actually a dual dualie) with 2GB of RAM (since upgraded to 4). Last year I got a Dell Inspiron B130 laptop, which is now my main machine at home, relegating the mini to a server for &lt;a href=&quot;http://guymcarthur.com/resources/gadgets/squeezebox.xml&quot;&gt;music&lt;/a&gt;. The laptop runs Kubuntu, a derivative of Debian Linux with the KDE desktop, which supports it very well.
&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;1. &lt;b&gt;Poor Performance&lt;/b&gt;&lt;/dt&gt;
&lt;dd&gt;OS X is beyond dog slow, it is slug slow. Windows XP or Linux on a ten-year-old Pentium II will be snappier than OS X. Even on high-end hardware, it is not discernably more responsive. In general, most applications are poorly threaded and the spinning beach ball busy cursor is always around the corner. For instance in Firefox, when launching a tab, you&#039;ll frequently be unable to do anything with the Finder menu while the tab is connecting. 
&lt;/dd&gt;
&lt;dt&gt;2. &lt;b&gt;iPhoto&lt;/b&gt;&lt;/dt&gt;
&lt;dd&gt;iPhoto is the all-time champion when it comes to poor performance, taking a minute to load up. It is such a memory hog that minimizing it to switch to other applications, or maximizing it again, takes almost another minute.
&lt;/dd&gt;
&lt;dt&gt;3. &lt;b&gt;Lack of package management&lt;/b&gt;&lt;/dt&gt;
&lt;dd&gt;Debian has &lt;tt&gt;apt-get&lt;/tt&gt; or the graphical versions &lt;i&gt;Adept&lt;/i&gt; or &lt;i&gt;Synaptic&lt;/i&gt;, which make installing (or un-installing) any one of over ten thousand applications and libraries a one-step procedure, complete with finding and installing all their dependencies, synchronized with an always up-to-date online catalog. The technique is used in nearly all Linux distributions and was perfected in Debian years ago. In contrast, OS X has the concept of dragging an application bundle to a folder. Each bundle (usually) includes its own copy of those libraries that it depends on, leading to bloat. If you want to upgrade to the latest version, there is no automated way to do it.
&lt;/dd&gt;
&lt;dt&gt;4. &lt;b&gt;Poor previewing&lt;/b&gt;&lt;/dt&gt;
&lt;dd&gt;In KDE, you can set the icon size to be different than the size of image previews (when viewing a folder). In OS X, you cannot. Either you have nicely sized icons and tiny previews, or giant icons and nice previews. What&#039;s more if you select a set of images for a slideshow, they are in random order, with no apparent way of changing the order! Preview.app is also flawed; you can&#039;t view a selected set of images at their actual size, instead you must hit &#039;actual size&#039; on each individual one.
&lt;/dd&gt;
&lt;/dl&gt;
 &lt;br /&gt;&lt;a href=&quot;http://wavespace.info/archives/170-One-Dozen-Mac-Annoyances.html#extended&quot;&gt;Continue reading &quot;One Dozen Mac Annoyances&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Mon, 26 Mar 2007 00:50:12 -0400</pubDate>
    <guid isPermaLink="false">http://wavespace.info/archives/170-guid.html</guid>
    
</item>
<item>
    <title>Joggle Update</title>
    <link>http://wavespace.info/archives/169-Joggle-Update.html</link>
            <category>Software</category>
    
    <comments>http://wavespace.info/archives/169-Joggle-Update.html#comments</comments>
    <wfw:comment>http://wavespace.info/wfwcomment.php?cid=169</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://wavespace.info/rss.php?version=2.0&amp;type=comments&amp;cid=169</wfw:commentRss>
    

    <author>nospam@example.com (Guy McArthur)</author>
    <content:encoded>
    &lt;p&gt;I tuned up the Javascript / DOM code for the &lt;a href=&quot;http://guymcarthur.com/projects/joggle/&quot;&gt;AJAX version of Joggle&lt;/a&gt;. Someday I will get around to a network, multi-player version, a cell phone version, and more. Sadly, I can barely get onto the high scores list of my own game. It&#039;s tough!&lt;/p&gt; 
    </content:encoded>

    <pubDate>Mon, 26 Mar 2007 00:31:09 -0400</pubDate>
    <guid isPermaLink="false">http://wavespace.info/archives/169-guid.html</guid>
    
</item>

</channel>
</rss>