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