Personal tools

itunes03.py

Click here to get the file

Size 5.0 kB - File type text/python-source

File contents

#!/usr/bin/env python
# coding=utf-8

from appscript import app
from re import compile

class AppWrapper(object):
    """
    A class for wrapping appscript's app object 
    """
    # A tupple for commands.
    COMMANDS = ()
    # A dictionary for command mappings. In case a attribute is to map
    # to another attribute of appscript app object, 
    # this dictionary should be used suppling key as class attributes,
    # value as mapped attribute of app object.
    ALT_COMMANDS = {}

    # A tupple of commands, which is called implicitly
    CALLABLES = ()
    # A tupple of settable values
    SETTABLES = ()

    def __getattr__(self, key):
        """
        Obtaining value by calling iTunes function directly
        """
        if key in self.COMMANDS:
            if key in self.ALT_COMMANDS:
                key = self.ALT_COMMANDS[key]
            attr = getattr(self.obj, key)
            if key in self.CALLABLES:
                return attr()
            return attr
        else:
            return super(AppWrapper, self).__getattr__(key)

    def __setattr__(self, key, value):
        """
        Changing values
        """
        if key in self.ALT_COMMANDS:
            key = self.ALT_COMMANDS[key]
        if key in self.SETTABLES:
            attr = getattr(self.obj, key)
            attr.set(value)
        else:
            return super(AppWrapper, self).__setattr__(key, value)

local_library_name = u'ライブラリ'

class Track(AppWrapper):
    """
    Class to map iTunes track object, which represents a song in library.
    """
    COMMANDS = ('id',
                'name', 'artist', 'composer',
                'album', 'album_artist', 'album_rating', 'album_rating_kind',
                'played_count', 'played_date',
                'date_added', 'modification_date', 'description',
                'category', 'comment',
                'genre', 'rating', 'video_kind',
                'bit_rate', 'duration', 'size', 'time',
                'play',
                )

    CALLABLES = COMMANDS[:-1] 

    def __init__(self, track_obj):
        """
        Initializing Track object by using given track_obj.
        """
        self.obj = track_obj

    def get_dict(self):
        """
        A method to get track information as a dictionary.
        """
        d = {}
        for k in self.CALLABLES:
            d[k] = getattr(self, k)
        return d

class iTunes(AppWrapper):
    """
    Class to map to functions, data of iTunes on Mac OS X
    """
    
    COMMANDS = ('launch', 'quit', 'version',
                'volume', 'play', 'stop', 'next_track', 'back_track',
                'player_state',)
    ALT_COMMANDS = {'volume': 'sound_volume',
                   }
    CALLABLES = ('version', 'sound_volume')
    SETTABLES = ('sound_volume')

    def __init__(self):
        """
        Initializing iTunes
        """
        self.obj = app('iTunes')
        #Finding library from playlists
        possible_libs = [x for x in self.obj.playlists()
                                if x.name.get() == local_library_name]
        if possible_libs:
            self.lib = possible_libs[0]
        else:
            self.lib = None

    def get_current_track(self):
        """
        A method to get current playing track.
        This method returns None in case no track is playing.
        """
        if repr(self.obj.player_state()) == 'k.stopped':
            return None
        return Track(self.obj.current_track())

    def find_in_library(self, **kwd):
        """
        Find track(s) in library.
        """
        kwargs = ('name', 'artist', 'album_title', 'album_artist',
                  'composer')
        # Checking keywords
        for k in kwd:
            if k not in kwargs:
                raise TypeError(("""The method find_in_library() """
                                 """doesn't take %s in arguments.""") % k)
        if 'album_title' in kwd:
            kwd['album'] = kwd['album_title']
            del kwd['album_title']
        for k in kwd:
            kwd[k] = compile(kwd[k])

        # Find macing track in library.
        result = []
        for track in self.lib.tracks():
            hit = True
            for k in kwd:
                val = getattr(track, k).get()
                if not kwd[k].findall(val):
                    # In case one of the condition fails,
                    # that means the track doesn't hit.
                    hit = False
                    break
            if hit:
                result.append(Track(track))
        return result

if __name__ == '__main__':
    # test for this module
    from nose.tools import *
    from time import sleep

    it = iTunes()

    it.launch()

    it.volume = 50
    assert_equal(it.volume, 50)
    assert_equal(it.obj.sound_volume(), 50)

    it.play()
    sleep(4)
    it.next_track()
    sleep(4)
    it.next_track()
    sleep(4)
    t = it.get_current_track()
    it.back_track()
    it.back_track()
    sleep(4)
    it.stop()
    sleep(4)
    print t.name, t.artist, t.album
    print t.get_dict()
    t.play()
    sleep(4)

    it.quit()
by ats last modified 2009-06-16 17:50
About this blog
■Author
atsこと柴田淳です。この記事を読んでいただくと,技術者としての人となりを分かってもらえるかも。
Webcore株式会社 代表取締役
Plone上で動く,オープンソースのBlog Product - COREBlog2を使って運用しています。

 
最近書いた本,Mook
みんなのPython 改訂版
Python使いはもちろん,プログラミングの初心者から,他言語からの移行組までご好評いただいているPythonの定番入門書の第2版です。Python 3.0を含む最新の情報について加筆を行い,より読みやすいように構成を大幅に見直しました。第一版をお持ちの方にもお役立ていただける内容になっています。
みんなのPython Webアプリ編
Pythonの基礎から,Webアプリやフレームワークの仕組みまで,つまることなく一気に学べる書籍です。「みんなのPython」と一緒に読んでください:-)。
 

Powered by Plone, the Open Source Content Management System