[epiphany] Migrate search-engines setting from an array of tuples to a vardict



commit fbde9b187244be4ff899ac33922e621031e5b438
Author: vanadiae <vanadiae35 gmail com>
Date:   Sun Dec 26 19:57:02 2021 +0100

    Migrate search-engines setting from an array of tuples to a vardict
    
    That will make it easier to extend the search engines later, e.g. to add
    OpenSearch support (w/ search suggestions).
    
    Part-of: <https://gitlab.gnome.org/GNOME/epiphany/-/merge_requests/1052>

 data/org.gnome.epiphany.gschema.xml          | 34 +++++++++++++-----
 lib/ephy-prefs.h                             |  2 +-
 lib/ephy-profile-utils.h                     |  2 +-
 lib/ephy-search-engine-manager.c             | 44 +++++++++++++++++------
 src/profile-migrator/ephy-profile-migrator.c | 53 ++++++++++++++++++++++++++++
 5 files changed, 114 insertions(+), 21 deletions(-)
---
diff --git a/data/org.gnome.epiphany.gschema.xml b/data/org.gnome.epiphany.gschema.xml
index 8f8dadedd..7d1e14a6f 100644
--- a/data/org.gnome.epiphany.gschema.xml
+++ b/data/org.gnome.epiphany.gschema.xml
@@ -22,16 +22,34 @@
                        <summary>Default search engine.</summary>
                        <description>Name of the search engine selected by default.</description>
                </key>
+               <!-- As much as it can be annoying, there is just no way of migrating from a GVariant type to
+                       an other one while keeping the previous key name, as GSettings enforces the new
+                       key type way too much. It detects the previous value isn't an aa{sv} and instead
+                       replaces it with the default value as fallback. It would erase all search engines
+                       one might have, which is of course unacceptable. So despite "search-engine-providers"
+                       being less nice than "search-engines", we need to change name to be able to migrate. 
-->
+               <!-- FIXME: Remove this deprecated key when dropping its migrator in the future. -->
                <key type="a(sss)" name="search-engines">
+                       <summary>Deprecated. Please use search-engine-providers instead.</summary>
+                       <default>[]</default>
+               </key>
+               <key type="aa{sv}" name="search-engine-providers">
                        <default l10n="messages">
-                                 <!-- TRANSLATORS: These are the prepopulated search engines. You should
-                                      add country-specific URL query parameters if appropriate. -->
-                                 [('DuckDuckGo', 'https://duckduckgo.com/?q=%s&amp;t=epiphany', '!ddg'),
-                                 ('Google', 'https://www.google.com/search?q=%s', '!g'),
-                                 ('Bing', 'https://www.bing.com/search?q=%s', '!b')]
-                       </default>
-                       <summary>Default search engines.</summary>
-                       <description>List of the default search engines. It is an array in which each search 
engine is described by a name, an address, and a bang (shortcut).</description>
+                               <!-- TRANSLATORS: These are the prepopulated search engines. You should
+                                       add country-specific URL query parameters if appropriate. -->
+                               <![CDATA[
+                               [
+                                       {'name': <'DuckDuckGo'>, 'url': 
<'https://duckduckgo.com/?q=%s&t=epiphany'>, 'bang': <'!ddg'>},
+                                       {'name': <'Google'>, 'url': <'https://www.google.com/search?q=%s'>, 
'bang': <'!g'>},
+                                       {'name': <'Bing'>, 'url': <'https://www.bing.com/search?q=%s'>, 
'bang': <'!b'>}
+                               ]
+                       ]]></default>
+                       <summary>List of the search engines.</summary>
+                       <description>List of the search engines. It is an array of vardicts with each vardict 
corresponding to a search engine, and with the following supported keys:
+                               - name: The name of the search engine
+                               - url: The search URL with the search term replaced with %s.
+                               - bang: The "bang" (shortcut word) of the search engine
+                       </description>
                </key>
                <key type="b" name="use-google-search-suggestions">
                        <default>false</default>
