def test_read_standardize_write_file(self):
        path = self.create_test_file(TEST_TAG_LIST)
        au_file = audio_file.scan(path)
        self.assertTrue(au_file is not None)
        au_file.volume = TEST_VOL
        au_file.import_timestamp = TEST_TS
        au_file.album_id = 77777
        # Inject the necessary UFID tag.
        au_file.mutagen_id3[constants.UFID_OWNER_IDENTIFIER] = ufid.ufid_tag(
            TEST_VOL, TEST_TS, au_file.fingerprint)

        import_file.standardize_file(au_file)
        # Do some basic checks
        for tag in au_file.mutagen_id3.values():
            self.assertTrue(
                (tag.FrameID in constants.ID3_TAG_WHITELIST
                 or tag.HashKey in constants.ID3_TAG_WHITELIST))
        for frame_id in constants.ID3_TAG_REQUIRED:
            self.assertTrue(frame_id in au_file.mutagen_id3)

        # Write the standardized file out, then re-read it and make sure
        # that everything is as we expected.
        alt_prefix = os.path.join(self.prefix, "alt")
        new_path = import_file.write_file(au_file, alt_prefix)
        new_au_file = audio_file.scan(new_path)
        self.assertEqual(sorted(au_file.mutagen_id3.keys()),
                         sorted(new_au_file.mutagen_id3.keys()))
        for key in au_file.mutagen_id3.keys():
            self.assertEqual(repr(au_file.mutagen_id3[key]),
                             repr(new_au_file.mutagen_id3[key]))
        self.assertEqual(au_file.fingerprint, new_au_file.fingerprint)
        self.assertEqual(au_file.payload, new_au_file.payload)
    def test_read_standardize_write_file(self):
        path = self.create_test_file(TEST_TAG_LIST)
        au_file = audio_file.scan(path)
        self.assertTrue(au_file is not None)
        au_file.volume = TEST_VOL
        au_file.import_timestamp = TEST_TS
        au_file.album_id = 77777
        # Inject the necessary UFID tag.
        au_file.mutagen_id3[constants.UFID_OWNER_IDENTIFIER] = ufid.ufid_tag(
            TEST_VOL, TEST_TS, au_file.fingerprint)

        import_file.standardize_file(au_file)
        # Do some basic checks
        for tag in au_file.mutagen_id3.values():
            self.assertTrue((tag.FrameID in constants.ID3_TAG_WHITELIST
                             or tag.HashKey in constants.ID3_TAG_WHITELIST))
        for frame_id in constants.ID3_TAG_REQUIRED:
            self.assertTrue(frame_id in au_file.mutagen_id3)

        # Write the standardized file out, then re-read it and make sure
        # that everything is as we expected.
        alt_prefix = os.path.join(self.prefix, "alt")
        new_path = import_file.write_file(au_file, alt_prefix)
        new_au_file = audio_file.scan(new_path)
        self.assertEqual(sorted(au_file.mutagen_id3.keys()),
                         sorted(new_au_file.mutagen_id3.keys()))
        for key in au_file.mutagen_id3.keys():
            self.assertEqual(repr(au_file.mutagen_id3[key]),
                             repr(new_au_file.mutagen_id3[key]))
        self.assertEqual(au_file.fingerprint, new_au_file.fingerprint)
        self.assertEqual(au_file.payload, new_au_file.payload)
