gboolean gs_plugin_refine_app (GsPlugin *plugin, GsApp *app, GsPluginRefineFlags flags, GCancellable *cancellable, GError **error) { GPtrArray *provides; guint i; /* not required */ if (gs_app_get_icons(app)->len > 0) return TRUE; if (gs_app_get_kind (app) != AS_APP_KIND_DRIVER) return TRUE; /* do any of the modaliases match any installed hardware */ provides = gs_app_get_provides (app); for (i = 0 ; i < provides->len; i++) { AsProvide *prov = g_ptr_array_index (provides, i); if (as_provide_get_kind (prov) != AS_PROVIDE_KIND_MODALIAS) continue; if (gs_plugin_modalias_matches (plugin, as_provide_get_value (prov))) { g_autoptr(AsIcon) ic = NULL; ic = as_icon_new (); as_icon_set_kind (ic, AS_ICON_KIND_STOCK); as_icon_set_name (ic, "emblem-system-symbolic"); gs_app_add_icon (app, ic); gs_app_add_quirk (app, GS_APP_QUIRK_NOT_LAUNCHABLE); break; } } return TRUE; }
static GsApp * gs_plugin_generic_updates_get_os_update (GsPlugin *plugin) { GsApp *app; const gchar *id = "org.gnome.Software.OsUpdate"; g_autoptr(AsIcon) ic = NULL; /* create new */ app = gs_app_new (id); gs_app_add_quirk (app, GS_APP_QUIRK_IS_PROXY); gs_app_set_management_plugin (app, ""); gs_app_set_kind (app, AS_APP_KIND_OS_UPDATE); gs_app_set_state (app, AS_APP_STATE_UPDATABLE_LIVE); gs_app_set_name (app, GS_APP_QUALITY_NORMAL, /* TRANSLATORS: this is a group of updates that are not * packages and are not shown in the main list */ _("OS Updates")); gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, /* TRANSLATORS: this is a longer description of the * "OS Updates" string */ _("Includes performance, stability and security improvements.")); gs_app_set_description (app, GS_APP_QUALITY_NORMAL, gs_app_get_summary (app)); ic = as_icon_new (); as_icon_set_kind (ic, AS_ICON_KIND_STOCK); as_icon_set_name (ic, "software-update-available-symbolic"); gs_app_add_icon (app, ic); return app; }
/** * gs_plugin_xdg_app_create_installed: */ static GsApp * gs_plugin_xdg_app_create_installed (GsPlugin *plugin, XdgAppInstalledRef *xref, GError **error) { g_autofree gchar *id = NULL; g_autoptr(AsIcon) icon = NULL; g_autoptr(GsApp) app = NULL; g_return_val_if_fail (xref != NULL, NULL); /* * Only show the current application in GNOME Software * * You can have multiple versions/branches of a particular app-id * installed but only one of them is "current" where this means: * 1) the default to launch unless you specify a version * 2) The one that gets its exported files exported */ if (!xdg_app_installed_ref_get_is_current (xref) && xdg_app_ref_get_kind (XDG_APP_REF(xref)) == XDG_APP_REF_KIND_APP) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_NOT_SUPPORTED, "%s not current, ignoring", xdg_app_ref_get_name (XDG_APP_REF (xref))); return NULL; } /* create new object */ id = gs_plugin_xdg_app_build_id (XDG_APP_REF (xref)); app = gs_app_new (id); gs_plugin_xdg_app_set_metadata_installed (app, xref); switch (xdg_app_ref_get_kind (XDG_APP_REF(xref))) { case XDG_APP_REF_KIND_APP: gs_app_set_kind (app, AS_APP_KIND_DESKTOP); break; case XDG_APP_REF_KIND_RUNTIME: gs_app_set_xdgapp_kind (app, XDG_APP_REF_KIND_RUNTIME); gs_app_set_kind (app, AS_APP_KIND_RUNTIME); gs_app_set_name (app, GS_APP_QUALITY_NORMAL, xdg_app_ref_get_name (XDG_APP_REF (xref))); gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "Framework for applications"); gs_app_set_version (app, xdg_app_ref_get_branch (XDG_APP_REF (xref))); icon = as_icon_new (); as_icon_set_kind (icon, AS_ICON_KIND_STOCK); as_icon_set_name (icon, "system-run-symbolic"); gs_app_set_icon (app, icon); break; default: g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_NOT_SUPPORTED, "XdgAppRefKind not known"); return NULL; } return g_object_ref (app); }
static gboolean load_desktop_icon (GsApp *app, SnapdSnap *snap) { GPtrArray *apps; guint i; apps = snapd_snap_get_apps (snap); for (i = 0; i < apps->len; i++) { SnapdApp *snap_app = apps->pdata[i]; const gchar *desktop_file_path; g_autoptr(GKeyFile) desktop_file = NULL; g_autoptr(GError) error = NULL; g_autofree gchar *icon_value = NULL; g_autoptr(AsIcon) icon = NULL; desktop_file_path = snapd_app_get_desktop_file (snap_app); if (desktop_file_path == NULL) continue; desktop_file = g_key_file_new (); if (!g_key_file_load_from_file (desktop_file, desktop_file_path, G_KEY_FILE_NONE, &error)) { g_warning ("Failed to load desktop file %s: %s", desktop_file_path, error->message); continue; } icon_value = g_key_file_get_string (desktop_file, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_ICON, &error); if (icon_value == NULL) { g_warning ("Failed to get desktop file icon %s: %s", desktop_file_path, error->message); continue; } icon = as_icon_new (); if (g_str_has_prefix (icon_value, "/")) { as_icon_set_kind (icon, AS_ICON_KIND_LOCAL); as_icon_set_filename (icon, icon_value); } else { as_icon_set_kind (icon, AS_ICON_KIND_STOCK); as_icon_set_name (icon, icon_value); } gs_app_add_icon (app, icon); return TRUE; } return FALSE; }
/** * as_icon_node_parse_dep11: * @icon: a #AsIcon instance. * @node: a #GNode. * @error: A #GError or %NULL. * * Populates the object from a DEP-11 node. * * Returns: %TRUE for success * * Since: 0.3.1 **/ gboolean as_icon_node_parse_dep11 (AsIcon *im, GNode *node, GError **error) { if (g_strcmp0 (as_yaml_node_get_key (node), "cached") != 0) return TRUE; as_icon_set_name (im, as_yaml_node_get_value (node), -1); as_icon_set_kind (im, AS_ICON_KIND_CACHED); return TRUE; }
/** * as_icon_node_parse: * @icon: a #AsIcon instance. * @node: a #GNode. * @error: A #GError or %NULL. * * Populates the object from a DOM node. * * Returns: %TRUE for success * * Since: 0.3.1 **/ gboolean as_icon_node_parse (AsIcon *icon, GNode *node, GError **error) { AsIconPrivate *priv = GET_PRIVATE (icon); const gchar *tmp; gint size; gboolean prepend_size = TRUE; tmp = as_node_get_attribute (node, "type"); as_icon_set_kind (icon, as_icon_kind_from_string (tmp)); switch (priv->kind) { case AS_ICON_KIND_EMBEDDED: if (!as_icon_node_parse_embedded (icon, node, error)) return FALSE; break; default: /* store the name without any prefix */ tmp = as_node_get_data (node); if (g_strstr_len (tmp, -1, "/") == NULL) { as_icon_set_name (icon, tmp, -1); } else { _cleanup_free_ gchar *basename = NULL; basename = g_path_get_basename (tmp); as_icon_set_name (icon, basename, -1); } /* width is optional, assume 64px if missing */ size = as_node_get_attribute_as_int (node, "width"); if (size == G_MAXINT) { size = 64; prepend_size = FALSE; } priv->width = size; /* height is optional, assume 64px if missing */ size = as_node_get_attribute_as_int (node, "height"); if (size == G_MAXINT) { size = 64; prepend_size = FALSE; } priv->height = size; /* only use the size if the metadata has width and height */ if (prepend_size) { g_free (priv->prefix_private); priv->prefix_private = g_strdup_printf ("%s/%ix%i", priv->prefix, priv->width, priv->height); } break; } return TRUE; }
static AsIcon * as_app_desktop_create_icon (AsApp *app, const gchar *name, AsAppParseFlags flags) { AsIcon *icon = as_icon_new (); gchar *dot; g_autofree gchar *name_fixed = NULL; /* local */ if (g_path_is_absolute (name)) { as_icon_set_kind (icon, AS_ICON_KIND_LOCAL); as_icon_set_filename (icon, name); return icon; } /* work around a common mistake in desktop files */ name_fixed = g_strdup (name); dot = g_strstr_len (name_fixed, -1, "."); if (dot != NULL && (g_strcmp0 (dot, ".png") == 0 || g_strcmp0 (dot, ".xpm") == 0 || g_strcmp0 (dot, ".svg") == 0)) { *dot = '\0'; } /* stock */ if (as_utils_is_stock_icon_name (name_fixed)) { as_icon_set_kind (icon, AS_ICON_KIND_STOCK); as_icon_set_name (icon, name_fixed); return icon; } /* stock, but kinda sneaky */ if ((flags & AS_APP_PARSE_FLAG_USE_FALLBACKS) > 0 && _as_utils_is_stock_icon_name_fallback (name_fixed)) { as_icon_set_kind (icon, AS_ICON_KIND_STOCK); as_icon_set_name (icon, name_fixed); return icon; } /* just use default of UNKNOWN */ as_icon_set_name (icon, name_fixed); return icon; }
static GsApp * gs_plugin_fwupd_new_app_from_device (GsPlugin *plugin, FwupdDevice *dev) { FwupdRelease *rel = fwupd_device_get_release_default (dev); GsApp *app; g_autofree gchar *id = NULL; g_autoptr(AsIcon) icon = NULL; /* older versions of fwups didn't record this for historical devices */ if (fwupd_release_get_appstream_id (rel) == NULL) return NULL; /* get from cache */ id = as_utils_unique_id_build (AS_APP_SCOPE_SYSTEM, AS_BUNDLE_KIND_UNKNOWN, NULL, /* origin */ AS_APP_KIND_FIRMWARE, fwupd_release_get_appstream_id (rel), NULL); app = gs_plugin_cache_lookup (plugin, id); if (app == NULL) { app = gs_app_new (id); gs_plugin_cache_add (plugin, id, app); } /* default stuff */ gs_app_set_kind (app, AS_APP_KIND_FIRMWARE); gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_CABINET); gs_app_add_quirk (app, GS_APP_QUIRK_NOT_LAUNCHABLE); gs_app_set_management_plugin (app, "fwupd"); gs_app_add_category (app, "System"); gs_fwupd_app_set_device_id (app, fwupd_device_get_id (dev)); /* create icon */ icon = as_icon_new (); as_icon_set_kind (icon, AS_ICON_KIND_STOCK); as_icon_set_name (icon, "application-x-firmware"); gs_app_add_icon (app, icon); gs_fwupd_app_set_from_release (app, rel); gs_fwupd_app_set_from_device (app, dev); if (fwupd_release_get_appstream_id (rel) != NULL) gs_app_set_id (app, fwupd_release_get_appstream_id (rel)); /* the same as we have already */ if (g_strcmp0 (fwupd_device_get_version (dev), fwupd_release_get_version (rel)) == 0) { g_warning ("same firmware version as installed"); } return app; }
static GsApp * gs_plugin_fwupd_new_app_from_device_raw (GsPlugin *plugin, FwupdDevice *device) { GPtrArray *icons; g_autofree gchar *id = NULL; g_autoptr(GsApp) app = NULL; /* create a GsApp based on the device, not the release */ id = gs_plugin_fwupd_build_device_id (device); app = gs_app_new (id); gs_app_set_kind (app, AS_APP_KIND_FIRMWARE); gs_app_set_scope (app, AS_APP_SCOPE_SYSTEM); gs_app_set_state (app, AS_APP_STATE_INSTALLED); gs_app_add_quirk (app, GS_APP_QUIRK_NOT_LAUNCHABLE); gs_app_set_version (app, fwupd_device_get_version (device)); gs_app_set_name (app, GS_APP_QUALITY_LOWEST, fwupd_device_get_name (device)); gs_app_set_summary (app, GS_APP_QUALITY_LOWEST, fwupd_device_get_summary (device)); gs_app_set_description (app, GS_APP_QUALITY_LOWEST, fwupd_device_get_description (device)); gs_app_set_origin (app, fwupd_device_get_vendor (device)); gs_fwupd_app_set_device_id (app, fwupd_device_get_id (device)); gs_app_set_management_plugin (app, "fwupd"); /* create icon */ icons = fwupd_device_get_icons (device); for (guint j = 0; j < icons->len; j++) { const gchar *icon = g_ptr_array_index (icons, j); g_autoptr(AsIcon) icon_tmp = as_icon_new (); if (g_str_has_prefix (icon, "/")) { as_icon_set_kind (icon_tmp, AS_ICON_KIND_LOCAL); as_icon_set_filename (icon_tmp, icon); } else { as_icon_set_kind (icon_tmp, AS_ICON_KIND_STOCK); as_icon_set_name (icon_tmp, icon); } gs_app_add_icon (app, icon_tmp); } return g_steal_pointer (&app); }
static gboolean load_store_icon (GsApp *app, SnapdSnap *snap) { const gchar *icon_url; icon_url = snapd_snap_get_icon (snap); if (icon_url == NULL) return FALSE; if (g_str_has_prefix (icon_url, "http://") || g_str_has_prefix (icon_url, "https://")) { g_autoptr(AsIcon) icon = as_icon_new (); as_icon_set_kind (icon, AS_ICON_KIND_REMOTE); as_icon_set_url (icon, icon_url); gs_app_add_icon (app, icon); return TRUE; } return FALSE; }
/** * asb_plugin_process: */ GList * asb_plugin_process (AsbPlugin *plugin, AsbPackage *pkg, const gchar *tmpdir, GError **error) { const gchar *tmp; gchar **split; GList *apps = NULL; GPtrArray *keywords; guint i; guint j; _cleanup_free_ gchar *app_id = NULL; _cleanup_object_unref_ AsbApp *app = NULL; _cleanup_object_unref_ AsIcon *icon = NULL; _cleanup_string_free_ GString *str = NULL; /* use the pkgname suffix as the app-id */ tmp = asb_package_get_name (pkg); if (g_str_has_prefix (tmp, "gstreamer1-")) tmp += 11; if (g_str_has_prefix (tmp, "gstreamer-")) tmp += 10; if (g_str_has_prefix (tmp, "plugins-")) tmp += 8; app_id = g_strdup_printf ("gstreamer-%s", tmp); /* create app */ app = asb_app_new (pkg, app_id); as_app_set_id_kind (AS_APP (app), AS_ID_KIND_CODEC); as_app_set_name (AS_APP (app), "C", "GStreamer Multimedia Codecs", -1); asb_app_set_requires_appdata (app, TRUE); asb_app_set_hidpi_enabled (app, asb_context_get_hidpi_enabled (plugin->ctx)); as_app_add_category (AS_APP (app), "Addons", -1); as_app_add_category (AS_APP (app), "Codecs", -1); /* add icon */ icon = as_icon_new (); as_icon_set_kind (icon, AS_ICON_KIND_STOCK); as_icon_set_name (icon, "application-x-executable", -1); as_app_add_icon (AS_APP (app), icon); for (i = 0; data[i].path != NULL; i++) { if (!asb_utils_is_file_in_tmpdir (tmpdir, data[i].path)) continue; split = g_strsplit (data[i].text, "|", -1); for (j = 0; split[j] != NULL; j++) as_app_add_keyword (AS_APP (app), NULL, split[j], -1); g_strfreev (split); } /* no codecs we care about */ keywords = as_app_get_keywords (AS_APP (app), NULL); if (keywords == NULL) { g_set_error (error, ASB_PLUGIN_ERROR, ASB_PLUGIN_ERROR_FAILED, "nothing interesting in %s", asb_package_get_basename (pkg)); return NULL; } /* sort categories by name */ g_ptr_array_sort (keywords, asb_utils_string_sort_cb); /* create a description */ str = g_string_new ("Multimedia playback for "); if (keywords->len > 1) { for (i = 0; i < keywords->len - 1; i++) { tmp = g_ptr_array_index (keywords, i); g_string_append_printf (str, "%s, ", tmp); } g_string_truncate (str, str->len - 2); tmp = g_ptr_array_index (keywords, keywords->len - 1); g_string_append_printf (str, " and %s", tmp); } else { g_string_append (str, g_ptr_array_index (keywords, 0)); } as_app_set_comment (AS_APP (app), "C", str->str, -1); /* add */ asb_plugin_add_app (&apps, AS_APP (app)); return apps; }
/** * gs_refine_item_pixbuf: */ static void gs_refine_item_pixbuf (GsPlugin *plugin, GsApp *app, AsApp *item) { AsIcon *icon; gboolean ret; g_autoptr(GError) error = NULL; g_autofree gchar *fn = NULL; g_autofree gchar *cachedir = NULL; icon = as_app_get_icon_default (item); switch (as_icon_get_kind (icon)) { case AS_ICON_KIND_REMOTE: gs_app_set_icon (app, icon); if (as_icon_get_filename (icon) == NULL) { cachedir = gs_utils_get_cachedir ("icons", NULL); fn = g_build_filename (cachedir, as_icon_get_name (icon), NULL); as_icon_set_filename (icon, fn); as_icon_set_prefix (icon, cachedir); } if (g_file_test (fn, G_FILE_TEST_EXISTS)) { as_icon_set_kind (icon, AS_ICON_KIND_LOCAL); ret = gs_app_load_icon (app, plugin->scale, &error); if (!ret) { g_warning ("failed to load icon %s: %s", as_icon_get_name (icon), error->message); return; } } break; case AS_ICON_KIND_STOCK: case AS_ICON_KIND_LOCAL: gs_app_set_icon (app, icon); /* does not exist, so try to find using the icon theme */ if (as_icon_get_kind (icon) == AS_ICON_KIND_LOCAL && as_icon_get_filename (icon) == NULL) as_icon_set_kind (icon, AS_ICON_KIND_STOCK); /* load */ ret = gs_app_load_icon (app, plugin->scale, &error); if (!ret) { g_warning ("failed to load %s icon %s: %s", as_icon_kind_to_string (as_icon_get_kind (icon)), as_icon_get_name (icon), error->message); return; } break; case AS_ICON_KIND_CACHED: if (plugin->scale == 2) icon = as_app_get_icon_for_size (item, 128, 128); if (icon == NULL) icon = as_app_get_icon_for_size (item, 64, 64); if (icon == NULL) { g_warning ("failed to find cached icon %s", as_icon_get_name (icon)); return; } if (!as_icon_load (icon, AS_ICON_LOAD_FLAG_SEARCH_SIZE, &error)) { g_warning ("failed to load cached icon %s: %s", as_icon_get_name (icon), error->message); return; } gs_app_set_pixbuf (app, as_icon_get_pixbuf (icon)); break; default: g_warning ("icon kind unknown for %s", as_app_get_id (item)); break; } }
/** * asb_plugin_process_filename: */ static gboolean asb_plugin_process_filename (AsbPlugin *plugin, AsbPackage *pkg, const gchar *filename, GList **apps, const gchar *tmpdir, GError **error) { gboolean ret = TRUE; gchar *error_msg = 0; gchar *filename_tmp; gint rc; guint i; sqlite3 *db = NULL; _cleanup_free_ gchar *basename = NULL; _cleanup_free_ gchar *description = NULL; _cleanup_free_ gchar *language_string = NULL; _cleanup_free_ gchar *name = NULL; _cleanup_free_ gchar *symbol = NULL; _cleanup_object_unref_ AsbApp *app = NULL; _cleanup_object_unref_ AsIcon *icon = NULL; _cleanup_strv_free_ gchar **languages = NULL; /* open IME database */ filename_tmp = g_build_filename (tmpdir, filename, NULL); rc = sqlite3_open (filename_tmp, &db); if (rc) { ret = FALSE; g_set_error (error, ASB_PLUGIN_ERROR, ASB_PLUGIN_ERROR_FAILED, "Can't open database: %s", sqlite3_errmsg (db)); goto out; } /* get name */ rc = sqlite3_exec(db, "SELECT * FROM ime WHERE attr = 'name' LIMIT 1;", asb_plugin_sqlite_callback_cb, &name, &error_msg); if (rc != SQLITE_OK) { ret = FALSE; g_set_error (error, ASB_PLUGIN_ERROR, ASB_PLUGIN_ERROR_FAILED, "Can't get IME name from %s: %s", filename, error_msg); sqlite3_free(error_msg); goto out; } /* get symbol */ rc = sqlite3_exec(db, "SELECT * FROM ime WHERE attr = 'symbol' LIMIT 1;", asb_plugin_sqlite_callback_cb, &symbol, &error_msg); if (rc != SQLITE_OK) { ret = FALSE; g_set_error (error, ASB_PLUGIN_ERROR, ASB_PLUGIN_ERROR_FAILED, "Can't get IME symbol from %s: %s", filename, error_msg); sqlite3_free(error_msg); goto out; } /* get languages */ rc = sqlite3_exec(db, "SELECT * FROM ime WHERE attr = 'languages' LIMIT 1;", asb_plugin_sqlite_callback_cb, &language_string, &error_msg); if (rc != SQLITE_OK) { ret = FALSE; g_set_error (error, ASB_PLUGIN_ERROR, ASB_PLUGIN_ERROR_FAILED, "Can't get IME languages from %s: %s", filename, error_msg); sqlite3_free(error_msg); goto out; } /* get description */ rc = sqlite3_exec(db, "SELECT * FROM ime WHERE attr = 'description' LIMIT 1;", asb_plugin_sqlite_callback_cb, &description, &error_msg); if (rc != SQLITE_OK) { ret = FALSE; g_set_error (error, ASB_PLUGIN_ERROR, ASB_PLUGIN_ERROR_FAILED, "Can't get IME name from %s: %s", filename, error_msg); sqlite3_free(error_msg); goto out; } /* this is _required_ */ if (name == NULL || description == NULL) { ret = FALSE; g_set_error (error, ASB_PLUGIN_ERROR, ASB_PLUGIN_ERROR_FAILED, "No 'name' and 'description' in %s", filename); goto out; } /* create new app */ basename = g_path_get_basename (filename); app = asb_app_new (pkg, basename); as_app_set_id_kind (AS_APP (app), AS_ID_KIND_INPUT_METHOD); as_app_add_category (AS_APP (app), "Addons"); as_app_add_category (AS_APP (app), "InputSources"); as_app_set_name (AS_APP (app), "C", name); as_app_set_comment (AS_APP (app), "C", description); if (symbol != NULL && symbol[0] != '\0') as_app_add_metadata (AS_APP (app), "X-IBus-Symbol", symbol); if (language_string != NULL) { languages = g_strsplit (language_string, ",", -1); for (i = 0; languages[i] != NULL; i++) { if (g_strcmp0 (languages[i], "other") == 0) continue; as_app_add_language (AS_APP (app), 100, languages[i]); } } asb_app_set_requires_appdata (app, TRUE); asb_app_set_hidpi_enabled (app, asb_context_get_flag (plugin->ctx, ASB_CONTEXT_FLAG_HIDPI_ICONS)); /* add icon */ icon = as_icon_new (); as_icon_set_kind (icon, AS_ICON_KIND_STOCK); as_icon_set_name (icon, "system-run-symbolic"); as_app_add_icon (AS_APP (app), icon); asb_plugin_add_app (apps, AS_APP (app)); out: if (db != NULL) sqlite3_close (db); return ret; }
static gboolean gs_plugin_steam_update_store_app (GsPlugin *plugin, AsStore *store, GHashTable *app, GError **error) { const gchar *name; GVariant *tmp; guint32 gameid; gchar *app_id; g_autofree gchar *cache_basename = NULL; g_autofree gchar *cache_fn = NULL; g_autofree gchar *gameid_str = NULL; g_autofree gchar *html = NULL; g_autofree gchar *uri = NULL; g_autoptr(AsApp) item = NULL; /* this is the key */ tmp = g_hash_table_lookup (app, "gameid"); if (tmp == NULL) return TRUE; gameid = g_variant_get_uint32 (tmp); /* valve use the name as the application ID, not the gameid */ tmp = g_hash_table_lookup (app, "name"); if (tmp == NULL) return TRUE; name = g_variant_get_string (tmp, NULL); app_id = g_strdup_printf ("%s.desktop", name); /* already exists */ if (as_store_get_app_by_id (store, app_id) != NULL) { g_debug ("already exists %" G_GUINT32_FORMAT ", skipping", gameid); return TRUE; } /* create application with the gameid as the key */ g_debug ("parsing steam %" G_GUINT32_FORMAT, gameid); item = as_app_new (); as_app_set_kind (item, AS_APP_KIND_DESKTOP); as_app_set_project_license (item, "Steam"); as_app_set_id (item, app_id); as_app_set_name (item, NULL, name); as_app_add_category (item, "Game"); as_app_add_kudo_kind (item, AS_KUDO_KIND_MODERN_TOOLKIT); as_app_set_comment (item, NULL, "Available on Steam"); /* this is for the GNOME Software plugin */ gameid_str = g_strdup_printf ("%" G_GUINT32_FORMAT, gameid); as_app_add_metadata (item, "X-Steam-GameID", gameid_str); as_app_add_metadata (item, "GnomeSoftware::Plugin", "steam"); /* ban certains apps based on the name */ if (g_strstr_len (name, -1, "Dedicated Server") != NULL) as_app_add_veto (item, "Dedicated Server"); /* oslist */ tmp = g_hash_table_lookup (app, "oslist"); if (tmp == NULL) { as_app_add_veto (item, "No operating systems listed"); } else if (g_strstr_len (g_variant_get_string (tmp, NULL), -1, "linux") == NULL) { as_app_add_veto (item, "No Linux support"); } /* url: homepage */ tmp = g_hash_table_lookup (app, "homepage"); if (tmp != NULL) as_app_add_url (item, AS_URL_KIND_HOMEPAGE, g_variant_get_string (tmp, NULL)); /* developer name */ tmp = g_hash_table_lookup (app, "developer"); if (tmp != NULL) as_app_set_developer_name (item, NULL, g_variant_get_string (tmp, NULL)); /* type */ tmp = g_hash_table_lookup (app, "type"); if (tmp != NULL) { const gchar *kind = g_variant_get_string (tmp, NULL); if (g_strcmp0 (kind, "DLC") == 0 || g_strcmp0 (kind, "Config") == 0 || g_strcmp0 (kind, "Tool") == 0) as_app_add_veto (item, "type is %s", kind); } /* don't bother saving apps with failures */ if (as_app_get_vetos(item)->len > 0) return TRUE; /* icons */ tmp = g_hash_table_lookup (app, "clienticns"); if (tmp != NULL) { g_autoptr(GError) error_local = NULL; g_autofree gchar *ic_uri = NULL; ic_uri = g_strdup_printf ("https://steamcdn-a.akamaihd.net/steamcommunity/public/images/apps/%" G_GUINT32_FORMAT "/%s.icns", gameid, g_variant_get_string (tmp, NULL)); if (!gs_plugin_steam_download_icon (plugin, item, ic_uri, &error_local)) { g_warning ("Failed to parse clienticns: %s", error_local->message); } } /* try clienticon */ if (as_app_get_icons(item)->len == 0) { tmp = g_hash_table_lookup (app, "clienticon"); if (tmp != NULL) { g_autoptr(GError) error_local = NULL; g_autofree gchar *ic_uri = NULL; ic_uri = g_strdup_printf ("http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/%" G_GUINT32_FORMAT "/%s.ico", gameid, g_variant_get_string (tmp, NULL)); if (!gs_plugin_steam_download_icon (plugin, item, ic_uri, &error_local)) { g_warning ("Failed to parse clienticon: %s", error_local->message); } } } /* fall back to a resized logo */ if (as_app_get_icons(item)->len == 0) { tmp = g_hash_table_lookup (app, "logo"); if (tmp != NULL) { AsIcon *icon = NULL; g_autofree gchar *ic_uri = NULL; ic_uri = g_strdup_printf ("http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/%" G_GUINT32_FORMAT "/%s.jpg", gameid, g_variant_get_string (tmp, NULL)); icon = as_icon_new (); as_icon_set_kind (icon, AS_ICON_KIND_REMOTE); as_icon_set_url (icon, ic_uri); as_app_add_icon (item, icon); } } /* size */ tmp = g_hash_table_lookup (app, "maxsize"); if (tmp != NULL) { /* string when over 16Gb... :/ */ if (g_strcmp0 (g_variant_get_type_string (tmp), "u") == 0) { g_autofree gchar *val = NULL; val = g_strdup_printf ("%" G_GUINT32_FORMAT, g_variant_get_uint32 (tmp)); as_app_add_metadata (item, "X-Steam-Size", val); } else { as_app_add_metadata (item, "X-Steam-Size", g_variant_get_string (tmp, NULL)); } } /* download page from the store */ cache_basename = g_strdup_printf ("%s.html", gameid_str); cache_fn = gs_utils_get_cache_filename ("steam", cache_basename, GS_UTILS_CACHE_FLAG_WRITEABLE, error); if (cache_fn == NULL) return FALSE; if (!g_file_test (cache_fn, G_FILE_TEST_EXISTS)) { g_autoptr(GsApp) app_dl = gs_app_new (gs_plugin_get_name (plugin)); uri = g_strdup_printf ("http://store.steampowered.com/app/%s/", gameid_str); if (!gs_plugin_download_file (plugin, app_dl, uri, cache_fn, NULL, /* GCancellable */ error)) return FALSE; } /* get screenshots and descriptions */ if (!g_file_get_contents (cache_fn, &html, NULL, error)) { gs_utils_error_convert_gio (error); return FALSE; } if (!gs_plugin_steam_update_screenshots (item, html, error)) return FALSE; if (!gs_plugin_steam_update_description (item, html, error)) return FALSE; /* add */ as_store_add_app (store, item); return TRUE; }
static gboolean as_app_parse_shell_extension_data (AsbPlugin *plugin, AsApp *app, const gchar *data, gsize len, GError **error) { JsonArray *json_array; JsonNode *json_root; JsonObject *json_obj; const gchar *tmp; g_autoptr(JsonParser) json_parser = NULL; /* parse the data */ json_parser = json_parser_new (); if (!json_parser_load_from_data (json_parser, data, (gssize) len, error)) return FALSE; json_root = json_parser_get_root (json_parser); if (json_root == NULL) { g_set_error_literal (error, ASB_PLUGIN_ERROR, ASB_PLUGIN_ERROR_FAILED, "no root"); return FALSE; } json_obj = json_node_get_object (json_root); if (json_obj == NULL) { g_set_error_literal (error, ASB_PLUGIN_ERROR, ASB_PLUGIN_ERROR_FAILED, "no object"); return FALSE; } as_app_set_kind (app, AS_APP_KIND_SHELL_EXTENSION); as_app_set_comment (app, NULL, "GNOME Shell Extension"); if (asb_context_get_flag (plugin->ctx, ASB_CONTEXT_FLAG_ADD_DEFAULT_ICONS)) { as_app_add_category (AS_APP (app), "Addons"); as_app_add_category (AS_APP (app), "ShellExtensions"); } tmp = json_object_get_string_member (json_obj, "uuid"); if (tmp != NULL) { g_autofree gchar *id = NULL; id = as_utils_appstream_id_build (tmp); as_app_set_id (app, id); as_app_add_metadata (AS_APP (app), "shell-extensions::uuid", tmp); } if (json_object_has_member (json_obj, "gettext-domain")) { tmp = json_object_get_string_member (json_obj, "gettext-domain"); if (tmp != NULL) { g_autoptr(AsTranslation) transaction = NULL; transaction = as_translation_new (); as_translation_set_kind (transaction, AS_TRANSLATION_KIND_GETTEXT); as_translation_set_id (transaction, tmp); as_app_add_translation (app, transaction); } } if (json_object_has_member (json_obj, "name")) { tmp = json_object_get_string_member (json_obj, "name"); if (tmp != NULL) as_app_set_name (app, NULL, tmp); } if (json_object_has_member (json_obj, "description")) { tmp = json_object_get_string_member (json_obj, "description"); if (tmp != NULL) { g_autofree gchar *desc = NULL; desc = as_markup_import (tmp, AS_MARKUP_CONVERT_FORMAT_SIMPLE, error); if (desc == NULL) return FALSE; as_app_set_description (app, NULL, desc); } } if (json_object_has_member (json_obj, "url")) { tmp = json_object_get_string_member (json_obj, "url"); if (tmp != NULL) as_app_add_url (app, AS_URL_KIND_HOMEPAGE, tmp); } if (json_object_has_member (json_obj, "original-authors")) { json_array = json_object_get_array_member (json_obj, "original-authors"); if (json_array != NULL) { tmp = json_array_get_string_element (json_array, 0); as_app_set_developer_name (app, NULL, tmp); } } if (as_app_get_release_default (app) == NULL && json_object_has_member (json_obj, "shell-version")) { json_array = json_object_get_array_member (json_obj, "shell-version"); if (json_array != NULL) { g_autoptr(AsRelease) release = NULL; tmp = json_array_get_string_element (json_array, 0); release = as_release_new (); as_release_set_state (release, AS_RELEASE_STATE_INSTALLED); as_release_set_version (release, tmp); as_app_add_release (app, release); } } /* use a stock icon */ if (asb_context_get_flag (plugin->ctx, ASB_CONTEXT_FLAG_ADD_DEFAULT_ICONS)) { g_autoptr(AsIcon) ic = as_icon_new (); as_icon_set_kind (ic, AS_ICON_KIND_STOCK); as_icon_set_name (ic, "application-x-addon-symbolic"); as_app_add_icon (app, ic); } return TRUE; }
static gboolean asb_plugin_desktop_add_icons (AsbPlugin *plugin, AsbApp *app, const gchar *tmpdir, const gchar *key, GError **error) { guint min_icon_size; g_autofree gchar *fn_hidpi = NULL; g_autofree gchar *fn = NULL; g_autofree gchar *name_hidpi = NULL; g_autofree gchar *name = NULL; g_autoptr(AsIcon) icon_hidpi = NULL; g_autoptr(AsIcon) icon = NULL; g_autoptr(GdkPixbuf) pixbuf_hidpi = NULL; g_autoptr(GdkPixbuf) pixbuf = NULL; /* find 64x64 icon */ fn = as_utils_find_icon_filename_full (tmpdir, key, AS_UTILS_FIND_ICON_NONE, error); if (fn == NULL) { g_prefix_error (error, "Failed to find icon: "); return FALSE; } /* load the icon */ min_icon_size = asb_context_get_min_icon_size (plugin->ctx); pixbuf = asb_app_load_icon (plugin, fn, fn + strlen (tmpdir), 64, min_icon_size, error); if (pixbuf == NULL) { g_prefix_error (error, "Failed to load icon: "); return FALSE; } /* save in target directory */ if (asb_context_get_flag (plugin->ctx, ASB_CONTEXT_FLAG_HIDPI_ICONS)) { name = g_strdup_printf ("%ix%i/%s.png", 64, 64, as_app_get_id_filename (AS_APP (app))); } else { name = g_strdup_printf ("%s.png", as_app_get_id_filename (AS_APP (app))); } icon = as_icon_new (); as_icon_set_pixbuf (icon, pixbuf); as_icon_set_name (icon, name); as_icon_set_kind (icon, AS_ICON_KIND_CACHED); as_icon_set_prefix (icon, as_app_get_icon_path (AS_APP (app))); as_app_add_icon (AS_APP (app), icon); /* is HiDPI disabled */ if (!asb_context_get_flag (plugin->ctx, ASB_CONTEXT_FLAG_HIDPI_ICONS)) return TRUE; /* try to get a HiDPI icon */ fn_hidpi = as_utils_find_icon_filename_full (tmpdir, key, AS_UTILS_FIND_ICON_HI_DPI, NULL); if (fn_hidpi == NULL) return TRUE; /* load the HiDPI icon */ pixbuf_hidpi = asb_app_load_icon (plugin, fn_hidpi, fn_hidpi + strlen (tmpdir), 128, 128, NULL); if (pixbuf_hidpi == NULL) return TRUE; if (gdk_pixbuf_get_width (pixbuf_hidpi) <= gdk_pixbuf_get_width (pixbuf) || gdk_pixbuf_get_height (pixbuf_hidpi) <= gdk_pixbuf_get_height (pixbuf)) return TRUE; as_app_add_kudo_kind (AS_APP (app), AS_KUDO_KIND_HI_DPI_ICON); /* save icon */ name_hidpi = g_strdup_printf ("%ix%i/%s.png", 128, 128, as_app_get_id_filename (AS_APP (app))); icon_hidpi = as_icon_new (); as_icon_set_pixbuf (icon_hidpi, pixbuf_hidpi); as_icon_set_name (icon_hidpi, name_hidpi); as_icon_set_kind (icon_hidpi, AS_ICON_KIND_CACHED); as_icon_set_prefix (icon_hidpi, as_app_get_icon_path (AS_APP (app))); as_app_add_icon (AS_APP (app), icon_hidpi); return TRUE; }
static gboolean add_icons (AsApp *app, const gchar *icons_dir, guint min_icon_size, const gchar *prefix, const gchar *key, GError **error) { g_autofree gchar *fn_hidpi = NULL; g_autofree gchar *fn = NULL; g_autofree gchar *name_hidpi = NULL; g_autofree gchar *name = NULL; g_autofree gchar *icon_path = NULL; g_autofree gchar *icon_subdir = NULL; g_autofree gchar *icon_path_hidpi = NULL; g_autofree gchar *icon_subdir_hidpi = NULL; g_autoptr(AsIcon) icon_hidpi = NULL; g_autoptr(AsIcon) icon = NULL; g_autoptr(AsImage) im = NULL; g_autoptr(GdkPixbuf) pixbuf_hidpi = NULL; g_autoptr(GdkPixbuf) pixbuf = NULL; g_autoptr(GError) error_local = NULL; /* find 64x64 icon */ fn = as_utils_find_icon_filename_full (prefix, key, AS_UTILS_FIND_ICON_NONE, error); if (fn == NULL) { g_prefix_error (error, "Failed to find icon: "); return FALSE; } /* load the icon */ im = as_image_new (); if (!as_image_load_filename_full (im, fn, 64, min_icon_size, AS_IMAGE_LOAD_FLAG_ONLY_SUPPORTED | AS_IMAGE_LOAD_FLAG_SHARPEN, error)) { g_prefix_error (error, "Failed to load icon: "); return FALSE; } pixbuf = g_object_ref (as_image_get_pixbuf (im)); /* save in target directory */ name = g_strdup_printf ("%ix%i/%s.png", 64, 64, as_app_get_id_filename (AS_APP (app))); icon = as_icon_new (); as_icon_set_pixbuf (icon, pixbuf); as_icon_set_name (icon, name); as_icon_set_kind (icon, AS_ICON_KIND_CACHED); as_icon_set_prefix (icon, as_app_get_icon_path (AS_APP (app))); as_app_add_icon (AS_APP (app), icon); icon_path = g_build_filename (icons_dir, name, NULL); icon_subdir = g_path_get_dirname (icon_path); if (g_mkdir_with_parents (icon_subdir, 0755)) { int errsv = errno; g_set_error (error, AS_APP_ERROR, AS_APP_ERROR_FAILED, "failed to create %s: %s", icon_subdir, strerror (errsv)); return FALSE; } /* TRANSLATORS: we've saving the icon file to disk */ g_print ("%s %s\n", _("Saving icon"), icon_path); if (!gdk_pixbuf_save (pixbuf, icon_path, "png", error, NULL)) return FALSE; /* try to get a HiDPI icon */ fn_hidpi = as_utils_find_icon_filename_full (prefix, key, AS_UTILS_FIND_ICON_HI_DPI, NULL); if (fn_hidpi == NULL) { g_debug ("no HiDPI icon found with key %s in %s", key, prefix); return TRUE; } /* load the HiDPI icon */ g_debug ("trying to load %s", fn_hidpi); if (!as_image_load_filename_full (im, fn_hidpi, 128, 128, AS_IMAGE_LOAD_FLAG_SHARPEN, &error_local)) { g_debug ("failed to load HiDPI icon: %s", error_local->message); return TRUE; } pixbuf_hidpi = g_object_ref (as_image_get_pixbuf (im)); if (gdk_pixbuf_get_width (pixbuf_hidpi) <= gdk_pixbuf_get_width (pixbuf) || gdk_pixbuf_get_height (pixbuf_hidpi) <= gdk_pixbuf_get_height (pixbuf)) { g_debug ("HiDPI icon no larger than normal icon"); return TRUE; } as_app_add_kudo_kind (AS_APP (app), AS_KUDO_KIND_HI_DPI_ICON); /* save icon */ name_hidpi = g_strdup_printf ("%ix%i/%s.png", 128, 128, as_app_get_id_filename (AS_APP (app))); icon_hidpi = as_icon_new (); as_icon_set_pixbuf (icon_hidpi, pixbuf_hidpi); as_icon_set_name (icon_hidpi, name_hidpi); as_icon_set_kind (icon_hidpi, AS_ICON_KIND_CACHED); as_icon_set_prefix (icon_hidpi, as_app_get_icon_path (AS_APP (app))); as_app_add_icon (AS_APP (app), icon_hidpi); icon_path_hidpi = g_build_filename (icons_dir, name_hidpi, NULL); icon_subdir_hidpi = g_path_get_dirname (icon_path_hidpi); if (g_mkdir_with_parents (icon_subdir_hidpi, 0755)) { int errsv = errno; g_set_error (error, AS_APP_ERROR, AS_APP_ERROR_FAILED, "failed to create %s: %s", icon_subdir_hidpi, strerror (errsv)); return FALSE; } /* TRANSLATORS: we've saving the icon file to disk */ g_print ("%s %s\n", _("Saving icon"), icon_path_hidpi); if (!gdk_pixbuf_save (pixbuf_hidpi, icon_path_hidpi, "png", error, NULL)) return FALSE; return TRUE; }
/** * asb_plugin_desktop_add_icons: */ static gboolean asb_plugin_desktop_add_icons (AsbPlugin *plugin, AsbApp *app, const gchar *tmpdir, const gchar *key, GError **error) { guint min_icon_size; _cleanup_free_ gchar *fn_hidpi = NULL; _cleanup_free_ gchar *fn = NULL; _cleanup_free_ gchar *name_hidpi = NULL; _cleanup_free_ gchar *name = NULL; _cleanup_object_unref_ AsIcon *icon_hidpi = NULL; _cleanup_object_unref_ AsIcon *icon = NULL; _cleanup_object_unref_ GdkPixbuf *pixbuf_hidpi = NULL; _cleanup_object_unref_ GdkPixbuf *pixbuf = NULL; /* find 64x64 icon */ fn = as_utils_find_icon_filename_full (tmpdir, key, AS_UTILS_FIND_ICON_NONE, error); if (fn == NULL) { g_prefix_error (error, "Failed to find icon: "); return FALSE; } /* is icon in a unsupported format */ if (!asb_context_get_flag (plugin->ctx, ASB_CONTEXT_FLAG_IGNORE_LEGACY_ICONS)) { if (g_str_has_suffix (fn, ".xpm")) { g_set_error (error, ASB_PLUGIN_ERROR, ASB_PLUGIN_ERROR_NOT_SUPPORTED, "Uses XPM icon: %s", key); return FALSE; } if (g_str_has_suffix (fn, ".gif")) { g_set_error (error, ASB_PLUGIN_ERROR, ASB_PLUGIN_ERROR_NOT_SUPPORTED, "Uses GIF icon: %s", key); return FALSE; } if (g_str_has_suffix (fn, ".ico")) { g_set_error (error, ASB_PLUGIN_ERROR, ASB_PLUGIN_ERROR_NOT_SUPPORTED, "Uses ICO icon: %s", key); return FALSE; } } /* load the icon */ min_icon_size = asb_context_get_min_icon_size (plugin->ctx); pixbuf = asb_app_load_icon (app, fn, fn + strlen (tmpdir), 64, min_icon_size, error); if (pixbuf == NULL) { g_prefix_error (error, "Failed to load icon: "); return FALSE; } /* save in target directory */ if (asb_context_get_flag (plugin->ctx, ASB_CONTEXT_FLAG_HIDPI_ICONS)) { name = g_strdup_printf ("%ix%i/%s.png", 64, 64, as_app_get_id_filename (AS_APP (app))); } else { name = g_strdup_printf ("%s.png", as_app_get_id_filename (AS_APP (app))); } icon = as_icon_new (); as_icon_set_pixbuf (icon, pixbuf); as_icon_set_name (icon, name); as_icon_set_kind (icon, AS_ICON_KIND_CACHED); as_icon_set_prefix (icon, as_app_get_icon_path (AS_APP (app))); as_app_add_icon (AS_APP (app), icon); /* is HiDPI disabled */ if (!asb_context_get_flag (plugin->ctx, ASB_CONTEXT_FLAG_HIDPI_ICONS)) return TRUE; /* try to get a HiDPI icon */ fn_hidpi = as_utils_find_icon_filename_full (tmpdir, key, AS_UTILS_FIND_ICON_HI_DPI, NULL); if (fn_hidpi == NULL) return TRUE; /* load the HiDPI icon */ pixbuf_hidpi = asb_app_load_icon (app, fn_hidpi, fn_hidpi + strlen (tmpdir), 128, 128, NULL); if (pixbuf_hidpi == NULL) return TRUE; if (gdk_pixbuf_get_width (pixbuf_hidpi) <= gdk_pixbuf_get_width (pixbuf) || gdk_pixbuf_get_height (pixbuf_hidpi) <= gdk_pixbuf_get_height (pixbuf)) return TRUE; as_app_add_kudo_kind (AS_APP (app), AS_KUDO_KIND_HI_DPI_ICON); /* save icon */ name_hidpi = g_strdup_printf ("%ix%i/%s.png", 128, 128, as_app_get_id_filename (AS_APP (app))); icon_hidpi = as_icon_new (); as_icon_set_pixbuf (icon_hidpi, pixbuf_hidpi); as_icon_set_name (icon_hidpi, name_hidpi); as_icon_set_kind (icon_hidpi, AS_ICON_KIND_CACHED); as_icon_set_prefix (icon_hidpi, as_app_get_icon_path (AS_APP (app))); as_app_add_icon (AS_APP (app), icon_hidpi); return TRUE; }
static gboolean asb_plugin_process_filename (AsbPlugin *plugin, AsbPackage *pkg, const gchar *filename, GList **apps, GError **error) { AsProblemKind problem_kind; AsProblem *problem; GPtrArray *icons; const gchar *tmp; guint i; g_autoptr(AsbApp) app = NULL; g_autoptr(GPtrArray) problems = NULL; app = asb_app_new (NULL, NULL); if (!as_app_parse_file (AS_APP (app), filename, AS_APP_PARSE_FLAG_USE_HEURISTICS, error)) return FALSE; if (as_app_get_kind (AS_APP (app)) == AS_APP_KIND_UNKNOWN) { g_set_error (error, ASB_PLUGIN_ERROR, ASB_PLUGIN_ERROR_FAILED, "%s has no recognised type", as_app_get_id (AS_APP (app))); return FALSE; } /* validate */ problems = as_app_validate (AS_APP (app), AS_APP_VALIDATE_FLAG_NO_NETWORK | AS_APP_VALIDATE_FLAG_RELAX, error); if (problems == NULL) return FALSE; asb_app_set_package (app, pkg); for (i = 0; i < problems->len; i++) { problem = g_ptr_array_index (problems, i); problem_kind = as_problem_get_kind (problem); asb_package_log (asb_app_get_package (app), ASB_PACKAGE_LOG_LEVEL_WARNING, "AppData problem: %s : %s", as_problem_kind_to_string (problem_kind), as_problem_get_message (problem)); } /* nuke things that do not belong */ icons = as_app_get_icons (AS_APP (app)); if (icons->len > 0) g_ptr_array_set_size (icons, 0); /* fix up the project license */ tmp = as_app_get_project_license (AS_APP (app)); if (tmp != NULL && !as_utils_is_spdx_license (tmp)) { g_autofree gchar *license_spdx = NULL; license_spdx = as_utils_license_to_spdx (tmp); if (as_utils_is_spdx_license (license_spdx)) { asb_package_log (asb_app_get_package (app), ASB_PACKAGE_LOG_LEVEL_WARNING, "project license fixup: %s -> %s", tmp, license_spdx); as_app_set_project_license (AS_APP (app), license_spdx); } else { asb_package_log (asb_app_get_package (app), ASB_PACKAGE_LOG_LEVEL_WARNING, "project license is invalid: %s", tmp); as_app_set_project_license (AS_APP (app), NULL); } } /* check license */ tmp = as_app_get_metadata_license (AS_APP (app)); if (tmp == NULL) { g_set_error (error, ASB_PLUGIN_ERROR, ASB_PLUGIN_ERROR_FAILED, "AppData %s has no licence", filename); return FALSE; } if (!as_utils_is_spdx_license (tmp)) { g_set_error (error, ASB_PLUGIN_ERROR, ASB_PLUGIN_ERROR_FAILED, "AppData %s license '%s' invalid", filename, tmp); return FALSE; } /* log updateinfo */ tmp = as_app_get_update_contact (AS_APP (app)); if (tmp != NULL) { asb_package_log (asb_app_get_package (app), ASB_PACKAGE_LOG_LEVEL_INFO, "Upstream contact <%s>", tmp); } /* add icon for firmware */ if (as_app_get_kind (AS_APP (app)) == AS_APP_KIND_FIRMWARE) { 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"); as_app_add_icon (AS_APP (app), icon); } /* fix up input methods */ if (as_app_get_kind (AS_APP (app)) == AS_APP_KIND_INPUT_METHOD) { g_autoptr(AsIcon) icon = NULL; icon = as_icon_new (); as_icon_set_kind (icon, AS_ICON_KIND_STOCK); as_icon_set_name (icon, "system-run-symbolic"); as_app_add_icon (AS_APP (app), icon); as_app_add_category (AS_APP (app), "Addons"); as_app_add_category (AS_APP (app), "InputSources"); } /* fix up codecs */ if (as_app_get_kind (AS_APP (app)) == AS_APP_KIND_CODEC) { 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"); as_app_add_icon (AS_APP (app), icon); as_app_add_category (AS_APP (app), "Addons"); as_app_add_category (AS_APP (app), "Codecs"); } /* success */ asb_app_set_hidpi_enabled (app, asb_context_get_flag (plugin->ctx, ASB_CONTEXT_FLAG_HIDPI_ICONS)); asb_plugin_add_app (apps, AS_APP (app)); return TRUE; }
/** * as_icon_convert_to_kind: * @icon: a #AsIcon instance. * @kind: a %AsIconKind, e.g. #AS_ICON_KIND_EMBEDDED * @error: A #GError or %NULL. * * Converts the icon from one kind to another. * * Returns: %TRUE for success * * Since: 0.3.1 **/ gboolean as_icon_convert_to_kind (AsIcon *icon, AsIconKind kind, GError **error) { AsIconPrivate *priv = GET_PRIVATE (icon); /* these can't be converted */ if (priv->kind == AS_ICON_KIND_STOCK || priv->kind == AS_ICON_KIND_REMOTE) return TRUE; /* no change */ if (priv->kind == kind) return TRUE; /* cached -> embedded */ if (priv->kind == AS_ICON_KIND_CACHED && kind == AS_ICON_KIND_EMBEDDED) { gsize data_size; g_autoptr(GBytes) tmp = NULL; g_autofree gchar *data = NULL; /* load the pixbuf and save it to a PNG buffer */ if (priv->pixbuf == NULL) { if (!as_icon_load (icon, AS_ICON_LOAD_FLAG_SEARCH_SIZE, error)) return FALSE; } if (!gdk_pixbuf_save_to_buffer (priv->pixbuf, &data, &data_size, "png", error, NULL)) return FALSE; /* set the PNG buffer to a blob of data */ tmp = g_bytes_new (data, data_size); as_icon_set_data (icon, tmp); as_icon_set_kind (icon, kind); return TRUE; } /* cached -> embedded */ if (priv->kind == AS_ICON_KIND_EMBEDDED && kind == AS_ICON_KIND_CACHED) { g_autofree gchar *size_str = NULL; g_autofree gchar *path = NULL; g_autofree gchar *fn = NULL; /* ensure the parent path exists */ size_str = g_strdup_printf ("%ux%u", priv->width, priv->height); path = g_build_filename (priv->prefix, size_str, NULL); if (g_mkdir_with_parents (path, 0700) != 0) { g_set_error (error, AS_ICON_ERROR, AS_ICON_ERROR_FAILED, "Failed to create: %s", path); return FALSE; } /* save the pixbuf */ fn = g_build_filename (path, priv->name, NULL); if (!gdk_pixbuf_save (priv->pixbuf, fn, "png", error, NULL)) return FALSE; as_icon_set_kind (icon, kind); return TRUE; } /* not supported */ g_set_error (error, AS_ICON_ERROR, AS_ICON_ERROR_FAILED, "converting %s to %s is not supported", as_icon_kind_to_string (priv->kind), as_icon_kind_to_string (kind)); return FALSE; }
/** * as_icon_node_parse: * @icon: a #AsIcon instance. * @node: a #GNode. * @ctx: a #AsNodeContext. * @error: A #GError or %NULL. * * Populates the object from a DOM node. * * Returns: %TRUE for success * * Since: 0.3.1 **/ gboolean as_icon_node_parse (AsIcon *icon, GNode *node, AsNodeContext *ctx, GError **error) { AsIconPrivate *priv = GET_PRIVATE (icon); const gchar *tmp; guint size; gboolean prepend_size = TRUE; tmp = as_node_get_attribute (node, "type"); as_icon_set_kind (icon, as_icon_kind_from_string (tmp)); switch (priv->kind) { case AS_ICON_KIND_EMBEDDED: if (!as_icon_node_parse_embedded (icon, node, error)) return FALSE; break; default: /* preserve the URL for remote icons */ tmp = as_node_get_data (node); if (tmp == NULL) { g_set_error (error, AS_ICON_ERROR, AS_ICON_ERROR_FAILED, "no data for icon of type %s", as_icon_kind_to_string (priv->kind)); return FALSE; } if (priv->kind == AS_ICON_KIND_REMOTE) as_icon_set_url (icon, tmp); else if (priv->kind == AS_ICON_KIND_LOCAL) as_icon_set_filename (icon, tmp); /* store the name without any prefix */ if (g_strstr_len (tmp, -1, "/") == NULL) { as_icon_set_name (icon, tmp); } else { g_autofree gchar *basename = NULL; basename = g_path_get_basename (tmp); as_icon_set_name (icon, basename); } /* width is optional, assume 64px if missing */ size = as_node_get_attribute_as_uint (node, "width"); if (size == G_MAXUINT) { size = 64; prepend_size = FALSE; } priv->width = size; /* height is optional, assume 64px if missing */ size = as_node_get_attribute_as_uint (node, "height"); if (size == G_MAXUINT) { size = 64; prepend_size = FALSE; } priv->height = size; /* only use the size if the metadata has width and height */ if (prepend_size) { g_free (priv->prefix_private); priv->prefix_private = g_strdup_printf ("%s/%ux%u", priv->prefix, priv->width, priv->height); } break; } return TRUE; }
static void refine_app (GsPlugin *plugin, GsApp *app, JsonObject *package, gboolean from_search, GCancellable *cancellable) { g_autofree gchar *macaroon = NULL; g_auto(GStrv) discharges = NULL; const gchar *status, *icon_url, *launch_name = NULL; g_autoptr(GdkPixbuf) icon_pixbuf = NULL; gint64 size = -1; get_macaroon (plugin, &macaroon, &discharges); status = json_object_get_string_member (package, "status"); if (g_strcmp0 (status, "installed") == 0 || g_strcmp0 (status, "active") == 0) { const gchar *update_available; update_available = json_object_has_member (package, "update_available") ? json_object_get_string_member (package, "update_available") : NULL; if (update_available) gs_app_set_state (app, AS_APP_STATE_UPDATABLE); else { if (gs_app_get_state (app) == AS_APP_STATE_AVAILABLE) gs_app_set_state (app, AS_APP_STATE_UNKNOWN); gs_app_set_state (app, AS_APP_STATE_INSTALLED); } } else if (g_strcmp0 (status, "not installed") == 0 || g_strcmp0 (status, "available") == 0) { gs_app_set_state (app, AS_APP_STATE_AVAILABLE); } gs_app_set_name (app, GS_APP_QUALITY_HIGHEST, json_object_get_string_member (package, "summary")); gs_app_set_summary (app, GS_APP_QUALITY_HIGHEST, json_object_get_string_member (package, "summary")); gs_app_set_description (app, GS_APP_QUALITY_HIGHEST, json_object_get_string_member (package, "description")); gs_app_set_version (app, json_object_get_string_member (package, "version")); if (json_object_has_member (package, "installed-size")) { size = json_object_get_int_member (package, "installed-size"); if (size > 0) gs_app_set_size_installed (app, (guint64) size); } if (json_object_has_member (package, "download-size")) { size = json_object_get_int_member (package, "download-size"); if (size > 0) gs_app_set_size_download (app, (guint64) size); } gs_app_add_quirk (app, AS_APP_QUIRK_PROVENANCE); icon_url = json_object_get_string_member (package, "icon"); if (g_str_has_prefix (icon_url, "/")) { g_autofree gchar *icon_data = NULL; gsize icon_data_length; g_autoptr(GError) error = NULL; icon_data = gs_snapd_get_resource (macaroon, discharges, icon_url, &icon_data_length, cancellable, &error); if (icon_data != NULL) { g_autoptr(GdkPixbufLoader) loader = NULL; loader = gdk_pixbuf_loader_new (); gdk_pixbuf_loader_write (loader, (guchar *) icon_data, icon_data_length, NULL); gdk_pixbuf_loader_close (loader, NULL); icon_pixbuf = g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader)); } else g_printerr ("Failed to get icon: %s\n", error->message); } else { g_autoptr(SoupMessage) message = NULL; g_autoptr(GdkPixbufLoader) loader = NULL; message = soup_message_new (SOUP_METHOD_GET, icon_url); if (message != NULL) { soup_session_send_message (gs_plugin_get_soup_session (plugin), message); loader = gdk_pixbuf_loader_new (); gdk_pixbuf_loader_write (loader, (guint8 *) message->response_body->data, (gsize) message->response_body->length, NULL); gdk_pixbuf_loader_close (loader, NULL); icon_pixbuf = g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader)); } } if (icon_pixbuf) { gs_app_set_pixbuf (app, icon_pixbuf); } else { g_autoptr(AsIcon) icon = as_icon_new (); as_icon_set_kind (icon, AS_ICON_KIND_STOCK); as_icon_set_name (icon, "package-x-generic"); gs_app_add_icon (app, icon); } if (json_object_has_member (package, "screenshots") && gs_app_get_screenshots (app)->len <= 0) { JsonArray *screenshots; guint i; screenshots = json_object_get_array_member (package, "screenshots"); for (i = 0; i < json_array_get_length (screenshots); i++) { JsonObject *screenshot = json_array_get_object_element (screenshots, i); g_autoptr(AsScreenshot) ss = NULL; g_autoptr(AsImage) image = NULL; ss = as_screenshot_new (); as_screenshot_set_kind (ss, AS_SCREENSHOT_KIND_NORMAL); image = as_image_new (); as_image_set_url (image, json_object_get_string_member (screenshot, "url")); as_image_set_kind (image, AS_IMAGE_KIND_SOURCE); as_screenshot_add_image (ss, image); gs_app_add_screenshot (app, ss); } } if (!from_search) { JsonArray *apps; apps = json_object_get_array_member (package, "apps"); if (apps && json_array_get_length (apps) > 0) launch_name = json_object_get_string_member (json_array_get_object_element (apps, 0), "name"); if (launch_name) gs_app_set_metadata (app, "snap::launch-name", launch_name); else gs_app_add_quirk (app, AS_APP_QUIRK_NOT_LAUNCHABLE); } }
static gboolean gs_plugin_steam_download_icon (GsPlugin *plugin, AsApp *app, const gchar *uri, GError **error) { gsize data_len; g_autofree gchar *cache_basename = NULL; g_autofree gchar *cache_fn = NULL; g_autofree gchar *cache_png = NULL; g_autofree gchar *data = NULL; g_autoptr(AsIcon) icon = NULL; g_autoptr(GdkPixbuf) pb = NULL; /* download icons from the cdn */ cache_basename = g_path_get_basename (uri); cache_fn = gs_utils_get_cache_filename ("steam", cache_basename, GS_UTILS_CACHE_FLAG_NONE, error); if (cache_fn == NULL) return FALSE; if (g_file_test (cache_fn, G_FILE_TEST_EXISTS)) { if (!g_file_get_contents (cache_fn, &data, &data_len, error)) { gs_utils_error_convert_gio (error); return FALSE; } } else { if (!gs_mkdir_parent (cache_fn, error)) return FALSE; if (!gs_plugin_download_file (plugin, NULL, /* GsApp */ uri, cache_fn, NULL, /* GCancellable */ error)) return FALSE; } /* load the icon as large as possible */ pb = gdk_pixbuf_new_from_file (cache_fn, error); if (pb == NULL) { gs_utils_error_convert_gdk_pixbuf (error); return FALSE; } /* too small? */ if (gdk_pixbuf_get_width (pb) < 48 || gdk_pixbuf_get_height (pb) < 48) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_INVALID_FORMAT, "icon is too small %ix%i", gdk_pixbuf_get_width (pb), gdk_pixbuf_get_height (pb)); return FALSE; } /* save to cache */ memcpy (cache_basename + 40, ".png\0", 5); cache_png = gs_utils_get_cache_filename ("steam", cache_basename, GS_UTILS_CACHE_FLAG_WRITEABLE, error); if (cache_png == NULL) return FALSE; if (!gdk_pixbuf_save (pb, cache_png, "png", error, NULL)) { gs_utils_error_convert_gdk_pixbuf (error); return FALSE; } /* add an icon */ icon = as_icon_new (); as_icon_set_kind (icon, AS_ICON_KIND_LOCAL); as_icon_set_filename (icon, cache_png); as_app_add_icon (app, icon); return TRUE; }
static GsApp * gs_editor_convert_app (GsEditor *self, AsApp *item) { AsApp *item_global; AsAppState item_state; GsApp *app; const gchar *keys[] = { "GnomeSoftware::AppTile-css", "GnomeSoftware::FeatureTile-css", "GnomeSoftware::UpgradeBanner-css", NULL }; /* copy name, summary and description */ app = gs_app_new (as_app_get_id (item)); item_global = as_store_get_app_by_id (self->store_global, as_app_get_id (item)); if (item_global == NULL) { const gchar *tmp; g_autoptr(AsIcon) ic = NULL; g_debug ("no app found for %s, using fallback", as_app_get_id (item)); /* copy from AsApp, falling back to something sane */ tmp = as_app_get_name (item, NULL); if (tmp == NULL) tmp = "Application"; gs_app_set_name (app, GS_APP_QUALITY_NORMAL, tmp); tmp = as_app_get_comment (item, NULL); if (tmp == NULL) tmp = "Description"; gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, tmp); tmp = as_app_get_description (item, NULL); if (tmp == NULL) tmp = "A multiline description"; gs_app_set_description (app, GS_APP_QUALITY_NORMAL, tmp); ic = as_icon_new (); as_icon_set_kind (ic, AS_ICON_KIND_STOCK); as_icon_set_name (ic, "application-x-executable"); gs_app_add_icon (app, ic); item_state = as_app_get_state (item); } else { GPtrArray *icons; g_debug ("found global app for %s", as_app_get_id (item)); gs_app_set_name (app, GS_APP_QUALITY_NORMAL, as_app_get_name (item_global, NULL)); gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, as_app_get_comment (item_global, NULL)); gs_app_set_description (app, GS_APP_QUALITY_NORMAL, as_app_get_description (item_global, NULL)); icons = as_app_get_icons (item_global); for (guint i = 0; i < icons->len; i++) { AsIcon *icon = g_ptr_array_index (icons, i); gs_app_add_icon (app, icon); } item_state = as_app_get_state (item_global); } /* copy state */ if (item_state == AS_APP_STATE_UNKNOWN) item_state = AS_APP_STATE_AVAILABLE; gs_app_set_state (app, item_state); /* copy version */ gs_app_set_version (app, "3.28"); /* load pixbuf */ gs_editor_refine_app_pixbuf (app); /* copy metadata */ for (guint i = 0; keys[i] != NULL; i++) { g_autoptr(GError) error = NULL; const gchar *markup = as_app_get_metadata_item (item, keys[i]); if (markup != NULL) { g_autofree gchar *css_new = NULL; css_new = gs_editor_css_download_resources (self, markup, &error); if (css_new == NULL) { g_warning ("%s", error->message); gs_app_set_metadata (app, keys[i], markup); } else { gs_app_set_metadata (app, keys[i], css_new); } } else { gs_app_set_metadata (app, keys[i], NULL); } } return app; }
/** * 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; }
static gboolean asb_plugin_desktop_refine (AsbPlugin *plugin, AsbPackage *pkg, const gchar *filename, AsbApp *app, const gchar *tmpdir, GError **error) { AsIcon *icon; AsAppParseFlags parse_flags = AS_APP_PARSE_FLAG_USE_HEURISTICS | AS_APP_PARSE_FLAG_ALLOW_VETO; GPtrArray *icons; gboolean ret; guint i; g_autoptr(AsApp) desktop_app = NULL; g_autoptr(GdkPixbuf) pixbuf = NULL; /* use GenericName fallback */ if (asb_context_get_flag (plugin->ctx, ASB_CONTEXT_FLAG_USE_FALLBACKS)) parse_flags |= AS_APP_PARSE_FLAG_USE_FALLBACKS; /* create app */ desktop_app = as_app_new (); if (!as_app_parse_file (desktop_app, filename, parse_flags, error)) return FALSE; /* convert any UNKNOWN icons to CACHED */ icons = as_app_get_icons (AS_APP (desktop_app)); for (i = 0; i < icons->len; i++) { icon = g_ptr_array_index (icons, i); if (as_icon_get_kind (icon) == AS_ICON_KIND_UNKNOWN) as_icon_set_kind (icon, AS_ICON_KIND_CACHED); } /* copy all metadata */ as_app_subsume_full (AS_APP (app), desktop_app, AS_APP_SUBSUME_FLAG_NO_OVERWRITE | AS_APP_SUBSUME_FLAG_MERGE); /* is the icon a stock-icon-name? */ icon = as_app_get_icon_default (AS_APP (app)); if (icon != NULL) { if (as_icon_get_kind (icon) == AS_ICON_KIND_STOCK) { asb_package_log (pkg, ASB_PACKAGE_LOG_LEVEL_DEBUG, "using stock icon %s", as_icon_get_name (icon)); } else { g_autofree gchar *key = NULL; g_autoptr(GError) error_local = NULL; switch (as_icon_get_kind (icon)) { case AS_ICON_KIND_LOCAL: key = g_strdup (as_icon_get_filename (icon)); break; default: key = g_strdup (as_icon_get_name (icon)); break; } g_ptr_array_set_size (as_app_get_icons (AS_APP (app)), 0); ret = asb_plugin_desktop_add_icons (plugin, app, tmpdir, key, &error_local); if (!ret) { as_app_add_veto (AS_APP (app), "%s", error_local->message); } } } return TRUE; }
/** * as_app_parse_file_key: **/ static gboolean as_app_parse_file_key (AsApp *app, GKeyFile *kf, const gchar *key, AsAppParseFlags flags, GError **error) { gchar *dot = NULL; guint i; guint j; g_autofree gchar *locale = NULL; g_autofree gchar *tmp = NULL; g_auto(GStrv) list = NULL; /* NoDisplay */ if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY) == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (tmp != NULL && strcasecmp (tmp, "True") == 0) as_app_add_veto (app, "NoDisplay=true"); /* Type */ } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_TYPE) == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (g_strcmp0 (tmp, G_KEY_FILE_DESKTOP_TYPE_APPLICATION) != 0) { g_set_error_literal (error, AS_APP_ERROR, AS_APP_ERROR_INVALID_TYPE, "not an application"); return FALSE; } /* Icon */ } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_ICON) == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (tmp != NULL && tmp[0] != '\0') { g_autoptr(AsIcon) icon = NULL; icon = as_icon_new (); as_icon_set_name (icon, tmp); dot = g_strstr_len (tmp, -1, "."); if (dot != NULL) *dot = '\0'; if (as_utils_is_stock_icon_name (tmp)) { as_icon_set_name (icon, tmp); as_icon_set_kind (icon, AS_ICON_KIND_STOCK); } else if ((flags & AS_APP_PARSE_FLAG_USE_FALLBACKS) > 0 && _as_utils_is_stock_icon_name_fallback (tmp)) { as_icon_set_name (icon, tmp); as_icon_set_kind (icon, AS_ICON_KIND_STOCK); } else { as_icon_set_kind (icon, AS_ICON_KIND_LOCAL); } as_app_add_icon (app, icon); } /* Categories */ } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_CATEGORIES) == 0) { list = g_key_file_get_string_list (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL, NULL); for (i = 0; list[i] != NULL; i++) { /* not a standard category */ if (g_str_has_prefix (list[i], "X-")) continue; /* check the category is valid */ if (!as_utils_is_category_id (list[i])) continue; /* ignore some useless keys */ if (g_strcmp0 (list[i], "GTK") == 0) continue; if (g_strcmp0 (list[i], "Qt") == 0) continue; if (g_strcmp0 (list[i], "KDE") == 0) continue; if (g_strcmp0 (list[i], "GNOME") == 0) continue; as_app_add_category (app, list[i]); } } else if (g_strcmp0 (key, "Keywords") == 0) { list = g_key_file_get_string_list (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL, NULL); for (i = 0; list[i] != NULL; i++) { g_auto(GStrv) kw_split = NULL; kw_split = g_strsplit (list[i], ",", -1); for (j = 0; kw_split[j] != NULL; j++) { if (kw_split[j][0] == '\0') continue; as_app_add_keyword (app, "C", kw_split[j]); } } } else if (g_str_has_prefix (key, "Keywords")) { locale = as_app_desktop_key_get_locale (key); list = g_key_file_get_locale_string_list (kf, G_KEY_FILE_DESKTOP_GROUP, key, locale, NULL, NULL); for (i = 0; list[i] != NULL; i++) { g_auto(GStrv) kw_split = NULL; kw_split = g_strsplit (list[i], ",", -1); for (j = 0; kw_split[j] != NULL; j++) { if (kw_split[j][0] == '\0') continue; as_app_add_keyword (app, locale, kw_split[j]); } } } else if (g_strcmp0 (key, "MimeType") == 0) { list = g_key_file_get_string_list (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL, NULL); for (i = 0; list[i] != NULL; i++) as_app_add_mimetype (app, list[i]); } else if (g_strcmp0 (key, "X-AppInstall-Package") == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_add_pkgname (app, tmp); /* OnlyShowIn */ } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN) == 0) { /* if an app has only one entry, it's that desktop */ list = g_key_file_get_string_list (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL, NULL); if (g_strv_length (list) == 1) as_app_set_project_group (app, list[0]); /* Name */ } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_NAME) == 0 || g_strcmp0 (key, "_Name") == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_set_name (app, "C", tmp); /* Name[] */ } else if (g_str_has_prefix (key, G_KEY_FILE_DESKTOP_KEY_NAME)) { locale = as_app_desktop_key_get_locale (key); tmp = g_key_file_get_locale_string (kf, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_NAME, locale, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_set_name (app, locale, tmp); /* Comment */ } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_COMMENT) == 0 || g_strcmp0 (key, "_Comment") == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_set_comment (app, "C", tmp); /* Comment[] */ } else if (g_str_has_prefix (key, G_KEY_FILE_DESKTOP_KEY_COMMENT)) { locale = as_app_desktop_key_get_locale (key); tmp = g_key_file_get_locale_string (kf, G_KEY_FILE_DESKTOP_GROUP, G_KEY_FILE_DESKTOP_KEY_COMMENT, locale, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_set_comment (app, locale, tmp); /* non-standard */ } else if (g_strcmp0 (key, "X-Ubuntu-Software-Center-Name") == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_set_name (app, "C", tmp); } else if (g_str_has_prefix (key, "X-Ubuntu-Software-Center-Name")) { locale = as_app_desktop_key_get_locale (key); tmp = g_key_file_get_locale_string (kf, G_KEY_FILE_DESKTOP_GROUP, "X-Ubuntu-Software-Center-Name", locale, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_set_name (app, locale, tmp); } return TRUE; }
gboolean gs_plugin_add_distro_upgrades (GsPlugin *plugin, GsAppList *list, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); gsize len; guint i; g_autofree gchar *data = NULL; g_autoptr(GPtrArray) distros = NULL; g_autoptr(GSettings) settings = NULL; /* just ensure there is any data, no matter how old */ if (!gs_plugin_fedora_distro_upgrades_refresh (plugin, G_MAXUINT, cancellable, error)) return FALSE; /* get cached file */ if (!g_file_get_contents (priv->cachefn, &data, &len, error)) { gs_utils_error_convert_gio (error); return FALSE; } /* parse data */ settings = g_settings_new ("org.gnome.software"); distros = parse_pkgdb_collections_data (data, (gssize) len, error); if (distros == NULL) return FALSE; g_ptr_array_sort (distros, sort_distros_cb); for (i = 0; i < distros->len; i++) { DistroInfo *distro_info = g_ptr_array_index (distros, i); g_autofree gchar *app_id = NULL; g_autofree gchar *app_version = NULL; g_autofree gchar *background = NULL; g_autofree gchar *cache_key = NULL; g_autofree gchar *url = NULL; g_autofree gchar *css = NULL; g_autoptr(GsApp) app = NULL; g_autoptr(AsIcon) ic = NULL; /* only interested in upgrades to the same distro */ if (g_strcmp0 (distro_info->name, priv->os_name) != 0) continue; /* only interested in newer versions, but not more than N+2 */ if (distro_info->version <= priv->os_version || distro_info->version > priv->os_version + 2) continue; /* only interested in non-devel distros */ if (!g_settings_get_boolean (settings, "show-upgrade-prerelease")) { if (distro_info->status == DISTRO_STATUS_DEVEL) continue; } /* search in the cache */ cache_key = g_strdup_printf ("release-%u", distro_info->version); app = gs_plugin_cache_lookup (plugin, cache_key); if (app != NULL) { gs_app_list_add (list, app); continue; } app_id = g_strdup_printf ("org.fedoraproject.release-%u.upgrade", distro_info->version); app_version = g_strdup_printf ("%u", distro_info->version); /* icon from disk */ ic = as_icon_new (); as_icon_set_kind (ic, AS_ICON_KIND_LOCAL); as_icon_set_filename (ic, "/usr/share/pixmaps/fedora-logo-sprite.png"); /* create */ app = gs_app_new (app_id); gs_app_set_kind (app, AS_APP_KIND_OS_UPGRADE); gs_app_set_state (app, AS_APP_STATE_AVAILABLE); gs_app_set_name (app, GS_APP_QUALITY_LOWEST, distro_info->name); gs_app_set_summary (app, GS_APP_QUALITY_LOWEST, /* TRANSLATORS: this is a title for Fedora distro upgrades */ _("A major upgrade, with new features and added polish.")); gs_app_set_description (app, GS_APP_QUALITY_LOWEST, "Fedora Workstation is a polished, " "easy to use operating system for " "laptop and desktop computers, with a " "complete set of tools for developers " "and makers of all kinds."); gs_app_set_version (app, app_version); gs_app_set_size_installed (app, 1024 * 1024 * 1024); /* estimate */ gs_app_set_size_download (app, 256 * 1024 * 1024); /* estimate */ gs_app_set_license (app, GS_APP_QUALITY_LOWEST, "LicenseRef-free"); gs_app_add_quirk (app, AS_APP_QUIRK_NEEDS_REBOOT); gs_app_add_quirk (app, AS_APP_QUIRK_PROVENANCE); gs_app_add_quirk (app, AS_APP_QUIRK_NOT_REVIEWABLE); gs_app_set_origin_ui (app, distro_info->name); gs_app_add_icon (app, ic); gs_app_set_management_plugin (app, "packagekit"); /* show a Fedora magazine article for the release */ url = g_strdup_printf ("https://fedoramagazine.org/whats-new-fedora-%u-workstation", distro_info->version); gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, url); /* use a fancy background */ background = get_upgrade_css_background (distro_info->version); css = g_strdup_printf ("background: %s;" "background-position: center;" "background-size: cover;", background); gs_app_set_metadata (app, "GnomeSoftware::UpgradeBanner-css", css); gs_app_list_add (list, app); /* save in the cache */ gs_plugin_cache_add (plugin, cache_key, app); } return TRUE; }