#! /usr/bin/env python

# This script is meant to remove poorly-formatted and duplicate entries from
# my cmus lib.pl file.
#
# I keep my entire music library on an external drive, along with a small
# subset on my internal data drive. The internal drive is symlinked from
# my home directory, but I prefer for cmus to only reference the drive by
# its full path.
#
# This script places a few restraints on the library file:
# [1] No album should appear twice. If an album exists on both my internal
#     and my external drives, I prefer the internal version since it's
#     always accessible. Any reference to an album on my external drive
#     which is also present on my internal drive should be removed.
# [2] No album on my internal drive should be referenced via the symlink
#     from my home directory. Any reference to an album using the symlinked
#     path shuold be replaced with a reference using the hard path; if this
#     results in duplicate entries, they should be removed.
#
# So far, it seems to work...

from __future__ import print_function

import os
import sys
import argparse
from random import choice
from string import digits

local_drive_good = "/Volumes/Data HDD/Music"
local_drive_bad = "/Users/julian/Data HDD/Music" # symlink to local_drive_good
external_drive = "/Volumes/WD_Passport_Wolf/Music/Releases"

get_song = lambda line: line.strip().split('/')[-1]

def remove_cmus_duplicates(playlist):
    local_songs = set()

    playlist_temp = random_filename(playlist.partition('.')[0])
    os.rename(playlist, playlist_temp)

    with open(playlist_temp, 'rt') as pl_old, open(playlist, 'wt') as pl_new:
        for line in pl_old:
            song_name = get_song(line)
            if song_name not in local_songs:
                if line.startswith(local_drive_good):
                    line_new = line
                elif line.startswith(local_drive_bad):
                    line_new = (local_drive_good +
                                line.split(local_drive_bad)[-1])
                else:
                    continue

                local_songs.add(song_name)
                pl_new.write(line_new)

        pl_old.seek(0)

        for line in pl_old:
            song_name = get_song(line)
            if (song_name not in local_songs
                    and line.startswith(external_drive)):
                pl_new.write(line)

    os.remove(playlist_temp)


def random_filename(base_name):
    while True:
        output = base_name + ''.join(choice(digits) for _ in range(5)) + '.temp'
        if not os.path.isfile(output):
            return output


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description=("Remove Duplicate entries "
                                                  "from a cmus playlist file."))
    parser.add_argument("playlist", help="cmus playlist file to process.")
    args = parser.parse_args()
    remove_cmus_duplicates(args.playlist)
