Index: configure.in =================================================================== RCS file: /cvs/gnome/tracker/configure.in,v retrieving revision 1.18 diff -u -p -r1.18 configure.in --- configure.in 26 Sep 2006 00:52:38 -0000 1.18 +++ configure.in 27 Sep 2006 03:07:13 -0000 @@ -347,6 +347,34 @@ AC_SUBST(THEORA_LIBS) test "$have_theora" = "yes" && AC_DEFINE(HAVE_THEORA, [], [Define if we have libtheora]) +################################################################## +# check for libpng +################################################################## + +LIBPNG_REQUIRED=1.2 + +PKG_CHECK_MODULES(LIBPNG, [libpng >= $LIBPNG_REQUIRED], [have_libpng=yes] , [have_png=no]) + +AM_CONDITIONAL(HAVE_LIBPNG, test "$have_libpng" = "yes") +AC_SUBST(LIBPNG_CFLAGS) +AC_SUBST(LIBPNG_LIBS) +test "$have_libpng" = "yes" && AC_DEFINE(HAVE_LIBPNG, [], [Define if we have libpng]) + + +################################################################## +# check for libexif +################################################################## + +LIBEXIF_REQUIRED=0.6 + +PKG_CHECK_MODULES(LIBEXIF, [libexif >= $LIBEXIF_REQUIRED], [have_libexif=yes] , [have_libexif=no]) + +AM_CONDITIONAL(HAVE_LIBEXIF, test "$have_libexif" = "yes") +AC_SUBST(LIBEXIF_CFLAGS) +AC_SUBST(LIBEXIF_LIBS) +test "$have_libexif" = "yes" && AC_DEFINE(HAVE_LIBEXIF, [], [Define if we have libexif]) + + ##################################################### AM_CONFIG_HEADER(src/trackerd/config.h) @@ -395,5 +423,7 @@ Metadata extractors: pdf : $have_poppler ogg/vorbis : $have_vorbis ogg/theora : $have_theora + png : $have_libpng + exif (jpeg) : $have_libexif " Index: src/trackerd/Makefile.am =================================================================== RCS file: /cvs/gnome/tracker/src/trackerd/Makefile.am,v retrieving revision 1.11 diff -u -p -r1.11 Makefile.am --- src/trackerd/Makefile.am 26 Sep 2006 00:52:39 -0000 1.11 +++ src/trackerd/Makefile.am 27 Sep 2006 03:07:25 -0000 @@ -15,9 +15,6 @@ INCLUDES = \ $(FAM_CFLAGS) \ $(DBUS_CFLAGS) \ $(MYSQL_CFLAGS) \ - $(POPPLER_GLIB_CFLAGS) \ - $(VORBIS_CFLAGS) \ - $(THEORA_CFLAGS) \ $(additional_mysql_flags) \ $(CFLAGS) \ -g @@ -101,11 +98,6 @@ trackerd_SOURCES = \ tracker-mbox.h \ tracker-metadata.c \ tracker-metadata.h \ - tracker-metadata-oasis.c \ - tracker-metadata-ps.c \ - tracker-metadata-pdf.c \ - tracker-metadata-abw.c \ - tracker-metadata-vorbis.c \ tracker-rdf-query.c \ tracker-rdf-query.h \ tracker-stemmer-english.c \ @@ -138,9 +130,6 @@ trackerd_LDADD = $(GLIB2_LIBS) \ $(GMIME_LIBS) \ $(QDBM_LIBS) \ $(SQLITE3_LIBS) \ - $(POPPLER_GLIB_LIBS) \ - $(VORBIS_LIBS) \ - $(THEORA_LIBS) \ -lbz2 \ -lstdc++ Index: src/trackerd/trackerd.c =================================================================== RCS file: /cvs/gnome/tracker/src/trackerd/trackerd.c,v retrieving revision 1.38 diff -u -p -r1.38 trackerd.c --- src/trackerd/trackerd.c 26 Sep 2006 00:52:39 -0000 1.38 +++ src/trackerd/trackerd.c 27 Sep 2006 03:08:05 -0000 @@ -1953,8 +1953,6 @@ main (int argc, char **argv) sigaction (SIGUSR1, &act, NULL); sigaction (SIGINT, &act, NULL); - g_type_init (); - if (!g_thread_supported ()) { g_thread_init (NULL); } Index: src/trackerd/tracker-metadata.c =================================================================== RCS file: /cvs/gnome/tracker/src/trackerd/tracker-metadata.c,v retrieving revision 1.11 diff -u -p -r1.11 tracker-metadata.c --- src/trackerd/tracker-metadata.c 26 Sep 2006 10:28:53 -0000 1.11 +++ src/trackerd/tracker-metadata.c 27 Sep 2006 03:08:21 -0000 @@ -127,39 +127,6 @@ char *development_mime_types[] = { }; -typedef void (*MetadataExtractFunc)(gchar *, GHashTable *); -typedef struct { - char *mime; - MetadataExtractFunc extractor; -} MimeToExtractor; - -void tracker_metadata_extract_oasis (gchar *, GHashTable *); -void tracker_metadata_extract_ps (gchar *, GHashTable *); -#ifdef HAVE_POPPLER -void tracker_metadata_extract_pdf (gchar *, GHashTable *); -#endif -void tracker_metadata_extract_abw (gchar *, GHashTable *); -void tracker_metadata_extract_vorbis (gchar *, GHashTable *); - -MimeToExtractor internal_metadata_extractors[] = { - /* Document extractors */ - { "application/vnd.oasis.opendocument.text", tracker_metadata_extract_oasis }, - { "application/vnd.oasis.opendocument.spreadsheet", tracker_metadata_extract_oasis }, - { "application/vnd.oasis.opendocument.graphics", tracker_metadata_extract_oasis }, - { "application/vnd.oasis.opendocument.presentation", tracker_metadata_extract_oasis }, - { "application/postscript", tracker_metadata_extract_ps }, -#ifdef HAVE_POPPLER - { "application/pdf", tracker_metadata_extract_pdf }, -#endif - { "application/x-abiword", tracker_metadata_extract_abw }, - /* Video extractors */ - //{ "video/x-theora+ogg", tracker_metadata_extract_theora }, - /* Audio extractors */ - { "audio/x-vorbis+ogg", tracker_metadata_extract_vorbis }, - /* Image extractors */ - { "", NULL } -}; - static MetadataFileType tracker_get_metadata_type (const char *mime) { @@ -431,32 +398,14 @@ tracker_metadata_get_thumbnail (const ch return NULL; } -static void log_metadata_cb (gpointer key, gpointer value, gpointer user_data) -{ - tracker_log ("%s = %s", (gchar *)key, (gchar *)value); -} - void tracker_metadata_get_embedded (const char *uri, const char *mime, GHashTable *table) { - MimeToExtractor *p; MetadataFileType meta_type; - gboolean found; if (!uri || !mime || !table) { return; } - - found = FALSE; - for (p = internal_metadata_extractors; p->extractor; ++p) { - if (strcmp (p->mime, mime) == 0) { - found = TRUE; - (*p->extractor)(uri, table); - g_hash_table_foreach (table, log_metadata_cb, NULL); - } - } - if (found) - return; meta_type = tracker_get_metadata_type (mime); Index: src/tracker-extract/Makefile.am =================================================================== RCS file: /cvs/gnome/tracker/src/tracker-extract/Makefile.am,v retrieving revision 1.4 diff -u -p -r1.4 Makefile.am --- src/tracker-extract/Makefile.am 21 Aug 2006 20:18:26 -0000 1.4 +++ src/tracker-extract/Makefile.am 27 Sep 2006 03:08:39 -0000 @@ -1,8 +1,20 @@ -INCLUDES = $(GLIB2_CFLAGS) $(CFLAGS) -g +INCLUDES = $(GLIB2_CFLAGS) $(CFLAGS) -g \ + $(POPPLER_GLIB_CFLAGS) \ + $(VORBIS_CFLAGS) \ + $(THEORA_CFLAGS) \ + $(LIBPNG_CFLAGS) \ + $(LIBEXIF_CFLAGS) bin_PROGRAMS = tracker-extract -tracker_extract_SOURCES = tracker-extract.c +tracker_extract_SOURCES = tracker-extract.c \ + tracker-extract-oasis.c \ + tracker-extract-ps.c \ + tracker-extract-pdf.c \ + tracker-extract-abw.c \ + tracker-extract-vorbis.c \ + tracker-extract-png.c \ + tracker-extract-exif.c if USING_INTERNAL_LIBEXTRACTOR extractor_ldadd = $(top_builddir)/src/libextractor/src/main/libextractor.la @@ -10,4 +22,9 @@ else extractor_ldadd = -lextractor endif -tracker_extract_LDADD = $(GLIB2_LIBS) $(extractor_ldadd) +tracker_extract_LDADD = $(GLIB2_LIBS) $(extractor_ldadd) \ + $(POPPLER_GLIB_LIBS) \ + $(VORBIS_LIBS) \ + $(THEORA_LIBS) \ + $(LIBPNG_LIBS) \ + $(LIBEXIF_LIBS) Index: src/tracker-extract/tracker-extract.c =================================================================== RCS file: /cvs/gnome/tracker/src/tracker-extract/tracker-extract.c,v retrieving revision 1.10 diff -u -p -r1.10 tracker-extract.c --- src/tracker-extract/tracker-extract.c 20 Sep 2006 23:40:50 -0000 1.10 +++ src/tracker-extract/tracker-extract.c 27 Sep 2006 03:09:19 -0000 @@ -30,6 +30,7 @@ # include "../libextractor/src/include/extractor.h" #endif +#include "config.h" typedef enum { IGNORE_METADATA, @@ -116,6 +117,62 @@ static struct metadata_format image_keyw {"EOF", EXTRACTOR_UNKNOWN} }; +typedef void (*MetadataExtractFunc)(gchar *, GHashTable *); +typedef struct { + char *mime; + MetadataExtractFunc extractor; +} MimeToExtractor; + +void tracker_extract_oasis (gchar *, GHashTable *); +void tracker_extract_ps (gchar *, GHashTable *); +#ifdef HAVE_POPPLER +void tracker_extract_pdf (gchar *, GHashTable *); +#endif +void tracker_extract_abw (gchar *, GHashTable *); +#ifdef HAVE_VORBIS +void tracker_extract_vorbis (gchar *, GHashTable *); +#endif +#ifdef HAVE_LIBPNG +void tracker_extract_png (gchar *, GHashTable *); +#endif +#ifdef HAVE_LIBEXIF +void tracker_extract_exif (gchar *, GHashTable *); +#endif + +MimeToExtractor extractors[] = { + /* Document extractors */ + { "application/vnd.oasis.opendocument.text", tracker_extract_oasis }, + { "application/vnd.oasis.opendocument.spreadsheet", tracker_extract_oasis }, + { "application/vnd.oasis.opendocument.graphics", tracker_extract_oasis }, + { "application/vnd.oasis.opendocument.presentation", tracker_extract_oasis }, + { "application/postscript", tracker_extract_ps }, +#ifdef HAVE_POPPLER + { "application/pdf", tracker_extract_pdf }, +#endif + { "application/x-abiword", tracker_extract_abw }, + + + /* Video extractors */ +#ifdef HAVE_THEORA + { "video/x-theora+ogg", tracker_extract_theora }, +#endif + + + /* Audio extractors */ +#ifdef HAVE_VORBIS + { "audio/x-vorbis+ogg", tracker_extract_vorbis }, +#endif + + + /* Image extractors */ +#ifdef HAVE_LIBPNG + { "image/png", tracker_extract_png }, +#endif +#ifdef HAVE_LIBEXIF + { "image/jpeg", tracker_extract_exif }, +#endif + { "", NULL } +}; static MetadataFileType get_metadata_type (const char *mime) @@ -386,6 +443,21 @@ tracker_get_file_metadata (const char *u return NULL; } + meta_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + if (mime) { + MimeToExtractor *p; + for (p = extractors; p->extractor; ++p) { + if (strcmp (p->mime, mime) == 0) { + (*p->extractor)(uri_in_locale, meta_table); + return meta_table; + } + } + fprintf (stderr, "Mime %s not found, falling back on libextractor\n", mime); + } + + + /* Fallback to libextractor */ keywords = EXTRACTOR_getKeywords (plugins, uri_in_locale); g_free (uri_in_locale); @@ -410,8 +482,6 @@ tracker_get_file_metadata (const char *u - meta_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - while (keywords != NULL) { value = g_locale_to_utf8 (keywords->keyword, -1, NULL, NULL, NULL); @@ -478,6 +548,7 @@ main (int argc, char **argv) GHashTable *meta; char *filename; + g_set_application_name ("tracker-extract"); setlocale (LC_ALL, ""); if ((argc == 1) || (argc > 3)) { --- /dev/null 2006-08-05 19:53:54.000000000 -0400 +++ src/tracker-extract/tracker-extract-abw.c 2006-09-26 18:35:58.000000000 -0400 @@ -0,0 +1,47 @@ + +#include +#include +#include + +void tracker_extract_abw (gchar *filename, GHashTable *metadata) +{ + FILE *f; + gchar *line; + gsize length = 0; + + if(f = fopen (filename, "r")) { + line = NULL; + getline (&line, &length, f); + while (!feof (f)) { + if (g_str_has_suffix (line, "\n")) { + line[strlen(line) - 5] = '\0'; + } + if (g_str_has_prefix (line, "")) { + g_hash_table_insert (metadata, + g_strdup ("Doc.Title"), g_strdup (line+18)); + } + else if (g_str_has_prefix (line, "")) { + g_hash_table_insert (metadata, + g_strdup ("Doc.Subject"), g_strdup (line+20)); + } + else if (g_str_has_prefix (line, "")) { + g_hash_table_insert (metadata, + g_strdup ("Doc.Author"), g_strdup (line+20)); + } + else if (g_str_has_prefix (line, "")) { + g_hash_table_insert (metadata, + g_strdup ("Doc.Keywords"), g_strdup (line+26)); + } + else if (g_str_has_prefix (line, "")) { + g_hash_table_insert (metadata, + g_strdup ("Doc.Comments"), g_strdup (line+24)); + } + g_free (line); + line = NULL; + getline (&line, &length, f); + } + g_free (line); + } + fclose (f); +} + --- /dev/null 2006-08-05 19:53:54.000000000 -0400 +++ src/tracker-extract/tracker-extract-oasis.c 2006-09-26 18:35:58.000000000 -0400 @@ -0,0 +1,181 @@ + +#include +#include + +typedef enum { + READ_TITLE, + READ_SUBJECT, + READ_AUTHOR, + READ_KEYWORDS, + READ_COMMENTS, + READ_STATS, + READ_CREATED, + READ_FILE_OTHER + } tag_type; + +typedef struct { + GHashTable *metadata; + tag_type current; +} ODTParseInfo; + +static void start_element_handler (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error); + +static void end_element_handler (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error); + +static void text_handler (GMarkupParseContext *context, + const gchar *text, + gsize text_len, + gpointer user_data, + GError **error); + +void tracker_extract_oasis (gchar *filename, GHashTable *metadata) +{ + + gchar *argv[5]; + gchar *xml; + ODTParseInfo info = { metadata, -1 }; + + argv[0] = g_strdup ("unzip"); + argv[1] = g_strdup ("-p"); + argv[2] = g_strdup (filename); + argv[3] = g_strdup ("meta.xml"); + argv[4] = NULL; + + if(g_spawn_sync (NULL, + argv, + NULL, + G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL, + NULL, + NULL, + &xml, + NULL, + NULL, + NULL)) { + + GMarkupParseContext *context; + GMarkupParser parser = { + start_element_handler, + end_element_handler, + text_handler, + NULL, + NULL + }; + + context = g_markup_parse_context_new (&parser, 0, &info, NULL); + g_markup_parse_context_parse (context, xml, -1, NULL); + + g_markup_parse_context_free (context); + g_free (xml); + } + + g_free (argv[3]); + g_free (argv[2]); + g_free (argv[1]); + g_free (argv[0]); + +} + +void start_element_handler (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) +{ + if(strcmp(element_name, "dc:title") == 0) { + ((ODTParseInfo *)user_data)->current = READ_TITLE; + } + else if(strcmp(element_name, "dc:subject") == 0) { + ((ODTParseInfo *)user_data)->current = READ_SUBJECT; + } + else if(strcmp(element_name, "dc:creator") == 0) { + ((ODTParseInfo *)user_data)->current = READ_AUTHOR; + } + else if(strcmp(element_name, "meta:keyword") == 0) { + ((ODTParseInfo *)user_data)->current = READ_KEYWORDS; + } + else if(strcmp(element_name, "dc:description") == 0) { + ((ODTParseInfo *)user_data)->current = READ_COMMENTS; + } + else if(strcmp(element_name, "meta:document-statistic") == 0) { + GHashTable *metadata = ((ODTParseInfo *)user_data)->metadata; + const gchar **a, **v; + for(a=attribute_names,v=attribute_values; *a; ++a,++v) { + if (strcmp (*a, "meta:word-count") == 0) { + g_hash_table_insert (metadata, + g_strdup("Doc.WordCount"), g_strdup (*v)); + } + else if (strcmp (*a, "meta:page-count") == 0) { + g_hash_table_insert (metadata, + g_strdup("Doc.PageCount"), g_strdup (*v)); + } + } + ((ODTParseInfo *)user_data)->current = READ_STATS; + } + else if(strcmp(element_name, "meta:creation-date") == 0) { + ((ODTParseInfo *)user_data)->current = READ_CREATED; + } + else if(strcmp(element_name, "meta:generator") == 0) { + ((ODTParseInfo *)user_data)->current = READ_FILE_OTHER; + } + else { + ((ODTParseInfo *)user_data)->current = -1; + } +} + +void end_element_handler (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error) +{ + ((ODTParseInfo *)user_data)->current = -1; +} + +void text_handler (GMarkupParseContext *context, + const gchar *text, + gsize text_len, + gpointer user_data, + GError **error) +{ + GHashTable *metadata = ((ODTParseInfo *)user_data)->metadata; + + switch(((ODTParseInfo *)user_data)->current) { + case READ_TITLE: + g_hash_table_insert (metadata, g_strdup("Doc.Title"), g_strdup (text)); + break; + case READ_SUBJECT: + g_hash_table_insert (metadata, g_strdup("Doc.Subject"), g_strdup (text)); + break; + case READ_AUTHOR: + g_hash_table_insert (metadata, g_strdup("Doc.Author"), g_strdup (text)); + break; + case READ_KEYWORDS: { + gchar *keywords; + if (keywords = g_hash_table_lookup (metadata, "Doc.Keywords")) { + g_hash_table_replace (metadata, "Doc.Keywords", + g_strconcat (keywords, ",", text, NULL)); + } + else { + g_hash_table_insert (metadata, g_strdup("Doc.Keywords"), g_strdup (text)); + } + } + break; + case READ_COMMENTS: + g_hash_table_insert (metadata, g_strdup("Doc.Comments"), g_strdup (text)); + break; + case READ_CREATED: + g_hash_table_insert (metadata, g_strdup("Doc.Created"), g_strdup (text)); + break; + case READ_FILE_OTHER: + g_hash_table_insert (metadata, g_strdup("File.Other"), g_strdup (text)); + break; + } +} --- /dev/null 2006-08-05 19:53:54.000000000 -0400 +++ src/tracker-extract/tracker-extract-exif.c 2006-09-26 23:03:09.000000000 -0400 @@ -0,0 +1,113 @@ + +#include "config.h" + +#ifdef HAVE_LIBEXIF + +#include +#include +#include +#include + +static gchar *fix_focal_length (gchar *fl) +{ + return g_strndup (fl, (strstr (fl, "mm") - fl)); +} + +static gchar *fix_flash (gchar *flash) +{ + if (g_str_has_prefix (flash, "No")) + return g_strdup ("0"); + else + return g_strdup ("1"); +} + +static gchar *fix_fnumber (gchar *fn) +{ + if (fn && fn[0] == 'F') { + fn[0] = ' '; + } + else if (fn && fn[0] == 'f' && fn[1] == '/') { + fn[0] = ' ', fn[1] = ' '; + } + return fn; +} + +static gchar *fix_exposure_time (gchar *et) +{ + gchar *sep = strchr (et, '/'); + + if (sep) { + gdouble fraction = g_ascii_strtod (sep+1, NULL); + + if (fraction > 0) { + gdouble val = 1.0f / fraction; + char str_value[30]; + + g_ascii_dtostr (str_value, 30, val); + return g_strdup (str_value); + } + } + return et; +} + +typedef gchar *(*PostProcessor)(gchar *); + +typedef struct { + ExifTag tag; + gchar *name; + PostProcessor post; +} TagType; + +TagType tags[] = { + { EXIF_TAG_PIXEL_Y_DIMENSION, "Image.Height", NULL }, + { EXIF_TAG_PIXEL_X_DIMENSION, "Image.Width", NULL }, + { EXIF_TAG_RELATED_IMAGE_WIDTH, "Image.Width", NULL }, + { EXIF_TAG_DOCUMENT_NAME, "Image.Title", NULL }, + /* { -1, "Image.Album", NULL }, */ + { EXIF_TAG_DATE_TIME, "Image.Date", NULL }, + /* { -1, "Image.Keywords", NULL }, */ + { EXIF_TAG_ARTIST, "Image.Creator", NULL }, + { EXIF_TAG_USER_COMMENT, "Image.Comments", NULL }, + { EXIF_TAG_IMAGE_DESCRIPTION, "Image.Description", NULL }, + { EXIF_TAG_SOFTWARE, "Image.Software", NULL }, + { EXIF_TAG_MAKE, "Image.CameraMake", NULL }, + { EXIF_TAG_MODEL, "Image.CameraModel", NULL }, + { EXIF_TAG_ORIENTATION, "Image.Orientation", NULL }, + { EXIF_TAG_EXPOSURE_PROGRAM, "Image.ExposureProgram", NULL }, + { EXIF_TAG_EXPOSURE_TIME, "Image.ExposureTime", fix_exposure_time }, + { EXIF_TAG_FNUMBER, "Image.Fnumber", fix_fnumber }, + { EXIF_TAG_FLASH, "Image.Flash", fix_flash }, + { EXIF_TAG_FOCAL_LENGTH, "Image.FocalLength", fix_focal_length }, + { EXIF_TAG_ISO_SPEED_RATINGS, "Image.ISOSpeed", NULL }, + { EXIF_TAG_METERING_MODE, "Image.MeteringMode", NULL }, + { EXIF_TAG_WHITE_BALANCE, "Image.WhiteBalance", NULL }, + { EXIF_TAG_COPYRIGHT, "Image.Copyright", NULL }, + { -1, NULL, NULL } +}; + +void +tracker_extract_exif (gchar *filename, GHashTable *metadata) +{ + ExifData *exif; + ExifEntry *entry; + char buffer[1024]; + TagType *p; + + exif = exif_data_new_from_file (filename); + for (p = tags; p->name; ++p) { + entry = exif_data_get_entry (exif, p->tag); + if (entry) { + exif_entry_get_value (entry, buffer, 1024); + if (p->post) + g_hash_table_insert (metadata, g_strdup (p->name), + g_strdup ((*p->post)(buffer))); + else + g_hash_table_insert (metadata, g_strdup (p->name), + g_strdup (buffer)); + } + } +} + +#else +#warning "Not building EXIF metadata extractor." +#endif /* HAVE_LIBEXIF */ --- /dev/null 2006-08-05 19:53:54.000000000 -0400 +++ src/tracker-extract/tracker-extract-pdf.c 2006-09-26 18:35:58.000000000 -0400 @@ -0,0 +1,64 @@ + +#include "config.h" + +#ifdef HAVE_POPPLER + +#include +#include +#include + +void tracker_extract_pdf (gchar *filename, GHashTable *metadata) +{ + PopplerDocument *document; + gchar *tmp; + gchar *title; + gchar *author; + gchar *subject; + gchar *keywords; + GTime creation_date; + GError *error = NULL; + + tmp = g_strconcat ("file://", filename, NULL); + document = poppler_document_new_from_file (tmp, NULL, &error); + g_free (tmp); + if (document == NULL || error) + return; + + g_object_get (document, + "title", &title, + "author", &author, + "subject", &subject, + "keywords", &keywords, + "creation-date", &creation_date, + NULL); + + if (title && strlen (title)) + g_hash_table_insert (metadata, g_strdup ("Doc.Title"), g_strdup (title)); + if (author && strlen (author)) + g_hash_table_insert (metadata, g_strdup ("Doc.Author"), g_strdup (author)); + if (subject && strlen (subject)) + g_hash_table_insert (metadata, g_strdup ("Doc.Subject"), g_strdup (subject)); + if (keywords && strlen (keywords)) + g_hash_table_insert (metadata, g_strdup ("Doc.Keywords"), g_strdup (keywords)); + +#if 0 + GTimeVal creation_date_val = { creation_date, 0 }; + g_hash_table_insert (metadata, g_strdup ("Doc.Created"), + g_time_val_to_iso8601 (creation_date_val)); +#endif + + g_hash_table_insert (metadata, g_strdup ("Doc.PageCount"), + g_strdup_printf ("%d", poppler_document_get_n_pages (document))); + + g_free (title); + g_free (author); + g_free (subject); + g_free (keywords); + g_object_unref (document); +} + +#else +#warning "Not building PDF metadata extractor." +#endif /* HAVE_POPPLER */ + + --- /dev/null 2006-08-05 19:53:54.000000000 -0400 +++ src/tracker-extract/tracker-extract-png.c 2006-09-26 18:35:58.000000000 -0400 @@ -0,0 +1,51 @@ + +#include "config.h" + +#ifdef HAVE_LIBPNG + +#include +#include +#include + +void +tracker_extract_png (gchar *filename, GHashTable *metadata) +{ + FILE *png; + png_structp png_ptr; + png_infop info_ptr; + png_uint_32 width, height; + + int bit_depth, color_type; + int interlace_type, compression_type, filter_type; + + if(png = fopen(filename, "r")) { + png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, + NULL, NULL, NULL); + if (!png_ptr) { + fclose (png); + return; + } + info_ptr = png_create_info_struct (png_ptr); + if (!info_ptr) { + png_destroy_read_struct (&png_ptr, &info_ptr, NULL); + fclose (png); + return; + } + png_init_io (png_ptr, png); + png_read_info (png_ptr, info_ptr); + if (png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, + &color_type, &interlace_type, &compression_type, &filter_type)) { + g_hash_table_insert (metadata, g_strdup ("Image.Width"), + g_strdup_printf ("%d", width)); + g_hash_table_insert (metadata, g_strdup ("Image.Height"), + g_strdup_printf ("%d", height)); + } + + png_destroy_read_struct (&png_ptr, &info_ptr, NULL); + fclose (png); + } +} + +#else +#warning "Not building PNG metadata extractor." +#endif /* HAVE_LIBPNG */ --- /dev/null 2006-08-05 19:53:54.000000000 -0400 +++ src/tracker-extract/tracker-extract-ps.c 2006-09-26 18:35:58.000000000 -0400 @@ -0,0 +1,58 @@ + +#include +#include +#include + +void tracker_extract_ps (gchar *filename, GHashTable *metadata) +{ + FILE *f; + gchar *line; + gsize length = 0; + gboolean pageno_atend = FALSE; + gboolean header_finished = FALSE; + + if(f = fopen (filename, "r")) { + line = NULL; + getline (&line, &length, f); + while (!feof (f)) { + line[strlen(line) - 1] = '\0'; /* overwrite \n char */ + if (!header_finished + && strncmp (line, "%%Copyright:", 12) == 0) { + g_hash_table_insert (metadata, + g_strdup ("File.Other"), g_strdup (line+13)); + } + else if (!header_finished + && strncmp (line, "%%Title:", 8) == 0) { + g_hash_table_insert (metadata, + g_strdup ("Doc.Title"), g_strdup (line+9)); + } + else if (!header_finished + && strncmp (line, "%%Creator:", 10) == 0) { + g_hash_table_insert (metadata, + g_strdup ("Doc.Author"), g_strdup (line+11)); + } + else if (!header_finished + && strncmp (line, "%%CreationDate:", 15) == 0) { + g_hash_table_insert (metadata, + g_strdup ("Doc.Created"), g_strdup (line+16)); + } + else if (strncmp (line, "%%Pages:", 8) == 0) { + if (strcmp (line+9, "(atend)") == 0) + pageno_atend = TRUE; + else + g_hash_table_insert (metadata, + g_strdup ("Doc.PageCount"), g_strdup (line+9)); + } + else if (strncmp (line, "%%EndComments", 14) == 0) { + header_finished = TRUE; + if (!pageno_atend) + break; + } + g_free (line); + line = NULL; + getline (&line, &length, f); + } + g_free (line); + } + fclose (f); +} --- /dev/null 2006-08-05 19:53:54.000000000 -0400 +++ src/tracker-extract/tracker-extract-vorbis.c 2006-09-26 18:35:58.000000000 -0400 @@ -0,0 +1,170 @@ + +#include "config.h" + +#ifdef HAVE_VORBIS + +#include +#include +#include +#include + +/*#include "tracker-utils.h"*/ + +static struct { + char * name; + char *meta_name; + gboolean writable; +} tags[] = { + {"title", "Audio.Title", FALSE}, + {"artist", "Audio.Artist", FALSE}, + {"album", "Audio.Album", FALSE}, + {"albumartist", "Audio.AlbumArtist", FALSE}, + {"trackcount", "Audio.AlbumTrackCount", FALSE}, + {"tracknumber", "Audio.TrackNo", FALSE}, + {"DiscNo", "Audio.DiscNo", FALSE}, + {"Performer", "Audio.Performer", FALSE}, + {"TrackGain", "Audio.TrackGain", FALSE}, + {"TrackPeakGain", "Audio.TrackPeakGain", FALSE}, + {"AlbumGain", "Audio.AlbumGain", FALSE}, + {"AlbumPeakGain", "Audio.AlbumPeakGain", FALSE}, + {"date", "Audio.ReleaseDate", FALSE}, + {"comment", "Audio.Comment", FALSE}, + {"genre", "Audio.Genre", FALSE}, + {"Codec", "Audio.Codec", FALSE}, + {"CodecVersion", "Audio.CodecVersion", FALSE}, + {"Samplerate", "Audio.Samplerate", FALSE}, + {"Channels", "Audio.Channels", FALSE}, + {"MBAlbumID", "Audio.MBAlbumID", FALSE}, + {"MBArtistID", "Audio.MBArtistID", FALSE}, + {"MBAlbumArtistID", "Audio.MBAlbumArtistID", FALSE}, + {"MBTrackID", "Audio.MBTrackID", FALSE}, + {"Lyrics", "Audio.Lyrics", FALSE}, + {"Copyright", "File.Copyright", FALSE}, + {"License", "File.License", FALSE}, + {"Organization", "File.Organization", FALSE}, + {"Location", "File.Location", FALSE}, + {"Publisher", "File.Publisher", FALSE}, + {NULL, NULL, FALSE}, +}; + + +static char* +get_comment (vorbis_comment *vc, char *label) +{ + char *tag; + char *utf_tag; + + if (vc && (tag = vorbis_comment_query (vc, label, 0)) != NULL) { + + utf_tag = g_locale_to_utf8 (tag, -1, NULL, NULL, NULL); + + /*g_free (tag);*/ + + return utf_tag; + + } else { + return NULL; + } + +} + +gboolean +tracker_metadata_ogg_is_writable (const char *meta) +{ + int i; + + i = 0; + while (tags[i].name != NULL) { + + if (strcmp (tags[i].meta_name, meta) == 0) { + return tags[i].writable; + } + + i++; + } + + return FALSE; + +} + + +gboolean +tracker_metadata_ogg_write (const char *meta_name, const char *value) +{ + /* to do */ + return FALSE; +} + + +void +tracker_extract_vorbis (const char *filename, GHashTable *metadata) +{ + FILE *oggFile; + OggVorbis_File vf; + int i; + + oggFile = fopen (filename,"r"); + + if (!oggFile) { + return; + } + + if ( ov_open (oggFile, &vf, NULL, 0) < 0 ) { + fclose (oggFile); + return; + } + + char *tmpComment; + + vorbis_comment *comment; + + if ((comment = ov_comment (&vf, -1)) == NULL) { + ov_clear (&vf); + return; + } + + i = 0; + while (tags[i].name != NULL) { + tmpComment = get_comment (comment, tags[i].name); + + if (tmpComment) { + g_hash_table_insert (metadata, g_strdup (tags[i].meta_name), tmpComment); + } + + i++; + } + + vorbis_comment_clear(comment); + + /* Bitrate */ + + vorbis_info *vi; + unsigned int bitrate; + char *str_bitrate; + + if ( ( vi = ov_info(&vf, 0)) != NULL ) { + bitrate = vi->bitrate_nominal/1000; + str_bitrate = g_strdup_printf ("%d", bitrate); + g_hash_table_insert (metadata, g_strdup ("Audio.Bitrate"), str_bitrate); + } + + + + /* Duration */ + + int time; + char *str_time; + if ( ( time = ov_time_total(&vf, -1) ) != OV_EINVAL ) { + str_time = g_strdup_printf ("%d", time); + g_hash_table_insert (metadata, g_strdup ("Audio.Duration"), str_time); + } + + g_hash_table_insert (metadata, g_strdup ("Audio.Codec"), g_strdup ("vorbis")); + + ov_clear(&vf); + +} + +#else +#warning "Not building ogg/vorbis metadata extractor" +#endif /* HAVE_VORBIS */