Пример #1
0
G_MODULE_EXPORT gboolean
tracker_extract_get_metadata (TrackerExtractInfo *info)
{
	TIFF *image;
	TrackerXmpData *xd = NULL;
	TrackerIptcData *id = NULL;
	TrackerExifData *ed = NULL;
	MergeData md = { 0 };
	TiffData td = { 0 };
	gchar *filename, *uri;
	gchar *date;
	glong exif_offset;
	GPtrArray *keywords;
	guint i;
	GFile *file;
	TrackerSparqlBuilder *metadata, *preupdate;
	const gchar *graph, *urn;
	int fd;

#ifdef HAVE_LIBIPTCDATA
	gchar *iptc_offset;
	guint32 iptc_size;
#endif

#ifdef HAVE_EXEMPI
	gchar *xmp_offset;
	guint32 size;
#endif /* HAVE_EXEMPI */

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

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

	fd = tracker_file_open_fd (filename);

	if (fd == -1) {
		g_warning ("Could not open tiff file '%s': %s\n",
		           filename,
		           g_strerror (errno));
		g_free (filename);
		return FALSE;
	}	

	if ((image = TIFFFdOpen (fd, filename, "r")) == NULL){
		g_warning ("Could not open image:'%s'\n", filename);
		g_free (filename);
		close (fd);
		return FALSE;
	}

	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);

#ifdef HAVE_LIBIPTCDATA
	if (TIFFGetField (image, 
	                  TIFFTAG_RICHTIFFIPTC, 
	                  &iptc_size, 
	                  &iptc_offset)) {
		if (TIFFIsByteSwapped(image) != 0) {
			TIFFSwabArrayOfLong((uint32*) iptc_offset, 
			                    (unsigned long) iptc_size);
		}
		id = tracker_iptc_new (iptc_offset, 4 * iptc_size, uri);
	}
#endif /* HAVE_LIBIPTCDATA */

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

	/* FIXME There are problems between XMP data embedded with different tools
	   due to bugs in the original spec (type) */
#ifdef HAVE_EXEMPI
	if (TIFFGetField (image, TIFFTAG_XMLPACKET, &size, &xmp_offset)) {
		xd = tracker_xmp_new (xmp_offset, size, uri);
	}