Esempio n. 3
0
    def test_scan_has_chirp_tags(self):
        path = os.path.join(TESTDATA, "has_chirp_tags.mp3")
        fast_au_file = audio_file.scan_fast(path)
        slow_au_file = audio_file.scan(path)

        self.assertEqual(path, fast_au_file.path)
        self.assertEqual(path, slow_au_file.path)

        # This volume and timestamp is extracted from the UFID.
        self.assertEqual(123, fast_au_file.volume)
        self.assertEqual(1230519180, fast_au_file.import_timestamp)

        self.assertEqual(3918, fast_au_file.duration_ms)
        self.assertEqual(slow_au_file.duration_ms, fast_au_file.duration_ms)

        self.assertEqual(slow_au_file.fingerprint, fast_au_file.fingerprint)

        # Test file contains 150 frames for a total of 137,173 bytes.
        self.assertEqual(150, slow_au_file.frame_count)
        self.assertEqual(137173, slow_au_file.frame_size)
        self.assertEqual(path, slow_au_file.path)

        # The fast scan picks up an album ID stored in the tags,
        # the slow scan doesn't.  The test file is marked as having
        # an album ID of 123454321.
        self.assertEqual(123454321, fast_au_file.album_id)
        self.assertEqual(None, slow_au_file.album_id)
    def test_scan_has_chirp_tags(self):
        path = os.path.join(TESTDATA, "has_chirp_tags.mp3")
        fast_au_file = audio_file.scan_fast(path)
        slow_au_file = audio_file.scan(path)

        self.assertEqual(path, fast_au_file.path)
        self.assertEqual(path, slow_au_file.path)

        # This volume and timestamp is extracted from the UFID.
        self.assertEqual(123, fast_au_file.volume)
        self.assertEqual(1230519180, fast_au_file.import_timestamp)

        self.assertEqual(3918, fast_au_file.duration_ms)
        self.assertEqual(slow_au_file.duration_ms, fast_au_file.duration_ms)

        self.assertEqual(slow_au_file.fingerprint, fast_au_file.fingerprint)

        # Test file contains 150 frames for a total of 137,173 bytes.
        self.assertEqual(150, slow_au_file.frame_count)
        self.assertEqual(137173, slow_au_file.frame_size)
        self.assertEqual(path, slow_au_file.path)

        # The fast scan picks up an album ID stored in the tags,
        # the slow scan doesn't.  The test file is marked as having
        # an album ID of 123454321.
        self.assertEqual(123454321, fast_au_file.album_id)
        self.assertEqual(None, slow_au_file.album_id)
Esempio n. 5
0
    def test_scan_no_chirp_tags(self):
        path = os.path.join(TESTDATA, "no_chirp_tags.mp3")
        fast_au_file = audio_file.scan_fast(path)
        self.assertEqual(None, fast_au_file.volume)
        self.assertEqual(None, fast_au_file.import_timestamp)
        self.assertEqual(None, fast_au_file.fingerprint)
        self.assertEqual(None, fast_au_file.frame_count)
        self.assertEqual(None, fast_au_file.frame_size)
        # File doesn't have a TLEN tag.
        self.assertEqual(None, fast_au_file.duration_ms)
        self.assertEqual(path, fast_au_file.path)

        slow_au_file = audio_file.scan(path)
        # The file's fingerprint is stashed in the UFID:test tag.
        fp = slow_au_file.mutagen_id3.get("UFID:test").data
        self.assertEqual(None, slow_au_file.volume)
        self.assertEqual(None, slow_au_file.import_timestamp)
        self.assertEqual(fp, slow_au_file.fingerprint)
        # Test file contains 150 frames for a total of 137,173 bytes.
        self.assertEqual(150, slow_au_file.frame_count)
        self.assertEqual(137173, slow_au_file.frame_size)
        self.assertEqual(path, slow_au_file.path)
    def test_scan_no_chirp_tags(self):
        path = os.path.join(TESTDATA, "no_chirp_tags.mp3")
        fast_au_file = audio_file.scan_fast(path)
        self.assertEqual(None, fast_au_file.volume)
        self.assertEqual(None, fast_au_file.import_timestamp)
        self.assertEqual(None, fast_au_file.fingerprint)
        self.assertEqual(None, fast_au_file.frame_count)
        self.assertEqual(None, fast_au_file.frame_size)
        # File doesn't have a TLEN tag.
        self.assertEqual(None, fast_au_file.duration_ms)
        self.assertEqual(path, fast_au_file.path)

        slow_au_file = audio_file.scan(path)
        # The file's fingerprint is stashed in the UFID:test tag.
        fp = slow_au_file.mutagen_id3.get("UFID:test").data
        self.assertEqual(None, slow_au_file.volume)
        self.assertEqual(None, slow_au_file.import_timestamp)
        self.assertEqual(fp, slow_au_file.fingerprint)
        # Test file contains 150 frames for a total of 137,173 bytes.
        self.assertEqual(150, slow_au_file.frame_count)
        self.assertEqual(137173, slow_au_file.frame_size)
        self.assertEqual(path, slow_au_file.path)
