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()