<?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/"
	xmlns:georss="http://www.georss.org/georss" >

<channel>
	<title>Ogre &#187; applescript</title>
	<atom:link href="http://rumsey.org/blog/tag/applescript/feed/" rel="self" type="application/rss+xml" />
	<link>http://rumsey.org/blog</link>
	<description></description>
	<lastBuildDate>Fri, 17 Feb 2012 00:55:25 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>I see what you did there</title>
		<link>http://rumsey.org/blog/2010/10/i-see-what-you-did-there/</link>
		<comments>http://rumsey.org/blog/2010/10/i-see-what-you-did-there/#comments</comments>
		<pubDate>Sun, 10 Oct 2010 02:37:27 +0000</pubDate>
		<dc:creator>Ogre</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[applescript]]></category>
		<category><![CDATA[appletv]]></category>
		<category><![CDATA[boxee]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[sqlite]]></category>
		<category><![CDATA[tv]]></category>

		<guid isPermaLink="false">http://rumsey.org/blog/?p=350</guid>
		<description><![CDATA[Today&#8217;s project was this little python script. This runs on a Mac, but goes out and grabs the sqlite database from a system that&#8217;s running Boxee, finds anything that&#8217;s been watched in Boxee in the last two days, then talks to iTunes and marks things watched there as well. This is so if we watch [...]]]></description>
			<content:encoded><![CDATA[<p>Today&#8217;s project was this little python script.  This runs on a Mac, but goes out and grabs the sqlite database from a system that&#8217;s running <a href="http://www.boxee.tv/">Boxee</a>, finds anything that&#8217;s been watched in Boxee in the last two days, then talks to iTunes and marks things watched there as well.  This is so if we watch something on Boxee, the blue &#8220;unplayed&#8221; dot will also go away on the AppleTV in the other room.</p>
<p>Next project, I suppose, is doing the same thing in reverse: letting Boxee know when we&#8217;ve watched something on the AppleTV.  That&#8217;s only possible with the old AppleTV right now, the new one doesn&#8217;t even sync the watched flag with iTunes any more.  I hope they will add that in an update, but the rental model is their main push right now, not helping me out with my crazy setup.</p>
<p>This requires <a href="http://appscript.sourceforge.net/">appscript</a> and <a href="http://github.com/dbr/tvnamer">tvnamer</a> for Python.  tvnamer is a great Python module that is able to parse filenames and turn them into structured TV episode data.  It&#8217;s often used in conjunction with <a href="http://github.com/dbr/tvdb_api">tvdb_api</a> to get descriptions, banners, etc. in media center applications based on nothing but filenames.  I have another project that does just that, but today&#8217;s script only needs tvnamer.</p>
<p>This is the first time I&#8217;ve used the applescript binding for python, I was happy to see how easy it was.  Applescript itself is an awful language, hurray for not actually having to write any!  It&#8217;s also the first time I&#8217;ve used sqlite in a program, though I&#8217;ve messed with other programs&#8217; databases by hand before.</p>
<p><span id="more-350"></span></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>, <span style="color: #dc143c;">sys</span>, <span style="color: #dc143c;">datetime</span>, <span style="color: #dc143c;">time</span>
<span style="color: #ff7700;font-weight:bold;">import</span> sqlite3
<span style="color: #ff7700;font-weight:bold;">import</span> tvnamer
<span style="color: #ff7700;font-weight:bold;">from</span> appscript <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> iTunesError<span style="color: black;">&#40;</span><span style="color: #008000;">Exception</span><span style="color: black;">&#41;</span>:
    <span style="color: #483d8b;">&quot;&quot;&quot;iTunes Error&quot;&quot;&quot;</span>
    <span style="color: #ff7700;font-weight:bold;">pass</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> mark_watched<span style="color: black;">&#40;</span>show, season, episode<span style="color: black;">&#41;</span>:
    playlists = app<span style="color: black;">&#40;</span><span style="color: #483d8b;">'iTunes'</span><span style="color: black;">&#41;</span>.<span style="color: black;">sources</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">'Library'</span><span style="color: black;">&#93;</span>.<span style="color: black;">playlists</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> p <span style="color: #ff7700;font-weight:bold;">in</span> playlists:
        <span style="color: #ff7700;font-weight:bold;">if</span> p.<span style="color: black;">name</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> == <span style="color: #483d8b;">'TV Shows'</span>:
            tv = p
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> tv:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Can't locate TV Shows playlist, exiting&quot;</span>
        <span style="color: #ff7700;font-weight:bold;">raise</span> iTunesError
&nbsp;
    found = <span style="color: #008000;">False</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">for</span> t <span style="color: #ff7700;font-weight:bold;">in</span> tv.<span style="color: black;">tracks</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#40;</span>t.<span style="color: black;">show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">lower</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> == show.<span style="color: black;">lower</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span>
            <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>t.<span style="color: black;">season_number</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> == <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>season<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span>
            <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>t.<span style="color: black;">episode_number</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> == <span style="color: #008000;">int</span><span style="color: black;">&#40;</span>episode<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>:
            ep = <span style="color: #483d8b;">&quot;%s.s%02ds%02d&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>t.<span style="color: black;">show</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, t.<span style="color: black;">season_number</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>, t.<span style="color: black;">episode_number</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'Marking ep watched: '</span> + ep
            found = <span style="color: #008000;">True</span>
            t.<span style="color: black;">unplayed</span>.<span style="color: #008000;">set</span><span style="color: black;">&#40;</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">if</span><span style="color: black;">&#40;</span>t.<span style="color: black;">played_count</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&lt;</span> <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>:
                t.<span style="color: black;">played_count</span>.<span style="color: #008000;">set</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> found:
        <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;Failed to find %s s%02de%02d&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>show, season, episode<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">return</span> found
&nbsp;
<span style="color: #dc143c;">os</span>.<span style="color: black;">system</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'rsync neurosuser@192.168.1.161:.boxee/UserData/profiles/tinyogre/Database/boxee_user_catalog.db .'</span><span style="color: black;">&#41;</span>
&nbsp;
period = <span style="color: #dc143c;">datetime</span>.<span style="color: #dc143c;">datetime</span>.<span style="color: black;">now</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> - <span style="color: #dc143c;">datetime</span>.<span style="color: black;">timedelta</span><span style="color: black;">&#40;</span>days = <span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>
since = <span style="color: #dc143c;">time</span>.<span style="color: black;">mktime</span><span style="color: black;">&#40;</span>period.<span style="color: black;">timetuple</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
conn = sqlite3.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'boxee_user_catalog.db'</span><span style="color: black;">&#41;</span>
c = conn.<span style="color: black;">cursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
c.<span style="color: black;">execute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'select strPath, iPlayCount from watched where iLastPlayed &gt; ?'</span>, <span style="color: black;">&#40;</span>since, <span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
<span style="color: #ff7700;font-weight:bold;">for</span> r <span style="color: #ff7700;font-weight:bold;">in</span> c:
    ep = r<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>.<span style="color: black;">rpartition</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'/'</span><span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span>
    parsed = tvnamer.<span style="color: black;">processSingleName</span><span style="color: black;">&#40;</span>ep<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">if</span> parsed <span style="color: #ff7700;font-weight:bold;">is</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">None</span>:
        mark_watched<span style="color: black;">&#40;</span>parsed<span style="color: black;">&#91;</span><span style="color: #483d8b;">'file_seriesname'</span><span style="color: black;">&#93;</span>, parsed<span style="color: black;">&#91;</span><span style="color: #483d8b;">'seasno'</span><span style="color: black;">&#93;</span>, parsed<span style="color: black;">&#91;</span><span style="color: #483d8b;">'epno'</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://rumsey.org/blog/2010/10/i-see-what-you-did-there/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iTunes Expressions</title>
		<link>http://rumsey.org/blog/2010/05/itunes-expressions/</link>
		<comments>http://rumsey.org/blog/2010/05/itunes-expressions/#comments</comments>
		<pubDate>Mon, 17 May 2010 04:48:25 +0000</pubDate>
		<dc:creator>Ogre</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[applescript]]></category>
		<category><![CDATA[geotag]]></category>
		<category><![CDATA[itunes]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://rumsey.org/blog/?p=306</guid>
		<description><![CDATA[iTunes smart playlists are actually fairly complex boolean expressions (since iTunes 9, previous versions were not as robust). This page describing iTunes library management contains more text than the entire Lua 3.0 manual! (I&#8217;m cheating here, Lua is on v5.1, and the manual is more than twice as large these days, but the point still [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-full wp-image-314" style="border: 0pt none;" title="ITunes" src="http://rumsey.org/blog/wp-content/uploads/2010/05/ITunes_Logo.png" alt="" width="128" height="128" />iTunes smart playlists are actually fairly complex boolean expressions (since iTunes 9, previous versions were not as robust).  <a href="http://www.google.com/url?sa=t&amp;source=web&amp;ct=res&amp;cd=8&amp;ved=0CDkQFjAH&amp;url=http%3A%2F%2Fwww.ilounge.com%2Findex.php%2Farticles%2Fcomments%2Fthe-complete-guide-to-managing-itunes-videos%2F&amp;ei=Ir7wS7rnKoWKlweBqMG1CA&amp;usg=AFQjCNEPk7oSmVlrDIYPSeySEG7bj_8u2Q&amp;sig2=Vk970UWA4n0eSmAToxIwaw">This page describing iTunes library management</a> contains more text than the entire <a href="http://www.lua.org/manual/3.0/manual.html">Lua 3.0 manual!</a> (I&#8217;m cheating here, Lua is on v5.1, and the manual is more than twice as large these days, but the point still stands).  Via dropdowns and text boxes you&#8217;re practically writing SQL WHERE clauses when creating a smart playlist.</p>
<p>Yet for all that complexity, there is STILL no way built into iTunes to make a Smart Playlist that can precisely select between High-def and standard-def TV Shows and movies.</p>
<p>My compromise is making a playlist that selects shows between 20 and 31 minutes that are greater than 500MB, and shows 39 minutes or longer that are greater than 900MB.  Those numbers aren&#8217;t very precisely chosen, but they seemed to work properly for all but one episode in my library, there was <a href="http://thetvdb.com/?tab=episode&amp;seriesid=92411&amp;seasonid=71361&amp;id=694421&amp;lid=7">one hour long episode</a> that says it&#8217;s &#8220;HD&#8221; but is only 600MB, I ignored that one, but it illustrates why this is such a bad solution.  There are standard def shows that are nearly 600MB in my library too.</p>
<p>The <a href="http://forums.macnn.com/82/applications/395805/question-about-itunes-hd-smart-playlists/">compromise some people come to</a> is manually adding an HD Tag to the composer, description, comments, or some other field, but the whole point here is that I&#8217;m trying to avoid manually doing anything to differentiate them.  I could just as easily add all the HD videos to a dumb playlist, and then select on that playlist in a smart playlist.</p>
<p>I&#8217;ve had this frustration for at least a year, since we first got an Apple TV.  When, when, when will Apple fix it?  Or if they have, then when, when, when someone on the internet figure out how to do it?</p>
<p>Since the thing I wanted this playlist for is already an Applescript that&#8217;s iterating TV Shows from a playlist, I suppose the &#8220;solution&#8221; in this case is to make the Applescript able to differentiate.  The filename actually has an &#8220;(HD)&#8221; in it for HD episodes, and Applescript does have access to filenames, but iTunes proper can&#8217;t select on filename contents.</p>
<p>On the other hand, the horror of having to actually write more than a few lines of Applescript caused me to write just enough to be able to call out to a python script instead.  So there&#8217;s a whole &#8216;nother rant about crappy Apple &#8220;programming languages&#8221; right there.  I do realize that <a href="http://wiki.python.org/moin/MacPython/AppleScript">Python can use Applescript interfaces directly</a>, but then it&#8217;s harder to just <a href="http://dougscripts.com/itunes/scripts/ss.php?sp=moveplaylisttofolder">Download a script that almost does what I want</a> and fix the parts that don&#8217;t.</p>
]]></content:encoded>
			<wfw:commentRss>http://rumsey.org/blog/2010/05/itunes-expressions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<georss:point>37.3316574 -122.0301743</georss:point>	</item>
	</channel>
</rss>

