Implement mutli-Library support.
Honestly, not going to bother summarizing this massive changeset. You are welcome to look it over in your own free time. Fixes #10. Fixes #11
This commit is contained in:
parent
8d823dbbec
commit
44e4564f1c
38 changed files with 2408 additions and 1072 deletions
|
@ -1,4 +1,4 @@
|
|||
/* file.c
|
||||
/* track.c
|
||||
*
|
||||
* Copyright 2021 Joshua Strobl
|
||||
*
|
||||
|
@ -18,8 +18,10 @@
|
|||
#include <glib-2.0/glib.h>
|
||||
#include <sqlite3.h>
|
||||
#include <taglib/tag_c.h>
|
||||
#include "../db/db.h"
|
||||
#include "../db/cartographer.h"
|
||||
#include "structs.h"
|
||||
#include "track-helpers.h"
|
||||
#include "koto-utils.h"
|
||||
|
||||
extern KotoCartographer * koto_maps;
|
||||
|
@ -30,15 +32,14 @@ struct _KotoTrack {
|
|||
gchar * artist_uuid;
|
||||
gchar * album_uuid;
|
||||
gchar * uuid;
|
||||
gchar * path;
|
||||
|
||||
gchar * file_name;
|
||||
GHashTable * paths;
|
||||
|
||||
gchar * parsed_name;
|
||||
guint * cd;
|
||||
guint * position;
|
||||
guint cd;
|
||||
guint position;
|
||||
guint * playback_position;
|
||||
|
||||
gboolean acquired_metadata_from_id3;
|
||||
gboolean do_initial_index;
|
||||
};
|
||||
|
||||
|
@ -50,8 +51,6 @@ enum {
|
|||
PROP_ALBUM_UUID,
|
||||
PROP_UUID,
|
||||
PROP_DO_INITIAL_INDEX,
|
||||
PROP_PATH,
|
||||
PROP_FILE_NAME,
|
||||
PROP_PARSED_NAME,
|
||||
PROP_CD,
|
||||
PROP_POSITION,
|
||||
|
@ -116,22 +115,6 @@ static void koto_track_class_init(KotoTrackClass * c) {
|
|||
G_PARAM_CONSTRUCT_ONLY | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_READWRITE
|
||||
);
|
||||
|
||||
props[PROP_PATH] = g_param_spec_string(
|
||||
"path",
|
||||
"Path",
|
||||
"Path to File",
|
||||
NULL,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_READWRITE
|
||||
);
|
||||
|
||||
props[PROP_FILE_NAME] = g_param_spec_string(
|
||||
"file-name",
|
||||
"Name of File",
|
||||
"Name of File",
|
||||
NULL,
|
||||
G_PARAM_CONSTRUCT | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_READWRITE
|
||||
);
|
||||
|
||||
props[PROP_PARSED_NAME] = g_param_spec_string(
|
||||
"parsed-name",
|
||||
"Parsed Name of File",
|
||||
|
@ -174,7 +157,7 @@ static void koto_track_class_init(KotoTrackClass * c) {
|
|||
}
|
||||
|
||||
static void koto_track_init(KotoTrack * self) {
|
||||
self->acquired_metadata_from_id3 = FALSE;
|
||||
self->paths = g_hash_table_new(g_str_hash, g_str_equal); // Create our hash table of paths
|
||||
}
|
||||
|
||||
static void koto_track_get_property(
|
||||
|
@ -195,20 +178,14 @@ static void koto_track_get_property(
|
|||
case PROP_UUID:
|
||||
g_value_set_string(val, self->uuid);
|
||||
break;
|
||||
case PROP_PATH:
|
||||
g_value_set_string(val, self->path);
|
||||
break;
|
||||
case PROP_FILE_NAME:
|
||||
g_value_set_string(val, self->file_name);
|
||||
break;
|
||||
case PROP_PARSED_NAME:
|
||||
g_value_set_string(val, self->parsed_name);
|
||||
break;
|
||||
case PROP_CD:
|
||||
g_value_set_uint(val, GPOINTER_TO_UINT(self->cd));
|
||||
g_value_set_uint(val, self->cd);
|
||||
break;
|
||||
case PROP_POSITION:
|
||||
g_value_set_uint(val, GPOINTER_TO_UINT(self->position));
|
||||
g_value_set_uint(val, self->position);
|
||||
break;
|
||||
case PROP_PLAYBACK_POSITION:
|
||||
g_value_set_uint(val, GPOINTER_TO_UINT(self->playback_position));
|
||||
|
@ -243,12 +220,6 @@ static void koto_track_set_property(
|
|||
case PROP_DO_INITIAL_INDEX:
|
||||
self->do_initial_index = g_value_get_boolean(val);
|
||||
break;
|
||||
case PROP_PATH:
|
||||
koto_track_update_path(self, g_value_get_string(val)); // Update the path
|
||||
break;
|
||||
case PROP_FILE_NAME:
|
||||
koto_track_set_file_name(self, g_strdup(g_value_get_string(val))); // Update the file name
|
||||
break;
|
||||
case PROP_PARSED_NAME:
|
||||
koto_track_set_parsed_name(self, g_strdup(g_value_get_string(val)));
|
||||
break;
|
||||
|
@ -268,37 +239,56 @@ static void koto_track_set_property(
|
|||
}
|
||||
|
||||
void koto_track_commit(KotoTrack * self) {
|
||||
if ((self->artist_uuid == NULL) || (strcmp(self->artist_uuid, "") == 0)) { // No valid required artist UUID
|
||||
if (!KOTO_IS_TRACK(self)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->album_uuid == NULL) {
|
||||
g_object_set(self, "album-uuid", "", NULL); // Set to an empty string
|
||||
if (!koto_utils_is_string_valid(self->artist_uuid)) { // No valid required artist UUID
|
||||
return;
|
||||
}
|
||||
|
||||
if (!koto_utils_is_string_valid(self->album_uuid)) { // If we do not have a valid album UUID
|
||||
self->album_uuid = g_strdup("");
|
||||
}
|
||||
|
||||
gchar * commit_msg = "INSERT INTO tracks(id, artist_id, album_id, name, disc, position)" \
|
||||
"VALUES('%s', '%s', '%s', quote(\"%s\"), %d, %d)" \
|
||||
"ON CONFLICT(id) DO UPDATE SET album_id=excluded.album_id, artist_id=excluded.artist_id, name=excluded.name, disc=excluded.disc, position=excluded.position;";
|
||||
|
||||
gchar * commit_op = g_strdup_printf(
|
||||
"INSERT INTO tracks(id, path, type, artist_id, album_id, file_name, name, disc, position)"
|
||||
"VALUES('%s', quote(\"%s\"), 0, '%s', '%s', quote(\"%s\"), quote(\"%s\"), %d, %d)"
|
||||
"ON CONFLICT(id) DO UPDATE SET path=excluded.path, type=excluded.type, album_id=excluded.album_id, file_name=excluded.file_name, name=excluded.file_name, disc=excluded.disc, position=excluded.position;",
|
||||
commit_msg,
|
||||
self->uuid,
|
||||
self->path,
|
||||
self->artist_uuid,
|
||||
self->album_uuid,
|
||||
self->file_name,
|
||||
self->parsed_name,
|
||||
GPOINTER_TO_INT((int*) self->cd),
|
||||
GPOINTER_TO_INT((int*) self->position)
|
||||
(int) self->cd,
|
||||
(int) self->position
|
||||
);
|
||||
|
||||
gchar * commit_op_errmsg = NULL;
|
||||
int rc = sqlite3_exec(koto_db, commit_op, 0, 0, &commit_op_errmsg);
|
||||
new_transaction(commit_op, "Failed to write our file to the database", FALSE);
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
g_warning("Failed to write our file to the database: %s", commit_op_errmsg);
|
||||
GHashTableIter paths_iter;
|
||||
g_hash_table_iter_init(&paths_iter, self->paths); // Create an iterator for our paths
|
||||
gpointer lib_uuid_ptr, track_rel_path_ptr;
|
||||
while (g_hash_table_iter_next(&paths_iter, &lib_uuid_ptr, &track_rel_path_ptr)) {
|
||||
gchar * lib_uuid = lib_uuid_ptr;
|
||||
gchar * track_rel_path = track_rel_path_ptr;
|
||||
|
||||
gchar * commit_op = g_strdup_printf(
|
||||
"INSERT INTO libraries_tracks(id, track_id, path)"
|
||||
"VALUES ('%s', '%s', quote(\"%s\"))"
|
||||
"ON CONFLICT(id, track_id) DO UPDATE SET path=excluded.path;",
|
||||
lib_uuid,
|
||||
self->uuid,
|
||||
track_rel_path
|
||||
);
|
||||
|
||||
new_transaction(commit_op, "Failed to add this path for the track", FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
g_free(commit_op);
|
||||
g_free(commit_op_errmsg);
|
||||
guint koto_track_get_disc_number(KotoTrack * self) {
|
||||
return KOTO_IS_TRACK(self) ? self->cd : 1;
|
||||
}
|
||||
|
||||
GVariant * koto_track_get_metadata_vardict(KotoTrack * self) {
|
||||
|
@ -307,27 +297,28 @@ GVariant * koto_track_get_metadata_vardict(KotoTrack * self) {
|
|||
}
|
||||
|
||||
GVariantBuilder * builder = g_variant_builder_new(G_VARIANT_TYPE_VARDICT);
|
||||
|
||||
gchar * album_art_path = NULL;
|
||||
gchar * album_name = NULL;
|
||||
gchar * artist_name = NULL;
|
||||
|
||||
KotoArtist * artist = koto_cartographer_get_artist_by_uuid(koto_maps, self->artist_uuid);
|
||||
KotoAlbum * album = koto_cartographer_get_album_by_uuid(koto_maps, self->album_uuid);
|
||||
gchar * artist_name = koto_artist_get_name(artist);
|
||||
|
||||
g_object_get(album, "art-path", &album_art_path, "name", &album_name, NULL);
|
||||
if (koto_utils_is_string_valid(self->album_uuid)) { // Have an album associated
|
||||
KotoAlbum * album = koto_cartographer_get_album_by_uuid(koto_maps, self->album_uuid);
|
||||
|
||||
g_object_get(artist, "name", &artist_name, NULL);
|
||||
if (KOTO_IS_ALBUM(album)) {
|
||||
gchar * album_art_path = koto_album_get_art(album);
|
||||
gchar * album_name = koto_album_get_name(album);
|
||||
|
||||
if (koto_utils_is_string_valid(album_art_path)) { // Valid album art path
|
||||
album_art_path = g_strconcat("file://", album_art_path, NULL); // Prepend with file://
|
||||
g_variant_builder_add(builder, "{sv}", "mpris:artUrl", g_variant_new_string(album_art_path));
|
||||
}
|
||||
|
||||
g_variant_builder_add(builder, "{sv}", "xesam:album", g_variant_new_string(album_name));
|
||||
}
|
||||
} else {
|
||||
} // TODO: Implement artist artwork fetching here
|
||||
|
||||
g_variant_builder_add(builder, "{sv}", "mpris:trackid", g_variant_new_string(self->uuid));
|
||||
|
||||
if (koto_utils_is_string_valid(album_art_path)) { // Valid album art path
|
||||
album_art_path = g_strconcat("file://", album_art_path, NULL); // Prepend with file://
|
||||
g_variant_builder_add(builder, "{sv}", "mpris:artUrl", g_variant_new_string(album_art_path));
|
||||
}
|
||||
|
||||
g_variant_builder_add(builder, "{sv}", "xesam:album", g_variant_new_string(album_name));
|
||||
|
||||
if (koto_utils_is_string_valid(artist_name)) { // Valid artist name
|
||||
GVariant * artist_name_variant;
|
||||
GVariantBuilder * artist_list_builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
|
||||
|
@ -339,16 +330,74 @@ GVariant * koto_track_get_metadata_vardict(KotoTrack * self) {
|
|||
g_variant_builder_add(builder, "{sv}", "playbackengine:artist", g_variant_new_string(artist_name)); // Add a sort of "meta" string val for our playback engine so we don't need to mess about with the array
|
||||
}
|
||||
|
||||
g_variant_builder_add(builder, "{sv}", "xesam:discNumber", g_variant_new_uint64(GPOINTER_TO_UINT(self->cd)));
|
||||
g_variant_builder_add(builder, "{sv}", "xesam:discNumber", g_variant_new_uint64(self->cd));
|
||||
g_variant_builder_add(builder, "{sv}", "xesam:title", g_variant_new_string(self->parsed_name));
|
||||
g_variant_builder_add(builder, "{sv}", "xesam:url", g_variant_new_string(self->path));
|
||||
g_variant_builder_add(builder, "{sv}", "xesam:trackNumber", g_variant_new_uint64(GPOINTER_TO_UINT(self->position)));
|
||||
g_variant_builder_add(builder, "{sv}", "xesam:url", g_variant_new_string(koto_track_get_path(self)));
|
||||
g_variant_builder_add(builder, "{sv}", "xesam:trackNumber", g_variant_new_uint64(self->position));
|
||||
|
||||
GVariant * metadata_ret = g_variant_builder_end(builder);
|
||||
|
||||
return metadata_ret;
|
||||
}
|
||||
|
||||
gchar * koto_track_get_name(KotoTrack * self) {
|
||||
if (!KOTO_IS_TRACK(self)) { // Not a track
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return g_strdup(self->parsed_name);
|
||||
}
|
||||
|
||||
gchar * koto_track_get_path(KotoTrack * self) {
|
||||
if (!KOTO_IS_TRACK(self) || (KOTO_IS_TRACK(self) && (g_list_length(g_hash_table_get_keys(self->paths)) == 0))) { // If this is not a track or is but we have no paths associated with it
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GList * libs = koto_cartographer_get_libraries(koto_maps); // Get all of our libraries
|
||||
GList * cur_lib_list;
|
||||
|
||||
for (cur_lib_list = libs; cur_lib_list != NULL; cur_lib_list = libs->next) { // Iterate over our libraries
|
||||
KotoLibrary * cur_library = libs->data; // Get this as a KotoLibrary
|
||||
gchar * library_relative_path = g_hash_table_lookup(self->paths, koto_library_get_uuid(cur_library)); // Get any relative path in our paths based on the current UUID
|
||||
|
||||
if (!koto_utils_is_string_valid(library_relative_path)) { // Not a valid path
|
||||
continue;
|
||||
}
|
||||
|
||||
return g_strdup(g_build_path(G_DIR_SEPARATOR_S, koto_library_get_path(cur_library), library_relative_path, NULL)); // Build our full library path using library's path and our file relative path
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
guint koto_track_get_position(KotoTrack * self) {
|
||||
return KOTO_IS_TRACK(self) ? self->position : 0;
|
||||
}
|
||||
|
||||
gchar * koto_track_get_uniqueish_key(KotoTrack * self) {
|
||||
KotoArtist * artist = koto_cartographer_get_artist_by_uuid(koto_maps, self->artist_uuid); // Get the artist associated with this track
|
||||
|
||||
if (!KOTO_IS_ARTIST(artist)) { // Don't have an artist
|
||||
return g_strdup(self->parsed_name); // Just return the name of the file, which is very likely not unique
|
||||
}
|
||||
|
||||
gchar * artist_name = koto_artist_get_name(artist); // Get the artist name
|
||||
|
||||
if (koto_utils_is_string_valid(self->album_uuid)) { // If we have an album associated with this track (not necessarily guaranteed)
|
||||
KotoAlbum * possible_album = koto_cartographer_get_album_by_uuid(koto_maps, self->album_uuid);
|
||||
|
||||
if (KOTO_IS_ALBUM(possible_album)) { // Album exists
|
||||
gchar * album_name = koto_album_get_name(possible_album); // Get the name of the album
|
||||
|
||||
if (koto_utils_is_string_valid(album_name)) {
|
||||
return g_strdup_printf("%s-%s-%s", artist_name, album_name, self->parsed_name); // Create a key of (ARTIST/WRITER)-(ALBUM/AUDIOBOOK)-(CHAPTER/TRACK)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return g_strdup_printf("%s-%s", artist_name, self->parsed_name); // Create a key of just (ARTIST/WRITER)-(CHAPTER/TRACK)
|
||||
}
|
||||
|
||||
gchar * koto_track_get_uuid(KotoTrack * self) {
|
||||
if (!KOTO_IS_TRACK(self)) {
|
||||
return NULL;
|
||||
|
@ -357,65 +406,6 @@ gchar * koto_track_get_uuid(KotoTrack * self) {
|
|||
return self->uuid; // Do not return a duplicate since otherwise comparison refs fail due to pointer positions being different
|
||||
}
|
||||
|
||||
void koto_track_parse_name(KotoTrack * self) {
|
||||
gchar * copied_file_name = g_strdelimit(g_strdup(self->file_name), "_", ' '); // Replace _ with whitespace for starters
|
||||
|
||||
KotoArtist * artist = NULL;
|
||||
|
||||
artist = koto_cartographer_get_artist_by_uuid(koto_maps, self->artist_uuid);
|
||||
|
||||
if (artist != NULL) { // If we have artist
|
||||
gchar * artist_name = NULL;
|
||||
g_object_get(artist, "name", &artist_name, NULL);
|
||||
|
||||
if (artist_name != NULL && (strcmp(artist_name, "") != 0)) {
|
||||
gchar ** split = g_strsplit(copied_file_name, artist_name, -1); // Split whenever we encounter the artist
|
||||
copied_file_name = g_strjoinv("", split); // Remove the artist
|
||||
g_strfreev(split);
|
||||
|
||||
split = g_strsplit(copied_file_name, g_utf8_strdown(artist_name, -1), -1); // Lowercase album name and split by that
|
||||
copied_file_name = g_strjoinv("", split); // Remove the artist
|
||||
g_strfreev(split);
|
||||
}
|
||||
}
|
||||
|
||||
gchar * file_without_ext = koto_utils_get_filename_without_extension(copied_file_name);
|
||||
|
||||
g_free(copied_file_name);
|
||||
|
||||
gchar ** split = g_regex_split_simple("^([\\d]+)", file_without_ext, G_REGEX_JAVASCRIPT_COMPAT, 0);
|
||||
|
||||
if (g_strv_length(split) > 1) { // Has positional info at the beginning of the file
|
||||
gchar * num = split[1];
|
||||
|
||||
g_free(file_without_ext); // Free the prior name
|
||||
file_without_ext = g_strdup(split[2]); // Set to our second item which is the rest of the song name without the prefixed numbers
|
||||
|
||||
if ((strcmp(num, "0") == 0) || (strcmp(num, "00") == 0)) { // Is exactly zero
|
||||
koto_track_set_position(self, 0); // Set position to 0
|
||||
} else { // Either starts with 0 (like 09) or doesn't start with it at all
|
||||
guint64 potential_pos = g_ascii_strtoull(num, NULL, 10); // Attempt to convert
|
||||
|
||||
if (potential_pos != 0) { // Got a legitimate position
|
||||
koto_track_set_position(self, potential_pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_strfreev(split);
|
||||
|
||||
split = g_strsplit(file_without_ext, " - ", -1); // Split whenever we encounter " - "
|
||||
file_without_ext = g_strjoinv("", split); // Remove entirely
|
||||
g_strfreev(split);
|
||||
|
||||
split = g_strsplit(file_without_ext, "-", -1); // Split whenever we encounter -
|
||||
file_without_ext = g_strjoinv("", split); // Remove entirely
|
||||
g_strfreev(split);
|
||||
|
||||
koto_track_set_parsed_name(self, file_without_ext);
|
||||
g_free(file_without_ext);
|
||||
}
|
||||
|
||||
void koto_track_remove_from_playlist(
|
||||
KotoTrack * self,
|
||||
gchar * playlist_uuid
|
||||
|
@ -430,15 +420,7 @@ void koto_track_remove_from_playlist(
|
|||
playlist_uuid
|
||||
);
|
||||
|
||||
gchar * commit_op_errmsg = NULL;
|
||||
int rc = sqlite3_exec(koto_db, commit_op, 0, 0, &commit_op_errmsg);
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
g_warning("Failed to remove track from playlist: %s", commit_op_errmsg);
|
||||
}
|
||||
|
||||
g_free(commit_op);
|
||||
g_free(commit_op_errmsg);
|
||||
new_transaction(commit_op, "Failed to remove track from playlist", FALSE);
|
||||
}
|
||||
|
||||
void koto_track_save_to_playlist(
|
||||
|
@ -458,39 +440,7 @@ void koto_track_save_to_playlist(
|
|||
current
|
||||
);
|
||||
|
||||
gchar * commit_op_errmsg = NULL;
|
||||
int rc = sqlite3_exec(koto_db, commit_op, 0, 0, &commit_op_errmsg);
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
g_warning("Failed to save track to playlist: %s", commit_op_errmsg);
|
||||
}
|
||||
|
||||
g_free(commit_op);
|
||||
g_free(commit_op_errmsg);
|
||||
}
|
||||
|
||||
void koto_track_set_file_name(
|
||||
KotoTrack * self,
|
||||
gchar * new_file_name
|
||||
) {
|
||||
if (new_file_name == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((self->file_name != NULL) && (strcmp(self->file_name, new_file_name) == 0)) { // Not null and the same
|
||||
return; // Don't do anything
|
||||
}
|
||||
|
||||
if (self->file_name != NULL) { // If it is defined
|
||||
g_free(self->file_name);
|
||||
}
|
||||
|
||||
self->file_name = g_strdup(new_file_name);
|
||||
g_object_notify_by_pspec(G_OBJECT(self), props[PROP_FILE_NAME]);
|
||||
|
||||
if (!self->acquired_metadata_from_id3 && self->do_initial_index) { // Haven't acquired our information from ID3
|
||||
koto_track_parse_name(self); // Update our parsed name
|
||||
}
|
||||
new_transaction(commit_op, "Failed to save track to playlist", FALSE);
|
||||
}
|
||||
|
||||
void koto_track_set_cd(
|
||||
|
@ -501,7 +451,7 @@ void koto_track_set_cd(
|
|||
return;
|
||||
}
|
||||
|
||||
self->cd = GUINT_TO_POINTER(cd);
|
||||
self->cd = cd;
|
||||
g_object_notify_by_pspec(G_OBJECT(self), props[PROP_CD]);
|
||||
}
|
||||
|
||||
|
@ -509,15 +459,17 @@ void koto_track_set_parsed_name(
|
|||
KotoTrack * self,
|
||||
gchar * new_parsed_name
|
||||
) {
|
||||
if (new_parsed_name == NULL) {
|
||||
if (!koto_utils_is_string_valid(new_parsed_name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((self->parsed_name != NULL) && (strcmp(self->parsed_name, new_parsed_name) == 0)) { // Not null and the same
|
||||
gboolean have_existing_name = koto_utils_is_string_valid(self->parsed_name);
|
||||
|
||||
if (have_existing_name && (strcmp(self->parsed_name, new_parsed_name) == 0)) { // Have existing name that matches one provided
|
||||
return; // Don't do anything
|
||||
}
|
||||
|
||||
if (self->parsed_name != NULL) {
|
||||
if (have_existing_name) {
|
||||
g_free(self->parsed_name);
|
||||
}
|
||||
|
||||
|
@ -525,6 +477,30 @@ void koto_track_set_parsed_name(
|
|||
g_object_notify_by_pspec(G_OBJECT(self), props[PROP_PARSED_NAME]);
|
||||
}
|
||||
|
||||
void koto_track_set_path(
|
||||
KotoTrack * self,
|
||||
KotoLibrary * lib,
|
||||
gchar * fixed_path
|
||||
) {
|
||||
if (!KOTO_IS_TRACK(self)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!koto_utils_is_string_valid(fixed_path)) { // Not a valid path
|
||||
return;
|
||||
}
|
||||
|
||||
gchar * path = g_strdup(fixed_path); // Duplicate our fixed_path
|
||||
gchar * relative_path = koto_library_get_relative_path_to_file(lib, path); // Get the relative path to the file for the given library
|
||||
|
||||
gchar * library_uuid = koto_library_get_uuid(lib); // Get the library for this path
|
||||
g_hash_table_replace(self->paths, library_uuid, relative_path); // Replace any existing value or add this one
|
||||
|
||||
if (self->do_initial_index) {
|
||||
koto_track_update_metadata(self); // Attempt to get ID3 info
|
||||
}
|
||||
}
|
||||
|
||||
void koto_track_set_position(
|
||||
KotoTrack * self,
|
||||
guint pos
|
||||
|
@ -533,58 +509,37 @@ void koto_track_set_position(
|
|||
return;
|
||||
}
|
||||
|
||||
self->position = GUINT_TO_POINTER(pos);
|
||||
self->position = pos;
|
||||
g_object_notify_by_pspec(G_OBJECT(self), props[PROP_POSITION]);
|
||||
}
|
||||
|
||||
void koto_track_update_metadata(KotoTrack * self) {
|
||||
TagLib_File * t_file = taglib_file_new(self->path); // Get a taglib file for this file
|
||||
if (!KOTO_IS_TRACK(self)) { // Not a track
|
||||
return;
|
||||
}
|
||||
|
||||
gchar * optimal_track_path = koto_track_get_path(self); // Check all the libraries associated with this track, based on priority, return a built path using lib path + relative file path
|
||||
TagLib_File * t_file = taglib_file_new(optimal_track_path); // Get a taglib file for this file
|
||||
g_free(optimal_track_path);
|
||||
|
||||
if ((t_file != NULL) && taglib_file_is_valid(t_file)) { // If we got the taglib file and it is valid
|
||||
self->acquired_metadata_from_id3 = TRUE;
|
||||
TagLib_Tag * tag = taglib_file_tag(t_file); // Get our tag
|
||||
koto_track_set_parsed_name(self, taglib_tag_title(tag)); // Set the title of the file
|
||||
koto_track_set_position(self, (uint) taglib_tag_track(tag)); // Get the track, convert to uint and cast as a pointer
|
||||
koto_track_set_file_name(self, g_path_get_basename(self->path)); // Update our file name
|
||||
} else {
|
||||
koto_track_set_file_name(self, g_path_get_basename(self->path)); // Update our file name
|
||||
} else { // Failed to get tag info
|
||||
guint64 position = koto_track_helpers_get_position_based_on_file_name(g_path_get_basename(optimal_track_path)); // Get the likely position
|
||||
koto_track_set_position(self, position); // Set our position
|
||||
}
|
||||
|
||||
taglib_tag_free_strings(); // Free strings
|
||||
taglib_file_free(t_file); // Free the file
|
||||
}
|
||||
|
||||
void koto_track_update_path(
|
||||
KotoTrack * self,
|
||||
const gchar * new_path
|
||||
) {
|
||||
if (new_path == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->path != NULL) { // Already have a path
|
||||
g_free(self->path); // Free it
|
||||
}
|
||||
|
||||
self->path = g_strdup(new_path); // Duplicate the path and set it
|
||||
|
||||
if (self->do_initial_index) {
|
||||
koto_track_update_metadata(self); // Attempt to get ID3 info
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec(G_OBJECT(self), props[PROP_PATH]);
|
||||
}
|
||||
|
||||
KotoTrack * koto_track_new(
|
||||
KotoAlbum * album,
|
||||
const gchar * path,
|
||||
guint * cd
|
||||
const gchar * artist_uuid,
|
||||
const gchar * album_uuid,
|
||||
const gchar * parsed_name,
|
||||
guint cd
|
||||
) {
|
||||
gchar * artist_uuid;
|
||||
gchar * album_uuid;
|
||||
|
||||
g_object_get(album, "artist-uuid", &artist_uuid, "uuid", &album_uuid, NULL); // Get the artist and album uuids from our Album
|
||||
|
||||
KotoTrack * track = g_object_new(
|
||||
KOTO_TYPE_TRACK,
|
||||
"artist-uuid",
|
||||
|
@ -595,14 +550,13 @@ KotoTrack * koto_track_new(
|
|||
TRUE,
|
||||
"uuid",
|
||||
g_uuid_string_random(),
|
||||
"path",
|
||||
path,
|
||||
"cd",
|
||||
cd,
|
||||
"parsed-name",
|
||||
parsed_name,
|
||||
NULL
|
||||
);
|
||||
|
||||
koto_track_commit(track); // Immediately commit to the database
|
||||
return track;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue