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

<channel>
	<title>ptone &#187; Random Observation</title>
	<atom:link href="http://ptone.com/dablog/category/random/feed/" rel="self" type="application/rss+xml" />
	<link>http://ptone.com/dablog</link>
	<description>Hodgepodge of thoughts, technical notes, and random observations</description>
	<lastBuildDate>Sat, 04 Jun 2011 14:42:35 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.5</generator>
		<item>
		<title>Broker Django do-gooders</title>
		<link>http://ptone.com/dablog/2011/02/broker-django-do-gooders/</link>
		<comments>http://ptone.com/dablog/2011/02/broker-django-do-gooders/#comments</comments>
		<pubDate>Mon, 28 Feb 2011 19:47:00 +0000</pubDate>
		<dc:creator>ptone</dc:creator>
				<category><![CDATA[Random Observation]]></category>

		<guid isPermaLink="false">http://ptone.com/dablog/?p=162</guid>
		<description><![CDATA[The Problems Small and growing charities have many operational and communications needs that would be well served with custom Django apps. At the same time there are many budding developers who are looking for real projects, not contrived tutorials to learn with. There are also a number of busy experienced developers who still have a [...]]]></description>
			<content:encoded><![CDATA[<div class="document">


<div class="section" id="the-problems">
<h2>The Problems</h2>
<p>Small and growing charities have many operational and communications needs that would be well served with custom Django apps.  At the same time there are many budding developers who are looking for real projects, not contrived tutorials to learn with.  There are also a number of busy experienced developers who still have a bit a spare time and have a strong moral core.</p>
</div>
<div class="section" id="a-possible-solution">
<h2>A Possible solution</h2>
<p>A site that connects worthy organizations with willing developers.
Charities/Groups put together proposals about what they need &#8211; clarity counts.
They must provide a contact/liason.</p>
<p>Developers can register, but their contact info is not shared with charities.  This is developer centric.</p>
<p>Everything must be open source (is license type specified?)
Can stipulate that some form of credit banner for project be placed on final
result such a credit would list this project (the broker project) and hosting
co, and would link to a project page listing all contributors</p>
<p>Provide github organization repo page utilyze issue tracker and read-the-docs what other collaboration tools could be used? a donated basecamp?  could leverage donated deployment options (with advertising credit)</p>
<dl class="docutils">
<dt>Roles of people helping out:</dt>
<dd><ul class="first last simple">
<li>developer python/django</li>
<li>front end designer</li>
<li>mentor</li>
<li>project manager</li>
</ul>
</dd>
</dl>
<p>Can look at the GSOC mentor model</p>
<p>Could have developers and community members vote for most worthy</p>
<p>Could have sprints for charities
How to verify groups/501c3 (can search IRS pub 78)</p>
<p>Limit this to smaller groups initially, based on cashflows? # employees?
Initially limit this to US Domestic agencies (even if they have international
projects)</p>
</div>
<div class="section" id="the-challenges">
<h2>The Challenges</h2>
<p>Would there be anything approaching equilibrium in supply and demand &#8211; or would the demand swamp the process?  Could filters/voting systems fix this?</p>
<p>How to ensure that organizations that CAN afford to hire developrs do, and not take advantage.</p>
<p>How to ensure that code quality is reasonable?
How to follow up with improvements, changes, and training?</p>
</div>
</div>

<p><a href="https://convore.com/django-community/bringing-together-django-devs-and-charities/"><h4>Discuss Here</h4></a></p>
]]></content:encoded>
			<wfw:commentRss>http://ptone.com/dablog/2011/02/broker-django-do-gooders/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MIDI to DMX light chases</title>
		<link>http://ptone.com/dablog/2010/11/midi-to-dmx-light-chases/</link>
		<comments>http://ptone.com/dablog/2010/11/midi-to-dmx-light-chases/#comments</comments>
		<pubDate>Thu, 04 Nov 2010 07:14:38 +0000</pubDate>
		<dc:creator>ptone</dc:creator>
				<category><![CDATA[Random Observation]]></category>

		<guid isPermaLink="false">http://ptone.com/dablog/2010/11/midi-to-dmx-light-chases/</guid>
		<description><![CDATA[As a follow on the previous post &#8211; I wanted to demonstrate how the individual lights (with all their own features) can not only be grouped into a simple synchronized group &#8211; but they can be added into a &#8220;sequence&#8221; container which will operate a chase. This also shows the type of interactive control provided [...]]]></description>
			<content:encoded><![CDATA[<p>As a follow on the previous post &#8211; I wanted to demonstrate how the individual lights (with all their own features) can not only be grouped into a simple synchronized group &#8211; but they can be added into a &#8220;sequence&#8221; container which will operate a chase.  This also shows the type of interactive control provided by MIDI hardware.</p>

<p><span id="more-160"></span>
Here is a video demonstrating some of the features, remember the lights on screen are just simple proxy lights for demo purposes.  The main output is realtime DMX &#8211; which is an already working feature, I just don&#8217;t have it hooked up to light gear yet.</p>

<p><object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/deP9JoYJLpw?fs=1&amp;hl=en_US"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/deP9JoYJLpw?fs=1&amp;hl=en_US" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object></p>

<p>Here is the code listing that created the demo sequence elements:</p>

<div class="highlight" ><pre><span style="color: #60a0b0; font-style: italic">#!/usr/bin/env python</span>
<span style="color: #60a0b0; font-style: italic"># encoding: utf-8</span>

<span style="color: #007020; font-weight: bold">from</span> <span style="color: #0e84b5; font-weight: bold">midi_reader</span> <span style="color: #007020; font-weight: bold">import</span> MidiDispatcher
<span style="color: #007020; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">time</span>
<span style="color: #007020; font-weight: bold">from</span> <span style="color: #0e84b5; font-weight: bold">lights</span> <span style="color: #007020; font-weight: bold">import</span> <span style="color: #666666">*</span>
<span style="color: #007020; font-weight: bold">import</span> <span style="color: #0e84b5; font-weight: bold">sys</span>


<span style="color: #60a0b0; font-style: italic"># create a light show - manages the updating of all lights</span>
show <span style="color: #666666">=</span> LightShow()

light_seqA <span style="color: #666666">=</span> LightSequence()
light_seqB <span style="color: #666666">=</span> LightSequence()
light_seqC <span style="color: #666666">=</span> LightSequence()
light_seqD <span style="color: #666666">=</span> LightSequence()


<span style="color: #60a0b0; font-style: italic"># create our 8 lights and add them to each sequence and the show</span>
<span style="color: #007020; font-weight: bold">for</span> i <span style="color: #007020; font-weight: bold">in</span> <span style="color: #007020">range</span>(<span style="color: #40a070">1</span>,<span style="color: #40a070">9</span>):
    l <span style="color: #666666">=</span> LightUnit(channels<span style="color: #666666">=</span>[i])
    l<span style="color: #666666">.</span>release <span style="color: #666666">=</span> <span style="color: #666666">.</span><span style="color: #40a070">3</span>
    show<span style="color: #666666">.</span>lights<span style="color: #666666">.</span>append(l)
    light_seqA<span style="color: #666666">.</span>elements<span style="color: #666666">.</span>append(SequenceElement(l))
    light_seqB<span style="color: #666666">.</span>elements<span style="color: #666666">.</span>append(SequenceElement(l))
    light_seqC<span style="color: #666666">.</span>elements<span style="color: #666666">.</span>append(SequenceElement(l))
    light_seqD<span style="color: #666666">.</span>elements<span style="color: #666666">.</span>append(SequenceElement(l))

<span style="color: #60a0b0; font-style: italic"># add the sequences themselves to the show</span>
show<span style="color: #666666">.</span>lights<span style="color: #666666">.</span>append(light_seqA)
show<span style="color: #666666">.</span>lights<span style="color: #666666">.</span>append(light_seqB)
show<span style="color: #666666">.</span>lights<span style="color: #666666">.</span>append(light_seqC)
show<span style="color: #666666">.</span>lights<span style="color: #666666">.</span>append(light_seqD)


<span style="color: #60a0b0; font-style: italic"># set up the midi communication thread</span>
dispatcher <span style="color: #666666">=</span> MidiDispatcher(<span style="color: #40a070">0</span>)

light_seqA<span style="color: #666666">.</span>speed_control <span style="color: #666666">=</span> <span style="color: #666666">.</span><span style="color: #40a070">01</span>
light_seqA<span style="color: #666666">.</span>duration <span style="color: #666666">=</span> <span style="color: #40a070">0</span>
light_seqA<span style="color: #666666">.</span>on_off_trigger <span style="color: #666666">=</span> <span style="color: #4070a0">&quot;reverse&quot;</span>
<span style="color: #60a0b0; font-style: italic"># set_message is a way of mapping a message to an attribute</span>
light_seqA<span style="color: #666666">.</span>set_message((<span style="color: #40a070">176</span>, <span style="color: #40a070">14</span>),[<span style="color: #4070a0">&#39;speed_control&#39;</span>])
light_seqA<span style="color: #666666">.</span>max_speed <span style="color: #666666">=</span> <span style="color: #666666">.</span><span style="color: #40a070">5</span>

light_seqB<span style="color: #666666">.</span>speed_control <span style="color: #666666">=</span> <span style="color: #666666">.</span><span style="color: #40a070">01</span>
light_seqB<span style="color: #666666">.</span>duration <span style="color: #666666">=</span> <span style="color: #40a070">0</span>
light_seqB<span style="color: #666666">.</span>on_off_trigger <span style="color: #666666">=</span> <span style="color: #4070a0">&quot;sequence&quot;</span>


light_seqC<span style="color: #666666">.</span>speed_control <span style="color: #666666">=</span> <span style="color: #666666">.</span><span style="color: #40a070">3</span>
light_seqC<span style="color: #666666">.</span>duration <span style="color: #666666">=</span> <span style="color: #666666">-</span><span style="color: #40a070">1</span>
light_seqC<span style="color: #666666">.</span>max_speed <span style="color: #666666">=</span> <span style="color: #666666">.</span><span style="color: #40a070">5</span>
light_seqC<span style="color: #666666">.</span>max_duration <span style="color: #666666">=</span> <span style="color: #666666">.</span><span style="color: #40a070">5</span>
light_seqC<span style="color: #666666">.</span>set_message((<span style="color: #40a070">176</span>, <span style="color: #40a070">15</span>),[<span style="color: #4070a0">&#39;speed_control&#39;</span>])
light_seqC<span style="color: #666666">.</span>set_message((<span style="color: #40a070">176</span>, <span style="color: #40a070">16</span>),[<span style="color: #4070a0">&#39;duration_control&#39;</span>])



light_seqD<span style="color: #666666">.</span>elements<span style="color: #666666">.</span>reverse()
light_seqD<span style="color: #666666">.</span>speed_control <span style="color: #666666">=</span> <span style="color: #666666">.</span><span style="color: #40a070">3</span>
light_seqD<span style="color: #666666">.</span>duration <span style="color: #666666">=</span> <span style="color: #666666">-</span><span style="color: #40a070">1</span>

dispatcher<span style="color: #666666">.</span>add_observer((<span style="color: #40a070">144</span>, <span style="color: #40a070">42</span>), light_seqA)
dispatcher<span style="color: #666666">.</span>add_observer((<span style="color: #40a070">176</span>, <span style="color: #40a070">14</span>), light_seqA)
dispatcher<span style="color: #666666">.</span>add_observer((<span style="color: #40a070">176</span>, <span style="color: #40a070">15</span>), light_seqC)
dispatcher<span style="color: #666666">.</span>add_observer((<span style="color: #40a070">176</span>, <span style="color: #40a070">16</span>), light_seqC)
dispatcher<span style="color: #666666">.</span>add_observer((<span style="color: #40a070">144</span>, <span style="color: #40a070">44</span>), light_seqB)
dispatcher<span style="color: #666666">.</span>add_observer((<span style="color: #40a070">144</span>, <span style="color: #40a070">54</span>), light_seqC)
dispatcher<span style="color: #666666">.</span>add_observer((<span style="color: #40a070">144</span>, <span style="color: #40a070">49</span>), light_seqD)



<span style="color: #60a0b0; font-style: italic"># startup the midi communication</span>
dispatcher<span style="color: #666666">.</span>start()

<span style="color: #60a0b0; font-style: italic"># this defaults to true for certain equipment</span>
show<span style="color: #666666">.</span>dmx_keep_alive <span style="color: #666666">=</span> <span style="color: #007020">False</span>
<span style="color: #60a0b0; font-style: italic"># run the show</span>
<span style="color: #007020; font-weight: bold">try</span>:
    show<span style="color: #666666">.</span>run_live()
<span style="color: #007020; font-weight: bold">except</span> <span style="color: #007020">KeyboardInterrupt</span>:
    <span style="color: #60a0b0; font-style: italic"># cleanup</span>
    dispatcher<span style="color: #666666">.</span>stop()
    sys<span style="color: #666666">.</span>exit(<span style="color: #40a070">0</span>)
</pre></div>
]]></content:encoded>
			<wfw:commentRss>http://ptone.com/dablog/2010/11/midi-to-dmx-light-chases/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>An object oriented approach to light show sequencing</title>
		<link>http://ptone.com/dablog/2010/11/an-object-oriented-approach-to-light-show-sequencing/</link>
		<comments>http://ptone.com/dablog/2010/11/an-object-oriented-approach-to-light-show-sequencing/#comments</comments>
		<pubDate>Tue, 02 Nov 2010 21:13:32 +0000</pubDate>
		<dc:creator>ptone</dc:creator>
				<category><![CDATA[Random Observation]]></category>

		<guid isPermaLink="false">http://ptone.com/dablog/2010/11/an-object-oriented-approach-to-light-show-sequencing/</guid>
		<description><![CDATA[There is a large hobbiest community out there of people putting together light shows synchronized to music. These are mostly around xmas string lights during the holidays. The lights are controlled via a hardware board that takes signals from a computer and operates multiple dimmers to control the brightness of the lights. These dimmers range [...]]]></description>
			<content:encoded><![CDATA[<p>There is a large hobbiest community out there of people putting together light shows synchronized to music.  These are mostly around xmas string lights during the holidays.</p>

<p>The lights are controlled via a hardware board that takes signals from a computer and operates multiple dimmers to control the brightness of the lights.  These dimmers range in the number of channels, but can be connected together to add more channel capacity.  It is not unusual to have hundreds of channels in a residential size show.</p>

<p>The sequencing of these dimmer channels is generally done with software that divides the show into a set of time chunks represented as columns, with each channel being a row &#8211; resulting in a grid.  To sequence a show, a light intensity level needs to be set for each chunk of time, usually many per second, for many channels.  This grid can be huge and time consuming to fill, and doesn&#8217;t seem an intuitive canvas to experiment with creativity in response to the music.  I thought there should be a better way.</p>

<p><span id="more-156"></span>
I&#8217;m not alone.  The problem with the grid and a hope for a better way are well outlined in this piece called &#8220;<a href="http://www.planetchristmas.com/magazine/Spring2010/index.htm#/18/">The Death of the Grid</a>&#8220;, which I did not discover till after I started down this path.</p>

<p>Other approaches that try to abstract away the grid is in development software called <a href="http://diylightanimation.com/index.php?topic=3290.0">Prancer</a>, and commercial software LightShow Pro which takes an interesting approach of using video images mapped to a light layout called <a href="http://vimeo.com/11969010">layer transitions</a>.</p>

<p>Being on a Mac and a Python programmer, I wanted to look at coming up with an easy way to create expressive sequences on my gear without too much work.</p>

<p>Now there is an existing protocol for capturing musical expressiveness via computer and that is the MIDI protocol which was designed to capture the act of playing a musical instrument into a digital signal.  I felt like this was a good input protocol to adopt, as there is lots of hardware out there to support it, and it was built to capture an expressive range of actions.  This would need to be converted into DMX &#8211; which is the protocol that controls the lights (there are other lighting protocols, but DMX seems to be the main non-proprietary standard, and the smartest to work with).</p>

<p>Now each protocol has its own features, and they are not a perfect match &#8211; but they are good enough.  Midi has 16 channels, each with 127 notes, and a whole mess of controller channels (see <a href="http://www.midi.org/techspecs/midimessages.php">here</a>) with a message data value range of 0-127.  DMX consists of a universe of 512 channels, with values of 0-255.</p>

<p>What I wanted to write was something that abstracts the channels of DMX involved in a set of lights, creating light objects (which may consist of one or more physical light sets), and allow these to be controlled expressively through MIDI.</p>

<p><img src="http://ptone.com/dablog/wp-content/uploads/2010/11/program_structure.png" alt="Program Structure" /></p>

<p>Now I&#8217;m not the first to consider the combination of midi and dmx &#8211; the most comprehensive review is <a href="http://www.innovateshowcontrols.com/support/downloads/midi-dmx.pdf">this paper</a> (but also see (<a href="http://response-box.com/gear/decabox-midi-to-dmx-bridge/">1</a>,<a href="http://www.anyma.ch/2007/research/udmx-midi-interface-10/">2</a>,<a href="http://www.chromakinetics.com/DMX/miniStageConsoleMac.html">3</a>, and I&#8217;m sure others).  I felt there was still a lot of room of putting a higher level of abstraction between the basics of MIDI notes to DMX channels.</p>

<p>Here are two quick screen captures showing the start of this project in action (if you have quicktime, you can just copy the URLs and open them directly in quicktime player)</p>

<p>The first shows just the basics of a simple light setup:</p>

<p><a href="http://www.ptone.com/lights_demo/single%20light.mov">A single light</a></p>

<p>The second shows the addition of a couple more lights, and a couple methods of creating simple groups</p>

<p><a href="http://www.ptone.com/lights_demo/three%20lights.mov">Three Lights</a></p>

<p>Here is more information about the <a href="http://en.wikiaudio.org/ADSR_envelope">A.ttack D.ecay S.ustain R.elease envelope</a></p>

<p>The remaining features I have implemented or planned are:</p>

<ul>
<li>combining lights or light groups into a &#8220;sequence&#8221; (not to be confused with a show sequence &#8211; more of a chase sequence).  These sequences have parameters like duration and speed, loop patterns etc.</li>
<li>Calculating RGB values for Hue, and blending between them over time or space.</li>
<li>Adding physics tween motion &#8211; such as acceleration, bounce, or elastic to sequence groups.</li>
</ul>

<p>The idea will be to record multiple &#8220;live sessions&#8221; and then merge them.  The complexity may prevent the realtime processing of the midi-track into DMX &#8211; and so a MIDI file would be compiled against a show setup to produce either a vixen sequence, or some other similar DMX &#8220;player file&#8221; (really just binary data of chunks of 512byte DMX data).</p>

<p>This will eventually all be open sourced.  I&#8217;m not planning on any GUI at the moment, I hope to come up with a clean API that actually makes it pretty easy to write out the scripts.</p>
]]></content:encoded>
			<wfw:commentRss>http://ptone.com/dablog/2010/11/an-object-oriented-approach-to-light-show-sequencing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://www.ptone.com/lights_demo/single%20light.mov" length="48974641" type="video/quicktime" />
<enclosure url="http://www.ptone.com/lights_demo/three%20lights.mov" length="37214717" type="video/quicktime" />
		</item>
		<item>
		<title>Easy Django choices done right</title>
		<link>http://ptone.com/dablog/2010/05/easy-django-choices-done-right/</link>
		<comments>http://ptone.com/dablog/2010/05/easy-django-choices-done-right/#comments</comments>
		<pubDate>Mon, 10 May 2010 18:26:48 +0000</pubDate>
		<dc:creator>ptone</dc:creator>
				<category><![CDATA[Random Observation]]></category>

		<guid isPermaLink="false">http://ptone.com/dablog/2010/05/easy-django-choices-done-right/</guid>
		<description><![CDATA[In a old, but still relevant post James Bennet argues for a way of handling the choice tuples used by Django. One of the reasons I haven&#8217;t always followed that advice was that it was just a lot of extra mundane keystrokes, and I&#8217;m lazy. It was well suited for a quick Python hack, and [...]]]></description>
			<content:encoded><![CDATA[<p>In a <a href="http://www.b-list.org/weblog/2007/nov/02/handle-choices-right-way/">old, but still relevant post</a> James Bennet argues for a way of handling the choice tuples used by Django.  One of the reasons I haven&#8217;t always followed that advice was that it was just a lot of extra mundane keystrokes, and I&#8217;m lazy.  It was well suited for a quick Python hack, and I now use the script below as a TextMate bundle so that I can just type in a list and have it converted to &#8220;the right way&#8221;.</p>

<p><span id="more-152"></span>
Here is the snippet:</p>

<pre><code>#!/usr/bin/env python
# encoding: utf-8


import os
import re
from sys import stdout, stdin, exit

display_list = stdin.read()
explicit = 1


def sanitize_enum(s):
    # @@ plenty to improve here
    s = s.upper().strip(' ()')
    s = re.sub('^[-\d ]+','',s)
    s = re.sub('[./() \-]', "_",s)
    while re.search('__',s):
        s = s.replace('__','_')
    return s

def format_choice(t):
    return "    ( %s, '%s' )," % t


choices = []
i = 1

for choice in display_list.split('\n'):
    if choice:
        if explicit:
            sanitized = sanitize_enum(choice)
            print "%s = %s" % (sanitized,i)
            choices.append((sanitized,choice.strip()))
        else:
            choices.append((i,choice.strip()))
        i+=1

print "choices = ("
for c in choices:
    print format_choice(c)
print "    )"
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://ptone.com/dablog/2010/05/easy-django-choices-done-right/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Turning a Mac Lab into a disc burning machine</title>
		<link>http://ptone.com/dablog/2010/03/turning-a-mac-lab-into-a-disc-burning-machine/</link>
		<comments>http://ptone.com/dablog/2010/03/turning-a-mac-lab-into-a-disc-burning-machine/#comments</comments>
		<pubDate>Fri, 12 Mar 2010 18:54:36 +0000</pubDate>
		<dc:creator>ptone</dc:creator>
				<category><![CDATA[Random Observation]]></category>

		<guid isPermaLink="false">http://ptone.com/dablog/2010/03/turning-a-mac-lab-into-a-disc-burning-machine/</guid>
		<description><![CDATA[Have a lab of Macs &#8211; need to burn a bunch of CD or DVDs? Harness those monkeys! No one part of this solution is all that earth shattering, but it is a simple clever combination of steps. So you have a bunch of Macs in a lab &#8211; you have Network accounts and server [...]]]></description>
			<content:encoded><![CDATA[<p>Have a lab of Macs &#8211; need to burn a bunch of CD or DVDs?  Harness those monkeys!</p>

<p><span id="more-147"></span>
No one part of this solution is all that earth shattering, but it is a simple clever combination of steps.</p>

<p>So you have a bunch of Macs in a lab &#8211; you have Network accounts and server based home folders working, and a fast network.  Here are the steps to turn that lab into a fast burn factory for optical disks.</p>

<ul>
<li><p>First, create a network home folder user, I call mine burn.</p></li>
<li><p>Set a few settings for that user, such as to ignore blank media when inserted.</p></li>
<li><p>Create your master .img .dmg or .cdr lets call it &#8216;burnme.img&#8217;, on any machine and then copy it to the Desktop of the burn user.</p></li>
<li><p>Create a burn.command file on the Desktop whose contents is:</p></li>
</ul>

<p>burn.command (make executable):</p>

<pre><code>#!/bin/bash
hdiutil burn ~/Desktop/burnme.img
</code></pre>

<p>Now you can execute two sets of commands through ARD.  The first will log a set of machines in as the burn user (you need to enable assistive devices in UniAccess prefs for this to work):</p>

<pre><code>osascript -e 'tell application "System Events" to keystroke "burn"'; \
osascript -e 'tell application "System Events" to keystroke tab'; \
osascript -e 'tell application "System Events" to delay 0.5'; \
osascript -e 'tell application "System Events" to keystroke "burn"'; \
osascript -e 'tell application "System Events" to delay 0.5'; \
osascript -e 'tell application "System Events" to keystroke return'
</code></pre>

<p>The next ARD UNIX command is a simple command to execute the burning:</p>

<pre><code>open ~/Desktop/burn.command
</code></pre>

<p>Using the combo of the open command with a command file will give you the visual feedback on each machine, as well as return from the ARD task immediately.</p>

<p>The hdiutil command will even wait for media to be inserted if you execute the above before a blank disc is inserted.</p>

<p>I believe hdiutil also uses buffer under-run protection so even if you hit a network bottleneck &#8211; you shouldn&#8217;t end up with coasters.  On a gigabit connection I&#8217;ve done up to 13 machines at the same time no problem.</p>
]]></content:encoded>
			<wfw:commentRss>http://ptone.com/dablog/2010/03/turning-a-mac-lab-into-a-disc-burning-machine/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Bash completion for diskutil (and others&#8230;)</title>
		<link>http://ptone.com/dablog/2010/03/bash-completion-for-diskutil-and-others/</link>
		<comments>http://ptone.com/dablog/2010/03/bash-completion-for-diskutil-and-others/#comments</comments>
		<pubDate>Fri, 12 Mar 2010 17:58:25 +0000</pubDate>
		<dc:creator>ptone</dc:creator>
				<category><![CDATA[Random Observation]]></category>

		<guid isPermaLink="false">http://ptone.com/dablog/2010/03/bash-completion-for-diskutil-and-others/</guid>
		<description><![CDATA[A few of the tools I use have spent some time working up bash completing. django-admin and virtualenvwrapper to name two. As a Mac sysadmin I use a number of CLI tools for stuff, and was interested in working up some bash completion for these. I picked diskutil for starters as its one I use [...]]]></description>
			<content:encoded><![CDATA[<p>A few of the tools I use have spent some time working up bash completing.  django-admin and virtualenvwrapper to name two.  As a Mac sysadmin I use a number of CLI tools for stuff, and was interested in working up some bash completion for these.</p>

<p><span id="more-142"></span>
I picked diskutil for starters as its one I use with some regularity on my personal machine (mainly for force unmounting stubborn volumes) as well it has a pretty basic verb set.  Other candidates to apply this two would be hdiutil, severadmin, dscl &#8211; I&#8217;m sure there are a bunch.  It would be interesting to work these up into a single package someday if the effort can ever be marshalled.</p>

<p>I borrowed the approach used in Django of having the completion choices be determined by a python script as it is much more pleasant (for me) to put together any logic or algorithms in Python vs Bash.  The same approach could be used with Ruby, Perl, etc.</p>

<p>You can find the project <a href="http://bitbucket.org/ptone/diskutil_completion/">here</a></p>

<p>Click below to watch a micro screencast:
<a href="http://ptone.com/misc/diskutilcomplete/"><img src="http://ptone.com/dablog/wp-content/uploads/2010/03/diskutilcomplete_poster.jpg"></a></p>
]]></content:encoded>
			<wfw:commentRss>http://ptone.com/dablog/2010/03/bash-completion-for-diskutil-and-others/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Integrating a paper based stage in a digital workflow with Django and QR code</title>
		<link>http://ptone.com/dablog/2010/03/integrating-a-paper-based-stage-in-a-digital-workflow-with-django-and-qr-code/</link>
		<comments>http://ptone.com/dablog/2010/03/integrating-a-paper-based-stage-in-a-digital-workflow-with-django-and-qr-code/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 00:41:50 +0000</pubDate>
		<dc:creator>ptone</dc:creator>
				<category><![CDATA[Random Observation]]></category>

		<guid isPermaLink="false">http://ptone.com/dablog/2010/03/integrating-a-paper-based-stage-in-a-digital-workflow-with-django-and-qr-code/</guid>
		<description><![CDATA[There are several procedural things at work that still involve a signature, or hand written note on a piece of paper. This reality has made it hard to digitize these practices. While much of the process could be replace with a web app, with plenty of benefits. The reality is that because the paper step [...]]]></description>
			<content:encoded><![CDATA[<p>There are several procedural things at work that still involve a signature, or hand written note on a piece of paper.  This reality has made it hard to digitize these practices.  While much of the process could be replace with a web app, with plenty of benefits.  The reality is that because the paper step is required, the process would become disjointed.  One way to reconcile the paper with the digital record, is to scan in the signed document and attach it to the digital record.  However this doesn&#8217;t pass my &#8220;ugh&#8221; test in that even with ajax, manually attaching scanned documents to the correct record is still a tedious process.  That is where qrcode comes in.</p>

<p><span id="more-140"></span>
<a href="http://en.wikipedia.org/wiki/QRcode">QR Code</a> is a 2 dimensional matrix code invented in Japan that has qualities of easy machine recognition.  The idea is that if the paper document is printed with a qrcode, then a computer could later do the work of attaching the scan back to the record. So the qrcode becomes the bridge between the digital and paper steps of the process.  The item could even switch between the two multiple times (ie to get multiple signatures in different locations).</p>

<p>I put together a quick django proof of concept that illustrates all the steps.</p>

<p>Briefly:</p>

<ul>
<li>a Django view prints a item-document with a generated qrcode in a corner of the page</li>
<li>an item has a filefield to store a scanned document</li>
<li>a cron script that loads up the Django environment looks through the scanned documents, decodes the qrcode, and matches them up with the django object</li>
</ul>

<p>The qrencoding is done with google charts (no hassle of a cached image), and the decode is done with <a href="http://pyqrcode.sourceforge.net/">pyqrcode</a>.  Note that the pyqrcode project doesn&#8217;t have an egg for 10.6, but I put one together <a href="http://ptone.com/temp/qrcode-0.2.1-py2.6-macosx-10.6-universal.egg.gz">here</a>.  A little ghostscript love can be used to convert PDF for the decoding step.</p>

<p>Many workplaces now have copiers with built in scanners that can scan a pile of documents with ease, making the effort to attach documents back to the object from where they came pretty easy.  There are also iPhone and phone apps that will open the embedded URL, which could be used to pull up a &#8220;quick action&#8221; list for the item.  I haven&#8217;t seen anything like that for iSight cameras &#8211; which is too bad.</p>

<p>So if you are interested in the proof of concept (it is bare bones, but does cover all the core steps you can grab it <a href="http://ptone.com/temp/qrcode-experiment.tgz">here</a> (if you don&#8217;t know python/django &#8211; you&#8217;re going to be a bit lost if you download it &#8211; sorry).  There is one hardcoded path in the link.py script which is what you run to do the importing (ie called from cron).  Now I just have to see if I can find time to actually get some apps that use this written.</p>
]]></content:encoded>
			<wfw:commentRss>http://ptone.com/dablog/2010/03/integrating-a-paper-based-stage-in-a-digital-workflow-with-django-and-qr-code/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Kevin Nails it</title>
		<link>http://ptone.com/dablog/2010/02/kevin-nails-it/</link>
		<comments>http://ptone.com/dablog/2010/02/kevin-nails-it/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 19:49:01 +0000</pubDate>
		<dc:creator>ptone</dc:creator>
				<category><![CDATA[Random Observation]]></category>

		<guid isPermaLink="false">http://ptone.com/dablog/2010/02/kevin-nails-it/</guid>
		<description><![CDATA[The Django Advent site is proving to be some great writing. The recent piece by Kevin Fricovsky hits the nail on the head in so many ways. Basically he is highlighting some areas for growth when it comes to the process of combining, in an efficient way, multiple reusable Django apps. He covers the following [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://djangoadvent.com/">Django Advent</a> site is proving to be some great writing.  The <a href="http://djangoadvent.com/1.2/everything-i-hate-about-mingus/">recent piece</a> by <a href="http://blog.montylounge.com/">Kevin Fricovsky</a> hits the nail on the head in so many ways.</p>

<p><span id="more-139"></span>
Basically he is highlighting some areas for growth when it comes to the process of combining, in an efficient way, multiple reusable Django apps.</p>

<p>He covers the following areas:</p>

<ul>
<li>settings</li>
<li>static media</li>
<li>upload paths</li>
<li>Migrations</li>
<li>cache keys</li>
<li>translation</li>
</ul>

<p>Basically &#8211; every one of those except the last two is a pain point that I&#8217;ve experienced relatively early in my Django life.</p>

<p>The Django community has a strong bent towards caution and letting &#8220;convention&#8221; pick the best in class.  While this works in some cases (ie I think it has happened with South for migrations) it is often slow to be recognized or slow to happen.</p>

<p>Basically &#8211; South is the way to go for migrations and it&#8217;s time to give the author the support that comes from it being the blessed version.  If not then there is the risk that he will burn out, and South will wither, and then we have to begin the process all over again (I know thats not likely &#8211; but it is a risk)</p>

<p>For other areas &#8211; waiting for a &#8220;cohesive&#8221; convention is a waste of time, because there are multiple, equally good, ways of doing something, and the problem is not that one is better, just that there exists frustrating variety in the context of predictable combination and reuse.</p>

<p>Take upload paths &#8211; it would really take nothing to namespace the upload zone as Kevin is suggesting.  This is not a convention that will organically come from the community easily, and should just be something that Django core dictates.  There is a reason why Python likes the BDFL tag &#8211; because we know that it&#8217;s often best in the end to just have certain things dictated.</p>

<p>Same with static media &#8211; Django already basically does this with templates, it seems like it makes sense to extend and expand on that approach for static media.</p>

<p>I don&#8217;t know much about cache keys and translation &#8211; but given how strongly I agree with everything else in the article, the suggestions should probably be strongly considered.</p>

<p>Like the whos down in whoville, just wanted to add one more &#8220;we are here, we are here&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://ptone.com/dablog/2010/02/kevin-nails-it/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>a little tip on color</title>
		<link>http://ptone.com/dablog/2010/02/a-little-tip-on-color/</link>
		<comments>http://ptone.com/dablog/2010/02/a-little-tip-on-color/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 16:48:12 +0000</pubDate>
		<dc:creator>ptone</dc:creator>
				<category><![CDATA[Random Observation]]></category>

		<guid isPermaLink="false">http://ptone.com/dablog/2010/02/a-little-tip-on-color/</guid>
		<description><![CDATA[Not much to say other than I&#8217;ve been using this for a while and want to pass it on. This post has a great tool for randomizing terminal colors. If you have a lot of terminal windows open &#8211; this can make expose very handy (I don&#8217;t really use tabs). I have this bound to [...]]]></description>
			<content:encoded><![CDATA[<p>Not much to say other than I&#8217;ve been using this for a while and want to pass it on.</p>

<p>This <a href="http://www.red-sweater.com/blog/220/random-color-terminal">post</a> has a great tool for randomizing terminal colors.</p>

<p>If you have a lot of terminal windows open &#8211; this can make expose very handy (I don&#8217;t really use tabs).</p>

<p>I have this bound to CMD-Shift-C</p>

<div style="width:90%;">
<a href="http://ptone.com/dablog/wp-content/uploads/2010/02/expose.png"><img style="width:90%;" src="http://ptone.com/dablog/wp-content/uploads/2010/02/expose.png" width=500></a>
</div>
]]></content:encoded>
			<wfw:commentRss>http://ptone.com/dablog/2010/02/a-little-tip-on-color/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python,Multiprocessing,Hyperthreading, and image resizing</title>
		<link>http://ptone.com/dablog/2010/01/pythonmultiprocessinghyperthreading-and-image-resizing/</link>
		<comments>http://ptone.com/dablog/2010/01/pythonmultiprocessinghyperthreading-and-image-resizing/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 22:18:33 +0000</pubDate>
		<dc:creator>ptone</dc:creator>
				<category><![CDATA[Random Observation]]></category>

		<guid isPermaLink="false">http://ptone.com/dablog/2010/01/pythonmultiprocessinghyperthreading-and-image-resizing/</guid>
		<description><![CDATA[I have the occasional need to resize a set of images. I used to use Photoshop batch actions, then I used some droplets, and recently I&#8217;ve been using a simple python script with PIL (Python Image Library) We recently got an 8 core Mac Pro, and I wanted to see if I could take more [...]]]></description>
			<content:encoded><![CDATA[<p>I have the occasional need to resize a set of images.  I used to use Photoshop batch actions, then I used some droplets, and recently I&#8217;ve been using a simple python script with PIL (Python Image Library)</p>

<p>We recently got an 8 core Mac Pro, and I wanted to see if I could take more advantage of all those cores when resizing images.</p>

<p><span id="more-134"></span>
One of the things that confused me when I first opened activity monitor, is that it had 16 processors listed.  A little digging turns up that this relates to Intel&#8217;s Hyperthreading technology, where they present the OS twice the cores and hand some extra concurrency on the chip.  There is some debate out there as to whether or not it makes a difference.</p>

<p>It&#8217;s frustrating to have all that power and watch a CPU utilization tool look like this:</p>

<p><img src="http://ptone.com/dablog/wp-content/uploads/2010/01/single.png" alt="Single" /></p>

<p>But that is what you get when a tool is not written to be parallel across processing units.  Much is made over Python&#8217;s limit to threading and the GIL, however it seems that multiple threads never take as much advantage of multicore horsepower as do multiple processes.</p>

<p>Thanks to Python&#8217;s <a href="http://docs.python.org/library/multiprocessing.html">multiprocessing library</a> it was very easy to create a worker <a href="http://docs.python.org/library/multiprocessing.html#module-multiprocessing.pool">pool</a> to handle the resizing.  The results are impressive.  The test task was to resize a folder of 350 jpeg files by 50% and save them to a folder.</p>

<p><img src="http://ptone.com/dablog/wp-content/uploads/2010/01/performance.png" alt="Performance" /></p>

<p>This shows you the performance gain by doing the image resizing in parallel.  It goes from a 6 minute task to a 30 second task.</p>

<p>What is interesting is that even though there are only 8 true cores, there is a 40% increase in speed using all 16 virtual cores, but almost no advantage in going any higher than that.  I&#8217;d say hyperthreading makes a difference in this case.</p>

<p>Now this is more like it:</p>

<p><img src="http://ptone.com/dablog/wp-content/uploads/2010/01/maxed.png" alt="Maxed" /></p>

<p>A couple assorted notes:</p>

<p>With 8 workers, there is a roughly 10% increase in performance seen when turning off hyperthreading (via processor prefpane from dev-tools).  It may be that the overhead of managing threads that aren&#8217;t doing much for you detracts from the overall performance?? Not sure.</p>

<p>Photoshop batch automate on the same task takes about 6 minutes, which seems to refute Adobe&#8217;s <a href="http://blogs.adobe.com/jnack/2006/12/photoshop_and_multicore.html">implication</a> that muliprocessing doesn&#8217;t often gain you much.</p>

<p>There is one gotcha however, and that is that there does seem to be some sort of memory leak with the multiprocessing module.  With just one worker in the pool, you can see a steadily increasing memory use that isn&#8217;t present in the same PIL code that isn&#8217;t run through the multiprocessing module.  This is probably a manifestation of <a href="http://bugs.python.org/issue6653">this bug</a></p>

<p>Finally, the script that I used to do the tests is available <a href="http://gist.github.com/276618">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://ptone.com/dablog/2010/01/pythonmultiprocessinghyperthreading-and-image-resizing/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Pretty view of hg diff</title>
		<link>http://ptone.com/dablog/2009/11/pretty-view-of-hg-diff/</link>
		<comments>http://ptone.com/dablog/2009/11/pretty-view-of-hg-diff/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 22:21:55 +0000</pubDate>
		<dc:creator>ptone</dc:creator>
				<category><![CDATA[Random Observation]]></category>

		<guid isPermaLink="false">http://ptone.com/dablog/2009/11/pretty-view-of-hg-diff/</guid>
		<description><![CDATA[Been using hg, and like to use hg diff to help me make better commit notes &#8211; but been spoiled by bitbuckets HTML view of diffs So here is a quick script that I keep on my path for viewing hg diff, formated with pygments &#8211; I&#8217;m sure it would be very easy to adopt [...]]]></description>
			<content:encoded><![CDATA[<p>Been using hg, and like to use hg diff to help me make better commit notes &#8211; but been spoiled by bitbuckets HTML view of diffs</p>

<p>So here is a quick script that I keep on my path for viewing hg diff, formated with pygments &#8211; I&#8217;m sure it would be very easy to adopt this to git.</p>

<p><a href="http://gist.github.com/239803">here is the gist</a></p>
]]></content:encoded>
			<wfw:commentRss>http://ptone.com/dablog/2009/11/pretty-view-of-hg-diff/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing MySQL Python bindings on OS X Leopard server</title>
		<link>http://ptone.com/dablog/2009/10/installing-mysql-python-bindings-on-os-x-leopard-server/</link>
		<comments>http://ptone.com/dablog/2009/10/installing-mysql-python-bindings-on-os-x-leopard-server/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 16:56:11 +0000</pubDate>
		<dc:creator>ptone</dc:creator>
				<category><![CDATA[Random Observation]]></category>

		<guid isPermaLink="false">http://ptone.com/dablog/2009/10/installing-mysql-python-bindings-on-os-x-leopard-server/</guid>
		<description><![CDATA[Installing the mysql-python package on Leopard is relatively easy if you&#8217;ve installed MySQL from the mysql.org distribution &#8211; but installing on Leopard Server is a bit more problematic. The crux of the issue is that the version of MySQL that comes with Leopard Server does not include the header and library files needed for linking [...]]]></description>
			<content:encoded><![CDATA[<p>Installing the mysql-python package on Leopard is relatively easy if you&#8217;ve installed MySQL from the mysql.org distribution &#8211; but installing on Leopard Server is a bit more problematic.</p>

<p><span id="more-96"></span>
The crux of the issue is that the version of MySQL that comes with Leopard Server does not include the header and library files needed for linking external libraries with.  This applies to 10.5, but a similar process should work with 10.6.</p>

<p>If you attempt to build the MySQLdb python module you&#8217;ll get errors like:</p>

<pre><code>building '_mysql' extension
gcc -fno-strict-aliasing -Wno-long-double -no-cpp-precomp -mno-fused-madd -fno-common -dynamic -DNDEBUG -g -Os -Wall -Wstrict-prototypes -DMACOSX -I/usr/include/ffi -DENABLE_DTRACE -arch i386 -arch ppc -pipe -Dversion_info=(1,2,3,'gamma',1) -D__version__=1.2.3c1 -I/usr/include -I/System/Library/Frameworks/Python.framework/Versions/2.5/include/python2.5 -c _mysql.c -o build/temp.macosx-10.5-i386-2.5/_mysql.o -fno-omit-frame-pointer -pipe -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DIGNORE_SIGHUP_SIGQUIT
_mysql.c:36:23: error: my_config.h: No such file or directory
_mysql.c:36:23: error: my_config.h: No such file or directory
_mysql.c:38:19: error: mysql.h: No such file or directory
_mysql.c:38:19: error: mysql.h: No such file or directory
</code></pre>

<p>Apple has a <a href="technote">http://support.apple.com/kb/TA25017</a> on the issue &#8211; and the solution is to download these separately.  You can also just install a different version of mysql &#8211; but for a variety of reasons, I wanted to continue to run the installed version.</p>

<p>So here are the commands that will build you a working mysql python binding:</p>

<p>(assumes you have dev tools installed)</p>

<p>grab the binding library source:</p>

<p>http://sourceforge.net/projects/mysql-python/files/</p>

<pre><code>mv path/to/MySQL-python-1.2.3c1.tar.gz /tmp
cd /tmp
tar xvzf MySQL-python-1.2.3c1.tar.gz
curl -O http://www.opensource.apple.com/other/MySQL-43.binaries.tar.gz
tar xzvf MySQL-43.binaries.tar.gz
tar xvzf MySQL-43.binaries/MySQL-43.root.tar.gz
cd usr
sudo ditto usr/include/ /usr/include/
sudo ditto usr/lib/ /usr/lib/
cd /tmp/MySQL-python-1.2.3c1
ARCHFLAGS='-arch i386 -arch x86_64'
export ARCHFLAGS
# edit site.cfg to point to point to /usr/bin/mysql_config
python setup.py build
sudo python setup.py install
</code></pre>

<p>To verify this worked &#8211; fire up a python console and &#8216;import MySQLdb&#8217;</p>
]]></content:encoded>
			<wfw:commentRss>http://ptone.com/dablog/2009/10/installing-mysql-python-bindings-on-os-x-leopard-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Local editing of remote files</title>
		<link>http://ptone.com/dablog/2009/10/local-editing-of-remote-files/</link>
		<comments>http://ptone.com/dablog/2009/10/local-editing-of-remote-files/#comments</comments>
		<pubDate>Thu, 15 Oct 2009 23:05:35 +0000</pubDate>
		<dc:creator>ptone</dc:creator>
				<category><![CDATA[Random Observation]]></category>

		<guid isPermaLink="false">http://ptone.com/dablog/2009/10/local-editing-of-remote-files/</guid>
		<description><![CDATA[So found this buried under some dust. I had forgotten that I had ever set this up, but in adding some stuff to a .bash_profile on an older server found some code that I&#8217;ve spruced up bit for this post that lets you locally edit a remote file initiated via command in a remote SSH [...]]]></description>
			<content:encoded><![CDATA[<p>So found this buried under some dust.  I had forgotten that I had ever set this up, but in adding some stuff to a .bash_profile on an older server found some code that I&#8217;ve spruced up bit for this post that lets you locally edit a remote file initiated via command in a remote SSH session.</p>

<p><span id="more-94"></span>
I&#8217;ve been mostly using transmit/SFTP to do editing of remote files with my local editor of choice (TextMate).  Before I switched to TextMate I was using TextWrangler.  The problem with using Transmit (or any FTP client) for editing is that if you are already where you need to be in a SSH session &#8211; you have to navigate to that same location in the FTP client before opening the file for local editing.</p>

<p>One feature TextWrangler has that TextMate does not is the ability to open files from a SFTP URL and save them back remotely when you do CMD-S.</p>

<p>So putting the following in the .bash_profile on the server will let you execute &#8220;redit somefile&#8221; which will cause a reverse ssh command to be sent you telling TextWrangler to open the file.</p>

<p>Some prereqs:</p>

<ul>
<li>You have to have key based SSH auth working in BOTH directions</li>
<li>You have to have the TextWrangler CLI tool (edit) installed</li>
<li>Since there is a good chance that the local user you are logged in as is different than the one you are shelling into as, you have to hard code that &#8211; so unless your name is preston &#8211; you will have to change that.</li>
</ul>

<p>`</p>

<pre><code>SSH_CLIENT_ADDRESS=`echo $SSH_CONNECTION | cut -f1 -d" "`
export SSH_CLIENT_ADDRESS

SSH_HOST_ADDRESS=`echo $SSH_CONNECTION | cut -f3 -d" "`
export SSH_HOST_ADDRESS

ME=`whoami`

function redit() {
    ssh preston@$SSH_CLIENT_ADDRESS edit \"sftp://$ME@$SSH_HOST_ADDRESS/$PWD/"$@"\"
}
</code></pre>

<p>`</p>
]]></content:encoded>
			<wfw:commentRss>http://ptone.com/dablog/2009/10/local-editing-of-remote-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Marking all read in Mail.app</title>
		<link>http://ptone.com/dablog/2009/09/marking-all-read-in-mail-app/</link>
		<comments>http://ptone.com/dablog/2009/09/marking-all-read-in-mail-app/#comments</comments>
		<pubDate>Mon, 14 Sep 2009 17:38:14 +0000</pubDate>
		<dc:creator>ptone</dc:creator>
				<category><![CDATA[Random Observation]]></category>

		<guid isPermaLink="false">http://ptone.com/dablog/2009/09/marking-all-read-in-mail-app/</guid>
		<description><![CDATA[I&#8217;ve always been annoyed that the only way to mark all as read for a mailbox was with a contextual menu in the sidebar &#8211; lets change that. I use Butler as my quicklaunch keyboard macro tool &#8211; but you could use your favorite one to run the following script while reading mail. #!applescript tell [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve always been annoyed that the only way to mark all as read for a mailbox was with a contextual menu in the sidebar &#8211; lets change that.</p>

<p><span id="more-93"></span>
I use Butler as my quicklaunch keyboard macro tool &#8211; but you could use your favorite one to run the following script while reading mail.</p>

<pre><code>#!applescript
tell application "Mail"
    activate
    get message viewer 1's selected mailboxes
    repeat with thisBox in result
        set read status of (messages of thisBox whose read status is false) to true
    end repeat

end tell
</code></pre>

<p>I find this almost critical for getting through mailing list traffic.</p>
]]></content:encoded>
			<wfw:commentRss>http://ptone.com/dablog/2009/09/marking-all-read-in-mail-app/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Letting users get to (i)Work</title>
		<link>http://ptone.com/dablog/2009/08/letting-users-get-to-iwork/</link>
		<comments>http://ptone.com/dablog/2009/08/letting-users-get-to-iwork/#comments</comments>
		<pubDate>Thu, 13 Aug 2009 14:15:51 +0000</pubDate>
		<dc:creator>ptone</dc:creator>
				<category><![CDATA[Random Observation]]></category>

		<guid isPermaLink="false">http://ptone.com/dablog/2009/08/letting-users-get-to-iwork/</guid>
		<description><![CDATA[iLife and iWork can throw up an awful lot of update dialogs and welcome screens for people who first launch them. For users on my network I wanted to prevent those from coming up There are a number of defaults that can be set to make these not appear. The preferred way is to manage [...]]]></description>
			<content:encoded><![CDATA[<p>iLife and iWork can throw up an awful lot of update dialogs and welcome screens for people who first launch them.  For users on my network I wanted to prevent those from coming up</p>

<p><span id="more-80"></span></p>

<p>There are a number of defaults that can be set to make these not appear.  The preferred way is to manage these with MCX, but for now I&#8217;ve deployed these as a login script (its lazy-easy because its all in just one text file)</p>

<p>This will set defaults so that iWork and iLife don&#8217;t bug the user.  There are also defaults to turn off auto update check in perian, disable the welcome movie for Safari 4 and to set the standard file format for iWork 09 to use the iWork 08 package style file format which is more efficient when saving over the network.  Finally there is a default to tell iTunes not to look for shared music.</p>

<p>Most of these should be pretty straight forward to read &#8211; if you have others, please post them in the comments.</p>

<p>TODO: make these into MCX manifests?</p>

<pre><code># !/bin/bash
echo Setting iPrefs...

sudo -u $1 defaults write org.perian.Perian NextRunDate -date '4000-12-31 16:00:00 -0800'

# iWork

sudo -u $1 defaults -currentHost write com.apple.iWork SFLDefaultsAutoUpdateCheck -bool FALSE
defaults write /Library/Preferences/com.apple.iWork09 DisplayedRegistrationWindowCount -int 3
defaults write /Library/Preferences/com.apple.iWork09 ShouldNotSendRegistration -bool TRUE
chown admin:admin /Library/Preferences/com.apple.iWork09.plist
chmod 644 /Library/Preferences/com.apple.iWork09.plist

sudo -u $1 defaults write com.apple.iWork.Keynote DisplayedRegistrationWindowCount -int 2
sudo -u $1 defaults write com.apple.iWork.Keynote RegistrationHasBeenSent -bool TRUE
sudo -u $1 defaults -currentHost write com.apple.iWork.Keynote FirstRunFlag -bool TRUE
sudo -u $1 defaults write com.apple.iWork.Keynote dontShowWhatsNew -bool TRUE
sudo -u $1 defaults write com.apple.iWork.Keynote DisableSingleFileFormat -bool TRUE

sudo -u $1 defaults write com.apple.iWork.Pages DisplayedRegistrationWindowCount -int 2
sudo -u $1 defaults write com.apple.iWork.Pages RegistrationHasBeenSent -bool TRUE
sudo -u $1 defaults -currentHost write com.apple.iWork.Pages FirstRunFlag -bool TRUE
sudo -u $1 defaults write com.apple.iWork.Pages dontShowWhatsNew -bool TRUE
sudo -u $1 defaults write com.apple.iWork.Pages DisableSingleFileFormat -bool TRUE

sudo -u $1 defaults write com.apple.iWork.Numbers DisplayedRegistrationWindowCount -int 2
sudo -u $1 defaults write com.apple.iWork.Numbers RegistrationHasBeenSent -bool TRUE
sudo -u $1 defaults -currentHost write com.apple.iWork.Numbers FirstRunFlag -bool TRUE
sudo -u $1 defaults write com.apple.iWork.Numbers dontShowWhatsNew -bool TRUE
sudo -u $1 defaults write com.apple.iWork.Numbers DisableSingleFileFormat -bool TRUE

# Garageband
sudo -u $1 defaults write com.apple.garageband dontShowWhatsNew -bool TRUE
sudo -u $1 defaults write com.apple.garageband DfPrefs_NoDocumentPanel -bool TRUE
sudo -u $1 defaults write com.apple.garageband DfPrefs_NextUpgradeCheck -date 'Aug 10, 2012 12:00:00 PM'
sudo -u $1 defaults write com.apple.garageband DfPrefs_AskAboutUpgrades -dict '5.1' 'NO'

# iMovie
sudo -u $1 defaults write com.apple.iMovie8 dontShowWhatsNew -bool TRUE
sudo -u $1 defaults write com.apple.iMovie8 AutoUpgradeCheck -bool FALSE
sudo -u $1 defaults write com.apple.iMovie8 NextUpgradeCheck -date 'Aug 10, 2012 12:00:00 PM'
# no proof that this one is recognized - but it is in the others
sudo -u $1 defaults write com.apple.iMovie8 SFLDefaultsAutoUpdateCheck -bool FALSE

# iPhoto
sudo -u $1 defaults write com.apple.iPhoto CheckForUpdates -bool FALSE
sudo -u $1 defaults write com.apple.iPhoto dontShowWhatsNew -bool TRUE
sudo -u $1 defaults write com.apple.iPhoto GeocodeLookupPreference -int 0
sudo -u $1 defaults write com.apple.iPhoto NextUpgradeCheck -date 'Aug 10, 2012 12:00:00 PM'
# not so sure about these:
sudo -u $1 defaults write com.apple.iPhoto SFLDefaultsAutoUpdateCheck -bool FALSE
sudo -u $1 defaults write com.apple.iPhoto UpdateSplash -int 8

# iTunes
sudo -u $1 defaults write com.apple.iTunes lookForSharedMusic -bool FALSE

# iWeb
sudo -u $1 defaults write com.apple.iWeb dontShowWhatsNew -bool TRUE
sudo -u $1 defaults write com.apple.iWeb dismissDotMacUpsellWindow -bool TRUE
sudo -u $1 defaults write com.apple.iWeb SFLDefaultsAutoUpdateCheck -bool FALSE
sudo -u $1 defaults -currentHost write com.apple.iWeb FirstRunFlag -bool TRUE 

# Safari
sudo -u $1 defaults write com.apple.Safari LastDisplayedWelcomePageVersionString '4.0'
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://ptone.com/dablog/2009/08/letting-users-get-to-iwork/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

