Skip to content

Commit

Permalink
[MED] ALPHA 1.9
Browse files Browse the repository at this point in the history
  • Loading branch information
nots1dd committed Jan 15, 2025
1 parent 37ed5c9 commit 950f575
Show file tree
Hide file tree
Showing 18 changed files with 69,821 additions and 72 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/codeql-inLimbo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
# Ensure any dependencies are installed before building
sudo apt-get update
sudo apt-get install -y build-essential cmake libtag1-dev git libglib2.0-dev # Example dependencies, modify as needed
sudo apt-get install -y build-essential cmake libtag1-dev git libglib2.0-dev imagemagick # Example dependencies, modify as needed
./init.sh
Expand Down
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -615,3 +615,36 @@ Small commit that may fix codeql CI issue, going for refactor + small feature up
- Runtime errors with respect to `PlayCurrentSong()` that may be due to detaching the audio thread

---

## [ALPHA 1.9] --- 14-01-2025

### Added
- Image Template processing kit `CImg.h` and `ftxui::image_view` component in `src/ui/components/` and `src/ui/components/libs`

- Thumbnail parsing function using taglib

### Changed
- New screen (SHOW_SONG_INFO_SCREEN) with thumbnail and currently playing song info with progress bar

- New field in `config.toml` to view song info screen (subsequent changes to `keymaps.hpp` and `ui_handler.hpp`)

- Modifications to build file (`CMakeLists.txt`) to include the component as library for proper linking

- Readme changes

- `imagemagick` is now a required dependency for the inLimbo project

### Fixed
**NIL**

### Removed
**NIL**

Medium commit with a new screen, I should really start to refactor now...

### Known Issues to fix in immediate commits
- Runtime errors with respect to `PlayCurrentSong()` that may be due to detaching the audio thread

- Centering of the image_view

---
11 changes: 11 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

add_library(tiv
${CMAKE_CURRENT_SOURCE_DIR}/src/ui/components/libs/tiv_lib.cpp
)

# --- Fetch FTXUI --------------------------------------------------------------
include(FetchContent)

Expand Down Expand Up @@ -40,6 +44,8 @@ endif()
add_executable(${EXECUTABLE_NAME}
src/main.cpp
src/ui/components/scroller.cpp
src/ui/components/image_view.cpp
src/ui/components/libs/tiv_lib.cpp
)

# Set include directories for source files
Expand Down Expand Up @@ -141,6 +147,8 @@ add_definitions(${GLIB_CFLAGS_OTHER})

