def volume(self, value): """Set volume level Must be a integer in range 0-100 """ if not isinstance(value, int): raise iTunesError('Volume adjustment must be integer value') if value < 0 or value > 100: raise iTunesError('Volume adjustment must be in range 0-100') self.itunes.sound_volume.set(to=value)
def syncTags(self, song): """Sync file tags Sync tags from file metadata to itunes """ modified = False try: for tag in ('artist', 'album', 'title', 'genre', 'date', 'bpm'): if not song.tags.has_key(tag): continue if tag in ( 'bpm', 'date', ): value = int(song.tags[tag]) else: value = song.tags[tag] if tag == 'bpm' and value == 0: continue if tag == 'title': tag = 'name' self.updateTag(tag, value) modified = True except TagError as e: raise iTunesError('Error updating tags: {0} {1}'.format(self.path, e)) if self.updateTracknumber(): modified = True return modified
def lookup_index(self, path): """Find index for filename Raises iTunesError if path was not in database """ path = os.path.realpath(path) try: c = self.cursor c.execute("""SELECT key FROM itunes WHERE path=?""", (path,)) res = c.fetchone() except OperationalError as e: raise iTunesError(e) if res: return res[0] else: raise iTunesError('Track not in index database: {0}'.format(path))
def repeat(self, value): """Set repeat Set repeat mode. Valid values are in pytunes.constants.REPEAT_VALUES """ try: self.itunes.current_playlist.song_repeat.set(to=REPEAT_VALUES[value]) except KeyError: raise iTunesError('Invalid repeat value {0}'.format(value))
def get_playlist(self, name): """Get playlist by name """ if self.itunes is None: self.__connect__() for pl in self.itunes.user_playlists.get(): if pl.name.get() == name: return iTunesPlaylist(self, name) raise iTunesError('No such playlist: {0}'.format(name))
def add_track(self, track): """Add track to index """ try: c = self.cursor c.execute("""SELECT key, mtime FROM itunes WHERE key=?""", (track.index,)) res = c.fetchone() except OperationalError as e: raise iTunesError(e) try: mtime = os.stat(track.path).st_mtime except OSError: mtime = None except IOError: mtime = None if res is not None: if mtime: if res[1] != mtime: c = self.cursor c.execute("""UPDATE itunes set mtime=? WHERE key=?""", (mtime, res[0],)) self.commit() else: c = self.cursor c.execute("""DELETE FROM itunes WHERE key=?""", (res[0],)) self.commit() elif mtime is not None: added = datetime.now(timezone("UTC")) try: c = self.cursor c.execute("""INSERT INTO itunes VALUES (?, ?, ?, ?)""", ( track.index, track.path, mtime, added )) self.commit() except OperationalError as e: raise iTunesError(e)
def jump(self, index): """Play track by index """ if self.itunes is None: self.__connect__() try: self.itunes.play(self.library.playlist.file_tracks[index]) except appscript.reference.CommandError: raise iTunesError('Invalid library index: {0}'.format(index)) return self.current_track
def cleanup(self, ids): """Remove unknown IDs Removes tracks with ID not provided in list 'ids' """ try: c = self.cursor c.execute("""DELETE FROM itunes WHERE key not in (?)""", (','.join(ids),)) self.commit() except OperationalError as e: raise iTunesError(e)
def log_track_change(self, details): """Log track changes Logs timestamp and path of track played to logfile, if defined. """ if self.logfile is not None: path = os.path.expandvars(os.path.expanduser(self.logfile)) try: with open(path, 'a') as f: f.write('{0} {1}\n'.format( details['started'], details['path'], )) f.flush() except OSError as e: raise iTunesError('Error writing to {0}: {1}'.format(self.log_file, e)) except IOError as e: raise iTunesError('Error writing to {0}: {1}'.format(self.log_file, e)) if self.redis is not None: self.redis.lpush(self.redis_key, details) self.redis.ltrim(self.redis_key, MAX_REDIS_LIST_ITEMS)
def __init__(self, itunes_path=None, codec='m4a', tree_path=ITUNES_PATH_FILE): self.itunes_path = itunes_path is not None and itunes_path or ITUNES_DIR if not os.path.isdir(self.itunes_path): raise iTunesError('No such directory: {0}'.format(self.itunes_path)) if tree_path is None: if os.path.isfile(ITUNES_PATH_FILE): try: tree_path = open(ITUNES_PATH_FILE, 'r').read().strip() except IOError as e: raise iTunesError('Error opening {0}: {1}'.format(tree_path, e)) except OSError as e: raise iTunesError('Error opening {0}: {1}'.format(tree_path, e)) else: tree_path = ITUNES_MUSIC if not os.path.isdir(tree_path): raise iTunesError('No such directory: {0}'.format(tree_path)) Tree.__init__(self, path=tree_path)
def delete(self, entry): """Delete entry from playlist Delete provided track entry from playlist (via entry.track) """ try: self.client.delete(entry.track) if self.__index__ > 0: self.__index__ -= 1 self.__update_len__() except appscript.reference.CommandError as e: raise iTunesError('Error deleting track {0}: {1}'.format(entry.track, e))
def __init__(self, client, name=None): self.client = client self.__index__ = 0 try: if name is None: self.playlist = self.client.get(self.client.library_playlists['library']) name = 'library' else: self.playlist = self.client.get(self.client.user_playlists[name]) except appscript.reference.CommandError: raise iTunesError('No such playlist: {0}'.format(name)) self.name = name self.__update_len__()
def __getitem__(self, item): if item == 'path': return self.path if item == 'extension': return os.path.splitext(self.path)[1][1:] if item in ('id', 'ID'): item = 'id' if item in ('date', 'year'): item = 'year' if item in ('title', 'name'): item = 'name' try: value = self.client.get(self.track.__getattr__(item)) if value == appscript.k.missing_value: value = None try: if item in TRACK_INT_FIELDS: return int(value) elif item in TRACK_FLOAT_FIELDS: return float(value) elif item in TRACK_DATE_FIELDS: return value elif item == 'location': return value.path return str(value) except AttributeError: return value except AttributeError: pass except appscript.reference.CommandError as e: raise iTunesError('Error reading track attribute: {0}'.format(e)) raise KeyError('Invalid Track item: {0}'.format(item))
def __connect__(self): if self.is_running: self.itunes = appscript.app('iTunes', terms=itunes_terminology) else: self.itunes = None raise iTunesError('iTunes is not running')