[gnome-shell] remoteSearch: Factor out collectFromDatadirsAsync() utility function



commit c528401b628337c3c66987d1e88a859cb116870e
Author: Florian MÃllner <fmuellner gnome org>
Date:   Fri Nov 30 16:36:12 2012 +0100

    remoteSearch: Factor out collectFromDatadirsAsync() utility function
    
    Processing files from a subdirectory of various share/gnome-shell
    directories asynchronously is a common enough pattern to share
    the common code.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=689304

 js/misc/fileUtils.js  |   54 +++++++++++++++++++++
 js/ui/remoteSearch.js |  124 ++++++++++++++++++-------------------------------
 2 files changed, 100 insertions(+), 78 deletions(-)
---
diff --git a/js/misc/fileUtils.js b/js/misc/fileUtils.js
index 4e62025..f130b2b 100644
--- a/js/misc/fileUtils.js
+++ b/js/misc/fileUtils.js
@@ -2,6 +2,8 @@
 
 const Gio = imports.gi.Gio;
 const GLib = imports.gi.GLib;
+const Lang = imports.lang;
+const Params = imports.misc.params;
 
 function listDirAsync(file, callback) {
     let allFiles = [];
@@ -23,6 +25,58 @@ function listDirAsync(file, callback) {
     });
 }
 
