def test_encoder_caf(self): from oodi.library.track import Track filename = self.configuration.get_temporary_file_path('test.caf') track = Track(filename, configuration=self.configuration) output_file = track.encode(self.input_file, remove_input_file=False) self.assertEqual(output_file, track.path) self.assertTrue(os.path.isfile(output_file))
def test_encoder_flac(self): from oodi.codecs.utils import detect_file_codec from oodi.library.track import Track filename = self.configuration.get_temporary_file_path('test.flac') track = Track(filename, configuration=self.configuration) output_file = track.encode(self.input_file, remove_input_file=False) self.assertEqual(output_file, track.path) self.assertTrue(os.path.isfile(output_file)) self.assertEqual(detect_file_codec(filename), 'flac')
def test_codec_decoders_tempfile_output(self): """ Call all decoders without explicit path, decoding to temporary file """ from oodi.configuration import Configuration from oodi.library.track import Track configuration = Configuration() for name in TEST_FILES: testfile = os.path.join(TEST_FILES_PATH, name) track = Track(testfile, configuration=configuration) output_file = track.decode() self.assertTrue( os.path.isfile(output_file), 'Error decoding {}: missing output file {}'.format( testfile, output_file)) if track.supports_tags: self.assertIsInstance(track.tags.items(), dict)
def test_codec_decoders_explicit_output_file(self): """ Call all decoders by specifying a named output file path """ from oodi.configuration import Configuration from oodi.library.track import Track configuration = Configuration() output_file = configuration.get_temporary_file_path('test.wav') for name in TEST_FILES: if os.path.isfile(output_file): os.unlink(output_file) testfile = os.path.join(TEST_FILES_PATH, name) track = Track(testfile, configuration) track.decode(output_file) self.assertTrue( os.path.isfile(output_file), 'Error decoding {}: missing output file {}'.format( testfile, output_file))
def test_encoder_alac(self): from oodi.codecs.utils import detect_file_codec from oodi.library.exceptions import LibraryError from oodi.library.track import Track filename = self.configuration.get_temporary_file_path('test.m4a') # Raises LibraryError because .alac matches multiple codecs with self.assertRaises(LibraryError): track = Track(filename, self.configuration) output_file = track.encode(self.input_file, remove_input_file=False) # Specifying explicit format allows encoding track = Track(filename, configuration=self.configuration, format='alac') output_file = track.encode(self.input_file, remove_input_file=False) self.assertEqual(output_file, track.path) self.assertTrue(os.path.isfile(output_file)) self.assertEqual(detect_file_codec(filename), 'alac')
def main(): script = Script(description='Update music player library metadata') script.add_argument('-c', '--codec', help='Music library default codec') script.add_argument('-l', '--music-path', help='Music library path') script.add_argument('-p', '--position', type=int, help='Start from given position in library') script.add_argument('-m', '--metadata', action='store_true', help='Update metadata') args = script.parse_args() client = Client() script.log.info('Loading music player library playlist') if args.position: try: client.library.jump(args.position) except ValueError: script.exit( 1, 'Invalid position: {0} ({1:d} entries)'.format( (args.position, len(client.library)))) try: tree = MusicTree(tree_path=args.music_path) tree.load() tree_paths = tree.realpaths except Exception as e: script.exit(1, e) processed = 0 progress_interval = PROGRESS_INTERVAL progress_start = time.time() start = time.time() app_files = {} script.log.info('Checking library files against music player database') for entry in client.library: processed += 1 if processed % progress_interval == 0: progress_time = float(time.time() - progress_start) progress_rate = int(progress_interval / progress_time) script.log.info('Index {0:d} ({1:d} entries per second)'.format( processed, progress_rate)) progress_start = time.time() try: if entry.path is None: try: client.library.delete(entry) except MusicPlayerError as e: print(e) continue except TypeError as e: print('Error processing entry {0}: {1}'.format(entry, e)) continue try: path = normalized(os.path.realpath(entry.path)) except AttributeError: script.log.info('Removing invalid entry (no path defined)') try: client.library.delete(entry) except MusicPlayerError as e: print(e) continue if path not in tree_paths: if not os.path.isfile(path): script.log.info('Removing non-existing: "}0}"'.format(path)) try: client.library.delete(entry) except MusicPlayerError as e: print(e) else: script.log.info('File outside tree: {0}'.format(path)) elif path not in app_files: app_files[path] = entry if args.metadata: mtime = os.stat(path).st_mtime if int(entry.modification_date.strftime('%s')) >= mtime: continue song = Track(entry.path) if entry.syncTags(song): client.library.__next = entry.index else: script.log.info('Removing duplicate: {0}'.format(entry.path)) try: client.library.delete(entry) except MusicPlayerError as e: print(e) loadtime = float(time.time() - start) script.log.info('Checked {0:d} files in {1:4.2f} seconds'.format( processed, loadtime)) start = time.time() processed = 0 script.log.info('Checking music player database against tree files') if args.position is None: for path in sorted(tree_paths.keys()): if path not in app_files: script.log.info('Adding: {0}'.format(path)) try: client.library.add(path) except ValueError as e: print(e) processed += 1 if processed % 1000 == 0: script.log.debug('Processed: {0:d} entries'.format(processed)) loadtime = float(time.time() - start) script.log.info('Checked {0:d} files in {1:2.2f} seconds'.format( processed, loadtime))