diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..fbc626b --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,44 @@ +cmake_minimum_required(VERSION 3.16) + +set(CMAKE_C_STANDARD 17) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +project(ossp) + +find_package(CURL REQUIRED) +find_package(OpenSSL REQUIRED) +find_package(Qt6 REQUIRED COMPONENTS Core Widgets) + +qt_standard_project_setup() + +qt_add_executable(ossp + main.c + gui/gui_entry.cpp + gui/window.cpp + gui/songWidget.cpp + configHandler.c + libopensubsonic/crypto.c + libopensubsonic/httpclient.c + libopensubsonic/logger.c + libopensubsonic/utils.c + libopensubsonic/scrobble_lastFm.c + libopensubsonic/scrobble_listenBrainz.c + libopensubsonic/endpoint_getAlbum.c + libopensubsonic/endpoint_getAlbumList.c + libopensubsonic/endpoint_getArtist.c + libopensubsonic/endpoint_getArtists.c + libopensubsonic/endpoint_getLyricsBySongId.c + libopensubsonic/endpoint_getPlaylist.c + libopensubsonic/endpoint_getPlaylists.c + libopensubsonic/endpoint_getSong.c + libopensubsonic/endpoint_getStarred.c + libopensubsonic/endpoint_ping.c + libopensubsonic/endpoint_scrobble.c + external/cJSON.c + external/cJSON_Utils.c + external/libcurl_uriescape.c + external/md5.c +) + +target_link_libraries(ossp PRIVATE OpenSSL::SSL OpenSSL::Crypto CURL::libcurl Qt6::Core Qt6::Widgets) diff --git a/src/main.c b/src/main.c index d39ed0b..f059a81 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,7 @@ #include #include +#include +#include "gui/gui_entry.hpp" #include "libopensubsonic/logger.h" #include "libopensubsonic/crypto.h" #include "libopensubsonic/httpclient.h" @@ -7,26 +9,117 @@ #include "configHandler.h" configHandler_config_t* configObj = NULL; +int checkConfigFile(); +int validateConnection(); -int main() { +int main(int argc, char** argv) { int rc = 0; + // Read config file rc = configHandler_Read(&configObj); if (rc != 0) { printf("Could not read config file!\n"); return 1; } + + // Run check on the config file + rc = checkConfigFile(); + if (rc != 0) { + return 1; + } + + // Generate opensubsonic login opensubsonic_crypto_generateLogin(); - opensubsonic_httpClient_URL_t* url = malloc(sizeof(opensubsonic_httpClient_URL_t)); - opensubsonic_httpClient_URL_prepare(&url); - url->endpoint = OPENSUBSONIC_ENDPOINT_PING; - opensubsonic_httpClient_formUrl(&url); - printf("URL: %s\n", url->formedUrl); - opensubsonic_ping_struct* OSS_ping_struct; - opensubsonic_httpClient_fetchResponse(&url, (void**)&OSS_ping_struct); - printf("PING OK: %s\n", OSS_ping_struct->status); + // Check the config for the newly generated crypto salt/token + if (configObj->internal_opensubsonic_loginSalt == NULL || + configObj->internal_opensubsonic_loginToken == NULL) { + printf("Internal Failure: Could not generate OpenSubsonic Login Salt/Token.\n"); + return 1; + } + // Attempt connection + rc = validateConnection(); + if (rc != 0) { + return 1; + } + + // Launch QT frontend + qt_gui_entry(argc, argv); + + // Cleanup and exit configHandler_Free(&configObj); return 0; } + +int checkConfigFile() { + // Check for OpenSubsonic username and password + if (strlen(configObj->opensubsonic_username) == 0 || + strlen(configObj->opensubsonic_password) == 0) { + printf("OpenSubsonic username/password is empty.\n"); + return 1; + } + + // Check for OpenSubsonic protocol and server + if (strlen(configObj->opensubsonic_protocol) == 0 || + strlen(configObj->opensubsonic_server) == 0) { + printf("OpenSubsonic protocol/server is empty.\n"); + return 1; + } + + // Check for ListenBrainz scrobble config + if (configObj->listenbrainz_enable) { + if (strlen(configObj->listenbrainz_token) == 0) { + printf("ListenBrainz scrobbling is enabled, but token is empty.\n"); + return 1; + } + } + + // Check for LastFM scrobble config + if (configObj->lastfm_enable) { + if (strlen(configObj->lastfm_username) == 0 || + strlen(configObj->lastfm_password) == 0) { + printf("LastFM scrobbling is enabled, but username/password is empty.\n"); + return 1; + } + if (strlen(configObj->lastfm_api_key) == 0 || + strlen(configObj->lastfm_api_secret) == 0) { + printf("LastFM scrobbling is enabled, but API key/secret is empty.\n"); + return 1; + } + if (strlen(configObj->lastfm_api_session_key) == 0) { + printf("LastFM scrobbling is enabled, but API session key is empty.\n"); + return 1; + } + } + + return 0; +} + +int validateConnection() { + printf("Attempting to connect to /ping at %s://%s...\n", configObj->opensubsonic_protocol, configObj->opensubsonic_server); + opensubsonic_httpClient_URL_t* pingUrl = malloc(sizeof(opensubsonic_httpClient_URL_t)); + opensubsonic_httpClient_URL_prepare(&pingUrl); + pingUrl->endpoint = OPENSUBSONIC_ENDPOINT_PING; + opensubsonic_httpClient_formUrl(&pingUrl); + opensubsonic_ping_struct* OSS_ping_struct; + opensubsonic_httpClient_fetchResponse(&pingUrl, (void**)&OSS_ping_struct); + + if (!OSS_ping_struct->error) { + printf("Connection to %s://%s successful.\n", configObj->opensubsonic_protocol, configObj->opensubsonic_server); + printf("Server: %s %s.\n", OSS_ping_struct->serverType, OSS_ping_struct->serverVersion); + } else { + printf("Connection to %s://%s failed:\n", configObj->opensubsonic_protocol, configObj->opensubsonic_server); + printf("Code %d - %s\n", OSS_ping_struct->errorCode, OSS_ping_struct->errorMessage); + } + + if (!OSS_ping_struct->error) { + opensubsonic_ping_struct_free(&OSS_ping_struct); + opensubsonic_httpClient_URL_cleanup(&pingUrl); + return 0; + } else { + opensubsonic_ping_struct_free(&OSS_ping_struct); + opensubsonic_httpClient_URL_cleanup(&pingUrl); + return 1; + } +}