#!/usr/bin/env python
#
# Author: Sebastian Sareyko <public nooms de>
# This script is hereby placed into the public domain.

import xmmsclient
from xmmsclient import collections as xc
import os
import sys
import getopt
from urllib import unquote_plus as unquote
from urllib import quote_plus as quote


VALID_MEDIA = ['mp3', 'ogg', 'flac', 'wav', 'mpc', 'wma']


class Checker:
    def __init__(self, xmms, media_path, media_ext, dry):
        self.xmms = xmms
        self.media = media_path
        self.media_ext = media_ext
        self.dry = dry


    def file_exists(self, f):
        try:
            file = open(f)
        except IOError:
            return 0
        return 1


    def check_mlib(self):
        songs = self.xmms.coll_query_infos(xc.Universe(), ['id', 'url'])
        for song in songs:
            if song['url'][:4] != 'file':
                print 'SKIPPING: "%(url)s"' % song
                continue

            song['url'] = unquote(song['url'][7:].encode('utf8'))

            if not self.file_exists(song['url']):
                print 'REMOVING: "%(url)s"' % song
                if not self.dry:
                    self.xmms.medialib_remove_entry(song['id'])


    def check_media(self):
        songs = self.xmms.coll_query_infos(xc.Universe(), ['url'])
        songlist = [unquote(song['url'].encode('utf8')) for song in songs]

        for root, dirs, files in os.walk(self.media):
            for file in files:
                (base, ext) = os.path.splitext(file)

                if not ext.lower()[1:] in self.media_ext:
                    continue

                file = 'file://%s' % os.path.join(root, file)

                # This is slooooooow
                #
                # file_enc = quote(file, '/:')
                # match = xc.Match(xc.Universe(), field='url', value=file_enc)
                #
                # num_songs = self.xmms.coll_query_ids(match)
                # if len(num_songs) < 1:
                #     print 'ADDING: "%s"' % file
                #     if not self.dry:
                #         self.xmms.medialib_add_entry(file)

                if not file in songlist:
                     print 'ADDING: "%s"' % file
                     if not self.dry:
                         self.xmms.medialib_add_entry(file)


def usage():
    print 'Usage:'
    print ' -h, --help            Print this help'
    print ' -d, --dry             Do a dry-run. I.e. don\'t actually modify'
    print '                       the media library'
    print ' -m, --media <dir>     Specify a directory to check for new media'
    print


def main(argv):
    try:
        opts, args = getopt.getopt(argv, 'hdm:', ['help', 'dry', 'media='])
    except getopt.GetoptError:
        usage()
        sys.exit(1)

    dry = False
    media_dir = None

    for opt, arg in opts:
        if opt in ('-h', '--help'):
            usage()
            sys.exit(0)
        elif opt in ('-d', '--dry'):
            dry = True
        elif opt in ('-m', '--media'):
            media_dir = arg

    xmms = xmmsclient.XMMSSync('mlib-update')

    try:
        xmms.connect(os.getenv('XMMS_PATH'))
    except IOError, detail:
        print 'Connection failed: %s' % detail
        sys.exit(1)

    checker = Checker(xmms, media_dir, VALID_MEDIA, dry)
    checker.check_mlib()
    if media_dir:
        checker.check_media()

    sys.exit(0)


if __name__ == '__main__':
    main(sys.argv[1:])

