[libmediaart/api-cleanup: 16/16] libmediaart: Split API into _process_buffer() and _process_file()



commit 880d09fbff1f89f4ce5ed9ee5b1d23ccc6e20da2
Author: Martyn Russell <martyn lanedo com>
Date:   Mon Jul 28 09:14:24 2014 +0100

    libmediaart: Split API into  _process_buffer() and _process_file()
    
    This is quite an API break, but the previous API was confusing and a monster,
    so this was really necessary.
    
    The unit tests have been put in place to make sure things work correctly too.

 docs/reference/libmediaart/libmediaart-docs.sgml   |    1 +
 .../reference/libmediaart/libmediaart-sections.txt |   33 ++-
 libmediaart/cache.c                                |   43 ++--
 libmediaart/extract.c                              |  312 +++++++++++++-------
 libmediaart/extract.h                              |   73 +++--
 libmediaart/extractdummy.c                         |   80 +++++-
 libmediaart/extractgeneric.h                       |    1 -
 libmediaart/storage.c                              |    2 +-
 "tests/LanedoIconHKS43-64\302\262.png"             |  Bin 1560 -> 0 bytes
 tests/mediaarttest.c                               |   51 ++--
 10 files changed, 397 insertions(+), 199 deletions(-)
---
diff --git a/docs/reference/libmediaart/libmediaart-docs.sgml 
b/docs/reference/libmediaart/libmediaart-docs.sgml
index 47e7abe..38a5021 100644
--- a/docs/reference/libmediaart/libmediaart-docs.sgml
+++ b/docs/reference/libmediaart/libmediaart-docs.sgml
@@ -32,6 +32,7 @@
       <title>Reference</title>
       <xi:include href="xml/extract.xml"/>
       <xi:include href="xml/cache.xml"/>
+      <xi:include href="xml/plugins.xml"/>
     </chapter>
 
   </part>
diff --git a/docs/reference/libmediaart/libmediaart-sections.txt 
b/docs/reference/libmediaart/libmediaart-sections.txt
index cca4ecf..77bd1f7 100644
--- a/docs/reference/libmediaart/libmediaart-sections.txt
+++ b/docs/reference/libmediaart/libmediaart-sections.txt
@@ -1,30 +1,45 @@
 <SECTION>
 <FILE>cache</FILE>
-media_art_get_file
 media_art_get_path
+media_art_get_file
 media_art_remove
 media_art_strip_invalid_entities
 </SECTION>
 
 <SECTION>
 <FILE>extract</FILE>
+<TITLE>MediaArtProcess</TITLE>
 MediaArtType
-media_art_init
-media_art_shutdown
+MediaArtError
+MediaArtProcessFlags
+MediaArtProcess
+MediaArtProcessClass
+media_art_error_quark
+media_art_process_get_type
+media_art_process_new
+media_art_process_uri
 media_art_process_file
-media_art_process
+media_art_process_buffer
+<SUBSECTION Standard>
+MEDIA_ART_IS_PROCESS
+MEDIA_ART_IS_PROCESS_CLASS
+MEDIA_ART_PROCESS
+MEDIA_ART_PROCESS_CLASS
+MEDIA_ART_PROCESS_GET_CLASS
+MEDIA_ART_TYPE_PROCESS
 </SECTION>
 
 <SECTION>
-<FILE>extractgeneric</FILE>
-media_art_buffer_to_jpeg
-media_art_file_to_jpeg
+<FILE>plugins</FILE>
 media_art_plugin_init
 media_art_plugin_shutdown
+media_art_file_to_jpeg
+media_art_buffer_to_jpeg
 </SECTION>
 
 <SECTION>
-<FILE>mediaart</FILE>
-
+<FILE>marshal</FILE>
+media_art_marshal_VOID__STRING_STRING
+media_art_marshal_VOID__STRING_STRING_STRING_BOOLEAN_BOOLEAN
 </SECTION>
 
diff --git a/libmediaart/cache.c b/libmediaart/cache.c
index 7249b14..82286a4 100644
--- a/libmediaart/cache.c
+++ b/libmediaart/cache.c
@@ -29,22 +29,25 @@
 
 /**
  * SECTION:cache
- * @title: Caching and Management
- * @short_description: Caching and management of stored media art.
+ * @title: Cache
+ * @short_description: Caching and lookup of stored media art.
  * @include: libmediaart/mediaart.h
  *
- * These functions give you access to the media art that has been extracted
- * and saved in the user's XDG_CACHE_HOME directory.
+ * These functions give you access to the media art that has been
+ * extracted and saved in the user's XDG_CACHE_HOME directory (usually
+ * ~/.cache/media-art/).
  *
  * To find the media art for a given media file, use the function
- * media_art_get_file() (you can also use media_art_get_path(), which does the
- * same thing but for path strings instead of #GFile objects).
+ * media_art_get_file() (you can also use media_art_get_path(), which
+ * does the same thing but for path strings instead of #GFile
+ * objects).
  *
- * If media art for the file is not found in the cache, these functions will
- * return %NULL. You may find some embedded media art upon loading the file,
- * and you can use media_art_process() to convert it to the correct format and
- * save it in the cache for next time. The media_art_process() function also
- * supports searching for external media art images using a basic heuristic.
+ * If media art for the file is not found in the cache, these
+ * functions will return %NULL. You may find some embedded media art
+ * upon loading the file, and you can use media_art_process_buffer()
+ * to convert it to the correct format and save it in the cache for
+ * next time. The media_art_process_file() function also supports
+ * searching for external media art images using a basic heuristic.
  **/
 
 static gboolean
