<?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>damontimm.com &#187; python</title>
	<atom:link href="http://blog.damontimm.com/tag/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.damontimm.com</link>
	<description>Where I go to remember what I did</description>
	<lastBuildDate>Tue, 17 Aug 2010 13:07:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>How To: Store iMovie &#8217;09 Events and Projects on a Network Volume (NAS)</title>
		<link>http://blog.damontimm.com/how-to-store-imovie-09-events-and-projects-on-a-network-volume-nas/</link>
		<comments>http://blog.damontimm.com/how-to-store-imovie-09-events-and-projects-on-a-network-volume-nas/#comments</comments>
		<pubDate>Sat, 10 Apr 2010 15:33:32 +0000</pubDate>
		<dc:creator>Damon</dc:creator>
				<category><![CDATA[how to]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[iMovie]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[nas]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blog.damontimm.com/?p=248</guid>
		<description><![CDATA[Purpose: while iMovie &#8217;09 allows you to store your events and projects on physically attached hard drives (external or internal) it doesn&#8217;t offer an out-of-the-box way to store them on a network attached storage (NAS) device. I have a file serve and I want to use it. how to set it up The only way [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Purpose</strong>: while iMovie &#8217;09 allows you to store your events and projects on physically attached hard drives (external or internal) it doesn&#8217;t offer an out-of-the-box way to store them on a network attached storage (NAS) device.  I have a file serve and I want to use it.</p>
<p><span id="more-248"></span></p>
<h2>how to set it up</h2>
<p>The only way I have found to circumvent this annoyance is to play a little trick on iMovie.  And that trick is to move the original <code>~/Movies</code> folder under a different name and put a symlink in its place (to the network folder of your choice).</p>
<p>Here are the steps I took from the Terminal to do this (you will need to have Administrator privileges and you will need to know where your network folder is attached):</p>
<ul class="terminal">
<li><code>sudo mv ~/Movies/ ~/Movies-original</code></li>
<li><code>ln -s /Volumes/my-network-volume/Movies/ ~/Movies</code></li>
</ul>
<p>Now, when I load up iMovie it will use the networked volume.  If you don&#8217;t like this, you can always move your <code>~/Movies-original</code> folder back where it was.</p>
<h2>remaining issues</h2>
<p>Unfortunately, this isn&#8217;t a perfect fix.  There are two caveats or issues I have found.  </p>
<p>One, is that now my hard drive (called Papa Bear) is listed twice in the <em>Project Library</em>:</p>
<p><img src="http://blog.damontimm.com/wp-content/uploads/2010/04/imovie-duplicate-project-libraries.png" alt="" title="imovie-duplicate-project-libraries" width="415" height="96" class="aligncenter size-full wp-image-249" /></p>
<p>And two, is that when you delete an event or project from within iMovie, it moves the project into a temporary folder rather than actually deleting it.  The next time you open iMovie, it will show up again.  I&#8217;m sure this is because it <em>thinks</em> it is working with a bona fide Trash system but its not (because it is network storage.  See this example:</p>
<p><img src="http://blog.damontimm.com/wp-content/uploads/2010/04/imovie-temporary-folders.png" alt="" title="imovie-temporary-folders" width="423" height="93" class="aligncenter size-full wp-image-250" /></p>
<p>In order to get around this annoyance, I created a Python script which removes the temporary files for me and created a cron job to run the script from time to time (cleaning up the mess iMovie leaves behind).</p>
<pre class="brush: python; gutter: true;">#!/usr/bin/env python
'''
Simple script to remove all directories that match the name:
    /iMovie Temporary Items */  [note the star!]

'''
import os
import fnmatch
import shutil

# tuple of directories to search through (you can add more than one)
DIRS = ('/Volumes/leaker-damon/tps/Videos/',)

for directory in DIRS:
    for root, dirnames, filenames in os.walk(directory):
        for directory in dirnames:
            if fnmatch.fnmatch(directory,'iMovie Temporary Items *'):
                shutil.rmtree(os.path.join(root,directory))</pre>
<h2>make this more better</h2>
<p>Am interested to hear how other people have been handling this &#8212; this approach certainly isn&#8217;t perfect, but it seems to work (for now).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.damontimm.com/how-to-store-imovie-09-events-and-projects-on-a-network-volume-nas/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Script: clean_bzip &#8211; a command line program for clean directory compression</title>
		<link>http://blog.damontimm.com/python-script-clean-bzip/</link>
		<comments>http://blog.damontimm.com/python-script-clean-bzip/#comments</comments>
		<pubDate>Tue, 30 Mar 2010 14:01:05 +0000</pubDate>
		<dc:creator>Damon</dc:creator>
				<category><![CDATA[scripts]]></category>
		<category><![CDATA[bzip2]]></category>
		<category><![CDATA[gzip]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[tar]]></category>

		<guid isPermaLink="false">http://blog.damontimm.com/?p=237</guid>
		<description><![CDATA[A simple command-line python utility that compresses a directory (or directories) and excludes certain unwanted files. As a self-taught Python user I am still looking for insight on the most pythonic and programmatically-friendly way of accomplishing a given task. In this case, I have written a script that will perform a &#8220;clean bzip2&#8243; of a [...]]]></description>
			<content:encoded><![CDATA[<p>A simple command-line python utility that compresses a directory (or directories) and excludes certain unwanted files.</p>
<p><span id="more-237"></span></p>
<p>As a self-taught Python user I am still looking for insight on the most pythonic and programmatically-friendly way of accomplishing a given task.  In this case, I have written a script that will perform a &#8220;clean bzip2&#8243; of a directory (or directories).  Mac OS X (via AFP and netatalk, in my case) tends leaves a bunch of ugly files/directories hanging around and I would rather not include them in my compressed tar file.</p>
<p>In writing the script, though, I ran into some questions and I am not sure what the recommended approach would be. The script works, as it is, but I feel its a little hacked together and also a little limited in its application.   There is something to be said for programs that &#8220;just work&#8221; (this does) but I want to take it a little further as an educational endeavor and would like it to appear robust, future-thinking, and pythonic.</p>
<p>My initial questions are:</p>
<ol>
<li><del datetime="2010-04-02T10:58:26+00:00">Is there a better way to implement a <code>--quiet</code> flag?</del> [using <code>logging</code>]</li>
<li>I am not very clear on the use of Exceptions (or even if I am using it in a good way here) &#8212; is what I have done the right approach? </li>
<li>Finally, in general: any feedback on how to improve this?  (I am thinking, just now, that the script is only suitable for a command line usage, and couldn&#8217;t be imported by another script, for example.)</li>
</ol>
<p>Any feedback is greatly appreciated.  Writing a script like this is a good learning tool (for me, at least).</p>
<pre class="brush: python;">#! /usr/bin/env python

'''Script to perform a "clean" bzip2 on a directory (or directories).  Removes
extraneous files that are created by Apple/AFP/netatalk before compressing.
'''

import os
import tarfile
import logging
from optparse import OptionParser

# Default files and directories to exclude from the bzip tar
IGNORE_DIRS = ('.AppleDouble',)
IGNORE_FILES = ('.DS_Store',)

class DestinationTarFileExists(Exception):
    '''If the destination tar.bz2 file already exists.'''

def ignore_walk(directory, ignore_dirs=None, ignore_files=None):
    '''Ignore defined files and directories when doing the walk.'''

    # TODO: this does not currently take wild cards into account.  For example,
    # if you wanted to exclude *.pyc files ... should fix that.  Perhaps
    # consider moving this entirely into the below function (or making it more
    # reusable for other apps).
    for dirpath, dirnames, filenames in os.walk(directory):
        if ignore_dirs:
            dirnames[:] = [dn for dn in dirnames if dn not in ignore_dirs]
        if ignore_files:
            filenames[:] = [fn for fn in filenames if fn not in ignore_files]
        yield dirpath, dirnames, filenames

def tar_bzip2_directory(directory, ignore_dirs=IGNORE_DIRS,
                                   ignore_files=IGNORE_FILES ):
    '''Takes a directory and creates a tar.bz2 file (based on the directory
    name).  You can exclude files and sub-directories as desired.'''

    file_name = '-'.join(directory.split(' '))
    tar_name = file_name.replace('/','').lower() + ".tar.bz2"

    if os.path.exists(tar_name):
        msg = ("The file %s already exists. " +
                "Please move or rename it and try again.") % tar_name
        raise DestinationTarFileExists(msg)

    tar = tarfile.open(tar_name, 'w:bz2')

    for dirpath, dirnames, filenames in ignore_walk(directory, ignore_dirs,
            ignore_files):
        for file in filenames:
            logging.info(os.path.join(dirpath, file))
            tar.add(os.path.join(dirpath, file))

    tar.close()

def main(args=None, callback=None):
    directories = []

    for arg in args:
        if os.path.isdir(arg):
            directories.append(arg)
        else:
            logging.ERROR("Ingoring: %s (it's not a directory)." % arg)

    for dir in directories:
        try:
            tar_bzip2_directory(dir)
        except DestinationTarFileExists, e:
            print e

if __name__ == "__main__":

    parser = OptionParser(usage="%prog [options: -q ] [dir1] [...dir2]")
    parser.add_option("-q", "--quiet", action="store_true", dest="quiet")
    options, args = parser.parse_args()

    if options.quiet:
        logging.basicConfig(level=logging.ERROR, format='%(message)s')
    else:
        logging.basicConfig(level=logging.INFO, format='%(message)s')

    main(args)</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.damontimm.com/python-script-clean-bzip/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>django-hitcount: simple app to count hits/views for an object</title>
		<link>http://blog.damontimm.com/django-hitcount-app-count-hits-views/</link>
		<comments>http://blog.damontimm.com/django-hitcount-app-count-hits-views/#comments</comments>
		<pubDate>Mon, 26 Oct 2009 01:10:38 +0000</pubDate>
		<dc:creator>Damon</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://blog.damontimm.com/?p=201</guid>
		<description><![CDATA[django-hitcount: a simply django application that allows you to count hits/views on a per object basis. This app came about as an answer to my own question at stackoverflow.com. Am hoping that others will find it useful. This isn&#8217;t meant to be a full-fledged tracking application (see django-tracking) or a real analytic tool (try Google [...]]]></description>
			<content:encoded><![CDATA[<p><strong>django-hitcount</strong>: a simply django application that allows you to count hits/views on a per object basis.  This app came about as an answer to <a href="http://stackoverflow.com/questions/1603340/track-the-number-of-page-views-or-hits-of-an-object">my own question</a> at stackoverflow.com.  Am hoping that others will find it useful.</p>
<p><span id="more-201"></span></p>
<p>This isn&#8217;t meant to be a full-fledged tracking application (see django-tracking) or a real analytic tool (try Google Analytics); rather, it&#8217;s meant to simply count the number of hits/view on an object-per-object basis.  </p>
<h2>How to install:</h2>
<p>I find that the easiest way to work with django apps is to symbolically link them to my <code>site-packages</code> directory.  It&#8217;s easier to update the apps with svn, git, or hg than it is to manually download the files and install by hand.</p>
<p>For me, this is what it looks like (you can cut and paste to make it easy):</p>
<ul class="terminal">
<li><code>cd ~/src</code></li>
<li><code>git clone git://github.com/thornomad/django-hitcount.git</code></li>
<li><code>sudo ln -s `pwd`/django-hitcount/hitcount `python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"`/hitcount</code></li>
</ul>
<p>Test it works by loading python and checking the version (should not get an error):</p>
<pre class="brush: python;">
>>> import hitcount
>>> hitcount.__version__
'0.1 alpha'
>>></pre>
<h2>Adding to your django project:</h2>
<p>Add the <code>hitcount</code> app to your <code>INSTALLED_APPS</code> tuple and run <code>syncdb</code>.  </p>
<p>There are two additional settings you can add to your <code>settings.py</code> file:</p>
<pre class="brush: python;">HITCOUNT_KEEP_HIT_ACTIVE = { 'days': 7 }
HITCOUNT_HITS_PER_IP_LIMIT = 0
HITCOUNT_EXCLUDE_USER_GROUP = ( 'Editor', )</pre>
<p><code><strong>HITCOUNT_KEEP_HIT_ACTIVE</strong></code>: is the number of days, weeks, months, hours, etc (timedelta kwargs), that an Hit is kept &#8216;active&#8217;.  If a Hit is &#8216;active&#8217; a repeat viewing will not be counted.  After the active period ends, however, a new Hit will be recorded.  You can decide how long you want this period to last &#8230;</p>
<p><code><strong>HITCOUNT_HITS_PER_IP_LIMIT</strong></code>: limit the number of &#8216;active&#8217; hits from a single IP address.  <code>0</code> means that it is unlimited.  You may want to set this, or not.  </p>
<p><code><strong>HITCOUNT_EXCLUDE_USER_GROUP</strong></code>: don&#8217;t count any hits from certain logged in users.  In the example above, I don&#8217;t want any of my editors inflating the total Hit count.</p>
<h2>Adding to your <code>urls.py</code>:</h2>
<p>You need to add one line to your <code>urls.py</code> file.  </p>
<p>You can have this url, itself, point to anywhere you like, but you need to keep the <code>name='hitcount_update_ajax'</code> constant.  </p>
<pre class="brush: python; gutter: true;">from django.conf.urls.defaults import *
from django.views.generic.list_detail import object_detail
from hitcount.views import update_hit_count_ajax

urlpatterns = patterns('',
    url(r'^ajax/hit/$', # you can change this url if you would like
        update_hit_count_ajax,
        name='hitcount_update_ajax'), # keep this name the same

    # other views, for example my object view is:

    url(r'^/video/(?P&lt;object_id>\d+)$', object_detail,
        {   'queryset': Video.objects.all(),
            'template_name': "video/view.html"},
            name='video_detail_view'),

)</pre>
<h2>Edit your templates</h2>
<p>Add the javascript to your <code>object_detail</code> templates (or any template that handles a single object) so that our hit counter is called after the document loads.  </p>
<p>Here is what my <code>head</code> includes:</p>
<pre class="brush: html;">{% load hitcount_tags %}
&lt;script src="/media/js/jquery-latest.js" type="text/javascript">&lt;/script>
&lt;script type="text/javascript">&lt;!--
    $(document).ready(function() {
        {% get_hit_count_javascript for object %}
    });
-->&lt;/script></pre>
<p>When the template is rendered, it should turn into something like this:</p>
<pre class="brush: js;">
$(document).ready(function() {

$.post( '/ajax/hit/',
	{ hitcount_pk : '3' },
	function(data, status) {
		if (data.status == 'error') {
			// do something for error?
		}
	},
	'json');

});</pre>
<h2>Display the hits!</h2>
<p>The most exciting part, is actually displaying your hits.  There are four different ways to do it:</p>
<pre class="brush: text;">    - Return total hits for an object:
      {% get_hit_count for [object] %}

    - Get total hits for an object as a specified variable:
      {% get_hit_count for [object] as [var] %}

    - Get total hits for an object over a certain time period:
      {% get_hit_count for [object] within ["days=1,minutes=30"] %}

    - Get total hits for an object over a certain time period as a variable:
      {% get_hit_count for [object] within ["days=1,minutes=30"] as [var] %}</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.damontimm.com/django-hitcount-app-count-hits-views/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss>
