11#include "fastfetch.h"
22
3+ #include <ctype.h>
34#include <string.h>
45#include <pthread.h>
56
@@ -53,20 +54,25 @@ static bool getValue(DBusMessageIter* iter, FFstrbuf* result, DBusData* data)
5354 return true;
5455 }
5556
56- if (argType != DBUS_TYPE_ARRAY )
57+ if (argType != DBUS_TYPE_VARIANT && argType != DBUS_TYPE_ARRAY )
5758 return false;
5859
59- DBusMessageIter arrayIter ;
60- data -> ffdbus_message_iter_recurse (iter , & arrayIter );
60+ DBusMessageIter subIter ;
61+ data -> ffdbus_message_iter_recurse (iter , & subIter );
62+
63+ if (argType == DBUS_TYPE_VARIANT )
64+ return getValue (& subIter , result , data );
65+
66+ //At this point we have an array
6167
6268 bool foundAValue = false;
6369
6470 while (true)
6571 {
66- if ((foundAValue = getValue (& arrayIter , result , data )))
72+ if ((foundAValue = getValue (& subIter , result , data )))
6773 ffStrbufAppendS (result , ", " );
6874
69- FF_DBUS_ITER_CONTINUE (arrayIter );
75+ FF_DBUS_ITER_CONTINUE (subIter );
7076 }
7177
7278 if (foundAValue )
@@ -75,51 +81,87 @@ static bool getValue(DBusMessageIter* iter, FFstrbuf* result, DBusData* data)
7581 return foundAValue ;
7682}
7783
78- static bool detectSong (const char * player , FFMediaResult * result , DBusData * data )
84+ static DBusMessage * getProperty (const char * busName , const char * objectPath , const char * interface , const char * property , DBusData * data )
7985{
80- DBusMessage * message = data -> ffdbus_message_new_method_call (player , "/org/mpris/MediaPlayer2" , "org.freedesktop.DBus.Properties" , "Get" );
86+ DBusMessage * message = data -> ffdbus_message_new_method_call (busName , objectPath , "org.freedesktop.DBus.Properties" , "Get" );
8187 if (message == NULL )
82- return false ;
88+ return NULL ;
8389
8490 DBusMessageIter requestIterator ;
8591 data -> ffdbus_message_iter_init_append (message , & requestIterator );
8692
87- const char * arg1 = "org.mpris.MediaPlayer2.Player" ;
88- if (!data -> ffdbus_message_iter_append_basic (& requestIterator , DBUS_TYPE_STRING , & arg1 ))
93+ if (!data -> ffdbus_message_iter_append_basic (& requestIterator , DBUS_TYPE_STRING , & interface ))
8994 {
9095 data -> ffdbus_message_unref (message );
91- return false ;
96+ return NULL ;
9297 }
9398
94- const char * arg2 = "Metadata" ;
95- if (!data -> ffdbus_message_iter_append_basic (& requestIterator , DBUS_TYPE_STRING , & arg2 ))
99+ if (!data -> ffdbus_message_iter_append_basic (& requestIterator , DBUS_TYPE_STRING , & property ))
96100 {
97101 data -> ffdbus_message_unref (message );
98- return false ;
102+ return NULL ;
99103 }
100104
101105 DBusPendingCall * pending ;
102106 bool sendSuccessfull = data -> ffdbus_connection_send_with_reply (data -> connection , message , & pending , DBUS_TIMEOUT_USE_DEFAULT );
103107 data -> ffdbus_message_unref (message );
104108 if (pending == NULL || !sendSuccessfull )
105- return false ;
109+ return NULL ;
106110
107111 data -> ffdbus_connection_flush (data -> connection );
108112 data -> ffdbus_pending_call_block (pending );
109113
110114 DBusMessage * reply = data -> ffdbus_pending_call_steal_reply (pending );
115+
111116 data -> ffdbus_pending_call_unref (pending );
117+
118+ return reply ;
119+ }
120+
121+ static void getPropertyString (const char * busName , const char * objectPath , const char * interface , const char * property , FFstrbuf * result , DBusData * data )
122+ {
123+ DBusMessage * reply = getProperty (busName , objectPath , interface , property , data );
124+ if (reply == NULL )
125+ return ;
126+
127+ DBusMessageIter rootIterator ;
128+ if (!data -> ffdbus_message_iter_init (reply , & rootIterator ))
129+ {
130+ data -> ffdbus_message_unref (reply );
131+ return ;
132+ }
133+
134+ getValue (& rootIterator , result , data );
135+
136+ data -> ffdbus_message_unref (reply );
137+ }
138+
139+ static bool getBusProperties (const char * busName , FFMediaResult * result , DBusData * data )
140+ {
141+ DBusMessage * reply = getProperty (busName , "/org/mpris/MediaPlayer2" , "org.mpris.MediaPlayer2.Player" , "Metadata" , data );
112142 if (reply == NULL )
113143 return false;
114144
115145 DBusMessageIter rootIterator ;
116- if (!data -> ffdbus_message_iter_init (reply , & rootIterator ) || data -> ffdbus_message_iter_get_arg_type (& rootIterator ) != DBUS_TYPE_VARIANT )
146+ if (!data -> ffdbus_message_iter_init (reply , & rootIterator ))
147+ {
148+ data -> ffdbus_message_unref (reply );
149+ return false;
150+ }
151+
152+ if (data -> ffdbus_message_iter_get_arg_type (& rootIterator ) != DBUS_TYPE_VARIANT )
153+ {
154+ data -> ffdbus_message_unref (reply );
117155 return false;
156+ }
118157
119158 DBusMessageIter variantIterator ;
120159 data -> ffdbus_message_iter_recurse (& rootIterator , & variantIterator );
121160 if (data -> ffdbus_message_iter_get_arg_type (& variantIterator ) != DBUS_TYPE_ARRAY )
161+ {
162+ data -> ffdbus_message_unref (reply );
122163 return false;
164+ }
123165
124166 DBusMessageIter arrayIterator ;
125167 data -> ffdbus_message_iter_recurse (& variantIterator , & arrayIterator );
@@ -143,55 +185,60 @@ static bool detectSong(const char* player, FFMediaResult* result, DBusData* data
143185
144186 data -> ffdbus_message_iter_next (& dictIterator );
145187
146- if (data -> ffdbus_message_iter_get_arg_type (& dictIterator ) != DBUS_TYPE_VARIANT )
147- FF_DBUS_ITER_CONTINUE (arrayIterator )
148-
149- DBusMessageIter valueIter ;
150- data -> ffdbus_message_iter_recurse (& dictIterator , & valueIter );
151-
152188 if (strcmp (key , "xesam:title" ) == 0 )
153- getValue (& valueIter , & result -> song , data );
189+ getValue (& dictIterator , & result -> song , data );
154190 else if (strcmp (key , "xesam:album" ) == 0 )
155- getValue (& valueIter , & result -> album , data );
191+ getValue (& dictIterator , & result -> album , data );
156192 else if (strcmp (key , "xesam:artist" ) == 0 )
157- getValue (& valueIter , & result -> artist , data );
193+ getValue (& dictIterator , & result -> artist , data );
194+ else if (strcmp (key , "xesam:url" ) == 0 )
195+ getValue (& dictIterator , & result -> url , data );
158196
159197 if (result -> song .length > 0 && result -> artist .length > 0 && result -> album .length > 0 )
160198 break ;
161199
162200 FF_DBUS_ITER_CONTINUE (arrayIterator )
163201 }
164202
203+ data -> ffdbus_message_unref (reply );
204+
165205 if (result -> song .length == 0 )
166206 {
167207 ffStrbufClear (& result -> artist );
168208 ffStrbufClear (& result -> album );
169209 return false;
170210 }
171211
212+ //We found a song, get the player name
213+
214+ getPropertyString (busName , "/org/mpris/MediaPlayer2" , "org.mpris.MediaPlayer2" , "Identity" , & result -> player , data );
215+
216+ if (result -> player .length == 0 )
217+ getPropertyString (busName , "/org/mpris/MediaPlayer2" , "org.mpris.MediaPlayer2" , "DesktopEntry" , & result -> player , data );
218+
172219 return true;
173220}
174221
175- static void getCustomPlayer (FFinstance * instance , FFMediaResult * result , DBusData * data )
222+ static void getCustomBus (FFinstance * instance , FFMediaResult * result , DBusData * data )
176223{
177224 if (ffStrbufStartsWithS (& instance -> config .playerName , FF_DBUS_MPRIS_PREFIX ))
178225 {
179- detectSong ( instance -> config .playerName .chars , result , data );
180- ffStrbufAppendS ( & result -> player , instance -> config .playerName .chars + sizeof ( FF_DBUS_MPRIS_PREFIX ) - 1 );
226+ ffStrbufAppendS ( & result -> busNameShort , instance -> config .playerName .chars + sizeof ( FF_DBUS_MPRIS_PREFIX ) - 1 );
227+ getBusProperties ( instance -> config .playerName .chars , result , data );
181228 return ;
182229 }
183230
231+ ffStrbufAppend (& result -> busNameShort , & instance -> config .playerName );
232+
184233 FFstrbuf busName ;
185234 ffStrbufInit (& busName );
186235 ffStrbufAppendS (& busName , FF_DBUS_MPRIS_PREFIX );
187236 ffStrbufAppend (& busName , & instance -> config .playerName );
188- detectSong (busName .chars , result , data );
237+ getBusProperties (busName .chars , result , data );
189238 ffStrbufDestroy (& busName );
190-
191- ffStrbufAppend (& result -> player , & instance -> config .playerName );
192239}
193240
194- static void getBestPlayer (FFMediaResult * result , DBusData * data )
241+ static void getBestBus (FFMediaResult * result , DBusData * data )
195242{
196243 DBusMessage * message = data -> ffdbus_message_new_method_call ("org.freedesktop.DBus" , "/org/freedesktop/DBus" , "org.freedesktop.DBus" , "ListNames" );
197244 if (message == NULL )
@@ -223,20 +270,22 @@ static void getBestPlayer(FFMediaResult* result, DBusData* data)
223270 if (data -> ffdbus_message_iter_get_arg_type (& arrayIterator ) != DBUS_TYPE_STRING )
224271 FF_DBUS_ITER_CONTINUE (arrayIterator )
225272
226- const char * name ;
227- data -> ffdbus_message_iter_get_basic (& arrayIterator , & name );
273+ const char * busName ;
274+ data -> ffdbus_message_iter_get_basic (& arrayIterator , & busName );
228275
229- if (strncmp (name , FF_DBUS_MPRIS_PREFIX , sizeof (FF_DBUS_MPRIS_PREFIX ) - 1 ) != 0 )
276+ if (strncmp (busName , FF_DBUS_MPRIS_PREFIX , sizeof (FF_DBUS_MPRIS_PREFIX ) - 1 ) != 0 )
230277 FF_DBUS_ITER_CONTINUE (arrayIterator )
231278
232- if (detectSong ( name , result , data ))
279+ if (getBusProperties ( busName , result , data ))
233280 {
234- ffStrbufAppendS (& result -> player , name + sizeof (FF_DBUS_MPRIS_PREFIX ) - 1 );
281+ ffStrbufAppendS (& result -> busNameShort , busName + sizeof (FF_DBUS_MPRIS_PREFIX ) - 1 );
235282 break ;
236283 }
237284
238285 FF_DBUS_ITER_CONTINUE (arrayIterator )
239286 }
287+
288+ data -> ffdbus_message_unref (reply );
240289}
241290
242291static void getMedia (FFinstance * instance , FFMediaResult * result )
@@ -269,9 +318,9 @@ static void getMedia(FFinstance* instance, FFMediaResult* result)
269318 }
270319
271320 if (instance -> config .playerName .length > 0 )
272- getCustomPlayer (instance , result , & data );
321+ getCustomBus (instance , result , & data );
273322 else
274- getBestPlayer (result , & data );
323+ getBestBus (result , & data );
275324
276325 dlclose (dbus );
277326}
@@ -292,23 +341,66 @@ const FFMediaResult* ffDetectMedia(FFinstance* instance)
292341 }
293342 init = true;
294343
344+ ffStrbufInit (& result .busNameShort );
295345 ffStrbufInit (& result .player );
346+ ffStrbufInit (& result .playerPretty );
296347 ffStrbufInit (& result .song );
297348 ffStrbufInit (& result .artist );
298349 ffStrbufInit (& result .album );
350+ ffStrbufInit (& result .url );
299351
300352 #ifdef FF_HAVE_DBUS
301353 getMedia (instance , & result );
302354 #endif
303355
356+ //Set busNameShort if a custom player was given, but loading dbus failed
304357 if (instance -> config .playerName .length > 0 && result .player .length == 0 )
305358 {
306359 if (ffStrbufStartsWithS (& instance -> config .playerName , FF_DBUS_MPRIS_PREFIX ))
307- ffStrbufAppendS (& result .player , instance -> config .playerName .chars + sizeof (FF_DBUS_MPRIS_PREFIX ) - 1 );
360+ ffStrbufAppendS (& result .busNameShort , instance -> config .playerName .chars + sizeof (FF_DBUS_MPRIS_PREFIX ) - 1 );
308361 else
309- ffStrbufAppend (& result .player , & instance -> config .playerName );
362+ ffStrbufAppend (& result .busNameShort , & instance -> config .playerName );
363+ }
364+
365+ //Set player to busNameShort, if detection failed
366+ if (result .player .length == 0 )
367+ ffStrbufAppend (& result .player , & result .busNameShort );
368+
369+ //If we are on a website, prepend the website name
370+ if (ffStrbufStartsWithS (& result .url , "https://www." )) {
371+ ffStrbufAppendS (& result .playerPretty , result .url .chars + 12 );
372+ }
373+ else if (ffStrbufStartsWithS (& result .url , "http://www." )) {
374+ ffStrbufAppendS (& result .playerPretty , result .url .chars + 11 );
375+ }
376+ else if (ffStrbufStartsWithS (& result .url , "https://" )) {
377+ ffStrbufAppendS (& result .playerPretty , result .url .chars + 8 );
378+ }
379+ else if (ffStrbufStartsWithS (& result .url , "http://" )) {
380+ ffStrbufAppendS (& result .playerPretty , result .url .chars + 7 );
381+ }
382+
383+ //If we found a website name, make it more pretty
384+ if (result .playerPretty .length > 0 )
385+ {
386+ ffStrbufSubstrBeforeFirstC (& result .playerPretty , '/' ); //Remove the path
387+ ffStrbufSubstrBeforeLastC (& result .playerPretty , '.' ); //Remove the TLD
310388 }
311389
390+ //We may have removed everything
391+ bool hasCustomPrettyName = result .playerPretty .length > 0 ;
392+
393+ if (hasCustomPrettyName )
394+ {
395+ result .playerPretty .chars [0 ] = (char ) toupper (result .playerPretty .chars [0 ]);
396+ ffStrbufAppendS (& result .playerPretty , " (" );
397+ }
398+
399+ ffStrbufAppend (& result .playerPretty , & result .player );
400+
401+ if (hasCustomPrettyName )
402+ ffStrbufAppendC (& result .playerPretty , ')' );
403+
312404 pthread_mutex_unlock (& mutex );
313405 return & result ;
314406}
0 commit comments