diff options
author | Martyn Russell <martyn@lanedo.com> | 2014-07-28 09:14:24 +0100 |
---|---|---|
committer | Martyn Russell <martyn@lanedo.com> | 2014-07-28 09:14:24 +0100 |
commit | 880d09fbff1f89f4ce5ed9ee5b1d23ccc6e20da2 (patch) | |
tree | 020db8fecac9c460faf2ffdb21ebd43f01086179 | |
parent | 92cb3a327c65c0ba6c9d28b01116ef01a54903c0 (diff) | |
download | libmediaart-880d09fbff1f89f4ce5ed9ee5b1d23ccc6e20da2.tar.gz |
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.
-rw-r--r-- | docs/reference/libmediaart/libmediaart-docs.sgml | 1 | ||||
-rw-r--r-- | docs/reference/libmediaart/libmediaart-sections.txt | 33 | ||||
-rw-r--r-- | libmediaart/cache.c | 43 | ||||
-rw-r--r-- | libmediaart/extract.c | 312 | ||||
-rw-r--r-- | libmediaart/extract.h | 73 | ||||
-rw-r--r-- | libmediaart/extractdummy.c | 80 | ||||
-rw-r--r-- | libmediaart/extractgeneric.h | 1 | ||||
-rw-r--r-- | libmediaart/storage.c | 2 | ||||
-rw-r--r-- | tests/LanedoIconHKS43-64².png | bin | 1560 -> 0 bytes | |||
-rw-r--r-- | 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'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'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/LanedoIconHKS43-64².png b/tests/LanedoIconHKS43-64².png Binary files differdeleted file mode 100644 index b5261a7..0000000 --- a/tests/LanedoIconHKS43-64².png +++ /dev/null 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", |