#endif /* HAVE_EXEMPI */

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

	ed = g_new0 (TrackerExifData, 1);

	/* Get Tiff specifics */
	td.width = tag_to_string (image, TIFFTAG_IMAGEWIDTH, TAG_TYPE_UINT32);
	td.length = tag_to_string (image, TIFFTAG_IMAGELENGTH, TAG_TYPE_UINT32);
	td.artist = tag_to_string (image, TIFFTAG_ARTIST, TAG_TYPE_STRING);
	td.copyright = tag_to_string (image, TIFFTAG_COPYRIGHT, TAG_TYPE_STRING);

	date = tag_to_string (image, TIFFTAG_DATETIME, TAG_TYPE_STRING);
	td.date = tracker_date_guess (date);
	g_free (date);

	td.title = tag_to_string (image, TIFFTAG_DOCUMENTNAME, TAG_TYPE_STRING);
	td.description = tag_to_string (image, TIFFTAG_IMAGEDESCRIPTION, TAG_TYPE_STRING);
	td.make = tag_to_string (image, TIFFTAG_MAKE, TAG_TYPE_STRING);
	td.model = tag_to_string (image, TIFFTAG_MODEL, TAG_TYPE_STRING);
	td.orientation = get_orientation (image);

	/* Get Exif specifics */
	if (TIFFGetField (image, TIFFTAG_EXIFIFD, &exif_offset)) {
		if (TIFFReadEXIFDirectory (image, exif_offset)) {
			ed->exposure_time = tag_to_string (image, EXIFTAG_EXPOSURETIME, TAG_TYPE_DOUBLE);
			ed->fnumber = tag_to_string (image, EXIFTAG_FNUMBER, TAG_TYPE_DOUBLE);
			ed->iso_speed_ratings = tag_to_string (image, EXIFTAG_ISOSPEEDRATINGS, TAG_TYPE_C16_UINT16);
			date = tag_to_string (image, EXIFTAG_DATETIMEORIGINAL, TAG_TYPE_STRING);
			ed->time_original = tracker_date_guess (date);
			g_free (date);

			ed->metering_mode = get_metering_mode (image);
			ed->flash = get_flash (image);
			ed->focal_length = tag_to_string (image, EXIFTAG_DATETIMEORIGINAL, TAG_TYPE_DOUBLE);
			ed->white_balance = get_white_balance (image);
			/* ed->software = tag_to_string (image, EXIFTAG_SOFTWARE, TAG_TYPE_STRING); */
		}
	}

	TIFFClose (image);
	g_free (filename);

	md.title = tracker_coalesce_strip (5, xd->title, xd->pdf_title, td.title, ed->document_name, xd->title2);
	md.orientation = tracker_coalesce_strip (4, xd->orientation, td.orientation, ed->orientation, id->image_orientation);
	md.copyright = tracker_coalesce_strip (4, xd->rights, td.copyright, 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 (4, xd->artist, td.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 (6, xd->date, xd->time_original, td.date, ed->time, id->date_created, ed->time_original);
	md.description = tracker_coalesce_strip (3, xd->description, td.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.x_dimension = tracker_coalesce_strip (2, td.width, ed->x_dimension);
	md.y_dimension = tracker_coalesce_strip (2, td.length, ed->y_dimension);
	md.make = tracker_coalesce_strip (3, xd->make, td.make, ed->make);
	md.model = tracker_coalesce_strip (3, xd->model, td.model, ed->model);

	keywords = g_ptr_array_new_with_free_func ((GDestroyNotify) g_free);

	if (ed->user_comment) {
		tracker_sparql_builder_predicate (metadata, "nie:comment");
		tracker_sparql_builder_object_unvalidated (metadata, ed->user_comment);
	}

	if (md.x_dimension) {
		tracker_sparql_builder_predicate (metadata, "nfo:width");
		tracker_sparql_builder_object_unvalidated (metadata, md.x_dimension);
	}

	if (md.y_dimension) {
		tracker_sparql_builder_predicate (metadata, "nfo:height");
		tracker_sparql_builder_object_unvalidated (metadata, md.y_dimension);
	}

	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->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->rating) {
		tracker_sparql_builder_predicate (metadata, "nao:numericRating");
		tracker_sparql_builder_object_unvalidated (metadata, xd->rating);
	}

	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 (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 (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);
	}

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

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

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

		/* ensure tag with specified label exists */
		tracker_sparql_builder_insert_open (preupdate, graph);
		tracker_sparql_builder_subject (preupdate, subject);
		tracker_sparql_builder_predicate (preupdate, "a");
		tracker_sparql_builder_object (preupdate, "nao:Tag");
		tracker_sparql_builder_predicate (preupdate, "nao:prefLabel");
		tracker_sparql_builder_object_unvalidated (preupdate, escaped);
		tracker_sparql_builder_insert_close (preupdate);
		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_insert_open (preupdate, graph);
		tracker_sparql_builder_subject_iri (preupdate, urn);
		tracker_sparql_builder_predicate (preupdate, "nao:hasTag");
		tracker_sparql_builder_object (preupdate, "?tag");
		tracker_sparql_builder_insert_close (preupdate);
		tracker_sparql_builder_where_open (preupdate);
		tracker_sparql_builder_subject (preupdate, "?tag");
		tracker_sparql_builder_predicate (preupdate, "a");
		tracker_sparql_builder_object (preupdate, "nao:Tag");
		tracker_sparql_builder_predicate (preupdate, "nao:prefLabel");
		tracker_sparql_builder_object_unvalidated (preupdate, escaped);
		tracker_sparql_builder_where_close (preupdate);

		g_free (subject);
		g_free (escaped);
	}
	g_ptr_array_free (keywords, 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_unvalidated (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_unvalidated (metadata, md.white_balance);
	}

	if (md.fnumber) {
		tracker_sparql_builder_predicate (metadata, "nmm:fnumber");
		tracker_sparql_builder_object_unvalidated (metadata, md.fnumber);
	}

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

	if (md.focal_length) {
		tracker_sparql_builder_predicate (metadata, "nmm:focalLength");
		tracker_sparql_builder_object_unvalidated (metadata, md.focal_length);
	}

	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) {
		tracker_sparql_builder_predicate (metadata, "nmm:exposureTime");
		tracker_sparql_builder_object_unvalidated (metadata, md.exposure_time);
	}

	if (md.iso_speed_ratings) {
		tracker_sparql_builder_predicate (metadata, "nmm:isoSpeed");
		tracker_sparql_builder_object_unvalidated (metadata, md.iso_speed_ratings);
	}

	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_unvalidated (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 (metadata, "a"); */
		/* 	tracker_sparql_builder_object (metadata, "nco:PersonContact"); */
		/* 	tracker_sparql_builder_predicate (metadata, "nco:hasAffiliation"); */
		/* 	tracker_sparql_builder_object (metadata, "_:affiliation_by_line"); */
		/* } */

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

	if (ed->x_resolution) {
		gdouble value;

		value = ed->resolution_unit != 3 ? g_strtod (ed->x_resolution, NULL) : g_strtod (ed->x_resolution, NULL) * CM_TO_INCH;
		tracker_sparql_builder_predicate (metadata, "nfo:horizontalResolution");
		tracker_sparql_builder_object_double (metadata, value);
	}

	if (ed->y_resolution) {
		gdouble value;

		value = ed->resolution_unit != 3 ? g_strtod (ed->y_resolution, NULL) : g_strtod (ed->y_resolution, NULL) * CM_TO_INCH;
		tracker_sparql_builder_predicate (metadata, "nfo:verticalResolution");
		tracker_sparql_builder_object_double (metadata, value);
	}

	tiff_data_free (&td);
	tracker_exif_free (ed);
	tracker_xmp_free (xd);
	tracker_iptc_free (id);
	g_free (uri);
	close (fd);

	return TRUE;
}
Пример #2
0
static void
opf_xml_text_handler (GMarkupParseContext   *context,
                      const gchar           *text,
                      gsize                  text_len,
                      gpointer               user_data,
                      GError               **error)
{
	OPFData *data = user_data;

	switch (data->element) {
	case OPF_TAG_TYPE_PUBLISHER:
		if (data->has_publisher) {
			g_warning ("Avoiding additional publisher (%s) in EPUB '%s'",
			           text, data->uri);
		} else {
			data->has_publisher = TRUE;
			tracker_sparql_builder_predicate (data->metadata, "nco:publisher");

			tracker_sparql_builder_object_blank_open (data->metadata);
			tracker_sparql_builder_predicate (data->metadata, "a");
			tracker_sparql_builder_object (data->metadata, "nco:Contact");

			tracker_sparql_builder_predicate (data->metadata, "nco:fullname");
			tracker_sparql_builder_object_unvalidated (data->metadata, text);
			tracker_sparql_builder_object_blank_close (data->metadata);
		}
		break;
	case OPF_TAG_TYPE_AUTHOR:
	case OPF_TAG_TYPE_EDITOR:
	case OPF_TAG_TYPE_ILLUSTRATOR:
	case OPF_TAG_TYPE_CONTRIBUTOR: {
		gchar *fname, *gname, *oname;
		const gchar *fullname = NULL;
		gchar *role_uri = NULL;
		const gchar *role_str = NULL;
		gint i, j = 0, len;

		fname = NULL;
		gname = NULL;
		oname = NULL;

		/* parse name.  may not work for dissimilar cultures. */
		if (data->savedstring != NULL) {
			fullname = data->savedstring;

			/* <family name>, <given name> <other name> */
			g_debug ("Parsing 'opf:file-as' attribute:'%s'", data->savedstring);
			len = strlen (data->savedstring);

			for (i = 0; i < len; i++) {
				if (data->savedstring[i] == ',') {
					fname = g_strndup (data->savedstring, i);
					g_debug ("Found family name:'%s'", fname);

					for (; data->savedstring[i] == ',' || data->savedstring[i] == ' '; i++);
					j = i;

					break;
				}
			}

			if (i == len) {
				fname = g_strdup (data->savedstring);
				g_debug ("Found only one name");
			} else {
				for (; i <= len; i++) {
					if (i == len || data->savedstring[i] == ' ') {
						gname = g_strndup (data->savedstring + j, i - j);
						g_debug ("Found given name:'%s'", gname);

						for (; data->savedstring[i] == ',' || data->savedstring[i] == ' '; i++);

						if (i != len) {
							oname = g_strdup (data->savedstring + i);
							g_debug ("Found other name:'%s'", oname);
						}

						break;
					}
				}
			}
		} else {
			fullname = text;

			/* <given name> <other name> <family name> */
			g_debug ("Parsing name, no 'opf:file-as' found: '%s'", text);

			len = strlen (text);

			for (i = 0; i < len; i++) {
				if (text[i] == ' ') {
					gname = g_strndup (text, i);
					g_debug ("Found given name:'%s'", gname);
					j = i + 1;

					break;
				}
			}

			if (j == 0) {
				fname = g_strdup (data->savedstring);
				g_debug ("Found only one name:'%s'", fname);
			} else {
				for (i = len - 1; i >= j - 1; i--) {
					if (text[i] == ' ') {
						fname = g_strdup (text + i + 1);
						g_debug ("Found family name:'%s'", fname);

						if (i > j) {
							oname = g_strndup (text + j, i - j);
							g_debug ("Found other name:'%s'", oname);
						}

						break;
					}
				}
			}
		}

		/* Role details */
		role_uri = tracker_sparql_escape_uri_printf ("urn:artist:%s", fullname);

		if (data->element == OPF_TAG_TYPE_AUTHOR) {
			role_str = "nco:creator";
		} else if (data->element == OPF_TAG_TYPE_EDITOR && !data->has_publisher) {
			/* Should this be nco:contributor ?
			 * 'Editor' is a bit vague here.
			 */
			role_str = "nco:publisher";
		} else if (data->element == OPF_TAG_TYPE_ILLUSTRATOR) {
			/* There is no illustrator class, using contributor */
			role_str = "nco:contributor";
		} else {
			g_assert ("Unknown role");
		}

		if (role_uri) {
			tracker_sparql_builder_insert_open (data->preupdate, NULL);
			if (data->graph) {
				tracker_sparql_builder_graph_open (data->preupdate, data->graph);
			}

			tracker_sparql_builder_subject_iri (data->preupdate, role_uri);
			tracker_sparql_builder_predicate (data->preupdate, "a");
			tracker_sparql_builder_object (data->preupdate, "nmm:Artist");
			tracker_sparql_builder_predicate (data->preupdate, "nmm:artistName");
			tracker_sparql_builder_object_unvalidated (data->preupdate, fullname);

			if (data->graph) {
				tracker_sparql_builder_graph_close (data->preupdate);
			}
			tracker_sparql_builder_insert_close (data->preupdate);
		}

		/* Creator contact details */
		tracker_sparql_builder_predicate (data->metadata, "nco:creator");
		tracker_sparql_builder_object_blank_open (data->metadata);
		tracker_sparql_builder_predicate (data->metadata, "a");
		tracker_sparql_builder_object (data->metadata, "nco:PersonContact");
		tracker_sparql_builder_predicate (data->metadata, "nco:fullname");
		tracker_sparql_builder_object_unvalidated (data->metadata, fullname);

		if (fname) {
			tracker_sparql_builder_predicate (data->metadata, "nco:nameFamily");
			tracker_sparql_builder_object_unvalidated (data->metadata, fname);
			g_free (fname);
		}

		if (gname) {
			tracker_sparql_builder_predicate (data->metadata, "nco:nameGiven");
			tracker_sparql_builder_object_unvalidated (data->metadata, gname);
			g_free (gname);
		}

		if (oname) {
			tracker_sparql_builder_predicate (data->metadata, "nco:nameAdditional");
			tracker_sparql_builder_object_unvalidated (data->metadata, oname);
			g_free (oname);
		}

		if (role_uri) {
			tracker_sparql_builder_predicate (data->metadata, role_str);
			tracker_sparql_builder_object_iri (data->metadata, role_uri);
			g_free (role_uri);
		}

		tracker_sparql_builder_object_blank_close (data->metadata);

		break;
	}
	case OPF_TAG_TYPE_TITLE:
		if (data->has_title) {
			g_warning ("Avoiding additional title (%s) in EPUB '%s'",
			           text, data->uri);
		} else {
			data->has_title = TRUE;
			tracker_sparql_builder_predicate (data->metadata, "nie:title");
			tracker_sparql_builder_object_unvalidated (data->metadata, text);
		}
		break;
	case OPF_TAG_TYPE_CREATED: {
		if (data->has_content_created) {
			g_warning ("Avoiding additional creation time (%s) in EPUB '%s'",
			           text, data->uri);
		} else {
			gchar *date = tracker_date_guess (text);

			if (date) {
				data->has_content_created = TRUE;
				tracker_sparql_builder_predicate (data->metadata, "nie:contentCreated");
				tracker_sparql_builder_object_unvalidated (data->metadata, date);
				g_free (date);
			} else {
				g_warning ("Could not parse creation time (%s) in EPUB '%s'",
				           text, data->uri);
			}
		}
		break;
	}
	case OPF_TAG_TYPE_LANGUAGE:
		if (data->has_language) {
			g_warning ("Avoiding additional language (%s) in EPUB '%s'",
			           text, data->uri);
		} else {
			data->has_language = TRUE;
			tracker_sparql_builder_predicate (data->metadata, "nie:language");
			tracker_sparql_builder_object_unvalidated (data->metadata, text);
		}
		break;
	case OPF_TAG_TYPE_SUBJECT:
		if (data->has_subject) {
			g_warning ("Avoiding additional subject (%s) in EPUB '%s'",
			           text, data->uri);
		} else {
			data->has_subject = TRUE;
			tracker_sparql_builder_predicate (data->metadata, "nie:subject");
			tracker_sparql_builder_object_unvalidated (data->metadata, text);
		}
		break;
	case OPF_TAG_TYPE_DESCRIPTION:
		if (data->has_description) {
			g_warning ("Avoiding additional description (%s) in EPUB '%s'",
			           text, data->uri);
		} else {
			data->has_description = TRUE;
			tracker_sparql_builder_predicate (data->metadata, "nie:description");
			tracker_sparql_builder_object_unvalidated (data->metadata, text);
		}
		break;
	case OPF_TAG_TYPE_UUID:
	case OPF_TAG_TYPE_ISBN:
		if (data->has_identifier) {
			g_warning ("Avoiding additional identifier (%s) in EPUB '%s'",
			           text, data->uri);
		} else {
			data->has_identifier = TRUE;
			tracker_sparql_builder_predicate (data->metadata, "nie:identifier");
			tracker_sparql_builder_object_unvalidated (data->metadata, text);
		}
		break;
	/* case OPF_TAG_TYPE_RATING: */
	case OPF_TAG_TYPE_UNKNOWN:
	default:
		break;
	}

	opf_data_clear_saved_string (data);
}
Пример #3
0
G_MODULE_EXPORT gboolean
tracker_extract_get_metadata (TrackerExtractInfo *info)
{
	GFile *file;
	TrackerSparqlBuilder *metadata;
	TrackerSparqlBuilder *preupdate;
	const gchar *graph;
	gchar *absolute_file_path;
	gchar *uri;
	AVFormatContext *format = NULL;
	AVStream *audio_stream = NULL;
	AVStream *video_stream = NULL;
	int audio_stream_index;
	int video_stream_index;
	AVDictionaryEntry *tag = NULL;
	const char *title = NULL;

	av_register_all ();

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

	uri = g_file_get_uri (file);

	absolute_file_path = g_file_get_path (file);
	if (avformat_open_input (&format, absolute_file_path, NULL, NULL)) {
		g_free (absolute_file_path);
		g_free (uri);
		return FALSE;
	}
	g_free (absolute_file_path);

	avformat_find_stream_info (format, NULL);

	audio_stream_index = av_find_best_stream (format, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
	if (audio_stream_index >= 0) {
		audio_stream = format->streams[audio_stream_index];
	}

	video_stream_index = av_find_best_stream (format, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
	if (video_stream_index >= 0) {
		video_stream = format->streams[video_stream_index];
	}

	if (!audio_stream && !video_stream) {
		avformat_free_context (format);
		g_free (uri);
		return FALSE;
	}

	if (audio_stream) {
		if (audio_stream->codec->sample_rate > 0) {
			set_value_int64 (metadata, "nfo:sampleRate", audio_stream->codec->sample_rate);
		}
		if (audio_stream->codec->channels > 0) {
			set_value_int64 (metadata, "nfo:channels", audio_stream->codec->channels);
		}
	}

	if (video_stream) {
		tracker_sparql_builder_predicate (metadata, "a");
		tracker_sparql_builder_object (metadata, "nmm:Video");

		if (video_stream->codec->width > 0 && video_stream->codec->height > 0) {
			set_value_int64 (metadata, "nfo:width", video_stream->codec->width);
			set_value_int64 (metadata, "nfo:height", video_stream->codec->height);
		}

		if (video_stream->avg_frame_rate.num > 0) {
			gdouble frame_rate = (gdouble) video_stream->avg_frame_rate.num
			                     / video_stream->avg_frame_rate.den;
			set_value_double (metadata, "nfo:frameRate", frame_rate);
		}

		if (video_stream->duration > 0) {
			gint64 duration = av_rescale(video_stream->duration, video_stream->time_base.num,
			                             video_stream->time_base.den);
			set_value_int64 (metadata, "nfo:duration", duration);
		}

		if (video_stream->sample_aspect_ratio.num > 0) {
			gdouble aspect_ratio = (gdouble) video_stream->sample_aspect_ratio.num
			                       / video_stream->sample_aspect_ratio.den;
			set_value_double (metadata, "nfo:aspectRatio", aspect_ratio);
		}

		if (video_stream->nb_frames > 0) {
			set_value_int64 (metadata, "nfo:frameCount", video_stream->nb_frames);
		}

		if ((tag = av_dict_get (format->metadata, "synopsis", NULL, 0))) {
			set_value_string (metadata, "nmm:synopsis", tag->value);
		}

		if ((tag = av_dict_get (format->metadata, "episode_sort", NULL, 0))) {
			set_value_int64 (metadata, "nmm:episodeNumber", atoi(tag->value));
		}

		if ((tag = av_dict_get (format->metadata, "season_number", NULL, 0))) {
			set_value_int64 (metadata, "nmm:season", atoi(tag->value));
		}

	} else if (audio_stream) {
		const char *album_title = NULL;
		const char *album_artist = NULL;
		gchar *album_artist_uri = NULL;
		gchar *performer_uri = NULL;

		tracker_sparql_builder_predicate (metadata, "a");
		tracker_sparql_builder_object (metadata, "nmm:MusicPiece");
		tracker_sparql_builder_object (metadata, "nfo:Audio");

		if (audio_stream->duration > 0) {
			gint64 duration = av_rescale(audio_stream->duration, audio_stream->time_base.num,
			                             audio_stream->time_base.den);
			set_value_int64 (metadata, "nfo:duration", duration);
		}

		if ((tag = find_tag (format, audio_stream, "track"))) {
			int track = atoi(tag->value);
			if (track > 0) {
				set_value_int64 (metadata, "nmm:trackNumber", track);
			}
		}

		if ((tag = find_tag (format, audio_stream, "album"))) {
			album_title = tag->value;
		}

		if (album_title && (tag = find_tag (format, audio_stream, "album_artist"))) {
			album_artist_uri = create_artist (preupdate, graph, tag->value);
			album_artist = tag->value;
		}

		if ((tag = find_tag (format, audio_stream, "artist"))) {
			performer_uri = create_artist (preupdate, graph, tag->value);
			if (!album_artist) {
				album_artist = tag->value;
			}
		}

		if (!performer_uri && (tag = find_tag (format, audio_stream, "performer"))) {
			performer_uri = create_artist (preupdate, graph, tag->value);
			if (!album_artist) {
				album_artist = tag->value;
			}
		}

		if (performer_uri) {
			set_value_iri (metadata, "nmm:performer", performer_uri);
		} else if (album_artist_uri) {
			set_value_iri (metadata, "nmm:performer", album_artist_uri);
		}

		if ((tag = find_tag (format, audio_stream, "composer"))) {
			gchar *composer_uri = create_artist (preupdate, graph, tag->value);
			set_value_iri (metadata, "nmm:composer", composer_uri);
			g_free(composer_uri);
		}


		if (album_title) {
			int disc = 1;
			gchar *disc_uri;
			gchar *album_uri = tracker_sparql_escape_uri_printf ("urn:album:%s", album_title);

			open_insert (preupdate, graph, album_uri, "nmm:MusicAlbum");
			set_value_string (preupdate, "nmm:albumTitle", album_title);
			if (album_artist_uri) {
				set_value_iri (preupdate, "nmm:albumArtist", album_artist_uri);
			} else if (performer_uri) {
				set_value_iri (preupdate, "nmm:albumArtist", performer_uri);
			}
			close_insert (preupdate, graph);


			if ((tag = find_tag (format, audio_stream, "disc"))) {
				disc = atoi (tag->value);
			}

			disc_uri = tracker_sparql_escape_uri_printf ("urn:album-disc:%s:Disc%d",
			                                             album_title,
			                                             disc);

			delete_value (preupdate, disc_uri, "nmm:setNumber", "unknown");
			delete_value (preupdate, disc_uri, "nmm:albumDiscAlbum", "unknown");

			open_insert (preupdate, graph, disc_uri, "nmm:MusicAlbumDisc");
			set_value_int64 (preupdate, "nmm:setNumber", disc);
			set_value_iri (preupdate, "nmm:albumDiscAlbum", album_uri);
			close_insert (preupdate, graph);

			set_value_iri (metadata, "nmm:musicAlbumDisc", disc_uri);
			set_value_iri (metadata, "nmm:musicAlbum", album_uri);

			g_free (disc_uri);
			g_free (album_uri);
		}

#ifdef HAVE_LIBMEDIAART
		if (album_artist || album_title) {
			MediaArtProcess *media_art_process;
			GError *error = NULL;
			gboolean success;

			media_art_process = tracker_extract_info_get_media_art_process (info);
			success = media_art_process_file (media_art_process,
			                                  MEDIA_ART_ALBUM,
			                                  MEDIA_ART_PROCESS_FLAGS_NONE,
			                                  file,
			                                  album_artist,
			                                  album_title,
			                                  &error);

			if (!success || error) {
				g_warning ("Could not process media art for '%s', %s",
				           uri,
				           error ? error->message : "No error given");
				g_clear_error (&error);
			}
		}
#endif

		g_free(performer_uri);
	}

	if (format->bit_rate > 0) {
		set_value_int64 (metadata, "nfo:averageBitrate", format->bit_rate);
	}


	if ((tag = av_dict_get (format->metadata, "comment", NULL, 0))) {
		set_value_string (metadata, "nie:comment", tag->value);
	}

	if ((tag = av_dict_get (format->metadata, "copyright", NULL, 0))) {
		set_value_string (metadata, "nie:copyright", tag->value);
	}

	if ((tag = av_dict_get (format->metadata, "creation_time", NULL, 0))) {
		gchar *content_created = tracker_date_guess (tag->value);
		if (content_created) {
			set_value_string (metadata, "nie:contentCreated", content_created);
			g_free (content_created);
		}
	}

	if ((tag = av_dict_get (format->metadata, "description", NULL, 0))) {
		set_value_string (metadata, "nie:description", tag->value);
	}

	if ((tag = av_dict_get (format->metadata, "genre", NULL, 0))) {
		set_value_string (metadata, "nfo:genre", tag->value);
	}

	if ((tag = av_dict_get (format->metadata, "language", NULL, 0))) {
		set_value_string (metadata, "nfo:language", tag->value);
	}

	if ((tag = av_dict_get (format->metadata, "title", NULL, 0))) {
		title = tag->value;
	}

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

	g_free (uri);

	avformat_free_context (format);

	return TRUE;
}
Пример #4
0
G_MODULE_EXPORT gboolean
tracker_extract_get_metadata (TrackerExtractInfo *info)
{
	TrackerSparqlBuilder *preupdate, *metadata;
	VorbisData vd = { 0 };
	MergeData md = { 0 };
	FILE *f;
	gchar *filename;
	OggVorbis_File vf;
	vorbis_comment *comment;
	vorbis_info *vi;
	unsigned int bitrate;
	gint time;
	GFile *file;
	const gchar *graph;

	file = tracker_extract_info_get_file (info);
	filename = g_file_get_path (file);
	f = tracker_file_open (filename);
	g_free (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 (!f) {
		return FALSE;
	}

	if (ov_open (f, &vf, NULL, 0) < 0) {
		tracker_file_close (f, FALSE);
		return FALSE;
	}

	tracker_sparql_builder_predicate (metadata, "a");
	tracker_sparql_builder_object (metadata, "nmm:MusicPiece");
	tracker_sparql_builder_object (metadata, "nfo:Audio");

	if ((comment = ov_comment (&vf, -1)) != NULL) {
		gchar *date;

		vd.title = ogg_get_comment (comment, "title");
		vd.artist = ogg_get_comment (comment, "artist");
		vd.album = ogg_get_comment (comment, "album");
		vd.album_artist = ogg_get_comment (comment, "albumartist");
		vd.track_count = ogg_get_comment (comment, "trackcount");
		vd.track_number = ogg_get_comment (comment, "tracknumber");
		vd.disc_number = ogg_get_comment (comment, "DiscNo");
		vd.performer = ogg_get_comment (comment, "Performer");
		vd.track_gain = ogg_get_comment (comment, "TrackGain");
		vd.track_peak_gain = ogg_get_comment (comment, "TrackPeakGain");
		vd.album_gain = ogg_get_comment (comment, "AlbumGain");
		vd.album_peak_gain = ogg_get_comment (comment, "AlbumPeakGain");

		date = ogg_get_comment (comment, "date");
		vd.date = tracker_date_guess (date);
		g_free (date);

		vd.comment = ogg_get_comment (comment, "comment");
		vd.genre = ogg_get_comment (comment, "genre");
		vd.codec = ogg_get_comment (comment, "Codec");
		vd.codec_version = ogg_get_comment (comment, "CodecVersion");
		vd.sample_rate = ogg_get_comment (comment, "SampleRate");
		vd.channels = ogg_get_comment (comment, "Channels");
		vd.mb_album_id = ogg_get_comment (comment, "MBAlbumID");
		vd.mb_artist_id = ogg_get_comment (comment, "MBArtistID");
		vd.mb_album_artist_id = ogg_get_comment (comment, "MBAlbumArtistID");
		vd.mb_track_id = ogg_get_comment (comment, "MBTrackID");
		vd.lyrics = ogg_get_comment (comment, "Lyrics");
		vd.copyright = ogg_get_comment (comment, "Copyright");
		vd.license = ogg_get_comment (comment, "License");
		vd.organization = ogg_get_comment (comment, "Organization");
		vd.location = ogg_get_comment (comment, "Location");
		vd.publisher = ogg_get_comment (comment, "Publisher");

		vorbis_comment_clear (comment);
	}

	md.creator = tracker_coalesce_strip (3, vd.artist, vd.album_artist, vd.performer);

	if (md.creator) {
		/* NOTE: This must be created before vd.album is evaluated */
		md.creator_uri = tracker_sparql_escape_uri_printf ("urn:artist:%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, md.creator_uri);
		tracker_sparql_builder_predicate (preupdate, "a");
		tracker_sparql_builder_object (preupdate, "nmm:Artist");
		tracker_sparql_builder_predicate (preupdate, "nmm:artistName");
		tracker_sparql_builder_object_unvalidated (preupdate, md.creator);

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

		tracker_sparql_builder_predicate (metadata, "nmm:performer");
		tracker_sparql_builder_object_iri (metadata, md.creator_uri);
	}

	if (vd.album) {
                gchar *uri;
                if (vd.album_artist) {
                        uri = tracker_sparql_escape_uri_printf ("urn:album:%s:%s", vd.album, vd.album_artist);
                } else {
                        uri = tracker_sparql_escape_uri_printf ("urn:album:%s", vd.album);
                }
		gchar *album_disc_uri;

		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, "nmm:MusicAlbum");
		/* FIXME: nmm:albumTitle is now deprecated
		 * tracker_sparql_builder_predicate (preupdate, "nie:title");
		 */
		tracker_sparql_builder_predicate (preupdate, "nmm:albumTitle");
		tracker_sparql_builder_object_unvalidated (preupdate, vd.album);

		if (md.creator_uri) {
			tracker_sparql_builder_predicate (preupdate, "nmm:albumArtist");
			tracker_sparql_builder_object_iri (preupdate, md.creator_uri);
		}

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

		if (vd.track_count) {
			tracker_sparql_builder_delete_open (preupdate, NULL);
			tracker_sparql_builder_subject_iri (preupdate, uri);
			tracker_sparql_builder_predicate (preupdate, "nmm:albumTrackCount");
			tracker_sparql_builder_object_variable (preupdate, "unknown");
			tracker_sparql_builder_delete_close (preupdate);

			tracker_sparql_builder_where_open (preupdate);
			tracker_sparql_builder_subject_iri (preupdate, uri);
			tracker_sparql_builder_predicate (preupdate, "nmm:albumTrackCount");
			tracker_sparql_builder_object_variable (preupdate, "unknown");
			tracker_sparql_builder_where_close (preupdate);

			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, "nmm:albumTrackCount");
			tracker_sparql_builder_object_unvalidated (preupdate, vd.track_count);

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

		if (vd.album_gain) {
			tracker_sparql_builder_delete_open (preupdate, NULL);
			tracker_sparql_builder_subject_iri (preupdate, uri);
			tracker_sparql_builder_predicate (preupdate, "nmm:albumGain");
			tracker_sparql_builder_object_variable (preupdate, "unknown");
			tracker_sparql_builder_delete_close (preupdate);

			tracker_sparql_builder_where_open (preupdate);
			tracker_sparql_builder_subject_iri (preupdate, uri);
			tracker_sparql_builder_predicate (preupdate, "nmm:albumGain");
			tracker_sparql_builder_object_variable (preupdate, "unknown");
			tracker_sparql_builder_where_close (preupdate);

			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, "nmm:albumGain");
			tracker_sparql_builder_object_double (preupdate, atof (vd.album_gain));

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

		if (vd.album_peak_gain) {
			tracker_sparql_builder_delete_open (preupdate, NULL);
			tracker_sparql_builder_subject_iri (preupdate, uri);
			tracker_sparql_builder_predicate (preupdate, "nmm:albumPeakGain");
			tracker_sparql_builder_object_variable (preupdate, "unknown");
			tracker_sparql_builder_delete_close (preupdate);

			tracker_sparql_builder_where_open (preupdate);
			tracker_sparql_builder_subject_iri (preupdate, uri);
			tracker_sparql_builder_predicate (preupdate, "nmm:albumPeakGain");
			tracker_sparql_builder_object_variable (preupdate, "unknown");
			tracker_sparql_builder_where_close (preupdate);

			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, "nmm:albumPeakGain");
			tracker_sparql_builder_object_double (preupdate, atof (vd.album_peak_gain));

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

                if (vd.album_artist) {
                        album_disc_uri = tracker_sparql_escape_uri_printf ("urn:album-disc:%s:%s:Disc%d",
                                                                           vd.album, vd.album_artist,
                                                                           vd.disc_number ? atoi(vd.disc_number) : 1);
                } else {
                        album_disc_uri = tracker_sparql_escape_uri_printf ("urn:album-disc:%s:Disc%d",
                                                                           vd.album,
                                                                           vd.disc_number ? atoi(vd.disc_number) : 1);
                }

		tracker_sparql_builder_delete_open (preupdate, NULL);
		tracker_sparql_builder_subject_iri (preupdate, album_disc_uri);
		tracker_sparql_builder_predicate (preupdate, "nmm:setNumber");
		tracker_sparql_builder_object_variable (preupdate, "unknown");
		tracker_sparql_builder_delete_close (preupdate);
		tracker_sparql_builder_where_open (preupdate);
		tracker_sparql_builder_subject_iri (preupdate, album_disc_uri);
		tracker_sparql_builder_predicate (preupdate, "nmm:setNumber");
		tracker_sparql_builder_object_variable (preupdate, "unknown");
		tracker_sparql_builder_where_close (preupdate);

		tracker_sparql_builder_delete_open (preupdate, NULL);
		tracker_sparql_builder_subject_iri (preupdate, album_disc_uri);
		tracker_sparql_builder_predicate (preupdate, "nmm:albumDiscAlbum");
		tracker_sparql_builder_object_variable (preupdate, "unknown");
		tracker_sparql_builder_delete_close (preupdate);
		tracker_sparql_builder_where_open (preupdate);
		tracker_sparql_builder_subject_iri (preupdate, album_disc_uri);
		tracker_sparql_builder_predicate (preupdate, "nmm:albumDiscAlbum");
		tracker_sparql_builder_object_variable (preupdate, "unknown");
		tracker_sparql_builder_where_close (preupdate);

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

		tracker_sparql_builder_subject_iri (preupdate, album_disc_uri);
		tracker_sparql_builder_predicate (preupdate, "a");
		tracker_sparql_builder_object (preupdate, "nmm:MusicAlbumDisc");
		tracker_sparql_builder_predicate (preupdate, "nmm:setNumber");
		tracker_sparql_builder_object_int64 (preupdate, vd.disc_number ? atoi (vd.disc_number) : 1);
		tracker_sparql_builder_predicate (preupdate, "nmm:albumDiscAlbum");
		tracker_sparql_builder_object_iri (preupdate, uri);

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

		tracker_sparql_builder_predicate (metadata, "nmm:musicAlbumDisc");
		tracker_sparql_builder_object_iri (metadata, album_disc_uri);

		g_free (album_disc_uri);
		g_free (vd.album);

		tracker_sparql_builder_predicate (metadata, "nmm:musicAlbum");
		tracker_sparql_builder_object_iri (metadata, uri);
		g_free (uri);
	}

	g_free (vd.track_count);
	g_free (vd.album_peak_gain);
	g_free (vd.album_gain);
	g_free (vd.disc_number);

	if (vd.title) {
		tracker_sparql_builder_predicate (metadata, "nie:title");
		tracker_sparql_builder_object_unvalidated (metadata, vd.title);
		g_free (vd.title);
	}

	if (vd.track_number) {
		tracker_sparql_builder_predicate (metadata, "nmm:trackNumber");
		tracker_sparql_builder_object_unvalidated (metadata, vd.track_number);
		g_free (vd.track_number);
	}

	if (vd.track_gain) {
		/* TODO */
		g_free (vd.track_gain);
	}

	if (vd.track_peak_gain) {
		/* TODO */
		g_free (vd.track_peak_gain);
	}

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

	if (vd.date) {
		tracker_sparql_builder_predicate (metadata, "nie:contentCreated");
		tracker_sparql_builder_object_unvalidated (metadata, vd.date);
		g_free (vd.date);
	}

	if (vd.genre) {
		tracker_sparql_builder_predicate (metadata, "nfo:genre");
		tracker_sparql_builder_object_unvalidated (metadata, vd.genre);
		g_free (vd.genre);
	}

	if (vd.codec) {
		tracker_sparql_builder_predicate (metadata, "nfo:codec");
		tracker_sparql_builder_object_unvalidated (metadata, vd.codec);
		g_free (vd.codec);
	}

	if (vd.codec_version) {
		/* TODO */
		g_free (vd.codec_version);
	}

	if (vd.sample_rate) {
		tracker_sparql_builder_predicate (metadata, "nfo:sampleRate");
		tracker_sparql_builder_object_unvalidated (metadata, vd.sample_rate);
		g_free (vd.sample_rate);
	}

	if (vd.channels) {
		tracker_sparql_builder_predicate (metadata, "nfo:channels");
		tracker_sparql_builder_object_unvalidated (metadata, vd.channels);
		g_free (vd.channels);
	}

	if (vd.mb_album_id) {
		/* TODO */
		g_free (vd.mb_album_id);
	}

	if (vd.mb_artist_id) {
		/* TODO */
		g_free (vd.mb_artist_id);
	}

	if (vd.mb_album_artist_id) {
		/* TODO */
		g_free (vd.mb_album_artist_id);
	}

	if (vd.mb_track_id) {
		/* TODO */
		g_free (vd.mb_track_id);
	}

	if (vd.lyrics) {
		tracker_sparql_builder_predicate (metadata, "nie:plainTextContent");
		tracker_sparql_builder_object_unvalidated (metadata, vd.lyrics);
		g_free (vd.lyrics);
	}

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

	if (vd.license) {
		tracker_sparql_builder_predicate (metadata, "nie:license");
		tracker_sparql_builder_object_unvalidated (metadata, vd.license);
		g_free (vd.license);
	}

	if (vd.organization) {
		/* TODO */
		g_free (vd.organization);
	}

	if (vd.location) {
		/* TODO */
		g_free (vd.location);
	}

	if (vd.publisher) {
		tracker_sparql_builder_predicate (metadata, "dc:publisher");

		tracker_sparql_builder_object_blank_open (metadata);
		tracker_sparql_builder_predicate (metadata, "a");
		tracker_sparql_builder_object (metadata, "nco:Contact");

		tracker_sparql_builder_predicate (metadata, "nco:fullname");
		tracker_sparql_builder_object_unvalidated (metadata, vd.publisher);
		tracker_sparql_builder_object_blank_close (metadata);
		g_free (vd.publisher);
	}

	if ((vi = ov_info (&vf, 0)) != NULL ) {
		bitrate = vi->bitrate_nominal / 1000;

		tracker_sparql_builder_predicate (metadata, "nfo:averageBitrate");
		tracker_sparql_builder_object_int64 (metadata, (gint64) bitrate);
	}

	/* Duration */
	if ((time = ov_time_total (&vf, -1)) != OV_EINVAL) {
		tracker_sparql_builder_predicate (metadata, "nfo:duration");
		tracker_sparql_builder_object_int64 (metadata, (gint64) time);
	}

	g_free (vd.artist);
	g_free (vd.album_artist);
	g_free (vd.performer);

	g_free (md.creator_uri);

#ifdef HAVE_POSIX_FADVISE
	posix_fadvise (fileno (f), 0, 0, POSIX_FADV_DONTNEED);
#endif /* HAVE_POSIX_FADVISE */

	/* NOTE: This calls fclose on the file */
	ov_clear (&vf);

	return TRUE;
}
static void
xml_text_handler_metadata (GMarkupParseContext  *context,
                           const gchar          *text,
                           gsize                 text_len,
                           gpointer              user_data,
                           GError              **error)
{
	ODTMetadataParseInfo *data;
	TrackerResource *metadata;
	gchar *date;

	data = user_data;
	metadata = data->metadata;

	if (text_len == 0) {
		/* ignore empty values */
		return;
	}

	switch (data->current) {
	case ODT_TAG_TYPE_TITLE:
		if (data->has_title) {
			g_warning ("Avoiding additional title (%s) in OASIS document '%s'",
			           text, data->uri);
		} else {
			data->has_title = TRUE;
			tracker_resource_set_string (metadata, "nie:title", text);
		}
		break;

	case ODT_TAG_TYPE_SUBJECT:
		if (data->has_subject) {
			g_warning ("Avoiding additional subject (%s) in OASIS document '%s'",
			           text, data->uri);
		} else {
			data->has_subject = TRUE;
			tracker_resource_set_string (metadata, "nie:subject", text);
		}
		break;

	case ODT_TAG_TYPE_AUTHOR:
		if (data->has_publisher) {
			g_warning ("Avoiding additional publisher (%s) in OASIS document '%s'",
			           text, data->uri);
		} else {
			TrackerResource *publisher = tracker_extract_new_contact (text);

			data->has_publisher = TRUE;
			tracker_resource_set_relation (metadata, "nco:publisher", publisher);

			g_object_unref (publisher);
		}
		break;

	case ODT_TAG_TYPE_KEYWORDS: {
		gchar *keywords;
		gchar *lasts, *keyw;

		keywords = g_strdup (text);

		for (keyw = strtok_r (keywords, ",; ", &lasts);
		     keyw;
		     keyw = strtok_r (NULL, ",; ", &lasts)) {
			tracker_resource_add_string (metadata, "nie:keyword", keyw);
		}

		g_free (keywords);

		break;
	}

	case ODT_TAG_TYPE_COMMENTS:
		if (data->has_comment) {
			g_warning ("Avoiding additional comment (%s) in OASIS document '%s'",
			           text, data->uri);
		} else {
			data->has_comment = TRUE;
			tracker_resource_set_string (metadata, "nie:comment", text);
		}
		break;

	case ODT_TAG_TYPE_CREATED:
		if (data->has_content_created) {
			g_warning ("Avoiding additional creation time (%s) in OASIS document '%s'",
			           text, data->uri);
		} else {
			date = tracker_date_guess (text);
			if (date) {
				data->has_content_created = TRUE;
				tracker_resource_set_string (metadata, "nie:contentCreated", date);
				g_free (date);
			} else {
				g_warning ("Could not parse creation time (%s) in OASIS document '%s'",
				           text, data->uri);
			}
		}
		break;

	case ODT_TAG_TYPE_GENERATOR:
		if (data->has_generator) {
			g_warning ("Avoiding additional creation time (%s) in OASIS document '%s'",
			           text, data->uri);
		} else {
			data->has_generator = TRUE;
			tracker_resource_set_string (metadata, "nie:generator", text);
		}
		break;

	default:
	case ODT_TAG_TYPE_STATS:
		break;
	}
}
Пример #6
0
static void
parse_vorbis_comments (FLAC__StreamMetadata_VorbisComment *comment,
                       FlacData                           *fd)
{
	gint i;

	/* FIXME: I hate the amount of duplicating this does, complete
	   memory fragmentation. We should be able to use some
	   GStringChunks */
	for (i = 0; i < comment->num_comments; i++) {
		FLAC__StreamMetadata_VorbisComment_Entry entry;

		entry = comment->comments[i];

		/* entry.entry is the format NAME=metadata */
		if (g_ascii_strncasecmp (entry.entry, "title", 5) == 0) {
			fd->title = g_strdup (entry.entry + 6);
		} else if (g_ascii_strncasecmp (entry.entry, "artist", 6) == 0) {
			/* FIXME: Handle multiple instances of artist */
			if (fd->artist == NULL) {
				fd->artist = g_strdup (entry.entry + 7);
			}
		} else if (g_ascii_strncasecmp (entry.entry, "album", 5) == 0) {
			fd->album = g_strdup (entry.entry + 6);
		} else if (g_ascii_strncasecmp (entry.entry, "albumartist", 11) == 0) {
			fd->albumartist = g_strdup (entry.entry + 12);
		} else if (g_ascii_strncasecmp (entry.entry, "trackcount", 10) == 0) {
			fd->trackcount = g_strdup (entry.entry + 11);
		} else if (g_ascii_strncasecmp (entry.entry, "tracknumber", 11) == 0) {
			fd->tracknumber = g_strdup (entry.entry + 12);
		} else if (g_ascii_strncasecmp (entry.entry, "discno", 6) == 0) {
			fd->discno = g_strdup (entry.entry + 7);
		} else if (g_ascii_strncasecmp (entry.entry, "performer", 9) == 0) {
			/* FIXME: Handle multiple instances of performer */
			if (fd->performer == NULL) {
				fd->performer = g_strdup (entry.entry + 10);
			}
		} else if (g_ascii_strncasecmp (entry.entry, "trackgain", 9) == 0) {
			fd->trackgain = g_strdup (entry.entry + 10);
		} else if (g_ascii_strncasecmp (entry.entry, "trackpeakgain", 13) == 0) {
			fd->trackpeakgain = g_strdup (entry.entry + 14);
		} else if (g_ascii_strncasecmp (entry.entry, "albumgain", 9) == 0) {
			fd->albumgain = g_strdup (entry.entry + 10);
		} else if (g_ascii_strncasecmp (entry.entry, "albumpeakgain", 13) == 0) {
			fd->albumpeakgain = g_strdup (entry.entry + 14);
		} else if (g_ascii_strncasecmp (entry.entry, "date", 4) == 0) {
			fd->date = tracker_date_guess (entry.entry + 5);
		} else if (g_ascii_strncasecmp (entry.entry, "comment", 7) == 0) {
			fd->comment = g_strdup (entry.entry + 8);
		} else if (g_ascii_strncasecmp (entry.entry, "genre", 5) == 0) {
			fd->genre = g_strdup (entry.entry + 6);
		} else if (g_ascii_strncasecmp (entry.entry, "mbalbumid", 9) == 0) {
			fd->mbalbumid = g_strdup (entry.entry + 10);
		} else if (g_ascii_strncasecmp (entry.entry, "mbartistid", 10) == 0) {
			fd->mbartistid = g_strdup (entry.entry + 11);
		} else if (g_ascii_strncasecmp (entry.entry, "mbalbumartistid", 15) == 0) {
			fd->mbalbumartistid = g_strdup (entry.entry + 16);
		} else if (g_ascii_strncasecmp (entry.entry, "mbtrackid", 9) == 0) {
			fd->mbtrackid = g_strdup (entry.entry + 10);
		} else if (g_ascii_strncasecmp (entry.entry, "lyrics", 6) == 0) {
			fd->lyrics = g_strdup (entry.entry + 7);
		} else if (g_ascii_strncasecmp (entry.entry, "copyright", 9) == 0) {
			fd->copyright = g_strdup (entry.entry + 10);
		} else if (g_ascii_strncasecmp (entry.entry, "license", 8) == 0) {
			fd->license = g_strdup (entry.entry + 9);
		} else if (g_ascii_strncasecmp (entry.entry, "organization", 12) == 0) {
			fd->organisation = g_strdup (entry.entry + 13);
		} else if (g_ascii_strncasecmp (entry.entry, "location", 8) == 0) {
			fd->location = g_strdup (entry.entry + 9);
		} else if (g_ascii_strncasecmp (entry.entry, "publisher", 9) == 0) {
			fd->publisher = g_strdup (entry.entry + 10);
		}
	}
}