[tracker-miners/wip/carlosg/cue-file-lookups: 4/5] tracker-extract: Use readonly connection to extract matching CUE sheets




commit 0383ef5e810a04eaebf9c5c2c00b335baa57a39d
Author: Carlos Garnacho <carlosg gnome org>
Date:   Mon Oct 3 12:53:49 2022 +0200

    tracker-extract: Use readonly connection to extract matching CUE sheets
    
    We used to iterate all files in the same folder than the audio file to
    look up CUE sheet files, but this may be overly expensive on very
    flat folder hierarchies where the audio file shares folder with other
    thousands of elements.
    
    Since we have this information indexed already, we can use a readonly
    connection to query for these CUE sheet files. It is very likely that
    these files are just indexed as nfo:FileDataObject, so we have to look
    up the file extension to determine cue files, since mimetype detection
    relies on the file extension too, the check is equivalent.
    
    Closes: https://gitlab.gnome.org/GNOME/tracker/-/issues/378

 src/tracker-extract/tracker-cue-sheet.c         | 79 +++++++++++--------------
 src/tracker-extract/tracker-cue-sheet.h         |  5 +-
 src/tracker-extract/tracker-extract-gstreamer.c |  2 +-
 3 files changed, 38 insertions(+), 48 deletions(-)
---
diff --git a/src/tracker-extract/tracker-cue-sheet.c b/src/tracker-extract/tracker-cue-sheet.c
index 4e662976d..363282e6b 100644
--- a/src/tracker-extract/tracker-cue-sheet.c
+++ b/src/tracker-extract/tracker-cue-sheet.c
@@ -291,64 +291,50 @@ tracker_cue_sheet_parse (const gchar *cue_sheet)
 }
 
 static GList *