+function _collectFromDirectoryAsync(dir, loadState) {
+    dir.query_info_async('standard:type', Gio.FileQueryInfoFlags.NONE,
+        GLib.PRIORITY_DEFAULT, null, function(object, res) {
+            try {
+                object.query_info_finish(res);
+            } catch (e) {
+                if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND))
+                    log(e.message);
+                return;
+            }
+
+            loadState.numLoading++;
+            listDirAsync(dir, Lang.bind(this, function(infos) {
+                for (let i = 0; i < infos.length; i++)
+                    loadState.processFile(dir.get_child(infos[i].get_name()),
+                                          infos[i], loadState.data);
+                loadState.numLoading--;
+                if (loadState.loadedCallback &&
+                    loadState.numLoading == 0)
+                    loadState.loadedCallback(loadState.data);
+            }));
+        });
+}
+
+function collectFromDatadirsAsync(subdir, params) {
+    params = Params.parse(params, { includeUserDir: false,
+                                    processFile: null,
+                                    loadedCallback: null,
+                                    data: null });
+    let loadState = { data: params.data,
+                      numLoading: 0,
+                      loadedCallback: params.loadedCallback,
+                      processFile: params.processFile };
+
+    if (params.processFile == null) {
+        if (params.loadedCallback)
+            params.loadedCallback(params.data);
+        return;
+    }
+
+    let dataDirs = GLib.get_system_data_dirs();
+    if (params.includeUserDir)
+        dataDirs.unshift(GLib.get_user_data_dir());
+
+    for (let i = 0; i < dataDirs.length; i++) {
+        let path = GLib.build_filenamev([dataDirs[i], 'gnome-shell', subdir]);
+        let dir = Gio.File.new_for_path(path);
+
+        _collectFromDirectoryAsync(dir, loadState);
+    }
+}
+
 function deleteGFile(file) {
     // Work around 'delete' being a keyword in JS.
     return file['delete'](null);
diff --git a/js/ui/remoteSearch.js b/js/ui/remoteSearch.js
index c9b25c6..8494e74 100644
--- a/js/ui/remoteSearch.js
+++ b/js/ui/remoteSearch.js
@@ -32,90 +32,58 @@ const SearchProviderIface = <interface name="org.gnome.Shell.SearchProvider">
 var SearchProviderProxy = Gio.DBusProxy.makeProxyWrapper(SearchProviderIface);
 
 function loadRemoteSearchProviders(addProviderCallback) {
-    let loadState = { loadedProviders: [],
-                      objectPaths: {},
-                      numLoading: 0,
-                      addProviderCallback: addProviderCallback };
-
-    let dataDirs = GLib.get_system_data_dirs();
-    for (let i = 0; i < dataDirs.length; i++) {
-        let path = GLib.build_filenamev([dataDirs[i], 'gnome-shell', 'search-providers']);
-        let dir = Gio.file_new_for_path(path);
-
-        dir.query_info_async('standard:type', Gio.FileQueryInfoFlags.NONE,
-            GLib.PRIORITY_DEFAULT, null,
-                function(object, res) {
-                    let exists = false;
-                    try {
-                        object.query_info_finish(res);
-                        exists = true;
-                    } catch (e) {
-                    }
-
-                    if (!exists)
-                        return;
-
-                    loadState.numLoading++;
-                    loadRemoteSearchProvidersFromDir(dir, loadState);
-                });
+    let data = { loadedProviders: [],
+                 objectPaths: {},
+                 addProviderCallback: addProviderCallback };
+    FileUtils.collectFromDatadirsAsync('search-providers',
+                                       { loadedCallback: remoteProvidersLoaded,
+                                         processFile: loadRemoteSearchProvider,
+                                         data: data
+                                       });
+}
+
+function loadRemoteSearchProvider(file, info, data) {
+    let keyfile = new GLib.KeyFile();
+    let path = file.get_path();
+
+    try {
+        keyfile.load_from_file(path, 0);
+    } catch(e) {
+        return;
     }
-};
-
-function loadRemoteSearchProvidersFromDir(dir, loadState) {
-    let dirPath = dir.get_path();
-    FileUtils.listDirAsync(dir, Lang.bind(this, function(files) {
-        for (let i = 0; i < files.length; i++) {
-            let keyfile = new GLib.KeyFile();
-            let path = GLib.build_filenamev([dirPath, files[i].get_name()]);
-
-            try {
-                keyfile.load_from_file(path, 0);
-            } catch(e) {
-                continue;
-            }
 
-            if (!keyfile.has_group(KEY_FILE_GROUP))
-                continue;
-
-            let remoteProvider;
-            try {
-                let group = KEY_FILE_GROUP;
-                let busName = keyfile.get_string(group, 'BusName');
-                let objectPath = keyfile.get_string(group, 'ObjectPath');
-
-                if (loadState.objectPaths[objectPath])
-                    continue;
-
-                let appInfo = null;
-                try {
-                    let desktopId = keyfile.get_string(group, 'DesktopId');
-                    appInfo = Gio.DesktopAppInfo.new(desktopId);
-                } catch (e) {
-                    log('Ignoring search provider ' + path + ': missing DesktopId');
-                    continue;
-                }
-
-                remoteProvider = new RemoteSearchProvider(appInfo,
-                                                          busName,
-                                                          objectPath);
-                loadState.objectPaths[objectPath] = remoteProvider;
-                loadState.loadedProviders.push(remoteProvider);
-            } catch(e) {
-                log('Failed to add search provider %s: %s'.format(path, e.toString()));
-                continue;
-            }
-        }
+    if (!keyfile.has_group(KEY_FILE_GROUP))
+        return;
 
-        remoteProvidersDirLoaded(loadState);
-    }));
+    let remoteProvider;
+    try {
+        let group = KEY_FILE_GROUP;
+        let busName = keyfile.get_string(group, 'BusName');
+        let objectPath = keyfile.get_string(group, 'ObjectPath');
 
-};
+        if (data.objectPaths[objectPath])
+            return;
 
-function remoteProvidersDirLoaded(loadState) {
-    loadState.numLoading--;
-    if (loadState.numLoading > 0)
-        return;
+        let appInfo = null;
+        try {
+            let desktopId = keyfile.get_string(group, 'DesktopId');
+            appInfo = Gio.DesktopAppInfo.new(desktopId);
+        } catch (e) {
+            log('Ignoring search provider ' + path + ': missing DesktopId');
+            return;
+        }
+
+        remoteProvider = new RemoteSearchProvider(appInfo,
+                                                  busName,
+                                                  objectPath);
+        data.objectPaths[objectPath] = remoteProvider;
+        data.loadedProviders.push(remoteProvider);
+    } catch(e) {
+        log('Failed to add search provider %s: %s'.format(path, e.toString()));
+    }
+}
 
+function remoteProvidersLoaded(loadState) {
     let searchSettings = new Gio.Settings({ schema: Search.SEARCH_PROVIDERS_SCHEMA });
     let sortOrder = searchSettings.get_strv('sort-order');
     let numSorted = sortOrder.length;



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