summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2017-06-19 15:33:42 +0200
committerCarlos Garnacho <carlosg@gnome.org>2017-06-29 20:49:06 +0200
commit64e594a4817aeedd5b0f3cc58b000147e037c5ee (patch)
tree6eb0373d5a470c6ca9ec450c09d3032ffbc06eb6
parentcdbb834a31c0b1c3ccb7fb93615c34f863f9eff9 (diff)
downloadtracker-64e594a4817aeedd5b0f3cc58b000147e037c5ee.tar.gz
libtracker-common: Add TrackerDomainOntology helper
This just wraps the information that can be extracted from a domain ontology rule file.
-rw-r--r--src/libtracker-common/Makefile.am2
-rw-r--r--src/libtracker-common/libtracker-common.vapi9
-rw-r--r--src/libtracker-common/meson.build1
-rw-r--r--src/libtracker-common/tracker-common.h1
-rw-r--r--src/libtracker-common/tracker-domain-ontology.c378
-rw-r--r--src/libtracker-common/tracker-domain-ontology.h44
6 files changed, 435 insertions, 0 deletions
diff --git a/src/libtracker-common/Makefile.am b/src/libtracker-common/Makefile.am
index 09d828263..8b00ee83d 100644
--- a/src/libtracker-common/Makefile.am
+++ b/src/libtracker-common/Makefile.am
@@ -23,6 +23,7 @@ libtracker_common_la_SOURCES = \
$(BUILT_SOURCES) \
tracker-date-time.c \
tracker-dbus.c \
+ tracker-domain-ontology.c \
tracker-file-utils.c \
tracker-ioprio.c \
tracker-log.c \
@@ -41,6 +42,7 @@ noinst_HEADERS = \
tracker-log.h \
tracker-common.h \
tracker-date-time.h \
+ tracker-domain-ontology.h \
tracker-file-utils.h \
tracker-sched.h \
tracker-seccomp.h \
diff --git a/src/libtracker-common/libtracker-common.vapi b/src/libtracker-common/libtracker-common.vapi
index 65c2e4399..6f0a8e024 100644
--- a/src/libtracker-common/libtracker-common.vapi
+++ b/src/libtracker-common/libtracker-common.vapi
@@ -88,6 +88,15 @@ namespace Tracker {
public static void enable_client_lookup (bool enable);
}
+ [CCode (cheader_filename = "libtracker-common/tracker-domain-ontology.h")]
+ public class DomainOntology : GLib.Object, GLib.Initable {
+ public DomainOntology (string? name, GLib.Cancellable? cancellable) throws GLib.Error;
+ public GLib.File get_cache ();
+ public GLib.File? get_journal ();
+ public GLib.File get_ontology ();
+ public string get_domain (string? suffix = null);
+ }
+
[CCode (cheader_filename = "libtracker-common/tracker-common.h")]
public void ioprio_init ();
diff --git a/src/libtracker-common/meson.build b/src/libtracker-common/meson.build
index ddf098177..b0411cc25 100644
--- a/src/libtracker-common/meson.build
+++ b/src/libtracker-common/meson.build
@@ -16,6 +16,7 @@ tracker_common_enum_header = enums[1]
tracker_common_sources = [
'tracker-date-time.c',
'tracker-dbus.c',
+ 'tracker-domain-ontology.c',
'tracker-file-utils.c',
'tracker-ioprio.c',
'tracker-log.c',
diff --git a/src/libtracker-common/tracker-common.h b/src/libtracker-common/tracker-common.h
index 2434b7f08..47191fd44 100644
--- a/src/libtracker-common/tracker-common.h
+++ b/src/libtracker-common/tracker-common.h
@@ -30,6 +30,7 @@
#include "tracker-date-time.h"
#include "tracker-dbus.h"
+#include "tracker-domain-ontology.h"
#include "tracker-file-utils.h"
#include "tracker-ioprio.h"
#include "tracker-language.h"
diff --git a/src/libtracker-common/tracker-domain-ontology.c b/src/libtracker-common/tracker-domain-ontology.c
new file mode 100644
index 000000000..07b440135
--- /dev/null
+++ b/src/libtracker-common/tracker-domain-ontology.c
@@ -0,0 +1,378 @@
+#include "config.h"
+
+#include <string.h>
+#include "tracker-domain-ontology.h"
+
+typedef struct {
+ /* DomainOntologies section */
+ GFile *cache_location;
+ GFile *journal_location;
+ GFile *ontology_location;
+ gchar *name;
+ gchar *domain;
+ gchar *ontology_name;
+} TrackerDomainOntologyPrivate;
+
+enum {
+ PROP_0,
+ PROP_NAME
+};
+
+struct {
+ const gchar *var;
+ const gchar *(*func) (void);
+} lookup_dirs[] = {
+ { "HOME", g_get_home_dir },
+ { "XDG_CACHE_HOME", g_get_user_cache_dir },
+ { "XDG_DATA_HOME", g_get_user_data_dir },
+ { "XDG_RUNTIME_DIR", g_get_user_runtime_dir },
+};
+
+struct {
+ const gchar *var;
+ GUserDirectory user_directory;
+} lookup_special_dirs[] = {
+ { "XDG_DESKTOP_DIR", G_USER_DIRECTORY_DESKTOP },
+ { "XDG_DOCUMENTS_DIR", G_USER_DIRECTORY_DOCUMENTS },
+ { "XDG_DOWNLOAD_DIR", G_USER_DIRECTORY_DOWNLOAD },
+ { "XDG_MUSIC_DIR", G_USER_DIRECTORY_MUSIC },
+ { "XDG_PICTURES_DIR", G_USER_DIRECTORY_PICTURES },
+ { "XDG_PICTURES_DIR", G_USER_DIRECTORY_PICTURES },
+ { "XDG_PUBLICSHARE_DIR", G_USER_DIRECTORY_PUBLIC_SHARE },
+ { "XDG_VIDEOS_DIR", G_USER_DIRECTORY_VIDEOS },
+ { "XDG_VIDEOS_DIR", G_USER_DIRECTORY_VIDEOS },
+};
+
+#define DOMAIN_ONTOLOGY_SECTION "DomainOntology"
+
+#define CACHE_KEY "CacheLocation"
+#define JOURNAL_KEY "JournalLocation"
+#define ONTOLOGY_KEY "OntologyLocation"
+#define ONTOLOGY_NAME_KEY "OntologyName"
+#define DOMAIN_KEY "Domain"
+
+static void tracker_domain_ontology_initable_iface_init (GInitableIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (TrackerDomainOntology, tracker_domain_ontology, G_TYPE_OBJECT,
+ G_ADD_PRIVATE (TrackerDomainOntology)
+ G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, tracker_domain_ontology_initable_iface_init))
+
+static void
+tracker_domain_ontology_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ TrackerDomainOntology *domain_ontology;
+ TrackerDomainOntologyPrivate *priv;
+
+ domain_ontology = TRACKER_DOMAIN_ONTOLOGY (object);
+ priv = tracker_domain_ontology_get_instance_private (domain_ontology);
+
+ switch (prop_id) {
+ case PROP_NAME:
+ priv->name = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+tracker_domain_ontology_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ TrackerDomainOntology *domain_ontology;
+ TrackerDomainOntologyPrivate *priv;
+
+ domain_ontology = TRACKER_DOMAIN_ONTOLOGY (object);
+ priv = tracker_domain_ontology_get_instance_private (domain_ontology);
+
+ switch (prop_id) {
+ case PROP_NAME:
+ g_value_set_string (value, priv->name);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+tracker_domain_ontology_finalize (GObject *object)
+{
+ TrackerDomainOntology *domain_ontology;
+ TrackerDomainOntologyPrivate *priv;
+
+ domain_ontology = TRACKER_DOMAIN_ONTOLOGY (object);
+ priv = tracker_domain_ontology_get_instance_private (domain_ontology);
+
+ g_clear_object (&priv->cache_location);
+ g_clear_object (&priv->journal_location);
+ g_clear_object (&priv->ontology_location);
+ g_free (priv->name);
+ g_free (priv->domain);
+
+ G_OBJECT_CLASS (tracker_domain_ontology_parent_class)->finalize (object);
+}
+
+static void
+tracker_domain_ontology_class_init (TrackerDomainOntologyClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->set_property = tracker_domain_ontology_set_property;
+ object_class->get_property = tracker_domain_ontology_get_property;
+ object_class->finalize = tracker_domain_ontology_finalize;
+
+ g_object_class_install_property (object_class,
+ PROP_NAME,
+ g_param_spec_string ("name",
+ "Name",
+ "Name",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+tracker_domain_ontology_init (TrackerDomainOntology *domain_ontology)
+{
+}
+
+static const gchar *
+lookup_dir (const gchar *variable,
+ gsize variable_len)
+{
+ gint i;
+
+ for (i = 0; i < G_N_ELEMENTS (lookup_dirs); i++) {
+ if (strncmp (lookup_dirs[i].var, variable, variable_len) == 0) {
+ return lookup_dirs[i].func ();
+ }
+ }
+
+ for (i = 0; i < G_N_ELEMENTS (lookup_special_dirs); i++) {
+ if (strncmp (lookup_special_dirs[i].var, variable, variable_len) == 0) {
+ return g_get_user_special_dir (lookup_special_dirs[i].user_directory);
+ }
+ }
+
+ return NULL;
+}
+
+static GFile *
+key_file_get_location (GKeyFile *key_file,
+ const gchar *section,
+ const gchar *key,
+ gboolean essential,
+ gboolean must_exist,
+ GError **error)
+{
+ GError *inner_error = NULL;
+ gchar *value;
+ GFile *file;
+
+ value = g_key_file_get_string (key_file, section, key, &inner_error);
+ if (inner_error) {
+ if (essential)
+ g_propagate_error (error, inner_error);
+ else
+ g_error_free (inner_error);
+
+ return NULL;
+ }
+
+ if (value[0] == '$') {
+ const gchar *var_end, *prefix;
+ gchar *path;
+
+ /* This is a path relative from a xdg dir */
+ var_end = strchr (value, '/');
+ if (!var_end) {
+ /* We must take $VAR/subdir values */
+ g_set_error (error,
+ G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_INVALID_VALUE,
+ "Path in key '%s' can not consist solely of a variable",
+ key);
+ g_free (value);
+ return NULL;
+ }
+
+ prefix = lookup_dir (&value[1], (var_end - &value[1]));
+ if (!prefix) {
+ g_set_error (error,
+ G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_INVALID_VALUE,
+ "Unrecognized variable in '%s'", key);
+ g_free (value);
+ return NULL;
+ }
+
+ path = g_strconcat (prefix, var_end, NULL);
+ file = g_file_new_for_path (path);
+ g_free (path);
+ } else {
+ file = g_file_new_for_uri (value);
+ }
+
+ g_free (value);
+
+ if (must_exist && file &&
+ g_file_query_file_type (file, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ NULL) != G_FILE_TYPE_DIRECTORY) {
+ gchar *uri = g_file_get_uri (file);
+ g_set_error (error,
+ G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_INVALID_VALUE,
+ "Uri '%s' is not a directory or does not exist", uri);
+ g_free (uri);
+ return NULL;
+ }
+
+ return file;
+}
+
+static gboolean
+tracker_domain_ontology_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
+{
+ TrackerDomainOntology *domain_ontology;
+ TrackerDomainOntologyPrivate *priv;
+ GError *inner_error = NULL;
+ GKeyFile *key_file;
+ gchar *rulename, *path;
+
+ domain_ontology = TRACKER_DOMAIN_ONTOLOGY (initable);
+ priv = tracker_domain_ontology_get_instance_private (domain_ontology);
+
+ rulename = g_strconcat (priv->name ? priv->name : "default", ".rule", NULL);
+ path = g_build_filename (SHAREDIR, "tracker", "domain-ontologies",
+ rulename, NULL);
+ key_file = g_key_file_new ();
+ g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, &inner_error);
+
+ g_free (rulename);
+ g_free (path);
+
+ if (inner_error)
+ goto end;
+
+ priv->domain = g_key_file_get_string (key_file, DOMAIN_ONTOLOGY_SECTION,
+ DOMAIN_KEY, &inner_error);
+ if (inner_error)
+ goto end;
+
+ priv->cache_location =
+ key_file_get_location (key_file, DOMAIN_ONTOLOGY_SECTION,
+ CACHE_KEY, TRUE, FALSE, &inner_error);
+ if (inner_error)
+ goto end;
+
+ priv->journal_location =
+ key_file_get_location (key_file, DOMAIN_ONTOLOGY_SECTION,
+ JOURNAL_KEY, FALSE, FALSE, &inner_error);
+ if (inner_error)
+ goto end;
+
+ priv->ontology_location =
+ key_file_get_location (key_file, DOMAIN_ONTOLOGY_SECTION,
+ ONTOLOGY_KEY, FALSE, TRUE, &inner_error);
+ if (inner_error)
+ goto end;
+
+ priv->ontology_name = g_key_file_get_string (key_file, DOMAIN_ONTOLOGY_SECTION,
+ ONTOLOGY_NAME_KEY, NULL);
+
+ /* Consistency check, we need one of OntologyLocation and OntologyName,
+ * no more, no less.
+ */
+ if ((priv->ontology_name && priv->ontology_location) ||
+ (!priv->ontology_name && !priv->ontology_location)) {
+ inner_error = g_error_new (G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_INVALID_VALUE,
+ "One of OntologyLocation and OntologyName must be provided");
+ }
+
+ /* Build ontology location from name if necessary */
+ if (!priv->ontology_location) {
+ gchar *ontology_path;
+
+ ontology_path = g_build_filename (SHAREDIR, "tracker", "ontologies",
+ priv->ontology_name, NULL);
+ priv->ontology_location = g_file_new_for_path (ontology_path);
+ g_free (ontology_path);
+ }
+
+end:
+ g_key_file_free (key_file);
+
+ if (inner_error) {
+ g_propagate_error (error, inner_error);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+tracker_domain_ontology_initable_iface_init (GInitableIface *iface)
+{
+ iface->init = tracker_domain_ontology_initable_init;
+}
+
+TrackerDomainOntology *
+tracker_domain_ontology_new (const gchar *domain_name,
+ GCancellable *cancellable,
+ GError **error)
+{
+ return g_initable_new (TRACKER_TYPE_DOMAIN_ONTOLOGY,
+ cancellable, error,
+ "name", domain_name,
+ NULL);
+}
+
+GFile *
+tracker_domain_ontology_get_cache (TrackerDomainOntology *domain_ontology)
+{
+ TrackerDomainOntologyPrivate *priv;
+
+ priv = tracker_domain_ontology_get_instance_private (domain_ontology);
+ return priv->cache_location;
+}
+
+GFile *
+tracker_domain_ontology_get_journal (TrackerDomainOntology *domain_ontology)
+{
+ TrackerDomainOntologyPrivate *priv;
+
+ priv = tracker_domain_ontology_get_instance_private (domain_ontology);
+ return priv->journal_location;
+}
+
+GFile *
+tracker_domain_ontology_get_ontology (TrackerDomainOntology *domain_ontology)
+{
+ TrackerDomainOntologyPrivate *priv;
+
+ priv = tracker_domain_ontology_get_instance_private (domain_ontology);
+ return priv->ontology_location;
+}
+
+gchar *
+tracker_domain_ontology_get_domain (TrackerDomainOntology *domain_ontology,
+ const gchar *suffix)
+{
+ TrackerDomainOntologyPrivate *priv;
+
+ priv = tracker_domain_ontology_get_instance_private (domain_ontology);
+ if (suffix)
+ return g_strconcat (priv->domain, ".Tracker1.", suffix, NULL);
+ else
+ return g_strconcat (priv->domain, ".Tracker1", NULL);
+}
diff --git a/src/libtracker-common/tracker-domain-ontology.h b/src/libtracker-common/tracker-domain-ontology.h
new file mode 100644
index 000000000..1530b771c
--- /dev/null
+++ b/src/libtracker-common/tracker-domain-ontology.h
@@ -0,0 +1,44 @@
+#ifndef __TRACKER_DOMAIN_ONTOLOGY_H__
+#define __TRACKER_DOMAIN_ONTOLOGY_H__
+
+#if !defined (__LIBTRACKER_COMMON_INSIDE__) && !defined (TRACKER_COMPILATION)
+#error "only <libtracker-common/tracker-common.h> must be included directly."
+#endif
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+#define TRACKER_TYPE_DOMAIN_ONTOLOGY (tracker_domain_ontology_get_type())
+#define TRACKER_DOMAIN_ONTOLOGY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TRACKER_TYPE_DOMAIN_ONTOLOGY, TrackerDomainOntology))
+#define TRACKER_DOMAIN_ONTOLOGY_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), TRACKER_TYPE_DOMAIN_ONTOLOGY, TrackerDomainOntologyClass))
+#define TRACKER_IS_DOMAIN_ONTOLOGY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TRACKER_TYPE_DOMAIN_ONTOLOGY))
+#define TRACKER_IS_DOMAIN_ONTOLOGY_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), TRACKER_TYPE_DOMAIN_ONTOLOGY))
+#define TRACKER_DOMAIN_ONTOLOGY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_DOMAIN_ONTOLOGY, TrackerDomainOntologyClass))
+
+typedef struct _TrackerDomainOntology TrackerDomainOntology;
+typedef struct _TrackerDomainOntologyClass TrackerDomainOntologyClass;
+
+struct _TrackerDomainOntology {
+ GObject parent_instance;
+};
+
+struct _TrackerDomainOntologyClass {
+ GObjectClass parent_class;
+ /*<private>*/
+ gpointer padding[10];
+};
+
+GType tracker_domain_ontology_get_type (void) G_GNUC_CONST;
+
+TrackerDomainOntology * tracker_domain_ontology_new (const gchar *name,
+ GCancellable *cancellable,
+ GError **error);
+
+GFile * tracker_domain_ontology_get_cache (TrackerDomainOntology *domain_ontology);
+GFile * tracker_domain_ontology_get_journal (TrackerDomainOntology *domain_ontology);
+GFile * tracker_domain_ontology_get_ontology (TrackerDomainOntology *domain_ontology);
+
+gchar * tracker_domain_ontology_get_domain (TrackerDomainOntology *domain_ontology,
+ const gchar *suffix);
+
+#endif /* __TRACKER_MINER_PROXY_H__ */