-find_local_cue_sheets (GFile *audio_file)
+find_local_cue_sheets (TrackerSparqlConnection *conn,
+                       GFile                   *audio_file)
 {
-       GFile *container;
-       GFile *cue_sheet;
-       GFileEnumerator *e;
-       GFileInfo *file_info;
-       gchar *container_path;
-       const gchar *file_name;
-       const gchar *file_content_type;
-       gchar *file_path;
+       g_autoptr (TrackerSparqlStatement) stmt = NULL;
+       g_autoptr (TrackerSparqlCursor) cursor = NULL;
+       g_autoptr (GFile) parent = NULL;
+       g_autofree gchar *parent_uri = NULL;
        GList *result = NULL;
-       GError *error = NULL;
 
-       container = g_file_get_parent (audio_file);
-       container_path = g_file_get_path (container);
+       stmt = tracker_sparql_connection_query_statement (conn,
+                                                         "SELECT ?u {"
+                                                         "  GRAPH tracker:FileSystem {"
+                                                         "    ?u a nfo:FileDataObject ;"
+                                                         "      nfo:fileName ?fn ;"
+                                                         "      nfo:belongsToContainer/nie:isStoredAs ?c ."
+                                                         "    FILTER (?c = ~parent) ."
+                                                         "    FILTER (STRENDS (?fn, \".cue\")) ."
+                                                         "  }"
+                                                         "}",
+                                                         NULL, NULL);
+       if (!stmt)
+               return NULL;
 
-       e = g_file_enumerate_children (container,
-                                      "standard::*",
-                                      G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
-                                      NULL,
-                                      &error);
+       parent = g_file_get_parent (audio_file);
+       parent_uri = g_file_get_uri (parent);
+       tracker_sparql_statement_bind_string (stmt, "parent", parent_uri);
+       cursor = tracker_sparql_statement_execute (stmt, NULL, NULL);
 
-       if (error != NULL) {
-               g_debug ("Unable to enumerate directory: %s", error->message);
-               g_object_unref (container);
-               g_error_free (error);
+       if (!cursor)
                return NULL;
-       }
 
-       while ((file_info = g_file_enumerator_next_file (e, NULL, NULL))) {
-               file_name = g_file_info_get_attribute_byte_string (file_info,
-                                                                  G_FILE_ATTRIBUTE_STANDARD_NAME);
-
-               file_content_type = g_file_info_get_content_type (file_info);
-
-               if (file_name == NULL || file_content_type == NULL) {
-                       g_debug ("Unable to get info for file %s/%s",
-                                container_path,
-                                g_file_info_get_display_name (file_info));
-               } else if (strcmp (file_content_type, "application/x-cue") == 0) {
-                       file_path = g_build_filename (container_path, file_name, NULL);
-                       cue_sheet = g_file_new_for_path (file_path);
-                       result = g_list_prepend (result, cue_sheet);
-                       g_free (file_path);
-               }
+       while (tracker_sparql_cursor_next (cursor, NULL, NULL)) {
+               const gchar *str;
 
-               g_object_unref (file_info);
+               str = tracker_sparql_cursor_get_string (cursor, 0, NULL);
+               result = g_list_prepend (result, g_file_new_for_uri (str));
        }
 
-       g_object_unref (e);
-       g_object_unref (container);
-       g_free (container_path);
-
        return result;
 }
 
 TrackerToc *
-tracker_cue_sheet_guess_from_uri (const gchar *uri)
+tracker_cue_sheet_guess_from_uri (TrackerSparqlConnection *conn,
+                                  const gchar             *uri)
 {
        GFile *audio_file;
        gchar *audio_file_name;
@@ -360,7 +346,7 @@ tracker_cue_sheet_guess_from_uri (const gchar *uri)
        audio_file = g_file_new_for_uri (uri);
        audio_file_name = g_file_get_basename (audio_file);
 
-       cue_sheet_list = find_local_cue_sheets (audio_file);
+       cue_sheet_list = find_local_cue_sheets (conn, audio_file);
 
        toc = NULL;
 
@@ -409,7 +395,8 @@ tracker_cue_sheet_parse (const gchar *cue_sheet)
 }
 
 TrackerToc *
-tracker_cue_sheet_guess_from_uri (const gchar *uri)
+tracker_cue_sheet_guess_from_uri (TrackerSparqlConnection *conn,
+                                  const gchar             *uri)
 {
        return NULL;
 }
diff --git a/src/tracker-extract/tracker-cue-sheet.h b/src/tracker-extract/tracker-cue-sheet.h
index 6a4bc6df4..de3905c9c 100644
--- a/src/tracker-extract/tracker-cue-sheet.h
+++ b/src/tracker-extract/tracker-cue-sheet.h
@@ -26,6 +26,8 @@
 #include <gst/gst.h>
 #include <gst/tag/tag.h>
 
+#include <libtracker-sparql/tracker-sparql.h>
+
 G_BEGIN_DECLS
 
 typedef struct {
@@ -49,7 +51,8 @@ void        tracker_toc_add_entry       (TrackerToc *toc,
                                          gdouble     duration);
 
 TrackerToc *tracker_cue_sheet_parse     (const gchar *cue_sheet);
-TrackerToc *tracker_cue_sheet_guess_from_uri (const gchar *uri);
+TrackerToc *tracker_cue_sheet_guess_from_uri (TrackerSparqlConnection *conn,
+                                              const gchar             *uri);
 
 G_END_DECLS
 
diff --git a/src/tracker-extract/tracker-extract-gstreamer.c b/src/tracker-extract/tracker-extract-gstreamer.c
index bb2f0e48f..1d561758c 100644
--- a/src/tracker-extract/tracker-extract-gstreamer.c
+++ b/src/tracker-extract/tracker-extract-gstreamer.c
@@ -1363,7 +1363,7 @@ tracker_extract_gstreamer (const gchar          *uri,
                        if (!local_conn)
                                local_conn = tracker_main_get_readonly_connection (NULL);
 
-                       extractor->toc = tracker_cue_sheet_guess_from_uri (uri);
+                       extractor->toc = tracker_cue_sheet_guess_from_uri (local_conn, uri);
                }
 
                if (extractor->toc == NULL &&


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]