<?xml version="1.0" encoding="UTF-8"?><feed
  xmlns="http://www.w3.org/2005/Atom"
  xmlns:thr="http://purl.org/syndication/thread/1.0"
  xml:lang="en"
  >
  <id>http://livingcode.org/feed/atom</id>
  <updated>2009-11-13T19:33:25Z</updated>
  <title type="text">Living Code</title>
  <subtitle type="text">Programming for the Fun of It</subtitle>
  <link rel="self" type="application/atom+xml" href="http://livingcode.org/feed" />
  <link rel="alternate" href="http://livingcode.org" />
  <rights type="text">Copyright 2009</rights>
  <generator uri="http://wordpress.org/" version="2.8.6">WordPress</generator>
      <entry>
    <id>http://livingcode.org/2006/back-to-the-drawing-board</id>
    <title type="html"><![CDATA[Back to the Drawing Board]]></title>
    <updated>2008-01-16T07:02:55Z</updated>
    <published>2006-11-14T06:59:01Z</published>
    <author>
      <name>Dethe</name>
      <email>delza@livingcode.org</email>
<uri>http://livingcode.org/</uri>    </author>
    <link rel="replies" type="application/atom+xml" href="http://livingcode.org/2006/11/13/back-to-the-drawing-board/feed" thr:count="0"  />
    <link rel="alternate" href="http://livingcode.org/2006/11/13/back-to-the-drawing-board" />
    <category scheme="http://livingcode.org" term="Python" />
    <summary type="html"><![CDATA[Well, I&#8217;ve been promising this off and on here in my intermittent blog, but I&#8217;ve had the code up on Google code hosting for some time now, my kids have tested out the latest version, I&#8217;ve fixed some bugs introduced when PyObjC switched from distutils to setuptools. It is still pretty raw, unpolished, unoptimized, but [...]]]></summary>
      <content type="html" xml:base="http://livingcode.org/2006/11/13/back-to-the-drawing-board"><![CDATA[<p>Well, I&#8217;ve been promising this off and on here in my intermittent blog, but I&#8217;ve had the code up on Google code hosting for some time now, my kids have tested out the latest version, I&#8217;ve fixed some bugs introduced when PyObjC switched from distutils to setuptools. It is still pretty raw, unpolished, unoptimized, but I&#8217;m ready to let the world see it and let me know what they think.</p>
<p>Current features of Drawing Board:</p>
<ul>
<li>Freehand sketching: This is the main point of the software</li>
<li>Onion-skinning: See previous frame dimmed behind current frame</li>
<li>Create new frames: Either blank, or containing a copy of the current frame. Copied frames include the entire undo stack for the frame, so you can copy, and then undo a portion of the frame</li>
<li>Change colours and line sizes</li>
<li>Change the opacity of the window (this is a hack to allow you to trace images until I get image backgrounds implemented)</li>
<li>Scale and translate the frame</li>
<li>Remove current frame (not undo-able)</li>
<li>Export as SVG</li>
<li>Export frame as PNG or JPEG (PNG includes alpha for any area not drawn)</li>
</ul>
<p>There is basic file handling, which may be useful as example code for learning Cocoa programming using Python. I&#8217;m still working at adding drawing tools besides freehand drawing, and I have ideas for a lot of other things, but the main idea is to keep the program from getting in your way&#8211;to keep as close to possible as sketching with a pencil on paper, but to make the process of creating simple animations easier.</p>
<p>Two features that are pretty close, and are important to the goal of the project, are export as Flash and export as Quicktime. Those will be coming sooner, rather than later.</p>
<p>The project page is at <a href="http://livingcode.org/project/drawingboard">http://livingcode.org/project/drawingboard</a> and you can find links there to the binary download, the source repository, and the bug/feature tracker. I&#8217;ve also set up Google groups for the Living Code projects: <a href="http://groups.google.com/group/livingcode-users">http://groups.google.com/group/livingcode-users</a> and <a href="http://groups.google.com/group/livingcode-developer">http://groups.google.com/group/livingcode-developer</a> for ongoing discussions.</p>
<p>A few people have seen me demo this program at the Vancouver Python Workshop and at Bar Camp Vancouver and expressed an interest, so I hope it can be of use, both in learning to program OS X with Python, and for creating animations. Please let me know what you find useful and what could be improved!</p>
]]></content>
        </entry>
    <entry>
    <id>http://livingcode.org/2008/pyobjc-at-vanpyz</id>
    <title type="html"><![CDATA[PyObjC at VanPyZ]]></title>
    <updated>2008-01-16T07:11:45Z</updated>
    <published>2006-10-03T07:03:04Z</published>
    <author>
      <name>Dethe</name>
      <email>delza@livingcode.org</email>
<uri>http://livingcode.org/</uri>    </author>
    <link rel="replies" type="application/atom+xml" href="http://livingcode.org/2006/10/02/pyobjc-at-vanpyz/feed" thr:count="0"  />
    <link rel="alternate" href="http://livingcode.org/2006/10/02/pyobjc-at-vanpyz" />
    <category scheme="http://livingcode.org" term="Python" />
    <summary type="html"><![CDATA[On Tuesday, October 3rd, at 7 pm, the Vancouver Python and Zope user&#8217;s group (VanPyZ) will be hosting two speakers. Paul Prescod will be discussing full-stack web frameworks in Python, and I will be presenting OS X programming in Python. This will probably not be a repeat of my presentation at the Vancouver Python Workshop [...]]]></summary>
      <content type="html" xml:base="http://livingcode.org/2006/10/02/pyobjc-at-vanpyz"><![CDATA[<p>On Tuesday, October 3rd, at 7 pm, the Vancouver Python and Zope user&#8217;s group (<a href="http://www.vanpyz.org/index_html_wiki">VanPyZ</a>) will be hosting two speakers. Paul Prescod will be discussing full-stack web frameworks in Python, and I will be presenting OS X programming in Python. This will probably not be a repeat of my presentation at the Vancouver Python Workshop (<a href="http://livingcode.org/slides/vanpyw_2006-08-05.pdf">PDF slides</a>, for anyone who is interested) but using <a href="http://livingcode.org/project/drawingboard/">Drawing Board</a> and the <a href="http://livingcode.org/entry/tab_dumping_in_safari.html">InputManager hack</a> to show how you can use <a href="http://pyobjc.sourceforge.net/">PyObjC</a> to build new applications in Python quickly and extend existing Cocoa applications easily. My focus these days is on how to take control of your computer and make it work for you, rather than the other way around.</p>
<p>The VanPyZ meeting will be at the <a href="http://www.uniserve.com/">Uniserve</a> office, where Paul and I now work, Suite 1550, 1055 West Hastings Street, in Vancouver, BC. <a href="http://www.vmunix.com/mark/blog/archives/2006/09/18/announcing-chlo-mayo/">Mark Mayo</a> took time out from his new baby (congratulations, Mark!) to create an Upcoming <a href="http://upcoming.org/event/111453">event</a> for it. We&#8217;ll be going out for drinks afterwards, so come hang out with the Vancouver pythoneers.</p>
]]></content>
        </entry>
    <entry>
    <id>http://livingcode.org/2006/tab-dumping-in-safari</id>
    <title type="html"><![CDATA[Tab Dumping in Safari]]></title>
    <updated>2008-01-17T07:30:28Z</updated>
    <published>2006-08-31T06:04:27Z</published>
    <author>
      <name>Dethe</name>
      <email>delza@livingcode.org</email>
<uri>http://livingcode.org/</uri>    </author>
    <link rel="replies" type="application/atom+xml" href="http://livingcode.org/2006/08/30/tab-dumping-in-safari/feed" thr:count="2"  />
    <link rel="alternate" href="http://livingcode.org/2006/08/30/tab-dumping-in-safari" />
    <category scheme="http://livingcode.org" term="Python" />
    <summary type="html"><![CDATA[The Problem
I first saw the term &#8220;tab dump&#8221; on Dori Smith&#8217;s blog, but I immediately recognized the concept. I keep Safari running all the time and with the help of Hao Li&#8217;s wonderful extension Saft I keep everything in tabs in one window. Among its many features, Saft will let you consolidate your windows into [...]]]></summary>
      <content type="html" xml:base="http://livingcode.org/2006/08/30/tab-dumping-in-safari"><![CDATA[<h3>The Problem</h3>
<p>I first saw the term &#8220;tab dump&#8221; on Dori Smith&#8217;s <a href="http://www.backupbrain.com/2006_04_16_archive.html">blog</a>, but I immediately recognized the concept. I keep Safari running all the time and with the help of Hao Li&#8217;s wonderful extension <a href="http://livingcode.org/entry/li.dnsalias.com/Saft/">Saft</a> I keep everything in tabs in one window. Among its many features, Saft will let you consolidate your windows into tabs of one window, and it can save the tabs you have open when you close (or crash) Safari, and re-open them automatically when you start Safari again. What it doesn&#8217;t do is give you a list of all the tabs you have open in text format, suitable for blog or email. I don&#8217;t currently put tag dumps on the blog because a) I&#8217;d feel guilty doing that without adding at least a short comment for each link, which would take too much time, and b) because this isn&#8217;t really a link blog, more a place for me to bash out example code and tutorials. At least, that&#8217;s how I think of it.</p>
<p>I do however, find Safari teetering on the brink of being unfunctionally slow because I have so many tabs open, and often they&#8217;re only open because I want to remember to do something with them later, or come back to them, or some other reminder-type function. So I send myself a tab dump on a more-or-less daily basis. Firefox has tools to help you do this, but I haven&#8217;t seen anything for Safari, possibly because you can&#8217;t really do it with a Safari plugin, but need to use an InputManager, which is fairly deep magic, and basically a hack, an abuse of the system.</p>
<p>On the other hand, I couldn&#8217;t keep using Safari if it wasn&#8217;t for Saft, and Saft is an InputManager. Another tool for blocking ads and such (which Saft also does) is <a href="http://www.culater.net/software/PithHelmet/PithHelmet.php">PithHelmet</a>, but the interesting thing to me about PithHelmet isn&#8217;t that it is a popular ad blocker, but that the Mike Solomon (who wrote PithHelmet) decided to not just make an InputManager, but to make <em>the only InputManager you&#8217;ll ever need</em>. You see, PithHelmet itself is not an InputManager, it is a plugin for <a href="http://www.culater.net/software/SIMBL/SIMBL.php">SIMBL</a> (also by Solomon), which is an InputManager that loads plugins based on the application(s) they claim to support. InputManagers get loaded by <em>every</em> application (Cocoa apps, at least), so you have to be careful you&#8217;re in the app you want to modify, and take steps not to break things. SIMBL takes care of the nasty business of being a well-behaved system hack, and your code can assume it is in the right app, because it doesn&#8217;t get loaded otherwise.</p>
<h3>The Goal</h3>
<p>Once I figured out that the only way I was going to get Tab Dumping behaviour into Safari (because Safari tabs don&#8217;t play well with Javascript, that turned out to be a dead-end), I decided to try writing an InputManager in Python. SIMBL is open-source, so at first I was looking at the code to see what I need to do to create an InputManager (remember, this is a hack, so Apple doesn&#8217;t document it very well). I also read Mike&#8217;s essay <a href="http://www.culater.net/wiki/moin.cgi/CocoaReverseEngineering">Armchair Guide To Cocoa Reverse Engineering</a>. What I decided was that, rather than recreate the functionality in SIMBL using Python, I would just create a SIMBL plugin in Python.</p>
<p>Getting started wasn&#8217;t too bad, but I found one issue in the above essay that stumped me for awhile. Mike recommends you put your initialization code into a class method <span class="code">load()</span> which gets called after your class is loaded. I don&#8217;t know if it is artifact of using PyObjC or what, but my <span class="code">load()</span> method was never getting called. What I did instead was to run the command-line utility <span class="code">class-dump</span> on another SIMBL plugin to see what they were doing. They were using the class method <span class="code">initialize()</span> rather than load and when I switched to that things started working, where by &#8220;things&#8221; I mean, &#8220;I could print to the console to see that my class had loaded.&#8221;</p>
<h3>The Solution</h3>
<p>The next step was to actually do something once I had my code loading into Safari. The tab behaviour of Safari isn&#8217;t part of WebKit, so it isn&#8217;t documented anywhere. Once again, I used the handy <span class="code">class-dump </span>utility. This is a fabulous tool which will read any Cocoa library, bundle, or application and produce a pseudo-header file showing all the objects and methods defined. I still had to try a few different paths to get to the tab information I wanted, but it was pretty easy, armed as I was with Python and the output of <span class="code">class-dump</span>. Here is the result:</p>
<pre>import objc</pre>
<pre>from Foundation import *</pre>
<pre>from AppKit import *</pre>
<pre>class TabDump(NSObject):</pre>
<pre>    # We will retain a pointer to the plugin to prevent it</pre>
<pre>    # being garbage-collected</pre>
<pre>    plugin = None</pre>
<pre>    @classmethod</pre>
<pre>    # the following is not strictly necessary, but we only</pre>
<pre>    # need one instance of our object</pre>
<pre>    def sharedInstance(cls):</pre>
<pre>        if not cls.plugin:</pre>
<pre>            cls.plugin = cls.alloc().init()</pre>
<pre>        return cls.plugin</pre>
<pre>    @classmethod</pre>
<pre>    def initialize(cls):</pre>
<pre>        app = NSApp()</pre>
<pre>        menu = app.windowsMenu()</pre>
<pre>        cls.item = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(</pre>
<pre>            'Dump tabs to clipboard',</pre>
<pre>             'tabdump:',</pre>
<pre>             '')</pre>
<pre>        # should be after "Previous Tab" and "Next Tab"</pre>
<pre>        menu.insertItem_atIndex_(cls.item, 6)</pre>
<pre>        cls.item.setTarget_(cls.sharedInstance())</pre>
<pre>    def tabdump_(self, source):</pre>
<pre>        output = []</pre>
<pre>        app = NSApp()</pre>
<pre>        for window in app.windows():</pre>
<pre>            if window.className() == 'BrowserWindow':</pre>
<pre>                controller = window.windowController()</pre>
<pre>                for browserWebView in controller.orderedTabs():</pre>
<pre>                    output.append(browserWebView.mainFrameTitle().encode('utf8'))</pre>
<pre>                    output.append(browserWebView.mainFrameURL().encode('utf8'))</pre>
<pre>                    output.append('')</pre>
<pre>        self.copyToPasteboard_('\n'.join(output))</pre>
<pre>    def copyToPasteboard_(self, string):</pre>
<pre>        pasteboard = NSPasteboard.generalPasteboard()</pre>
<pre>        pasteboard.declareTypes_owner_([NSStringPboardType], self)</pre>
<pre>        pasteboard.setString_forType_(string, NSStringPboardType)</pre>
<p>As you can see, on my class being initialized, I create a new menu item and insert it into the Windows menu. This could be more robust, by testing menu item names to make sure I&#8217;m in the right place, but it works for me, and simple code is more maintainable code. I create an instance of my object and make it the target of the menu item. Pretty basic stuff.</p>
<p>When the tabdump method is called (by selecting the menu item in Safari), it walks through Safari&#8217;s window objects (of which there are many) until it finds browser windows, then it extracts the tabbed views from the browser windows to get the titles and URLs involved. When it has collected all the title/URL pairs, it turns it into a big string and puts the string on the pasteboard. Here is where we could be a lot fancier. I&#8217;m just putting title/URL pairs, separated by newlines in plain text, because that&#8217;s how I mail them to myself. You could easily create Markdown links or any other format here. You could turn them into HTML and put them on the Pasteboard that way. There&#8217;s a lot you can do, and the Firefox tool I used to use to do this offered so many options that I was never sure what most of them actually did. Here you can customize the code to do exactly what you need, and keep it simple.</p>
<h3>Building the plugin</h3>
<p>I haven&#8217;t tested this with multiple windows, or with a window with only one tab. It might work, might not. I don&#8217;t plan on using it that way, and if I do, it&#8217;s easy enough to fix. Now, there is one more thing you&#8217;ll need, which is the <span class="code">setup.py</span> script to build it. Assuming you&#8217;ve saved the above code as <span class="code">TabDump.py</span>, the following script should be what you need:</p>
<pre>'''</pre>
<pre>    Minimalist build file for TabDump.py</pre>
<pre>    To build run 'python setup.py py2app' on the command line</pre>
<pre>'''</pre>
<pre>from distutils.core import setup</pre>
<pre>import py2app</pre>
<pre>plist = dict(</pre>
<pre>    NSPrincipalClass='TabDump',</pre>
<pre>    CFBundleName='TabDump',</pre>
<pre>    SIMBLTargetApplications=[</pre>
<pre>        dict(</pre>
<pre>            BundleIdentifier='com.apple.Safari',</pre>
<pre>            MinBundleVersion='312',</pre>
<pre>            MaxBundleVersion='420')],</pre>
<pre>)</pre>
<pre>setup(</pre>
<pre>    plugin=['TabDump.py'],</pre>
<pre>    options=dict(py2app=dict(</pre>
<pre>        extension='.bundle',</pre>
<pre>        plist=plist,</pre>
<pre>    )),</pre>
<pre>)</pre>
<p>In the above file, <span class="code">MinBundleVersion</span> and <span class="code">MaxBundleVersion</span> can keep your code from being loaded if an untested version of the application is running. I have more-or-less dummy values there, don&#8217;t treat them as the right thing to do. The <span class="code">SIMBLTargetApplications</span> key holds a list, so if you want your code to load in other applications, add more dictionaries to the list.</p>
<p>Also note that you can build your bundle with python <span class="code">setup.py py2app -A</span> to create a development version (can&#8217;t ship it that way) that is all symlinks, so you can edit TabDump.py to make changes without having to rebuild the plugin. If you modify the <span class="code">MinBundleVersion</span> or <span class="code">MaxBundleVersion</span> you will have to rebuild to regenerate the property list (or move the property list to be an external file rather than generating it in setup.py), but that should be an infrequent operation. More importantly, you can put a symlink to your bundle in your <span class="code">~/Library/Application Support/SIMBL/Plugins/</span> directory. Then you can make changes to the python code and test it by simply restarting Safari. <strong>WARNING:</strong> If you have a syntax error in your file, Safari will most likely hang on restart. Just force quit it and check your console for the error to fix.</p>
<h3>The Promise</h3>
<p>Now, if you&#8217;ve followed along with me so far, I&#8217;d like to point out a few things that are <em>really freaking cool</em> about this. Item the first: You now have Python running in Safari. Can you think of anything else you&#8217;d like it to do while you&#8217;re there? I bet you can. Item the second: You can do this in any Cocoa-based application just as easily. Problems in Mail.app? Frustrated by iChat? Just fix it. Take control of your own applications! Make the computer work for you, not the other way around. Item the third: dump-classes gives you the keys to the kingdom. Seriously, the combination of being able to embed Python and get a listing of the objects and methods at will is so powerful that when I got TabDump working late last night and realized what I&#8217;d just done (i.e., these three things), I was barely able to get to sleep after that. The possibilities are endless.</p>
<p>If you use this and do something cool with it, please drop me a line and tell me about it. I&#8217;m really looking forward to hearing about what kind of cool ways we can push our existing applications.</p>
<h3>Correction [2006-08-30]</h3>
<p>The <span class="code">class-dump</span> utility rocks, and you should add it to your arsenal of Cocoa tools, along with Python and PyObjC. Since I&#8217;ve found it it has already become indispensable for examining existing applications that I want to, er, adjust. Here&#8217;s what I&#8217;ve learned so far.</p>
<p>First, I want to update my previous post to talk a little bit more about the command-line utility <span class="code">class-dump</span>. This is a fine tool that lets you introspect a Cocoa bundle (plugin, library, or application) and prints out a header file describing all the objects and methods in that bundle. I didn&#8217;t mention where to get it, and at BarCamp this weekend I gave some mis-information by telling people it came with Apple&#8217;s developer tools, which is not true. I assumed that&#8217;s where it came from, because I didn&#8217;t remember hearing of it before reading Mike Solomon&#8217;s <a href="http://www.culater.net/wiki/moin.cgi/CocoaReverseEngineering">Armchair Guide to Cocoa Reverse Engineering</a>, which refers to <span class="code">classdump</span> without any explanation of where to get it. I tried it, found <span class="code">class-dump</span> worked (tab-completion is your friend), and assumed it came with my system, when in fact I had installed it earlier after reading about it on another blog (I&#8217;m afraid I don&#8217;t remember where) meaning to try it out, then forgotten about it. So it was there, waiting for me, when I discovered a need for it.</p>
<p>So the truth is, <a href="http://www.codethecode.com/Projects/class-dump/">class-dump</a> is a utility written by Steve Nygard. He says it provides the same output as the developer tools command <span class="code">otool -ov</span>, but formatted as a header file. Besides the basic output it can also do various kinds of filtering, sorting, and formatting.<br />
So this is my Tool of the Week (and then some): <span class="code">class-dump</span>. Use it, love it, thank Steve.</p>
]]></content>
        </entry>
    <entry>
    <id>http://livingcode.org/2006/bar-camp-tomorrow</id>
    <title type="html"><![CDATA[Bar Camp Tomorrow]]></title>
    <updated>2008-01-25T21:27:43Z</updated>
    <published>2006-08-26T07:30:29Z</published>
    <author>
      <name>Dethe</name>
      <email>delza@livingcode.org</email>
<uri>http://livingcode.org/</uri>    </author>
    <link rel="replies" type="application/atom+xml" href="http://livingcode.org/2006/08/25/bar-camp-tomorrow/feed" thr:count="0"  />
    <link rel="alternate" href="http://livingcode.org/2006/08/25/bar-camp-tomorrow" />
    <category scheme="http://livingcode.org" term="News" />
    <summary type="html"><![CDATA[Tomorrow, from 6PM to Saturday at 6PM will be the Bar Camp Vancouver. I&#8217;ll be heading over there with my neighbor, former co-worker, and original member of Pluto, John Ounpuu, currently of Sutori fame. I&#8217;m planning on ducking out to sleep at home rather than camping there, but I&#8217;m sure it will be a great [...]]]></summary>
      <content type="html" xml:base="http://livingcode.org/2006/08/25/bar-camp-tomorrow"><![CDATA[<p>Tomorrow, from 6PM to Saturday at 6PM will be the <a href="http://barcamp.org/BarCampVancouver">Bar Camp Vancouver</a>. I&#8217;ll be heading over there with my neighbor, former co-worker, and original member of Pluto, John Ounpuu, currently of <a href="http://sutori.com/">Sutori</a> fame. I&#8217;m planning on ducking out to sleep at home rather than camping there, but I&#8217;m sure it will be a great time. If there is time I may reprise my presentation on Python, OS X, and Kids from the Vancouver Python Workshop. If time is short I may still be able to demo Drawing Board. If time is really short I&#8217;ll still try to squeeze in a demo of the new hack I figured out last night (see next post). I&#8217;m also hoping to find some time to hack on turtle graphics for OS X, since I&#8217;m so close to having a working port of the standard library turtle graphics in PyObjC. But the main thing I&#8217;m excited about is meeting folks, it&#8217;s going to be a <a href="http://barcamp.org/BarCampVancouverRegistry">great crowd</a>.</p>
<p>Vancouver is such a great place. There&#8217;s the standard stuff: Great weather, beautiful beaches, forests and mountains. Then there is all the rest: lots of interesting geeks of various stripes, cool places to work, small conferences to attend. I&#8217;ve had so much more fun at the Vancouver Python Workshop and Northern Voices than at big anonymous events like JavaOne and OOPSLA. There&#8217;s just no contest. And BarCamp is all about being a small, intimate event&#8211;that appears to be its whole entire purpose. I can hardly wait.</p>
]]></content>
        </entry>
    <entry>
    <id>http://livingcode.org/2006/pastels</id>
    <title type="html"><![CDATA[Pastels]]></title>
    <updated>2008-01-21T04:43:10Z</updated>
    <published>2006-08-20T02:37:58Z</published>
    <author>
      <name>Dethe</name>
      <email>delza@livingcode.org</email>
<uri>http://livingcode.org/</uri>    </author>
    <link rel="replies" type="application/atom+xml" href="http://livingcode.org/2006/08/19/pastels/feed" thr:count="0"  />
    <link rel="alternate" href="http://livingcode.org/2006/08/19/pastels" />
    <category scheme="http://livingcode.org" term="Python" />
    <summary type="html"><![CDATA[[Update: Thanks to Blake Winton for pointing out that the project page link to the Pastels download was broken, fixed now. Also added a link to the project page.]
Pastels is an example project for creating an OS X screensaver in Python using PyObjC. By extension it could be used as an example for building nearly [...]]]></summary>
      <content type="html" xml:base="http://livingcode.org/2006/08/19/pastels"><![CDATA[<p>[Update: Thanks to Blake Winton for pointing out that the project page link to the Pastels download was broken, fixed now. Also added a link to the project page.]</p>
<p>Pastels is an example project for creating an OS X screensaver in Python using PyObjC. By extension it could be used as an example for building nearly any plugin or bundle for OS X. It started when I had an idea for drawing a simple squiggle, over and over, while cycling the colours and moving the squiggle around. I was very pleased with how it turned out.</p>
<p>Project page: <a href="http://livingcode.org/project/pastels/">http://livingcode.org/project/pastels/</a></p>
<p>It&#8217;s also my first attempt at hosting an open-source project at Google with their new hosting program. If it works out well I will add more of my projects there, which will save me trying to set up and configure Subversion on Dreamhost for public access (probably not difficult, but one more thing I don&#8217;t have to do means more time for writing example code and tutorials).</p>
<p>I&#8217;m working on the tutorial text to go along with this project, so ask any questions you have and I&#8217;ll try to get to them in the tutorial.</p>
<p>If you are seeing this on my site (as opposed to the Atom feed), there are some changes I&#8217;m making to the site that I&#8217;d like to point out. I&#8217;ve added pages for projects and mini-projects which use the same stylesheet and includes as the rest of the site. I know the stylesheet is uglyless than completely attractive right now&#8211;the first thing was to get everything factored and consistent, then to make it pretty. The projects page only has one item on it (Pastels), but that should be changing now that I have the infrastructure set up the way I want it. Nearly all the projects I mentioned in my presentation at the Vancouver Python Workshop will get their own pages soon. More about that in my next post.</p>
]]></content>
        </entry>
    <entry>
    <id>http://livingcode.org/2006/xml-article-without-the-xml</id>
    <title type="html"><![CDATA[XML Article without the XML]]></title>
    <updated>2008-01-21T05:02:55Z</updated>
    <published>2006-08-05T04:52:30Z</published>
    <author>
      <name>Dethe</name>
      <email>delza@livingcode.org</email>
<uri>http://livingcode.org/</uri>    </author>
    <link rel="replies" type="application/atom+xml" href="http://livingcode.org/2006/08/04/xml-article-without-the-xml/feed" thr:count="0"  />
    <link rel="alternate" href="http://livingcode.org/2006/08/04/xml-article-without-the-xml" />
    <category scheme="http://livingcode.org" term="Python" />
    <summary type="html"><![CDATA[My latest article for David Mertz&#8217;s column XML Matters is up at IBM developerWorks: Lighter than microformats: Picoformats Ajax without X, Microformats without angle brackets went live a couple of days ago. It isn&#8217;t so much about XML as how to avoid XML. My feelings towards XML are that it is useful and good, but [...]]]></summary>
      <content type="html" xml:base="http://livingcode.org/2006/08/04/xml-article-without-the-xml"><![CDATA[<p>My latest article for <a href="http://gnosis.cx/dW/">David Mertz&#8217;s </a>column <a href="http://www.ibm.com/developerworks/views/xml/libraryview.jsp?search_by=xml+matters">XML Matters</a> is up at <a href="http://www.ibm.com/developerworks">IBM developerWorks</a>: <a href="http://www-128.ibm.com/developerworks/library/x-matters46/">Lighter than microformats: Picoformats</a> <em>Ajax without X, Microformats without angle brackets</em> went live a couple of days ago. It isn&#8217;t so much about XML as how to avoid XML. My feelings towards XML are that it is useful and good, but overused and not a panacea. By providing some alternatives, maybe some of the backlash against the &#8220;XML everywhere for everything&#8221; meme can be averted.</p>
<p>I&#8217;ve been meaning to post about the article, but I keep getting caught up preparing my presentation for the <a href="http://www.vanpyz.org/conference">Vancouver Python Workshop</a> on Saturday (the workshop starts Friday August 3rd and goes through Sunday August 5th). My talk this year is on using [PyObjC] to create applications and plugins for OS X using Python. I&#8217;ll get the slides up after, as soon as I can. I&#8217;m also planning on doing a shorter version of this talk at <a href="http://upcoming.org/event/87852">Bar Camp Vancouver</a> which is 6 pm Friday, August 25 to 6 pm Saturday, August 26.</p>
<p>And I should have mentioned the Google talk at the<a href="http://www.bcgsc.ca/vanhpc/"> Vancouver High Performance Computing User Group</a> before it happened on July 27th. Narayanan &#8216;Shiva&#8217; Shivakumar came up from their Seattle office to present mostly old information from their published papers such as The <a href="http://labs.google.com/papers/gfs.html">Google File System</a>, <a href="http://labs.google.com/papers/mapreduce.html">MapReduce</a>, and <a href="http://video.google.com/videoplay?docid=7278544055668715642">BigTable</a> (video). The talk over beers after was fun, and it was good to see my friend <a href="http://www.vmunix.com/mark/">Mark</a> and find out he has a <a href="http://www.vmunix.com/mark/blog/">blog</a>, even if it&#8217;s over my head much of the time.</p>
<p>Well, that&#8217;s my update dump. More stuff on actually using PyObjC coming Real Soon Now.</p>
]]></content>
        </entry>
    <entry>
    <id>http://livingcode.org/2005/pysight-preview</id>
    <title type="html"><![CDATA[PySight Preview]]></title>
    <updated>2008-01-26T23:25:23Z</updated>
    <published>2005-10-20T06:53:40Z</published>
    <author>
      <name>Dethe</name>
      <email>delza@livingcode.org</email>
<uri>http://livingcode.org/</uri>    </author>
    <link rel="replies" type="application/atom+xml" href="http://livingcode.org/2005/10/19/pysight-preview/feed" thr:count="0"  />
    <link rel="alternate" href="http://livingcode.org/2005/10/19/pysight-preview" />
    <category scheme="http://livingcode.org" term="Python" />
    <summary type="html"><![CDATA[Awhile back I promised a bunch of posts, but delays were made (including a month of vacation travelling around BC which I won&#8217;t apologize for). One of the promised projects I was going to talk about was PySight, which ought to be simple, since it&#8217;s just a trivial wrapper around Tim Omernick&#8217;s CocoaSequenceGrabber (used with [...]]]></summary>
      <content type="html" xml:base="http://livingcode.org/2005/10/19/pysight-preview"><![CDATA[<p>Awhile back I promised a bunch of posts, but delays were made (including a month of vacation travelling around BC which I won&#8217;t apologize for). One of the promised projects I was going to talk about was PySight, which ought to be simple, since it&#8217;s just a trivial wrapper around Tim Omernick&#8217;s <a href="http://www.skyfell.org/cocoasequencegrabber.html">CocoaSequenceGrabber</a> (used with his permission). But I wanted to package it nicely, write more example code, maybe some documentation.</p>
<p>So instead of a polished project I have no project, and finishing it is pretty low on my priorities right now, sad to say.</p>
<p>Fortunately, Robbie Tingey came to the rescue and prompted me about it. I put a zip file together with Tim&#8217;s code to create a framework, his example program to use the framework, my simple wrapper, and my re-write of Tim&#8217;s example program in python using PyObjC to show how to use this. There&#8217;s a README, but not much else. I sent Robbie the URL and he tried it out successfully, so I thought I&#8217;d toss it out to the rest of the world. Caveat emptor, this is pre-alpha, no guarantees, no promises, but hey, it &#8220;Works for me™.&#8221;</p>
<p>So if you&#8217;re feeling adventurous, go ahead and try out <a href="http://livingcode.org/pysight/PySight.zip">PySight</a> (74K Zip) and start grabbing data from your iSight camera from Python. Contributions to packaging it nicely, documenting it, or adding examples are gratefully accepted. Or, just bug me about it and I&#8217;ll see what I can do to move it up my priority list.</p>
<p>Python, meet iSight. iSight, meet Python. Play nice together now.</p>
<p>[Update: I forgot the link. Thanks, Marcia!]</p>
]]></content>
        </entry>
    <entry>
    <id>http://livingcode.org/2003/happiness-is-a-warm-tiger</id>
    <title type="html"><![CDATA[Happiness is a Warm Tiger]]></title>
    <updated>2008-01-26T05:58:21Z</updated>
    <published>2005-05-04T05:51:02Z</published>
    <author>
      <name>Dethe</name>
      <email>delza@livingcode.org</email>
<uri>http://livingcode.org/</uri>    </author>
    <link rel="replies" type="application/atom+xml" href="http://livingcode.org/2005/05/03/happiness-is-a-warm-tiger/feed" thr:count="0"  />
    <link rel="alternate" href="http://livingcode.org/2005/05/03/happiness-is-a-warm-tiger" />
    <category scheme="http://livingcode.org" term="Mac" />
    <summary type="html"><![CDATA[My copy of Mac OS 10.4 arrived Friday, right on schedule. I spent the weekend backing up my laptop, doing a clean install, and then restoring my data, which also fixed the problem I&#8217;ve been having where applications take a really long time to launch. No problems so far and performance is noticeably faster. You [...]]]></summary>
      <content type="html" xml:base="http://livingcode.org/2005/05/03/happiness-is-a-warm-tiger"><![CDATA[<p>My copy of Mac OS 10.4 arrived Friday, right on schedule. I spent the weekend backing up my laptop, doing a clean install, and then restoring my data, which also fixed the problem I&#8217;ve been having where applications take a really long time to launch. No problems so far and performance is noticeably faster. You gotta love an OS where each update makes your existing hardware faster.</p>
<p>First impressions: Spotlight searching really is as fast as they claim, Dashboard is neat in a gee-whiz sort of way, but I&#8217;m not sure how much I&#8217;ll actually use it. The built-in dictionary and thesaurus are welcome additions. I&#8217;m sure with time I will come to use smart folders in both the Finder and Mail. But for me the real juice in this version is underneath the hood in the development tools.</p>
<p>I&#8217;ve had a few secret hopes for Tiger, for things which have not been announced, but might be slipped under the door. Three of them were: NSOutlineView gaining support for varying row height (to make it easier to write applications like OmniOutline), improved Cocoa support for QuickTime, and being able to round-trip Nibs to text format and back via nibtool. Well, two out of three ain&#8217;t bad. The NSOutline now supports row height via it&#8217;s delegate method <a href="http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/ObjC_classic/Classes/NSOutlineView.html#//apple_ref/doc/uid/20000110-BABHDHAE%22">heightOfRow:ofItem:</a>, the <a href="http://developer.apple.com/documentation/QuickTime/Reference/QTCocoaObjCKit/index.html#//apple_ref/doc/uid/TP40001164">QTKit</a> framework provides excellent support for QuickTime media from Cocoa (and thus from PyObjC), but alas, nibs cannot be created from text input via <a href="http://developer.apple.com/documentation/Darwin/Reference/ManPages/man1/nibtool.1.html">nibtool</a> (or any other tool that I&#8217;m aware of), although the nibtool man page does at least list this deficiency as a known bug.</p>
<p>But there is more good news in the <a href="http://developer.apple.com/documentation/GraphicsImaging/Reference/CoreImagingRef/index.html">Core Image</a>, <a href="http://developer.apple.com/documentation/MusicAudio/Reference/CoreAudio/book_intro/chapter_1_section_1.html">Core Audio</a>, and <a href="http://developer.apple.com/documentation/GraphicsImaging/Reference/CoreImagingRef/index.html">Core Data</a> frameworks. Core Image gives fast, powerful graphic processing and pipelining tools for both still images and video. Core Audio does the same for sound. And while Mac development in the Model-View-Controller (MVC) has been supported via Interface Builder (View), NSArrayController and NSObjectController (Controller), now with Core Data the Model portion is fully supported as well. Bill Bumgarner has a welcome <a href="http://www.pycs.net/bbum/2005/5/1/">example</a> on his blog of how to use CoreData from Python.</p>
<p>But wait, there&#8217;s more! There&#8217;s an <a href="http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/ObjC_classic/Classes/NSTreeController.html#//apple_ref/occ/cl/NSTreeController">NSTreeController</a> to go along with the NSArrayController and friends. There are hooks and documentation for many more of the Apple-supplied applications, including the new <a href="http://developer.apple.com/documentation/Cocoa/Reference/SyncServicesRef_ObjC/index.html">Sync Services</a>. And PyObjC now has wrappers for Core Data, Automator, XGrid, and Sync Services. And that&#8217;s not to mention the improved WebKit, new features of NSTextView, and much more. It&#8217;s a great time to be a Mac developer, and being able to do all this from Python really ices the cake for me.</p>
]]></content>
        </entry>
    <entry>
    <id>http://livingcode.org/2005/coming-attractions</id>
    <title type="html"><![CDATA[Coming attractions]]></title>
    <updated>2008-01-25T06:10:19Z</updated>
    <published>2005-02-26T06:06:57Z</published>
    <author>
      <name>Dethe</name>
      <email>delza@livingcode.org</email>
<uri>http://livingcode.org/</uri>    </author>
    <link rel="replies" type="application/atom+xml" href="http://livingcode.org/2005/02/25/coming-attractions/feed" thr:count="0"  />
    <link rel="alternate" href="http://livingcode.org/2005/02/25/coming-attractions" />
    <category scheme="http://livingcode.org" term="Python" />
    <summary type="html"><![CDATA[I&#8217;m slowly making progress on ZenPaint, a simple animation tool for kids. I started writing it using PyGame, but hit the wall in terms of display, having to redefine my own widgets, etc. So I&#8217;ve taken a couple of step back and now I&#8217;m working on it using PyObjC. I keep waffling back and forth [...]]]></summary>
      <content type="html" xml:base="http://livingcode.org/2005/02/25/coming-attractions"><![CDATA[<p>I&#8217;m slowly making progress on ZenPaint, a simple animation tool for kids. I started writing it using PyGame, but hit the wall in terms of display, having to redefine my own widgets, etc. So I&#8217;ve taken a couple of step back and now I&#8217;m working on it using PyObjC. I keep waffling back and forth on whether to use Interface Builder or not. I don&#8217;t find Interface Builder very intuitive at all, but maybe I need to buckle down and get good at it. Knowing about nibtool helps&#8211;at least I can do text diffs and simple renames from the command-line.</p>
<p>One thing I would like to point out, the Apple <a href="http://developer.apple.com/releasenotes/Cocoa/NSDocumentFAQ.html">NSDocument FAQ</a> is one of the best bits of documentation I&#8217;ve ever seen out of Apple. So I&#8217;m mentally translating it into Python and trying to apply it to ZenPaint. As soon as I can load and save files reliably I&#8217;ll post the program and code up here for comments.</p>
]]></content>
        </entry>
    <entry>
    <id>http://livingcode.org/2005/slides-up</id>
    <title type="html"><![CDATA[Slides up]]></title>
    <updated>2008-01-25T06:25:56Z</updated>
    <published>2005-02-11T06:13:12Z</published>
    <author>
      <name>Dethe</name>
      <email>delza@livingcode.org</email>
<uri>http://livingcode.org/</uri>    </author>
    <link rel="replies" type="application/atom+xml" href="http://livingcode.org/2005/02/10/slides-up/feed" thr:count="0"  />
    <link rel="alternate" href="http://livingcode.org/2005/02/10/slides-up" />
    <category scheme="http://livingcode.org" term="Python" />
    <summary type="html"><![CDATA[After much delay, my slides are finally up from the VanPyZ talk last week.
Using Python and Cocoa on OS X 
Again I&#8217;m using Eric Meyer&#8217;s S5 tool for HTML slides, but it still ends up being a large download because it includes a completely unneccesary quicktime movie. My daughter and I have been playing with [...]]]></summary>
      <content type="html" xml:base="http://livingcode.org/2005/02/10/slides-up"><![CDATA[<p>After much delay, my slides are finally up from the VanPyZ talk last week.</p>
<p><a href="http://livingcode.org/slides/cocoa.html">Using Python and Cocoa on OS X </a></p>
<p>Again I&#8217;m using Eric Meyer&#8217;s S5 tool for HTML slides, but it still ends up being a large download because it includes a completely unneccesary quicktime movie. My daughter and I have been playing with iStopMotion and this was one of our first forays into claymation.</p>
<p>The reason it&#8217;s in the slideshow, is that movie making is now completely accessible to an eight-year-old, and I want to writing games and other programs equally accessible to her.</p>
<p>Still a ways to go&#8230;</p>
]]></content>
        </entry>
  </feed>
