def _run(self): logo = figlet_format("``MishMash``", font="graffiti") print(Fg.green(logo, Style.BRIGHT)) self._displayMetaInfo() all_libs = { l.name: l for l in self.db_session.query(Library).filter( Library.id > NULL_LIB_ID).all() } lib_args = set(self.args.libs or all_libs.keys()) for lib in lib_args: if lib not in all_libs.keys(): print(Fg.red(f"Unknown library: {lib}")) continue lib = all_libs[lib] if self.args.show_artists: print(Fg.green(f"\n=== {lib.name} library artists ===")) self._displayArtists(lib) else: print(Fg.green(f"\n=== {lib.name} library ===")) self._displayLibraryInfo(lib)
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=list(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
def selectArtist(heading, choices=None, multiselect=False, allow_create=True): color = Fg.green artist = None name = None menu_num = 0 if heading: print(heading) while artist is None: if choices: name = choices[0].name for menu_num, a in enumerate(choices, start=1): print(" %d) %s" % (menu_num + 1, a.origin())) 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 Exception: 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
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): pout(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)
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): pout(Fg.red("Removing track") + ": " + track.path) session.delete(track) num_orphaned_tracks += 1 log.warn("Deleting track: %s" % str(track)) 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) 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 or not any_album.tracks): log.warn("Deleting artist: %s" % str(artist)) session.delete(artist) num_orphaned_artists += 1 else: found_ids.add(artist.id) session.flush() return (num_orphaned_tracks, num_orphaned_artists, num_orphaned_albums)
def _write_log(self, environ, method, req_uri, start, status, bytes): if bytes is None: bytes = '-' if time.daylight: offset = time.altzone / 60 / 60 * -100 else: offset = time.timezone / 60 / 60 * -100 if offset >= 0: offset = "+%0.4d" % (offset) elif offset < 0: offset = "%0.4d" % (offset) remote_addr = '-' if environ.get('HTTP_X_FORWARDED_FOR'): remote_addr = environ['HTTP_X_FORWARDED_FOR'] elif environ.get('REMOTE_ADDR'): remote_addr = environ['REMOTE_ADDR'] stat = status.split(None, 1)[0] if (environ.get("webob._parsed_query_vars") and environ.get("webob._parsed_query_vars")[0].get("u")): user = environ.get("webob._parsed_query_vars")[0].get("u") user = environ.get('REMOTE_USER') or user or None else: user = None if user: remote_addr = "%s@%s" % (user, remote_addr) d = { 'REMOTE_ADDR': remote_addr, 'REQUEST_METHOD': method, 'REQUEST_URI': req_uri, 'HTTP_VERSION': environ.get('SERVER_PROTOCOL'), 'time': time.strftime('%d/%b/%Y:%H:%M:%S ', start) + offset, 'status': stat, 'bytes': bytes, 'HTTP_REFERER': environ.get('HTTP_REFERER', '-'), 'HTTP_USER_AGENT': environ.get('HTTP_USER_AGENT', '-'), } message = self.format % d stat = int(stat) if stat >= 200 and stat < 300: message = Fg.green(message) if stat >= 400 and stat < 500: message = Fg.yellow(message) if stat >= 500: message = Fg.red(message) self.logger.log(self.logging_level, message)
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()
def _run(self): session = self.db_session lib = session.query(Library).filter(Library.name == self.args.lib).one() artists = session.query(Artist).filter(Artist.lib_id == lib.id)\ .filter(Artist.name == self.args.artist)\ .all() if not artists: print("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): try: return _n > 1 and _n <= len(albums) except Exception: return False n = prompt("\nEnter the number of distinct artists", type_=int, validate=_validN) new_artists = [] for i in range(1, n + 1): print(Style.bright("\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, lib_id=artist.lib_id) 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_TYPE: 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()
def test_NicfitApp_default(capfd): with pytest.raises(SystemExit): app.run([]) out, _ = capfd.readouterr() assert out == Fg.red("\m/ {} \m/".format(Style.inverse("Welcome"))) + "\n"