Example #1
0
def selectArtist(heading, choices=None, multiselect=False, allow_create=True):
    color = fg.green
    artist = None
    name = None

    if heading:
        print(heading)

    while artist is None:
        if choices:
            name = choices[0].name
            for menu_num, a in enumerate(choices):
                print("   %d) %s" % (menu_num + 1, a.origin()))
            menu_num += 1

            if not multiselect:
                if allow_create:
                    menu_num += 1
                    print("   %d) Enter a new artist" % menu_num)

                choice = prompt("Which artist", type_=int,
                                choices=range(1, menu_num + 1))
                choice -= 1
                if choice < len(choices):
                    artist = choices[choice]
                # Otherwise fall through to select artist below
            else:
                def _validate(_resp):
                    try:
                        _ints = [_i for _i in parseIntList(_resp)
                                    if _i in range(1, menu_num + 1)]
                        return bool(_ints)
                    except:
                        return False

                resp = prompt(color("Choose one or more artists"),
                              validate=_validate)
                artists = []
                for choice in [i - 1 for i in parseIntList(resp)]:
                    artists.append(choices[choice])
                # XXX: blech, returning a list here and a single value below
                return artists

        if artist is None:
            artist = promptArtist(None, name=name)
            if choices:
                if not Artist.checkUnique(choices + [artist]):
                    print(fg.red("Artist entered is not unique, try again..."))
                    artist = None

    assert(artist)
    return artist
Example #2
0
def deleteOrphans(session):
    num_orphaned_artists = 0
    num_orphaned_albums = 0
    num_orphaned_tracks = 0
    found_ids = set()

    # Tracks
    for track in session.query(Track).all():
        if not os.path.exists(track.path):
            print(fg.red("Removing track") + ": " + track.path)
            session.delete(track)
            num_orphaned_tracks += 1
            log.warn("Deleting track: %s" % str(track))

    session.flush()

    # Artists
    found_ids.clear()
    for artist in session.query(Artist).all():
        if (artist.id == VARIOUS_ARTISTS_ID or
                artist.id in found_ids):
            continue

        any_track = session.query(Track).filter(Track.artist_id == artist.id) \
                                        .first()
        any_album = session.query(Album).filter(Album.artist_id == artist.id) \
                                        .first()
        if not any_track and not any_album:
            log.warn("Deleting artist: %s" % str(artist))
            session.delete(artist)
            num_orphaned_artists += 1
        else:
            found_ids.add(artist.id)

    session.flush()

    # Albums
    found_ids.clear()
    for album in session.query(Album).all():
        if album.id in found_ids:
            continue

        any_track = session.query(Track).filter(Track.album_id == album.id) \
                                        .first()
        if not any_track:
            log.warn("Deleting album: %s" % str(album))
            session.delete(album)
            num_orphaned_albums += 1
        else:
            found_ids.add(album.id)

    return (num_orphaned_tracks, num_orphaned_artists, num_orphaned_albums)
Example #3
0
def _pErr(subject, msg):
    print(fg.red(subject) + ": %s" % str(msg))
Example #4
0
    def _run(self):
        session = self.db_session

        artists = session.query(Artist)\
                         .filter(Artist.name == self.args.artist).all()
        if not artists:
            print(u"Artist not found: %s" % self.args.artist)
            return 1
        elif len(artists) > 1:
            artist = selectArtist(fg.blue("Select which '%s' to split...") %
                                  artists[0].name,
                                  choices=artists, allow_create=False)
        else:
            artist = artists[0]

        # Albums by artist
        albums = list(artist.albums) + artist.getAlbumsByType(VARIOUS_TYPE)
        # Singles by artist and compilations the artist appears on
        singles = artist.getTrackSingles()

        if len(albums) < 2 and len(singles) < 2:
            print("%d albums and %d singles found for '%s', nothing to do." %
                    (len(albums), len(singles), artist.name))
            return 0

        self._displayArtistMusic(artist, albums, singles)

        def _validN(_n):
            return _n > 1 and _n <= len(albums)
        n = prompt("\nEnter the number of distinct artists", type_=int,
                   validate=_validN)
        new_artists = []
        for i in range(1, n + 1):
            print(Style.bright(u"\n%s #%d") % (fg.blue(artist.name), i))

            # Reuse original artist for first
            a = artist if i == 1 else Artist(name=artist.name,
                                             date_added=artist.date_added)
            a.origin_city = prompt("   City", required=False)
            a.origin_state = prompt("   State", required=False)
            a.origin_country = prompt("   Country", required=False,
                                      type_=normalizeCountry)

            new_artists.append(a)

        if not Artist.checkUnique(new_artists):
            print(fg.red("Artists must be unique."))
            return 1

        for a in new_artists:
            session.add(a)

        # New Artist objects need IDs
        session.flush()

        print(Style.bright("\nAssign albums to the correct artist."))
        for i, a in enumerate(new_artists):
            print("Enter %s%d%s for %s from %s%s%s" %
                  (Style.BRIGHT, i + 1, Style.RESET_BRIGHT,
                  a.name,
                  Style.BRIGHT, a.origin(country_code="iso3c",
                                         title_case=False),
                  Style.RESET_BRIGHT))

        # prompt for correct artists
        def _promptForArtist(_text):
            a = prompt(_text, type_=int,
                       choices=range(1, len(new_artists) + 1))
            return new_artists[a - 1]

        print("")
        for alb in albums:
            # Get some of the path to help the decision
            path = commonDirectoryPrefix(*[t.path for t in alb.tracks])
            path = os.path.join(*path.split(os.sep)[-2:])

            a = _promptForArtist("%s (%s)" % (alb.title, path))
            if alb.type != "various":
                alb.artist_id = a.id
            for track in alb.tracks:
                if track.artist_id == artist.id:
                    track.artist_id = a.id

        print("")
        for track in singles:
            a = _promptForArtist(track.title)
            track.artist_id = a.id

        session.flush()