From 50ef028a97e33c2a0e3f1169cfa4a1ea26906c6a Mon Sep 17 00:00:00 2001 From: Matthias Kiefer Date: Mon, 27 Oct 2014 10:23:31 +0100 Subject: [PATCH 01/12] added some more storage styles for comment fields --- beets/mediafile.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/beets/mediafile.py b/beets/mediafile.py index 95bbd309d..d17bc4fd2 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -1481,10 +1481,14 @@ class MediaFile(object): ) comments = MediaField( MP3DescStorageStyle(key='COMM'), + MP3DescStorageStyle(key='COMM', desc=u'ID3v1 Comment'), + MP3DescStorageStyle(key='COMM', desc=u'Comment'), + MP3DescStorageStyle(key='COMM', desc=u'Track:Comments'), MP4StorageStyle("\xa9cmt"), StorageStyle('DESCRIPTION'), StorageStyle('COMMENT'), ASFStorageStyle('WM/Comments'), + StorageStyle('Description') ) bpm = MediaField( MP3StorageStyle('TBPM'), From 2658edbd5f0c3eeb0eef8156a79802442f20775b Mon Sep 17 00:00:00 2001 From: Matthias Kiefer Date: Mon, 27 Oct 2014 10:27:56 +0100 Subject: [PATCH 02/12] Also allow slashes as separator in date fields --- beets/mediafile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/beets/mediafile.py b/beets/mediafile.py index d17bc4fd2..0b11f1c0d 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -1088,11 +1088,11 @@ class DateField(MediaField): year, month, and day number. Each number is either an integer or None. """ - # Get the underlying data and split on hyphens. + # Get the underlying data and split on hyphens and slashes. datestring = super(DateField, self).__get__(mediafile, None) if isinstance(datestring, basestring): datestring = re.sub(r'[Tt ].*$', '', unicode(datestring)) - items = unicode(datestring).split('-') + items = re.split('-|/', unicode(datestring)) else: items = [] From f8abb03b401135cefb416af5b2742f4248a5fb76 Mon Sep 17 00:00:00 2001 From: Matthias Kiefer Date: Mon, 27 Oct 2014 16:10:17 +0100 Subject: [PATCH 03/12] Added support for APEv2 cover tags --- beets/mediafile.py | 67 ++++++++++++++++++++++++++++++++++++++++- test/rsrc/image.ape | Bin 0 -> 14279 bytes test/test_mediafile.py | 3 +- 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 test/rsrc/image.ape diff --git a/beets/mediafile.py b/beets/mediafile.py index 95bbd309d..11c0459fd 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -868,7 +868,7 @@ class VorbisImageStorageStyle(ListStorageStyle): base64-encoded. Values are `Image` objects. """ formats = ['OggOpus', 'OggTheora', 'OggSpeex', 'OggVorbis', - 'OggFlac', 'APEv2File', 'WavPack', 'Musepack', 'MonkeysAudio'] + 'OggFlac'] def __init__(self): super(VorbisImageStorageStyle, self).__init__( @@ -950,6 +950,70 @@ class FlacImageStorageStyle(ListStorageStyle): mutagen_file.clear_pictures() +class APEv2ImageStorageStyle(ListStorageStyle): + """Store images in APEv2 tags. Values are `Image` objects. + """ + formats = ['APEv2File', 'WavPack', 'Musepack', 'MonkeysAudio', 'OptimFROG'] + + _APE_COVER_TAG_NAMES = {ImageType.other: 'Cover Art (other)', + ImageType.icon: 'Cover Art (icon)', + ImageType.other_icon: 'Cover Art (other icon)', + ImageType.front: 'Cover Art (front)', + ImageType.back: 'Cover Art (back)', + ImageType.leaflet: 'Cover Art (leaflet)', + ImageType.media: 'Cover Art (media)', + ImageType.lead_artist: 'Cover Art (lead)', + ImageType.artist: 'Cover Art (artist)', + ImageType.conductor: 'Cover Art (conductor)', + ImageType.group: 'Cover Art (band)', + ImageType.composer: 'Cover Art (composer)', + ImageType.lyricist: 'Cover Art (lyricist)', + ImageType.recording_location: 'Cover Art (studio)', + ImageType.recording_session: 'Cover Art (recording)', + ImageType.performance: 'Cover Art (performance)', + ImageType.screen_capture: 'Cover Art (movie scene)', + ImageType.fish: 'Cover Art (colored fish)', + ImageType.illustration: 'Cover Art (illustration)', + ImageType.artist_logo: 'Cover Art (band logo)', + ImageType.publisher_logo: 'Cover Art (publisher logo)' + } + + def __init__(self): + super(APEv2ImageStorageStyle, self).__init__(key='') + + def fetch(self, mutagen_file): + images = [] + for cover_type, cover_tag in APEv2ImageStorageStyle._APE_COVER_TAG_NAMES.iteritems(): + try: + frame = mutagen_file[cover_tag] + text_delimiter_index = frame.value.find('\x00') + comment = frame.value[0:text_delimiter_index] if text_delimiter_index > 0 else None + image_data = frame.value[text_delimiter_index+1:] + images.append(Image(data=image_data, type=cover_type, desc=comment)) + except KeyError: + pass + + return images + + def set_list(self, mutagen_file, values): + self.delete(mutagen_file) + + for image in values: + image_type = image.type if image.type is not None else ImageType.other + comment = image.desc if image.desc else '' + image_data = comment + "\x00" + image.data + cover_tag = APEv2ImageStorageStyle._APE_COVER_TAG_NAMES[image_type] + mutagen_file[cover_tag] = image_data + + def delete(self, mutagen_file): + """Remove all images from the file. + """ + for cover_tag in APEv2ImageStorageStyle._APE_COVER_TAG_NAMES.itervalues(): + try: + del mutagen_file[cover_tag] + except KeyError: + pass + # MediaField is a descriptor that represents a single logical field. It # aggregates several StorageStyles describing how to access the data for # each file type. @@ -1206,6 +1270,7 @@ class ImageListField(MediaField): ASFImageStorageStyle(), VorbisImageStorageStyle(), FlacImageStorageStyle(), + APEv2ImageStorageStyle(), ) def __get__(self, mediafile, _): diff --git a/test/rsrc/image.ape b/test/rsrc/image.ape new file mode 100644 index 0000000000000000000000000000000000000000..f8a559289eac60d0dcc3a81cb1bac42640b8ac44 GIT binary patch literal 14279 zcmbumbBr%v5a{_G+r}N+wr$(CZQHgzcWmp9Z5wxNd-nd`d;2!oWRuNqb*fIKPMwqb z^hy8G-6>f?VS+RS0DuJm0AT)8(0}@$Y%%}O@jtuHKn~4thH5|TGyU!OczPXy@?R7g zAW{tg0R8h2|Jnb1g?~N;c{|pBv*7>ql$xzWB%mua+uW<~@W&4G6u7})?5qx7cuAO6 zcV9zwqi1s_;wx>cBVbbL(J-2{Anj}6jsgCmlH5lAY)zZ&hT`T%;)ybc$dZ)JP*zHw zQEXTsRD@$4+tJ41tt3ViPB*!ObuxMW7{2-H-# zEqf`QtL(z~Dar6x0ddW$hfkz({=2ymH&2@nm#>ev1iy7P_B|@mz@m4;(dDuGF6{pH z*)~`q4v|~NyGxvbyettN;Ae;$gl_VM$dMP(EE$~}=C2qy8HXuV63<8Tl>|%FnB~b1 zt$SB9yVDm}$z}#{j#MCl&I4iV7Ku7Jhc-*{WmU+eAd=gqtcKWx>d!O!Jsth0+?zs+hL1g7@pS%q?WExr{93xL0%i z^9aR~E#6sWIK4cIIuOYV5EmH??sCP96c~oFz+5!yjHrlY{`c2 z02!e09wA)RpV-Ge1XL;yrKW>da0&MhT&7!ptIEcBvd% z^8|UmmuoqzaYDmEJEvp~r?mGNm$ye9T-Jg2`qZ8{k#nAcS`>U4xEs=Td^rmn)ZRQ^ z-?K|0-LA9kHX^Xp#zvb%#vyzsjrWg;ZBfOFWD7e7WLqXQ0+<9<@*Log%%~_!PtN2XGKQurUh)Ly{?Kq5PmZ zhglWBe@W+}wJ$D0j4hH;Hnb*kT5TDYRvCcyo=3wAa+FN1ropCEqV@$Z6JaIqg>f4x zF}K4dLx@!7s>8S)k5V4aHYsCg&tMhD#cxbZH438p&d!|&g{!PY_ln>cLug2Vp}K#n zi}H=_C6cFd%>|~8qsi-GZTQqY)G}^{^_Zm_Lp|5AGK53NCpteg5Zxf7XM6`cB+Y^DtQ%*8V2u;K- z=78+BQXlb4eM~9YrRft`Z;dDfT1YlRzS|K9^2C>NV-_`poBG(Hv((RI-j~N+(NxZ% z_p^2zUm3WAVkoT34`S1O93@2U6l}?;!J)04MuVQm(+2HmZE__qTJ3Rcvrn!|QNL3t z+Dzj&eq;yXc)i;gl%C43KB!%}L~Cru9?nu6VB(w|%O!1r?Pulj#H3Rsvi@1OtkyF9 z6}me6Z*bL|+~b$^WtSHZ8QhJY^VdiT`huWY+t3BG)4sv+XgW_UxDk$}7hq}NPesvI z2QJi9c5b`K?9YvI;?l_!{&TKvn+1zoc@+-y6Y0tDD`VpbP0`I; zB!3mX_MKVah~Tis0WFBEH;nN&orQ^N)WFtKPy8kr|B9N3-;azvtr{f8$ z89ywH7|)U^^7(4|3s&?9;q5Z}T;}Jx28vyyw1`r)OM81?TZ?4A7h$9md^oMA?^-%b z{SQV->B3;nm1!10llX3(Ch{tFC&d4f&a{7lCrbNt8f`6%CKgPRI0h5#aiNX1S!e^c z2#jqC<1Y?n>H3?jLM9`VZXT@A(II)FB~cPBBuxiCrUtko^FU_6nm&%e>)*-|O;&`N z7!i|PTQ~)1Ak_;~Dz6(T-mg%ad*g6a+CFn6;fEeJL$t&qMpxsvxF_9Gt`E<{33^BDNXldLYByM|n55BC2YUbV<<#A@Ul@qG~;N z@5A7A!+nr^j{9D9nToy?b;Rwm_Hw_!gJ>|)Xixl%KJbmxIN860H(}NFzc#S`5Rf}V z=E-TwLs{wKo0*QeHczlUYzHGS<5ZW*9VAjSn&Y(N85~&+ajV&}eKk6m>C1x%p_o|j z{xCGTE9bHoJ_7BAG63cO^8k5urJzc|N) zO|q`eOk8G8rcW1y)+G(Aw*VG^v*%GOiK4gJsuKysoSt$z;*LoYs$J}U2pBWvd{|G& z9hD1Dyucj;R!BFw>a2RE6_>FxZoLwbJ34VrsEN>@zScp~8Pofbe})gvrR&kXZ-%`y zp#rzc@Yu@LANJ-)yN3qro91HigSrr&H(Mbga7|YWP+?7-VoCQANF@Fx#&iPk(Bi^J z*+_0hqg+4Il2L7p(!BG?=d9^LnjHlLrfSu5XJU4sShep z+6hD)%h{u==r}D)rr06MDV70o5qRDgIg8{`m9FdB0k?QQa4` zM|Y0ok4%nVz-{3(Z1-l?LpPbbqaN(@?p=dd9hjGAm)ZBVI3S9Tu2PhOOo1$TM_5g; zZuZwM%C0{j9Z9|H>^gm~?XF$u#mTI0AVuC6lU>=T!?{5b;dHJ2lOa9a?u(!HZr5o3JtaUXS_BnJf3w<$ zn<`jvco~~jmJOc2eJ17wix_>mm^|Gs6e*xRSwOnEx=%RaXZMH0zN}V)n7x7b_pLZ| z{&Sz>G}hb$dQ_u zV3*V=rTf0sY^*rty~M4?_F1!EP-irwIahD?Fx9g`n^wG2q6k z%O4nUN6&SC_D`^yxOSoT{iqhW1OplKs>&E;(o&HXR#P#@Q4j(W+voJl4&1T8OJuD* z7ZUl-t)t6PsV=m!l9kThdb-DgrSJ59)bHrN;ypd|@PJR1OAR_kHSSm%vyKQzpy2h4G=>F+V)j#p%ipbot{Bg*3d$cu#%9J%KE#LPpu<3)lQAmzKpNBK3EMBrn*EqZk%(lkJ zR}^L}qO0qi7!?^(mI=fsYa}ZHjp20Ntv%Q2sAe7Vn^}hGeWPNA&&T$YVrm^oY#ffp z*s1qiuG$K9`cMMFm_$O^_>uH0$Bvhg~ir%WmIp;YhGcx(5TI6@a~7w5=p=BA!UKr^0Xpzn7C!0Ff3z_k->#1UV>Viep4+{!Ok-x_Uu z;Z?18esbS@dLbiLyFJ85)ir9fq(D1iA!{ZaE;683rNJBEVq8adIr^~IPh%cVPE~&& z8{k6r;?(ed75=1i=Mc`1d`hgBR`y5^2_|&v>zHJo?`URaxkN}#_Ld)d!7mVEm66hP z6M3gmz@-I`Sl$i~*Dc;iR&_ncnl={M+PylK#*Bx8x;ITCXb?I+ecIOe5n<%e4YE!# za1?T&KqOrVl4V=Jcy>9UPi>pGe;*YR%45U6kFYM#6N|Yu&i8g92<}1{N|Llbze&oH zoT=%K;3CD%xIA@cz;qx*=mf;-JyX>Pm21$O2BH~wk66Hg&&WLBpO>=EsIgdFiDC%c ziw;=C#4*w;Wf?f))H{Z*TA5s3-uMWb0R0jFf`t1xU1OsMv<^ooaO4a zKPD#Ipd`;cif!*yBck^(jF>_w8^uxgC0#}G%*(V(B|hmz6I#UH-xMlaeh6X}#G7Fn z1__a%^MjwQYT*mIv=hUn!SZGSV?#lF_RWaDr$e5od@OxDsrDu&QX}JtooW=6%dr1+ z(e5950Hb%c^kv8eV;Iy8BtV9+kr+QO5)Awi+IYg`O8=HaO|rEXUgM2B6r=a$I9NH< z+Yq@Gbna-bCHBzIgh&;xl2*~pSQ%-=S?cYveKlO&_x-dFgM?8-f5&Y;I0_1Y!=Top zYLff)(k7l;PnQWJIgx#iu&)fI6E?&@Q=;_cODpAdSh!*|UE_Y@ree3 z#fTfN=%o0cso$Bsa~#Ae8(eDWTs!7c_JAbepj`&PRo|3jmpm4dQmoDg_@#Ti`T@&i z0V57mhmDqjma7p_>I|b7&$L}5`V#H4`5^pa;#X=%o#Mt z#ev9hxhl#q?;L-ONTbGb{%jgryKgv;9&6|sepFSJP^A5ddKNdElu`w6(%;+BZbPoy zWkPlsx59l^k}oX6GEx}j@pzX_8rJ+~!gYVG9G-UjEYMaRQ>rclfmj)oBvh%w7uHaw zXl-g9Sv>mrL_maJu?%P z*fzR5VW&n~3yms8=FK>rOP7uRrSn91uUF%0*h1hwfTGGJU^unzNmuJ8>;)vp2_c<) zo#VnSMO8OMT=q3by`Pl!+&7Daw%%YFL0Y&B;k4mUkG2q+;En**6}gbBqR1J7l!PX} z4vvjrG${epkh++q!ZM5Q9C04+ZzxtC<9TpAY)OsX!#Ec5pv={5yy!Eu`e(zE&%E)^ z!&5;3PvSQM*KVrp*fQYOiIoK!i`1#XA z<6*R}iO^bw$S-4^Jn3OjVyeZH?kFcxC31dQ^_tKlmWl4j%#ZxAtm1N*Yc_wf44b4X&&jN64UPQ>&}@V`-qnDkY=Ysv zIIFtLp9xj2#YW%mTi(Ty2=#qZY<1D^;N&Rx&%c@6UBoeaYgS;iw{8mFmqM*8lb4;J zXdqGXnhG&<+Z`dsFhXBDl_Os{Wds640k${+F$aqcNEDM|bL<~aLQp&#VKr{3w&;$zm#MWeR7gorRke8Dd zI(4b#dk4x>Ru;(Ycb`qHL-hI%j_bhge*JN32U|y~Zq@p$bz=ovGpYAQVjdTCOWSbM z#X-<;$xZBs!3lg$C!xwzrvoGwZ=ffRxyLbuV_HV-n3i3)KvbY;@5ghGVUB5?F`I>b znCfZ#u=a!NE79CdiEo(U)KPBo+&CZCLqr_qZkL{}Vs!>2@snp&r0_u%=ija2nVtFJ z&>wMx4iPP@oTe+XgVH#`J>H|n9#>n0N=Lp*D=D#xB*Jwb*Qe&H+Ds@U?KWcw1+g<= z_ak26!#TC+qcr%NthsVnLQWo}QGOtt`Brvm{kfS@S?WCI$v=5@ffpI;rLD_uZr=~y zoqM2Y2pM9#!p&Y=`B1kUJi%iG$MM{i78cJtk|ajcajX|&UE#X$%3_Zmf1fH9#}S)) zh};-=oh$Rq@_%_qat?Z1*sr-0`2nZarLfHsy)hQr9AxlK_iGh&c~9s?RX&&zVx~je zgKAb#gPXbID>tKFkwVp4@>ktK9?zm~1s*g2Kvf zJ0LlrO{#pg=)Uk{+vFn0KR89;FDkU25B)!{%z$53pW z!fUiexyd!tDS!wzrH*_8@0qT}fkSxXpSb*OLTQqdJpK?DTiOy5A6l!P38-zJm&9@+ z(G=pqcl#A6uvWmp79V9s+D`Wc(v~nm&8R<73$X*dF`Mrj(+Aa z>mTDj1s8O=-Yg1su;j?L`8)V-vUxT8D?vY)mcBdE`UDQ(DEEFS9d{=q;)?Kcv!8@c zV5~19OE`6K;_j^0Rsq%lOM9!j_;LujmM>VB5Y^o6SZgkzYVCe?>ENd<%Gu+x-Du(p zm`03u`SGP1AiL2tjYs$TbG@m&ekb~{eZcE8SdKpcJ%azI3>b}HNfKOPd-{y+wG zEB1cLCy8A1 zEv46<>)oIR&!(>bisS(@bR7B^5%e|&O$5DpEnL7MxX)8v2H#n}Ygy|gT0iHY+E4rk zX5RP${XMI7z$GnVvi8s`6501%47At^Iswj#_r;xK!y4F=y9G{MDfID~=M!_IZu;@j zS;Xe1f)1;k$lK+59*+Glj67q(G3B!ZHCsOI?*m_JQ7(iyqR-B0l@SE;D z#Ve~Q*EJ7-`6&9kos(7CsVu6ZXUow^{%o$rs~T1_q&gUO7+4zF&d;XkI^{#!SQXFj zFPTN#pW)yZDFo5yt09pCpI4J(VXKZj++D$P>Z1to)yO6H2pY_7C@15QFWIe{D%s@O z)sk3icrj`7jKxvt&%#kHV-KLSg3Ad?8%51HDkawrco+F3rlM{{y`K9Pb%C#=ogn|7 z;GsE#?=Am7D!Fx8TXk_LXZowE(}r zL1jX=)+~1d`)5IDq^SI~W+aU8eT~y%Mt3I=S%;~Oy9zg^!pg8tTwhWc6rYa$X3;I2 z2PYYTqli`{8EDJ>HT2~HIb{mmuxm>2E>d^!G|vwR&s${*;3X0YqMFze+L~esrh({2 zOf$Z$$#u1xJraCK46s%<1V@eGQ`E3CAJgU}H=~WDeBnY|4$TB{$n_!JL=gF+?zz=n zApDY{{GOurAsBCkkYN;|_tSDUN-~V74(K>;Rfa(37GLm2HxO=(BPB?bP}7?7y$cTIz zfH-6;@KaWR@>>i9^2t}@S;~Ojdj1%a#nil6>1Biv-JX?b?pU!sXmDquZFVpHneKHP zMVtZ!eAuhp`#=c8BIsRQr1ez_wd7ge)_~dGCdYb`?O+#H@4?Ii-7PO*eRbs>^p%?iD8v;QAa{U7)^p+br8tampdB=HGyN~ZqWF!mmd@3ve8AK{{5)# z*Yo}BFhG0$F*UN|IVtWL0v0t^Zc=mP#-lWUYYtj%yM3xr7i%Zf6NYwLe9RGEaB3V> zaJVhs&12(KW@R4ncUcyLzh6-eeP3TqJWSt(9}p*+L+`syG3Ir37r?R*n*yx@)X=$X z6rBhv=tyT%Gv&}NWSBTT0?ZKUNf%YAu@Cf_WtdV3& zq2A4}yGS{M8+QwH%%D%kDD$5}evPlQuS9?GSnckzc2;;XS`!)EI#Lrod2#$r(-)-K zf<(CV{P4KQ4la>|;hw5pPK3+4BT;&f{QFP2%^FrX2mLm31rTL~YklLTHMmYdFe#^X zEHDf>q`!AEZ%OT_Ynd+zPzuvl%k*`5`BL43?*JR0zC*63^WRcjziz9t^rLa{ zXZ?P!QF4lv&+JAHEK_%+plM%PMM8X{MJEOakOt6Yz`FahZLsp3Xp-M@==~KGGU8}% z-6(d$G^kc6H(<3a&wVGRmN5;`VKWOxmp6Fv$H~0KsNaA7s>ggXquu{?8) zqmmxkkz0po15W*EupFs}w$iv+I6qZqn}P0)i|>qQU1ng9EzAHue>ym}i*|j&GyOq) zc8N)%W-RO~2m}s#M%tqM{*tUib0YQh!3isqa+=QuCke_DS=NdLXeM0{b~j|1jD-ez zv0(-nv6d|5&sV{zkp4R27(OR_rKpUU#-dIn_WTgZx55Z(VDvVC;Aa%oOXD{?dwIF0 z}%FuyLLzp8IbmLn~bQ@x#QpaF=oCPrhK7koCvZ>GH&u~wsLJg6e zAR5@o2rm4=a0lF;Ow=CUd>s_>yo+0L(plrtOlEi1!SOQE7u8!Th+QXOK(FxoS)uApjm z-!mdrpjy{4nO=`CYz%S@$KA6^I&H(o{{^a6-(ZBC1ZSi`D2CDC^&5vbIAVR}7NQ9@ zNk?sFjS_;A){=k2<@-cbri)kEhKedUBc*DO0UPf8zOt8pXYrKESmGcON^CU{C-4W> zgjaq%AkL43RmH84Ooe8AfAP0_JG%Cy^pmq<4~&0F)!H)e&_VMlDiWQ8gyGSmy1v!V z47m>a5n70rUYQMu^cp-uf>3wJ?azwE4bSfM1Yt6cFW=Kb4P5ouG&jxvP6>=dSBl#O z=P1WB3&X;Id})jSE)n=nn>my~!pjnnlMYcU>l{(U7x+MIMVb%kzJ0OWC^rY)4J;vC zec_=h1brYXAxzf@>|39CC~?5qcV_Ykl@vpBwRE=2-t2K9*W6%7iYbPnHZcE!O<=H= zqbtk}+4mt+yHgkK$(tBaQR(N8$0jy zi+i0@D8ZcrUoa)h$QgdSbjj>R6#+socLrdNuuF|&T!ilhrLB`JSXF(-)>4{=Uz@z1 zn2pO{zBqDL$G}_*RFH4~Rf#U94QIecINI_qw zY%;@zzqEKcycbd5pwubwhmByb$ua?LCnkY%Wgm7ykwh;H7AT$nTp^#amySZUsR)F2 zD=<&T)`0N=G4)HjWgHujHh48nWnU6`Lwl=l-2OnIgq1Ey6V*-H_qnpsv6216qLxUX zIt#IKV=d_rnBAoSsu)qIrHr3Eh+92=(@txQhTFE)$NmCr&FM-kwk`o|Ojbk3L@!5H zhS?c}Zc(j*d7Xz$P=45IyI76W55uGPM`@p2_E!VlEH=|S&lLI2@ffZ-6SjhEx^9lZ z*r6sgvX{P2Eux!R)EMiqEAF3(7g!C8J)I?}1Su981pg*fJsmhX<5G%VD~Xu2#ilYY zWb5`=WaKG>oBI%p?TuZx4-P@z&;eVas7iVPlMi29j*|CLA)ct? z8uJ(7Ma8A_tGVJMeI7`pfsO-y`E6mWkM~J7XqF#G+`3-%F}5@;4UAN@bas>LK&DsS z$Fb?+asT}hn-SeO$653qOia-}mmQ{}lKIZkXHXz-ZzuV@IPeeAU+%;6i0P`VJ4-?` z5%Vu%@tRo_JZ5&m(mB8(FgVjel)Cp!o62+`O32ac-f+_6_*%3TdzK*Fn)C;aW8@ZJ zuPtu5@L)2@g?SS6SH>7i5Ay&KdluXnqN3SFN*qKB%Up%w?PAbUAuO9FJWBUz?Uj8G z%321q;&hWj9w?Np{LG5$#v=NVWN-2$u&g`F)LEb_V~=@NrK+EDoy(x7pb&z*v(?m` zsvq4NBNgcA=%;@a9GlXy>zx*ypkHO?Nj7M8W1@}>=`Hda#l|z@sj+h^S>J-dB|nG= z-Z-_2nZ>}G=bsP{BXKx6%cgDk z*VG;q61p+Is-G%`ptvg}JLT))*#7QhOx1S9%q<2N?B^BeG}s^DknW&y`+0Sn^2v5?K41dX4_ zX=whX=%h|@Q8K@b1Wx|aCd9|n>~44#43uue!pM3k!5($z+UrG+f8v;&$W`Y*nw88x z4E+VN-6Jj7WPH(vzn326js~X7dl%{)ruj-J+6Qob7ejpO;gt_ek+tv@oYNDAG5dh5 zR4MPId#db$i1EKpGKexU74el=DZ27s=6M8ECVgD{k!UYgWpX^$y?JlB6Y@(&VkQ|D ztWpv_3+&bRj0v>DSgCmFfabm7Q-7<1cc;GM&7BYa9{JquPJ>tJ`4y8`+$j`8P4|u& zuuZy&PTrvP4s90Tk55`n1GQ zLY{L%Obp=EB@`gbn0kocE)x5a2@{K&quNdVV_3qLabr+Zj8njfu4C02Q~9w~M*Qb- zVxVfOAB@$nMGHEon%g<;s$(r5vCf{ehLwPeaF(Pey%5pB_AySXbD;ucUYI)PTY}q> zfKWz0=q~U#_B@0oF21#((eF3?mSlB8SFY2MYE=Xy-s`rYg^BX(z`p^8yGbhzp8{e0{fT2L zxP`u7kX`|3kxM%wfdfP#?W*K4LloZ_B?_1K$4B|cIG-`r00nIwo*H6L6B;KfeC zHGTZn&3?MDFoXr+1Ag>WkwtT8W{O5>Hw6O6$A^J;tZskts3t`>YpvJ zZX(dEh3PG@O*-w=rJL~m*flt2nMhz%_5?>k%HR&zqZzMrfdM!X$_77yFb*Ve)#K4y zQnqUp$K{_)AsQxXJg2>4z_Q#%;45WO#H7S6FMD(zNt!7#JO8DR=?|NK&SPCz9weuE zexd0ZZT#)3?eFBi{avs!Ygb?i35~KJsd5sw$cZ1QfrNoL>s;Oh5_Jj;r_;7pz}uPg zc#V|72!&46Zft)vOn+W@7#iA|jE@8Z8hn;#4bM+bI}IkG{@WTl)YW>75r)Amn|2#9 zel8`W8iEy}(fsc05cT)#iZLVta0Yr;fny+dgjWAGHmlB`MNL+!7j3+~HIFp#{=2$e zSbU`}O*o?>(DxyI3ev#PRhi5SLpY1Za#o5q&qX`F+{ElNkto`dfvyO8iTedGZ`UJJ zvjln-Vad@pC2BF7fri(iu7Vd;u)__Gn|Cvz55uw@o~$GudX;Z{Z@qpeq^Nl(TXS&(YCB+Ej=_|ns=nwq9>I4~b#w0#HXp%$wj`I3HMm=)Eb;9Q zI@L>@>jq_Y2D9Es2P@&bU?3o$WL9Yj7PY*>U!XsssX8-rGY6xTxc)6aY zO}>fu{QZHeR-YssRImg-v^1#E#b>`7TNL$# zsSOXwT;e+Obg#TI?r^GQzt$U&VYo7Xw2K`t%UsTK03Msb2LjJWg0_0^B=)PSVzg;kp%{^X-Yr~M~k$eE_>?_56_ijF{rTH8c+(;vlJ}T8-_!rx*k;eYHS`Fi$OWwy#=|Lb7xj{SnkLG47#+|sbc^fSrU$7 z)S>qSucT|*ZrY@qfZB#;LB<46lKxG4(cofs8dC^-;UUDTTB1Uv;VPku560K?zcFuta(qh2bPjin zpXHP?HI-ZtBra{C`%|m#qfL=vZ&bN9 ze{HY$Y5blgG9DnZ5pZpvXXt&qANyKeBwvFLQZCYn>Oa(~0Mj9LIa_jyinhZlDP^5P zIH9W0QS{m$;T0e~@Imf-o&TUy`2!(O)UwuYBK|H)`ppF99hJi$2h;lo;gUEyVooKmERe) zaa%)qntgvxnND?g{Onuc2nT->4$TmKXj(Dq;O>^S2zy*A`3JMEdrdtY?~#T{Ukvh7 z%O-Y@Yl#$uh9-B5uoDb|vp3XpF@;h)-cMLdgl6MHHhCA=N3Q=(AGl&rN*g>8htcBV zXvwa0nD)0G=8Kc_R25dar!9~SqR_z0F9px=P#&!ptU(C2#WG<`!QnJg@s#`ulvF8~ z<6d%#O7HdJCxVx3tk(B6CXTRDtcy{TMzu#Ij{(g$)Zp-%8n_n@*rgu2 zA=(SBg(diKi{6kj=-$879-{PXfjm*-(01Nx3r(6{YTJB2*2F3Eco>S_4|pEPpu>;g z=AYUGYZBEphTQ~jbtUda?&8b&Z;*Q2F+30a4;4Ix+k_)Va<(f7w>)~2&6(q{U;YX> zE0ehh3)pO3o_f)5g>zvgeW~2@Ap%iFC2pu@)Vd#yOy0+ZTWVszHy$cX%g8dV8JE?r zt=PKti!;r7R%Musr0SHX*3oRga;umXCAV}ty0%sT$NKrjz~Q$XulYQ#*&aTAXLL*< zT`BSQZx0gZ&Zx3QpSdhC9=b8^?5?4tY8?iVq6tc#8Wm3?5R#d*BmBwk5rY*97CeOhm+jR?JDWl~G*-6`Xb`+!APYNi`hH~Pe&fg>`{_3c;!Flm zgdgFRKJ=E^SBT>&^h!EX@Q7Hwy9mSN)$rJKn2uNKNp*s@ogJ-bQk=HV3k`vPH2lI_ zNd?c=C-UsoRn2ZrD|W|54PZFLlM7W)K9F~OnyYJApLE#W9#ww{b(zmO0lW0WG%%`b z86N}G^7Cl?emCM0Q!~`Q=;Bb=Q@J0am&&LfnepyXy zjGfb9=5=K|P%!*yn%{l_Nq~NZ)ikpf)YH}0-uzn47{|hALSbC-Y7%T>V7-y4llDH^ zzHE;*sOz!sXWq#1GpS6YP9&kE1oD_>3CcCiI(Y{ws;7G$V!{}?&LbCqpJaTm3por) zOIa0qdVC8*fNKHQd~efqqZb5Wr1sahAgLj($&cgWhz7s;$z<2zSVt5p>|F)`8P-zh z0K0L7_YA#kI69E1lks{57-BHk(4*D?HBS-0Gvh+7 zB+`vDE7;bC=?{yNN8{c&K6;&Z@h61RZjjhgt9;z&7dxR6iTc z!yOdfkXtVO$SEiGh|{ZuxqVr150*ReSmEUOy(l#5+qsYwknvCVSzO_QQ3m`GMloSY z_`!gr*HCsWgkx-6CBu-HdE0pW3)pvlK`5o{@0BJ-hJ&Qg-TuC0m#Im=io}y`df#%b zqh)tS5dcCKckC;=SukMPqdD@?*H>mu6gX$x|FqFX{MX8(|6fm!pn|B1ptz{U90UO1 z4FUiF{}%)R3jT-vXUhNSe=%WuH&Z79K_?di3Nt5rI~PiTp^cHNErIcWaX_SkoH!gb zHuS$lI7tZ+rT?`E1oFS7Y!Q+x{{|=r2~B4J0Ont#5ey0tAS>s;)+7iQNm)^d9bjm9 zSVSox^vr)DEEiD?7h!u_TT?q1fUuLPp^K>rfxD%P1%bGvtb%$VJjTByG)WOb706ZN z&z~QD5D*ZQe;Nb~;KTs|nGf|R|Ca!e6qOUH6*36&|5w8Q4ZzUJ#nSm7fs2JH!T(D!BG?qA&4ANnF13FA&G?=2GEq|Z%LSqoPwaB(J?Twut~|tDJZE}SlQS)IJtyH zM8(7 Date: Mon, 27 Oct 2014 23:14:28 -0700 Subject: [PATCH 04/12] Fix #1045: whitespace-separated queries in web --- beetsplug/web/static/beets.js | 3 ++- docs/changelog.rst | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/beetsplug/web/static/beets.js b/beetsplug/web/static/beets.js index 5df50764a..eedec8a5f 100644 --- a/beetsplug/web/static/beets.js +++ b/beetsplug/web/static/beets.js @@ -146,7 +146,8 @@ var BeetsRouter = Backbone.Router.extend({ "item/query/:query": "itemQuery", }, itemQuery: function(query) { - $.getJSON('/item/query/' + query, function(data) { + var queryURL = query.split(/\s+/).map(encodeURIComponent).join('/'); + $.getJSON('/item/query/' + queryURL, function(data) { var models = _.map( data['results'], function(d) { return new Item(d); } diff --git a/docs/changelog.rst b/docs/changelog.rst index 71bd27bab..daeea77f0 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -55,6 +55,8 @@ Fixes: :user:`multikatt`. :bug:`1027`, :bug:`1040` * :doc:`/plugins/play`: Fix a potential crash when the command outputs special characters. :bug:`1041` +* :doc:`/plugins/web`: Typed queries are now treated as separate query + components. :bug:`1045` 1.3.8 (September 17, 2014) From 4a33fe7158065bad2adc9683ccc8cc2ea0e1658d Mon Sep 17 00:00:00 2001 From: Matthias Kiefer Date: Tue, 28 Oct 2014 08:25:44 +0100 Subject: [PATCH 05/12] Style adjustments --- beets/mediafile.py | 63 +++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/beets/mediafile.py b/beets/mediafile.py index 11c0459fd..ace8288b4 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -955,41 +955,44 @@ class APEv2ImageStorageStyle(ListStorageStyle): """ formats = ['APEv2File', 'WavPack', 'Musepack', 'MonkeysAudio', 'OptimFROG'] - _APE_COVER_TAG_NAMES = {ImageType.other: 'Cover Art (other)', - ImageType.icon: 'Cover Art (icon)', - ImageType.other_icon: 'Cover Art (other icon)', - ImageType.front: 'Cover Art (front)', - ImageType.back: 'Cover Art (back)', - ImageType.leaflet: 'Cover Art (leaflet)', - ImageType.media: 'Cover Art (media)', - ImageType.lead_artist: 'Cover Art (lead)', - ImageType.artist: 'Cover Art (artist)', - ImageType.conductor: 'Cover Art (conductor)', - ImageType.group: 'Cover Art (band)', - ImageType.composer: 'Cover Art (composer)', - ImageType.lyricist: 'Cover Art (lyricist)', - ImageType.recording_location: 'Cover Art (studio)', - ImageType.recording_session: 'Cover Art (recording)', - ImageType.performance: 'Cover Art (performance)', - ImageType.screen_capture: 'Cover Art (movie scene)', - ImageType.fish: 'Cover Art (colored fish)', - ImageType.illustration: 'Cover Art (illustration)', - ImageType.artist_logo: 'Cover Art (band logo)', - ImageType.publisher_logo: 'Cover Art (publisher logo)' - } + _APE_COVER_TAG_NAMES = { + ImageType.other: 'Cover Art (other)', + ImageType.icon: 'Cover Art (icon)', + ImageType.other_icon: 'Cover Art (other icon)', + ImageType.front: 'Cover Art (front)', + ImageType.back: 'Cover Art (back)', + ImageType.leaflet: 'Cover Art (leaflet)', + ImageType.media: 'Cover Art (media)', + ImageType.lead_artist: 'Cover Art (lead)', + ImageType.artist: 'Cover Art (artist)', + ImageType.conductor: 'Cover Art (conductor)', + ImageType.group: 'Cover Art (band)', + ImageType.composer: 'Cover Art (composer)', + ImageType.lyricist: 'Cover Art (lyricist)', + ImageType.recording_location: 'Cover Art (studio)', + ImageType.recording_session: 'Cover Art (recording)', + ImageType.performance: 'Cover Art (performance)', + ImageType.screen_capture: 'Cover Art (movie scene)', + ImageType.fish: 'Cover Art (colored fish)', + ImageType.illustration: 'Cover Art (illustration)', + ImageType.artist_logo: 'Cover Art (band logo)', + ImageType.publisher_logo: 'Cover Art (publisher logo)'} def __init__(self): super(APEv2ImageStorageStyle, self).__init__(key='') def fetch(self, mutagen_file): images = [] - for cover_type, cover_tag in APEv2ImageStorageStyle._APE_COVER_TAG_NAMES.iteritems(): + for cover_type, cover_tag in \ + APEv2ImageStorageStyle._APE_COVER_TAG_NAMES.iteritems(): try: frame = mutagen_file[cover_tag] text_delimiter_index = frame.value.find('\x00') - comment = frame.value[0:text_delimiter_index] if text_delimiter_index > 0 else None - image_data = frame.value[text_delimiter_index+1:] - images.append(Image(data=image_data, type=cover_type, desc=comment)) + comment = frame.value[0:text_delimiter_index] \ + if text_delimiter_index > 0 else None + image_data = frame.value[text_delimiter_index + 1:] + images.append(Image(data=image_data, type=cover_type, + desc=comment)) except KeyError: pass @@ -999,8 +1002,8 @@ class APEv2ImageStorageStyle(ListStorageStyle): self.delete(mutagen_file) for image in values: - image_type = image.type if image.type is not None else ImageType.other - comment = image.desc if image.desc else '' + image_type = image.type or ImageType.other + comment = image.desc or '' image_data = comment + "\x00" + image.data cover_tag = APEv2ImageStorageStyle._APE_COVER_TAG_NAMES[image_type] mutagen_file[cover_tag] = image_data @@ -1008,12 +1011,14 @@ class APEv2ImageStorageStyle(ListStorageStyle): def delete(self, mutagen_file): """Remove all images from the file. """ - for cover_tag in APEv2ImageStorageStyle._APE_COVER_TAG_NAMES.itervalues(): + for cover_tag in \ + APEv2ImageStorageStyle._APE_COVER_TAG_NAMES.itervalues(): try: del mutagen_file[cover_tag] except KeyError: pass + # MediaField is a descriptor that represents a single logical field. It # aggregates several StorageStyles describing how to access the data for # each file type. From b02da5e1507a5dac3f851f3273b0bc0b3c7e325a Mon Sep 17 00:00:00 2001 From: Matthias Kiefer Date: Tue, 28 Oct 2014 08:52:03 +0100 Subject: [PATCH 06/12] Added test for date with slashed and fixed date regex --- beets/mediafile.py | 2 +- test/rsrc/date_with_slashes.ogg | Bin 0 -> 8562 bytes test/test_mediafile.py | 6 ++++++ 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 test/rsrc/date_with_slashes.ogg diff --git a/beets/mediafile.py b/beets/mediafile.py index 0b11f1c0d..9b90488e9 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -1092,7 +1092,7 @@ class DateField(MediaField): datestring = super(DateField, self).__get__(mediafile, None) if isinstance(datestring, basestring): datestring = re.sub(r'[Tt ].*$', '', unicode(datestring)) - items = re.split('-|/', unicode(datestring)) + items = re.split('[-/]', unicode(datestring)) else: items = [] diff --git a/test/rsrc/date_with_slashes.ogg b/test/rsrc/date_with_slashes.ogg new file mode 100644 index 0000000000000000000000000000000000000000..be676115bd72eb94ffe7920e27bb0a9044cfdb24 GIT binary patch literal 8562 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 E4_I|Jy#N3J literal 0 HcmV?d00001 diff --git a/test/test_mediafile.py b/test/test_mediafile.py index 56a7bf572..e4f3edcb4 100644 --- a/test/test_mediafile.py +++ b/test/test_mediafile.py @@ -807,6 +807,12 @@ class OggTest(ReadWriteTestBase, ExtendedImageStructureTestMixin, mediafile = MediaFile(mediafile.path) self.assertFalse('coverart' in mediafile.mgfile) + def test_date_tag_with_slashes(self): + mediafile = self._mediafile_fixture('date_with_slashes') + self.assertEqual(mediafile.year, 2005) + self.assertEqual(mediafile.month, 6) + self.assertEqual(mediafile.day, 5) + class FlacTest(ReadWriteTestBase, PartialTestMixin, ExtendedImageStructureTestMixin, From 610942b1a581b6b2b1b22d861c7b60ff90198be0 Mon Sep 17 00:00:00 2001 From: Matthias Kiefer Date: Tue, 28 Oct 2014 10:28:12 +0100 Subject: [PATCH 07/12] Fixed getting description for wma file with standard WMA attributes --- beets/mediafile.py | 2 +- test/rsrc/pure.wma | Bin 0 -> 23680 bytes test/test_mediafile.py | 6 ++++++ 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 test/rsrc/pure.wma diff --git a/beets/mediafile.py b/beets/mediafile.py index 9b90488e9..049d069fb 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -1488,7 +1488,7 @@ class MediaFile(object): StorageStyle('DESCRIPTION'), StorageStyle('COMMENT'), ASFStorageStyle('WM/Comments'), - StorageStyle('Description') + ASFStorageStyle('Description') ) bpm = MediaField( MP3StorageStyle('TBPM'), diff --git a/test/rsrc/pure.wma b/test/rsrc/pure.wma new file mode 100644 index 0000000000000000000000000000000000000000..4dee3f7bf34b4d85d82ce4b1927a272168955fd6 GIT binary patch literal 23680 zcmeIZ30PBC-!Hlo0wfF)LO?)i0w$OM5kyd{mJEO<0VD*ZNNfQSWe^aHR9l1)fFLjf=56Ju=nmk8Wi{()WACgDtS_RYDaOG?wRL6gBI2^DERlp z|8#Hm_=CiC=zCgu3G%7*ry%T({#;*o$A!<&tF=D=0iTFmF#hQRrXfJJirjDAr}vEh z{+_+RX9IM5dQ0m*(Z_zLs{wXk%IiCGw}0Y%Pv;*fIps9(+F|@hZU7LkUgLC5e2*ca zn&|CxKIHYclnwvX&(J^0paBE0HOAl-4Fm&002cfY0k4B#9QczK037~I{|>x=3jdKe z5QqfA!Cw#%0n)zvoJPs-?ol7@(arh*pAG2JJ$ViMCRHQYKe7R1y0bbzU z9oYG~gz|nk{ecD;m=gd{;K;fG z*1(R>NICqu6ab+A9E$^gM<@J|*BSg0pYZi*{3Cz^V84RE{GZVI>FIZ@tp-OT0Ehuw zVh^@>9oXV8!TWl!C!gjC?vI*iV95ZmNxQAQpW;mr-Pxz~=8_thX`RWv{{(sW4J&8KG={7~&DG z`5dK`=|xlZ>SX}Z^;XUhJ2AEZP!kJ#L_Ix7E@Mj`f3M1Zh;+R<3<7rqE19!1MbKqwg3GUrZzIv^D##8oh3a~7>1txJobJq0geE}g6mwmgft>)tWHwGcH{;u& zdoq$#m$05KH5IYdRM%a$Vo?}*=$&R01iyu2`8#hjQ4VOHbPxP6?a~8|H#yf0KhcHHQOX#S9 zcaPrgajZ=qb(VKd6wdl6uZ3KJcyD^O^Z#CefPnu4_sq|@&-{dY9SDG2+%1Oys6)>p z7#A#Gj+EjkT2_~wZovZrv~a-AlnszmFkRFez|a<;i2!!dKGl6Gt`bO!=^BJvdkGFz z843?~N<`3{ov^#?&k5lO9F}JABbC9wkc-A@@Xx2H34@TvsWu#mb%z!YD_Ul;Q=8PZ znplGH7nP1mPu+j74A~TJ-M!{16$>y{ ztJAeNccfEsr@w)2eSxggvTUhOz=jRD!6hdr`&|BmuHYVtF3xyfHKDD99TwE_B-xOW%bL^E+5G+9_)#>g|p)((3 zcR0S_eN!8&nEFto2)wN@4VlCQePfDXI_6G9ak>rOJvpkun@{dKd*OKV<#puVi5=OJ z2yVtr$;>a|AED%*I%ikDh#2LJE~YzUL=RTJR79;kn;H`FWC7AkFUXM1S^7#s2%|Dd z*wmtuAzLo?T`cmQ^2^KiE8CnozF4#*k9pPj&FUkkPD#VRh{*V9;6>dqro^OH+U&)y zde>h*E<>(%Ud&7rBj52>JB`SeJ9Xs2OD`;GgFZ87WX_x6oSf$_Eehh|P~3Jwa9jFh zw0!0B^f9H~*}?10%y{>la&OzdKuOQEKaTST^Obz}TiIBt@l$0AD_MC#I%C2tw-aDTb5L@K!WaVjiwGHXV2 z*$T$&ecug_tKLJt@KzFb7Q(soOJEdd@}g?%?H&4uCWh0emD94s125^4(8|nLl7W}< zsr$>BC#C%z4;yx!`j?XdqVgy1kNzF*BSGMgMO$@&$hQhQ_{(XQ&5`y_fsbC)hDzI; z>vKa9R@n31=d{`=x*DnHL%wYYJ)y#a2UDREJeO`-K>_IFFrJf5qM?TuJQJPetD(Zu zg5r^(P6+P43SpWW&IE_mWqY9Us_IP>vU6-w=uQ}04 z=e7niPuMxq#thnoky;Eay1i7@%AbVtv_k6b#uESl32l)Qi-zbYo|zT~5*Yvpi?PN^x0ONu(O<&U|hAED8| zSj%04r}o6m{M_o!_sFn3)fMu^ZX3PHxu{{XJy#h$ES5I!QJ-(v z$xCkBMkVLID_>;Tkz+!9t&2vT4>=S<{B4$NZL@7Nq$hs#7(Ti&8{^R6m4%$fEAs0& zkmV10i>v&O-S{zO)5m9H@6O65f`}b{$8txs9%$D+d|Qw`Jc6lfiT#&=|04kc`xEzt ze}{Vrpqugm3Bg-=Tlws=y?H4y53aTEgj!W~h0}^@U*o<06;6g+pcI7=`Svu6d?0Ei zhdSBTwTvW$xv@Va5OLxf(xocWms*LjXH9Gm=Sl=G+0owI?et+ElA zm!&5Yo%g+Urd>h`0XIhvnAQdsw%(4d;S8tg63`lzOqXdnjm4tbyn<8Ud?=rj=4O2x zE`_G%4iv>Rk=%;>G7NiB;*VK*$7}hu`)aRZk3hGZ!V0xaImy>o8r*|i(v0XJO;2o5 zUA-qPU|UG6w%tWlcDCQy!EJt7@Aj&03v=(!%qg7oy)s1{$;E8+7RBDXG6^o|xo|pN-4vSkvnSh$=5B%#S?M0-67G}o_gx!$T?;H zN{D|+?V&H6PSmRNzk5M@%JO@l^96z>?*B^vjEvS7xRx+_wlDD5)wO+%TxH}diPGfI zg}|v7jo(6J!d$OFmi^LaUA|WHXp!;0eyCMGkn;d&^oAbau3h-m2bA9f=u=NxpI!Y2 zUc8l*&=40n)o9T>-&%H1L3$F?S|6n*{2!ry=kFG zub8P~gUt_kB-;cc%>2h;Z?)4;Kx{pZF===!r);jdf2N?Vz>|-F+WtyWwGoAAhtkEj zEST6twR7v?x|%3m0xu+AjLn6ijBt6yunw&zW`GTi$CZrS!yA^tlqo zdXKd0G!zq(lz??@6eV#RU`Due{NJ)e3Z#^DW;00xfULVSEztEq(ba?PTU2i;w=g(=MyC9N+xl-9{ttrjIx(?H0~XF9>SgFG$1pp1sqA z$@rz`{kx&6GxquQ?&Hl4o{9mb1*@j3-C(A~q@pWUom)H=7V{gv-uiCkE6HY^&T`L% zLe)Ld&s`MDC#6$^25+KbWwiKBF6CcC++W^q#vH3(vv6FYsPnt>Rfj?P;>s7w3%=4w zf~+^P><5F3ju&TT%X4%6wTo*mE9-Fs{h1$Dj!(_^8o6h8V2<5XJ1l77bR132j$h~q z0VO1l)`h}OPOZ{(VNw3AZgkC$adVlO$=O{8Re3H)4h3zCEPtp&WInzZuc%FR3sgE( zE6P1~vSfZa1D9`fzacn%3!ITkvOY~CSmi!@R+TReWV>PosRa6pVy2r@dk7_)X9(P57AH>(6%zNByklHV zXn>}~cv>+v4ymO0-n;ALFP#*ljF zrJ9Tp>*RNlld-XV*U_ANJM>c4E8J??0=D<9*GNonWZd$Qn~}4f7#}IfsJ97;trD}V zn`=n-Ny%-pH7UzV#&(s_ZS)vc&EmZl@1eDjUN4vjH>W(Qer?;8)Q$7VMUMpup~1yZ z*1v2SKSqelwoID&Wp#9Y-YNaK%v&=jSmXQ1v1Dr$*+MsB#lYm%l~mudpnQeACw>cN z;LdOBa2G!osy#s+xOVi?g&0pUd-XaGRf>)7B zv0=LuAqCe2C*a8YuCNn)FM8@Od@iz5i|{Z7%Y)ylcNOH_+7-sYc9unWCGHL4t-IgW z+cIme-WN8{6ZIpl}Mfy3Ira0>5OB(zQ3p)amcAO=LofWFAWh zJ5vIhEbC65E_iBi&)mXcB<4w&dyW;6#uio6LJ(Lh4k0VCP=ijJ1?5fAh-ULN9P`rRQNs&YjC-&W|r59_P4Dm9DDeuKn?6e%ZtWzujX_xGLU_^_sRIXS~=kg(JVUuNusG0TLH zo{>xC^;c%cE;>c6{3sg(5nkRpD}I46xRnDxc1^a>VVjK^9vCaWs;(4at~6PC&kuKO zqcaDTT{96^ItNNuO~rVB2#c`5F2e8qs0F{LFD_$ zhDHTakVq#06^2i^MUOkjr1?PjcpMDMrTQ2mvk$$_6{BoYOo<6U`}Vl}&`UY!=(R7Mv_UQA(3nv!1<%K+I8%7Pn&C4009U7L z+y#y2G`3ixAHqa3ExL)h_q`)pV&;8qFjdMR3y$P(>hXE^i6K1+a-UmLJ)y zbQ0n#;=aAdpkpW2p6X+Iiue}D>ar}?cv@A7)HoWd5cvg<<@UdSJIphmQM z61j229BcV*cf;81kSVWw?yq{qo?`JtAOEFnJR~AR-Z3bS8c2Q@G5AcU z=Wv1|5#%u>8>i1ccwIS^9DXq7$0%?~w;tlG2$|Xwwwu-ujaQKEUZ_>}R5vR^l+P7L zv_mL^3P!7f99Mn0tt-Ml_o8&;>z0nX#dl|ljtu}L_uR_2}&U5*qv=bZ;I9@eFgI)qBAyahO zuG|$!P&T0iJ7Eh<4#8;~DX<2!DP$1Vg=Ngpu2ZoxfUZJ1b<+HuC`nlOS5Kb|oT8pX z?z)w+Pp#v`Uag>JiqkcENDqx6O3)=nJhy`4m`)OOK~}pDnhV!QP-uFtz|RSG$!&Oa zI?-Gt7P`zcK~+-=oGyi{PD@O~S3F9Mc@kiEk71pLP+j;iCykKgm3Vgx3>uHO(j8}{ zRV2y$=A5K_R&u9wMn^Qy6Ukcm-KS1@IIn1Tsn8`?C=eLgld$-T`4sHLiY-;7^1`!3 z9|vE~NJqTOG54f$k5-q39|m4Furs7*pI19Wx;N*LgJpB+^BuNXTltizxM#jd;@y5Z5%p%)mD$%XF?R7R|omOn14gQg48%U_5YKRsNO?}k z+57T^b!j5(Y-fE|Yv*$RNvW_}9Q37Q;nQ+*MRml~kz3+{3KMcwTJl!6O^+YA|26dKk8$OS9nZ6$HSDdN8?@eI#QgQ$FH48O9j$!A`y9vF{Z8itb)?&& zppEZAU9|34&dc_Q4uhWu!@io#C}EG7k^N+Inw_l%Kaw1x7bb$x{??lo%6>fbFX!Wb zBtSmA20T=i3gMavaV7ge8=`5Ys~T05D)`k2%V5H~1Ki;l z54??e3En1+p$o&JvXOM3GPb}Y8H;Av<*}ho-Ht&BhAJvV!1_7OT)>BU+6!@f;kis8 zn|DnBWr=wf8bPL@NAT8SpwBG(CU2?-Fdj&h&wDaL?3E&>>Ld-UCkQu*6?bxLpSu_!ccB$wi#ctP_fJ>!H(|Xu`RmaswV!-@L|78$!Akz zv;8y`v@;R|hfu8mi)EN(|9UTNgpL0S&Ml&LGsla+-}4?1ufB9+_JmNsva z-|5WD`uN)W<^wMGA%whyp4%~_FuSPk8`Lw0lP+Cfs_ozOZst&wLzK4oK;3Qv9-GzScHNS=IgXW*I1^d^I$@Y36LCtoQb9Zuu+cKt);M=%{CY4(din97!OEf9-%m61;G{Xgb_jn@A-P06hK=fU0ieViqE7h3aq1pUxd8?;Pn11$6Rtu1XHvHwzQFk5lkE?!&fGDNR4uo? z8T@Oo5h~I@iEqn**|i0fLPc#*h7=p1J| z!jYuYw8tooK2-!WR6a`3IkVl}L@h(WLJ7Q+tZPrcY?tx*EWed^zF6BP2?mG^sFX^k_#9OQH>B8I4ifq`f#T>@-@WgSSC~JkQ4)PQ8^rPkAN*2O`3vh}H*ofRH0V{h^Sxhv>1+q`V2b<$ zvI|#Nt1H;q&q@_NNnF0-g@)h{)ul14 z>aihEf2*j|c^7$lY4wp?&wR9JZk*~(TgR#y-?u7GMMip{TC4bJV+NRaJUZ^knUS@x zIO(@$>y_EW4)U6a(U?1arH9FTc4i*u zmftyQ(LvtTH1|Mb@KD{im7x57+~;XTRqNO|L;SM+@=HPV~Y0xDPk z;B$;u{DZ#fGnHa)gQEwP~!%leO!bv1&Ui; zd!&!cY9r-}SO`%93VU9)c)b=x#KcNW?MN z=|Elyigyur4&h&%w_B};%D=FF{7u%K*uz8#VmlkMg!do+!QlLEW7K84wZyz^ z(#z9kf}?WAh-6;3^>#!9b;8$|`o%$q8MA z<*pB&W7m>yeq16i1${}qG8r3h+B){S{5d0{Y~PLV-#Efj3#XSRpR%ecOoN;kI?4#s zL91#pseW{^|A5~_k6$iU%(=H`bzozu&p5cY$JQ~2bZz4*`PIExmNLxJJi1+ zrFhD{D6T5jOa`h!#ZhGj2mIpP(}unBy*DBVw5LC69+Qy^9u6}xr}8-<10@yut?U{i zd2f3C1QcYHcVIb^7Em?`OR#iTTHhUPUYe5LgsC>H7`)9Lv{pRO{w3t#u$5}dc$^h# zZu`lji*HsD3W*>GNxcHATF%V8IT#qUF3Y#k>|YBcpHTmA7JipMNT37CC;0>1g#MV9 zjK9rG)pLHJ{IPBColPITGUgo~Fe+N??DBq0@qfgox@LJb7r}(>Ty~2KWtD}Yt1gjF z^5-F3q5BW)wSakPug5wy14Ntie1@|l-p0(PW-(}-5`$khjIlHmCwMjBPJPL=@Jik1 z^edAV49CL)QjW9(_C!^Jy{Xx2#6h!S5i60;slrO|{caG`{7x->2BCN}HG>gsABv>y zOu!mq(a7_!Qjzzx#yDPTc98+x_pS#M?&+E|qz~-8TW5pb-}VD!o6}BAfT&Ag2AGvQ>QfTX=LisgqNyD(gh`FXTuYw5HKiHZz!RK{UU}cj?;g|O zm1H#|md{ohQ4DxGKJQ7O5@Qv_JaL^WjQvhY^Xp+EWf2@u#YB)sWc4p^@lF>z#LgFQ zeCIjuT7HA*?9{8!@XnkQR(`nggN}(EIktMo3vq7*ru4hnu40bS4g(b?hO7PsJF#_4 z$z85Y+sXb0qUl%CB8!{jjxdK_pRp@3Y8V=IWa zFj(xft3xbpVRy6VaB(>UqUBlx<+oucQ)hLfR(96=#w@zHfHF%xN3t$qI2L4}?!n_y zM?kF;-@|9C=**$)<6>`HOm~eR=w?=4Zgy5Puj+RFg&6I#nR3g+eLBkR zmG5qW0z%=_@Fi3GTinTHg=1x6`1R&3E)e?JZ9_C@{mqv^RAydbuu%R zx~~?SpbwHr!&?KJ^je4`n8KOUJKlqS20uS88JG`mv^xsd08A`n=6f+&FUOSYEcC?n zWI6l=+WRXbXXbG1!pSoa-?#709$tzo8jY^_yUpjnh(bWH|AG7OKjZ$h`~mu3>Dtfj z2H7xX#`2E`f0E~QTEGkw*Dm|iYuTv{0@b!DTn$KK0Ye+X?LTO6iNH&F=m@#E89^0A zyY0q7*szNm2n-igy8cd4dr=d0i<$~bE78goaHWR8(f0}FFdFriEw@|GMwhjVpo>U% z?F(Q~a8R11Enk$)EkWSX=Ly*syKuMl%^CJ=uFy#UFTw*osJCe_ys2st4I%_hBc^Lt zNZEYB6?n4-9HmsmY!@PRF;JK6bPb|gr$YRu^t z=*+!Z*rE^`MU76QYoeRz6g#N6Y#4*y6+?lC!c}c3lw3SoH8q$IYG@hK$;Slg!%_x3 zKdDN9yEFStr`JhP1ne+wDj9^4Ip!JloA%wX!$&+7SoG+M^Mu+fy59LGom{r?%kQq) z+_MxC991p}i5Q&MJm@P`8h!x%_8f|DJJ;nAbjC*uK;NvR{jWwi1}{oHnV1ROl@wr} zA4PJ|hs%21-_J%K9|IkqTxON$ovj5u;cwiP4tAbyI&PtRe&P5bMIGyG@5H>c+Y-|mw1&8tb1LsiRn21kvg)?& zXVy7vQH3vQxCIXMcP|LU9A(IMcJ+?;Gd_xU?$2{JT^`Scv}8R~f*TED)Hj|MJ~Fr< zyAf%B`8j!F?TlhMQtmz}IHXU`*f??UhcH8S+E~{MZrW~6(;lbAJFkb!qRlIFCV~uJ z$nU`F4Hi0IRVlsX?wl zj?zx4i{q3rt-SHbyMx^Fhxq904LePhe$_wSX)NVSUK2IKllEA?Pd zD8mejw{?X5dJfxkXxM(M5SxFVVIJBT9IQuSkRbLjv{V;nBh|y|f})8LlDWzZQJn1T zChnjEZ7xB5C?dhGFICTrZYD;`7{c8r!lo)ztJu(AVlrU=dpK+p!-;v zQngZ=e;Yr)Ifa41i+(lVBXZF(dt9+e%L`R>@bYg-J}&2L>2rZ>yoa6yl5_!RUyn64 z-|Op|2&3$7$WOQJ0q9H%Q^fgfR;5m3etup$!l#Gj>Y&d=n(3NJG>svAVWnNSGdiE0 zO+fG+!1K{|eRc&rq2k~~x2U4HSg@l3}j4-K=*cEmhR9}7RX7AA&DR~%|JYMz# zs;Z`HX(Imij_2F3;a%Ob+mX@vQ}-r3p6SlJ!AD{YZW0EDmgNjzUwVfP21Pi|yAh{y z6>|>}KUUm<`NB%o=S|G)n`6u!<00r}VMYmg8!WiP@5RQqvm>Jo$3QdVq9`m;H7pLd z)w;F6Mp}Ud2V(C}#^kL>YUiA%KFpsCXzJ(ip4?&pYPl<17Tn*@h_}Rbeg8BPR^22^48lmIrSW<% zU6#9&%I8+~4cCRn=SF>)buM@p_wmRH&mX4+l4?~YGgpP?unBa+Bnb<>FDd)W}Airb;Vc)7h=1YU2NcM z7g2wA{>X_FCuk*){4Zo2Tun6NlwPTAqKM2Prh8qDA)EcB1uXjdoexoLu_5Fke2V~Z z`It+QqOo53s9^lOYo9aB3c+N3lN<#1jeWJvnRr~&lke%g@k2JoJkPts8=ilU!ja6F z^JI~u%$~uur|13RN;kc4jLSB7_i?ttL4q!?kC`?*I~;{}AYaJ!@*Rzt&fZ*P7gvG# zEqNLX6{wq7_vhs049H^B_gHs49(b+MJNw4Rg1~&NE1oc&k9UbYt)8k$8*F(uZYQ1Z zBTH)=_E0Bv_mF>T%k2?!(x{+MR{0AfcLTO%lBSmgK2kU;~>#AT+76<01l)Fx-WP`ucvd^{+J zl;hS;3tDC69C@%b>?@_+*XsOjy(y($SI#8A|M~d{Coks#=FL}cjB8iy8oWLu@9bZ{ zv^lx4+7Ra(rR7(DRr803g`MR+f-vK!OWmLWDx$KK?;$=`=l1~7b!ee;xx#gLZO?p? z93B@PWIZStZmg-b<^B`)KcW8LEc`Bid^+**N&e9N)Vj}lU=?s{`kNn$u6}eYs0X(E zx^L60_L;e@rcyrT)j1qPwXD~ovXY+#(jFU#w8ReP$!&54L2Lz2pKAb#l4`)6cjpKWI98^t-6=qbIcz^IxuGwlw z5*rs$a@U?b<@mZvI%7J}qcG179_7b*tvU{i>y2z=w`6bbIr+n2Z2{NM%2Ny)%KNWn zZ?1jU|5jRbrBm)Q`%&51O^^+*eXj%^Obp(bOcJNui+!VI7wpRMYd$J8somb&f=4W) z*?w_@>Zd~pGIHEyeEr(HT>h1m`kfw$2i~nd(xeFM^!}0osz^ujh7|H8xuNzlOQ7>| zeuN{7D~a26mRk$@C(8Oa>C30*YyIlsO(Tof`1i!7ANM^OBreSF5^*Ui2$A>j@chZ>Ve0|uZJiG$*CSOUPtM4@CZm@k^c#KpZe3mu zexP~?^nqRuj=r&Y1$Ob*)&VzT7ygEx$PGvDg@92I$OFfQ~&HUKm>y&DxmRcA~+Vp=q3Z2eC@kQ(sr@doP@oQ@$711wh^x@Jn?19UhH!A{=7)9fSJ_ zKx+}z;dE+u%B>^U*vKZz7QE0HMujlX9YWCY1!iuK_tgZHJwiIQ`{NoCt_P@cB-=OI z?Ri#y{d6EJh=DT@bwe(tkV23Q0ItE85{mfnEo!*n_?2V?I! zzDQvPOVKwhtSGT5SybYv8i8P9tE-62XjX$S3H4-yUW4|(;+4!=pXen%lX}iUH zoHk@)Hz4;S-3ZF>mPJxx`X>)3$$zci-41%-rMD^uhTPEPIN5ejaa{CrX00fv#~G77 z2+wcA3=|b4k9G>4$qHvcKiX$TE(?c7WKngT)Pp1viQW*|@nDR=x$@P!u6IotSIIq( zZ%15ZEk6}lCQf#cV_qs;W|50KO;4z-4vUTp!DMPoCUD0Mo|l83Ro0nrOsp3N5BaZU zIt8JZ-%xipJ&7Wui2NP5UVuk`gutrz#y{LclO)05bM zJ)F7$PIA-|^)wlaQTtg=4CbK}h8Lf4jt7S~1>qz(TP<+~k{y(>mt%L)3`#(!vl1CJ zXV^O^!q!l0XB(cNiLhlN_laqH%c%Z91BIRdz&cP)ZM3FLDT>ieAi})%i=gHRSju`h z(H~dr9b>NQXyY2Tf|_`OqJ~)YD9sz1o|55zJymmhlSPT?dJS%O*@i<59-|1`gl#@w zR=vT4+wDdS#Yyc%!cZ1PU0aRlnvE2T_3NOnTvb@PoDUZ=@_E&CdXd0HlzhifGQYR< znxAPPjVKMbZlL?L9Vb`y5aTF}SdqYDE$MRPKT%$`;| zU+>05!8qLug#3YP;yRsd&7&)xWaM}IVIGGZU-0dU)hAEjF{M8|CI`D=ej3!=nHjef zG7~t^@$^UbQs|&UZ=oRDAU)zLnv9+x+n=)hqEZwE+fes;;-U*4CK-NX^M3T zpkKUq(Ng^q$#k7r5Izh-(|mvDwDn|8-!}K5V`ZiC_W7fk>4w_Y@A_YFUbH?*T>O9< zdaf|UFKbG396(Q~h))Wmk!{;+iFV81h8X;2y|G%n?3Z(4yQq(!l9~-XC-wStDUZDu z>)dG~r$y;?`fpQRSbSsn4>=WFsFv__W(!E2h%F`8T|D)<5NXi7#7PDR)FW?nxZXG1-k{pefcOF zoOh38YKm=xrHBB~GJPILGvo?VY(fyGx#BckBF~hNsm2u=0el`ygy(V%gG!--+Jih@ zKE%caZo_t_!ZNYCrn&jMxSqBNu>4=!^aCLJL8by54X$lKKh1o5+c`fZ1jU)uEdsy%n!&VOg+sO?Cg76By<2b{6ea`U_(q@jKuhP@q;_;}&$5t@BNMHK8bnEW_(KLGmM4~?(P)Pv;_--* z`E#{lTCam53@C5(|z?9E7}q9Eg7YU+z<$Z7Zn7@inkKG1oNai?QQ;S z*&at`__&KKwO}P(AxLr%%(p;}NBUXqJ6A>8DN1;Mi)n zdj3FdYpPD|C}e`f%8*K{>SZrXmrR5GEryr!1&6bTcl?%AkH5Me^bJW{h|PK$dP+Sp z_;{r6NI_PYJm$@@<6}ZlvGe+3?g1G}jg?WIY$BhW+Pz)HXPL44BIu}k6xvf$Bio@j z`^ZgxTDj`E205g|X62Ym;WCa>9AzLbNY)MeB4OUG^44kVxgy!HgZ=q|!=%15XNR7H z>{)&C^hDN+a6?T(gU?26|0a{bVVmWLvv(phi>Lg4x|`)PQ7-SWy_h$|y<{ch`I@NA zvZ7malh~e^q-jr4|=meM2!BKCN^Z|M3UsFHz+=y-Ilb%enz6 zs6;-T{VZC!$Lz_`q58!^D_zRS@qA|ViU`yJ7xK#g$CpWa+v~Bf*<3hG4>Xv@b};EK7P;AcTnCinLGa;o&!c<^Tp}E=WhW>G z&mUr8J&S3Zy?VWYxQtYZE`_1F$DK>mNrKC=Gu((wPbM^2x;mC2Ifz&4T}yD8y=_SB zZFR=4j_A}W#?Ro*hjcQDmb*e+u8EF{DrLPc%Ev=`Ggs{jp1O})Mhf}mbgAWml!*z) z_dQ6|q8!~T2JPt0RZDigEzWjSUzh0@*ugf#B$n|2p#Hu%vLyqnd={Vv<9L&TrZAiHh=NKgoP-LYl<`llqG& z@2^1H|5FvrP1q~zYZ=m?9!XdG$-7d!y+QxUXB=5PuvRtto|r5f-d5PTyfZVp#zVnb z?5nL`G7V)BcU+*vkG*>mFYBLg>4=Z@6Aef~y=qDD84HYD7Nm1?NPpw#SmxrI)|Ta` zSx=6+8KJgr-bnIPEW1Q|I!;UG{RVP2pJ*guE=bcO~Ljz${Di>Z}o|L5hKSHoZbjY&-=xp zZ2SMjoEOhvay8H_cxq;H~Ae%00v`+9o! z-dDsgV=D9SPzksEGY|>61cVTP=D|Z7?|Xx1Dr;|!TTqfP@22K-7s_sz{ z)Df2n8tJ`sA{MviV-454sCW_6AwY(bR|k(Sp?jHZ@4;*LT&}&vYlcx+RW%E<29s3+ zb{5q#L{@(9a=TO?6P44w?Feynhi-$5zI^uN)Iqj|oZdCZ$)SVT;Jr9| zJV}gwL5RzcO~(bE{OVm>-bGlN&#Se9?3N{gpF>$_ucdp1-o)i`#AZ!_P)R8446^Pp zm=x!FfM(Ka-~GuS7rsXg{ALAPARb@1a&l(g*d3(vRg29HmH7;4wsaITGF`n&(90N)9uX7 zX+Fvl%M(LB_cx!&tDF-l!kafC|K;ZMUnP7({a@j)5%_Ba{u+V5M&Pdz_+LK){}-oV B(s2L) literal 0 HcmV?d00001 diff --git a/test/test_mediafile.py b/test/test_mediafile.py index e4f3edcb4..3d50b7b08 100644 --- a/test/test_mediafile.py +++ b/test/test_mediafile.py @@ -770,6 +770,12 @@ class WMATest(ReadWriteTestBase, ExtendedImageStructureTestMixin, mediafile = MediaFile(mediafile.path) self.assertIn(mediafile.genre, [u'one', u'two']) + def test_read_pure_tags(self): + mediafile = self._mediafile_fixture('pure') + self.assertEqual(mediafile.comments, 'the comments') + self.assertEqual(mediafile.title, 'the title') + self.assertEqual(mediafile.artist, 'the artist') + class OggTest(ReadWriteTestBase, ExtendedImageStructureTestMixin, unittest.TestCase): From 5ed6f59983895d3ba7c855959f0ec1b7c7f26f3c Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Tue, 28 Oct 2014 11:05:26 -0700 Subject: [PATCH 08/12] Slight simplification for #1042 --- beets/mediafile.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/beets/mediafile.py b/beets/mediafile.py index c101c9f32..51ef64895 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -955,7 +955,7 @@ class APEv2ImageStorageStyle(ListStorageStyle): """ formats = ['APEv2File', 'WavPack', 'Musepack', 'MonkeysAudio', 'OptimFROG'] - _APE_COVER_TAG_NAMES = { + TAG_NAMES = { ImageType.other: 'Cover Art (other)', ImageType.icon: 'Cover Art (icon)', ImageType.other_icon: 'Cover Art (other icon)', @@ -976,15 +976,15 @@ class APEv2ImageStorageStyle(ListStorageStyle): ImageType.fish: 'Cover Art (colored fish)', ImageType.illustration: 'Cover Art (illustration)', ImageType.artist_logo: 'Cover Art (band logo)', - ImageType.publisher_logo: 'Cover Art (publisher logo)'} + ImageType.publisher_logo: 'Cover Art (publisher logo)', + } def __init__(self): super(APEv2ImageStorageStyle, self).__init__(key='') def fetch(self, mutagen_file): images = [] - for cover_type, cover_tag in \ - APEv2ImageStorageStyle._APE_COVER_TAG_NAMES.iteritems(): + for cover_type, cover_tag in self.TAG_NAMES.items(): try: frame = mutagen_file[cover_tag] text_delimiter_index = frame.value.find('\x00') @@ -1005,14 +1005,13 @@ class APEv2ImageStorageStyle(ListStorageStyle): image_type = image.type or ImageType.other comment = image.desc or '' image_data = comment + "\x00" + image.data - cover_tag = APEv2ImageStorageStyle._APE_COVER_TAG_NAMES[image_type] + cover_tag = self.TAG_NAMES[image_type] mutagen_file[cover_tag] = image_data def delete(self, mutagen_file): """Remove all images from the file. """ - for cover_tag in \ - APEv2ImageStorageStyle._APE_COVER_TAG_NAMES.itervalues(): + for cover_tag in self.TAG_NAMES.values(): try: del mutagen_file[cover_tag] except KeyError: From 689d27c299940c61c61b1833acc818807409068f Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Tue, 28 Oct 2014 11:06:28 -0700 Subject: [PATCH 09/12] Changelog for #1042 --- docs/changelog.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index daeea77f0..34555f6fb 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -22,6 +22,8 @@ Features: embed album art when no album art is present. Thanks to kerobaros. * :doc:`/plugins/ftintitle`: The plugin now runs automatically on import. To disable this, unset the ``auto`` config flag. +* Standard cover art in APEv2 metadata is now supported. Thanks to Matthias + Kiefer. :bug:`1042` Fixes: From f463a3916b77f5d9b03341551e6466beb149a4dd Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Tue, 28 Oct 2014 11:30:23 -0700 Subject: [PATCH 10/12] Back out `desc` styles from #1043 More discussion to come. --- beets/mediafile.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/beets/mediafile.py b/beets/mediafile.py index 411878f9c..9b50aaa57 100644 --- a/beets/mediafile.py +++ b/beets/mediafile.py @@ -1550,9 +1550,6 @@ class MediaFile(object): ) comments = MediaField( MP3DescStorageStyle(key='COMM'), - MP3DescStorageStyle(key='COMM', desc=u'ID3v1 Comment'), - MP3DescStorageStyle(key='COMM', desc=u'Comment'), - MP3DescStorageStyle(key='COMM', desc=u'Track:Comments'), MP4StorageStyle("\xa9cmt"), StorageStyle('DESCRIPTION'), StorageStyle('COMMENT'), From a4fd02a3c504df09d3ce31174094b6fac4b09503 Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Tue, 28 Oct 2014 11:32:51 -0700 Subject: [PATCH 11/12] Changelog for #1043 --- docs/changelog.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index 34555f6fb..17c8c0560 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -59,6 +59,10 @@ Fixes: characters. :bug:`1041` * :doc:`/plugins/web`: Typed queries are now treated as separate query components. :bug:`1045` +* Date tags that use slashes instead of dashes as separators are now + interpreted correctly. And WMA (ASF) files now map the ``comments`` field to + the "Description" tag (in addition to "WM/Comments"). Thanks to Matthias + Kiefer. :bug:`1043` 1.3.8 (September 17, 2014) From 69b7d1f16040bec0a6b6be0779e00c4962cb02ec Mon Sep 17 00:00:00 2001 From: Adrian Sampson Date: Tue, 28 Oct 2014 11:50:36 -0700 Subject: [PATCH 12/12] Changelog for #1036 (fix #1028) --- beetsplug/embedart.py | 6 +++--- docs/changelog.rst | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/beetsplug/embedart.py b/beetsplug/embedart.py index 00a6ad969..d4d0fe4af 100644 --- a/beetsplug/embedart.py +++ b/beetsplug/embedart.py @@ -110,7 +110,7 @@ def album_imported(lib, album): def embed_item(item, imagepath, maxwidth=None, itempath=None, - compare_threshold=0, ifempty=False, asalbum=False): + compare_threshold=0, ifempty=False, as_album=False): """Embed an image into the item's media file. """ if compare_threshold: @@ -126,7 +126,7 @@ def embed_item(item, imagepath, maxwidth=None, itempath=None, displayable_path(imagepath) )) return - if maxwidth and not asalbum: + if maxwidth and not as_album: imagepath = resize_image(imagepath, maxwidth) try: @@ -165,7 +165,7 @@ def embed_album(album, maxwidth=None, quiet=False): for item in album.items(): embed_item(item, imagepath, maxwidth, None, config['embedart']['compare_threshold'].get(int), - config['embedart']['ifempty'].get(bool), asalbum=True) + config['embedart']['ifempty'].get(bool), as_album=True) def resize_image(imagepath, maxwidth): diff --git a/docs/changelog.rst b/docs/changelog.rst index 17c8c0560..1f1221543 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -63,6 +63,9 @@ Fixes: interpreted correctly. And WMA (ASF) files now map the ``comments`` field to the "Description" tag (in addition to "WM/Comments"). Thanks to Matthias Kiefer. :bug:`1043` +* :doc:`/plugins/embedart`: Avoid resizing the image multiple times when + embedding into an album. Thanks to :user:`kerobaros`. :bug:`1028`, + :bug:`1036` 1.3.8 (September 17, 2014)