diff --git a/lib/ephy-prefs.h b/lib/ephy-prefs.h
index a52e1ab4e..41c08a3a2 100644
--- a/lib/ephy-prefs.h
+++ b/lib/ephy-prefs.h
@@ -147,7 +147,7 @@ static const char * const ephy_prefs_web_schema[] = {
 #define EPHY_PREFS_RESTORE_SESSION_POLICY             "restore-session-policy"
 #define EPHY_PREFS_RESTORE_SESSION_DELAYING_LOADS     "restore-session-delaying-loads"
 #define EPHY_PREFS_CONTENT_FILTERS                    "content-filters"
-#define EPHY_PREFS_SEARCH_ENGINES                     "search-engines"
+#define EPHY_PREFS_SEARCH_ENGINES                     "search-engine-providers"
 #define EPHY_PREFS_DEFAULT_SEARCH_ENGINE              "default-search-engine"
 #define EPHY_PREFS_ASK_FOR_DEFAULT                    "ask-for-default"
 #define EPHY_PREFS_START_IN_INCOGNITO_MODE            "start-in-incognito-mode"
diff --git a/lib/ephy-profile-utils.h b/lib/ephy-profile-utils.h
index c97910063..6da1ef834 100644
--- a/lib/ephy-profile-utils.h
+++ b/lib/ephy-profile-utils.h
@@ -24,7 +24,7 @@
 
 G_BEGIN_DECLS
 
-#define EPHY_PROFILE_MIGRATION_VERSION 35
+#define EPHY_PROFILE_MIGRATION_VERSION 36
 #define EPHY_INSECURE_PASSWORDS_MIGRATION_VERSION 11
 #define EPHY_FIREFOX_SYNC_PASSWORDS_MIGRATION_VERSION 19
 #define EPHY_TARGET_ORIGIN_MIGRATION_VERSION 21
diff --git a/lib/ephy-search-engine-manager.c b/lib/ephy-search-engine-manager.c
index 7f9c5eb49..96285a721 100644
--- a/lib/ephy-search-engine-manager.c
+++ b/lib/ephy-search-engine-manager.c
@@ -81,23 +81,33 @@ search_engines_changed_cb (GSettings *settings,
 static void
 ephy_search_engine_manager_init (EphySearchEngineManager *manager)
 {
-  const char *address;
-  const char *bang;
-  char *name;
   g_autoptr (GVariantIter) iter = NULL;
+  GVariant *search_engine;
 
   manager->search_engines = g_hash_table_new_full (g_str_hash,
                                                    g_str_equal,
                                                    g_free,
                                                    (GDestroyNotify)ephy_search_engine_info_free);
 
-  g_settings_get (EPHY_SETTINGS_MAIN, EPHY_PREFS_SEARCH_ENGINES, "a(sss)", &iter);
+  g_settings_get (EPHY_SETTINGS_MAIN, EPHY_PREFS_SEARCH_ENGINES, "aa{sv}", &iter);
+
+  while ((search_engine = g_variant_iter_next_value (iter))) {
+    const char *address;
+    const char *bang;
+    char *name = NULL;
+    GVariantDict dict;
+    EphySearchEngineInfo *info;
+
+    g_variant_dict_init (&dict, search_engine);
+    g_variant_dict_lookup (&dict, "url", "&s", &address);
+    g_variant_dict_lookup (&dict, "bang", "&s", &bang);
+    g_variant_dict_lookup (&dict, "name", "s", &name);
+
+    info = ephy_search_engine_info_new (address, bang);
 
-  while (g_variant_iter_next (iter, "(s&s&s)", &name, &address, &bang)) {
-    g_hash_table_insert (manager->search_engines,
-                         name,
-                         ephy_search_engine_info_new (address,
-                                                      bang));
+    g_hash_table_insert (manager->search_engines, name, info);
+
+    g_variant_unref (search_engine);
   }
 
   g_signal_connect (EPHY_SETTINGS_MAIN,
@@ -260,12 +270,24 @@ ephy_search_engine_manager_apply_settings (EphySearchEngineManager *manager)
   GVariantBuilder builder;
   GVariant *variant;
 
-  g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(sss)"));
+  g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
   g_hash_table_iter_init (&iter, manager->search_engines);
 
   while (g_hash_table_iter_next (&iter, &key, &value)) {
+    GVariantDict dict;
+
     info = (EphySearchEngineInfo *)value;
-    g_variant_builder_add (&builder, "(sss)", key, info->address, info->bang);
+    g_assert (key != NULL);
+    g_assert (info != NULL);
+    g_assert (info->address != NULL);
+    g_assert (info->bang != NULL);
+
+    g_variant_dict_init (&dict, NULL);
+    g_variant_dict_insert (&dict, "url", "s", info->address);
+    g_variant_dict_insert (&dict, "bang", "s", info->bang);
+    g_variant_dict_insert (&dict, "name", "s", key);
+
+    g_variant_builder_add_value (&builder, g_variant_dict_end (&dict));
   }
   variant = g_variant_builder_end (&builder);
   g_settings_set_value (EPHY_SETTINGS_MAIN, EPHY_PREFS_SEARCH_ENGINES, variant);
diff --git a/src/profile-migrator/ephy-profile-migrator.c b/src/profile-migrator/ephy-profile-migrator.c
index 76c4a7b39..fcec8eb5b 100644
--- a/src/profile-migrator/ephy-profile-migrator.c
+++ b/src/profile-migrator/ephy-profile-migrator.c
@@ -1421,6 +1421,57 @@ next:
   }
 }
 
+static void
+migrate_search_engines_to_vardict (void)
+{
+  g_autoptr (GVariant) search_engines =
+    g_settings_get_value (EPHY_SETTINGS_MAIN, "search-engines");
+  GVariantBuilder search_engines_builder;
+  GVariantIter iter;
+  const char *name, *url, *bang;
+
+  /* Very unlikely to happen unless someone badly modified the gsettings manually. */
+  if (!g_variant_check_format_string (search_engines, "a(sss)", FALSE)) {
+    /* Let's not reset the deprecated search engines key though, to give a chance
+     * to migrate it by manually copy-pasting them in the prefs from the gsettings.
+     */
+    g_warning ("Couldn't migrate search engines to new GVariant type because the old key isn't using the 
proper GVariant type!");
+    return;
+  }
+
+  /* Here it would mean the value is unchanged _and_ that it's the empty array.
+   * This case arises if you try running the newer Epiphany with
+   * the migration (e.g. from this branch), then the older one using
+   * the deprecated key. The older Epiphany will downgrade the
+   * .migrated file's version, and when running the new Epiphany it
+   * will think you have no search engines at all, and replace all
+   * your already migrated search engines with the empty array.
+   * Now of course if you reach step 2 you'll have no search engines
+   * in the older Epiphany as they'll have been reset when migrating,
+   * but at least when you use back the newer Epiphany it won't try
+   * migrating (and hence erasing) all your search engines.
+   */
+  if (!g_settings_get_user_value (EPHY_SETTINGS_MAIN, "search-engines"))
+    return;
+
+  g_variant_builder_init (&search_engines_builder, G_VARIANT_TYPE ("aa{sv}"));
+  g_variant_iter_init (&iter, search_engines);
+  while (g_variant_iter_next (&iter, "(&s&s&s)", &name, &url, &bang)) {
+    GVariantDict vardict;
+
+    g_variant_dict_init (&vardict, NULL);
+    g_variant_dict_insert (&vardict, "name", "s", name);
+    g_variant_dict_insert (&vardict, "url", "s", url);
+    g_variant_dict_insert (&vardict, "bang", "s", bang);
+
+    g_variant_builder_add_value (&search_engines_builder, g_variant_dict_end (&vardict));
+  }
+
+  /* Erase the deprecated key's value, and set the new key's value to the migrated format. */
+  g_settings_reset (EPHY_SETTINGS_MAIN, "search-engines");
+  g_settings_set_value (EPHY_SETTINGS_MAIN, EPHY_PREFS_SEARCH_ENGINES, g_variant_builder_end 
(&search_engines_builder));
+}
+
 static void
 migrate_nothing (void)
 {
@@ -1471,6 +1522,8 @@ const EphyProfileMigrator migrators[] = {
   /* 33 */ migrate_adblock_to_content_filters,
   /* 34 */ migrate_adblock_to_shared_cache_dir,
   /* 35 */ migrate_webapp_names,
+  /* FIXME: Please also remove the "search-engines" deprecated gschema key when dropping this migrator in 
the future. */
+  /* 36 */ migrate_search_engines_to_vardict,
 };
 
 static gboolean


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