@@ -271,9 +274,7 @@ media_art_get_file (const gchar  *artist,
                *local_file = NULL;
        }
 
-       if (!artist && !title) {
-               return;
-       }
+       g_return_if_fail (artist != NULL || title != NULL);
 
        if (artist) {
                artist_stripped = media_art_strip_invalid_entities (artist);
@@ -359,8 +360,8 @@ media_art_get_file (const gchar  *artist,
  * @local_uri: (out) (transfer full) (allow-none): the location to store the
  * local uri or %NULL
  *
- * Get the path to media art for a given resource. Newly allocated data in
- * @path and @local_uri must be freed with g_free().
+ * Get the path to media art for a given resource. Newly allocated
+ * data returned in @path and @local_uri must be freed with g_free().
  *
  * Since: 0.2.0
  */
@@ -417,7 +418,7 @@ media_art_remove_foreach (gpointer data,
  * @artist: artist the media art belongs to
  * @album: (allow-none): album the media art belongs or %NULL
  *
- * Removes media art for given album/artist/etc provided.
+ * Removes media art for given album/artist provided.
  *
  * Returns: #TRUE on success, otherwise #FALSE.
  *
@@ -470,9 +471,11 @@ media_art_remove (const gchar *artist,
        }
 
        /* Add the album path also (to which the symlinks are made) */
-       media_art_get_path (NULL, album, "album", NULL, &target, NULL);
-       if (target) {
-               g_hash_table_replace (table, target, target);
+       if (album) {
+               media_art_get_path (NULL, album, "album", NULL, &target, NULL);
+               if (target) {
+                       g_hash_table_replace (table, target, target);
+               }
        }
 
        /* Perhaps we should have an internal list of media art files that we made,
diff --git a/libmediaart/extract.c b/libmediaart/extract.c
index 48f1476..40bc05d 100644
--- a/libmediaart/extract.c
+++ b/libmediaart/extract.c
@@ -46,7 +46,7 @@
  * from a media file and saving it into the media art cache, so that future
  * applications can display the media art without having to extract the image
  * again. This is done using the media_art_process_file() or
- * media_art_process() functions.
+ * media_art_process_buffer() functions.
  *
  * Extracting new media art from a file needs to be done by your application.
  * Usually, when an application loads a media file any embedded images will be
@@ -56,19 +56,16 @@
  *
  * The media art cache requires that all images are saved as 'application/jpeg'
  * files. Embedded images can be in several formats, and
- * media_art_process_file() and media_art_process() functions will
+ * media_art_process_file() and media_art_process_buffer() functions will
  * convert the supplied image data into the correct format if
  * necessary. There are multiple backends that can be used for this,
  * and you can choose which is used at build time using the library's
  * 'configure' script.
  *
  * If there is no embedded media art in a file,
- * media_art_process_file() and media_art_process() functions will
+ * media_art_process_file() and media_art_process_buffer() functions will
  * look in the directory that contains the media file for likely media
  * art using a simple heuristic.
- *
- * You must call media_art_init() before using the functions in libmediaart,
- * and call media_art_shutdown() to free the resources it uses.
  **/
 
 typedef struct {
@@ -179,7 +176,7 @@ media_art_process_initable_init (GInitable     *initable,
                g_critical ("Could not start storage module for removable media detection");
 
                if (error) {
-                       *error = g_error_new (MEDIA_ART_ERROR,
+                       *error = g_error_new (media_art_error_quark (),
                                              MEDIA_ART_ERROR_NO_STORAGE,
                                              "Could not initialize storage module");
                }
@@ -218,7 +215,8 @@ media_art_process_init (MediaArtProcess *thumbnailer)
  * This function initializes cache hash tables, backend plugins,
  * storage modules used for removable devices and a connection to D-Bus.
  *
- * Returns: %TRUE on success or %FALSE if @error is set.
+ * Returns: A new #MediaArtProcess object on success or %NULL if
+ * @error is set. This object must be freed using g_object_unref().
  *
  * Since: 0.3.0
  */
@@ -397,7 +395,7 @@ convert_from_other_format (const gchar  *found,
 
                if (!retval) {
                        g_set_error (error,
-                                    MEDIA_ART_ERROR,
+                                    media_art_error_quark (),
                                     MEDIA_ART_ERROR_RENAME_FAILED,
                                     "Could not rename '%s' to '%s': %s",
                                     target_temp,
@@ -429,7 +427,7 @@ convert_from_other_format (const gchar  *found,
 
                                if (!retval) {
                                        g_set_error (error,
-                                                    MEDIA_ART_ERROR,
+                                                    media_art_error_quark (),
                                                     MEDIA_ART_ERROR_RENAME_FAILED,
                                                     "Could not rename '%s' to '%s': %s",
                                                     album_path,
@@ -451,7 +449,7 @@ convert_from_other_format (const gchar  *found,
 
                                if (!retval) {
                                        g_set_error (error,
-                                                    MEDIA_ART_ERROR,
+                                                    media_art_error_quark (),
                                                     MEDIA_ART_ERROR_RENAME_FAILED,
                                                     "Could not rename '%s' to '%s': %s",
                                                     target_temp,
@@ -473,7 +471,7 @@ convert_from_other_format (const gchar  *found,
 
                        if (!retval) {
                                g_set_error (error,
-                                            MEDIA_ART_ERROR,
+                                            media_art_error_quark (),
                                             MEDIA_ART_ERROR_RENAME_FAILED,
                                             "Could not rename '%s' to '%s': %s",
                                             album_path,
@@ -484,7 +482,7 @@ convert_from_other_format (const gchar  *found,
 
                                if (!retval) {
                                        g_set_error (error,
-                                                    MEDIA_ART_ERROR,
+                                                    media_art_error_quark (),
                                                     MEDIA_ART_ERROR_SYMLINK_FAILED,
                                                     "Could not rename '%s' to '%s': %s",
                                                     album_path,
@@ -709,7 +707,7 @@ get_heuristic (MediaArtType   type,
 
        if (title == NULL || title[0] == '\0') {
                g_set_error (error,
-                            MEDIA_ART_ERROR,
+                            media_art_error_quark (),
                             MEDIA_ART_ERROR_NO_TITLE,
                             "Title is required, but was not provided, or was empty");
                return FALSE;
@@ -842,7 +840,7 @@ get_heuristic (MediaArtType   type,
 
                                                if (!retval) {
                                                        g_set_error (error,
-                                                                    MEDIA_ART_ERROR,
+                                                                    media_art_error_quark (),
                                                                     MEDIA_ART_ERROR_SYMLINK_FAILED,
                                                                     "Could not link '%s' to '%s': %s",
                                                                     album_art_file_path,
@@ -857,7 +855,6 @@ get_heuristic (MediaArtType   type,
                                        } else {
                                                GFile *art_file;
                                                GFile *target_file;
-                                               GError *local_error = NULL;
 
                                                /* If album-space-md5.jpg isn't the same as found,
                                                 * make a new album-md5-md5.jpg (found -> target) */
@@ -879,7 +876,6 @@ get_heuristic (MediaArtType   type,
                                } else {
                                        GFile *art_file;
                                        GFile *album_art_file;
-                                       GError *local_error = NULL;
 
                                        /* If there's not yet a album-space-md5.jpg, make one,
                                         * and symlink album-md5-md5.jpg to it */
@@ -898,7 +894,7 @@ get_heuristic (MediaArtType   type,
 
                                                if (!retval) {
                                                        g_set_error (error,
-                                                                    MEDIA_ART_ERROR,
+                                                                    media_art_error_quark (),
                                                                     MEDIA_ART_ERROR_SYMLINK_FAILED,
                                                                     "Could not link '%s' to '%s': %s",
                                                                     album_art_file_path,
@@ -961,8 +957,6 @@ is_buffer_jpeg (const gchar         *mime,
                 const unsigned char *buffer,
                 size_t               buffer_len)
 {
-       gboolean is_jpeg;
-
        if (buffer == NULL || buffer_len < 3) {
                return FALSE;
        }
@@ -995,9 +989,6 @@ media_art_set (const unsigned char  *buffer,
        gchar *md5_album = NULL;
        gchar *md5_tmp = NULL;
        gchar *temp;
-       const gchar *save_path = NULL;
-       gboolean save_buffer = FALSE;
-       gboolean need_symlink = FALSE;
        gboolean retval = FALSE;
 
        g_return_val_if_fail (type > MEDIA_ART_NONE && type < MEDIA_ART_TYPE_COUNT, FALSE);
@@ -1071,7 +1062,7 @@ media_art_set (const unsigned char  *buffer,
 
                        if (!retval) {
                                g_set_error (error,
-                                            MEDIA_ART_ERROR,
+                                            media_art_error_quark (),
                                             MEDIA_ART_ERROR_SYMLINK_FAILED,
                                             "Could not link '%s' to '%s': %s",
                                             album_path,
@@ -1122,7 +1113,7 @@ media_art_set (const unsigned char  *buffer,
 
                        if (!retval) {
                                g_set_error (error,
-                                            MEDIA_ART_ERROR,
+                                            media_art_error_quark (),
                                             MEDIA_ART_ERROR_SYMLINK_FAILED,
                                             "Could not link '%s' to '%s': %s",
                                             album_path,
@@ -1184,7 +1175,7 @@ media_art_set (const unsigned char  *buffer,
 
                        if (!retval) {
                                g_set_error (error,
-                                            MEDIA_ART_ERROR,
+                                            media_art_error_quark (),
                                             MEDIA_ART_ERROR_SYMLINK_FAILED,
                                             "Could not link '%s' to '%s': %s",
                                             album_path,
@@ -1204,7 +1195,7 @@ media_art_set (const unsigned char  *buffer,
 
                        if (!retval) {
                                g_set_error (error,
-                                            MEDIA_ART_ERROR,
+                                            media_art_error_quark (),
                                             MEDIA_ART_ERROR_RENAME_FAILED,
                                             "Could not rename '%s' to '%s': %s",
                                             temp,
@@ -1466,7 +1457,7 @@ get_mtime (GFile   *file,
        return mtime;
 }
 
-gchar *
+static gchar *
 get_heuristic_for_parent_path (GFile        *file,
                                MediaArtType  type,
                                const gchar  *artist,
@@ -1499,27 +1490,22 @@ get_heuristic_for_parent_path (GFile        *file,
 }
 
 /**
- * media_art_process_file:
+ * media_art_process_buffer:
  * @process: Media art process object
- * @file: File to be processed
+ * @type: The type of media
+ * @flags: The options given for how to process the media art
+ * @related_file: File related to the media art
  * @buffer: (array length=len)(allow-none): a buffer containing @file data, or %NULL
  * @len: length of @buffer, or 0
  * @mime: MIME type of @buffer, or %NULL
- * @type: The type of media
- * @artist: The media file artist name, or %NULL
- * @title: The media file title, or %NULL
+ * @artist: (allow-none): The artist name @file or %NULL
+ * @title: (allow-none): The title for @file or %NULL
  * @error: Pointer to potential GLib / MediaArt error, or %NULL
  *
- * Processes a media file. If you have extracted any embedded media art and
- * passed this in as @buffer, the image data will be converted to the correct
- * format and saved in the media art cache.
- *
- * If @buffer is %NULL, libmediaart will search the parent directory of @file
- * for image files that are likely to be media art for @file, and if one is
- * found it will be saved in the media art cache. If @buffer is %NULL
- * for a @file which is *not* an image file (typically JPEG or PNG,
- * supported by the backends), this function will return %FALSE with
- * no error set, because it's not expected to work.
+ * Processes a memory buffer represented by @buffer and @len. If you
+ * have extracted any embedded media art and passed this in as
+ * @buffer, the image data will be converted to the correct format and
+ * saved in the media art cache.
  *
  * If @file is on a removable filesystem, the media art file will be saved in a
  * cache on the removable file system rather than on the host machine.
@@ -1529,43 +1515,44 @@ get_heuristic_for_parent_path (GFile        *file,
  * Since: 0.3.0
  */
 gboolean
-media_art_process_file (MediaArtProcess  *process,
-                        GFile            *file,
-                        const guchar     *buffer,
-                        gsize             len,
-                        const gchar      *mime,
-                        MediaArtType      type,
-                        const gchar      *artist,
-                        const gchar      *title,
-                        GError          **error)
+media_art_process_buffer (MediaArtProcess       *process,
+                          MediaArtType           type,
+                          MediaArtProcessFlags   flags,
+                          GFile                 *related_file,
+                          const guchar          *buffer,
+                          gsize                  len,
+                          const gchar           *mime,
+                          const gchar           *artist,
+                          const gchar           *title,
+                          GError               **error)
 {
-       MediaArtProcessPrivate *private;
        GFile *cache_art_file, *local_art_file;
        GError *local_error = NULL;
        gchar *cache_art_path, *uri;
-       gboolean processed, created, no_cache_or_old;
+       gboolean processed, created;
        guint64 mtime, cache_mtime = 0;
 
        g_return_val_if_fail (MEDIA_ART_IS_PROCESS (process), FALSE);
-       g_return_val_if_fail (G_IS_FILE (file), FALSE);
        g_return_val_if_fail (type > MEDIA_ART_NONE && type < MEDIA_ART_TYPE_COUNT, FALSE);
-
-       private = media_art_process_get_instance_private (process);
+       g_return_val_if_fail (G_IS_FILE (related_file), FALSE);
+       g_return_val_if_fail (buffer != NULL, FALSE);
+       g_return_val_if_fail (len < 0, FALSE);
 
        processed = created = FALSE;
 
-       uri = g_file_get_uri (file);
-       g_debug ("Processing media art: artist:'%s', title:'%s', type:'%s', uri:'%s'. Buffer is %ld bytes, 
mime:'%s'",
+       uri = g_file_get_uri (related_file);
+       g_debug ("Processing media art: artist:'%s', title:'%s', type:'%s', uri:'%s', flags:0x%.8x. Buffer is 
%ld bytes, mime:'%s'",
                 artist ? artist : "",
                 title ? title : "",
                 media_art_type_name[type],
                 uri,
+                flags,
                 (long int) len,
                 mime);
 
-       mtime = get_mtime (file, &local_error);
+       mtime = get_mtime (related_file, &local_error);
        if (local_error != NULL) {
-               g_debug ("Could not get mtime for file '%s': %s",
+               g_debug ("Could not get mtime for related file '%s': %s",
                         uri,
                         local_error->message);
                g_propagate_error (error, local_error);
@@ -1577,7 +1564,7 @@ media_art_process_file (MediaArtProcess  *process,
        media_art_get_file (artist,
                            title,
                            media_art_type_name[type],
-                           file,
+                           related_file,
                            &cache_art_file,
                            &local_art_file);
 
@@ -1592,13 +1579,11 @@ media_art_process_file (MediaArtProcess  *process,
                gchar *path;
 
                path = g_file_get_uri (cache_art_file);
-               g_debug ("Cache for media art didn't exist (%s)",
+               g_debug ("Cache for media art did not exist (%s)",
                         path);
                g_free (path);
                g_clear_error (&local_error);
-       }
-
-       if (local_error) {
+       } else if (local_error) {
                g_free (uri);
 
                uri = g_file_get_uri (cache_art_file);
@@ -1616,16 +1601,144 @@ media_art_process_file (MediaArtProcess  *process,
                return FALSE;
        }
 
+
        cache_art_path = g_file_get_path (cache_art_file);
-       no_cache_or_old = cache_mtime == 0 || mtime > cache_mtime;
 
-       if ((buffer && len > 0) && no_cache_or_old) {
+       if (flags & MEDIA_ART_PROCESS_FLAGS_FORCE ||
+           cache_mtime == 0 || mtime > cache_mtime) {
                processed = media_art_set (buffer, len, mime, type, artist, title, error);
                set_mtime (cache_art_path, mtime);
-               created = TRUE;
+       } else {
+               g_debug ("Album art already exists for uri:'%s' as '%s'",
+                        uri,
+                        cache_art_path);
+               processed = TRUE;
+       }
+
+       if (local_art_file && !g_file_query_exists (local_art_file, NULL)) {
+               /* We can't reuse art_exists here because the
+                * situation might have changed
+                */
+               if (g_file_query_exists (cache_art_file, NULL)) {
+                       gchar *local_art_uri;
+
+                       local_art_uri = g_file_get_uri (local_art_file);
+                       media_art_copy_to_local (process, cache_art_path, local_art_uri);
+                       g_free (local_art_uri);
+               }
        }
 
-       if (!created && no_cache_or_old) {
+       if (cache_art_file) {
+               g_object_unref (cache_art_file);
+       }
+
+       if (local_art_file) {
+               g_object_unref (local_art_file);
+       }
+
+       g_free (cache_art_path);
+       g_free (uri);
+
+       return processed;
+}
+
+/**
+ * media_art_process_file:
+ * @process: Media art process object
+ * @type: The type of media
+ * @flags: The options given for how to process the media art
+ * @file: File to be processed
+ * @artist: (allow-none): The artist name @file or %NULL
+ * @title: (allow-none): The title for @file or %NULL
+ * @error: Pointer to potential GLib / MediaArt error, or %NULL
+ *
+ * Process @file and check if media art exists and if it is up to date
+ * with @artist and @title provided. Either @artist OR @title can be
+ * %NULL, but they can not both be %NULL.
+ *
+ * NOTE: This function MAY retrieve media art for
+ * @artist and @title combinations. It is not guaranteed and depends
+ * on download services available over DBus at the time.
+ *
+ * In cases where download is unavailable, media_art_process_file()
+ * will only try to procure a cache for possible media art found in
+ * directories surrounding the location of @file. If a buffer or
+ * memory chunk needs to be saved to disk which has been retrieved
+ * from an MP3 (for example), you should use
+ * media_art_process_buffer().
+ *
+ * The modification time (mtime) of @file is checked against the
+ * cached stored for @artist and @title. If the cache is old or
+ * doesn't exist, it will be updated. What this actually does is
+ * update the mtime of the cache (a symlink) on the disk.
+ *
+ * If there is no actual media art stored locally (for example, it's
+ * stored in a directory on a removable device), it is copied locally
+ * (usually to an XDG cache directory).
+ *
+ * If @file is on a removable filesystem, the media art file will be
+ * saved in a cache on the removable file system rather than on the
+ * host machine.
+ *
+ * Returns: %TRUE if @file could be processed or %FALSE if @error is set.
+ *
+ * Since: 0.3.0
+ */
+gboolean
+media_art_process_file (MediaArtProcess       *process,
+                        MediaArtType           type,
+                        MediaArtProcessFlags   flags,
+                        GFile                 *file,
+                        const gchar           *artist,
+                        const gchar           *title,
+                        GError               **error)
+{
+       MediaArtProcessPrivate *private;
+       GFile *cache_art_file, *local_art_file;
+       GError *local_error = NULL;
+       gchar *cache_art_path, *uri;
+       gboolean no_cache_or_old;
+       guint64 mtime, cache_mtime;
+
+       g_return_val_if_fail (MEDIA_ART_IS_PROCESS (process), FALSE);
+       g_return_val_if_fail (type > MEDIA_ART_NONE && type < MEDIA_ART_TYPE_COUNT, FALSE);
+       g_return_val_if_fail (G_IS_FILE (file), FALSE);
+       g_return_val_if_fail (artist != NULL || title != NULL, FALSE);
+
+       private = media_art_process_get_instance_private (process);
+
+       uri = g_file_get_uri (file);
+       g_debug ("Processing media art: artist:'%s', title:'%s', type:'%s', uri:'%s', flags:0x%.8x",
+                artist ? artist : "",
+                title ? title : "",
+                media_art_type_name[type],
+                uri,
+                flags);
+
+       mtime = get_mtime (file, &local_error);
+       if (local_error != NULL) {
+               g_debug ("Could not get mtime for file '%s': %s",
+                        uri,
+                        local_error->message);
+               g_propagate_error (error, local_error);
+               g_free (uri);
+
+               return FALSE;
+       }
+
+       media_art_get_file (artist,
+                           title,
+                           media_art_type_name[type],
+                           file,
+                           &cache_art_file,
+                           &local_art_file);
+
+       cache_art_path = g_file_get_path (cache_art_file);
+
+       cache_mtime = get_mtime (cache_art_file, &local_error);
+       no_cache_or_old = cache_mtime == -1 || cache_mtime < mtime;
+
+       if (no_cache_or_old) {
                /* If not, we perform a heuristic on the dir */
                gchar *key;
 
@@ -1648,6 +1761,8 @@ media_art_process_file (MediaArtProcess  *process,
                                                            title,
                                                            local_art_uri,
                                                            cache_art_path);
+
+                               /* FIXME: Should return TRUE or FALSE? */
                        }
 
                        set_mtime (cache_art_path, mtime);
@@ -1659,25 +1774,12 @@ media_art_process_file (MediaArtProcess  *process,
                } else {
                        g_free (key);
                }
-       } else if (!created) {
+       } else {
                g_debug ("Album art already exists for uri:'%s' as '%s'",
                         uri,
                         cache_art_path);
        }
 
-       if (local_art_file && !g_file_query_exists (local_art_file, NULL)) {
-               /* We can't reuse art_exists here because the
-                * situation might have changed
-                */
-               if (g_file_query_exists (cache_art_file, NULL)) {
-                       gchar *local_art_uri;
-
-                       local_art_uri = g_file_get_uri (local_art_file);
-                       media_art_copy_to_local (process, cache_art_path, local_art_uri);
-                       g_free (local_art_uri);
-               }
-       }
-
        if (cache_art_file) {
                g_object_unref (cache_art_file);
        }
@@ -1689,54 +1791,50 @@ media_art_process_file (MediaArtProcess  *process,
        g_free (cache_art_path);
        g_free (uri);
 
-       return processed;
+       return TRUE;
 }
 
-
 /**
  * media_art_process_uri:
  * @process: Media art process object
- * @uri: URI of the media file that contained the data
- * @buffer: (array length=len): A buffer of binary data
- * @len: The length of @buffer, in bytes
- * @mime: The MIME type of the data stored in @buffer
  * @type: The type of media that contained the image data
- * @artist: (allow-none): Artist name of the media
- * @title: (allow-none): Title of the media
+ * @flags: How the media art is processed
+ * @uri: URI of the media file that contained the data
+ * @artist: (allow-none): The artist name @uri or %NULL
+ * @title: (allow-none): The title for @uri or %NULL
  * @error: Pointer to potential GLib / MediaArt error, or %NULL
  *
- * This function is the same as media_art_process_file(), but takes the URI as
- * a string rather than a #GFile object.
+ * This function calls media_art_process_file(), but takes the @uri as
+ * a string rather than a #GFile object. Either @artist OR @title can be
+ * %NULL, but they can not both be %NULL.
  *
  * Returns: %TRUE if @uri could be processed or %FALSE if @error is set.
  *
  * Since: 0.3.0
  */
 gboolean
-media_art_process_uri (MediaArtProcess      *process,
-                       const gchar          *uri,
-                       const unsigned char  *buffer,
-                       size_t                len,
-                       const gchar          *mime,
-                       MediaArtType          type,
-                       const gchar          *artist,
-                       const gchar          *title,
-                       GError              **error)
+media_art_process_uri (MediaArtProcess       *process,
+                       MediaArtType           type,
+                       MediaArtProcessFlags   flags,
+                       const gchar           *uri,
+                       const gchar           *artist,
+                       const gchar           *title,
+                       GError               **error)
 {
        GFile *file;
        gboolean result;
 
        g_return_val_if_fail (MEDIA_ART_IS_PROCESS (process), FALSE);
+       g_return_val_if_fail (type > MEDIA_ART_NONE && type < MEDIA_ART_TYPE_COUNT, FALSE);
        g_return_val_if_fail (uri != NULL, FALSE);
+       g_return_val_if_fail (artist != NULL || title != NULL, FALSE);
 
        file = g_file_new_for_uri (uri);
 
        result = media_art_process_file (process,
-                                        file,
-                                        buffer,
-                                        len,
-                                        mime,
                                         type,
+                                        flags,
+                                        file,
                                         artist,
                                         title,
                                         error);
diff --git a/libmediaart/extract.h b/libmediaart/extract.h
index a17c8c9..e96ee59 100644
--- a/libmediaart/extract.h
+++ b/libmediaart/extract.h
@@ -46,6 +46,19 @@ typedef enum {
        MEDIA_ART_TYPE_COUNT
 } MediaArtType;
 
+/**
+ * MediaArtProcessFlags:
+ * @MEDIA_ART_PROCESS_FLAGS_NONE: Normal operation.
+ * @MEDIA_ART_PROCESS_FLAGS_FORCE: Force media art to be re-saved to disk even if it already exists and the 
related file or URI has the same modified time (mtime).
+ *
+ * This type categorized the flags used when processing media art.
+ *
+ * Since: 0.3
+ */
+typedef enum {
+       MEDIA_ART_PROCESS_FLAGS_NONE   = 0,
+       MEDIA_ART_PROCESS_FLAGS_FORCE  = 1 << 0,
+} MediaArtProcessFlags;
 
 /**
  * MediaArtError:
@@ -69,8 +82,14 @@ typedef enum {
        MEDIA_ART_ERROR_RENAME_FAILED
 } MediaArtError;
 
-#define MEDIA_ART_ERROR media_art_error_quark ()
 
+/**
+ * media_art_error_quark:
+ *
+ * A #GQuark representing the type of #GError for #MediaArtProcess failures.
+ *
+ * Since: 0.2.0.
+ **/
 GQuark media_art_error_quark (void) G_GNUC_CONST;
 
 
@@ -104,30 +123,34 @@ struct _MediaArtProcessClass {
        GObjectClass parent;
 };
 
-GType    media_art_process_type (void) G_GNUC_CONST;
-MediaArtProcess *
-         media_art_process_new  (GError              **error);
-
-gboolean media_art_process_uri  (MediaArtProcess      *process,
-                                 const gchar          *uri,
-                                 const unsigned char  *buffer,
-                                 size_t                len,
-                                 const gchar          *mime,
-                                 MediaArtType          type,
-                                 const gchar          *artist,
-                                 const gchar          *title,
-                                 GError              **error);
-
-gboolean media_art_process_file (MediaArtProcess      *process,
-                                 GFile                *file,
-                                 const guchar         *buffer,
-                                gsize                 len,
-                                const gchar          *mime,
-                                MediaArtType          type,
-                                const gchar          *artist,
-                                 const gchar          *title,
-                                 GError              **error);
+
+GType            media_art_process_get_type (void) G_GNUC_CONST;
+MediaArtProcess *media_art_process_new      (GError               **error);
+gboolean         media_art_process_uri      (MediaArtProcess       *process,
+                                             MediaArtType           type,
+                                             MediaArtProcessFlags   flags,
+                                             const gchar           *uri,
+                                             const gchar           *artist,
+                                             const gchar           *title,
+                                             GError               **error);
+gboolean         media_art_process_file     (MediaArtProcess       *process,
+                                             MediaArtType           type,
+                                             MediaArtProcessFlags   flags,
+                                             GFile                 *file,
+                                             const gchar           *artist,
+                                             const gchar           *title,
+                                             GError               **error);
+gboolean         media_art_process_buffer   (MediaArtProcess       *process,
+                                             MediaArtType           type,
+                                             MediaArtProcessFlags   flags,
+                                             GFile                 *related_file,
+                                             const guchar          *buffer,
+                                             gsize                  len,
+                                             const gchar           *mime,
+                                             const gchar           *artist,
+                                             const gchar           *title,
+                                             GError               **error);
 
 G_END_DECLS
 
-#endif /* __LIBMEDIAART_UTILS_H__ */
+#endif /* __LIBMEDIAART_EXTRACT_H__ */
diff --git a/libmediaart/extractdummy.c b/libmediaart/extractdummy.c
index 195de31..f80ccd2 100644
--- a/libmediaart/extractdummy.c
+++ b/libmediaart/extractdummy.c
@@ -22,30 +22,98 @@
 
 #include "extractgeneric.h"
 
+/**
+ * SECTION:plugins
+ * @title: Plugins
+ * @short_description: Plugins for cache conversion.
+ * @include: libmediaart/mediaart.h
+ *
+ * Plugins are provided to allow different systems to make use of
+ * existing file format conversion APIs. By default, a GdkPixbuf and
+ * Qt implementation are provided. This API allows new implementations
+ * to be provided.
+ *
+ **/
+
+/**
+ * media_art_plugin_init:
+ * @max_width: The maximum width that an image is allowed to be
+ *
+ * This function facilitates a plugin&apos;s need to create any
+ * internal caches before anything else is done. This function must
+ * exist in each plugin and is called immediately after the plugin is
+ * loaded. Conversely, media_art_plugin_shutdown() is called before
+ * tear down of the plugin system or plugin itself.
+ *
+ * Since: 0.1.0
+ */
 void
 media_art_plugin_init (gint max_width)
 {
        /* Initialize something */
 }
 
+/**
+ * media_art_plugin_shutdown:
+ *
+ * This function facilitates a plugin&apos;s need to clean up any
+ * internal caches. This function must exist in each plugin and is
+ * called immediately after the plugin is loaded. Conversely,
+ * media_art_plugin_init() is called after the plugin is loaded.
+ *
+ * Since: 0.1.0
+ */
 void
 media_art_plugin_shutdown (void)
 {
        /* Shutdown something */
 }
 
+/**
+ * media_art_file_to_jpeg:
+ * @filename: Original file name (not URI) to convert
+ * @target: Output file name (not URI) to save converted content to
+ * @error: A #GError to use upon failure, or %NULL
+ *
+ * Save @filename to @target as JPEG format. The @filename may not be
+ * a JPEG in the first place.
+ *
+ * Returns: %TRUE if conversion was successful, otherwise %FALSE is
+ * returned if @error is set.
+ *
+ * Since: 0.1.0
+ */
 gboolean
-media_art_file_to_jpeg (const gchar *filename,
-                        const gchar *target)
+media_art_file_to_jpeg (const gchar  *filename,
+                        const gchar  *target,
+                        GError      **error)
 {
        return FALSE;
 }
 
+/**
+ * media_art_buffer_to_jpeg:
+ * @buffer: Raw buffer representing content to save
+ * @len: Length of @buffer to use
+ * @buffer_mime: MIME type for @buffer
+ * @target: Output file name (not URI) to save converted content to
+ * @error: A #GError to use upon failure, or %NULL
+ *
+ * This function performs the same operation as
+ * media_art_file_to_jpeg() with the exception that a raw @buffer can
+ * be used instead providing @len and the @buffer_mime too.
+ *
+ * Returns: %TRUE if conversion was successful, otherwise %FALSE is
+ * returned if @error is set.
+ *
+ * Since: 0.1.0
+ */
 gboolean
-media_art_buffer_to_jpeg (const unsigned char *buffer,
-                          size_t               len,
-                          const gchar         *buffer_mime,
-                          const gchar         *target)
+media_art_buffer_to_jpeg (const unsigned char  *buffer,
+                          size_t                len,
+                          const gchar          *buffer_mime,
+                          const gchar          *target,
+                          GError              **error)
 {
        return FALSE;
 }
diff --git a/libmediaart/extractgeneric.h b/libmediaart/extractgeneric.h
index 7f0584e..8fa114b 100644
--- a/libmediaart/extractgeneric.h
+++ b/libmediaart/extractgeneric.h
@@ -20,7 +20,6 @@
  * Philip Van Hoof <philip codeminded be>
  */
 
-
 #ifndef __LIBMEDIAART_EXTRACTGENERIC_H__
 #define __LIBMEDIAART_EXTRACTGENERIC_H__
 
diff --git a/libmediaart/storage.c b/libmediaart/storage.c
index 93cb533..36213d7 100644
--- a/libmediaart/storage.c
+++ b/libmediaart/storage.c
@@ -28,7 +28,7 @@
 #include "marshal.h"
 
 /**
- * SECTION:-storage
+ * SECTION:storage
  * @short_description: Removable storage and mount point convenience API
  * @include: libmediaart/mediaart.h
  *
diff --git a/tests/mediaarttest.c b/tests/mediaarttest.c
index 9cead21..09cc1ae 100644
--- a/tests/mediaarttest.c
+++ b/tests/mediaarttest.c
@@ -161,8 +161,13 @@ test_mediaart_location_null (void)
         gchar *path = NULL, *local_uri = NULL;
 
         /* NULL parameters */
-        media_art_get_path (NULL, NULL, "album", "file:///a/b/c.mp3", &path, &local_uri);
-        g_assert (!path && !local_uri);
+        media_art_get_path (NULL, "some-title", "album", "file:///a/b/c.mp3", &path, &local_uri);
+        g_assert (path != NULL);
+        g_assert (local_uri != NULL);
+
+        media_art_get_path ("some-artist", NULL, "album", "file:///a/b/c.mp3", &path, &local_uri);
+        g_assert (path != NULL);
+        g_assert (local_uri != NULL);
 }
 
 static void
@@ -199,8 +204,6 @@ test_mediaart_embedded_mp3 (void)
        gchar *dir, *path;
        gboolean retval;
 
-       /* FIXME: Handle 'buffer' AND 'file/path', is broken currently */
-
        dir = g_get_current_dir ();
        path = g_build_filename (G_DIR_SEPARATOR_S, dir, "543249_King-Kilo---Radium.mp3", NULL);
        file = g_file_new_for_path (path);
@@ -209,22 +212,16 @@ test_mediaart_embedded_mp3 (void)
        process = media_art_process_new (&error);
        g_assert_no_error (error);
 
-       /* NOTE: This should fail because we aren't passing a buffer
-        * in. With MP3 files, or none IMAGE based files, we don't
-        * have extractors for each type and it's up to the caller to
-        * pass in the data buffer to save in this case. */
        retval = media_art_process_file (process,
-                                        file,
-                                        NULL,
-                                        0,
-                                        "audio/mp3", /* mime */
                                         MEDIA_ART_ALBUM,
+                                        MEDIA_ART_PROCESS_FLAGS_FORCE,
+                                        file,
                                         "King Kilo", /* artist */
                                         "Radium",    /* title */
                                         &error);
 
        g_assert_no_error (error);
-       g_assert_false (retval);
+       g_assert_true (retval);
 
        g_object_unref (file);
        g_free (dir);
@@ -233,7 +230,7 @@ test_mediaart_embedded_mp3 (void)
 }
 
 static void
-test_mediaart_png (void)
+test_mediaart_process_buffer (void)
 {
        MediaArtProcess *process;
        GError *error = NULL;
@@ -245,7 +242,7 @@ test_mediaart_png (void)
        gboolean retval;
 
        dir = g_get_current_dir ();
-       path = g_build_filename (G_DIR_SEPARATOR_S, dir, "LanedoIconHKS43-64².png", NULL);
+       path = g_build_filename (G_DIR_SEPARATOR_S, dir, "cover.png", NULL);
        file = g_file_new_for_path (path);
        g_free (dir);
 
@@ -265,11 +262,9 @@ test_mediaart_png (void)
 
        /* Process data */
        retval = media_art_process_file (process,
-                                        file,
-                                        NULL,
-                                        0,
-                                        "image/png", /* mime */
                                         MEDIA_ART_ALBUM,
+                                        MEDIA_ART_PROCESS_FLAGS_NONE,
+                                        file,
                                         NULL,        /* album */
                                         "Lanedo",    /* title */
                                         &error);
@@ -294,7 +289,7 @@ test_mediaart_png (void)
         /* FIXME: Why does this next test fail - i.e. file does not
          * exist if we've processed it?
          */
-        /* g_assert (g_file_test (out_path, G_FILE_TEST_EXISTS) == TRUE); */
+        g_assert (g_file_test (out_path, G_FILE_TEST_EXISTS) == TRUE);
 
         g_free (out_path);
         g_free (out_uri);
@@ -327,11 +322,9 @@ test_mediaart_process_failures (void)
 
        /* Test: invalid file */
        g_assert (!media_art_process_uri (process,
-                                         "file:///invalid/path.png",
-                                         NULL,
-                                         0,
-                                         "image/png", /* mime */
                                          MEDIA_ART_ALBUM,
+                                         MEDIA_ART_PROCESS_FLAGS_NONE,
+                                         "file:///invalid/path.png",
                                          "Foo",       /* album */
                                          "Bar",       /* title */
                                          &error));
@@ -365,11 +358,9 @@ test_mediaart_process_failures_subprocess (void)
        g_assert_no_error (error);
 
        g_assert (!media_art_process_uri (process,
-                                         NULL,
-                                         NULL,
-                                         0,
-                                         "image/png", /* mime */
                                          MEDIA_ART_ALBUM,
+                                         MEDIA_ART_PROCESS_FLAGS_NONE,
+                                         NULL,
                                          "Foo",       /* album */
                                          "Bar",       /* title */
                                          &error));
@@ -401,8 +392,8 @@ main (int argc, char **argv)
                          test_mediaart_location_path);
         g_test_add_func ("/mediaart/embedded_mp3",
                          test_mediaart_embedded_mp3);
-        g_test_add_func ("/mediaart/png",
-                         test_mediaart_png);
+        g_test_add_func ("/mediaart/process_buffer",
+                         test_mediaart_process_buffer);
         g_test_add_func ("/mediaart/process_failures",
                          test_mediaart_process_failures);
         g_test_add_func ("/mediaart/process_failures/subprocess",



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]