class IntQueryTest(unittest.TestCase, TestHelper): def setUp(self): self.lib = Library(':memory:') def test_exact_value_match(self): item = self.add_item(bpm=120) matched = self.lib.items('bpm:120').get() self.assertEqual(item.id, matched.id) def test_range_match(self): item = self.add_item(bpm=120) self.add_item(bpm=130) matched = self.lib.items('bpm:110..125') self.assertEqual(1, len(matched)) self.assertEqual(item.id, matched.get().id) def test_flex_range_match(self): Item._types = {'myint': types.Integer()} item = self.add_item(myint=2) matched = self.lib.items('myint:2').get() self.assertEqual(item.id, matched.id) def test_flex_dont_match_missing(self): Item._types = {'myint': types.Integer()} self.add_item() matched = self.lib.items('myint:2').get() self.assertIsNone(matched) def test_no_substring_match(self): self.add_item(bpm=120) matched = self.lib.items('bpm:12').get() self.assertIsNone(matched)
def create(self, lib: Library, name: str, qs: str, playlist_dir: str, relative_to: str): if playlist_dir is None: playlist_dir = self.config_playlist_dir() if relative_to is None: relative_to = self.config_relative_to() # Try to parse the query try: if qs is None: query, sort = None, None else: query, sort = parse_query_string(qs, Item) except ParsingError as ex: self._log.warning(u'invalid query: {}', ex) return # Map items to their paths items = lib.items(query, sort) item_path: Callable[[Item], str] = lambda item: path.relpath( item.path.decode('utf-8'), relative_to) paths = [item_path(item) for item in items] filename = path.join(playlist_dir, name + '.m3u') with open(filename, 'w+') as file: write_str = '\n'.join(paths) file.write(write_str)
def prompt_tags(db_file, query): library = Library(db_file) for track in library.items(query=query): try: scan_version = int(float(track.scan_version)) except Exception: scan_version = 0 if scan_version < VERSION: _prompt_for_track(track, TAGS_MODEL) track.scan_version = VERSION track.store()
class NoneQueryTest(unittest.TestCase, TestHelper): def setUp(self): self.lib = Library(':memory:') def test_match_singletons(self): singleton = self.add_item() album_item = self.add_album().items().get() matched = self.lib.items(NoneQuery('album_id')) self.assertInResult(singleton, matched) self.assertNotInResult(album_item, matched) def test_match_after_set_none(self): item = self.add_item(rg_track_gain=0) matched = self.lib.items(NoneQuery('rg_track_gain')) self.assertNotInResult(item, matched) item['rg_track_gain'] = None item.store() matched = self.lib.items(NoneQuery('rg_track_gain')) self.assertInResult(item, matched)
class NoneQueryTest(unittest.TestCase, TestHelper): def setUp(self): self.lib = Library(":memory:") def test_match_singletons(self): singleton = self.add_item() album_item = self.add_album().items().get() matched = self.lib.items(NoneQuery("album_id")) self.assertInResult(singleton, matched) self.assertNotInResult(album_item, matched) def test_match_after_set_none(self): item = self.add_item(rg_track_gain=0) matched = self.lib.items(NoneQuery("rg_track_gain")) self.assertNotInResult(item, matched) item["rg_track_gain"] = None item.store() matched = self.lib.items(NoneQuery("rg_track_gain")) self.assertInResult(item, matched)
class BoolQueryTest(unittest.TestCase, TestHelper): def setUp(self): self.lib = Library(':memory:') Item._types = {'flexbool': types.Boolean()} def tearDown(self): Item._types = {} def test_parse_true(self): item_true = self.add_item(comp=True) item_false = self.add_item(comp=False) matched = self.lib.items('comp:true') self.assertInResult(item_true, matched) self.assertNotInResult(item_false, matched) def test_flex_parse_true(self): item_true = self.add_item(flexbool=True) item_false = self.add_item(flexbool=False) matched = self.lib.items('flexbool:true') self.assertInResult(item_true, matched) self.assertNotInResult(item_false, matched) def test_flex_parse_false(self): item_true = self.add_item(flexbool=True) item_false = self.add_item(flexbool=False) matched = self.lib.items('flexbool:false') self.assertInResult(item_false, matched) self.assertNotInResult(item_true, matched) def test_flex_parse_1(self): item_true = self.add_item(flexbool=True) item_false = self.add_item(flexbool=False) matched = self.lib.items('flexbool:1') self.assertInResult(item_true, matched) self.assertNotInResult(item_false, matched) def test_flex_parse_0(self): item_true = self.add_item(flexbool=True) item_false = self.add_item(flexbool=False) matched = self.lib.items('flexbool:0') self.assertInResult(item_false, matched) self.assertNotInResult(item_true, matched) def test_flex_parse_any_string(self): # TODO this should be the other way around item_true = self.add_item(flexbool=True) item_false = self.add_item(flexbool=False) matched = self.lib.items('flexbool:something') self.assertInResult(item_false, matched) self.assertNotInResult(item_true, matched) def assertInResult(self, item, results): result_ids = map(lambda i: i.id, results) self.assertIn(item.id, result_ids) def assertNotInResult(self, item, results): result_ids = map(lambda i: i.id, results) self.assertNotIn(item.id, result_ids)
class IntQueryTest(unittest.TestCase, TestHelper): def setUp(self): self.lib = Library(':memory:') def tearDown(self): Item._types = {} def test_exact_value_match(self): item = self.add_item(bpm=120) matched = self.lib.items('bpm:120').get() self.assertEqual(item.id, matched.id) def test_range_match(self): item = self.add_item(bpm=120) self.add_item(bpm=130) matched = self.lib.items('bpm:110..125') self.assertEqual(1, len(matched)) self.assertEqual(item.id, matched.get().id) def test_flex_range_match(self): Item._types = {'myint': types.Integer()} item = self.add_item(myint=2) matched = self.lib.items('myint:2').get() self.assertEqual(item.id, matched.id) def test_flex_dont_match_missing(self): Item._types = {'myint': types.Integer()} self.add_item() matched = self.lib.items('myint:2').get() self.assertIsNone(matched) def test_no_substring_match(self): self.add_item(bpm=120) matched = self.lib.items('bpm:12').get() self.assertIsNone(matched)
def get_tracks(db_file, tag_list: List[str]) -> Dict[str, Track]: result = dict() library = Library(db_file) tag_list = [ tag for tag in tag_list if tag != "rating" and not tag.startswith("_") ] for item in library.items(): path = convert_attr_to_string(item.path).lower() tags = {tag: _get_attr_dont_throw(item, tag) for tag in tag_list} rating = _get_int_attr_dont_throw(item, "rating") if not (rating is not None and 0 <= rating <= 5): rating = None result[path] = Track(Path(path), tags, rating) return result
def ls(lib: Library, opts, args): items = lib.items(" ".join(args)) item: Item for item in items: path = item.destination().decode("utf-8") flac: bool = any(ext in path for ext in ["flac", "alac", "wav"]) bit_depth = item.bitdepth sample_rate = round(float(item["samplerate"]) / 1000, 1) if flac: print( f"{item} - {'FLAC' if flac else path[path.rfind('.')+1:].upper()} - {sample_rate}/{bit_depth}" ) else: print( f"{item} - {path[path.rfind('.')+1:].upper()} - {item.bitrate//1000}kbps" )
class BoolQueryTest(unittest.TestCase, TestHelper): def setUp(self): self.lib = Library(':memory:') Item._types = {'flexbool': types.Boolean()} def tearDown(self): Item._types = {} def test_parse_true(self): item_true = self.add_item(comp=True) item_false = self.add_item(comp=False) matched = self.lib.items('comp:true') self.assertInResult(item_true, matched) self.assertNotInResult(item_false, matched) def test_flex_parse_true(self): item_true = self.add_item(flexbool=True) item_false = self.add_item(flexbool=False) matched = self.lib.items('flexbool:true') self.assertInResult(item_true, matched) self.assertNotInResult(item_false, matched) def test_flex_parse_false(self): item_true = self.add_item(flexbool=True) item_false = self.add_item(flexbool=False) matched = self.lib.items('flexbool:false') self.assertInResult(item_false, matched) self.assertNotInResult(item_true, matched) def test_flex_parse_1(self): item_true = self.add_item(flexbool=True) item_false = self.add_item(flexbool=False) matched = self.lib.items('flexbool:1') self.assertInResult(item_true, matched) self.assertNotInResult(item_false, matched) def test_flex_parse_0(self): item_true = self.add_item(flexbool=True) item_false = self.add_item(flexbool=False) matched = self.lib.items('flexbool:0') self.assertInResult(item_false, matched) self.assertNotInResult(item_true, matched) def test_flex_parse_any_string(self): # TODO this should be the other way around item_true = self.add_item(flexbool=True) item_false = self.add_item(flexbool=False) matched = self.lib.items('flexbool:something') self.assertInResult(item_false, matched) self.assertNotInResult(item_true, matched)
class BoolQueryTest(unittest.TestCase, TestHelper): def setUp(self): self.lib = Library(":memory:") Item._types = {"flexbool": types.Boolean()} def tearDown(self): Item._types = {} def test_parse_true(self): item_true = self.add_item(comp=True) item_false = self.add_item(comp=False) matched = self.lib.items("comp:true") self.assertInResult(item_true, matched) self.assertNotInResult(item_false, matched) def test_flex_parse_true(self): item_true = self.add_item(flexbool=True) item_false = self.add_item(flexbool=False) matched = self.lib.items("flexbool:true") self.assertInResult(item_true, matched) self.assertNotInResult(item_false, matched) def test_flex_parse_false(self): item_true = self.add_item(flexbool=True) item_false = self.add_item(flexbool=False) matched = self.lib.items("flexbool:false") self.assertInResult(item_false, matched) self.assertNotInResult(item_true, matched) def test_flex_parse_1(self): item_true = self.add_item(flexbool=True) item_false = self.add_item(flexbool=False) matched = self.lib.items("flexbool:1") self.assertInResult(item_true, matched) self.assertNotInResult(item_false, matched) def test_flex_parse_0(self): item_true = self.add_item(flexbool=True) item_false = self.add_item(flexbool=False) matched = self.lib.items("flexbool:0") self.assertInResult(item_false, matched) self.assertNotInResult(item_true, matched) def test_flex_parse_any_string(self): # TODO this should be the other way around item_true = self.add_item(flexbool=True) item_false = self.add_item(flexbool=False) matched = self.lib.items("flexbool:something") self.assertInResult(item_false, matched) self.assertNotInResult(item_true, matched)
def write_tracks_rating_and_tags(db_file, tracks: Dict[str, Track]): library = Library(db_file) conflicting_tracks = [] traktor_modification_count = 0 for i in library.items(): path = convert_attr_to_string(i.path).lower() if path in tracks: if tracks.get(path).rating is not None: i.rating = tracks.get(path).rating conflicting_tags = [] for tag_key, traktor_tag_value in tracks.get(path).tags.items(): existing_tag_in_beets = _get_attr_dont_throw(i, tag_key) if existing_tag_in_beets is None or existing_tag_in_beets != traktor_tag_value: traktor_modification_count += 1 setattr(i, tag_key, traktor_tag_value) if existing_tag_in_beets is not None and existing_tag_in_beets != traktor_tag_value: conflicting_tags.append( (tag_key, existing_tag_in_beets, traktor_tag_value)) if conflicting_tags: conflicting_tracks.append((path, conflicting_tags)) i.store() if conflicting_tracks: for c in conflicting_tracks[:10]: print( "Conflict in '%s':\n Conflicting tags (tag_key, beet_tags, traktor_tags):\n\t%s" % (c[0], c[1])) print("==========================") print( "Conflicting tags were overwritten in beets: Traktor tags have priority over beets" ) print("Total conflicting tracks: %s" % len(conflicting_tracks)) print("New tags coming from Traktor: %s" % traktor_modification_count)