/** * asb_plugin_process_app: */ gboolean asb_plugin_process_app (AsbPlugin *plugin, AsbPackage *pkg, AsbApp *app, const gchar *tmpdir, GError **error) { gchar **filelist; guint i; filelist = asb_package_get_filelist (pkg); for (i = 0; filelist[i] != NULL; i++) { GError *error_local = NULL; _cleanup_free_ gchar *filename = NULL; if (!g_str_has_prefix (filelist[i], "/usr/bin/")) continue; if (as_app_get_metadata_item (AS_APP (app), "X-Kudo-UsesAppMenu") != NULL) break; filename = g_build_filename (tmpdir, filelist[i], NULL); if (!asb_plugin_nm_app (app, filename, &error_local)) { asb_package_log (pkg, ASB_PACKAGE_LOG_LEVEL_WARNING, "Failed to run nm on %s: %s", filename, error_local->message); g_clear_error (&error_local); } } return TRUE; }
/** * asb_plugin_merge: */ void asb_plugin_merge (AsbPlugin *plugin, GList **list) { AsApp *app; AsApp *found; GList *l; GList *list_new = NULL; const gchar *tmp; _cleanup_hashtable_unref_ GHashTable *hash; /* add X-Merge-With-Parent on any metainfo files that are in a package * required by a desktop package */ asb_plugin_merge_prepare_deps (*list); /* add all packages to the hash */ hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref); for (l = *list; l != NULL; l = l->next) { app = AS_APP (l->data); g_hash_table_insert (hash, g_strdup (as_app_get_id_full (app)), g_object_ref (app)); } /* absorb some apps into their parent */ for (l = *list; l != NULL; l = l->next) { app = AS_APP (l->data); /* no absorb metadata */ tmp = as_app_get_metadata_item (app, "X-Merge-With-Parent"); if (tmp == NULL) { asb_plugin_add_app (&list_new, app); continue; } /* find the parent app */ found = g_hash_table_lookup (hash, tmp); if (found == NULL) { g_error ("Cannot find referenced '%s' from '%s'", tmp, as_app_get_id_full (app)); continue; } /* partially absorb */ g_debug ("partially absorbing %s into %s", as_app_get_id_full (app), as_app_get_id_full (found)); as_app_subsume_full (found, app, AS_APP_SUBSUME_FLAG_PARTIAL); } /* success */ g_list_free_full (*list, (GDestroyNotify) g_object_unref); *list = list_new; }
static gboolean setup_ext_runtime_version (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { const char *runtime_version; g_autoptr(GError) local_error = NULL; g_autoptr(AsApp) as_app = NULL; if (!app_is_legacy_external_app (app)) return TRUE; as_app = get_installed_appstream_app (plugin, app, cancellable, &local_error); if (!as_app) { g_warning ("Failed to get AsApp from installed AppStream " "data of app '%s': %s", gs_app_get_unique_id (app), local_error->message); g_propagate_error (error, g_steal_pointer (&local_error)); return FALSE; } /* get the runtime version that is set in the installed AppStream data */ runtime_version = as_app_get_metadata_item (as_app, LEGACY_RUNTIME_MTD_KEY); /* we setup the version of the external runtime used by this external * app so it is later used by "external-apps-cleaner" plugin when * removing those runtimes; we use a new key and not the one that is * already set in the metadata so we verify that this key has been * set by this plugin (and thus, by what was installed) and not by * the general AppStream data */ gs_app_set_metadata (app, LEGACY_RUNTIME_INSTALLED_MTD_KEY, NULL); gs_app_set_metadata (app, LEGACY_RUNTIME_INSTALLED_MTD_KEY, runtime_version); return TRUE; }
static gboolean gs_plugin_steam_update_screenshots (AsApp *app, const gchar *html, GError **error) { const gchar *gameid_str; gchar *tmp1; guint i = 0; guint idx = 0; /* find all the screenshots */ gameid_str = as_app_get_metadata_item (app, "X-Steam-GameID"); while ((tmp1 = gs_plugin_steam_capture (html, "data-screenshotid=\"", "\"", &i))) { g_autoptr(AsImage) im = NULL; g_autoptr(AsScreenshot) ss = NULL; g_autofree gchar *cdn_uri = NULL; /* create an image */ im = as_image_new (); as_image_set_kind (im, AS_IMAGE_KIND_SOURCE); cdn_uri = g_build_filename (GS_PLUGIN_STEAM_SCREENSHOT_URI, gameid_str, tmp1, NULL); as_image_set_url (im, cdn_uri); /* create screenshot with no caption */ ss = as_screenshot_new (); as_screenshot_set_kind (ss, idx == 0 ? AS_SCREENSHOT_KIND_DEFAULT : AS_SCREENSHOT_KIND_NORMAL); as_screenshot_add_image (ss, im); as_app_add_screenshot (app, ss); g_free (tmp1); /* limit this to a sane number */ if (idx++ >= 4) break; } return TRUE; }
/** * cra_plugin_process_filename: */ static gboolean cra_plugin_process_filename (CraPlugin *plugin, CraPackage *pkg, const gchar *filename, GList **apps, const gchar *tmpdir, GError **error) { const gchar *key; gboolean ret; _cleanup_free_ gchar *app_id = NULL; _cleanup_free_ gchar *full_filename = NULL; _cleanup_free_ gchar *icon_filename = NULL; _cleanup_object_unref_ CraApp *app = NULL; _cleanup_object_unref_ GdkPixbuf *pixbuf = NULL; /* create app */ app_id = g_path_get_basename (filename); app = cra_app_new (pkg, app_id); full_filename = g_build_filename (tmpdir, filename, NULL); ret = as_app_parse_file (AS_APP (app), full_filename, AS_APP_PARSE_FLAG_USE_HEURISTICS, error); if (!ret) return FALSE; /* NoDisplay requires AppData */ if (as_app_get_metadata_item (AS_APP (app), "NoDisplay") != NULL) cra_app_add_requires_appdata (app, "NoDisplay=true"); /* Settings or DesktopSettings requires AppData */ if (as_app_has_category (AS_APP (app), "Settings")) cra_app_add_requires_appdata (app, "Category=Settings"); if (as_app_has_category (AS_APP (app), "DesktopSettings")) cra_app_add_requires_appdata (app, "Category=DesktopSettings"); /* is the icon a stock-icon-name? */ key = as_app_get_icon (AS_APP (app)); if (key != NULL) { if (as_app_get_icon_kind (AS_APP (app)) == AS_ICON_KIND_STOCK) { cra_package_log (pkg, CRA_PACKAGE_LOG_LEVEL_DEBUG, "using stock icon %s", key); } else { /* is icon XPM or GIF */ if (g_str_has_suffix (key, ".xpm")) cra_app_add_veto (app, "Uses XPM icon: %s", key); else if (g_str_has_suffix (key, ".gif")) cra_app_add_veto (app, "Uses GIF icon: %s", key); else if (g_str_has_suffix (key, ".ico")) cra_app_add_veto (app, "Uses ICO icon: %s", key); /* find icon */ pixbuf = cra_app_find_icon (tmpdir, key, error); if (pixbuf == NULL) return FALSE; /* save in target directory */ icon_filename = g_strdup_printf ("%s.png", as_app_get_id (AS_APP (app))); as_app_set_icon (AS_APP (app), icon_filename, -1); as_app_set_icon_kind (AS_APP (app), AS_ICON_KIND_CACHED); cra_app_set_pixbuf (app, pixbuf); } } /* add */ cra_plugin_add_app (apps, app); return TRUE; }
static void gs_editor_refresh_details (GsEditor *self) { AsAppKind app_kind = AS_APP_KIND_UNKNOWN; GtkWidget *widget; const gchar *css = NULL; g_autoptr(GError) error = NULL; g_autoptr(GsApp) app = NULL; /* ignore changed events */ self->is_in_refresh = TRUE; /* create a GsApp for the AsApp */ if (self->selected_item != NULL) { app = gs_editor_convert_app (self, self->selected_item); g_debug ("refreshing details for %s", gs_app_get_id (app)); } /* get kind */ if (self->selected_item != NULL) app_kind = as_app_get_kind (self->selected_item); /* feature tiles */ if (app_kind != AS_APP_KIND_OS_UPGRADE) { if (self->selected_item != NULL) { gs_app_tile_set_app (GS_APP_TILE (self->featured_tile1), app); gtk_widget_set_sensitive (self->featured_tile1, TRUE); } else { gtk_widget_set_sensitive (self->featured_tile1, FALSE); } gtk_widget_set_visible (self->featured_tile1, TRUE); } else { gtk_widget_set_visible (self->featured_tile1, FALSE); } /* upgrade banner */ if (app_kind == AS_APP_KIND_OS_UPGRADE) { if (self->selected_item != NULL) { gs_upgrade_banner_set_app (GS_UPGRADE_BANNER (self->upgrade_banner), app); gtk_widget_set_sensitive (self->upgrade_banner, TRUE); } else { gtk_widget_set_sensitive (self->upgrade_banner, FALSE); } gtk_widget_set_visible (self->upgrade_banner, TRUE); } else { gtk_widget_set_visible (self->upgrade_banner, FALSE); } /* name */ widget = GTK_WIDGET (gtk_builder_get_object (self->builder, "box_name")); if (self->selected_item != NULL) { const gchar *tmp; gtk_widget_set_visible (widget, app_kind == AS_APP_KIND_OS_UPGRADE); widget = GTK_WIDGET (gtk_builder_get_object (self->builder, "entry_name")); tmp = as_app_get_name (self->selected_item, NULL); if (tmp != NULL) gtk_entry_set_text (GTK_ENTRY (widget), tmp); } else { gtk_widget_set_visible (widget, FALSE); } /* summary */ widget = GTK_WIDGET (gtk_builder_get_object (self->builder, "box_summary")); if (self->selected_item != NULL) { const gchar *tmp; gtk_widget_set_visible (widget, app_kind == AS_APP_KIND_OS_UPGRADE); widget = GTK_WIDGET (gtk_builder_get_object (self->builder, "entry_summary")); tmp = as_app_get_comment (self->selected_item, NULL); if (tmp != NULL) gtk_entry_set_text (GTK_ENTRY (widget), tmp); } else { gtk_widget_set_visible (widget, FALSE); } /* kudos */ widget = GTK_WIDGET (gtk_builder_get_object (self->builder, "box_kudos")); if (self->selected_item != NULL) { gtk_widget_set_visible (widget, app_kind != AS_APP_KIND_OS_UPGRADE); } else { gtk_widget_set_visible (widget, TRUE); } /* category featured */ widget = GTK_WIDGET (gtk_builder_get_object (self->builder, "checkbutton_category_featured")); if (self->selected_item != NULL) { gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), as_app_has_category (self->selected_item, "Featured")); gtk_widget_set_sensitive (widget, TRUE); } else { gtk_widget_set_sensitive (widget, FALSE); } /* kudo popular */ widget = GTK_WIDGET (gtk_builder_get_object (self->builder, "checkbutton_editors_pick")); if (self->selected_item != NULL) { gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), as_app_has_kudo (self->selected_item, "GnomeSoftware::popular")); gtk_widget_set_sensitive (widget, TRUE); } else { gtk_widget_set_sensitive (widget, FALSE); } /* featured */ widget = GTK_WIDGET (gtk_builder_get_object (self->builder, "textview_css")); if (self->selected_item != NULL) { GtkTextBuffer *buffer; GtkTextIter iter_end; GtkTextIter iter_start; g_autofree gchar *css_existing = NULL; if (app_kind == AS_APP_KIND_OS_UPGRADE) { css = as_app_get_metadata_item (self->selected_item, "GnomeSoftware::UpgradeBanner-css"); } else { css = as_app_get_metadata_item (self->selected_item, "GnomeSoftware::FeatureTile-css"); } if (css == NULL) css = ""; buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget)); gtk_text_buffer_get_bounds (buffer, &iter_start, &iter_end); css_existing = gtk_text_buffer_get_text (buffer, &iter_start, &iter_end, FALSE); if (g_strcmp0 (css_existing, css) != 0) gtk_text_buffer_set_text (buffer, css, -1); gtk_widget_set_sensitive (widget, TRUE); } else { gtk_widget_set_sensitive (widget, FALSE); } /* desktop ID */ widget = GTK_WIDGET (gtk_builder_get_object (self->builder, "entry_desktop_id")); if (self->selected_item != NULL) { const gchar *id = as_app_get_id (self->selected_item); if (id == NULL) id = ""; gtk_entry_set_text (GTK_ENTRY (widget), id); gtk_widget_set_sensitive (widget, TRUE); } else { gtk_entry_set_text (GTK_ENTRY (widget), ""); gtk_widget_set_sensitive (widget, FALSE); } /* validate CSS */ if (css == NULL) { widget = GTK_WIDGET (gtk_builder_get_object (self->builder, "label_infobar_css")); gtk_label_set_label (GTK_LABEL (widget), ""); widget = GTK_WIDGET (gtk_builder_get_object (self->builder, "infobar_css")); gtk_info_bar_set_message_type (GTK_INFO_BAR (widget), GTK_MESSAGE_OTHER); } else if (!gs_design_validate_css (self, css, &error)) { g_autofree gchar *msg = g_strdup (error->message); g_strdelimit (msg, "\n\r<>", '\0'); widget = GTK_WIDGET (gtk_builder_get_object (self->builder, "label_infobar_css")); gtk_label_set_label (GTK_LABEL (widget), msg); widget = GTK_WIDGET (gtk_builder_get_object (self->builder, "infobar_css")); gtk_info_bar_set_message_type (GTK_INFO_BAR (widget), GTK_MESSAGE_WARNING); } else { widget = GTK_WIDGET (gtk_builder_get_object (self->builder, "label_infobar_css")); gtk_label_set_label (GTK_LABEL (widget), _("CSS validated OK!")); widget = GTK_WIDGET (gtk_builder_get_object (self->builder, "infobar_css")); gtk_info_bar_set_message_type (GTK_INFO_BAR (widget), GTK_MESSAGE_OTHER); } /* do not ignore changed events */ self->is_in_refresh = FALSE; }
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; }
/** * asb_plugin_process_filename: */ static gboolean asb_plugin_process_filename (AsbPlugin *plugin, AsbPackage *pkg, const gchar *filename, GList **apps, const gchar *tmpdir, GError **error) { AsIcon *icon; AsAppParseFlags parse_flags = AS_APP_PARSE_FLAG_USE_HEURISTICS; gboolean ret; _cleanup_free_ gchar *app_id = NULL; _cleanup_free_ gchar *full_filename = NULL; _cleanup_object_unref_ AsbApp *app = NULL; _cleanup_object_unref_ 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 */ app_id = g_path_get_basename (filename); app = asb_app_new (pkg, app_id); asb_app_set_hidpi_enabled (app, asb_context_get_flag (plugin->ctx, ASB_CONTEXT_FLAG_HIDPI_ICONS)); full_filename = g_build_filename (tmpdir, filename, NULL); if (!as_app_parse_file (AS_APP (app), full_filename, parse_flags, error)) return FALSE; /* NoDisplay apps are never included */ if (as_app_get_metadata_item (AS_APP (app), "NoDisplay") != NULL) asb_app_add_requires_appdata (app, "NoDisplay=true"); /* Settings or DesktopSettings requires AppData */ if (!asb_context_get_flag (plugin->ctx, ASB_CONTEXT_FLAG_IGNORE_SETTINGS)) { if (as_app_has_category (AS_APP (app), "Settings")) asb_app_add_requires_appdata (app, "Category=Settings"); if (as_app_has_category (AS_APP (app), "DesktopSettings")) asb_app_add_requires_appdata (app, "Category=DesktopSettings"); } /* is the icon a stock-icon-name? */ icon = as_app_get_icon_default (AS_APP (app)); if (icon != NULL) { _cleanup_free_ gchar *key = NULL; key = g_strdup (as_icon_get_name (icon)); if (as_icon_get_kind (icon) == AS_ICON_KIND_STOCK) { asb_package_log (pkg, ASB_PACKAGE_LOG_LEVEL_DEBUG, "using stock icon %s", key); } else { _cleanup_error_free_ GError *error_local = NULL; 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); } } } /* add */ asb_plugin_add_app (apps, AS_APP (app)); return TRUE; }