diff options
author | Richard Hughes <richard@hughsie.com> | 2016-01-20 11:08:38 +0000 |
---|---|---|
committer | Richard Hughes <richard@hughsie.com> | 2016-01-25 12:00:50 +0000 |
commit | 547e770715302b75f4b815212a7952ce6508f8a9 (patch) | |
tree | 6807cea88cfe6069cd744bc7dd473fba553ba524 | |
parent | 9391e856ae20fa826c34c6f3aed0d0822bcc712f (diff) | |
download | appstream-glib-547e770715302b75f4b815212a7952ce6508f8a9.tar.gz |
Add support for per-user and system-wide xdg-app installed stores
-rw-r--r-- | client/as-util.c | 8 | ||||
-rw-r--r-- | libappstream-glib/as-store.c | 144 | ||||
-rw-r--r-- | libappstream-glib/as-store.h | 4 |
3 files changed, 133 insertions, 23 deletions
diff --git a/client/as-util.c b/client/as-util.c index 42cf2f7..3911475 100644 --- a/client/as-util.c +++ b/client/as-util.c @@ -1251,6 +1251,12 @@ as_util_dump (AsUtilPrivate *priv, gchar **values, GError **error) NULL, error)) { return FALSE; } + } else if (g_strcmp0 (values[0], "xdg-app") == 0) { + if (!as_store_load (store, + AS_STORE_LOAD_FLAG_XDG_APP_USER, + NULL, error)) { + return FALSE; + } } else { for (i = 0; values[i] != NULL; i++) { if (!as_util_add_file_to_store (store, values[i], error)) @@ -1293,6 +1299,8 @@ as_util_search (AsUtilPrivate *priv, gchar **values, GError **error) if (!as_store_load (store, AS_STORE_LOAD_FLAG_APP_INFO_SYSTEM | AS_STORE_LOAD_FLAG_APPDATA | + AS_STORE_LOAD_FLAG_XDG_APP_USER | + AS_STORE_LOAD_FLAG_XDG_APP_SYSTEM | AS_STORE_LOAD_FLAG_DESKTOP, NULL, error)) return FALSE; diff --git a/libappstream-glib/as-store.c b/libappstream-glib/as-store.c index e7508ba..5c35921 100644 --- a/libappstream-glib/as-store.c +++ b/libappstream-glib/as-store.c @@ -905,14 +905,34 @@ as_store_from_root (AsStore *store, if (tmp != NULL) as_store_set_builder_id (store, tmp); - /* if we have an origin either from the XML or _set_origin() */ + /* nothing specified */ + if (icon_root == NULL) + icon_root = "/usr/share/app-info/"; + + /* try the speecification directory first */ if (priv->origin != NULL) { - if (icon_root == NULL) - icon_root = "/usr/share/app-info/icons/"; icon_path = g_build_filename (icon_root, + "..", + "icons", priv->origin, NULL); + if (!g_file_test (icon_path, G_FILE_TEST_IS_DIR)) { + g_free (icon_path); + icon_path = NULL; + } } + + /* fall back to the xdg-app location */ + if (icon_path == NULL) { + icon_path = g_build_filename (icon_root, + "icons", + NULL); + if (!g_file_test (icon_path, G_FILE_TEST_IS_DIR)) { + g_free (icon_path); + icon_path = NULL; + } + } + ctx = as_node_context_new (); for (n = apps->children; n != NULL; n = n->next) { g_autoptr(GError) error_local = NULL; @@ -1769,7 +1789,6 @@ as_store_load_app_info_file (AsStore *store, static gboolean as_store_load_app_info (AsStore *store, const gchar *path, - const gchar *format, GCancellable *cancellable, GError **error) { @@ -1777,33 +1796,31 @@ as_store_load_app_info (AsStore *store, const gchar *tmp; g_autoptr(GDir) dir = NULL; g_autoptr(GError) error_local = NULL; - g_autofree gchar *icon_root = NULL; - g_autofree gchar *path_md = NULL; _cleanup_uninhibit_ guint32 *tok = NULL; /* emit once when finished */ tok = as_store_changed_inhibit (store); /* search all files */ - path_md = g_build_filename (path, format, NULL); - if (!g_file_test (path_md, G_FILE_TEST_EXISTS)) + if (!g_file_test (path, G_FILE_TEST_EXISTS)) return TRUE; - dir = g_dir_open (path_md, 0, &error_local); + dir = g_dir_open (path, 0, &error_local); if (dir == NULL) { g_set_error (error, AS_STORE_ERROR, AS_STORE_ERROR_FAILED, "Failed to open %s: %s", - path_md, error_local->message); + path, error_local->message); return FALSE; } - icon_root = g_build_filename (path, "icons", NULL); while ((tmp = g_dir_read_name (dir)) != NULL) { g_autofree gchar *filename_md = NULL; - filename_md = g_build_filename (path_md, tmp, NULL); + if (g_strcmp0 (tmp, "icons") == 0) + continue; + filename_md = g_build_filename (path, tmp, NULL); if (!as_store_load_app_info_file (store, filename_md, - icon_root, + path, cancellable, error)) return FALSE; @@ -1811,7 +1828,7 @@ as_store_load_app_info (AsStore *store, /* watch the directories for changes */ if (!as_monitor_add_directory (priv->monitor, - path_md, + path, cancellable, error)) return FALSE; @@ -2062,6 +2079,37 @@ as_store_load_path (AsStore *store, const gchar *path, } /** + * as_store_add_path_xdg_app: + **/ +static void +as_store_add_path_xdg_app (GPtrArray *array, const gchar *base) +{ + const gchar *filename; + g_autoptr(GDir) dir = NULL; + dir = g_dir_open (base, 0, NULL); + if (dir == NULL) + return; + while ((filename = g_dir_read_name (dir)) != NULL) { + gchar *fn = g_build_filename (base, + filename, + "x86_64", + "active", + NULL); + g_ptr_array_add (array, fn); + } +} + +/** + * as_store_add_path_both: + **/ +static void +as_store_add_path_both (GPtrArray *array, const gchar *base) +{ + g_ptr_array_add (array, g_build_filename (base, "yaml", NULL)); + g_ptr_array_add (array, g_build_filename (base, "xmls", NULL)); +} + +/** * as_store_load: * @store: a #AsStore instance. * @flags: #AsStoreLoadFlags, e.g. %AS_STORE_LOAD_FLAG_APP_INFO_SYSTEM @@ -2101,7 +2149,7 @@ as_store_load (AsStore *store, for (i = 0; data_dirs[i] != NULL; i++) { if ((flags & AS_STORE_LOAD_FLAG_APP_INFO_SYSTEM) > 0) { path = g_build_filename (data_dirs[i], "app-info", NULL); - g_ptr_array_add (app_info, path); + as_store_add_path_both (app_info, path); } if ((flags & AS_STORE_LOAD_FLAG_APPDATA) > 0) { path = g_build_filename (data_dirs[i], "appdata", NULL); @@ -2114,23 +2162,23 @@ as_store_load (AsStore *store, } if ((flags & AS_STORE_LOAD_FLAG_APP_INFO_SYSTEM) > 0) { path = g_build_filename (LOCALSTATEDIR, "lib", "app-info", NULL); - g_ptr_array_add (app_info, path); + as_store_add_path_both (app_info, path); path = g_build_filename (LOCALSTATEDIR, "cache", "app-info", NULL); - g_ptr_array_add (app_info, path); + as_store_add_path_both (app_info, path); /* ignore the prefix; we actually want to use the * distro-provided data in this case. */ if (g_strcmp0 (LOCALSTATEDIR, "/var") != 0) { path = g_build_filename ("/var", "lib", "app-info", NULL); - g_ptr_array_add (app_info, path); + as_store_add_path_both (app_info, path); path = g_build_filename ("/var", "cache", "app-info", NULL); - g_ptr_array_add (app_info, path); + as_store_add_path_both (app_info, path); } } /* per-user locations */ if ((flags & AS_STORE_LOAD_FLAG_APP_INFO_USER) > 0) { path = g_build_filename (g_get_user_data_dir (), "app-info", NULL); - g_ptr_array_add (app_info, path); + as_store_add_path_both (app_info, path); } if ((flags & AS_STORE_LOAD_FLAG_APPDATA) > 0) { path = g_build_filename (g_get_user_data_dir (), "appdata", NULL); @@ -2140,6 +2188,58 @@ as_store_load (AsStore *store, path = g_build_filename (g_get_user_data_dir (), "applications", NULL); g_ptr_array_add (installed, path); } + if ((flags & AS_STORE_LOAD_FLAG_XDG_APP_USER) > 0) { + if ((flags & AS_STORE_LOAD_FLAG_APPDATA) > 0) { + path = g_build_filename (g_get_user_data_dir (), + "xdg-app", + "exports", + "share", + "applications", + NULL); + g_ptr_array_add (installed, path); + } + if ((flags & AS_STORE_LOAD_FLAG_DESKTOP) > 0) { + path = g_build_filename (g_get_user_data_dir (), + "xdg-app", + "exports", + "share", + "appdata", + NULL); + g_ptr_array_add (installed, path); + } + /* add AppStream */ + path = g_build_filename (g_get_user_data_dir (), + "xdg-app", + "appstream", + NULL); + as_store_add_path_xdg_app (app_info, path); + } + if ((flags & AS_STORE_LOAD_FLAG_XDG_APP_SYSTEM) > 0) { + if ((flags & AS_STORE_LOAD_FLAG_APPDATA) > 0) { + path = g_build_filename (LOCALSTATEDIR, + "xdg-app", + "exports", + "share", + "applications", + NULL); + g_ptr_array_add (installed, path); + } + if ((flags & AS_STORE_LOAD_FLAG_DESKTOP) > 0) { + path = g_build_filename (LOCALSTATEDIR, + "xdg-app", + "exports", + "share", + "appdata", + NULL); + g_ptr_array_add (installed, path); + } + /* add AppStream */ + path = g_build_filename (LOCALSTATEDIR, + "xdg-app", + "appstream", + NULL); + as_store_add_path_xdg_app (app_info, path); + } /* load each app-info path if it exists */ tok = as_store_changed_inhibit (store); @@ -2149,9 +2249,7 @@ as_store_load (AsStore *store, dest = g_build_filename (priv->destdir ? priv->destdir : "/", tmp, NULL); if (!g_file_test (dest, G_FILE_TEST_EXISTS)) continue; - if (!as_store_load_app_info (store, dest, "xmls", cancellable, error)) - return FALSE; - if (!as_store_load_app_info (store, dest, "yaml", cancellable, error)) + if (!as_store_load_app_info (store, dest, cancellable, error)) return FALSE; } diff --git a/libappstream-glib/as-store.h b/libappstream-glib/as-store.h index 4847c0d..e8e61f8 100644 --- a/libappstream-glib/as-store.h +++ b/libappstream-glib/as-store.h @@ -60,6 +60,8 @@ struct _AsStoreClass * @AS_STORE_LOAD_FLAG_APPDATA: The installed AppData files * @AS_STORE_LOAD_FLAG_DESKTOP: The installed desktop files * @AS_STORE_LOAD_FLAG_ALLOW_VETO: Add vetoed applications + * @AS_STORE_LOAD_FLAG_XDG_APP_USER: Add xdg-app user applications + * @AS_STORE_LOAD_FLAG_XDG_APP_SYSTEM: Add xdg-app system applications * * The flags to use when loading the store. **/ @@ -71,6 +73,8 @@ typedef enum { AS_STORE_LOAD_FLAG_APPDATA = 8, /* Since: 0.2.2 */ AS_STORE_LOAD_FLAG_DESKTOP = 16, /* Since: 0.2.2 */ AS_STORE_LOAD_FLAG_ALLOW_VETO = 32, /* Since: 0.2.5 */ + AS_STORE_LOAD_FLAG_XDG_APP_USER = 64, /* Since: 0.5.7 */ + AS_STORE_LOAD_FLAG_XDG_APP_SYSTEM = 128, /* Since: 0.5.7 */ /*< private >*/ AS_STORE_LOAD_FLAG_LAST } AsStoreLoadFlags; |