Skip to content

Commit 0916258

Browse files
Greatly improved detection of media player name
1 parent ad006b4 commit 0916258

File tree

6 files changed

+155
-54
lines changed

6 files changed

+155
-54
lines changed

CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
cmake_minimum_required(VERSION 3.1.0) # Threads::Threads
22

33
project(fastfetch
4-
VERSION 1.0.0
4+
VERSION 1.1.0
55
LANGUAGES C
66
)
77

8-
#e.g. -alpha or -beta or +1
8+
#e.g. +1
99
#This allows to track builds between versions, without GitHub creating a new release
10-
set(PROJECT_VERSION_EXTRA "+1")
10+
set(PROJECT_VERSION_EXTRA "")
1111

1212
include(GNUInstallDirs)
1313

src/detection/media.c

Lines changed: 133 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
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

242291
static 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
}

src/fastfetch.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -304,16 +304,19 @@ static inline void printCommandHelp(const char* command)
304304
}
305305
else if(strcasecmp(command, "player-format") == 0)
306306
{
307-
constructAndPrintCommandHelpFormat("player", "{}", 1,
308-
"Player name"
307+
constructAndPrintCommandHelpFormat("player", "{}", 3,
308+
"Pretty player name",
309+
"Player name",
310+
"DBus bus name"
309311
);
310312
}
311313
else if(strcasecmp(command, "song-format") == 0)
312314
{
313-
constructAndPrintCommandHelpFormat("song", "{2} - {3} - {1}", 3,
315+
constructAndPrintCommandHelpFormat("song", "{2} - {3} - {1}", 4,
314316
"Song name",
315317
"Artist name",
316-
"Album name"
318+
"Album name",
319+
"Song url"
317320
);
318321
}
319322
else if(strcasecmp(command, "datetime-format") == 0 || strcasecmp(command, "date-format") == 0 || strcasecmp(command, "time-format") == 0)

src/fastfetch.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,10 +257,13 @@ typedef struct FFTempsResult
257257

258258
typedef struct FFMediaResult
259259
{
260-
FFstrbuf player;
260+
FFstrbuf busNameShort; //e.g. plasma-browser-integration
261+
FFstrbuf player; // e.g. Google Chrome
262+
FFstrbuf playerPretty; // e.g. YouTube (Google Chrome)
261263
FFstrbuf song;
262264
FFstrbuf artist;
263265
FFstrbuf album;
266+
FFstrbuf url;
264267
} FFMediaResult;
265268

266269
typedef struct FFDateTimeResult

0 commit comments

Comments
 (0)