static void
insert_data_from_desktop_file (TrackerSparqlBuilder *sparql,
                               const gchar          *subject,
                               const gchar          *metadata_key,
                               GKeyFile             *desktop_file,
                               const gchar          *key,
                               const gchar          *locale)
{
	gchar *str;

	if (locale) {
		/* Try to get the key with our desired LANG locale... */
		str = g_key_file_get_locale_string (desktop_file, GROUP_DESKTOP_ENTRY, key, locale, NULL);
		/* If our desired locale failed, use the list of LANG locales prepared by GLib
		 * (will return untranslated string if none of the locales available) */
		if (!str) {
			str = g_key_file_get_locale_string (desktop_file, GROUP_DESKTOP_ENTRY, key, NULL, NULL);
		}
	} else {
		str = g_key_file_get_string (desktop_file, GROUP_DESKTOP_ENTRY, key, NULL);
	}

	if (str) {
		tracker_sparql_builder_subject_iri (sparql, subject);
		tracker_sparql_builder_predicate_iri (sparql, metadata_key);
		tracker_sparql_builder_object_string (sparql, str);
		g_free (str);
	}
}
static void
process_directory (ProcessApplicationData  *data,
                   GFileInfo               *file_info,
                   GError                 **error)
{
	TrackerSparqlBuilder *sparql;
	gchar *urn, *path, *uri;

	sparql = data->sparql;

	path = g_file_get_path (data->file);
	uri = g_file_get_uri (data->file);
	urn = tracker_sparql_escape_uri_printf ("urn:applications-dir:%s", path);

	tracker_sparql_builder_insert_silent_open (sparql, TRACKER_OWN_GRAPH_URN);

	tracker_sparql_builder_subject_iri (sparql, urn);

	tracker_sparql_builder_predicate (sparql, "a");
	tracker_sparql_builder_object (sparql, "nfo:FileDataObject");
	tracker_sparql_builder_object (sparql, "nie:DataObject");
	tracker_sparql_builder_object (sparql, "nie:Folder");

	tracker_sparql_builder_predicate (sparql, "tracker:available");
	tracker_sparql_builder_object_boolean (sparql, TRUE);

	tracker_sparql_builder_predicate (sparql, "nie:isStoredAs");
	tracker_sparql_builder_object_iri (sparql, urn);

	tracker_sparql_builder_predicate (sparql, "nie:url");
	tracker_sparql_builder_object_string (sparql, uri);

	if (file_info) {
		guint64 time;

		time = g_file_info_get_attribute_uint64 (file_info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
		tracker_sparql_builder_predicate (sparql, "nfo:fileLastModified");
		tracker_sparql_builder_object_date (sparql, (time_t *) &time);
	}

	tracker_sparql_builder_insert_close (data->sparql);

	g_free (path);
	g_free (urn);
	g_free (uri);
}
Example #3
0
G_MODULE_EXPORT gboolean
tracker_extract_get_metadata (TrackerExtractInfo *info_)
{
	/* NOTE: This function has to exist, tracker-extract checks
	 * the symbole table for this function and if it doesn't
	 * exist, the module is not loaded to be used as an extractor.
	 */

	/* File information */
	GFile *file;
	GError *error = NULL;
	gchar *filename;
	OsinfoLoader *loader = NULL;
	OsinfoMedia *media;
	OsinfoDb *db;
	OsinfoOs *os;
	OsinfoOsVariantList *variants;

	/* Data input */
	gboolean bootable;
	const gchar *id;
	const gchar *name;
	TrackerSparqlBuilder *metadata;

	metadata = tracker_extract_info_get_metadata_builder (info_);

	file = tracker_extract_info_get_file (info_);
	filename = g_file_get_path (file);

	media = osinfo_media_create_from_location (filename, NULL, &error);
	if (error != NULL) {
		if (error->code != OSINFO_MEDIA_ERROR_NOT_BOOTABLE) {
			g_message ("Could not extract iso info from '%s': %s",
				   filename, error->message);
			g_free (filename);
			g_error_free (error);
			return FALSE;
		}
		bootable = FALSE;
		goto no_os;
	} else {
		bootable = TRUE;
	}
	g_free (filename);

	loader = osinfo_loader_new ();
	osinfo_loader_process_default_path (loader, &error);
	if (error != NULL) {
		g_message ("Error loading libosinfo OS data: %s",
			   error->message);
		g_error_free (error);
		goto no_os;
	}
	g_warn_if_fail (media != NULL);
	g_warn_if_fail (loader != NULL);

	db = osinfo_loader_get_db (loader);
	osinfo_db_identify_media (db, media);
	os = osinfo_media_get_os (media);

	if (os == NULL)
		goto unknown_os;

	tracker_sparql_builder_predicate (metadata, "a");
	tracker_sparql_builder_object (metadata, "nfo:FilesystemImage");

	variants = osinfo_media_get_os_variants (media);
	if (osinfo_list_get_length (OSINFO_LIST (variants)) > 0) {
		OsinfoEntity *variant;

		/* FIXME: Assuming first variant from multivariant medias. */
		variant = osinfo_list_get_nth (OSINFO_LIST (variants), 0);
		name = osinfo_os_variant_get_name (OSINFO_OS_VARIANT (variant));
	} else {
		name = osinfo_product_get_name (OSINFO_PRODUCT (os));
	}

	if (name != NULL) {
		tracker_sparql_builder_predicate (metadata, "nie:title");
		tracker_sparql_builder_object_string (metadata, name);
	}

	if (osinfo_media_get_live (media)) {
		tracker_sparql_builder_predicate (metadata, "a");
		tracker_sparql_builder_object (metadata, "nfo:OperatingSystem");
	}

	if (osinfo_media_get_installer (media)) {
		tracker_sparql_builder_predicate (metadata, "a");
		tracker_sparql_builder_object (metadata, "osinfo:Installer");
	}

	tracker_sparql_builder_predicate (metadata, "nfo:isBootable");
	tracker_sparql_builder_object_boolean (metadata, bootable);

	id = osinfo_entity_get_id (OSINFO_ENTITY (os));
	if (id != NULL) {
		tracker_sparql_builder_predicate (metadata, "osinfo:id");
		tracker_sparql_builder_object_string (metadata, id);
	}

        id = osinfo_entity_get_id (OSINFO_ENTITY (media));
	if (id != NULL) {
		tracker_sparql_builder_predicate (metadata, "osinfo:mediaId");
		tracker_sparql_builder_object_string (metadata, id);
	}

	g_object_unref (G_OBJECT (media));
	g_object_unref (G_OBJECT (loader));

	return TRUE;

unknown_os:
        name = osinfo_media_get_volume_id (media);
	if (name != NULL) {
                gchar *stripped = g_strdup (name);

                g_strstrip (stripped);
		tracker_sparql_builder_predicate (metadata, "nie:title");
		tracker_sparql_builder_object_string (metadata, stripped);
                g_free (stripped);
	}

no_os:
	if (media != NULL) {
		g_object_unref (G_OBJECT (media));
	}
	if (loader != NULL) {
		g_object_unref (G_OBJECT (loader));
	}

	tracker_sparql_builder_predicate (metadata, "a");
	tracker_sparql_builder_object (metadata, "nfo:FilesystemImage");

	tracker_sparql_builder_predicate (metadata, "nfo:isBootable");
	tracker_sparql_builder_object_boolean (metadata, bootable);

	return TRUE;
}
static void
process_desktop_file (ProcessApplicationData  *data,
                      GFileInfo               *file_info,
                      GError                 **error)
{
	TrackerSparqlBuilder *sparql;
	GKeyFile *key_file;
	gchar *name = NULL;
	gchar *path;
	gchar *type;
	gchar *filename;
	gchar *uri = NULL;
	GStrv cats;
	gsize cats_len;
	gboolean is_software = TRUE;
	const gchar *parent_urn;
	gchar *lang;
#ifdef HAVE_MEEGOTOUCH
	gchar *logical_id = NULL;
	gchar *translation_catalog = NULL;
#endif /* HAVE_MEEGOTOUCH */

	sparql = data->sparql;
	key_file = data->key_file;
	type = data->type;

	path = g_file_get_path (data->file);

	/* Retrieve LANG locale setup */
	lang = tracker_locale_get (TRACKER_LOCALE_LANGUAGE);

	/* Try to get the categories with our desired LANG locale... */
	cats = g_key_file_get_locale_string_list (key_file, GROUP_DESKTOP_ENTRY, "Categories", lang, &cats_len, NULL);
	if (!cats) {
		/* If our desired locale failed, use the list of LANG locales prepared by GLib
		 * (will return untranslated string if none of the locales available) */
		cats = g_key_file_get_locale_string_list (key_file, GROUP_DESKTOP_ENTRY, "Categories", NULL, &cats_len, NULL);
	}

	/* NOTE: We sanitize categories later on when iterating them */

#ifdef HAVE_MEEGOTOUCH
	/* If defined, start with the logical strings */
	logical_id = g_key_file_get_string (key_file, GROUP_DESKTOP_ENTRY, "X-MeeGo-Logical-Id", NULL);
	translation_catalog = g_key_file_get_string (key_file, GROUP_DESKTOP_ENTRY, "X-MeeGo-Translation-Catalog", NULL);

	if (logical_id && translation_catalog) {
		name = tracker_meego_translate (translation_catalog, logical_id);
	}

	g_free (logical_id);
	g_free (translation_catalog);
#endif /* HAVE_MEEGOTOUCH */

	if (!name) {
		/* Try to get the name with our desired LANG locale... */
		name = g_key_file_get_locale_string (key_file, GROUP_DESKTOP_ENTRY, "Name", lang, NULL);
		if (!name) {
			/* If our desired locale failed, use the list of LANG locales prepared by GLib
			 * (will return untranslated string if none of the locales available) */
			name = g_key_file_get_locale_string (key_file, GROUP_DESKTOP_ENTRY, "Name", NULL, NULL);
		}
	}

	/* Sanitize name */
	if (name) {
		g_strstrip (name);
	}

	if (name && g_ascii_strcasecmp (type, "Directory") == 0) {
		gchar *canonical_uri = tracker_sparql_escape_uri_printf (SOFTWARE_CATEGORY_URN_PREFIX "%s", path);
		gchar *icon = g_key_file_get_string (key_file, GROUP_DESKTOP_ENTRY, "Icon", NULL);

		uri = canonical_uri;
		tracker_sparql_builder_insert_silent_open (sparql, TRACKER_OWN_GRAPH_URN);
		tracker_sparql_builder_subject_iri (sparql, uri);

		tracker_sparql_builder_predicate (sparql, "a");
		tracker_sparql_builder_object (sparql, "nfo:SoftwareCategory");

		if (icon) {
			gchar *escaped_icon;
			gchar *icon_uri;

			/* Sanitize icon */
			g_strstrip (icon);

			escaped_icon = g_uri_escape_string (icon, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, FALSE);

			icon_uri = g_strdup_printf (THEME_ICON_URN_PREFIX "%s", escaped_icon);

			tracker_sparql_builder_subject_iri (sparql, icon_uri);
			tracker_sparql_builder_predicate (sparql, "a");
			tracker_sparql_builder_object (sparql, "nfo:Image");

			tracker_sparql_builder_subject_iri (sparql, uri);
			tracker_sparql_builder_predicate (sparql, "nfo:softwareCategoryIcon");
			tracker_sparql_builder_object_iri (sparql, icon_uri);

			g_free (icon_uri);
			g_free (escaped_icon);
			g_free (icon);
		}

		is_software = FALSE;
	} else if (name && g_ascii_strcasecmp (type, "Application") == 0) {
		uri = g_file_get_uri (data->file);
		tracker_sparql_builder_insert_silent_open (sparql, TRACKER_OWN_GRAPH_URN);

		tracker_sparql_builder_subject_iri (sparql, APPLICATION_DATASOURCE_URN);
		tracker_sparql_builder_predicate (sparql, "a");
		tracker_sparql_builder_object (sparql, "nie:DataSource");

		tracker_sparql_builder_subject_iri (sparql, uri);

		tracker_sparql_builder_predicate (sparql, "a");
		tracker_sparql_builder_object (sparql, "nfo:SoftwareApplication");
		tracker_sparql_builder_object (sparql, "nie:DataObject");

		tracker_sparql_builder_predicate (sparql, "nie:dataSource");
		tracker_sparql_builder_object_iri (sparql, APPLICATION_DATASOURCE_URN);
	} else if (name && g_ascii_strcasecmp (type, "Link") == 0) {
		gchar *url = g_key_file_get_string (key_file, GROUP_DESKTOP_ENTRY, "URL", NULL);

		if (url) {
			uri = g_file_get_uri (data->file);
			tracker_sparql_builder_insert_silent_open (sparql, TRACKER_OWN_GRAPH_URN);

			tracker_sparql_builder_subject_iri (sparql, uri);
			tracker_sparql_builder_predicate (sparql, "a");
			tracker_sparql_builder_object (sparql, "nfo:Bookmark");

			tracker_sparql_builder_predicate (sparql, "nfo:bookmarks");
			tracker_sparql_builder_object_iri (sparql, url);

			tracker_sparql_builder_predicate (sparql, "nie:dataSource");
			tracker_sparql_builder_object_iri (sparql, APPLICATION_DATASOURCE_URN);

			is_software = FALSE;

			g_free (url);
		} else {
			g_warning ("Invalid desktop file: '%s'", uri);
			g_warning ("  Type 'Link' requires a URL");
		}
#ifdef HAVE_MEEGOTOUCH
	} else if (name && g_ascii_strcasecmp (type, "ControlPanelApplet") == 0) {
		/* Special case control panel applets */
		/* The URI of the InformationElement should be a UUID URN */
		uri = g_file_get_uri (data->file);
		tracker_sparql_builder_insert_silent_open (sparql, TRACKER_MINER_FS_GRAPH_URN);

		tracker_sparql_builder_subject_iri (sparql, APPLET_DATASOURCE_URN);
		tracker_sparql_builder_predicate (sparql, "a");
		tracker_sparql_builder_object (sparql, "nie:DataSource");

		/* TODO This is atm specific for Maemo */
		tracker_sparql_builder_subject_iri (sparql, uri);

		tracker_sparql_builder_predicate (sparql, "a");
		tracker_sparql_builder_object (sparql, "maemo:ControlPanelApplet");

		tracker_sparql_builder_predicate (sparql, "nie:dataSource");
		tracker_sparql_builder_object_iri (sparql, APPLET_DATASOURCE_URN);

		/* This matches SomeApplet as Type= */
	} else if (name && g_str_has_suffix (type, "Applet")) {
		/* The URI of the InformationElement should be a UUID URN */
		uri = g_file_get_uri (data->file);
		tracker_sparql_builder_insert_silent_open (sparql, TRACKER_MINER_FS_GRAPH_URN);

		tracker_sparql_builder_subject_iri (sparql, APPLET_DATASOURCE_URN);
		tracker_sparql_builder_predicate (sparql, "a");
		tracker_sparql_builder_object (sparql, "nie:DataSource");

		/* TODO This is atm specific for Maemo */
		tracker_sparql_builder_subject_iri (sparql, uri);

		tracker_sparql_builder_predicate (sparql, "a");
		tracker_sparql_builder_object (sparql, "maemo:SoftwareApplet");

		tracker_sparql_builder_predicate (sparql, "nie:dataSource");
		tracker_sparql_builder_object_iri (sparql, APPLET_DATASOURCE_URN);

	} else if (name && g_ascii_strcasecmp (type, "DUIApplication") == 0) {

		uri = g_file_get_uri (data->file);
		tracker_sparql_builder_insert_silent_open (sparql, TRACKER_MINER_FS_GRAPH_URN);

		tracker_sparql_builder_subject_iri (sparql, APPLICATION_DATASOURCE_URN);
		tracker_sparql_builder_predicate (sparql, "a");
		tracker_sparql_builder_object (sparql, "nie:DataSource");

		tracker_sparql_builder_subject_iri (sparql, uri);

		tracker_sparql_builder_predicate (sparql, "a");
		tracker_sparql_builder_object (sparql, "nfo:SoftwareApplication");
		tracker_sparql_builder_object (sparql, "nie:DataObject");

		tracker_sparql_builder_predicate (sparql, "nie:dataSource");
		tracker_sparql_builder_object_iri (sparql, APPLICATION_DATASOURCE_URN);
#endif /* HAVE_MEEGOTOUCH */
	} else {
		/* Invalid type, all valid types are already listed above */
		uri = g_file_get_uri (data->file);
		tracker_sparql_builder_insert_silent_open (sparql, TRACKER_OWN_GRAPH_URN);

		tracker_sparql_builder_subject_iri (sparql, APPLICATION_DATASOURCE_URN);
		tracker_sparql_builder_predicate (sparql, "a");
		tracker_sparql_builder_object (sparql, "nie:DataSource");

		tracker_sparql_builder_subject_iri (sparql, uri);

		tracker_sparql_builder_predicate (sparql, "a");
		tracker_sparql_builder_object (sparql, "nfo:SoftwareApplication");
		tracker_sparql_builder_object (sparql, "nie:DataObject");

		tracker_sparql_builder_predicate (sparql, "nie:dataSource");
		tracker_sparql_builder_object_iri (sparql, APPLICATION_DATASOURCE_URN);

		if (name) {
			/* If we got a name, then the issue comes from the type.
			 * As we're defaulting to Application here, we just g_debug() the problem. */
			g_debug ("Invalid desktop file: '%s'", uri);
			g_debug ("  Type '%s' is not part of the desktop file specification (expected 'Application', 'Link' or 'Directory')", type);
			g_debug ("  Defaulting to 'Application'");
		} else {
			/* If we didn't get a name, the problem is more severe as we don't default it
			 * to anything, so we g_warning() it.  */
			g_warning ("Invalid desktop file: '%s'", uri);
#ifdef HAVE_MEEGOTOUCH
			g_warning ("  Couldn't get name, missing or wrong key (X-MeeGo-Logical-Id, X-MeeGo-Translation-Catalog or Name)");
#else
			g_warning ("  Couldn't get name, missing key (Name)");
#endif
		}
	}

	if (sparql && uri) {
		gchar *desktop_file_uri;

		tracker_sparql_builder_predicate (sparql, "a");

		if (is_software) {
			tracker_sparql_builder_object (sparql, "nfo:Executable");
		}

		tracker_sparql_builder_object (sparql, "nfo:FileDataObject");
		tracker_sparql_builder_object (sparql, "nie:DataObject");

		/* Apparently this gets added by the file-module ATM
		   tracker_sparql_builder_predicate (sparql, "tracker:available");
		   tracker_sparql_builder_object_boolean (sparql, TRUE); */

		/* We should always always have a proper name if the desktop file is correct
		 * w.r.t to the Meego or Freedesktop specs, but sometimes this is not true,
		 * so instead of passing wrong stuff to the SPARQL builder, we avoid it.
		 * If we don't have a proper name, we already warned it before. */
		if (name) {
			tracker_sparql_builder_predicate (sparql, "nie:title");
			tracker_sparql_builder_object_string (sparql, name);
		}

		if (is_software) {
			gchar *icon;

			insert_data_from_desktop_file (sparql,
			                               uri,
			                               TRACKER_PREFIX_NIE "comment",
			                               key_file,
			                               "Comment",
			                               lang);
			insert_data_from_desktop_file (sparql,
			                               uri,
			                               TRACKER_PREFIX_NFO "softwareCmdLine",
			                               key_file,
			                               "Exec",
			                               lang);

			icon = g_key_file_get_string (key_file, GROUP_DESKTOP_ENTRY, "Icon", NULL);

			if (icon) {
				gchar *escaped_icon;
				gchar *icon_uri;

				/* Sanitize icon */
				g_strstrip (icon);

				escaped_icon = g_uri_escape_string (icon, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, FALSE);

				icon_uri = g_strdup_printf (THEME_ICON_URN_PREFIX "%s", escaped_icon);

				tracker_sparql_builder_subject_iri (sparql, icon_uri);
				tracker_sparql_builder_predicate (sparql, "a");
				tracker_sparql_builder_object (sparql, "nfo:Image");

				tracker_sparql_builder_subject_iri (sparql, uri);
				tracker_sparql_builder_predicate (sparql, "nfo:softwareIcon");
				tracker_sparql_builder_object_iri (sparql, icon_uri);

				g_free (icon_uri);
				g_free (escaped_icon);
				g_free (icon);
			}
		}

		if (cats) {
			gsize i;

			for (i = 0 ; cats[i] && i < cats_len ; i++) {
				gchar *cat_uri;
				gchar *cat;

				cat = cats[i];

				if (!cat) {
					continue;
				}

				/* Sanitize category */
				g_strstrip (cat);

				cat_uri = tracker_sparql_escape_uri_printf (SOFTWARE_CATEGORY_URN_PREFIX "%s", cat);

				/* There are also .desktop
				 * files that describe these categories, but we can handle
				 * preemptively creating them if we visit a app .desktop
				 * file that mentions one that we don't yet know about */

				tracker_sparql_builder_subject_iri (sparql, cat_uri);
				tracker_sparql_builder_predicate (sparql, "a");
				tracker_sparql_builder_object (sparql, "nfo:SoftwareCategory");

				tracker_sparql_builder_predicate (sparql, "nie:title");
				tracker_sparql_builder_object_string (sparql, cat);

				tracker_sparql_builder_subject_iri (sparql, uri);
				tracker_sparql_builder_predicate (sparql, "nie:isLogicalPartOf");
				tracker_sparql_builder_object_iri (sparql, cat_uri);

				g_free (cat_uri);
			}
		}

		filename = g_filename_display_basename (path);
		tracker_sparql_builder_predicate (sparql, "nfo:fileName");
		tracker_sparql_builder_object_string (sparql, filename);
		g_free (filename);

		/* The URL of the DataObject */
		desktop_file_uri = g_file_get_uri (data->file);
		tracker_sparql_builder_predicate (sparql, "nie:url");
		tracker_sparql_builder_object_string (sparql, desktop_file_uri);

		/* Laying the link between the IE and the DO */
		tracker_sparql_builder_subject_iri (sparql, uri);
		tracker_sparql_builder_predicate (sparql, "nie:isStoredAs");
		tracker_sparql_builder_object_iri (sparql, desktop_file_uri);


		g_free (desktop_file_uri);
	}

	if (file_info) {
		guint64 time;

		time = g_file_info_get_attribute_uint64 (file_info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
		tracker_sparql_builder_predicate (sparql, "nfo:fileLastModified");
		tracker_sparql_builder_object_date (sparql, (time_t *) &time);
	}

	parent_urn = tracker_miner_fs_get_parent_urn (TRACKER_MINER_FS (data->miner), data->file);

	if (parent_urn) {
		tracker_sparql_builder_predicate (sparql, "nfo:belongsToContainer");
		tracker_sparql_builder_object_iri (sparql, parent_urn);
	}

	tracker_sparql_builder_insert_close (sparql);

	g_strfreev (cats);

	g_free (uri);
	g_free (path);
	g_free (name);
	g_free (lang);
}
Example #5
0
G_MODULE_EXPORT gboolean
tracker_extract_get_metadata (TrackerExtractInfo *info)
{
	struct jpeg_decompress_struct cinfo;
	struct tej_error_mgr tejerr;
	struct jpeg_marker_struct *marker;
	TrackerSparqlBuilder *preupdate, *metadata;
	TrackerXmpData *xd = NULL;
	TrackerExifData *ed = NULL;
	TrackerIptcData *id = NULL;
	MergeData md = { 0 };
	GFile *file;
	FILE *f;
	goffset size;
	gchar *filename, *uri;
	gchar *comment = NULL;
	const gchar *dlna_profile, *dlna_mimetype, *graph;
	GPtrArray *keywords;
	gboolean success = TRUE;
	GString *where;
	guint i;

	metadata = tracker_extract_info_get_metadata_builder (info);
	preupdate = tracker_extract_info_get_preupdate_builder (info);
	graph = tracker_extract_info_get_graph (info);

	file = tracker_extract_info_get_file (info);
	filename = g_file_get_path (file);

	size = tracker_file_get_size (filename);

	if (size < 18) {
		g_free (filename);
		return FALSE;
	}

	f = tracker_file_open (filename);
	g_free (filename);

	if (!f) {
		return FALSE;
	}

	uri = g_file_get_uri (file);

	tracker_sparql_builder_predicate (metadata, "a");
	tracker_sparql_builder_object (metadata, "nfo:Image");
	tracker_sparql_builder_predicate (metadata, "a");
	tracker_sparql_builder_object (metadata, "nmm:Photo");

	cinfo.err = jpeg_std_error (&tejerr.jpeg);
	tejerr.jpeg.error_exit = extract_jpeg_error_exit;
	if (setjmp (tejerr.setjmp_buffer)) {
		success = FALSE;
		goto fail;
	}

	jpeg_create_decompress (&cinfo);

	jpeg_save_markers (&cinfo, JPEG_COM, 0xFFFF);
	jpeg_save_markers (&cinfo, JPEG_APP0 + 1, 0xFFFF);
	jpeg_save_markers (&cinfo, JPEG_APP0 + 13, 0xFFFF);

	jpeg_stdio_src (&cinfo, f);

	jpeg_read_header (&cinfo, TRUE);

	/* FIXME? It is possible that there are markers after SOS,
	 * but there shouldn't be. Should we decompress the whole file?
	 *
	 * jpeg_start_decompress(&cinfo);
	 * jpeg_finish_decompress(&cinfo);
	 *
	 * jpeg_calc_output_dimensions(&cinfo);
	 */

	marker = (struct jpeg_marker_struct *) &cinfo.marker_list;

	while (marker) {
		gchar *str;
		gsize len;
#ifdef HAVE_LIBIPTCDATA
		gsize offset;
		guint sublen;
#endif /* HAVE_LIBIPTCDATA */

		switch (marker->marker) {
		case JPEG_COM:
			g_free (comment);
			comment = g_strndup ((gchar*) marker->data, marker->data_length);
			break;

		case JPEG_APP0 + 1:
			str = (gchar*) marker->data;
			len = marker->data_length;

#ifdef HAVE_LIBEXIF
			if (strncmp (EXIF_NAMESPACE, str, EXIF_NAMESPACE_LENGTH) == 0) {
				ed = tracker_exif_new ((guchar *) marker->data, len, uri);
			}
#endif /* HAVE_LIBEXIF */

#ifdef HAVE_EXEMPI
			if (strncmp (XMP_NAMESPACE, str, XMP_NAMESPACE_LENGTH) == 0) {
				xd = tracker_xmp_new (str + XMP_NAMESPACE_LENGTH,
				                      len - XMP_NAMESPACE_LENGTH,
				                      uri);
			}
#endif /* HAVE_EXEMPI */

			break;

		case JPEG_APP0 + 13:
			str = (gchar*) marker->data;
			len = marker->data_length;
#ifdef HAVE_LIBIPTCDATA
			if (len > 0 && strncmp (PS3_NAMESPACE, str, PS3_NAMESPACE_LENGTH) == 0) {
				offset = iptc_jpeg_ps3_find_iptc (str, len, &sublen);
				if (offset > 0 && sublen > 0) {
					id = tracker_iptc_new (str + offset, sublen, uri);
				}
			}
#endif /* HAVE_LIBIPTCDATA */

			break;

		default:
			marker = marker->next;
			continue;
		}

		marker = marker->next;
	}

	if (!ed) {
		ed = g_new0 (TrackerExifData, 1);
	}

	if (!xd) {
		xd = g_new0 (TrackerXmpData, 1);
	}

	if (!id) {
		id = g_new0 (TrackerIptcData, 1);
	}

	md.title = tracker_coalesce_strip (4, xd->title, ed->document_name, xd->title2, xd->pdf_title);
	md.orientation = tracker_coalesce_strip (3, xd->orientation, ed->orientation, id->image_orientation);
	md.copyright = tracker_coalesce_strip (4, xd->copyright, xd->rights, ed->copyright, id->copyright_notice);
	md.white_balance = tracker_coalesce_strip (2, xd->white_balance, ed->white_balance);
	md.fnumber = tracker_coalesce_strip (2, xd->fnumber, ed->fnumber);
	md.flash = tracker_coalesce_strip (2, xd->flash, ed->flash);
	md.focal_length =  tracker_coalesce_strip (2, xd->focal_length, ed->focal_length);
	md.artist = tracker_coalesce_strip (3, xd->artist, ed->artist, xd->contributor);
	md.exposure_time = tracker_coalesce_strip (2, xd->exposure_time, ed->exposure_time);
	md.iso_speed_ratings = tracker_coalesce_strip (2, xd->iso_speed_ratings, ed->iso_speed_ratings);
	md.date = tracker_coalesce_strip (5, xd->date, xd->time_original, ed->time, id->date_created, ed->time_original);
	md.description = tracker_coalesce_strip (2, xd->description, ed->description);
	md.metering_mode = tracker_coalesce_strip (2, xd->metering_mode, ed->metering_mode);
	md.city = tracker_coalesce_strip (2, xd->city, id->city);
	md.state = tracker_coalesce_strip (2, xd->state, id->state);
	md.address = tracker_coalesce_strip (2, xd->address, id->sublocation);
	md.country = tracker_coalesce_strip (2, xd->country, id->country_name);

	/* FIXME We are not handling the altitude ref here for xmp */
	md.gps_altitude = tracker_coalesce_strip (2, xd->gps_altitude, ed->gps_altitude);
	md.gps_latitude = tracker_coalesce_strip (2, xd->gps_latitude, ed->gps_latitude);
	md.gps_longitude = tracker_coalesce_strip (2, xd->gps_longitude, ed->gps_longitude);
	md.gps_direction = tracker_coalesce_strip (2, xd->gps_direction, ed->gps_direction);
	md.creator = tracker_coalesce_strip (3, xd->creator, id->byline, id->credit);
	md.comment = tracker_coalesce_strip (2, comment, ed->user_comment);
	md.make = tracker_coalesce_strip (2, xd->make, ed->make);
	md.model = tracker_coalesce_strip (2, xd->model, ed->model);

	/* Prioritize on native dimention in all cases */
	tracker_sparql_builder_predicate (metadata, "nfo:width");
	tracker_sparql_builder_object_int64 (metadata, cinfo.image_width);

	/* TODO: add ontology and store ed->software */

	tracker_sparql_builder_predicate (metadata, "nfo:height");
	tracker_sparql_builder_object_int64 (metadata, cinfo.image_height);

	if (guess_dlna_profile (cinfo.image_width, cinfo.image_height, &dlna_profile, &dlna_mimetype)) {
		tracker_sparql_builder_predicate (metadata, "nmm:dlnaProfile");
		tracker_sparql_builder_object_string (metadata, dlna_profile);
		tracker_sparql_builder_predicate (metadata, "nmm:dlnaMime");
		tracker_sparql_builder_object_string (metadata, dlna_mimetype);
	}

	if (id->contact) {
		gchar *uri = tracker_sparql_escape_uri_printf ("urn:contact:%s", id->contact);

		tracker_sparql_builder_insert_open (preupdate, NULL);
		if (graph) {
			tracker_sparql_builder_graph_open (preupdate, graph);
		}

		tracker_sparql_builder_subject_iri (preupdate, uri);
		tracker_sparql_builder_predicate (preupdate, "a");
		tracker_sparql_builder_object (preupdate, "nco:Contact");
		tracker_sparql_builder_predicate (preupdate, "nco:fullname");
		tracker_sparql_builder_object_unvalidated (preupdate, id->contact);

		if (graph) {
			tracker_sparql_builder_graph_close (preupdate);
		}
		tracker_sparql_builder_insert_close (preupdate);

		tracker_sparql_builder_predicate (metadata, "nco:representative");
		tracker_sparql_builder_object_iri (metadata, uri);
		g_free (uri);
	}

	keywords = g_ptr_array_new ();

	if (xd->keywords) {
		tracker_keywords_parse (keywords, xd->keywords);
	}

	if (xd->pdf_keywords) {
		tracker_keywords_parse (keywords, xd->pdf_keywords);
	}

	if (xd->subject) {
		tracker_keywords_parse (keywords, xd->subject);
	}

	if (xd->publisher) {
		gchar *uri = tracker_sparql_escape_uri_printf ("urn:contact:%s", xd->publisher);

		tracker_sparql_builder_insert_open (preupdate, NULL);
		if (graph) {
			tracker_sparql_builder_graph_open (preupdate, graph);
		}

		tracker_sparql_builder_subject_iri (preupdate, uri);
		tracker_sparql_builder_predicate (preupdate, "a");
		tracker_sparql_builder_object (preupdate, "nco:Contact");
		tracker_sparql_builder_predicate (preupdate, "nco:fullname");
		tracker_sparql_builder_object_unvalidated (preupdate, xd->publisher);

		if (graph) {
			tracker_sparql_builder_graph_close (preupdate);
		}
		tracker_sparql_builder_insert_close (preupdate);

		tracker_sparql_builder_predicate (metadata, "nco:publisher");
		tracker_sparql_builder_object_iri (metadata, uri);
		g_free (uri);
	}

	if (xd->type) {
		tracker_sparql_builder_predicate (metadata, "dc:type");
		tracker_sparql_builder_object_unvalidated (metadata, xd->type);
	}

	if (xd->rating) {
		tracker_sparql_builder_predicate (metadata, "nao:numericRating");
		tracker_sparql_builder_object_unvalidated (metadata, xd->rating);
	}

	if (xd->format) {
		tracker_sparql_builder_predicate (metadata, "dc:format");
		tracker_sparql_builder_object_unvalidated (metadata, xd->format);
	}

	if (xd->identifier) {
		tracker_sparql_builder_predicate (metadata, "dc:identifier");
		tracker_sparql_builder_object_unvalidated (metadata, xd->identifier);
	}

	if (xd->source) {
		tracker_sparql_builder_predicate (metadata, "dc:source");
		tracker_sparql_builder_object_unvalidated (metadata, xd->source);
	}

	if (xd->language) {
		tracker_sparql_builder_predicate (metadata, "dc:language");
		tracker_sparql_builder_object_unvalidated (metadata, xd->language);
	}

	if (xd->relation) {
		tracker_sparql_builder_predicate (metadata, "dc:relation");
		tracker_sparql_builder_object_unvalidated (metadata, xd->relation);
	}

	if (xd->coverage) {
		tracker_sparql_builder_predicate (metadata, "dc:coverage");
		tracker_sparql_builder_object_unvalidated (metadata, xd->coverage);
	}

	if (xd->license) {
		tracker_sparql_builder_predicate (metadata, "nie:license");
		tracker_sparql_builder_object_unvalidated (metadata, xd->license);
	}

        if (xd->regions) {
	        tracker_xmp_apply_regions (preupdate, metadata, graph, xd);
        }

	if (id->keywords) {
		tracker_keywords_parse (keywords, id->keywords);
	}

	where = g_string_new ("");

	for (i = 0; i < keywords->len; i++) {
		gchar *p, *escaped, *var;

		p = g_ptr_array_index (keywords, i);
		escaped = tracker_sparql_escape_string (p);
		var = g_strdup_printf ("tag%d", i + 1);

		/* ensure tag with specified label exists */
		tracker_sparql_builder_append (preupdate, "INSERT { ");

		if (graph) {
			tracker_sparql_builder_append (preupdate, "GRAPH <");
			tracker_sparql_builder_append (preupdate, graph);
			tracker_sparql_builder_append (preupdate, "> { ");
		}

		tracker_sparql_builder_append (preupdate,
		                               "_:tag a nao:Tag ; nao:prefLabel \"");
		tracker_sparql_builder_append (preupdate, escaped);
		tracker_sparql_builder_append (preupdate, "\"");

		if (graph) {
			tracker_sparql_builder_append (preupdate, " } ");
		}

		tracker_sparql_builder_append (preupdate, " }\n");
		tracker_sparql_builder_append (preupdate,
		                               "WHERE { FILTER (NOT EXISTS { "
		                               "?tag a nao:Tag ; nao:prefLabel \"");
		tracker_sparql_builder_append (preupdate, escaped);
		tracker_sparql_builder_append (preupdate,
		                               "\" }) }\n");

		/* associate file with tag */
		tracker_sparql_builder_predicate (metadata, "nao:hasTag");
		tracker_sparql_builder_object_variable (metadata, var);

		g_string_append_printf (where, "?%s a nao:Tag ; nao:prefLabel \"%s\" .\n", var, escaped);

		g_free (var);
		g_free (escaped);
		g_free (p);
	}
	g_ptr_array_free (keywords, TRUE);

	tracker_extract_info_set_where_clause (info, where->str);
	g_string_free (where, TRUE);

	if (md.make || md.model) {
		gchar *equip_uri;

		equip_uri = tracker_sparql_escape_uri_printf ("urn:equipment:%s:%s:",
		                                              md.make ? md.make : "",
		                                              md.model ? md.model : "");

		tracker_sparql_builder_insert_open (preupdate, NULL);
		if (graph) {
			tracker_sparql_builder_graph_open (preupdate, graph);
		}

		tracker_sparql_builder_subject_iri (preupdate, equip_uri);
		tracker_sparql_builder_predicate (preupdate, "a");
		tracker_sparql_builder_object (preupdate, "nfo:Equipment");

		if (md.make) {
			tracker_sparql_builder_predicate (preupdate, "nfo:manufacturer");
			tracker_sparql_builder_object_unvalidated (preupdate, md.make);
		}
		if (md.model) {
			tracker_sparql_builder_predicate (preupdate, "nfo:model");
			tracker_sparql_builder_object_unvalidated (preupdate, md.model);
		}

		if (graph) {
			tracker_sparql_builder_graph_close (preupdate);
		}
		tracker_sparql_builder_insert_close (preupdate);

		tracker_sparql_builder_predicate (metadata, "nfo:equipment");
		tracker_sparql_builder_object_iri (metadata, equip_uri);
		g_free (equip_uri);
	}

	tracker_guarantee_title_from_file (metadata,
	                                   "nie:title",
	                                   md.title,
	                                   uri,
	                                   NULL);

	if (md.orientation) {
		tracker_sparql_builder_predicate (metadata, "nfo:orientation");
		tracker_sparql_builder_object (metadata, md.orientation);
	}

	if (md.copyright) {
		tracker_sparql_builder_predicate (metadata, "nie:copyright");
		tracker_sparql_builder_object_unvalidated (metadata, md.copyright);
	}

	if (md.white_balance) {
		tracker_sparql_builder_predicate (metadata, "nmm:whiteBalance");
		tracker_sparql_builder_object (metadata, md.white_balance);
	}

	if (md.fnumber) {
		gdouble value;

		value = g_strtod (md.fnumber, NULL);
		tracker_sparql_builder_predicate (metadata, "nmm:fnumber");
		tracker_sparql_builder_object_double (metadata, value);
	}

	if (md.flash) {
		tracker_sparql_builder_predicate (metadata, "nmm:flash");
		tracker_sparql_builder_object (metadata, md.flash);
	}

	if (md.focal_length) {
		gdouble value;

		value = g_strtod (md.focal_length, NULL);
		tracker_sparql_builder_predicate (metadata, "nmm:focalLength");
		tracker_sparql_builder_object_double (metadata, value);
	}

	if (md.artist) {
		gchar *uri = tracker_sparql_escape_uri_printf ("urn:contact:%s", md.artist);

		tracker_sparql_builder_insert_open (preupdate, NULL);
		if (graph) {
			tracker_sparql_builder_graph_open (preupdate, graph);
		}

		tracker_sparql_builder_subject_iri (preupdate, uri);
		tracker_sparql_builder_predicate (preupdate, "a");
		tracker_sparql_builder_object (preupdate, "nco:Contact");
		tracker_sparql_builder_predicate (preupdate, "nco:fullname");
		tracker_sparql_builder_object_unvalidated (preupdate, md.artist);

		if (graph) {
			tracker_sparql_builder_graph_close (preupdate);
		}
		tracker_sparql_builder_insert_close (preupdate);

		tracker_sparql_builder_predicate (metadata, "nco:contributor");
		tracker_sparql_builder_object_iri (metadata, uri);
		g_free (uri);
	}

	if (md.exposure_time) {
		gdouble value;

		value = g_strtod (md.exposure_time, NULL);
		tracker_sparql_builder_predicate (metadata, "nmm:exposureTime");
		tracker_sparql_builder_object_double (metadata, value);
	}

	if (md.iso_speed_ratings) {
		gdouble value;

		value = g_strtod (md.iso_speed_ratings, NULL);
		tracker_sparql_builder_predicate (metadata, "nmm:isoSpeed");
		tracker_sparql_builder_object_double (metadata, value);
	}

	tracker_guarantee_date_from_file_mtime (metadata,
	                                        "nie:contentCreated",
	                                        md.date,
	                                        uri);

	if (md.description) {
		tracker_sparql_builder_predicate (metadata, "nie:description");
		tracker_sparql_builder_object_unvalidated (metadata, md.description);
	}

	if (md.metering_mode) {
		tracker_sparql_builder_predicate (metadata, "nmm:meteringMode");
		tracker_sparql_builder_object (metadata, md.metering_mode);
	}

	if (md.creator) {
		gchar *uri = tracker_sparql_escape_uri_printf ("urn:contact:%s", md.creator);

		tracker_sparql_builder_insert_open (preupdate, NULL);
		if (graph) {
			tracker_sparql_builder_graph_open (preupdate, graph);
		}

		tracker_sparql_builder_subject_iri (preupdate, uri);
		tracker_sparql_builder_predicate (preupdate, "a");
		tracker_sparql_builder_object (preupdate, "nco:Contact");
		tracker_sparql_builder_predicate (preupdate, "nco:fullname");
		tracker_sparql_builder_object_unvalidated (preupdate, md.creator);

		if (graph) {
			tracker_sparql_builder_graph_close (preupdate);
		}
		tracker_sparql_builder_insert_close (preupdate);

		/* NOTE: We only have affiliation with
		 * nco:PersonContact and we are using
		 * nco:Contact here.
		 */

		/* if (id->byline_title) { */
		/* 	tracker_sparql_builder_insert_open (preupdate, NULL); */

		/* 	tracker_sparql_builder_subject (preupdate, "_:affiliation_by_line"); */
		/* 	tracker_sparql_builder_predicate (preupdate, "a"); */
		/* 	tracker_sparql_builder_object (preupdate, "nco:Affiliation"); */

		/* 	tracker_sparql_builder_predicate (preupdate, "nco:title"); */
		/* 	tracker_sparql_builder_object_unvalidated (preupdate, id->byline_title); */

		/* 	tracker_sparql_builder_insert_close (preupdate); */

		/*      tracker_sparql_builder_predicate (preupdate, "a"); */
		/*      tracker_sparql_builder_object (preupdate, "nco:Contact"); */
		/*      tracker_sparql_builder_predicate (preupdate, "nco:hasAffiliation"); */
		/*      tracker_sparql_builder_object (preupdate, "_:affiliation_by_line"); */
		/* } */

		tracker_sparql_builder_predicate (metadata, "nco:creator");
		tracker_sparql_builder_object_iri (metadata, uri);
		g_free (uri);
	}

	if (md.comment) {
		tracker_sparql_builder_predicate (metadata, "nie:comment");
		tracker_sparql_builder_object_unvalidated (metadata, md.comment);
	}

	if (md.address || md.state || md.country || md.city ||
	    md.gps_altitude || md.gps_latitude || md.gps_longitude) {

		tracker_sparql_builder_predicate (metadata, "slo:location");

		tracker_sparql_builder_object_blank_open (metadata); /* GeoPoint */
		tracker_sparql_builder_predicate (metadata, "a");
		tracker_sparql_builder_object (metadata, "slo:GeoLocation");

		if (md.address || md.state || md.country || md.city) {
			gchar *addruri;

			addruri = tracker_sparql_get_uuid_urn ();

			tracker_sparql_builder_predicate (metadata, "slo:postalAddress");
			tracker_sparql_builder_object_iri (metadata, addruri);

			tracker_sparql_builder_insert_open (preupdate, NULL);
			if (graph) {
				tracker_sparql_builder_graph_open (preupdate, graph);
			}

			tracker_sparql_builder_subject_iri (preupdate, addruri);

			g_free (addruri);

			tracker_sparql_builder_predicate (preupdate, "a");
			tracker_sparql_builder_object (preupdate, "nco:PostalAddress");

			if (md.address) {
				tracker_sparql_builder_predicate (preupdate, "nco:streetAddress");
				tracker_sparql_builder_object_unvalidated (preupdate, md.address);
			}

			if (md.state) {
				tracker_sparql_builder_predicate (preupdate, "nco:region");
				tracker_sparql_builder_object_unvalidated (preupdate, md.state);
			}

			if (md.city) {
				tracker_sparql_builder_predicate (preupdate, "nco:locality");
				tracker_sparql_builder_object_unvalidated (preupdate, md.city);
			}

			if (md.country) {
				tracker_sparql_builder_predicate (preupdate, "nco:country");
				tracker_sparql_builder_object_unvalidated (preupdate, md.country);
			}

			if (graph) {
				tracker_sparql_builder_graph_close (preupdate);
			}
			tracker_sparql_builder_insert_close (preupdate);
		}

		if (md.gps_altitude) {
			tracker_sparql_builder_predicate (metadata, "slo:altitude");
			tracker_sparql_builder_object_unvalidated (metadata, md.gps_altitude);
		}

		if (md.gps_latitude) {
			tracker_sparql_builder_predicate (metadata, "slo:latitude");
			tracker_sparql_builder_object_unvalidated (metadata, md.gps_latitude);
		}

		if (md.gps_longitude) {
			tracker_sparql_builder_predicate (metadata, "slo:longitude");
			tracker_sparql_builder_object_unvalidated (metadata, md.gps_longitude);
		}

		tracker_sparql_builder_object_blank_close (metadata); /* GeoLocation */
	}

	if (md.gps_direction) {
		tracker_sparql_builder_predicate (metadata, "nfo:heading");
		tracker_sparql_builder_object_unvalidated (metadata, md.gps_direction);
	}

	if (cinfo.density_unit != 0 || ed->x_resolution) {
		gdouble value;

		if (cinfo.density_unit == 0) {
			if (ed->resolution_unit != 3)
				value = g_strtod (ed->x_resolution, NULL);
			else
				value = g_strtod (ed->x_resolution, NULL) * CM_TO_INCH;
		} else {
			if (cinfo.density_unit == 1)
				value = cinfo.X_density;
			else
				value = cinfo.X_density * CM_TO_INCH;
		}

		tracker_sparql_builder_predicate (metadata, "nfo:horizontalResolution");
		tracker_sparql_builder_object_double (metadata, value);
	}

	if (cinfo.density_unit != 0 || ed->y_resolution) {
		gdouble value;

		if (cinfo.density_unit == 0) {
			if (ed->resolution_unit != 3)
				value = g_strtod (ed->y_resolution, NULL);
			else
				value = g_strtod (ed->y_resolution, NULL) * CM_TO_INCH;
		} else {
			if (cinfo.density_unit == 1)
				value = cinfo.Y_density;
			else
				value = cinfo.Y_density * CM_TO_INCH;
		}

		tracker_sparql_builder_predicate (metadata, "nfo:verticalResolution");
		tracker_sparql_builder_object_double (metadata, value);
	}

	jpeg_destroy_decompress (&cinfo);

	tracker_exif_free (ed);
	tracker_xmp_free (xd);
	tracker_iptc_free (id);
	g_free (comment);

fail:
	tracker_file_close (f, FALSE);
	g_free (uri);

	return success;
}
static inline void
process_item (ProcessUserguideData  *data,
              GFileInfo             *file_info,
              gboolean               is_dir,
              GError               **error)
{
	TrackerSparqlBuilder *sparql;
	gchar *uri;
	const gchar *mime_type;
	const gchar *urn;
	const gchar *parent_urn;
	gboolean is_iri;
	guint64 time_;

	sparql = data->sparql;

	uri = g_file_get_uri (data->file);
	mime_type = g_file_info_get_content_type (file_info);

	urn = get_file_urn (data->miner, data->file, &is_iri);

	tracker_sparql_builder_insert_silent_open (sparql, NULL);
	tracker_sparql_builder_graph_open (sparql, TRACKER_MINER_FS_GRAPH_URN);

	if (is_iri) {
		tracker_sparql_builder_subject_iri (sparql, urn);
	} else {
		tracker_sparql_builder_subject (sparql, urn);
	}

	tracker_sparql_builder_predicate (sparql, "a");
	tracker_sparql_builder_object (sparql, "nfo:FileDataObject");
	tracker_sparql_builder_object (sparql, "nie:InformationElement");

	if (is_dir) {
		tracker_sparql_builder_object (sparql, "nfo:Folder");
	} else {
		tracker_sparql_builder_object (sparql, "nfo:HelpDocument");
	}

	parent_urn = tracker_miner_fs_get_parent_urn (TRACKER_MINER_FS (data->miner), data->file);

	if (parent_urn) {
		tracker_sparql_builder_predicate (sparql, "nfo:belongsToContainer");
		tracker_sparql_builder_object_iri (sparql, parent_urn);
	}

	tracker_sparql_builder_predicate (sparql, "nfo:fileName");
	tracker_sparql_builder_object_string (sparql, g_file_info_get_display_name (file_info));

	tracker_sparql_builder_predicate (sparql, "nfo:fileSize");
	tracker_sparql_builder_object_int64 (sparql, g_file_info_get_size (file_info));

	time_ = g_file_info_get_attribute_uint64 (file_info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
	tracker_sparql_builder_predicate (sparql, "nfo:fileLastModified");
	tracker_sparql_builder_object_date (sparql, (time_t *) &time_);

	time_ = g_file_info_get_attribute_uint64 (file_info, G_FILE_ATTRIBUTE_TIME_ACCESS);
	tracker_sparql_builder_predicate (sparql, "nfo:fileLastAccessed");
	tracker_sparql_builder_object_date (sparql, (time_t *) &time_);

	/* Laying the link between the IE and the DO. We use IE = DO */
	tracker_sparql_builder_predicate (sparql, "nie:isStoredAs");
	if (is_iri) {
		tracker_sparql_builder_object_iri (sparql, urn);
	} else {
		tracker_sparql_builder_object (sparql, urn);
	}

	/* The URL of the DataObject (because IE = DO, this is correct) */
	tracker_sparql_builder_predicate (sparql, "nie:url");
	tracker_sparql_builder_object_string (sparql, uri);

	tracker_sparql_builder_predicate (sparql, "nie:mimeType");
	tracker_sparql_builder_object_string (sparql, mime_type);

	/* FIXME: Add nie:dataSource for switching different userguides? */
	tracker_sparql_builder_predicate (sparql, "tracker:available");
	tracker_sparql_builder_object_boolean (sparql, TRUE);

	if (!is_dir) {
		gchar *content = NULL;
		gchar *title = NULL;

		/* Get content */
		parser_get_file_content (uri, MAX_EXTRACT_SIZE, &content, &title);

		g_message ("Adding userguide:'%s', uri:'%s'",
		           title,
		           uri);

		if (title && title[0]) {
			tracker_sparql_builder_predicate (sparql, "nie:title");
			tracker_sparql_builder_object_unvalidated (sparql, title);
		}

		if (content && content[0]) {
			tracker_sparql_builder_predicate (sparql, "nie:plainTextContent");
			tracker_sparql_builder_object_unvalidated (sparql, content);
		}

		g_free (content);
		g_free (title);
	} else {
		g_message ("Adding userguide directory:'%s'", uri);
	}

	tracker_sparql_builder_graph_close (sparql);
	tracker_sparql_builder_insert_close (sparql);

	g_free (uri);
}
Example #7
0
G_MODULE_EXPORT gboolean
tracker_extract_get_metadata (TrackerExtractInfo *info)
{
	goffset size;
	FILE *f;
	png_structp png_ptr;
	png_infop info_ptr;
	png_infop end_ptr;
	png_bytepp row_pointers;
	guint row;
	png_uint_32 width, height;
	gint bit_depth, color_type;
	gint interlace_type, compression_type, filter_type;
	const gchar *dlna_profile, *dlna_mimetype, *graph;
	TrackerSparqlBuilder *preupdate, *metadata;
	gchar *filename, *uri;
	GString *where;
	GFile *file;

	file = tracker_extract_info_get_file (info);
	filename = g_file_get_path (file);
	size = tracker_file_get_size (filename);

	preupdate = tracker_extract_info_get_preupdate_builder (info);
	metadata = tracker_extract_info_get_metadata_builder (info);
	graph = tracker_extract_info_get_graph (info);

	if (size < 64) {
		return FALSE;
	}

	f = tracker_file_open (filename);
	g_free (filename);

	if (!f) {
		return FALSE;
	}

	png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING,
	                                  NULL,
	                                  NULL,
	                                  NULL);
	if (!png_ptr) {
		tracker_file_close (f, FALSE);
		return FALSE;
	}

	info_ptr = png_create_info_struct (png_ptr);
	if (!info_ptr) {
		png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
		tracker_file_close (f, FALSE);
		return FALSE;
	}

	end_ptr = png_create_info_struct (png_ptr);
	if (!end_ptr) {
		png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
		tracker_file_close (f, FALSE);
		return FALSE;
	}

	if (setjmp (png_jmpbuf (png_ptr))) {
		png_destroy_read_struct (&png_ptr, &info_ptr, &end_ptr);
		tracker_file_close (f, FALSE);
		return FALSE;
	}

	png_init_io (png_ptr, f);
	png_read_info (png_ptr, info_ptr);

	if (!png_get_IHDR (png_ptr,
	                   info_ptr,
	                   &width,
	                   &height,
	                   &bit_depth,
	                   &color_type,
	                   &interlace_type,
	                   &compression_type,
	                   &filter_type)) {
		png_destroy_read_struct (&png_ptr, &info_ptr, &end_ptr);
		tracker_file_close (f, FALSE);
		return FALSE;
	}

	/* Read the image. FIXME We should be able to skip this step and
	 * just get the info from the end. This causes some errors atm.
	 */
	row_pointers = g_new0 (png_bytep, height);

	for (row = 0; row < height; row++) {
		row_pointers[row] = png_malloc (png_ptr,
		                                png_get_rowbytes (png_ptr,info_ptr));
	}

	png_read_image (png_ptr, row_pointers);

	for (row = 0; row < height; row++) {
		png_free (png_ptr, row_pointers[row]);
	}

	g_free (row_pointers);

	png_read_end (png_ptr, end_ptr);

	tracker_sparql_builder_predicate (metadata, "a");
	tracker_sparql_builder_object (metadata, "nfo:Image");
	tracker_sparql_builder_object (metadata, "nmm:Photo");

	uri = g_file_get_uri (file);
	where = g_string_new ("");

	read_metadata (preupdate, metadata, where, png_ptr, info_ptr, end_ptr, uri, graph);
	tracker_extract_info_set_where_clause (info, where->str);
	g_string_free (where, TRUE);
	g_free (uri);

	tracker_sparql_builder_predicate (metadata, "nfo:width");
	tracker_sparql_builder_object_int64 (metadata, width);

	tracker_sparql_builder_predicate (metadata, "nfo:height");
	tracker_sparql_builder_object_int64 (metadata, height);

	if (guess_dlna_profile (bit_depth, width, height, &dlna_profile, &dlna_mimetype)) {
		tracker_sparql_builder_predicate (metadata, "nmm:dlnaProfile");
		tracker_sparql_builder_object_string (metadata, dlna_profile);
		tracker_sparql_builder_predicate (metadata, "nmm:dlnaMime");
		tracker_sparql_builder_object_string (metadata, dlna_mimetype);
	}

	png_destroy_read_struct (&png_ptr, &info_ptr, &end_ptr);
	tracker_file_close (f, FALSE);

	return TRUE;
}