mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-10-29 16:26:39 +01:00
Greatly improved detection of media player name
This commit is contained in:
+3
-3
@@ -1,13 +1,13 @@
|
||||
cmake_minimum_required(VERSION 3.1.0) # Threads::Threads
|
||||
|
||||
project(fastfetch
|
||||
VERSION 1.0.0
|
||||
VERSION 1.1.0
|
||||
LANGUAGES C
|
||||
)
|
||||
|
||||
#e.g. -alpha or -beta or +1
|
||||
#e.g. +1
|
||||
#This allows to track builds between versions, without GitHub creating a new release
|
||||
set(PROJECT_VERSION_EXTRA "+1")
|
||||
set(PROJECT_VERSION_EXTRA "")
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
|
||||
+133
-41
@@ -1,5 +1,6 @@
|
||||
#include "fastfetch.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
|
||||
@@ -53,20 +54,25 @@ static bool getValue(DBusMessageIter* iter, FFstrbuf* result, DBusData* data)
|
||||
return true;
|
||||
}
|
||||
|
||||
if(argType != DBUS_TYPE_ARRAY)
|
||||
if(argType != DBUS_TYPE_VARIANT && argType != DBUS_TYPE_ARRAY)
|
||||
return false;
|
||||
|
||||
DBusMessageIter arrayIter;
|
||||
data->ffdbus_message_iter_recurse(iter, &arrayIter);
|
||||
DBusMessageIter subIter;
|
||||
data->ffdbus_message_iter_recurse(iter, &subIter);
|
||||
|
||||
if(argType == DBUS_TYPE_VARIANT)
|
||||
return getValue(&subIter, result, data);
|
||||
|
||||
//At this point we have an array
|
||||
|
||||
bool foundAValue = false;
|
||||
|
||||
while(true)
|
||||
{
|
||||
if((foundAValue = getValue(&arrayIter, result, data)))
|
||||
if((foundAValue = getValue(&subIter, result, data)))
|
||||
ffStrbufAppendS(result, ", ");
|
||||
|
||||
FF_DBUS_ITER_CONTINUE(arrayIter);
|
||||
FF_DBUS_ITER_CONTINUE(subIter);
|
||||
}
|
||||
|
||||
if(foundAValue)
|
||||
@@ -75,51 +81,87 @@ static bool getValue(DBusMessageIter* iter, FFstrbuf* result, DBusData* data)
|
||||
return foundAValue;
|
||||
}
|
||||
|
||||
static bool detectSong(const char* player, FFMediaResult* result, DBusData* data)
|
||||
static DBusMessage* getProperty(const char* busName, const char* objectPath, const char* interface, const char* property, DBusData* data)
|
||||
{
|
||||
DBusMessage* message = data->ffdbus_message_new_method_call(player, "/org/mpris/MediaPlayer2", "org.freedesktop.DBus.Properties", "Get");
|
||||
DBusMessage* message = data->ffdbus_message_new_method_call(busName, objectPath, "org.freedesktop.DBus.Properties", "Get");
|
||||
if(message == NULL)
|
||||
return false;
|
||||
return NULL;
|
||||
|
||||
DBusMessageIter requestIterator;
|
||||
data->ffdbus_message_iter_init_append(message, &requestIterator);
|
||||
|
||||
const char* arg1 = "org.mpris.MediaPlayer2.Player";
|
||||
if(!data->ffdbus_message_iter_append_basic(&requestIterator, DBUS_TYPE_STRING, &arg1))
|
||||
if(!data->ffdbus_message_iter_append_basic(&requestIterator, DBUS_TYPE_STRING, &interface))
|
||||
{
|
||||
data->ffdbus_message_unref(message);
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* arg2 = "Metadata";
|
||||
if(!data->ffdbus_message_iter_append_basic(&requestIterator, DBUS_TYPE_STRING, &arg2))
|
||||
if(!data->ffdbus_message_iter_append_basic(&requestIterator, DBUS_TYPE_STRING, &property))
|
||||
{
|
||||
data->ffdbus_message_unref(message);
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DBusPendingCall* pending;
|
||||
bool sendSuccessfull = data->ffdbus_connection_send_with_reply(data->connection, message, &pending, DBUS_TIMEOUT_USE_DEFAULT);
|
||||
data->ffdbus_message_unref(message);
|
||||
if(pending == NULL || !sendSuccessfull)
|
||||
return false;
|
||||
return NULL;
|
||||
|
||||
data->ffdbus_connection_flush(data->connection);
|
||||
data->ffdbus_pending_call_block(pending);
|
||||
|
||||
DBusMessage* reply = data->ffdbus_pending_call_steal_reply(pending);
|
||||
|
||||
data->ffdbus_pending_call_unref(pending);
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
static void getPropertyString(const char* busName, const char* objectPath, const char* interface, const char* property, FFstrbuf* result, DBusData* data)
|
||||
{
|
||||
DBusMessage* reply = getProperty(busName, objectPath, interface, property, data);
|
||||
if(reply == NULL)
|
||||
return;
|
||||
|
||||
DBusMessageIter rootIterator;
|
||||
if(!data->ffdbus_message_iter_init(reply, &rootIterator))
|
||||
{
|
||||
data->ffdbus_message_unref(reply);
|
||||
return;
|
||||
}
|
||||
|
||||
getValue(&rootIterator, result, data);
|
||||
|
||||
data->ffdbus_message_unref(reply);
|
||||
}
|
||||
|
||||
static bool getBusProperties(const char* busName, FFMediaResult* result, DBusData* data)
|
||||
{
|
||||
DBusMessage* reply = getProperty(busName, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player", "Metadata", data);
|
||||
if(reply == NULL)
|
||||
return false;
|
||||
|
||||
DBusMessageIter rootIterator;
|
||||
if(!data->ffdbus_message_iter_init(reply, &rootIterator) || data->ffdbus_message_iter_get_arg_type(&rootIterator) != DBUS_TYPE_VARIANT)
|
||||
if(!data->ffdbus_message_iter_init(reply, &rootIterator))
|
||||
{
|
||||
data->ffdbus_message_unref(reply);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(data->ffdbus_message_iter_get_arg_type(&rootIterator) != DBUS_TYPE_VARIANT)
|
||||
{
|
||||
data->ffdbus_message_unref(reply);
|
||||
return false;
|
||||
}
|
||||
|
||||
DBusMessageIter variantIterator;
|
||||
data->ffdbus_message_iter_recurse(&rootIterator, &variantIterator);
|
||||
if(data->ffdbus_message_iter_get_arg_type(&variantIterator) != DBUS_TYPE_ARRAY)
|
||||
{
|
||||
data->ffdbus_message_unref(reply);
|
||||
return false;
|
||||
}
|
||||
|
||||
DBusMessageIter arrayIterator;
|
||||
data->ffdbus_message_iter_recurse(&variantIterator, &arrayIterator);
|
||||
@@ -143,18 +185,14 @@ static bool detectSong(const char* player, FFMediaResult* result, DBusData* data
|
||||
|
||||
data->ffdbus_message_iter_next(&dictIterator);
|
||||
|
||||
if(data->ffdbus_message_iter_get_arg_type(&dictIterator) != DBUS_TYPE_VARIANT)
|
||||
FF_DBUS_ITER_CONTINUE(arrayIterator)
|
||||
|
||||
DBusMessageIter valueIter;
|
||||
data->ffdbus_message_iter_recurse(&dictIterator, &valueIter);
|
||||
|
||||
if(strcmp(key, "xesam:title") == 0)
|
||||
getValue(&valueIter, &result->song, data);
|
||||
getValue(&dictIterator, &result->song, data);
|
||||
else if(strcmp(key, "xesam:album") == 0)
|
||||
getValue(&valueIter, &result->album, data);
|
||||
getValue(&dictIterator, &result->album, data);
|
||||
else if(strcmp(key, "xesam:artist") == 0)
|
||||
getValue(&valueIter, &result->artist, data);
|
||||
getValue(&dictIterator, &result->artist, data);
|
||||
else if(strcmp(key, "xesam:url") == 0)
|
||||
getValue(&dictIterator, &result->url, data);
|
||||
|
||||
if(result->song.length > 0 && result->artist.length > 0 && result->album.length > 0)
|
||||
break;
|
||||
@@ -162,6 +200,8 @@ static bool detectSong(const char* player, FFMediaResult* result, DBusData* data
|
||||
FF_DBUS_ITER_CONTINUE(arrayIterator)
|
||||
}
|
||||
|
||||
data->ffdbus_message_unref(reply);
|
||||
|
||||
if(result->song.length == 0)
|
||||
{
|
||||
ffStrbufClear(&result->artist);
|
||||
@@ -169,29 +209,36 @@ static bool detectSong(const char* player, FFMediaResult* result, DBusData* data
|
||||
return false;
|
||||
}
|
||||
|
||||
//We found a song, get the player name
|
||||
|
||||
getPropertyString(busName, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2", "Identity", &result->player, data);
|
||||
|
||||
if(result->player.length == 0)
|
||||
getPropertyString(busName, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2", "DesktopEntry", &result->player, data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void getCustomPlayer(FFinstance* instance, FFMediaResult* result, DBusData* data)
|
||||
static void getCustomBus(FFinstance* instance, FFMediaResult* result, DBusData* data)
|
||||
{
|
||||
if(ffStrbufStartsWithS(&instance->config.playerName, FF_DBUS_MPRIS_PREFIX))
|
||||
{
|
||||
detectSong(instance->config.playerName.chars, result, data);
|
||||
ffStrbufAppendS(&result->player, instance->config.playerName.chars + sizeof(FF_DBUS_MPRIS_PREFIX) - 1);
|
||||
ffStrbufAppendS(&result->busNameShort, instance->config.playerName.chars + sizeof(FF_DBUS_MPRIS_PREFIX) - 1);
|
||||
getBusProperties(instance->config.playerName.chars, result, data);
|
||||
return;
|
||||
}
|
||||
|
||||
ffStrbufAppend(&result->busNameShort, &instance->config.playerName);
|
||||
|
||||
FFstrbuf busName;
|
||||
ffStrbufInit(&busName);
|
||||
ffStrbufAppendS(&busName, FF_DBUS_MPRIS_PREFIX);
|
||||
ffStrbufAppend(&busName, &instance->config.playerName);
|
||||
detectSong(busName.chars, result, data);
|
||||
getBusProperties(busName.chars, result, data);
|
||||
ffStrbufDestroy(&busName);
|
||||
|
||||
ffStrbufAppend(&result->player, &instance->config.playerName);
|
||||
}
|
||||
|
||||
static void getBestPlayer(FFMediaResult* result, DBusData* data)
|
||||
static void getBestBus(FFMediaResult* result, DBusData* data)
|
||||
{
|
||||
DBusMessage* message = data->ffdbus_message_new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "ListNames");
|
||||
if(message == NULL)
|
||||
@@ -223,20 +270,22 @@ static void getBestPlayer(FFMediaResult* result, DBusData* data)
|
||||
if(data->ffdbus_message_iter_get_arg_type(&arrayIterator) != DBUS_TYPE_STRING)
|
||||
FF_DBUS_ITER_CONTINUE(arrayIterator)
|
||||
|
||||
const char* name;
|
||||
data->ffdbus_message_iter_get_basic(&arrayIterator, &name);
|
||||
const char* busName;
|
||||
data->ffdbus_message_iter_get_basic(&arrayIterator, &busName);
|
||||
|
||||
if(strncmp(name, FF_DBUS_MPRIS_PREFIX, sizeof(FF_DBUS_MPRIS_PREFIX) - 1) != 0)
|
||||
if(strncmp(busName, FF_DBUS_MPRIS_PREFIX, sizeof(FF_DBUS_MPRIS_PREFIX) - 1) != 0)
|
||||
FF_DBUS_ITER_CONTINUE(arrayIterator)
|
||||
|
||||
if(detectSong(name, result, data))
|
||||
if(getBusProperties(busName, result, data))
|
||||
{
|
||||
ffStrbufAppendS(&result->player, name + sizeof(FF_DBUS_MPRIS_PREFIX) - 1);
|
||||
ffStrbufAppendS(&result->busNameShort, busName + sizeof(FF_DBUS_MPRIS_PREFIX) - 1);
|
||||
break;
|
||||
}
|
||||
|
||||
FF_DBUS_ITER_CONTINUE(arrayIterator)
|
||||
}
|
||||
|
||||
data->ffdbus_message_unref(reply);
|
||||
}
|
||||
|
||||
static void getMedia(FFinstance* instance, FFMediaResult* result)
|
||||
@@ -269,9 +318,9 @@ static void getMedia(FFinstance* instance, FFMediaResult* result)
|
||||
}
|
||||
|
||||
if(instance->config.playerName.length > 0)
|
||||
getCustomPlayer(instance, result, &data);
|
||||
getCustomBus(instance, result, &data);
|
||||
else
|
||||
getBestPlayer(result, &data);
|
||||
getBestBus(result, &data);
|
||||
|
||||
dlclose(dbus);
|
||||
}
|
||||
@@ -292,23 +341,66 @@ const FFMediaResult* ffDetectMedia(FFinstance* instance)
|
||||
}
|
||||
init = true;
|
||||
|
||||
ffStrbufInit(&result.busNameShort);
|
||||
ffStrbufInit(&result.player);
|
||||
ffStrbufInit(&result.playerPretty);
|
||||
ffStrbufInit(&result.song);
|
||||
ffStrbufInit(&result.artist);
|
||||
ffStrbufInit(&result.album);
|
||||
ffStrbufInit(&result.url);
|
||||
|
||||
#ifdef FF_HAVE_DBUS
|
||||
getMedia(instance, &result);
|
||||
#endif
|
||||
|
||||
//Set busNameShort if a custom player was given, but loading dbus failed
|
||||
if(instance->config.playerName.length > 0 && result.player.length == 0)
|
||||
{
|
||||
if(ffStrbufStartsWithS(&instance->config.playerName, FF_DBUS_MPRIS_PREFIX))
|
||||
ffStrbufAppendS(&result.player, instance->config.playerName.chars + sizeof(FF_DBUS_MPRIS_PREFIX) - 1);
|
||||
ffStrbufAppendS(&result.busNameShort, instance->config.playerName.chars + sizeof(FF_DBUS_MPRIS_PREFIX) - 1);
|
||||
else
|
||||
ffStrbufAppend(&result.player, &instance->config.playerName);
|
||||
ffStrbufAppend(&result.busNameShort, &instance->config.playerName);
|
||||
}
|
||||
|
||||
//Set player to busNameShort, if detection failed
|
||||
if(result.player.length == 0)
|
||||
ffStrbufAppend(&result.player, &result.busNameShort);
|
||||
|
||||
//If we are on a website, prepend the website name
|
||||
if(ffStrbufStartsWithS(&result.url, "https://www.")) {
|
||||
ffStrbufAppendS(&result.playerPretty, result.url.chars + 12);
|
||||
}
|
||||
else if(ffStrbufStartsWithS(&result.url, "http://www.")) {
|
||||
ffStrbufAppendS(&result.playerPretty, result.url.chars + 11);
|
||||
}
|
||||
else if(ffStrbufStartsWithS(&result.url, "https://")) {
|
||||
ffStrbufAppendS(&result.playerPretty, result.url.chars + 8);
|
||||
}
|
||||
else if(ffStrbufStartsWithS(&result.url, "http://")) {
|
||||
ffStrbufAppendS(&result.playerPretty, result.url.chars + 7);
|
||||
}
|
||||
|
||||
//If we found a website name, make it more pretty
|
||||
if(result.playerPretty.length > 0)
|
||||
{
|
||||
ffStrbufSubstrBeforeFirstC(&result.playerPretty, '/'); //Remove the path
|
||||
ffStrbufSubstrBeforeLastC(&result.playerPretty, '.'); //Remove the TLD
|
||||
}
|
||||
|
||||
//We may have removed everything
|
||||
bool hasCustomPrettyName = result.playerPretty.length > 0;
|
||||
|
||||
if(hasCustomPrettyName)
|
||||
{
|
||||
result.playerPretty.chars[0] = (char) toupper(result.playerPretty.chars[0]);
|
||||
ffStrbufAppendS(&result.playerPretty, " (");
|
||||
}
|
||||
|
||||
ffStrbufAppend(&result.playerPretty, &result.player);
|
||||
|
||||
if(hasCustomPrettyName)
|
||||
ffStrbufAppendC(&result.playerPretty, ')');
|
||||
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return &result;
|
||||
}
|
||||
|
||||
+7
-4
@@ -304,16 +304,19 @@ static inline void printCommandHelp(const char* command)
|
||||
}
|
||||
else if(strcasecmp(command, "player-format") == 0)
|
||||
{
|
||||
constructAndPrintCommandHelpFormat("player", "{}", 1,
|
||||
"Player name"
|
||||
constructAndPrintCommandHelpFormat("player", "{}", 3,
|
||||
"Pretty player name",
|
||||
"Player name",
|
||||
"DBus bus name"
|
||||
);
|
||||
}
|
||||
else if(strcasecmp(command, "song-format") == 0)
|
||||
{
|
||||
constructAndPrintCommandHelpFormat("song", "{2} - {3} - {1}", 3,
|
||||
constructAndPrintCommandHelpFormat("song", "{2} - {3} - {1}", 4,
|
||||
"Song name",
|
||||
"Artist name",
|
||||
"Album name"
|
||||
"Album name",
|
||||
"Song url"
|
||||
);
|
||||
}
|
||||
else if(strcasecmp(command, "datetime-format") == 0 || strcasecmp(command, "date-format") == 0 || strcasecmp(command, "time-format") == 0)
|
||||
|
||||
+4
-1
@@ -257,10 +257,13 @@ typedef struct FFTempsResult
|
||||
|
||||
typedef struct FFMediaResult
|
||||
{
|
||||
FFstrbuf player;
|
||||
FFstrbuf busNameShort; //e.g. plasma-browser-integration
|
||||
FFstrbuf player; // e.g. Google Chrome
|
||||
FFstrbuf playerPretty; // e.g. YouTube (Google Chrome)
|
||||
FFstrbuf song;
|
||||
FFstrbuf artist;
|
||||
FFstrbuf album;
|
||||
FFstrbuf url;
|
||||
} FFMediaResult;
|
||||
|
||||
typedef struct FFDateTimeResult
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "fastfetch.h"
|
||||
|
||||
#define FF_PLAYER_MODULE_NAME "Media Player"
|
||||
#define FF_PLAYER_NUM_FORMAT_ARGS 1
|
||||
#define FF_PLAYER_NUM_FORMAT_ARGS 3
|
||||
|
||||
void ffPrintPlayer(FFinstance* instance)
|
||||
{
|
||||
@@ -16,12 +16,14 @@ void ffPrintPlayer(FFinstance* instance)
|
||||
if(instance->config.playerFormat.length == 0)
|
||||
{
|
||||
ffPrintLogoAndKey(instance, FF_PLAYER_MODULE_NAME, 0, &instance->config.playerKey);
|
||||
ffStrbufPutTo(&media->player, stdout);
|
||||
ffStrbufPutTo(&media->playerPretty, stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
ffPrintFormatString(instance, FF_PLAYER_MODULE_NAME, 0, &instance->config.playerKey, &instance->config.playerFormat, NULL, FF_PLAYER_NUM_FORMAT_ARGS, (FFformatarg[]){
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &media->player}
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &media->playerPretty},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &media->player},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &media->busNameShort}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -1,7 +1,7 @@
|
||||
#include "fastfetch.h"
|
||||
|
||||
#define FF_SONG_MODULE_NAME "Song"
|
||||
#define FF_SONG_NUM_FORMAT_ARGS 3
|
||||
#define FF_SONG_NUM_FORMAT_ARGS 4
|
||||
|
||||
void ffPrintSong(FFinstance* instance)
|
||||
{
|
||||
@@ -36,7 +36,8 @@ void ffPrintSong(FFinstance* instance)
|
||||
ffPrintFormatString(instance, FF_SONG_MODULE_NAME, 0, &instance->config.songKey, &instance->config.songFormat, NULL, FF_SONG_NUM_FORMAT_ARGS, (FFformatarg[]){
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &media->song},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &media->artist},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &media->album}
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &media->album},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &media->url}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user