def _checkCoverArt(self, directory, audio_files): valid_cover = False # Check for cover file. images = [os.path.splitext(os.path.basename(i))[0] for i in self._dir_images] _printChecking("for cover art...") for dimg in self._dir_images: art_type = art.matchArtFile(dimg) if art_type == art.FRONT_COVER: dimg_name = os.path.basename(dimg) print("\t%s" % dimg_name) valid_cover = True if not valid_cover: # FIXME: move the logic out fixup and into art. # Look for a cover in the tags. images = [] for tag in [af.tag for af in audio_files if af.tag]: if valid_cover: # It could be set below... break for img in tag.images: if img.picture_type == img.FRONT_COVER: file_name = img.makeFileName("cover") print("\tFound front cover in tag, writing '%s'" % file_name) with open(os.path.join(directory, file_name), "wb") as img_file: img_file.write(img.image_data) img_file.close() valid_cover = True return valid_cover
def __init__(self, file_path): self.art_type = art.matchArtFile(file_path) self.file_path = file_path self.id3_art_type = (art.TO_ID3_ART_TYPES[self.art_type][0] if self.art_type else None) self._img_data = None self._mime_type = None
def _checkCoverArt(self, directory, audio_files): valid_cover = False # Check for cover file. _printChecking("for cover art...") for dimg in self._dir_images: art_type = art.matchArtFile(dimg) if art_type == art.FRONT_COVER: dimg_name = os.path.basename(dimg) print("\t%s" % dimg_name) valid_cover = True if not valid_cover: # FIXME: move the logic out fixup and into art. # Look for a cover in the tags. for tag in [af.tag for af in audio_files if af.tag]: if valid_cover: # It could be set below... break for img in tag.images: if img.picture_type == img.FRONT_COVER: file_name = img.makeFileName("cover") print("\tFound front cover in tag, writing '%s'" % file_name) with open(os.path.join(directory, file_name), "wb") as img_file: img_file.write(img.image_data) img_file.close() valid_cover = True return valid_cover
def handleDirectory(self, d, _): pout(Fg.blue("Syncing directory") + ": " + str(d)) audio_files = list(self._file_cache) self._file_cache = [] image_files = self._dir_images self._dir_images = [] if not audio_files: return d_datetime = datetime.fromtimestamp(getctime(d)) album_type = self._albumTypeHint(audio_files) or LP_TYPE album = None session = self._db_session for audio_file in audio_files: try: album = self._syncAudioFile(audio_file, album_type, d_datetime, session) except Exception as ex: # TODO: log and skip???? raise if album: # Directory images. for img_file in image_files: img_type = art.matchArtFile(img_file) if img_type is None: log.warn("Skipping unrecognized image file: %s" % img_file) continue new_img = Image.fromFile(img_file, img_type) if new_img: new_img.description = os.path.basename(img_file) syncImage( new_img, album if img_type in IMAGE_TYPES["album"] else album.artist, session) else: log.warn("Invalid image file: " + img_file) session.commit() if self.args.monitor: self._watchDir(d)
def handleDirectory(self, d, _): audio_files = list(self._file_cache) self._file_cache = [] image_files = self._dir_images self._dir_images = [] if not audio_files: return d_datetime = datetime.fromtimestamp(getctime(d)) # This directory of files can be: # 1) an album by a single artist (tag.artist, or tag.albun_srtist and # tag.album all equal) # 2) a comp (tag.album equal, tag.artist differ) # 3) not associated with a collection (tag.artist and tag.album differ) artists = set([f.tag.artist for f in audio_files if f.tag]) album_artists = set([f.tag.album_artist for f in audio_files if f.tag]) albums = set([f.tag.album for f in audio_files if f.tag]) for s in artists, album_artists, albums: if None in s: s.remove(None) is_various = (len(artists) > 1 and len(album_artists) == 0 and len(albums) == 1) def type_hint(): hints = set() for tag in [f.tag for f in audio_files if f.tag]: hint_frame = tag.user_text_frames.get(TXXX_ALBUM_TYPE) if hint_frame: hints.add(hint_frame.text) if len(hints) > 1: log.warn("Inconsistent type hints: %s" % str(hints)) return None else: return hints.pop() if hints else None album_type = type_hint() or LP_TYPE if is_various and album_type not in (None, VARIOUS_TYPE): # is_various overrides log.warn("Using type various despite files saying %s" % album_type) album_type = VARIOUS_TYPE if is_various else album_type album = None session = self._db_session for audio_file in audio_files: album = self._syncAudioFile(audio_file, album_type, d_datetime, session) if album: # Directory images. for img_file in image_files: img_type = art.matchArtFile(img_file) if img_type is None: log.warn("Skipping unrecognized image file: %s" % img_file) continue new_img = Image.fromFile(img_file, img_type) if new_img: new_img.description = os.path.basename(img_file) syncImage( new_img, album if img_type in IMAGE_TYPES["album"] else album.artist, session) else: log.warn("Invalid image file: " + img_file) if self.args.monitor: self._watchDir(d)
def handleDirectory(self, d, _): audio_files = list(self._file_cache) self._file_cache = [] image_files = self._dir_images self._dir_images = [] if not audio_files: return d_datetime = datetime.fromtimestamp(getctime(d)) # This directory of files can be: # 1) an album by a single artist (tag.artist, or tag.albun_srtist and # tag.album all equal) # 2) a comp (tag.album equal, tag.artist differ) # 3) not associated with a collection (tag.artist and tag.album differ) artists = set([f.tag.artist for f in audio_files if f.tag]) album_artists = set([f.tag.album_artist for f in audio_files if f.tag]) albums = set([f.tag.album for f in audio_files if f.tag]) for s in artists, album_artists, albums: if None in s: s.remove(None) is_various = (len(artists) > 1 and len(album_artists) == 0 and len(albums) == 1) def type_hint(): hints = set() for tag in [f.tag for f in audio_files if f.tag]: hint_frame = tag.user_text_frames.get(TXXX_ALBUM_TYPE) if hint_frame: hints.add(hint_frame.text) if len(hints) > 1: log.warn("Inconsistent type hints: %s" % str(hints)) return None else: return hints.pop() if hints else None album_type = type_hint() or LP_TYPE if is_various and album_type not in (None, VARIOUS_TYPE): # is_various overrides log.warn("Using type various despite files saying %s" % album_type) album_type = VARIOUS_TYPE if is_various else album_type # Used when a duplicate artist is resolved for the entire directory. resolved_artist = None resolved_album_artist = None album = None session = self._db_session for audio_file in audio_files: path = audio_file.path info = audio_file.info tag = audio_file.tag if not info or not tag: log.warn("File missing %s, skipping: %s" % ("audio" if not info else "tag/metadata", path)) continue elif None in (tag.title, tag.artist): log.warn("File missing required artist and/or title " "metadata, skipping: %s" % path) continue try: track = session.query(Track).filter_by(path=path).one() except NoResultFound: track = None else: if datetime.fromtimestamp(getctime(path)) == track.ctime: # Track is in DB and the file is not modified. # stash the album though, we'll look for artwork # updates later album = track.album continue # Either adding the track (track == None) # or modifying (track != None) artist, resolved_artist = self._getArtist(session, tag.artist, resolved_artist) if tag.album_type != SINGLE_TYPE: if tag.album_artist and tag.artist != tag.album_artist: album_artist, resolved_album_artist = \ self._getArtist(session, tag.album_artist, resolved_album_artist) else: album_artist = artist if artist is None: # see PromptExit continue album_artist_id = album_artist.id if not is_various \ else VARIOUS_ARTISTS_ID album_rows = session.query(Album)\ .filter_by(title=tag.album, artist_id=album_artist_id)\ .all() rel_date = tag.release_date rec_date = tag.recording_date or_date = tag.original_release_date if album_rows: if len(album_rows) > 1: # This artist has more than one album with the same # title. raise NotImplementedError("FIXME") album = album_rows[0] album.type = album_type album.release_date = rel_date album.original_release_date = or_date album.recording_date = rec_date print(fg.yellow("Updating album") + ": " + album.title) elif tag.album: album = Album(title=tag.album, artist_id=album_artist_id, type=album_type, release_date=rel_date, original_release_date=or_date, recording_date=rec_date, date_added=d_datetime) session.add(album) print(fg.green("Adding album") + ": " + album.title) session.flush() if not track: track = Track(audio_file=audio_file) self._num_added += 1 print(fg.green("Adding track") + ": " + path) else: track.update(audio_file) self._num_modified += 1 print(fg.yellow("Updating track") + ": " + path) genre = tag.genre genre_tag = None if genre: try: genre_tag = session.query(Tag).filter_by(name=genre.name)\ .one() except NoResultFound: genre_tag = Tag(name=genre.name) session.add(genre_tag) session.flush() track.artist_id = artist.id track.album_id = album.id if album else None if genre_tag: track.tags.append(genre_tag) session.add(track) if album: # Tag images for img in tag.images: for img_type in art.TO_ID3_ART_TYPES: if img.picture_type in \ art.TO_ID3_ART_TYPES[img_type]: break img_type = None if img_type is None: log.warn("Skipping unsupported image type: %s" % img.picture_type) continue new_img = Image.fromTagFrame(img, img_type) if new_img: syncImage(new_img, album if img_type in IMAGE_TYPES["album"] else album.artist, session) else: log.warn("Invalid image in tag") if album: # Directory images. for img_file in image_files: img_type = art.matchArtFile(img_file) if img_type is None: log.warn("Skipping unrecognized image file: %s" % img_file) continue new_img = Image.fromFile(img_file, img_type) if new_img: new_img.description = os.path.basename(img_file) syncImage(new_img, album if img_type in IMAGE_TYPES["album"] else album.artist, session) else: log.warn("Invalid image file: " + img_file)