Esempio n. 7
0
def from_directory(dirpath, fast=False):
    """Creates Album objects from the files in a directory.

    Found audio files are grouped into albums based on their TALB tags.
    Non-audio files are silently ignored.

    Args:
      dirpath: The path to the directory to scan for audio files.
      fast: If True, do a fast scan when analyzing the audio files.

    Returns:
      A list of Album objects.
    """
    by_talb = {}
    for basename in os.listdir(dirpath):
        file_path = os.path.join(dirpath, basename)
        # Skip anything that isn't a regular file.
        if not os.path.isfile(file_path):
            continue
        # Skip dotfiles
        if basename.startswith("."):
            continue
        # Must have mp3 as the extension.
        if not basename.lower().endswith(".mp3"):
            continue
        if fast:
            au_file = audio_file.scan_fast(file_path)
        else:
            au_file = audio_file.scan(file_path)
        # Silently skip anything that seems bogus.
        if not au_file:
            continue
        if not "TALB" in au_file.mutagen_id3:
            raise AlbumError("Missing TALB tag on %s" % file_path)
        talb = au_file.mutagen_id3["TALB"].text[0]
        by_talb.setdefault(talb, []).append(au_file)

    return [Album(all_au_files) for all_au_files in by_talb.values()]
Esempio n. 8
0
def from_directory(dirpath, fast=False):
    """Creates Album objects from the files in a directory.

    Found audio files are grouped into albums based on their TALB tags.
    Non-audio files are silently ignored.

    Args:
      dirpath: The path to the directory to scan for audio files.
      fast: If True, do a fast scan when analyzing the audio files.

    Returns:
      A list of Album objects.
    """
    by_talb = {}
    for basename in os.listdir(dirpath):
        file_path = os.path.join(dirpath, basename)
        # Skip anything that isn't a regular file.
        if not os.path.isfile(file_path):
            continue
        # Skip dotfiles
        if basename.startswith("."):
            continue
        # Must have mp3 as the extension.
        if not basename.lower().endswith(".mp3"):
            continue
        if fast:
            au_file = audio_file.scan_fast(file_path)
        else:
            au_file = audio_file.scan(file_path)
        # Silently skip anything that seems bogus.
        if not au_file:
            continue
        if not "TALB" in au_file.mutagen_id3:
            raise AlbumError("Missing TALB tag on %s" % file_path)
        talb = au_file.mutagen_id3["TALB"].text[0]
        by_talb.setdefault(talb, []).append(au_file)

    return [Album(all_au_files) for all_au_files in by_talb.values()]
