/** * gs_appstream_refine_add_addons: */ static void gs_appstream_refine_add_addons (GsPlugin *plugin, GsApp *app, AsApp *item) { GPtrArray *addons; guint i; addons = as_app_get_addons (item); if (addons == NULL) return; for (i = 0; i < addons->len; i++) { AsApp *as_addon = g_ptr_array_index (addons, i); g_autoptr(GError) error = NULL; g_autoptr(GsApp) addon = NULL; addon = gs_app_new (as_app_get_id (as_addon)); /* add all the data we can */ if (!gs_appstream_refine_app (plugin, addon, as_addon, &error)) { g_warning ("failed to refine addon: %s", error->message); continue; } gs_app_add_addon (app, addon); } }
/** * gs_plugin_file_to_app: */ gboolean gs_plugin_file_to_app (GsPlugin *plugin, GList **list, GFile *file, GCancellable *cancellable, GError **error) { g_autofree gchar *content_type = NULL; g_autofree gchar *id_prefixed = NULL; g_autoptr(GBytes) appstream_gz = NULL; g_autoptr(GBytes) icon_data = NULL; g_autoptr(GBytes) metadata = NULL; g_autoptr(GsApp) app = NULL; g_autoptr(XdgAppBundleRef) xref_bundle = NULL; const gchar *mimetypes[] = { "application/vnd.xdgapp", NULL }; /* does this match any of the mimetypes we support */ content_type = gs_utils_get_content_type (file, cancellable, error); if (content_type == NULL) return FALSE; if (!g_strv_contains (mimetypes, content_type)) return TRUE; /* load bundle */ xref_bundle = xdg_app_bundle_ref_new (file, error); if (xref_bundle == NULL) { g_prefix_error (error, "error loading bundle: "); return FALSE; } /* create a virtual ID */ id_prefixed = gs_plugin_xdg_app_build_id (XDG_APP_REF (xref_bundle)); /* load metadata */ app = gs_app_new (id_prefixed); gs_app_set_kind (app, AS_APP_KIND_DESKTOP); gs_app_set_state (app, AS_APP_STATE_AVAILABLE_LOCAL); gs_app_set_size_installed (app, xdg_app_bundle_ref_get_installed_size (xref_bundle)); gs_plugin_xdg_app_set_metadata (app, XDG_APP_REF (xref_bundle)); metadata = xdg_app_bundle_ref_get_metadata (xref_bundle); if (!gs_plugin_xdg_app_set_app_metadata (app, g_bytes_get_data (metadata, NULL), g_bytes_get_size (metadata), error)) return FALSE; /* load AppStream */ appstream_gz = xdg_app_bundle_ref_get_appstream (xref_bundle); if (appstream_gz != NULL) { g_autoptr(GZlibDecompressor) decompressor = NULL; g_autoptr(GInputStream) stream_gz = NULL; g_autoptr(GInputStream) stream_data = NULL; g_autoptr(GBytes) appstream = NULL; g_autoptr(AsStore) store = NULL; g_autofree gchar *id = NULL; AsApp *item; /* decompress data */ decompressor = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP); stream_gz = g_memory_input_stream_new_from_bytes (appstream_gz); if (stream_gz == NULL) return FALSE; stream_data = g_converter_input_stream_new (stream_gz, G_CONVERTER (decompressor)); appstream = g_input_stream_read_bytes (stream_data, 0x100000, /* 1Mb */ cancellable, error); if (appstream == NULL) return FALSE; store = as_store_new (); if (!as_store_from_bytes (store, appstream, cancellable, error)) return FALSE; /* find app */ id = g_strdup_printf ("%s.desktop", gs_app_get_xdgapp_name (app)); item = as_store_get_app_by_id (store, id); if (item == NULL) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "application %s not found", id); return FALSE; } /* copy details from AppStream to app */ if (!gs_appstream_refine_app (plugin, app, item, error)) return FALSE; } /* load icon */ icon_data = xdg_app_bundle_ref_get_icon (xref_bundle, 64 * gs_plugin_get_scale (plugin)); if (icon_data == NULL) icon_data = xdg_app_bundle_ref_get_icon (xref_bundle, 64); if (icon_data != NULL) { g_autoptr(GInputStream) stream_icon = NULL; g_autoptr(GdkPixbuf) pixbuf = NULL; stream_icon = g_memory_input_stream_new_from_bytes (icon_data); pixbuf = gdk_pixbuf_new_from_stream (stream_icon, cancellable, error); if (pixbuf == NULL) return FALSE; gs_app_set_pixbuf (app, pixbuf); } else { g_autoptr(AsIcon) icon = NULL; icon = as_icon_new (); as_icon_set_kind (icon, AS_ICON_KIND_STOCK); as_icon_set_name (icon, "application-x-executable"); gs_app_set_icon (app, icon); } /* not quite true: this just means we can update this specific app */ if (xdg_app_bundle_ref_get_origin (xref_bundle)) gs_app_add_quirk (app, AS_APP_QUIRK_HAS_SOURCE); g_debug ("created local app: %s", gs_app_to_string (app)); gs_app_list_add (list, app); return TRUE; }