<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Alex Clark - Python Web Developer</title><link href="http://aclark.net/blog/" rel="alternate"></link><link href="http://aclark.net/blog/feeds/Python.atom.xml" rel="self"></link><id>http://aclark.net/blog/</id><updated>2013-04-22T12:00:00-04:00</updated><entry><title>New Pyramid Site</title><link href="http://aclark.net/blog/2013/04/22/new-pyramid-site/" rel="alternate"></link><updated>2013-04-22T12:00:00-04:00</updated><author><name>aclark</name></author><id>tag:aclark.net/blog,2013-04-22:2013/04/22/new-pyramid-site/</id><summary type="html">&lt;img alt="https://raw.github.com/ACLARKNET/aclarknet/master/screenshot.png" src="https://raw.github.com/ACLARKNET/aclarknet/master/screenshot.png" style="width: 98%;" /&gt;
&lt;p&gt;For the first time in 10 years, &lt;a class="reference external" href="http://aclark.net"&gt;aclark.net&lt;/a&gt; is not powered by Plone. Nothing against Plone: it's still one of the greatest loves of my life (inasmuch as you can love a software and community, as I do).&lt;/p&gt;
&lt;div class="section" id="why"&gt;
&lt;h2&gt;Why&lt;/h2&gt;
&lt;p&gt;This was not the result of a revolutionary plan, rather more of an evolution. It happened like this:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;As soon as Plone 4.3a1 was released (a year ago?) I deployed a new Plone site to aclark.net with it, featuring a &lt;strong&gt;Diazo&lt;/strong&gt; (new Plone theming engine) theme.&lt;/li&gt;
&lt;li&gt;Around the same time I became obsessed with deploying to Heroku, and also gained an interest in &lt;strong&gt;Python 3&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;A few months ago, I got tired of paying $11/month to host my Plone site so I converted the site to &lt;strong&gt;static HTML&lt;/strong&gt; and moved it to &lt;strong&gt;GitHub pages&lt;/strong&gt;. But the result was flawed because maintenance involved editing duplicate copies of the website content (e.g. both clients.html and clients/foo.html contained the same text describing &amp;quot;foo&amp;quot;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So when it came time to do more than a few casual edits, I knew I had to find a new approach. That's when various elements of the Universe conspired to lead me in a new direction.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="how"&gt;
&lt;h2&gt;How&lt;/h2&gt;
&lt;div class="section" id="pyramid"&gt;
&lt;h3&gt;Pyramid&lt;/h3&gt;
&lt;p&gt;I spent a lot of time (~ 1 year) developing &lt;a class="reference external" href="http://pythonpackages.com"&gt;pythonpackages.com&lt;/a&gt; in Pyramid, but the result was a mess (code-wise). I'm in the process of rewriting and open sourcing it, but it's slow going. So what better way to get started than to do a small-ish site in Pyramid for fun?&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="about-me"&gt;
&lt;h3&gt;about.me&lt;/h3&gt;
&lt;p&gt;I also recently gave in and created an &lt;a class="reference external" href="http://about.me/alex.clark"&gt;about.me site&lt;/a&gt;. I was impressed by their content editing features, and my ability to create a page that looked OK using them.&lt;/p&gt;
&lt;p&gt;In my about.me profile, I used a picture of me and a picture of DC I took in early 2012. When it came time to redo aclark.net I felt like I really wanted to capture the simplicity of the about.me site, so I used the same photo in the background.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="bootstrap"&gt;
&lt;h3&gt;Bootstrap&lt;/h3&gt;
&lt;p&gt;Bootstrap is old news at this point, but I really enjoy using it and I particularly like that they have added more example templates. So I combined my background photo with one of &lt;a class="reference external" href="http://twitter.github.io/bootstrap/getting-started.html#examples"&gt;their example templates&lt;/a&gt; and a new site idea was born. As I'm not a particularly talented visual artist, my ability to produce something that looked OK (with code this time) was exciting.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="what"&gt;
&lt;h2&gt;What&lt;/h2&gt;
&lt;p&gt;Until I added a contact form, the site was entirely unremarkable. There are views and routes and templates, typical fare for a web framework. Here is the entire &amp;quot;main routine&amp;quot;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
from pyramid.session import UnencryptedCookieSessionFactoryConfig
from pyramid.config import Configurator
from .redir import blog
from .redir import blog_entry
from .redir import blog_slash
from .views import contact
from .views import default
import deform_bootstrap


def main(global_config, **settings):
    &amp;quot;&amp;quot;&amp;quot;
    Oppan wsgi style! Configure and return WSGI application.
    &amp;quot;&amp;quot;&amp;quot;
    my_session_factory = UnencryptedCookieSessionFactoryConfig('itsaseekreet')
    config = Configurator(session_factory=my_session_factory)
    config.add_route('blog', '/blog')
    config.add_route('blog_entry', '/blog/{entry:.*}')
    config.add_route('blog_slash', '/blog/')
    config.add_route('contact', '/contact')
    config.add_route('clients', '/clients')
    config.add_route('projects', '/projects')
    config.add_route('services', '/services')
    config.add_route('team', '/team')
    config.add_route('testimonials', '/testimonials')
    config.add_route('root', '/')
    config.add_static_view(
        'static', 'aclarknet:static', cache_max_age=3600)
    config.add_view(blog, route_name='blog')
    config.add_view(blog_entry, route_name='blog_entry')
    config.add_view(blog_slash, route_name='blog_slash')
    config.add_view(
        default,
        renderer='aclarknet:templates/clients.mak',
        route_name='clients')
    config.add_view(
        contact,
        renderer='aclarknet:templates/contact.mak',
        route_name='contact')
    config.add_view(
        default,
        renderer='aclarknet:templates/projects.mak',
        route_name='projects')
    config.add_view(
        default,
        renderer='aclarknet:templates/root.mak',
        route_name='root')
    config.add_view(
        default,
        renderer='aclarknet:templates/services.mak',
        route_name='services')
    config.add_view(
        default,
        renderer='aclarknet:templates/testimonials.mak',
        route_name='testimonials')
    config.add_view(
        default,
        renderer='aclarknet:templates/team.mak',
        route_name='team')
    config.include(deform_bootstrap)
    return config.make_wsgi_app()
&lt;/pre&gt;
&lt;div class="section" id="contact-form"&gt;
&lt;h3&gt;Contact form&lt;/h3&gt;
&lt;p&gt;But then I wanted a contact form. Which lead me to wanting an elegant way to send mail via Heroku. Which lead me to discover &lt;a class="reference external" href="http://sendgrid.com/"&gt;SendGrid&lt;/a&gt;. Which lead me create some primitive marketing features I am quite proud of and excited about.&lt;/p&gt;
&lt;p&gt;I still ended up sending mail &amp;quot;the old way&amp;quot; via GMail. But now I send two mails: one to &lt;a class="reference external" href="mailto:info&amp;#64;aclark.net"&gt;info&amp;#64;aclark.net&lt;/a&gt; to alert our staff about the lead (using GMail). And one to the lead acknowledging their submission (using SendGrid). SendGrid keeps a record of all the leads we've contacted, amongst other &amp;quot;fancy marketing features&amp;quot;. Here's the relevant view code:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
import deform
import smtplib

from email.mime.text import MIMEText

from .config import FORM_ERROR
from .config import FORM_SUCCESS

from .config import MIME_ONE_RECIPIENT
from .config import MIME_ONE_SUBJECT
from .config import MIME_TWO_MESSAGE
from .config import MIME_TWO_SUBJECT

from .config import GMAIL_HOSTNAME
from .config import GMAIL_PASSWORD
from .config import GMAIL_USERNAME

from .config import SENDGRID_HOSTNAME
from .config import SENDGRID_PASSWORD
from .config import SENDGRID_USERNAME

from .forms import ContactFormSchema


def contact(request):
    &amp;quot;&amp;quot;&amp;quot;
    Create and render deform form containing colander schema. Provide
    sendgrid integration for marketing.
    &amp;quot;&amp;quot;&amp;quot;
    button = deform.Button('Send', css_class='span9 btn-block btn-large')
    schema = ContactFormSchema().bind(request=request)
    form = deform.Form(schema, buttons=(button, ))
    if 'Send' in request.POST:
        items = request.POST.items()
        try:
            appstruct = form.validate(items)
        except deform.ValidationFailure:
            return {
                'form': form.render(),
                'request': request,
            }
        # This is the form contents
        email = appstruct['email']
        message = appstruct['message']

        # This is the mail to info&amp;#64;aclark.net
        mime_document_one = MIMEText(message)
        mime_document_one['Subject'] = MIME_ONE_SUBJECT
        mime_document_one['To'] = MIME_ONE_RECIPIENT
        mime_document_one['From'] = email
        mime_document_one = mime_document_one.as_string()

        # This is the mail to the new lead
        mime_document_two = MIMEText(MIME_TWO_MESSAGE)
        mime_document_two['Subject'] = MIME_TWO_SUBJECT
        mime_document_two['To'] = email
        mime_document_two['From'] = MIME_ONE_RECIPIENT
        mime_document_two = mime_document_two.as_string()

        try:
            # This is the mail to info&amp;#64;aclark.net
            smtp_server = smtplib.SMTP(GMAIL_HOSTNAME)
            smtp_server.starttls()
            smtp_server.login(GMAIL_USERNAME, GMAIL_PASSWORD)
            smtp_server.sendmail(email, MIME_ONE_RECIPIENT, mime_document_one)
            smtp_server.quit()

            # This is the mail to the new lead
            smtp_server = smtplib.SMTP(SENDGRID_HOSTNAME)
            smtp_server.starttls()
            smtp_server.login(SENDGRID_USERNAME, SENDGRID_PASSWORD)
            smtp_server.sendmail(MIME_ONE_RECIPIENT, email, mime_document_two)
            smtp_server.quit()
            request.session.flash(FORM_SUCCESS)
        except:
            request.session.flash(FORM_ERROR, 'errors')
        return {
            'form': form.render(appstruct={}),
            'request': request,
        }
    return {
        'form': form.render(),
        'request': request,
    }


def default(request):
    &amp;quot;&amp;quot;&amp;quot;
    This is the default view, to be used with most routes since we do not
    provide any content editing ability yet. Even then, maybe a default view
    would still be helpful.
    &amp;quot;&amp;quot;&amp;quot;
    return {}
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="who-cares"&gt;
&lt;h2&gt;Who cares&lt;/h2&gt;
&lt;p&gt;The best thing about all of this being able to run the site &lt;strong&gt;100% for free on Heroku&lt;/strong&gt;. Also:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Python 3 compat!&lt;/li&gt;
&lt;li&gt;Free caching via CloudFlare&lt;/li&gt;
&lt;li&gt;Free ping service from Pingdom keeps the site from &amp;quot;going to sleep&amp;quot; (HT: natea).&lt;/li&gt;
&lt;li&gt;Updating the site fits my workflow. If I'm the content editor, I don't necessarily need or want to use Plone to edit my content. I can save Plone for my clients, and focus on &lt;strong&gt;what makes them happy&lt;/strong&gt; with their CMS system.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
</summary><category term="Django"></category><category term="Mozilla"></category><category term="Plone"></category><category term="Python"></category></entry><entry><title>The Story of Pillow</title><link href="http://aclark.net/blog/2013/03/15/the-story-of-pillow/" rel="alternate"></link><updated>2013-03-15T17:00:00-04:00</updated><author><name>aclark</name></author><id>tag:aclark.net/blog,2013-03-15:2013/03/15/the-story-of-pillow/</id><summary type="html">&lt;p&gt;On March 4, 2013 I got an email from the Python Software Foundation (PSF):&lt;/p&gt;
&lt;blockquote&gt;
This email notification is being sent to you to inform you of the PSF Board’s decision to fund the facilitation of a Python 3 compatible release of the Python Imaging Library for the amount of $1,300 USD. Please see the resolution that was passed unanimously on March 4, 2013 via email below:&lt;/blockquote&gt;
&lt;p&gt;Yay! That was in response to &lt;a class="reference external" href="https://github.com/python-imaging/psf-grant-proposal"&gt;my proposal&lt;/a&gt; asking for funding to finish a Pillow 2.0.0 release. In that proposal, I presented the &amp;quot;story of Pillow&amp;quot; which I'd like to present again now, for anyone interested:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Tired of seeing the proliferation of third party packagings of the Python Imaging Library, in 2010 Alex Clark took Hanno Schlicting's repackaging and used it to create a fork of the Python Imaging Library on GitHub. He subsequently released that fork to PyPI as Pillow 1.0. The ability to add additional development library paths to setup.py (e.g. 64 bit library and headers directories) and make releases quickly eventually led to widespread adoption of Pillow.&lt;/p&gt;
&lt;p&gt;A little over a year later on 2011-09-08, Takayuki Shimizukawa uploaded the first Windows (win32) eggs. Since then, every Pillow release included Windows eggs thanks to Takayuki. And on 2013-02-02, the first 64-bit Windows eggs (amd64) were uploaded to PyPI by Takayuki.&lt;/p&gt;
&lt;p&gt;For the first 3 years, the fork focused on packaging fixes only. Now a Python 3 compatible pull request from Brian Crowell has been merged, and the final stages of release preparation are underway. In early 2013, Barry Warsaw created an Ubuntu Personal Package Archive and tested it with Python 3. And the Fedora Project is now planning to include Pillow with their release of Fedora 19. Finally, the Pillow project has promised a Python 3 compatible release of Pillow by PyCon 2013.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That release is now done! And I have had an absolute blast working on Pillow full time over the course of the last week or so. So much so, that I'm going to propose you help me continue to have fun and be productive with Pillow… but more on that later. First, about the new release.&lt;/p&gt;
&lt;div class="section" id="about-2-0-0"&gt;
&lt;h2&gt;About 2.0.0&lt;/h2&gt;
&lt;img alt="https://raw.github.com/ACLARKNET/blog/gh-pages/images/story-of-pillow.png" src="https://raw.github.com/ACLARKNET/blog/gh-pages/images/story-of-pillow.png" /&gt;
&lt;p&gt;This release marks the first &amp;quot;serious effort&amp;quot; I have put into Pillow. While I've always enjoyed working on it in my spare time, I knew that there was no way I could finish it in time for PyCon 2013 (as I promised) without getting some financial assistance.&lt;/p&gt;
&lt;p&gt;Enter: The PSF, who graciously offered to fund my work (and the work of one other contributor). Once I had funding in place, I knew exactly what needed to be done:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;So much time has passed since the fork, no one seemed to care if we made image code changes (we were originally a packaging fork), so this release contains &lt;strong&gt;EVERY PATCH EVER SUBMITTED TO PIL&lt;/strong&gt; but not released until now. I'm exaggerating, but we really crammed a lot of &amp;quot;goodness&amp;quot; in to the 2.0.0 release along with Python 3 support which is what prompted the release in the first place.&lt;/li&gt;
&lt;li&gt;In order to fully test, I fine-tuned my tox environment on Mac OS X (tox is awesome) as well as fired up a new Windows VM (and used an already-existing Linux VM). Additionally, other folks joined in to test on their environments (most notably Christophe Gohlke and Eric Soroos). You'll find the results here: &lt;a class="reference external" href="https://github.com/python-imaging/Pillow#platform-support"&gt;https://github.com/python-imaging/Pillow#platform-support&lt;/a&gt;. That means: &lt;strong&gt;THIS RELEASE HAS BEEN FULLY, EXTENSIVELY, AND EXHAUSTIVELY DEVELOPED AND TESTED&lt;/strong&gt;. Aside from the possible inconvenience of Pillow 2.0.0 dropping 2.4 and 2.5 support (use Pillow 1.x if you need Python 2.4,2.5), you should not have any trouble with it. If you do, please open a ticket here: &lt;a class="reference external" href="https://github.com/python-imaging/Pillow/issues"&gt;https://github.com/python-imaging/Pillow/issues&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;As important as quality software is to me, quality presentation is almost equally important. (That's developer-eye quality, not designer-eye quality. ;-)) So I spent a lot of time cleaning up and enhancing the more subtle aspects of the release e.g. README.rst, docs/* (including the pythondoc documentation and HISTORY.txt and CONTRIBUTORS.txt). The pythondoc documentation has been converted to re-structured text and is hosted on ReadTheDocs: &lt;a class="reference external" href="http://pillow.readthedocs.org/en/latest/"&gt;http://pillow.readthedocs.org/en/latest/&lt;/a&gt;. The website has been updated to include an &lt;strong&gt;actual&lt;/strong&gt; image generated by PIL :-) &lt;a class="reference external" href="http://python-imaging.github.com/"&gt;http://python-imaging.github.com/&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I hope you enjoy and use Pillow 2.0.0. If you'd like to see me continue to devote significant time to maintaining Pillow, please &lt;a class="reference external" href="http://gittip.com/aclark4life"&gt;consider a gittip&lt;/a&gt;! Thank you.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="Django"></category><category term="Plone"></category><category term="Python"></category></entry><entry><title>I love checkoutmanager and dotfiles</title><link href="http://aclark.net/blog/2013/02/08/i-love-checkoutmanager-and-dotfiles/" rel="alternate"></link><updated>2013-02-08T12:00:00-05:00</updated><author><name>aclark</name></author><id>tag:aclark.net/blog,2013-02-08:2013/02/08/i-love-checkoutmanager-and-dotfiles/</id><summary type="html">&lt;p&gt;&lt;em&gt;An ode to my OS X development workstation setup&lt;/em&gt; &lt;a class="footnote-reference" href="#id11" id="id1"&gt;[1]&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I am big on setting up my development environment, and enjoying the environment I work in. And I'm very thankful to the folks who make my life easier, including the authors of:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.ohloh.net/p/python/contributors/summary"&gt;Python&lt;/a&gt;: Python Core Developers&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/dotfiles"&gt;dotfiles&lt;/a&gt;: Jon Bernard&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://pypi.python.org/pypi/checkoutmanager"&gt;checkoutmanager&lt;/a&gt;: Reinout Van Rees&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I also love &lt;strong&gt;repetition&lt;/strong&gt;. So picture if you will, a new &lt;strong&gt;Macbook Air or Pro&lt;/strong&gt; ready to serve as my development workstation. I like to perform, and study, the steps required to turn a new laptop in to my development workstation. So here we go. In this article, I will walk through the steps required to turn a new machine in to my developer workstation. Do follow along!&lt;/p&gt;
&lt;div class="section" id="shell"&gt;
&lt;h2&gt;Shell&lt;/h2&gt;
&lt;p&gt;One of the first things I do on a new system is change my shell to &lt;strong&gt;Zsh&lt;/strong&gt; in &lt;tt class="docutils literal"&gt;System Preferences &lt;span class="pre"&gt;-&amp;gt;&lt;/span&gt; Users &amp;amp; Groups &lt;span class="pre"&gt;-&amp;gt;&lt;/span&gt; Current User &lt;span class="pre"&gt;-&amp;gt;&lt;/span&gt; Right Click &lt;span class="pre"&gt;-&amp;gt;&lt;/span&gt; Advanced &lt;span class="pre"&gt;Options...&lt;/span&gt;&lt;/tt&gt;. Don't forget to &lt;tt class="docutils literal"&gt;Click the lock to make changes&lt;/tt&gt; first.&lt;/p&gt;
&lt;img alt="https://raw.github.com/ACLARKNET/blog/gh-pages/images/zsh.png" src="https://raw.github.com/ACLARKNET/blog/gh-pages/images/zsh.png" /&gt;
&lt;div class="section" id="zsh"&gt;
&lt;h3&gt;Zsh&lt;/h3&gt;
&lt;p&gt;Why &lt;strong&gt;Zsh&lt;/strong&gt;? One of my favorite features is &lt;strong&gt;shared history between open sessions&lt;/strong&gt;. So I can run a command in one window, and then run the same command from another window by fetching it from the history (with CTRL-R).&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="xcode"&gt;
&lt;h2&gt;XCode&lt;/h2&gt;
&lt;p&gt;After I take possession of my new laptop (running &lt;strong&gt;Mountain Lion&lt;/strong&gt;, the newest OS X at the time of this writing), I head to the App Store to download XCode. &lt;a class="footnote-reference" href="#id12" id="id2"&gt;[2]&lt;/a&gt; Among many other things, XCode gives me the GNU C Compiler and allows me to type &amp;quot;gcc&amp;quot; in my &lt;tt class="docutils literal"&gt;Applications &lt;span class="pre"&gt;-&amp;gt;&lt;/span&gt; Utilities &lt;span class="pre"&gt;-&amp;gt;&lt;/span&gt; Terminal&lt;/tt&gt;.&lt;/p&gt;
&lt;img alt="https://raw.github.com/ACLARKNET/blog/gh-pages/images/gcc.png" src="https://raw.github.com/ACLARKNET/blog/gh-pages/images/gcc.png" /&gt;
&lt;/div&gt;
&lt;div class="section" id="id3"&gt;
&lt;h2&gt;Python&lt;/h2&gt;
&lt;img alt="https://raw.github.com/ACLARKNET/blog/gh-pages/images/homebrew.png" src="https://raw.github.com/ACLARKNET/blog/gh-pages/images/homebrew.png" /&gt;
&lt;p&gt;Now I need a Python interpreter &lt;a class="footnote-reference" href="#id13" id="id4"&gt;[3]&lt;/a&gt;. For development I use the &lt;a class="reference external" href="https://github.com/collective/buildout.python"&gt;Collective Python Buildout&lt;/a&gt; but I also enjoy using &lt;a class="reference external" href="http://mxcl.github.com/homebrew/"&gt;Homebrew's&lt;/a&gt; Python 2.7. I use Homebrew for a variety of other things too (e.g. mobile-shell AKA mosh) so here we go:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ ruby -e &amp;quot;$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)&amp;quot;
&lt;/pre&gt;
&lt;p&gt;… follow instructions …&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ brew install python
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section" id="git"&gt;
&lt;h2&gt;Git&lt;/h2&gt;
&lt;p&gt;I think OS X (or XCode) includes git, but just in case:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ brew install git
&lt;/pre&gt;
&lt;p&gt;Which reminds me, don't forget that installing the command line utilities in Mountain Lion's XCode requires an additional step in &lt;tt class="docutils literal"&gt;Preferences &lt;span class="pre"&gt;-&amp;gt;&lt;/span&gt; Downloads &lt;span class="pre"&gt;-&amp;gt;&lt;/span&gt; Command Line Tools &lt;span class="pre"&gt;-&amp;gt;&lt;/span&gt; Install&lt;/tt&gt;:&lt;/p&gt;
&lt;img alt="https://raw.github.com/ACLARKNET/blog/gh-pages/images/command-line-utils.png" src="https://raw.github.com/ACLARKNET/blog/gh-pages/images/command-line-utils.png" /&gt;
&lt;/div&gt;
&lt;div class="section" id="id5"&gt;
&lt;h2&gt;Dotfiles&lt;/h2&gt;
&lt;p&gt;At this point, I can begin to get serious about turning this new machine in to my developer workstation. And that means: &lt;strong&gt;installing my private ssh key&lt;/strong&gt; so I can check out code without typing a password, of course. Normally this would be tedious, but with git and dotfiles it's not so bad. This is what I do from my home directory:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ git clone https://super_secret_url/dotfiles.git Dotfiles
&lt;/pre&gt;
&lt;p&gt;I use https which requires a password for the first time only. Then I edit &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;Dotfiles/.git/config&lt;/span&gt;&lt;/tt&gt; and change the repository URL to &lt;tt class="docutils literal"&gt;git&amp;#64;super_secret_url/dotfiles.git&lt;/tt&gt;. So every subsequent pull and push will require no password. And to &amp;quot;install&amp;quot; these dotfiles, I do &lt;a class="footnote-reference" href="#id16" id="id6"&gt;[6]&lt;/a&gt;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ pip install dotfiles
$ dotfiles -s --force
&lt;/pre&gt;
&lt;p&gt;Note: the dotfiles command finds my dotfiles in the default directory &amp;quot;Dotfiles&amp;quot; and create symbolic links to them.&lt;/p&gt;
&lt;div class="section" id="distribute-pip"&gt;
&lt;h3&gt;Distribute &amp;amp; Pip&lt;/h3&gt;
&lt;p&gt;Homebrew's Python includes pip, but even if it didn't:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ curl -O http://python-distribute.org/distribute_setup.py
$ /usr/local/bin/python distribute_setup.py
$ {easy_install, pip install} dotfiles
&lt;/pre&gt;
&lt;p&gt;In other words, you can always install Distribute &lt;a class="footnote-reference" href="#id14" id="id7"&gt;[4]&lt;/a&gt;. After which you can use &lt;tt class="docutils literal"&gt;easy_install&lt;/tt&gt; or &lt;tt class="docutils literal"&gt;pip&lt;/tt&gt; to install dotfiles. (You can read up on the differences. TL;DR: neither is &amp;quot;better&amp;quot; or &amp;quot;worse&amp;quot;, it's just a question of which tradeoffs you are willing to make. I tend to use pip just because it's newer and I like its requirements.txt feature, but easy_install is still very well supported as part of the Distribute project.)&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="id8"&gt;
&lt;h2&gt;Checkoutmanager&lt;/h2&gt;
&lt;p&gt;Now I need some things to develop. Since I work on a bunch of different projects, I need a way to keep track of what should be checked out at any given time. So I do this &lt;a class="footnote-reference" href="#id15" id="id9"&gt;[5]&lt;/a&gt;:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ pip install checkoutmanager
$ checkoutmanager co
&lt;/pre&gt;
&lt;p&gt;This creates and populates my &lt;tt class="docutils literal"&gt;~/Developer&lt;/tt&gt; directory with code. And it &amp;quot;just works&amp;quot; because I keep a &lt;tt class="docutils literal"&gt;.checkoutmanager.cfg&lt;/tt&gt; in my Dotfiles repository. It currently looks like this:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
[aclark]
basedir = /Users/aclark/Developer/aclark
checkouts =
    git&amp;#64;github.com:aclark4life/aclark4life.github.com.git resume
    git&amp;#64;github.com:aclark4life/desktops.git
    git&amp;#64;github.com:aclark4life/hireme.git
    git&amp;#64;github.com:aclark4life/projects.git
    git&amp;#64;github.com:aclark4life/reinstall.git
    git&amp;#64;github.com:ACLARKNET/tweets.git
    git&amp;#64;github.com:aclark4life/usesthis.git
vcs = git

[alt]
basedir = /Users/aclark/Developer/alt
checkouts =
    git&amp;#64;github.com:alt-aclark-net/alt-aclark-net.github.com.git
    git&amp;#64;github.com:alt-aclark-net/dexter.git
    git&amp;#64;github.com:alt-aclark-net/headstraight.git
vcs = git

[buildout]
basedir = /Users/aclark/Developer/buildout
checkouts =
    git&amp;#64;github.com:collective/buildout.bootstrap.git
    git&amp;#64;github.com:buildout/buildout.git
    git&amp;#64;github.com:buildout/buildout.github.com.git
vcs = git

[distribute]
basedir = /Users/aclark/Developer
checkouts = ssh://hg&amp;#64;bitbucket.org/tarek/distribute
vcs = hg

[clients]
basedir = /Users/aclark/Developer
checkouts =
; Bunch o client repos
vcs = git

[clients-hg]
basedir = /Users/aclark/Developer
checkouts =
; Bunch o client repos
vcs = hg

[dcpython]
basedir = /Users/aclark/Developer/dcpython
checkouts =
    git&amp;#64;github.com:DCPython/dcpython.github.com.git
    git&amp;#64;github.com:DCPython/pyramid-tutorials.git
vcs = git

[misc]
basedir = /Users/aclark/Developer
checkouts =
    git&amp;#64;github.com:ACLARKNET/aclarknet.github.com.git blog
    git&amp;#64;github.com:ACLARKNET/new_style.git
    git&amp;#64;github.com:aclark4life/binfiles.git
;    git&amp;#64;github.com:aclark4life/pyramid_python_3.git
    git&amp;#64;github.com:aclark4life/vanity.git
    git&amp;#64;github.com:aclark4life/zope2-heroku.git
    git&amp;#64;github.com:aclark4life/zope2_bootstrap.git
    git&amp;#64;github.com:codekoala/django-axes.git
    git&amp;#64;github.com:collective/buildout.python
vcs = git

[pillow]
basedir = /Users/aclark/Developer/pillow
checkouts =
    git&amp;#64;github.com:python-imaging/Pillow.git
    git&amp;#64;github.com:python-imaging/python-imaging.github.com.git
vcs = git

[plethorasociety]
basedir = /Users/aclark/Developer/plethorasociety
checkouts =
    git&amp;#64;github.com:plethorasociety/plethorasociety.github.com.git
vcs = git

[plone]
basedir = /Users/aclark/Developer/plone
checkouts =
    git&amp;#64;github.com:aclark4life/Plone-Debug-Assistant.git
    git&amp;#64;github.com:aclark4life/collective.recipe.bluebream.git
    git&amp;#64;github.com:aclark4life/event_days_indexer.git
    git&amp;#64;github.com:aclark4life/hello_plone.git
    git&amp;#64;github.com:aclark4life/mr_migrator_demo.git
    git&amp;#64;github.com:aclark4life/parse2plone.git
    git&amp;#64;github.com:aclark4life/plone_1_fun.git
    git&amp;#64;github.com:aclark4life/plone_addon_upgrade.git
    git&amp;#64;github.com:aclark4life/plone_guide.git
    git&amp;#64;github.com:aclark4life/plone_workflow_events.git
    git&amp;#64;github.com:aclark4life/schemaextender-facetednav-demo.git
    git&amp;#64;github.com:aclark4life/silly_content_import.git
    git&amp;#64;github.com:aclark4life/transmogrify.extract.git
    git&amp;#64;github.com:aclark4life/transmogrify.regexp.git
    git&amp;#64;github.com:aclark4life/viewlets_dont_suck.git
    git&amp;#64;github.com:aclark4life/wordpress2plone.git
    git&amp;#64;github.com:collective/Products.AttachmentField.git
    git&amp;#64;github.com:collective/Products.CalendarX.git
    git&amp;#64;github.com:collective/Products.EventRegistration.git
    git&amp;#64;github.com:collective/Products.PloneSoftwareCenter.git
    git&amp;#64;github.com:collective/Products.ifQuotes.git
    git&amp;#64;github.com:collective/Products.naked_plone.git
    git&amp;#64;github.com:collective/buildout.plonetest.git
    git&amp;#64;github.com:collective/collective.contacts.git
    git&amp;#64;github.com:collective/collective.controlpanel.edit_css.git
    git&amp;#64;github.com:collective/collective.developermanual.git
    git&amp;#64;github.com:collective/collective.formtoy.git
    git&amp;#64;github.com:collective/collective.github.com.git
    git&amp;#64;github.com:collective/collective.googleanalytics.git
    git&amp;#64;github.com:collective/collective.package.git
    git&amp;#64;github.com:collective/collective.project.git
    git&amp;#64;github.com:collective/collective.recaptcha.git
    git&amp;#64;github.com:collective/collective.recipe.grp.git
    git&amp;#64;github.com:collective/collective.recipe.rsync.git
    git&amp;#64;github.com:collective/collective.rip.git
    git&amp;#64;github.com:collective/collective.stats.git
    git&amp;#64;github.com:collective/funnelweb.git
    git&amp;#64;github.com:collective/github-collective.git
    git&amp;#64;github.com:collective/mr.migrator.git
    git&amp;#64;github.com:collective/plonecom-buildout.git
    git&amp;#64;github.com:collective/plonecom.theme.git
    git&amp;#64;github.com:collective/plonetheme.coolblue.git
    git&amp;#64;github.com:collective/plonetheme.freshpick.git
    git&amp;#64;github.com:collective/plonetheme.grungeera.git
    git&amp;#64;github.com:collective/plonetheme.keepitsimple.git
    git&amp;#64;github.com:collective/plonetheme.unilluminated.git
    git&amp;#64;github.com:collective/transmogrify.filesystem.git
    git&amp;#64;github.com:plone/Installers-OS-X.git
    git&amp;#64;github.com:plone/Products.PloneOrg.git
    git&amp;#64;github.com:plone/admin-docs.git
    git&amp;#64;github.com:plone/buildout.coredev.git
    git&amp;#64;github.com:plone/planet.plone.org.git
    git&amp;#64;github.com:plone/plone.api.git
    git&amp;#64;github.com:plone/plone.github.com.git
    git&amp;#64;github.com:plone/ploneorg.admin.git
    git&amp;#64;github.com:plone/plonetheme.ploneorg.git
vcs = git

[pythonpackages]
basedir = /Users/aclark/Developer/pythonpackages
checkouts =
    git&amp;#64;github.com:aclark4life/buildout-apache-mysql.git
    git&amp;#64;github.com:aclark4life/buildout-munin.git
    git&amp;#64;github.com:aclark4life/buildout-mysql.git
    git&amp;#64;github.com:aclark4life/buildout-nginx.git
    git&amp;#64;github.com:aclark4life/buildout-plone-haproxy.git
    git&amp;#64;github.com:aclark4life/buildout-plone-varnish.git
    git&amp;#64;github.com:aclark4life/buildout-zenoss.git
    git&amp;#64;bitbucket.org:pythonpackages/pythonpackages.com.git vanity_app
    git&amp;#64;github.com:pythonpackages/buildout-apache-modwsgi.git
    git&amp;#64;github.com:pythonpackages/buildout-bluebream.git
    git&amp;#64;github.com:pythonpackages/buildout-django.git
    git&amp;#64;github.com:pythonpackages/buildout-jenkins.git
    git&amp;#64;github.com:pythonpackages/buildout-plone-getpaid.git
    git&amp;#64;github.com:pythonpackages/buildout-plone.git
    git&amp;#64;github.com:pythonpackages/buildout-wordpress.git
    git&amp;#64;github.com:pythonpackages/buildout-zope2.git
    git&amp;#64;github.com:pythonpackages/experimental.pythonpackages.git
    git&amp;#64;github.com:pythonpackages/github-services.git pythonpackages-github-services
    git&amp;#64;github.com:pythonpackages/pyramidpypi.git pythonpackages-index
    git&amp;#64;github.com:pythonpackages/pythonpackages-blog.git
    git&amp;#64;github.com:pythonpackages/pythonpackages-docs.git
    git&amp;#64;github.com:pythonpackages/pythonpackages-graphs.git
    git&amp;#64;github.com:pythonpackages/pythonpackages-paste.git
    git&amp;#64;github.com:pythonpackages/pythonpackages-scaffolds.git
    git&amp;#64;github.com:pythonpackages/pythonpackages.sendpickedversions.git
    git&amp;#64;github.com:pythonpackages/pythonpackages-whiskers.git
    git&amp;#64;github.com:pythonpackages/pythonpackages.git
vcs = git

[toys]
basedir = /Users/aclark/Developer/toys
checkouts =
    git&amp;#64;github.com:aclark4life/basic_pyramid_zodb.git
    git&amp;#64;github.com:aclark4life/github_repos_cloner.git
    git&amp;#64;github.com:aclark4life/other.git
    git&amp;#64;github.com:aclark4life/python_study.git
    git&amp;#64;github.com:aclark4life/django-hello.git
vcs = git
&lt;/pre&gt;
&lt;p&gt;Now it's time to bootstrap the Collective Python Buildout, which gives me &lt;strong&gt;all versions of Python, ever&lt;/strong&gt; &lt;a class="footnote-reference" href="#id17" id="id10"&gt;[7]&lt;/a&gt;. And off we go:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ cd Developer/buildout.python
$ python bootstrap.py
&lt;/pre&gt;
&lt;p&gt;Finally, there is some PATH configuration required to make all of this seemless. The Collective Python Buildout gets installed in /opt while brew's stuff is in /usr/local. My PATH config currently looks like this:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
export PATH=/usr/local/bin:/usr/local/sbin:/opt/local/bin:/Users/aclark/Developer/buildout.python/python-2.7/bin:$PATH
export PATH=~/Developer/binfiles:/usr/local/share/npm/bin:$PATH
&lt;/pre&gt;
&lt;p&gt;With the above configuration, I default to the Python 2.7 in the Collective Python Buildout. That means that is the &amp;quot;python&amp;quot; or &amp;quot;virtualenv&amp;quot; I get when I type those commands. I use the full path or expanded binary name when I need them e.g. /usr/local/bin/python or python3.3.&lt;/p&gt;
&lt;p&gt;That's it! I hope you will check out dotfiles and checkoutmanager for all your development needs.&lt;/p&gt;
&lt;table class="docutils footnote" frame="void" id="id11" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id1"&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Not really an ode: &lt;a class="reference external" href="http://en.wikipedia.org/wiki/Ode"&gt;http://en.wikipedia.org/wiki/Ode&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id12" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id2"&gt;[2]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;I know about Kenneth Reitz's XCode Command line Tools only, but if I recall correctly there is some &amp;quot;gotcha&amp;quot; that has bitten me more than once if I use that instead of the full XCode. I wish I could remember what it was now, but it's not coming to me. If it works for you though, great!&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id13" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id4"&gt;[3]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;I know about the system Python, and for small things like checkoutmanager and dotfiles I don't mind using it. But there is merit in avoiding it because Apple treats it like &amp;quot;their&amp;quot; Python and makes decisions for you that you may prefer to make yourself. E.g. I believe they use a crippled version of the readline library.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id14" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id7"&gt;[4]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Distribute is a more actively maintained fork of the venerable setuptools library (which itself is built on top of the Python standard library's distutils). Are we having fun yet?&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id15" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id9"&gt;[5]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;I also alias checkoutmanager to cm :-)&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id16" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id6"&gt;[6]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;I force because I want to replace the newly created .ssh dir with the one I keep in my Dotfiles repository.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils footnote" frame="void" id="id17" rules="none"&gt;
&lt;colgroup&gt;&lt;col class="label" /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td class="label"&gt;&lt;a class="fn-backref" href="#id10"&gt;[7]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Well, 2.4 through 3.3 at last count.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
</summary><category term="Django"></category><category term="Mozilla"></category><category term="Plone"></category><category term="Python"></category></entry><entry><title>Please Help Me Do Open Source Work</title><link href="http://aclark.net/blog/2013/01/31/please-help-me-do-open-source-work/" rel="alternate"></link><updated>2013-01-31T13:00:00-05:00</updated><author><name>aclark</name></author><id>tag:aclark.net/blog,2013-01-31:2013/01/31/please-help-me-do-open-source-work/</id><summary type="html">&lt;p&gt;&lt;em&gt;From my 'mid-life-crisis' series of blog entries :-)&lt;/em&gt;&lt;/p&gt;
&lt;img alt="https://raw.github.com/ACLARKNET/blog/gh-pages/images/open-source-work.png" src="https://raw.github.com/ACLARKNET/blog/gh-pages/images/open-source-work.png" /&gt;
&lt;div class="section" id="open-source-work"&gt;
&lt;h2&gt;Open Source Work&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Open Source Work&lt;/strong&gt; has paid my bills for a long time. Starting with &lt;a class="reference external" href="http://plone.org"&gt;Plone&lt;/a&gt; in the early 2000s, to &lt;a class="reference external" href="http://djangoproject.com"&gt;Django&lt;/a&gt; in the early 2010s, to now. And for this, I am very grateful. To be clear: it's not exactly the &lt;em&gt;Open Source Work&lt;/em&gt; that has paid my bills, it's the consulting work I've been able to secure as a result of my dedication and devotion to open source software and communities. Which is great! (Even more clear: my dedication and devotion to open source software and communities has made learning new skills fun. And those skills have paid my bills for the past 8 years.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TL;DR: Open Source Work is awesome. I'll likely spend my entire life doing it (in some capacity or another). And while Open Source Work does not pay, the experience is invaluable.&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="saas-offering"&gt;
&lt;h2&gt;SaaS Offering&lt;/h2&gt;
&lt;p&gt;Along the way, I caught the &amp;quot;startup bug&amp;quot; and have been interested in building a SaaS offering that would at least pay my bills, if not make me fantastically wealthy. Enter 2012's: &lt;a class="reference external" href="http://pythonpackages.com"&gt;pythonpackages.com&lt;/a&gt;. The year I spent doing pythonpackages.com work was awesome. I learned a lot. Traveled. Met a lot of cool folks who seemed genuinely interested in my idea(s). But unfortunately, I never made a dime doing it. The lesson, among others, is that &lt;strong&gt;SaaS offerings are hard&lt;/strong&gt;. I am now semi-focused on a &amp;quot;reboot&amp;quot; of the pythonpackages.com idea(s), but that's going to take a while to get going.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TL;DR: Consulting *was* the dream. Now building a SaaS offering *is* the dream (among others). So where does Open Source Work fit in?&lt;/strong&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="play-as-work"&gt;
&lt;h2&gt;Play as Work&lt;/h2&gt;
&lt;p&gt;I've been &amp;quot;working for a living&amp;quot; since age 14. Back then, I was a busboy and dishwasher in my family's Italian restaurant, where I first learned to &lt;strong&gt;work hard and have fun doing it&lt;/strong&gt;. Since then, I've always worked hard, had fun, and taken few vacations (except for 1994-1998 when I was a full time CS student). I suspect I will always &amp;quot;work for a living&amp;quot; though as I get older, the line between work and play becomes even blurrier. Everyone wants to love or at least like their work. But very few are able to turn their play in to paid work. That's what I want to do. And I am very fortunate, I think, to know what I want to do in life. I know middle aged folk that still don't know the answer to that question.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TL;DR: liking my work *was* the dream. Now turning the things I like to do into paid work *is* the dream. In 2013, I would like to spend more time doing Open Source Work, working on projects like&lt;/strong&gt; &lt;a class="reference external" href="http://github.com/buildout"&gt;Buildout&lt;/a&gt;, &lt;a class="reference external" href="http://dcpython.org"&gt;DC Python&lt;/a&gt;, &lt;a class="reference external" href="http://github.com/python-imaging"&gt;Pillow&lt;/a&gt;, &lt;a class="reference external" href="http://plone.org"&gt;Plone&lt;/a&gt;, &lt;a class="reference external" href="http://github.com/codekoala/django-axes"&gt;django-axes&lt;/a&gt;, &lt;a class="reference external" href="http://resume.aclark.net/projects/#collective"&gt;et al&lt;/a&gt;. &lt;strong&gt;If you have benefited from my work on any of these projects, directly or indirectly, please consider making a&lt;/strong&gt; &lt;a class="reference external" href="https://www.gittip.com/aclark4life"&gt;gittip donation&lt;/a&gt; &lt;strong&gt;to help me do more Open Source Work in 2013.&lt;/strong&gt;&lt;/p&gt;
&lt;script data-gittip-username="aclark4life"
src="https://www.gittip.com/assets/widgets/0002.js"&gt;
&lt;/script&gt;&lt;/div&gt;
</summary><category term="Django"></category><category term="Mozilla"></category><category term="Plone"></category><category term="Python"></category></entry><entry><title>Python 3 Porting</title><link href="http://aclark.net/blog/2013/01/10/python-3-porting/" rel="alternate"></link><updated>2013-01-10T19:15:00-05:00</updated><author><name>aclark</name></author><id>tag:aclark.net/blog,2013-01-10:2013/01/10/python-3-porting/</id><summary type="html">&lt;p&gt;&lt;em&gt;The 3 in 2013 is for Python 3&lt;/em&gt;&lt;/p&gt;
&lt;img alt="https://raw.github.com/ACLARKNET/blog/gh-pages/images/python-3-port.jpg" src="https://raw.github.com/ACLARKNET/blog/gh-pages/images/python-3-port.jpg" /&gt;
&lt;p&gt;I tend to like projects that everyone else &lt;strong&gt;hates&lt;/strong&gt;, e.g.:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Removing persistent Python objects associated with missing classes in ZODB.&lt;/li&gt;
&lt;li&gt;Making new releases for old software that is still useful but unmaintained.&lt;/li&gt;
&lt;li&gt;Running flake8 on 10s or 100s of source files and hand-fixing the results.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Part of this has to do with &lt;strong&gt;repetition&lt;/strong&gt;. I know how to do these things, and I like doing them. Over and over. If someone says, &amp;quot;my Data.fs file is broken&amp;quot; I get excited. Anyway, I hope you get the idea.&lt;/p&gt;
&lt;div class="section" id="i-am-your-man"&gt;
&lt;h2&gt;I am your man&lt;/h2&gt;
&lt;p&gt;Which brings me to the subject of this post: &lt;strong&gt;Python 3 Porting&lt;/strong&gt;. I've been helping out porting the Python Imaging Library to Python 3 (via the Pillow fork, where I am the release manager). And it strikes me as the type of thing I'd be very interested in doing professionally. So, if you or your company are in need of a &amp;quot;workhorse&amp;quot; to plow through old code and update it, &lt;a class="reference external" href="http://aclark.net/team/alex-clark"&gt;I am your man&lt;/a&gt;. Please do &lt;a class="reference external" href="mailto:info&amp;#64;aclark.net"&gt;get in touch&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what-s-in-it-for-you"&gt;
&lt;h2&gt;What's in it for you&lt;/h2&gt;
&lt;p&gt;Now I know what you are thinking: &lt;strong&gt;porting Python 2 software to Python 3 is a lot of work for little gain&lt;/strong&gt;. Maybe. Maybe not. I'm not going to try to convince you otherwise, however I will tell you this:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;For me, 2013 is &amp;quot;the year of Python 3&amp;quot;. I've now promised to deliver and maintain a &lt;strong&gt;Python 3 compatible PIL by PyCon 2013&lt;/strong&gt;. I now care about Python 3 (this was not true before).&lt;/li&gt;
&lt;li&gt;The Python 3 Wall of Shame is now the &lt;a class="reference external" href="https://python3wos.appspot.com/"&gt;Python 3 Wall of Superpowers&lt;/a&gt;. We are over the hump.&lt;/li&gt;
&lt;li&gt;Many popular Python web frameworks support or are about to support Python 3 e.g. CherryPy, Django, Pyramid.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, there is no time like the present to &lt;strong&gt;take a serious look at Python 3&lt;/strong&gt;.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="Django"></category><category term="Mozilla"></category><category term="Plone"></category><category term="Python"></category></entry><entry><title>Pillow Python 3</title><link href="http://aclark.net/blog/2013/01/10/pillow-python-3/" rel="alternate"></link><updated>2013-01-10T12:15:00-05:00</updated><author><name>aclark</name></author><id>tag:aclark.net/blog,2013-01-10:2013/01/10/pillow-python-3/</id><summary type="html">&lt;p&gt;PIL is on its way to &lt;strong&gt;Python 3&lt;/strong&gt; via Pillow. Support from Brian Crowell and others has been merged into master here:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="https://github.com/python-imaging/Pillow/pull/35"&gt;https://github.com/python-imaging/Pillow/pull/35&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And work continues toward a pre &lt;strong&gt;PyCon 2013&lt;/strong&gt; release! Please help if you can:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Ubuntu users, read through &lt;a class="reference external" href="https://github.com/python-imaging/Pillow/issues/18"&gt;https://github.com/python-imaging/Pillow/issues/18&lt;/a&gt; and provide assistance with testing this Ubuntu package: &lt;a class="reference external" href="https://launchpad.net/~pythoneers/+archive/ppa"&gt;https://launchpad.net/~pythoneers/+archive/ppa&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Git experts, please comment on the merge issue described here: &lt;a class="reference external" href="https://github.com/python-imaging/Pillow/pull/35"&gt;https://github.com/python-imaging/Pillow/pull/35&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Everyone else, please git clone the master branch for testing: &lt;strong&gt;git://github.com/python-imaging/Pillow.git&lt;/strong&gt; and report issues as you find them: &lt;a class="reference external" href="https://github.com/python-imaging/Pillow/issues"&gt;https://github.com/python-imaging/Pillow/issues&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thank you!&lt;/p&gt;
</summary><category term="Python"></category></entry><entry><title>Introducing The Plone Kitty</title><link href="http://aclark.net/blog/2013/01/09/introducing-the-plone-kitty/" rel="alternate"></link><updated>2013-01-09T12:15:00-05:00</updated><author><name>aclark</name></author><id>tag:aclark.net/blog,2013-01-09:2013/01/09/introducing-the-plone-kitty/</id><summary type="html">&lt;p&gt;&lt;em&gt;Actually: re-introducing the Plone Kitty from Plone 1!&lt;/em&gt;&lt;/p&gt;
&lt;img alt="https://raw.github.com/ACLARKNET/blog/gh-pages/images/plone-kitty.png" src="https://raw.github.com/ACLARKNET/blog/gh-pages/images/plone-kitty.png" /&gt;
&lt;p&gt;&lt;em&gt;Plone Kitty&lt;/em&gt; is the name of a theme (then called &amp;quot;skin&amp;quot;) that shipped with the earliest versions of &lt;a class="reference external" href="http://plone.org"&gt;Plone&lt;/a&gt; (1.1 in the image above). This was a simpler time when the web was new, and everything was possible!&lt;/p&gt;
&lt;p&gt;Today, we know that the &lt;strong&gt;web is hard&lt;/strong&gt;. While everything is still possible, building the web requires a tremendous amount of hard work. But it doesn't have to be all drudgery. There is still quite a bit of fun to be had building the web, if you know where to look (in addition to all the unavoidable hard work).&lt;/p&gt;
&lt;p&gt;Enter: Plone. Both the web and Plone have changed drastically since The Plone Kitty once prowled the internet. And while the Plone Kitty is all but extinct, Plone lives on; continously modernizing itself to keep up with the fast pace of today's modern web.&lt;/p&gt;
&lt;p&gt;From the &lt;a class="reference external" href="http://plone-1-fun.herokuapp.com"&gt;Plone Kitty website&lt;/a&gt; (now running on Heroku!):&lt;/p&gt;
&lt;pre class="literal-block"&gt;
If you used Plone &amp;quot;back in the day&amp;quot; (early 2000s), please add a comment below about your experiences then. If you are new to Plone or just curious about it now, please add a comment below about your initial impressions.
&lt;/pre&gt;
&lt;p&gt;So if you'd like to add &lt;strong&gt;your bit of nostalgia&lt;/strong&gt;, or first impressions of Plone, &lt;a class="reference external" href="http://plone-1-fun.herokuapp.com/#disqus"&gt;please do so here&lt;/a&gt;. I appreciate any and all comments.&lt;/p&gt;
</summary><category term="Plone"></category><category term="Python"></category></entry><entry><title>New Year's Python Meme 2012</title><link href="http://aclark.net/blog/2012/12/29/new-years-python-meme-2012/" rel="alternate"></link><updated>2012-12-29T15:30:00-05:00</updated><author><name>aclark</name></author><id>tag:aclark.net/blog,2012-12-29:2012/12/29/new-years-python-meme-2012/</id><summary type="html">&lt;img alt="https://raw.github.com/ACLARKNET/blog/gh-pages/images/tarek-meme-reminder.png" src="https://raw.github.com/ACLARKNET/blog/gh-pages/images/tarek-meme-reminder.png" /&gt;
&lt;p&gt;&lt;em&gt;This is my entry for Tarek Ziadé's New Year's Python Meme, a tradition I have come to enjoy. Both to reflect on the current year and look back on previous years. So here it is.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I did this in &lt;a class="reference external" href="http://blog.aclark.net/2009/12/31/new-years-python-meme/"&gt;2009&lt;/a&gt; &amp;amp; &lt;a class="reference external" href="http://blog.aclark.net/2011/12/21/new-years-python-meme-2011/"&gt;2011&lt;/a&gt;. Let's try it again.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. What’s the coolest Python application, framework or library you have discovered in 2012?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;That would be &lt;a class="reference external" href="http://docs.python-requests.org/en/latest/"&gt;Kenneth Reitz's Requests&lt;/a&gt;. Like many others, I've been bitten by the elegance and simplicity bug that is inherent and ingrained in the Requests library. Primarily, I used it to build pythonpackages.com. In particular, I used it to communicate with the almost-equally-elegant (IMHO) GitHub API. This is why I like requests (among other reasons): I don't need to use a &amp;quot;third party&amp;quot; library to communicate with the GitHub API. Such libraries (I think) attempt to make my job easier by hiding complexity and presenting simpler APIs to use. This is sometimes necessary, but no substitute for &lt;em&gt;really&lt;/em&gt; and &lt;em&gt;actually&lt;/em&gt; simple APIs and good documentation (both of which GitHub and Kenneth provide, with their respective APIs.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. What new programming technique did you learn in 2012?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;JavaScript: check. Unit testing: check. These are techniques I have learned enough of to be effective in my &amp;quot;day job&amp;quot; (I'm self-employed). But I learned (finally) that I am primarily: a Python Web Developer. And it feels good to say that. I use Python, and related web technologies to build web applications for my clients. I typically only care to learn enough of a technology to get my job done, then I lose interest (for the most part). That's because I'm also a Hacker. I identify significantly with this monicker because it fits who I am and how I conduct myself professionally. I care about getting the job done above all else. And if there is a job to be done, my intellectual curiosity knows no bounds. If the job is done, I'm going to play guitar. So whatever the technique, I'll learn it if it's something I care about for whatever reason.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Which open source project did you contribute to the most in 2012 ? What did you do?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is the first year that Plone did not consume my every moment. I also spent significant time working on &lt;a class="reference external" href="https://github.com/buildout"&gt;Buildout&lt;/a&gt; (INI-config-driven system to install Python packages and other software, &amp;amp; perform other related and miscellaneous tasks) and &lt;a class="reference external" href="https://github.com/python-imaging"&gt;Pillow (PIL fork)&lt;/a&gt;. With the help of many others, I hope to get a Python 3.3 compatible release of Pillow out by PyCon 2013. And I'll support Buildout &amp;lt; 2.x until such time as Buildout 2.x goes mainstream.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. Which Python blog or website did you read the most in 2012?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Planets: Django, Mozilla, Plone, Python. Reddits: Python. Other feeds: Hacker News &amp;amp; Tech Crunch. I added Tech Crunch this year to satisfy my &amp;quot;startup itch&amp;quot;, as was recommended to me by Jonathon Perrelli of Fortify.vc in DC.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. What are the three top things you want to learn in 2013?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;How to hustle. Hustling, and more hustling. I've gained a lot (enough?) technical skill over the years. Now I want to put that skill to good use in business. I've managed to remain self-employed for a number of years, now I'd like to employ others full time, build successful businesses and otherwise &amp;quot;expand my empire&amp;quot;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;6. What is the top software, application or library you wish someone would write in 2013?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I hope that I get more significant time to put into my &amp;quot;baby&amp;quot;: &lt;a class="reference external" href="https://github.com/pythonpackages"&gt;pythonpackages.com&lt;/a&gt;. In particular, I'm considering adding a Travis-like service which would spawn Windows VMs to run tests and produce executables for Python packages (to address a particular pain point I've discovered along the way: people want to support Windows, but often don't have the ability to do so easily.)&lt;/p&gt;
&lt;p&gt;Happy (Python) New Year!&lt;/p&gt;
&lt;p&gt;Want to do your own list? Here's how:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Copy-paste the questions and answer to them in your blog&lt;/li&gt;
&lt;li&gt;Tweet it with the &lt;a class="reference external" href="https://twitter.com/search/realtime?q=%232012pythonmeme&amp;amp;src=typd"&gt;#2012pythonmeme&lt;/a&gt; hashtag&lt;/li&gt;
&lt;/ul&gt;
</summary><category term="Django"></category><category term="Mozilla"></category><category term="Plone"></category><category term="Python"></category></entry><entry><title>The Zen of Zope, by Alex Clark</title><link href="http://aclark.net/blog/2012/12/09/the-zen-of-zope-by-alex-clark/" rel="alternate"></link><updated>2012-12-09T18:00:00-05:00</updated><author><name>aclark</name></author><id>tag:aclark.net/blog,2012-12-09:2012/12/09/the-zen-of-zope-by-alex-clark/</id><summary type="html">&lt;pre class="literal-block"&gt;
&amp;gt;&amp;gt;&amp;gt; import other
The Zen of Zope, by Alex Clark


Beautiful is an attribute of ugly.
Explicit is implemented by implicit.
Simple is provided by complex.
Complex is directly provided by complicated.
Flat only implements nested.
Sparse has tagged value dense.
Readability count is not in range.
Special cases could not adapt the rules.
Practicality implements purity.
Errors should never require a specification that doesn’t extend the specification of silence.
Unless explicit is a multi-adapter.
In subscribing to ambiguity, return all the objects that refuse the temptation to guess.
There should be none-- and preferably only zero --output from a handler.
Although that way may not be obvious at first unless you've registered an adapter hook
Now is verified by never.
Although never is not implemented by *right* now.
If the implementation is hard to explain, it queries the bad idea utility.
If the implementation is easy to explain, it may query the good idea utility.
Implicit namespace packages are one honking great idea -- let's do more of those!
&lt;/pre&gt;
</summary><category term="Plone"></category><category term="Python"></category></entry><entry><title>Plone Guide</title><link href="http://aclark.net/blog/2012/11/23/plone-guide/" rel="alternate"></link><updated>2012-11-23T08:30:00-05:00</updated><author><name>aclark</name></author><id>tag:aclark.net/blog,2012-11-23:2012/11/23/plone-guide/</id><summary type="html">&lt;div class="section" id="who"&gt;
&lt;h2&gt;Who&lt;/h2&gt;
&lt;p&gt;For anyone new to my blog, welcome. I am Alex Clark: Python Web Developer.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="what"&gt;
&lt;h2&gt;What&lt;/h2&gt;
&lt;p&gt;Recently with a tweet, I announced the start of a new personal project:&lt;/p&gt;
&lt;img alt="https://raw.github.com/ACLARKNET/blog/gh-pages/images/tweet.png" src="https://raw.github.com/ACLARKNET/blog/gh-pages/images/tweet.png" /&gt;
&lt;/div&gt;
&lt;div class="section" id="when"&gt;
&lt;h2&gt;When&lt;/h2&gt;
&lt;p&gt;I have tentatively scheduled this project to be completed by the end of 2013, because it's important to set a deadline.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="where"&gt;
&lt;h2&gt;Where&lt;/h2&gt;
&lt;p&gt;This project will be hosted on one of my current favorite websites: &lt;a class="reference external" href="http://readthedocs.org"&gt;http://readthedocs.org&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="why"&gt;
&lt;h2&gt;Why&lt;/h2&gt;
&lt;p&gt;I think about Plone a lot as it relates to my current professional work. And I have more thoughts than I can currently keep track of in blogs, tweets, etc. So I decided to make an effort to write them all down.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="how"&gt;
&lt;h2&gt;How&lt;/h2&gt;
&lt;p&gt;I think a lot about what other people think about Plone, so I decided this book will feature comments from the general public in it. E.g.:&lt;/p&gt;
&lt;img alt="https://raw.github.com/ACLARKNET/blog/gh-pages/images/comments.png" src="https://raw.github.com/ACLARKNET/blog/gh-pages/images/comments.png" /&gt;
&lt;/div&gt;
&lt;div class="section" id="how-much"&gt;
&lt;h2&gt;How much?&lt;/h2&gt;
&lt;p&gt;This book will be free. But if you'd like to support its development, please &lt;a class="reference external" href="http://gittip.com/aclark4life"&gt;gittip me&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There's not much to it yet, but feel free to head over and add some comments: &lt;a class="reference external" href="https://plone-guide.readthedocs.org/en/latest/"&gt;https://plone-guide.readthedocs.org/en/latest/&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
</summary><category term="Plone"></category><category term="Python"></category></entry></feed>