Esempio n. 9
0
    """
    # Make sure the canonical directory exists.
    try:
        os.makedirs(au_file.canonical_directory(prefix))
    except OSError, ex:
        if ex.errno != errno.EEXIST:
            raise

    path = au_file.canonical_path(prefix)
    if os.path.exists(path):
        raise ImportFileError(["File exists: " + path])
    au_file.mutagen_id3.save(path)
    assert au_file.payload is not None
    out_fh = open(path, "a")
    out_fh.write(au_file.payload)
    out_fh.close()

    # Now make sure that the file we just wrote passes our checks.
    new_au_file = audio_file.scan(path)
    if new_au_file is None:
        raise ImportFileError(["New file damaged!"])
    new_au_file.volume = au_file.volume
    new_au_file.import_timestamp = au_file.import_timestamp
    post_write_tagging_errors = checker.find_tags_errors(new_au_file)
    if post_write_tagging_errors:
        os.unlink(path)
        raise ImportFileError(["Found post-write errors!"] +
                              post_write_tagging_errors)

    return path
Esempio n. 10
0
 def ensure_payloads(self):
     for au in self.all_au_files:
         if au.payload is None:
             new_au = audio_file.scan(au.path)
             assert new_au.fingerprint == au.fingerprint
             au.payload = new_au.payload
Esempio n. 11
0
 def ensure_payloads(self):
     for au in self.all_au_files:
         if au.payload is None:
             new_au = audio_file.scan(au.path)
             assert new_au.fingerprint == au.fingerprint
             au.payload = new_au.payload
Esempio n. 12
0
    def __iter__(self):
        """Iterator that yields a sequence of crawled MP3s.

        Yields:
          An AudioFile object.
        """
        self._reset()

        yielded_size = 0
        for root_path in self._all_roots:
            for self._current_dir, dirnames, filenames in os.walk(root_path):

                # We do not recursively descend into these directoryies.
                dirnames[:] = self._remove_ignored_directories(
                    self._current_dir, dirnames)

                # If a directory filter has been specified, use it to know
                # when to silently skip any files in a single directory.
                if (self._directory_filter
                        and not self._directory_filter(self._current_dir)):
                    continue

                # Now walk across each file in this dir, yielding a
                # stream of AudioFile objects.
                for name in filenames:
                    full_path = os.path.join(self._current_dir, name)

                    # Skip files with the wrong sorts of names.  These are
                    # not logged.
                    if name.startswith("."):
                        continue

                    if not name.lower().endswith(".mp3"):
                        self.skipped_files.append(
                            (full_path, "Invalid filename"))
                        continue

                    # Stat the file, and skip the files when that
                    # operation fails.
                    try:
                        stat_obj = os.stat(full_path)
                    except (IOError, OSError), ex:
                        self.skipped_files.append((full_path, str(ex)))
                        continue

                    try:
                        if self._fast:
                            au_file = audio_file.scan_fast(full_path)
                        else:
                            au_file = audio_file.scan(full_path)
                    except Exception, ex:
                        # TODO(trow): Here we should really only catch
                        # the exceptions we expect audio_file.scan and
                        # .scan_fast to raise.
                        self.skipped_files.append((full_path, str(ex)))
                        logging.error("Skipping file %s: %s", full_path,
                                      str(ex))
                        continue

                    if au_file is None:
                        self.skipped_files.append(
                            (full_path, "Not an MP3 (No tags?)"))
                        continue

                    # Remember this directory, then yield the AudioFile.
                    self.directories_seen.add(self._current_dir)
                    yield au_file
Esempio n. 13
0
    def __iter__(self):
        """Iterator that yields a sequence of crawled MP3s.

        Yields:
          An AudioFile object.
        """
        self._reset()

        yielded_size = 0
        for root_path in self._all_roots:
            for self._current_dir, dirnames, filenames in os.walk(root_path):

                # We do not recursively descend into these directoryies.
                dirnames[:] = self._remove_ignored_directories(
                    self._current_dir, dirnames)

                # If a directory filter has been specified, use it to know
                # when to silently skip any files in a single directory.
                if (self._directory_filter
                    and not self._directory_filter(self._current_dir)):
                    continue

                # Now walk across each file in this dir, yielding a
                # stream of AudioFile objects.
                for name in filenames:
                    full_path = os.path.join(self._current_dir, name)

                    # Skip files with the wrong sorts of names.  These are
                    # not logged.
                    if name.startswith("."):
                        continue

                    if not name.lower().endswith(".mp3"):
                        self.skipped_files.append(
                            (full_path, "Invalid filename"))
                        continue
                    
                    # Stat the file, and skip the files when that
                    # operation fails.
                    try:
                        stat_obj = os.stat(full_path)
                    except (IOError, OSError), ex:
                        self.skipped_files.append((full_path, str(ex)))
                        continue

                    try:
                        if self._fast:
                            au_file = audio_file.scan_fast(full_path)
                        else:
                            au_file = audio_file.scan(full_path)
                    except Exception, ex:
                        # TODO(trow): Here we should really only catch
                        # the exceptions we expect audio_file.scan and
                        # .scan_fast to raise.
                        self.skipped_files.append((full_path, str(ex)))
                        logging.error("Skipping file %s: %s",
                                      full_path, str(ex))
                        continue

                    if au_file is None:
                        self.skipped_files.append((full_path,
                                                   "Not an MP3 (No tags?)"))
                        continue

                    # Remember this directory, then yield the AudioFile.
                    self.directories_seen.add(self._current_dir)
                    yield au_file