[gnome-color-manager] Ignore duplicate profiles by the MD5 checksum and add self test code to test this
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-color-manager] Ignore duplicate profiles by the MD5 checksum and add self test code to test this
- Date: Tue, 1 Jun 2010 10:54:41 +0000 (UTC)
commit 8ff51a149c69065162e645ca80f7a47fa0d8dede
Author: Richard Hughes <richard hughsie com>
Date: Tue Jun 1 11:23:20 2010 +0100
Ignore duplicate profiles by the MD5 checksum and add self test code to test this
src/gcm-prefs.c | 3 +
src/gcm-profile-store.c | 179 +++++++++++++++++++++++++++++++++++++----------
src/gcm-profile-store.h | 5 ++
src/gcm-self-test.c | 43 +++++++++++
4 files changed, 192 insertions(+), 38 deletions(-)
---
diff --git a/src/gcm-prefs.c b/src/gcm-prefs.c
index c6d09fc..48e4bdb 100644
--- a/src/gcm-prefs.c
+++ b/src/gcm-prefs.c
@@ -2860,6 +2860,9 @@ gcm_prefs_startup_phase1_idle_cb (gpointer user_data)
gchar *intent_display;
gchar *intent_softproof;
+ /* search the disk for profiles */
+ gcm_profile_store_search_default (profile_store);
+
/* setup RGB combobox */
widget = GTK_WIDGET (gtk_builder_get_object (builder, "combobox_space_rgb"));
colorspace_rgb = g_settings_get_string (settings, GCM_SETTINGS_COLORSPACE_RGB);
diff --git a/src/gcm-profile-store.c b/src/gcm-profile-store.c
index 882fc53..7d45b52 100644
--- a/src/gcm-profile-store.c
+++ b/src/gcm-profile-store.c
@@ -41,9 +41,6 @@ static void gcm_profile_store_finalize (GObject *object);
#define GCM_PROFILE_STORE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GCM_TYPE_PROFILE_STORE, GcmProfileStorePrivate))
-static gboolean gcm_profile_store_add_profiles_for_path (GcmProfileStore *profile_store, const gchar *path);
-static void gcm_profile_store_add_profiles (GcmProfileStore *profile_store);
-
/**
* GcmProfileStorePrivate:
*
@@ -138,22 +135,71 @@ out:
}
/**
- * gcm_profile_store_notify_filename_cb:
+ * gcm_profile_store_get_by_checksum:
+ *
+ * @profile_store: a valid %GcmProfileStore instance
+ * @checksum: the profile checksum
+ *
+ * Gets a profile.
+ *
+ * Return value: a valid %GcmProfile or %NULL. Free with g_object_unref()
**/
-static void
-gcm_profile_store_notify_filename_cb (GcmProfile *profile, GParamSpec *pspec, GcmProfileStore *profile_store)
+GcmProfile *
+gcm_profile_store_get_by_checksum (GcmProfileStore *profile_store, const gchar *checksum)
{
- const gchar *description;
+ guint i;
+ GcmProfile *profile = NULL;
+ GcmProfile *profile_tmp;
+ const gchar *checksum_tmp;
+ GcmProfileStorePrivate *priv = profile_store->priv;
+
+ g_return_val_if_fail (GCM_IS_PROFILE_STORE (profile_store), NULL);
+ g_return_val_if_fail (checksum != NULL, NULL);
+
+ /* find profile */
+ for (i=0; i<priv->profile_array->len; i++) {
+ profile_tmp = g_ptr_array_index (priv->profile_array, i);
+ checksum_tmp = gcm_profile_get_checksum (profile_tmp);
+ if (g_strcmp0 (checksum, checksum_tmp) == 0) {
+ profile = g_object_ref (profile_tmp);
+ goto out;
+ }
+ }
+out:
+ return profile;
+}
+
+/**
+ * gcm_profile_store_remove_profile:
+ **/
+static gboolean
+gcm_profile_store_remove_profile (GcmProfileStore *profile_store, GcmProfile *profile)
+{
+ gboolean ret;
GcmProfileStorePrivate *priv = profile_store->priv;
/* remove from list */
- g_ptr_array_remove (priv->profile_array, profile);
+ ret = g_ptr_array_remove (priv->profile_array, profile);
+ if (!ret) {
+ egg_warning ("failed to remove %s", gcm_profile_get_filename (profile));
+ goto out;
+ }
/* emit a signal */
- description = gcm_profile_get_description (profile);
- egg_debug ("emit removed (and changed): %s", description);
+ egg_debug ("emit removed (and changed): %s", gcm_profile_get_filename (profile));
g_signal_emit (profile_store, signals[SIGNAL_REMOVED], 0, profile);
g_signal_emit (profile_store, signals[SIGNAL_CHANGED], 0);
+out:
+ return ret;
+}
+
+/**
+ * gcm_profile_store_notify_filename_cb:
+ **/
+static void
+gcm_profile_store_notify_filename_cb (GcmProfile *profile, GParamSpec *pspec, GcmProfileStore *profile_store)
+{
+ gcm_profile_store_remove_profile (profile_store, profile);
}
/**
@@ -164,8 +210,10 @@ gcm_profile_store_add_profile (GcmProfileStore *profile_store, GFile *file)
{
gboolean ret = FALSE;
GcmProfile *profile = NULL;
+ GcmProfile *profile_tmp = NULL;
GError *error = NULL;
gchar *filename = NULL;
+ const gchar *checksum;
GcmProfileStorePrivate *priv = profile_store->priv;
/* already added? */
@@ -183,6 +231,22 @@ gcm_profile_store_add_profile (GcmProfileStore *profile_store, GFile *file)
goto out;
}
+ /* check the profile has not been added already */
+ checksum = gcm_profile_get_checksum (profile);
+ profile_tmp = gcm_profile_store_get_by_checksum (profile_store, checksum);
+ if (profile_tmp != NULL) {
+
+ /* we value a local file higher than the shared file */
+ if (gcm_profile_get_can_delete (profile_tmp)) {
+ egg_debug ("already added a deletable profile %s, cannot add %s",
+ gcm_profile_get_filename (profile_tmp), filename);
+ goto out;
+ }
+
+ /* remove the old profile in favour of the new one */
+ gcm_profile_store_remove_profile (profile_store, profile_tmp);
+ }
+
/* add to array */
egg_debug ("parsed new profile '%s'", filename);
g_ptr_array_add (priv->profile_array, g_object_ref (profile));
@@ -194,6 +258,8 @@ gcm_profile_store_add_profile (GcmProfileStore *profile_store, GFile *file)
g_signal_emit (profile_store, signals[SIGNAL_CHANGED], 0);
out:
g_free (filename);
+ if (profile_tmp != NULL)
+ g_object_unref (profile_tmp);
if (profile != NULL)
g_object_unref (profile);
return ret;
@@ -218,20 +284,23 @@ gcm_profile_store_file_monitor_changed_cb (GFileMonitor *monitor, GFile *file, G
goto out;
}
egg_debug ("%s was added, rescanning everything", path);
- gcm_profile_store_add_profiles (profile_store);
+ gcm_profile_store_search_default (profile_store);
out:
g_free (path);
}
/**
- * gcm_profile_store_add_profiles_for_path:
+ * gcm_profile_store_search_by_path:
+ *
+ * Return value: if any profile were added
**/
-static gboolean
-gcm_profile_store_add_profiles_for_path (GcmProfileStore *profile_store, const gchar *path)
+gboolean
+gcm_profile_store_search_by_path (GcmProfileStore *profile_store, const gchar *path)
{
GDir *dir = NULL;
GError *error = NULL;
- gboolean ret = TRUE;
+ gboolean ret;
+ gboolean success = FALSE;
const gchar *name;
gchar *full_path;
GcmProfileStorePrivate *priv = profile_store->priv;
@@ -245,7 +314,7 @@ gcm_profile_store_add_profiles_for_path (GcmProfileStore *profile_store, const g
file = g_file_new_for_path (path);
ret = gcm_utils_is_icc_profile (file);
if (ret) {
- gcm_profile_store_add_profile (profile_store, file);
+ success = gcm_profile_store_add_profile (profile_store, file);
goto out;
}
@@ -289,7 +358,9 @@ gcm_profile_store_add_profiles_for_path (GcmProfileStore *profile_store, const g
/* make the compete path */
full_path = g_build_filename (path, name, NULL);
- gcm_profile_store_add_profiles_for_path (profile_store, full_path);
+ ret = gcm_profile_store_search_by_path (profile_store, full_path);
+ if (ret)
+ success = TRUE;
g_free (full_path);
} while (TRUE);
out:
@@ -299,13 +370,13 @@ out:
g_object_unref (file);
if (dir != NULL)
g_dir_close (dir);
- return ret;
+ return success;
}
/**
* gcm_profile_store_add_profiles_from_mounted_volume:
**/
-static void
+static gboolean
gcm_profile_store_add_profiles_from_mounted_volume (GcmProfileStore *profile_store, GMount *mount)
{
GFile *root;
@@ -314,6 +385,8 @@ gcm_profile_store_add_profiles_from_mounted_volume (GcmProfileStore *profile_sto
const gchar *type;
GFileInfo *info;
GError *error = NULL;
+ gboolean ret;
+ gboolean success = FALSE;
/* get the mount root */
root = g_mount_get_root (mount);
@@ -334,7 +407,9 @@ gcm_profile_store_add_profiles_from_mounted_volume (GcmProfileStore *profile_sto
/* only scan hfs volumes for OSX */
if (g_strcmp0 (type, "hfs") == 0) {
path = g_build_filename (path_root, "Library", "ColorSync", "Profiles", "Displays", NULL);
- gcm_profile_store_add_profiles_for_path (profile_store, path);
+ ret = gcm_profile_store_search_by_path (profile_store, path);
+ if (ret)
+ success = TRUE;
g_free (path);
/* no more matching */
@@ -346,17 +421,23 @@ gcm_profile_store_add_profiles_from_mounted_volume (GcmProfileStore *profile_sto
/* Windows XP */
path = g_build_filename (path_root, "Windows", "system32", "spool", "drivers", "color", NULL);
- gcm_profile_store_add_profiles_for_path (profile_store, path);
+ ret = gcm_profile_store_search_by_path (profile_store, path);
+ if (ret)
+ success = TRUE;
g_free (path);
/* Windows 2000 */
path = g_build_filename (path_root, "Winnt", "system32", "spool", "drivers", "color", NULL);
- gcm_profile_store_add_profiles_for_path (profile_store, path);
+ ret = gcm_profile_store_search_by_path (profile_store, path);
+ if (ret)
+ success = TRUE;
g_free (path);
/* Windows 98 and ME */
path = g_build_filename (path_root, "Windows", "System", "Color", NULL);
- gcm_profile_store_add_profiles_for_path (profile_store, path);
+ ret = gcm_profile_store_search_by_path (profile_store, path);
+ if (ret)
+ success = TRUE;
g_free (path);
/* no more matching */
@@ -365,14 +446,17 @@ gcm_profile_store_add_profiles_from_mounted_volume (GcmProfileStore *profile_sto
out:
g_free (path_root);
g_object_unref (root);
+ return success;
}
/**
* gcm_profile_store_add_profiles_from_mounted_volumes:
**/
-static void
+static gboolean
gcm_profile_store_add_profiles_from_mounted_volumes (GcmProfileStore *profile_store)
{
+ gboolean ret;
+ gboolean success = FALSE;
GList *mounts, *l;
GMount *mount;
GcmProfileStorePrivate *priv = profile_store->priv;
@@ -381,32 +465,47 @@ gcm_profile_store_add_profiles_from_mounted_volumes (GcmProfileStore *profile_st
mounts = g_volume_monitor_get_mounts (priv->volume_monitor);
for (l = mounts; l != NULL; l = l->next) {
mount = l->data;
- gcm_profile_store_add_profiles_from_mounted_volume (profile_store, mount);
+ ret = gcm_profile_store_add_profiles_from_mounted_volume (profile_store, mount);
+ if (ret)
+ success = TRUE;
g_object_unref (mount);
}
g_list_free (mounts);
+ return success;
}
/**
* gcm_profile_store_add_profiles:
+ *
+ * Return value: if any profile were added
**/
-static void
-gcm_profile_store_add_profiles (GcmProfileStore *profile_store)
+gboolean
+gcm_profile_store_search_default (GcmProfileStore *profile_store)
{
gchar *path;
gboolean ret;
+ gboolean success = FALSE;
GError *error;
GcmProfileStorePrivate *priv = profile_store->priv;
/* get OSX and Linux system-wide profiles */
- gcm_profile_store_add_profiles_for_path (profile_store, "/usr/share/color/icc");
- gcm_profile_store_add_profiles_for_path (profile_store, "/usr/local/share/color/icc");
- gcm_profile_store_add_profiles_for_path (profile_store, "/Library/ColorSync/Profiles/Displays");
+ ret = gcm_profile_store_search_by_path (profile_store, "/usr/share/color/icc");
+ if (ret)
+ success = TRUE;
+ ret = gcm_profile_store_search_by_path (profile_store, "/usr/local/share/color/icc");
+ if (ret)
+ success = TRUE;
+ ret = gcm_profile_store_search_by_path (profile_store, "/Library/ColorSync/Profiles/Displays");
+ if (ret)
+ success = TRUE;
/* get OSX and Windows system-wide profiles when using Linux */
ret = g_settings_get_boolean (priv->settings, GCM_SETTINGS_USE_PROFILES_FROM_VOLUMES);
- if (ret)
- gcm_profile_store_add_profiles_from_mounted_volumes (profile_store);
+ if (ret) {
+ ret = gcm_profile_store_add_profiles_from_mounted_volumes (profile_store);
+ if (ret)
+ success = TRUE;
+ }
/* get Linux per-user profiles */
path = g_build_filename (g_get_user_data_dir (), "icc", NULL);
@@ -415,19 +514,26 @@ gcm_profile_store_add_profiles (GcmProfileStore *profile_store)
egg_error ("failed to create directory on startup: %s", error->message);
g_error_free (error);
} else {
- gcm_profile_store_add_profiles_for_path (profile_store, path);
+ ret = gcm_profile_store_search_by_path (profile_store, path);
+ if (ret)
+ success = TRUE;
}
g_free (path);
/* get per-user profiles from obsolete location */
path = g_build_filename (g_get_home_dir (), ".color", "icc", NULL);
- gcm_profile_store_add_profiles_for_path (profile_store, path);
+ ret = gcm_profile_store_search_by_path (profile_store, path);
+ if (ret)
+ success = TRUE;
g_free (path);
/* get OSX per-user profiles */
path = g_build_filename (g_get_home_dir (), "Library", "ColorSync", "Profiles", NULL);
- gcm_profile_store_add_profiles_for_path (profile_store, path);
+ ret = gcm_profile_store_search_by_path (profile_store, path);
+ if (ret)
+ success = TRUE;
g_free (path);
+ return success;
}
/**
@@ -497,9 +603,6 @@ gcm_profile_store_init (GcmProfileStore *profile_store)
"mount-added",
G_CALLBACK(gcm_profile_store_volume_monitor_mount_added_cb),
profile_store);
-
- /* get profiles */
- gcm_profile_store_add_profiles (profile_store);
}
/**
diff --git a/src/gcm-profile-store.h b/src/gcm-profile-store.h
index ec593dd..7546ae3 100644
--- a/src/gcm-profile-store.h
+++ b/src/gcm-profile-store.h
@@ -64,7 +64,12 @@ GcmProfileStore *gcm_profile_store_new (void);
GcmProfile *gcm_profile_store_get_by_filename (GcmProfileStore *profile_store,
const gchar *filename);
+GcmProfile *gcm_profile_store_get_by_checksum (GcmProfileStore *profile_store,
+ const gchar *checksum);
GPtrArray *gcm_profile_store_get_array (GcmProfileStore *profile_store);
+gboolean gcm_profile_store_search_default (GcmProfileStore *profile_store);
+gboolean gcm_profile_store_search_by_path (GcmProfileStore *profile_store,
+ const gchar *path);
G_END_DECLS
diff --git a/src/gcm-self-test.c b/src/gcm-self-test.c
index 69328f6..a4ac4a7 100644
--- a/src/gcm-self-test.c
+++ b/src/gcm-self-test.c
@@ -40,6 +40,7 @@
#include "gcm-image.h"
#include "gcm-print.h"
#include "gcm-profile.h"
+#include "gcm-profile-store.h"
#include "gcm-profile-lcms1.h"
#include "gcm-tables.h"
#include "gcm-trc-widget.h"
@@ -816,6 +817,7 @@ typedef struct {
GcmProfileKind kind;
GcmColorspace colorspace;
gfloat luminance;
+ gboolean has_vcgt;
} GcmProfileTestData;
static void
@@ -849,6 +851,7 @@ gcm_test_profile_test_parse_file (const gchar *datafile, GcmProfileTestData *tes
g_assert_cmpstr (gcm_profile_get_checksum (profile_lcms1), ==, test_data->checksum);
g_assert_cmpint (gcm_profile_get_kind (profile_lcms1), ==, test_data->kind);
g_assert_cmpint (gcm_profile_get_colorspace (profile_lcms1), ==, test_data->colorspace);
+ g_assert_cmpint (gcm_profile_get_has_vcgt (profile_lcms1), ==, test_data->has_vcgt);
g_object_get (profile_lcms1,
"red", &xyz,
@@ -876,6 +879,7 @@ gcm_test_profile_func (void)
test_data.luminance = 0.648454;
test_data.datetime = "February 9 1998, 06:49:00 AM";
test_data.checksum = "8e2aed5dac6f8b5d8da75610a65b7f27";
+ test_data.has_vcgt = TRUE;
gcm_test_profile_test_parse_file ("bluish.icc", &test_data);
/* Adobe test */
@@ -888,10 +892,48 @@ gcm_test_profile_func (void)
test_data.luminance = 0.648446;
test_data.datetime = "August 16 2005, 09:49:54 PM";
test_data.checksum = "bd847723f676e2b846daaf6759330624";
+ test_data.has_vcgt = TRUE;
gcm_test_profile_test_parse_file ("AdobeGammaTest.icm", &test_data);
}
static void
+gcm_test_profile_store_func (void)
+{
+ GcmProfileStore *store;
+ GPtrArray *array;
+ GcmProfile *profile;
+ gboolean ret;
+ gchar *filename;
+
+ store = gcm_profile_store_new ();
+ g_assert (store != NULL);
+
+ /* add test files */
+ filename = gcm_test_get_data_file (".");
+ ret = gcm_profile_store_search_by_path (store, filename);
+ g_assert (ret);
+ g_free (filename);
+
+ /* profile does not exist */
+ profile = gcm_profile_store_get_by_filename (store, "xxxxxxxxx");
+ g_assert (profile == NULL);
+
+ /* profile does exist */
+ profile = gcm_profile_store_get_by_checksum (store, "8e2aed5dac6f8b5d8da75610a65b7f27");
+ g_assert (profile != NULL);
+ g_assert_cmpstr (gcm_profile_get_checksum (profile), ==, "8e2aed5dac6f8b5d8da75610a65b7f27");
+ g_object_unref (profile);
+
+ /* get array of profiles */
+ array = gcm_profile_store_get_array (store);
+ g_assert (array != NULL);
+ g_assert_cmpint (array->len, ==, 3);
+ g_ptr_array_unref (array);
+
+ g_object_unref (store);
+}
+
+static void
gcm_test_tables_func (void)
{
GcmTables *tables;
@@ -1197,6 +1239,7 @@ main (int argc, char **argv)
g_test_add_func ("/color/utils", gcm_test_utils_func);
g_test_add_func ("/color/device", gcm_test_device_func);
g_test_add_func ("/color/profile", gcm_test_profile_func);
+ g_test_add_func ("/color/profile_store", gcm_test_profile_store_func);
g_test_add_func ("/color/clut", gcm_test_clut_func);
g_test_add_func ("/color/xyz", gcm_test_xyz_func);
g_test_add_func ("/color/calibrate_dialog", gcm_test_calibrate_dialog_func);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]