Fandom

Music Player Daemon Community Wiki

Hack:mpdipod

525pages on
this wiki
Add New Page
Talk0 Share

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

Small script to sync up ipods to mpd playlists.

Requires libgpod's python bindings and python-mpd.

#!/usr/bin/env python

# Python mpd syncer
# Copyright (c) 2009 Matan Peled <chaosite@gmail.com>

import os

# Constants

# iPod mount point (make sure it's properly mounted)
MOUNT_POINT = '/mnt/ipod'
# Safety factor, in gigabytes
SIZE_FUDGE = 0.4

# mpd host, port
MPD_CONNECTION = ('localhost', 6600, )

# mpd root directory
MPD_ROOT = os.path.expanduser('~/mp3')

# Playlists (mpd_name, ipod_name)
PLAYLISTS = [('ipod_Rock', 'Rock'),
             ]
# Covers dir
COVERS_DIR = os.path.expanduser('~/.covers/')

# Code

import gpod
import mpd

def ipod_capacity(mountpoint = MOUNT_POINT):
    if not os.path.exists(mountpoint):
        raise ValueError("Mount point does not exist")
    device = gpod.itdb_device_new()
    gpod.itdb_device_set_mountpoint(device, mountpoint)
    info = gpod.itdb_device_get_ipod_info(device)
    return int((info.capacity - SIZE_FUDGE) * 1024 * 1024 * 1024)

def compare_tracks(a, b):
    return (a['size'] == b['size'] and
            a['title'] == b['title'] and
            a['artist'] == b['artist'] and
            a['album'] == b['album'])

class FreeSpaceException(Exception): pass

class iPod(object):
    def __init__(self, path = MOUNT_POINT):
        self.path = path
        self.db = gpod.Database(self.path)

    # simplistic, but OK
    def used_space(self):
        size = 0
        for track in self.db.Master:
            size += track['size']
        for track in self.db.Podcasts:
            size += track['size']
        return size

    def free_space(self):
        return ipod_capacity(self.path) - self.used_space()

    def sync_playlist(self, name, tracks):
        for playlist in self.db.Playlists:
            if playlist.name == name:
                for i, track in enumerate(tracks):
                    if i >= len(playlist):
                        playlist.add(track)
                        continue
                    if not compare_tracks(track, playlist[i]):
                        to_del = playlist[i]
                        playlist.remove(to_del)
                        self.db.Master.remove(to_del)
                        playlist.add(track, pos = i)
                if len(playlist) - 1 > i:
                    for track in playlist[i + 1:]:
                        playlist.remove(track)
                        self.db.Master.remove(track)
                return True
        playlist = self.db.new_Playlist(title = name)
        for track in tracks:
            playlist.add(track)
        return True

    def check_freespace(self, tracks):
        size = sum([ track['size'] for track in tracks ])
        return size < self.free_space()

    def close(self):
        self.db.copy_delayed_files()
        self.db.close()

    def track_factory(self, filename):
        _track = gpod.Track(filename)
        for track in self.db.Master:
            if compare_tracks(_track, track):
                return track
        t = self.db.new_Track(filename = filename)
        t.set_coverart_from_file(os.path.join(COVERS_DIR, t['artist'],
                                              "%s.jpg" % (t['album'], )))
        return t

# mpd code (move to different file when it gets too complex)

def get_filenames(mpd_playlist):
    client = mpd.MPDClient()
    client.connect(*MPD_CONNECTION)
    return [ os.path.join(MPD_ROOT, filename)
             for filename in client.listplaylist(mpd_playlist) ]

def sync(ipod, playlists):
    for mpd_playlist, ipod_playlist in playlists:
        tracks = [ ipod.track_factory(filename)
                   for filename in get_filenames(mpd_playlist) ]
        if not ipod.check_freespace(tracks):
            raise FreeSpaceException("Not enough free space!")
        ipod.sync_playlist(ipod_playlist, tracks)
    return True

def main():
    ipod = iPod(MOUNT_POINT)
    sync(ipod, PLAYLISTS)
    ipod.close()

if __name__ == '__main__':
     main()

Also on Fandom

Random Wiki