From 581a68cf46be6a132e2d6908c5ba8b620882bee2 Mon Sep 17 00:00:00 2001 From: Lars Noack Date: Tue, 10 Jan 2023 18:52:47 +0100 Subject: [PATCH] started metadata --- src/goof.py | 4 +- src/music_kraken/database/objects/song.py | 54 ++++++++++++++++++---- src/try_python.py | 19 ++++++++ test.db | Bin 65536 -> 69632 bytes 4 files changed, 64 insertions(+), 13 deletions(-) create mode 100644 src/try_python.py diff --git a/src/goof.py b/src/goof.py index 03b52f6..2d025bd 100644 --- a/src/goof.py +++ b/src/goof.py @@ -44,9 +44,6 @@ song_input = Song( length=666, tracksort=2, target=Target(file="~/Music/genre/artist/album/song.mp3", path="~/Music/genre/artist/album"), - metadata={ - "album": "One Final Action" - }, lyrics=[ Lyrics(text="these are some depressive lyrics", language="en"), Lyrics(text="test", language="en") @@ -85,6 +82,7 @@ div() song_output_list = cache.pull_songs(song_ref=song_ref) print(len(song_output_list), song_output_list, song_output_list[0].album, sep=" | ") print("tracksort", song_output_list[0].tracksort, sep=": ") +print("id3", str(song_output_list[0].metadata)) # getting song by album ref div() diff --git a/src/music_kraken/database/objects/song.py b/src/music_kraken/database/objects/song.py index 8c4c981..c675061 100644 --- a/src/music_kraken/database/objects/song.py +++ b/src/music_kraken/database/objects/song.py @@ -1,7 +1,8 @@ import os -from typing import List, Tuple +from typing import List, Tuple, Dict from mutagen.easyid3 import EasyID3 +from .id3_mapping import Mapping as ID3_MAPPING from ...utils.shared import ( MUSIC_DIR, DATABASE_LOGGER as logger @@ -38,24 +39,32 @@ class SongAttribute: class Metadata: """ Shall only be read or edited via the Song object. - For this reason there is no reference to the song needed. + call it like a dict to read/write values """ def __init__(self, data: dict = {}) -> None: - self.data = data + # this is pretty self explanatory + # the key is a 4 letter key from the id3 standarts like TITL + self.id3_attributes: Dict[str, any] = {} def get_all_metadata(self): - return list(self.data.items()) + return list(self.id3_attributes.items()) def __setitem__(self, item, value): - if item in EasyID3.valid_keys.keys(): - self.data[item] = value + self.id3_attributes[item] = value def __getitem__(self, item): if item not in self.data: return None return self.data[item] + def __str__(self) -> str: + rows = [] + for key, value in self.id3_attributes.items(): + rows.append(f"{key} - {str(value)}") + return "\n".join(rows) + + class Source(DatabaseObject, SongAttribute): """ @@ -149,7 +158,6 @@ class Song(DatabaseObject): sources: List[Source] = None, target: Target = None, lyrics: List[Lyrics] = None, - metadata: dict = {}, album=None, main_artist_list: list = [], feature_artist_list: list = [] @@ -163,16 +171,18 @@ class Song(DatabaseObject): super().__init__(id_=id_) # attributes # self.id_: str | None = id_ + self._title = None + self.mb_id: str | None = mb_id - self.title: str | None = title self.album_name: str | None = album_name self.isrc: str | None = isrc self.length_: int | None = length self.artist_names = artist_names self.tracksort: int | None = tracksort - # self.metadata = Metadata(data=metadata) - self.metadata = None + self.metadata = Metadata() + + self.title = title if sources is None: sources = [] @@ -218,6 +228,29 @@ class Song(DatabaseObject): def __repr__(self) -> str: return self.__str__() + def set_simple_metadata(self, name: str, value): + """ + this method is for setting values of attributes, + that directly map to an ID3 value. + A good example is the title or the isrc. + + for more complex data I will use seperate functions + + the naming convention for the name I follow is, to name + the attribute the same as the defined property, but with one underscore infront: + title -> _title + """ + + attribute_map = { + "_title": ID3_MAPPING.TITLE + } + + # if this crashes/raises an error the function is + # called wrongly. I DO NOT CACH ERRORS DUE TO PERFORMANCE AND DEBUGGING + self.__setattr__(name, value) + self.metadata[attribute_map[name].value] = value + + def get_metadata(self): return self.metadata.get_all_metadata() @@ -242,6 +275,7 @@ class Song(DatabaseObject): return None return self.album.id + title: str = property(fget=lambda self: self._title, fset=lambda self, value: self.set_simple_metadata("_title", value)) album_id: str = property(fget=get_album_id) length: int = property(fget=get_length, fset=set_length) diff --git a/src/try_python.py b/src/try_python.py new file mode 100644 index 0000000..a28c681 --- /dev/null +++ b/src/try_python.py @@ -0,0 +1,19 @@ +class AttributeThing: + def __init__(self) -> None: + self.an_attribute = 666 + + def __setattr__(self, __name: str, __value: any) -> None: + print(__name, __value) + self.an_attribute = __value + + def __getattribute__(self, __name: str) -> any: + print(__name) + self.an_attribute += 333 + return self.an_attribute + + +if __name__ == "__main__": + attribute_class = AttributeThing() + + attribute_class.an_attribute = 333 + #print(attribute_class.an_attribute) diff --git a/test.db b/test.db index f534e7c6d8e3e2f06c1abbb13665d6fc0d249493..e482c537c25c085cafbdf99cbb5f6a3ba6697681 100644 GIT binary patch literal 69632 zcmeI*OK;r90SEAX=xtlH5V#AYmoaj%1ZymkOLCV<(?pKfhH5=(X}7U~w8C&WT+v!_ z6_V>lKp&9O80e)vZ% zDgP{79{*cm_D{-RFO_HG3lA?opV2NX&ired&Wug{VY)CGPJAV2KnDQ`KmY=-Byjkn z%afIN-YFh!$IR&n->u5e+{c@Z5VLzj*YrOd)s%@P;RZhx7e;7RYAfPGhsN{&8cAY{}*3eRpAI;qX&svhwb`#iQS*(O>R3y}jiy_M>=c z@bXAlrMF>ll8^nYRM@3FcgBwg7oi-fNK^P-3O;?sgHA@&FBTEcI9$h3Ing;6Y+O^^rzfO~vq&rL9$&fOVxRde6X^V!CNk465eWOX%TdS*sXnj{AzcrH|ZF_>n zy)ezmTN@jzjpg;@xybFto#obQlc8t5=JM?`JumWqSI3 zX@n#L>vQxA+kj!Y)!f)#S(o##HP)Ntr<*Hl%bO3Aa+jqc=$H4Tu+J>qxHM7u@M^K( z2d?-$`m7^=3~jSs+)e-A&epT7W&PR1=1dyDFUo2BRu4j-N7?sJ&+nW{W2MTA0I;GzAD<6Tj(ILv-egr3kwqyl@BUsZrACtK}+!`kAiYqqQ9)AIkna8 zgHgu=AqHT!b<6gE+C2B*zO6?W5%sdDuRl z@dK669~0^2N5mDLAIP0s=YTLGkKA&n8KntL%SkpOTl<-+S{BXWV^5awm)_{cUbG!$ z%G+AjA3wTLoUB~AQv99W&z+#19AiqSawceh|9lx75t8(ultOOB_Ld8OnGsq~3AJ_-?<19~bXzlgy50XTc8U z89C;r#W?$MalJHAdH>2;#Xf;cV1ss9{=l3{eq>&ff92VK6qK(NQ})n700Izz00bZa z0SG_<0uX=z1pXfcZkH!pA0`PARaLEN)he}hRilQ>1a&x5sjhOp?o@T#GVFLKIiHWn zqh1sf7Ifns5z4D3LHpCvWb3*Nq$Pyv)GWrS$Lbz6bX%o$!>du9)m2BeYPJk&nRtBH z587!BhpoD*%XytTRnC$HT*^#Vqh^)4wyNo@>S?>hB#xzGi#wXfW$<#AnxKYStJ8YT zs8Qy+oS8CcR@Z(eOLjB7+VB z5P$##AOHafKmY;|fB*y_0D;#dFkfyJ^IVZAr!(fb=uo;|ZcXR8evs7vmz24J@_YG( z4gwH>00bZa0SG_<0uX=z1R(IX2t1Z``&T!nrdxL1(p^WFmHG8rl^S(NqmJ-QYE(5- z*F2NijA3*?qJVxp`Kb z)c==c#lNioNA3UHQpS-^2tWV=5P$##AOHafKmY;|c+&-v`u{u^Cer%=OzFv{8sSo%%B-xfhAma-T4E~W4M zTT0$LaC2|J`V!0Jeg41S{{K_?8US<hM-T-*c3OJ$*0SG_<0uX=z z1Rwwb2tWV==T0E0|Ic%wBEA1V&lQLC{{K8z5z_YmlukkUTInd?oI5x~7y=N000bZa z0SG_<0uX=z1R(In2`rA6TNO_@8fThKU6WbzegV^^Ot(zRYRsy;I&<6_zq`|o;>D7j z+f^;q;IdUh*LGBDn2tjo)#Q{hIc#{QDl|3P@A$DbQEuI+x|XNwwncTrtW%?AtFkr2 zYK^L*YF2fxZtG5M<@z4+1HuUJdY&K5$QS>Wm7f=sC(2XVLk9r}KmY;|fB*y_009U< z00Izzz{?6G)%tnP_s5eN^PId-Bs1o@CQy=5ozD~9r2c1AP3Mv00Izz z00bZa0SG_<0uX=z1m0kQ)v>WwYdX*S{_>n>ua;$KQ+Yzmb9%p8O5&F1@&8<*6_dE- z2`x`blk@+Q;uVx<@(UdVAOHafKmY;|fB*y_009U<00OTda8KUL-?CL#bvc)<_*FTh zhHlF{|4mk-W|g_Ns_CriX?g1Q?-g?fmiPR>aQPLIhD9L&0SG_<0uX=z1Rwwb2tWV= J5P0JS{tbIcrzQXZ delta 1796 zcmb`Hy^B;=7{>41*+gpJ)c~ zXJaXMQB#MhVGIi*4YtWMOeGIFaLa?FU-om@-y7cPe>WQ5v5I;Vh{4XJj75?XJNOJM zpHq&(@odR{=R~tn)tyE$OH8%`YacDByMR4&37-_skifO}G^+N+`EwTvRHvK2psfPC z^`P6VyzAt*51x`WbRp+NGT}I|?6A;8VV_LENmIqV^2Bo5ez7sQULtr8a<5%mUTG3F zB558$h65xiDF!W$nW0=8&7`HW{cYn@Qlk11%&A6`3Qf?Tv);~+sGWSfxK-eL4x+@$ zbmtFLGJ)COw_l>G1*1AOw_I1~I;x>?|C}Cg*NY9*%~0ok(h3vH0^p7k8_OA1ff~sL zkCB>^Nv+)qJQf#AfKNAP zXuHJe9B_$+4`1Eqf1SQ)y;CwlZEd6xV8YtkY#eq}bCRQ0#Km@T^7)up%Z2g=>X?8M zR}y<22o@m|##y4tki&Fvn1&^IMu2|1*Ekhmls4lmV8KO-4x5lQSV$~6u1w_qa5o*K ze*0o_mX#j(#QmnU4R>tY71APOxTM|0+T#S6~5XX9UQ7ox4Fz!fT|~oGp7oG3yX~=fQm%M zh^8XTZ}|4U1Calp*(W