diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2017-06-19 15:33:42 +0200 |
---|---|---|
committer | Carlos Garnacho <carlosg@gnome.org> | 2017-06-29 20:49:06 +0200 |
commit | 64e594a4817aeedd5b0f3cc58b000147e037c5ee (patch) | |
tree | 6eb0373d5a470c6ca9ec450c09d3032ffbc06eb6 | |
parent | cdbb834a31c0b1c3ccb7fb93615c34f863f9eff9 (diff) | |
download | tracker-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.am | 2 | ||||
-rw-r--r-- | src/libtracker-common/libtracker-common.vapi | 9 | ||||
-rw-r--r-- | src/libtracker-common/meson.build | 1 | ||||
-rw-r--r-- | src/libtracker-common/tracker-common.h | 1 | ||||
-rw-r--r-- | src/libtracker-common/tracker-domain-ontology.c | 378 | ||||
-rw-r--r-- | src/libtracker-common/tracker-domain-ontology.h | 44 |
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__ */ |