From 8607bf15a90f5ba0814c97b7e35ef32e4a4632c4 Mon Sep 17 00:00:00 2001 From: coderkun Date: Sun, 8 Jan 2023 19:09:19 +0100 Subject: [PATCH] Add option to sort by last modification date (close #88) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Store the metadate “last-modified” for a track and an album and add an option sort by it. --- data/ui/library-toolbar.ui | 18 +++++++++++++++++- data/xyz.suruatoel.mcg.gschema.xml | 1 + po/de.mo | Bin 4190 -> 4246 bytes po/de.po | 22 +++++++++++++--------- po/en.mo | Bin 3931 -> 4042 bytes po/en.po | 22 +++++++++++++--------- po/mcg.pot | 16 ++++++++++------ src/client.py | 26 ++++++++++++++++++++++++++ src/librarypanel.py | 4 +++- src/utils.py | 1 + 10 files changed, 84 insertions(+), 26 deletions(-) diff --git a/data/ui/library-toolbar.ui b/data/ui/library-toolbar.ui index 97cad01..aabcc8f 100644 --- a/data/ui/library-toolbar.ui +++ b/data/ui/library-toolbar.ui @@ -129,6 +129,22 @@ 4 + + + sort by modification + True + True + False + True + sort_year + + + + False + True + 5 + + gtk-sort-descending @@ -143,7 +159,7 @@ False True - 5 + 6 diff --git a/data/xyz.suruatoel.mcg.gschema.xml b/data/xyz.suruatoel.mcg.gschema.xml index 934564c..9f50878 100644 --- a/data/xyz.suruatoel.mcg.gschema.xml +++ b/data/xyz.suruatoel.mcg.gschema.xml @@ -4,6 +4,7 @@ + diff --git a/po/de.mo b/po/de.mo index da025a58e832a15d8da250d349124781c1c8f3c1..abfee53fda80f21b12bf31bcc5049bc16bef6d96 100644 GIT binary patch delta 1618 zcmYk*OK4MB9LMpKG>tZ~58sZX)2OYEmK&2)r#5!%*oTVvs9Nv^maDnOKy6AM3R2A= zf}+f#Tpa`%unKNObj)TJf()|}1zm_DE>r{;g6Kj=7Yh3Q#VdHY|9tM_JpSi@Z=OW{ zoKt!-DR9QnRuQv^b$(-P90~BF7BnUdKAecP$YB~i=i@l8Ev&_*-u-SI&-GfY!!0-o zccc0jajG#TbJ*+PVu%M9uo|zR7B1re-b5wX$mrSFf!s1XQ2lM>Flp~Pi`qjGweTV2 zFn{o)M9*Ly>zj*}6JxI96dwGGHTV!U!86oCFHk#rg<9}`@A*g6I6c%(r=k{YLLQkm z?|vuNbG-ql;VulazA18|2}W=Zj^dA4MlEy?mB<5Bg&t!iAyg$^;ZGPM>mP6-YJ4}U zVgsmoMo_QtC~Ev^ENS9%UWfDEgG;ELT=BetO7ISos}MK~XqU<2+%Rb&vgz(M3N zhxs{(Cvh(N$woG#UdbBNdVRIjUlVWTh9Rh4)YDWYjdjqAl`T!;E*N;yvS(TsXGE~6&Ajhg5+Dv@`n9R|rpHh9kT zY(i}$isWE=QI+aPC6YmnD|jA3isLsY-0gwRnx#BaK^D7Xfywb0XKE{nB+;!4ns%V1 zx`-8o7En2V(J1#?AmDxqG?e1pSw(znO`Nn5szZd(f1-!52(mEKi7GL zo^Do;U2u|-L@d#2#o|_MStQ<`jJ37I;_lqghN^*{UUxXO)Afa|*456Cld}uiTr$#^ zbyAr^q&1p|CPLe+ua{Prop*-q!oFlA8eLpD+?H@-`B->jRd9<_N%M5w1z-Jt$A(f) Rt~iv=r|d#;zZ+|aegRHHtegM< delta 1560 zcmYk+TSyd99LMpa?w0PRnU}KKYP7qx>#nX{R?{@AhoClM!Lo=!mu{$GDPnX{`Yfc&YW}p=Rbo3myu@Vcg28*y6^?U+L zjY*pW?gJ;#$G}-+ZF2>+v4aP35S8E*F2Vq-&^0mC^G&FQx4YN7P-jS>Hr|K)nNEI` zXfGD9zd1MEG3F|kFffF9cn`I}W7I|?s1rRyZTQ9=|A3k|jymag)P^1&rfcS*?k~aF z7{a;OfF!vWR2m0KBG%C}JuKlP|UBg*;7xhXWx%bELW|lGU-0KSrmND+2)*VKM%w5+9 zsC7nBiM;Ytf08%vxuMcb-~#-HnpnWoE3ga;u@O~?IBJ77groWw4yz|XFEWUp7S z7PVm%wQe11{?>fzuTt#bMlr@w8+4#b){T0%XOOSe44~fKFlwQvuFp~L{4MGrUr`(U zL?xiIYJM(i{$kWYYtwX8fjDZzy{MBOLzVIr>cM_oinlS0uTdL#*-Z)ik)oNosFPOU za$Jr2Ms}gTkuLZ85^6pBIvp)EhDzWi>SPnHldeBpv&c>-@FO{x3RD6S)VzAvZOGwG z-0AZ)=0)l0{2}Lwr#MnYPi-@?k!T{+l(=$H+eE1Hs$Q*TIWIgOC*Unihq=>2{AtVR ztRr-Mi_oXvOsJ8BnMdRhI&LGOtW)Yv!`r2w+gWHo`$sRk^-4nCo-N}w4DXTgZ4Mlvd!QYp`X8T0)xScv2vqGV&=|9Kv zhn(~Nz{bDN>`B@^?T6z$6%5C$&h|t9rvEn-iCG\n" "Language-Team: \n" "Language: de_DE\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.4.1\n" -"X-Poedit-Basepath: ../../..\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.2.2\n" +"X-Poedit-Basepath: ../../..\n" "X-Poedit-SourceCharset: UTF-8\n" #: data/xyz.suruatoel.mcg.gschema.xml:11 @@ -216,15 +216,19 @@ msgstr "nach Titel" msgid "sort by year" msgstr "nach Jahr" -#: data/ui/library-toolbar.ui:169 data/ui/shortcuts-dialog.ui:115 +#: data/ui/library-toolbar.ui:134 +msgid "sort by modification" +msgstr "nach Änderungsdatum" + +#: data/ui/library-toolbar.ui:185 data/ui/shortcuts-dialog.ui:115 msgid "Search the library" msgstr "Die Bibliothek durchsuchen" -#: data/ui/library-toolbar.ui:192 data/ui/playlist-toolbar.ui:15 +#: data/ui/library-toolbar.ui:208 data/ui/playlist-toolbar.ui:15 msgid "Select multiple albums" msgstr "Mehrere Alben auswählen" -#: data/ui/library-toolbar.ui:214 +#: data/ui/library-toolbar.ui:230 msgid "Settings and actions" msgstr "Einstellungen und Aktionen" @@ -353,11 +357,11 @@ msgstr "Zu MPD verbinden" msgid "Adjust the volume" msgstr "Die Lautstärke anpassen" -#: src/librarypanel.py:419 +#: src/librarypanel.py:421 msgid "Loading albums" msgstr "Alben werden geladen" -#: src/librarypanel.py:519 +#: src/librarypanel.py:521 msgid "Loading images" msgstr "Bilder werden geladen" diff --git a/po/en.mo b/po/en.mo index 39a611bfc9450b522475a80bd696a35fed4a99bd..8fa584c622e4f01f211e77efe784de52feb62f08 100644 GIT binary patch delta 1610 zcmYk+S!_&E9LMo9HKm;{+S=D%`%-s03(6>^txCie`cO+WL$4a!FrA7>WyGUIM6N!F z#7>Bi#&{tT@#295FO`N^UU(9`NF+S?{_05F-2Z&;J?EbDKj(jM=I!KX)w%ao!Cu4B zLQEvq6d04lo*+Luh8j}>0j$I_hUmD0g?I;*IFIf47`4D^Mo+?eq{(bSJ)cBQ(`oP1s6BL}5+6lQbBZ4=v=__C zZ>|nr7;_It((wd~@il6KkEleSP&@j9O8CR}|3ZyZr*=9Dm2f)JW$J8u0}khY9gfEB zIF$URn+r|QgH!MfPQW}W(M!}q`cV~ngM$k~RpJXy#t^F>hjUQln@|;NN6piNdW9!Y zI}eS})zb5!X*Vkv$_y`o>XeHg2|7N7#C_J{l^;Zsz?0qX}; zWj>cse@*z+cKk**V}>xh7Ep>ReUsv=uaJKTj#VfLZEnIotQ44^9Y z1GSJ5B-Qid%c#F5c5K6JR7Jw5#Bo%A3v!xu{Agj@tb0+FIf@j)oJNg5he~t-wV~^% zgm-QKebl%IIW9Ee3sk~)sD$6GKT#iz9@0lsftq+0YJxE8n`y#1=%EswMpdTQdI>e| zHmVZ$P~S}M6&LzwzFCXOrjkuVO|%^K4qH$Yw4rv`Zu>iI`yONpa|l(5|~ zLH~EKA{V8lh4^<&=c0~KT8Gf~nhBSvAjS|wh-t)ff@KXZS@qM=K+GU&h_M78k(o~{ zA#`ZFa|!-AO-zea9Txd#3ae+txmrvtCF+S;#7g4-Bb@IqJW&wL9QHE#)}ppR>Hc&_ zYFBD!GMh>t@UIqcso&@wOlPw0+OE!2huhfQ+2yvT6HaKudUvCDIMu~tZgVp0C7f6! z7I!02H?qiyE>1-1Y9dj8YUq|9C~@PfyaQe)nN4RB&W5ztk;*#pa4Z}PwYh(9-Ns~> pcQBdVop8e8+QBnlQ*!(7!u-~vP5GJSWr51I|1Hi@R=;-mygztjsOi}hTmVH)P5=1ciW#tKZw8qC60)cxI< zYfQ}a*&Bw@!^AkUwwXdDcJMG>MHRS;MOerxbWH?xe+z2i4tu>HwTEt0;)BSa8Q@2S zj$%6b&H1&CF_$ohiEEgG_fZSXqY^EkcJvCBaM8{$p`Ket?eqsKp^Ka8nmp8a31(mb zH)0d!kl%FE*^DP~6HcNM%%Tdog*urys*p#h6Ij4vT)_fNq-s51h&rh{)H>a$SJ#Vr zegL)Z2*z~7n4O5BD!pKxMjh34OvQVsSMu17zr?8oW8T~GV@xX1Fe=f6brN+F4r;y2 zc6`pu`BS{P!+;V$KpovP)B{V%M`Bj&{7=+LBvXwF&qjt!0qPqmL+yM5bwV?!LgrET zKSizk+FmcFa{fAsB?gpu+1~ISRp~EOVJTe5eAK%xM>cI5QO~!d675B8=m08Vubq#g zo;!+K=PWAU#TXq`bj5lD^^x2}eIyT2557ZvBVTYkdRavYYEdWBU~NYg(uF#K9@IB- z2K9|hTW_OID*Bv`7W#yGcVAHp{6_7}O*NYLpvE(iDU*jffvu<=2T>cTN4=63q*k-f z8FMwKgz4!;2An6Z>`)awwcSKL(L$(cedSWyMQGz%vsOS|*W4tRqT^WeLQT7@Ao#~\n" "Language-Team: \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.4.1\n" -"X-Poedit-Basepath: ../../..\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.2.2\n" +"X-Poedit-Basepath: ../../..\n" "X-Poedit-SearchPath-0: mcg\n" "X-Poedit-SearchPath-1: data/ui\n" @@ -217,15 +217,19 @@ msgstr "by Title" msgid "sort by year" msgstr "by Year" -#: data/ui/library-toolbar.ui:169 data/ui/shortcuts-dialog.ui:115 +#: data/ui/library-toolbar.ui:134 +msgid "sort by modification" +msgstr "by Modification Date" + +#: data/ui/library-toolbar.ui:185 data/ui/shortcuts-dialog.ui:115 msgid "Search the library" msgstr "Search the library" -#: data/ui/library-toolbar.ui:192 data/ui/playlist-toolbar.ui:15 +#: data/ui/library-toolbar.ui:208 data/ui/playlist-toolbar.ui:15 msgid "Select multiple albums" msgstr "Select multiple albums" -#: data/ui/library-toolbar.ui:214 +#: data/ui/library-toolbar.ui:230 msgid "Settings and actions" msgstr "Settings and actions" @@ -354,11 +358,11 @@ msgstr "Connect to MPD" msgid "Adjust the volume" msgstr "Adjust the volume" -#: src/librarypanel.py:419 +#: src/librarypanel.py:421 msgid "Loading albums" msgstr "Loading albums" -#: src/librarypanel.py:519 +#: src/librarypanel.py:521 msgid "Loading images" msgstr "Loading images" diff --git a/po/mcg.pot b/po/mcg.pot index 19fd383..c409fd6 100644 --- a/po/mcg.pot +++ b/po/mcg.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: mcg\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-09-05 15:08+0200\n" +"POT-Creation-Date: 2023-01-08 19:06+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -215,15 +215,19 @@ msgstr "" msgid "sort by year" msgstr "" -#: data/ui/library-toolbar.ui:169 data/ui/shortcuts-dialog.ui:115 +#: data/ui/library-toolbar.ui:134 +msgid "sort by modification" +msgstr "" + +#: data/ui/library-toolbar.ui:185 data/ui/shortcuts-dialog.ui:115 msgid "Search the library" msgstr "" -#: data/ui/library-toolbar.ui:192 data/ui/playlist-toolbar.ui:15 +#: data/ui/library-toolbar.ui:208 data/ui/playlist-toolbar.ui:15 msgid "Select multiple albums" msgstr "" -#: data/ui/library-toolbar.ui:214 +#: data/ui/library-toolbar.ui:230 msgid "Settings and actions" msgstr "" @@ -352,11 +356,11 @@ msgstr "" msgid "Adjust the volume" msgstr "" -#: src/librarypanel.py:419 +#: src/librarypanel.py:421 msgid "Loading albums" msgstr "" -#: src/librarypanel.py:519 +#: src/librarypanel.py:521 msgid "Loading images" msgstr "" diff --git a/src/client.py b/src/client.py index 3929d26..cc043d8 100644 --- a/src/client.py +++ b/src/client.py @@ -3,6 +3,7 @@ import concurrent.futures import configparser +import dateutil.parser import logging import os import queue @@ -937,6 +938,8 @@ class Client(Base): track.set_date(song['date']) if 'albumartist' in song: track.set_albumartists(song['albumartist']) + if 'last-modified' in song: + track.set_last_modified(song['last-modified']) return track @@ -998,6 +1001,7 @@ class MCGAlbum: self._host = host self._tracks = [] self._length = 0 + self._last_modified = None self._id = Utils.generate_id(title) @@ -1057,6 +1061,9 @@ class MCGAlbum: path = os.path.dirname(track.get_file()) if path not in self._pathes: self._pathes.append(path) + if track.get_last_modified(): + if not self._last_modified or track.get_last_modified() > self._last_modified: + self._last_modified = track.get_last_modified() def get_tracks(self): @@ -1067,6 +1074,10 @@ class MCGAlbum: return self._length + def get_last_modified(self): + return self._last_modified + + def filter(self, filter_string): if len(filter_string) == 0: return True @@ -1102,6 +1113,8 @@ class MCGAlbum: value_function = "get_title" elif criterion == SortOrder.YEAR: value_function = "get_date" + elif criterion == SortOrder.MODIFIED: + value_function = "get_last_modified" value1 = getattr(album1, value_function)() value2 = getattr(album2, value_function)() @@ -1137,6 +1150,7 @@ class MCGTrack: self._track = None self._length = 0 self._date = None + self._last_modified = None def __eq__(self, other): @@ -1208,6 +1222,18 @@ class MCGTrack: return self._file + def set_last_modified(self, date_string): + if date_string: + try: + self._last_modified = dateutil.parser.isoparse(date_string) + except ValueError as e: + self._logger.debug("Invalid date format: %s", date_string) + + + def get_last_modified(self): + return self._last_modified + + class MCGPlaylistTrack(MCGTrack): diff --git a/src/librarypanel.py b/src/librarypanel.py index 48b5342..2626c7b 100644 --- a/src/librarypanel.py +++ b/src/librarypanel.py @@ -39,6 +39,7 @@ class LibraryToolbar(Gtk.ButtonBox): sort_artist = Gtk.Template.Child() sort_title = Gtk.Template.Child() sort_year = Gtk.Template.Child() + sort_modified = Gtk.Template.Child() grid_scale = Gtk.Template.Child() @@ -50,7 +51,8 @@ class LibraryToolbar(Gtk.ButtonBox): self._toolbar_sort_buttons = { SortOrder.ARTIST: self.sort_artist, SortOrder.TITLE: self.sort_title, - SortOrder.YEAR: self.sort_year + SortOrder.YEAR: self.sort_year, + SortOrder.MODIFIED: self.sort_modified } diff --git a/src/utils.py b/src/utils.py index 713c85c..e5a08bd 100644 --- a/src/utils.py +++ b/src/utils.py @@ -86,3 +86,4 @@ class SortOrder: ARTIST = 0 TITLE = 1 YEAR = 2 + MODIFIED = 3