# Link libraries for native build
target_link_libraries(${EXECUTABLE_NAME}
PRIVATE tiv
PRIVATE X11
PRIVATE ftxui::screen
PRIVATE ftxui::dom
PRIVATE ftxui::component
Expand All @@ -153,3 +161,6 @@ if (NOT EXISTS "$ENV{HOME}/.config/inLimbo/config.toml")
file(MAKE_DIRECTORY "$ENV{HOME}/.config/inLimbo")
configure_file("${CMAKE_SOURCE_DIR}/src/parser/examples/config.toml" "$ENV{HOME}/.config/inLimbo/config.toml" COPYONLY)
endif()
if (NOT EXISTS "$ENV{HOME}/.cache/inLimbo/")
file(MAKE_DIRECTORY "$ENV{HOME}/.cache/inLimbo")
endif()
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
> and no stable release is present as of yet.
>
A possible revamp of LiteMus
The inLimbo project aims to be a new upcoming TUI music player for UNIX based systems that gives music lovers a clean and efficient environment to browse, play and interact with your favourite offline music.

## Features

Expand All @@ -43,10 +43,13 @@ A possible revamp of LiteMus

## DEPENDENCIES

1. TagLib ==> [here](https://taglib.org/) [libtag1-dev for Ubuntu]
2. Gio ==> [here](https://docs.gtk.org/gio/) [libgio-2.0-dev for Ubuntu]
3. GLib ==> [here](https://docs.gtk.org/glib/) [libglib-2.0-dev for Ubuntu]
4. pkg-config ==> [here](https://www.freedesktop.org/wiki/Software/pkg-config/) [pkg-config for Ubuntu]
| Dependency | Ubuntu | Fedora | Arch Linux |
|-----------------|---------------------------|-------------------------------|------------------------------|
| **TagLib** | `libtag1-dev` | `taglib-devel` | `taglib` |
| **Gio** | `libgio-2.0-dev` | `glib2-devel` | `glib2` |
| **GLib** | `libglib-2.0-dev` | `glib2-devel` | `glib2` |
| **pkg-config** | `pkg-config` | `pkgconf` | `pkgconf` |
| **ImageMagick** | `imagemagick` | `ImageMagick` | `imagemagick` |

**FTXUI** is fetched from GitHub [here](https://github.com/ArthurSonzogni/FTXUI/) itself during building so **NO** need to install it separately.

Expand Down
32 changes: 16 additions & 16 deletions src/dbus/mpris-service.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,22 +147,22 @@ class MPRISService

~MPRISService()
{
if (connection_)
{
g_object_unref(connection_);
connection_ = nullptr;
}
if (introspection_data_)
{
g_dbus_node_info_unref(introspection_data_);
introspection_data_ = nullptr;
}
if (current_metadata_)
{
g_variant_unref(current_metadata_);
current_metadata_ = nullptr;
}
std::cout << "-- MPRISService cleaned up." << std::endl;
if (connection_)
{
g_object_unref(connection_);
connection_ = nullptr;
}
if (introspection_data_)
{
g_dbus_node_info_unref(introspection_data_);
introspection_data_ = nullptr;
}
if (current_metadata_)
{
g_variant_unref(current_metadata_);
current_metadata_ = nullptr;
}
std::cout << "-- MPRISService cleaned up." << std::endl;
}

/**
Expand Down
51 changes: 51 additions & 0 deletions src/dirsort/taglib_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@
#define TAGLIB_PARSER_H

#include <filesystem>
#include <fstream>
#include <iostream>
#include <string>
#include <sys/stat.h>
#ifndef __EMSCRIPTEN__
#include <taglib/fileref.h>
#include <taglib/tag.h>
#include <taglib/id3v2tag.h>
#include <taglib/mpegfile.h>
#include <taglib/attachedpictureframe.h>
#include <taglib/tpropertymap.h>
#include <png.h>
#endif
#include <unordered_map>

Expand Down Expand Up @@ -186,4 +191,50 @@ void printMetadata(const Metadata& metadata) {
std::cout << "+++++++++++++++++++++++++++" << std::endl;
}

bool extractThumbnail(const std::string& audioFilePath, const std::string& outputImagePath) {
// Open the file using TagLib
TagLib::MPEG::File file(audioFilePath.c_str());
if (!file.isValid()) {
std::cerr << "Error: Could not open audio file." << std::endl;
return false;
}

// Ensure the file has ID3v2 tags
TagLib::ID3v2::Tag* id3v2Tag = file.ID3v2Tag();
if (!id3v2Tag) {
std::cerr << "Error: No ID3v2 tags found in the audio file." << std::endl;
return false;
}

// Search for the APIC (Attached Picture) frame
const TagLib::ID3v2::FrameList& frameList = id3v2Tag->frameListMap()["APIC"];
if (frameList.isEmpty()) {
std::cerr << "Error: No embedded album art found in the audio file." << std::endl;
return false;
}

// Extract the first APIC frame (album art)
auto* apicFrame = dynamic_cast<TagLib::ID3v2::AttachedPictureFrame*>(frameList.front());
if (!apicFrame) {
std::cerr << "Error: Failed to retrieve album art." << std::endl;
return false;
}

// Get the picture data and MIME type
const auto& pictureData = apicFrame->picture();
const std::string mimeType = apicFrame->mimeType().toCString(true);

// Save the picture data to a file
std::ofstream outputFile(outputImagePath, std::ios::binary);
if (!outputFile) {
std::cerr << "Error: Could not create output image file." << std::endl;
return false;
}

outputFile.write(reinterpret_cast<const char*>(pictureData.data()), pictureData.size());
outputFile.close();

return true;
}

#endif // TAGLIB_PARSER_H
1 change: 1 addition & 0 deletions src/parser/examples/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ add_artists_songs_to_queue = "e"
remove_song_from_queue = "d"
play_this_song_next = "b"
view_song_queue = "3"
view_current_song_info = "i"

# Colors format: Solid Colors and Hexadecimal values of format `#RRGGBB`
[colors]
Expand Down
75 changes: 46 additions & 29 deletions src/parser/toml_parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,36 @@ namespace fs = std::filesystem;

/**
* @brief Macros for parent and field names used in the TOML configuration.
*
*
* These macros represent the sections and fields in the TOML configuration file.
*/
#define PARENT_LIB "library" /**< Parent section for library settings */
#define PARENT_LIB_FIELD_NAME "name" /**< Field for the library name */
#define PARENT_LIB "library" /**< Parent section for library settings */
#define PARENT_LIB_FIELD_NAME "name" /**< Field for the library name */
#define PARENT_LIB_FIELD_DIR "directory" /**< Field for the library directory */

#define PARENT_FTP "ftp" /**< Parent section for FTP settings */
#define PARENT_FTP_FIELD_USER "username" /**< Field for FTP username */
#define PARENT_FTP_FIELD_SALT "salt" /**< Field for FTP salt */
#define PARENT_FTP "ftp" /**< Parent section for FTP settings */
#define PARENT_FTP_FIELD_USER "username" /**< Field for FTP username */
#define PARENT_FTP_FIELD_SALT "salt" /**< Field for FTP salt */
#define PARENT_FTP_FIELD_PWD_HASH "password_hash" /**< Field for FTP password hash */

#define PARENT_DBG "debug" /**< Parent section for debug settings */
#define PARENT_DBG "debug" /**< Parent section for debug settings */
#define PARENT_DBG_FIELD_PARSER_LOG "parser_log" /**< Field for debug parser log setting */

/* SPECIAL KEYBINDS MACROS */
#define PARENT_KEYBINDS "keybinds" /**< Parent section for keybinds */
#define SPECIAL_KEYBIND_ENTER_STR "Enter" /**< Special keybind for Enter */
#define SPECIAL_KEYBIND_TAB_STR "Tab" /**< Special keybind for Tab */
#define SPECIAL_KEYBIND_SPACE_STR "Space" /**< Special keybind for Space */
#define SPECIAL_KEYBIND_ENTER_STR "Enter" /**< Special keybind for Enter */
#define SPECIAL_KEYBIND_TAB_STR "Tab" /**< Special keybind for Tab */
#define SPECIAL_KEYBIND_SPACE_STR "Space" /**< Special keybind for Space */

#define PARENT_COLORS "colors" /**< Parent section for color settings */

/**
* @brief Retrieves the path to the configuration file.
*
* This function constructs the path to the `config.toml` file located in the user's home directory, inside the
*
* This function constructs the path to the `config.toml` file located in the user's home directory,
* inside the
* `.config/inLimbo/` folder.
*
*
* @param fileName The name of the configuration file (e.g., "config.toml").
* @return A string representing the full path to the configuration file.
* @throws std::runtime_error If the HOME environment variable is not found.
Expand All @@ -58,22 +59,36 @@ string getConfigPath(string fileName)
return configFilePath;
}

string getCachePath()
{
const char* homeDir = std::getenv("HOME");
if (!homeDir)
{
cerr << "ERROR: HOME environment variable not found." << endl;
exit(EXIT_FAILURE); /**< Exit gracefully if the HOME environment variable is not set. */
}

string cacheFilePath = string(homeDir) + "/.cache/inLimbo/";

return cacheFilePath;
}

/**
* @brief Checks if the configuration file exists.
*
*
* This function checks if the `config.toml` file exists at the given file path.
*
*
* @param filePath The path to the configuration file.
* @return `true` if the file exists, otherwise `false`.
*/
bool configFileExists(const string& filePath) { return fs::exists(filePath); }

/**
* @brief Loads the configuration file.
*
* This function loads the `config.toml` file and parses it using the `toml` library. If the file does not exist,
* the program exits gracefully with an error message.
*
*
* This function loads the `config.toml` file and parses it using the `toml` library. If the file
* does not exist, the program exits gracefully with an error message.
*
* @return A `toml::parse_result` object representing the parsed configuration.
* @throws std::runtime_error If the configuration file does not exist or cannot be parsed.
*/
Expand All @@ -95,32 +110,34 @@ auto config = loadConfig();

/**
* @brief Parses a string field from the TOML configuration.
*
* This function retrieves the value of a specific field within a parent section of the TOML configuration.
* If the field is not found, it returns an empty string view.
*
*
* This function retrieves the value of a specific field within a parent section of the TOML
* configuration. If the field is not found, it returns an empty string view.
*
* @param parent The parent section name (e.g., "library").
* @param field The field name within the parent section (e.g., "name").
* @return A string view representing the value of the field.
*/
string_view parseTOMLField(string parent, string field)
{
return config[parent][field].value_or(""sv); /**< If the field is not found, return an empty string view. */
return config[parent][field].value_or(
""sv); /**< If the field is not found, return an empty string view. */
}

/**
* @brief Parses an integer field from the TOML configuration.
*
* This function retrieves the value of a specific field as an integer from the TOML configuration. If the field is
* not found, it returns -1 as a default value.
*
*
* This function retrieves the value of a specific field as an integer from the TOML configuration.
* If the field is not found, it returns -1 as a default value.
*
* @param parent The parent section name (e.g., "ftp").
* @param field The field name within the parent section (e.g., "username").
* @return The integer value of the field, or -1 if the field is not found.
*/
int64_t parseTOMLFieldInt(string parent, string field)
{
return config[parent][field].value_or(-1); /**< If the field is not found, return -1 as default. */
return config[parent][field].value_or(
-1); /**< If the field is not found, return -1 as default. */
}

#endif
4 changes: 2 additions & 2 deletions src/signal/signalHandler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class SignalHandler {
return std::string(buffer);
}

static void createLogDirectory(const std::string& path) {
static void createCacheDirectory(const std::string& path) {
struct stat info;
if (stat(path.c_str(), &info) != 0 || !(info.st_mode & S_IFDIR)) {
mkdir(path.c_str(), 0755); // Create directory with rwx permissions
Expand Down Expand Up @@ -100,7 +100,7 @@ class SignalHandler {
}

std::string logDir = std::string(std::getenv("HOME")) + "/.cache/inLimbo/";
createLogDirectory(logDir); // Ensure the directory exists
createCacheDirectory(logDir); // Ensure the directory exists

std::string logFileName = logDir +"debug-" + std::to_string(signal) + ".log";
std::ofstream logFile(logFileName, std::ios::out | std::ios::app);
Expand Down
Loading

0 comments on commit 950f575

Please sign in to comment.