void gs_app_notify_installed (GsApp *app) { _cleanup_free_ gchar *summary = NULL; _cleanup_object_unref_ GNotification *n = NULL; /* TRANSLATORS: this is the summary of a notification that an application * has been successfully installed */ summary = g_strdup_printf (_("%s is now installed"), gs_app_get_name (app)); n = g_notification_new (summary); if (gs_app_get_id_kind (app) == AS_ID_KIND_DESKTOP) { /* TRANSLATORS: this is button that opens the newly installed application */ g_notification_add_button_with_target (n, _("Launch"), "app.launch", "s", gs_app_get_id (app)); } g_notification_set_default_action_and_target (n, "app.details", "(ss)", gs_app_get_id (app), ""); g_application_send_notification (g_application_get_default (), "installed", n); }
gboolean gs_plugin_launch (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { const gchar *launch_name; g_autofree gchar *binary_name = NULL; GAppInfoCreateFlags flags = G_APP_INFO_CREATE_NONE; g_autoptr(GAppInfo) info = NULL; /* We can only launch apps we know of */ if (g_strcmp0 (gs_app_get_management_plugin (app), "snap") != 0) return TRUE; launch_name = gs_app_get_metadata_item (app, "snap::launch-name"); if (!launch_name) return TRUE; if (g_strcmp0 (launch_name, gs_app_get_id (app)) == 0) binary_name = g_strdup_printf ("/snap/bin/%s", launch_name); else binary_name = g_strdup_printf ("/snap/bin/%s.%s", gs_app_get_id (app), launch_name); if (!is_graphical (app, cancellable)) flags |= G_APP_INFO_CREATE_NEEDS_TERMINAL; info = g_app_info_create_from_commandline (binary_name, NULL, flags, error); if (info == NULL) return FALSE; return g_app_info_launch (info, NULL, NULL, error); }
/** * gs_plugin_refine_app: */ static gboolean gs_plugin_refine_app (GsPlugin *plugin, GsApp *app, GError **error) { guint i; const gchar *app_globs[] = { "freeciv-server.desktop", "nm-connection-editor.desktop", "plank.desktop", "*release-notes*.desktop", "*Release_Notes*.desktop", "remote-viewer.desktop", "Rodent-*.desktop", "rygel-preferences.desktop", "system-config-keyboard.desktop", "tracker-preferences.desktop", "Uninstall*.desktop", NULL }; /* not set yet */ if (gs_app_get_id (app) == NULL) return TRUE; /* search */ for (i = 0; app_globs[i] != NULL; i++) { if (fnmatch (app_globs[i], gs_app_get_id (app), 0) == 0) { gs_app_add_category (app, "Blacklisted"); break; } } return TRUE; }
/** * gs_plugin_adopt_app: */ void gs_plugin_adopt_app (GsPlugin *plugin, GsApp *app) { if (g_str_has_prefix (gs_app_get_id (app), "user-xdgapp:") || g_str_has_prefix (gs_app_get_id (app), "xdgapp:")) { gs_app_set_management_plugin (app, gs_plugin_get_name (plugin)); } }
/** * gs_plugin_refine_item_state: */ static gboolean gs_plugin_refine_item_state (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); guint i; g_autoptr(GPtrArray) xrefs = NULL; g_autoptr(AsProfileTask) ptask = NULL; /* already found */ if (gs_app_get_state (app) != AS_APP_STATE_UNKNOWN) return TRUE; /* need broken out metadata */ if (!gs_plugin_refine_item_metadata (plugin, app, cancellable, error)) return FALSE; /* get apps and runtimes */ ptask = as_profile_start_literal (gs_plugin_get_profile (plugin), "xdg-app::refine-action"); xrefs = xdg_app_installation_list_installed_refs (priv->installation, cancellable, error); if (xrefs == NULL) return FALSE; for (i = 0; i < xrefs->len; i++) { XdgAppInstalledRef *xref = g_ptr_array_index (xrefs, i); /* check xref is app */ if (!gs_plugin_xdg_app_is_xref (app, XDG_APP_REF(xref))) continue; /* mark as installed */ g_debug ("marking %s as installed with xdg-app", gs_app_get_id (app)); gs_plugin_xdg_app_set_metadata_installed (app, xref); if (gs_app_get_state (app) == AS_APP_STATE_UNKNOWN) gs_app_set_state (app, AS_APP_STATE_INSTALLED); } /* anything not installed just check the remote is still present */ if (gs_app_get_state (app) == AS_APP_STATE_UNKNOWN && gs_app_get_origin (app) != NULL) { g_autoptr(XdgAppRemote) xremote = NULL; xremote = xdg_app_installation_get_remote_by_name (priv->installation, gs_app_get_origin (app), cancellable, NULL); if (xremote != NULL) { g_debug ("marking %s as available with xdg-app", gs_app_get_id (app)); gs_app_set_state (app, AS_APP_STATE_AVAILABLE); } } /* success */ return TRUE; }
static void gs_editor_app_tile_clicked_cb (GsAppTile *tile, GsEditor *self) { GsApp *app = gs_app_tile_get_app (tile); AsApp *item = as_store_get_app_by_id (self->store, gs_app_get_id (app)); if (item == NULL) { g_warning ("failed to find %s", gs_app_get_id (app)); return; } g_set_object (&self->selected_item, item); gs_editor_refresh_details (self); gs_editor_set_page (self, "details"); }
/** * gs_plugin_app_remove: */ gboolean gs_plugin_app_remove (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { const gchar *epi_desktop; g_autofree gchar *basename = NULL; g_autofree gchar *app_desktop = NULL; g_autoptr(GFile) file_epi = NULL; g_autoptr(GFile) file_app = NULL; /* only process this app if was created by this plugin */ if (g_strcmp0 (gs_app_get_management_plugin (app), "Epiphany") != 0) return TRUE; epi_desktop = gs_app_get_source_id_default (app); if (epi_desktop == NULL) return TRUE; /* remove the epi 'config' file */ gs_app_set_state (app, AS_APP_STATE_REMOVING); file_epi = g_file_new_for_path (epi_desktop); if (!g_file_delete (file_epi, NULL, error)) return FALSE; /* remove the shared desktop file */ basename = g_file_get_basename (file_epi); app_desktop = g_build_filename (g_get_user_data_dir (), "applications", gs_app_get_id (app), NULL); file_app = g_file_new_for_path (app_desktop); if (!g_file_delete (file_app, NULL, error)) return FALSE; gs_app_set_state (app, AS_APP_STATE_AVAILABLE); return TRUE; }
/** * gs_plugin_app_set_rating: */ gboolean gs_plugin_app_set_rating (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { GPtrArray *sources; const gchar *pkgname; gboolean ret; guint i; /* get the package name */ sources = gs_app_get_sources (app); if (sources->len == 0) { g_warning ("no pkgname for %s", gs_app_get_id (app)); return TRUE; } /* ensure networking is set up */ if (!gs_plugin_setup_networking (plugin, error)) return FALSE; /* set rating for each package */ for (i = 0; i < sources->len; i++) { pkgname = g_ptr_array_index (sources, i); ret = gs_plugin_app_set_rating_pkg (plugin, pkgname, gs_app_get_rating (app), error); if (!ret) return FALSE; } return TRUE; }
// Check if an app is graphical by checking if it uses a known GUI interface. // This doesn't necessarily mean that every binary uses this interfaces, but is probably true. // https://bugs.launchpad.net/bugs/1595023 static gboolean is_graphical (GsApp *app, GCancellable *cancellable) { g_autoptr(JsonObject) result = NULL; JsonArray *plugs; guint i; g_autoptr(GError) error = NULL; result = gs_snapd_get_interfaces (NULL, NULL, cancellable, &error); if (result == NULL) { g_warning ("Failed to check interfaces: %s", error->message); return FALSE; } plugs = json_object_get_array_member (result, "plugs"); for (i = 0; i < json_array_get_length (plugs); i++) { JsonObject *plug = json_array_get_object_element (plugs, i); const gchar *interface; // Only looks at the plugs for this snap if (g_strcmp0 (json_object_get_string_member (plug, "snap"), gs_app_get_id (app)) != 0) continue; interface = json_object_get_string_member (plug, "interface"); if (interface == NULL) continue; if (g_strcmp0 (interface, "unity7") == 0 || g_strcmp0 (interface, "x11") == 0 || g_strcmp0 (interface, "mir") == 0) return TRUE; } return FALSE; }
static gboolean gs_plugin_odrs_refine_ratings (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); GArray *review_ratings; gint rating; g_autoptr(AsProfileTask) ptask = NULL; /* profile */ ptask = as_profile_start_literal (gs_plugin_get_profile (plugin), "odrs::refine-ratings"); g_assert (ptask != NULL); /* get ratings */ review_ratings = g_hash_table_lookup (priv->ratings, gs_app_get_id (app)); if (review_ratings == NULL) return TRUE; gs_app_set_review_ratings (app, review_ratings); /* find the wilson rating */ rating = gs_utils_get_wilson_rating (g_array_index (review_ratings, guint32, 1), g_array_index (review_ratings, guint32, 2), g_array_index (review_ratings, guint32, 3), g_array_index (review_ratings, guint32, 4), g_array_index (review_ratings, guint32, 5)); if (rating > 0) gs_app_set_rating (app, rating); return TRUE; }
static void gs_page_remove_app_response_cb (GtkDialog *dialog, gint response, gpointer user_data) { g_autoptr(GsPageHelper) helper = (GsPageHelper *) user_data; GsPagePrivate *priv = gs_page_get_instance_private (helper->page); g_autoptr(GsPluginJob) plugin_job = NULL; /* unmap the dialog */ gtk_widget_destroy (GTK_WIDGET (dialog)); /* not agreed */ if (response != GTK_RESPONSE_OK) return; g_debug ("remove %s", gs_app_get_id (helper->app)); plugin_job = gs_plugin_job_newv (helper->action, "interactive", TRUE, "app", helper->app, NULL); gs_plugin_loader_job_process_async (priv->plugin_loader, plugin_job, helper->cancellable, gs_page_app_removed_cb, helper); g_steal_pointer (&helper); }
gboolean gs_plugin_refine_app (GsPlugin *plugin, GsApp *app, GsPluginRefineFlags flags, GCancellable *cancellable, GError **error) { /* not valid */ if (gs_app_get_kind (app) == AS_APP_KIND_ADDON) return TRUE; if (gs_app_get_id (app) == NULL) return TRUE; /* add reviews if possible */ if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEWS) { if (gs_app_get_reviews(app)->len > 0) return TRUE; if (!gs_plugin_odrs_refine_reviews (plugin, app, cancellable, error)) return FALSE; } /* add ratings if possible */ if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEW_RATINGS || flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_RATING) { if (gs_app_get_review_ratings(app) != NULL) return TRUE; if (!gs_plugin_odrs_refine_ratings (plugin, app, cancellable, error)) return FALSE; } return TRUE; }
/** * gs_plugin_xdg_app_is_xref: */ static gboolean gs_plugin_xdg_app_is_xref (GsApp *app, XdgAppRef *xref) { g_autofree gchar *id = NULL; /* check ID */ id = gs_plugin_xdg_app_build_id (xref); if (g_strcmp0 (id, gs_app_get_id (app)) == 0) return TRUE; /* check source ID */ // if (g_strcmp0 (id, gs_app_get_id (app)) == 0) // return TRUE; /* do all the metadata items match? */ if (g_strcmp0 (gs_app_get_xdgapp_name (app), xdg_app_ref_get_name (xref)) == 0 && g_strcmp0 (gs_app_get_xdgapp_arch (app), xdg_app_ref_get_arch (xref)) == 0 && g_strcmp0 (gs_app_get_xdgapp_branch (app), xdg_app_ref_get_branch (xref)) == 0) return TRUE; /* sad panda */ return FALSE; }
/** * _gs_app_get_id_nonfull: */ static gchar * _gs_app_get_id_nonfull (GsApp *app) { gchar *id; gchar *tmp; id = g_strdup (gs_app_get_id (app)); tmp = g_strrstr (id, ".desktop"); if (tmp != NULL) *tmp = '\0'; return id; }
static gboolean app_is_legacy_external_app (GsApp *app) { guint i; for (i = 0; LEGACY_EXTERNAL_APPS[i] != NULL; ++i) { const char *current_id = LEGACY_EXTERNAL_APPS[i]; if (g_strcmp0 (gs_app_get_id (app), current_id) == 0) return TRUE; } return FALSE; }
gboolean gs_plugin_refine_app (GsPlugin *plugin, GsApp *app, GsPluginRefineFlags flags, GCancellable *cancellable, GError **error) { /* we have to whitelist Chrome which has been blacklisted so previous * versions of the OS (without the helper app) would not see it */ if (g_strcmp0 (gs_app_get_id (app), "com.google.Chrome.desktop") == 0) gs_app_remove_category (app, "Blacklisted"); return TRUE; }
static AsApp * get_installed_appstream_app (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { AsApp *as_app; GsPluginData *priv = gs_plugin_get_data (plugin); const char *deploy_dir; g_autoptr(AsStore) store = NULL; g_autoptr(FlatpakInstalledRef) ref = NULL; g_autoptr(GFile) appstream_file = NULL; g_autofree char *appstream_xml = NULL; g_autofree char *appstream_path = NULL; ref = flatpak_installation_get_installed_ref (priv->installation, FLATPAK_REF_KIND_APP, gs_app_get_flatpak_name (app), gs_app_get_flatpak_arch (app), gs_app_get_flatpak_branch (app), cancellable, error); if (!ref) return NULL; deploy_dir = flatpak_installed_ref_get_deploy_dir (ref); appstream_xml = g_strdup_printf ("%s.appdata.xml", gs_app_get_flatpak_name (app)); appstream_path = g_build_filename (deploy_dir, "files", "share", "app-info", "xmls", appstream_xml, NULL); appstream_file = g_file_new_for_path (appstream_path); store = as_store_new (); as_store_set_add_flags (store, AS_STORE_ADD_FLAG_USE_UNIQUE_ID | AS_STORE_ADD_FLAG_USE_MERGE_HEURISTIC); if (!as_store_from_file (store, appstream_file, NULL, cancellable, error)) return NULL; as_app = as_store_get_app_by_id (store, gs_app_get_id (app)); if (!as_app) g_set_error (error, AS_STORE_ERROR, AS_STORE_ERROR_FAILED, "Failed to get app %s from its own installation " "AppStream file.", gs_app_get_unique_id (app)); return g_object_ref (as_app); }
gboolean gs_plugin_refine_app (GsPlugin *plugin, GsApp *app, GsPluginRefineFlags flags, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); LiPkgInfo *pki; g_autoptr(GError) error_local = NULL; g_autoptr(AsProfileTask) ptask = NULL; /* not us */ if (g_strcmp0 (gs_app_get_management_plugin (app), gs_plugin_get_name (plugin)) != 0) return TRUE; /* profile */ ptask = as_profile_start (gs_plugin_get_profile (plugin), "limba::refine{%s}", gs_app_get_id (app)); /* sanity check */ if (gs_app_get_source_default (app) == NULL) return TRUE; pki = li_manager_get_software_by_pkid (priv->mgr, gs_app_get_source_default (app), &error_local); if (error_local != NULL) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "Unable to refine metadata: %s", error_local->message); return FALSE; } if (pki == NULL) return TRUE; if (li_pkg_info_has_flag (pki, LI_PACKAGE_FLAG_INSTALLED)) gs_app_set_state (app, AS_APP_STATE_INSTALLED); else gs_app_set_state (app, AS_APP_STATE_AVAILABLE); gs_app_set_version (app, li_pkg_info_get_version (pki)); return TRUE; }
void gs_plugin_adopt_app (GsPlugin *plugin, GsApp *app) { if (gs_app_get_bundle_kind (app) == AS_BUNDLE_KIND_SNAP) gs_app_set_management_plugin (app, "snap"); if (g_str_has_prefix (gs_app_get_id (app), "io.snapcraft.")) { g_autofree gchar *name_and_id = NULL; gchar *divider, *snap_name;/*, *id;*/ name_and_id = g_strdup (gs_app_get_id (app) + strlen ("io.snapcraft.")); divider = strrchr (name_and_id, '-'); if (divider != NULL) { *divider = '\0'; snap_name = name_and_id; /*id = divider + 1;*/ /* NOTE: Should probably validate ID */ gs_app_set_management_plugin (app, "snap"); gs_app_set_metadata (app, "snap::name", snap_name); gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_SNAP); } } }
/** * gs_plugin_xdg_app_refine_app: */ static gboolean gs_plugin_xdg_app_refine_app (GsPlugin *plugin, GsApp *app, GsPluginRefineFlags flags, GCancellable *cancellable, GError **error) { g_autoptr(AsProfileTask) ptask = NULL; /* only process this app if was created by this plugin */ if (g_strcmp0 (gs_app_get_management_plugin (app), gs_plugin_get_name (plugin)) != 0) return TRUE; /* profile */ ptask = as_profile_start (gs_plugin_get_profile (plugin), "xdg-app::refine{%s}", gs_app_get_id (app)); /* AppStream sets the source to appname/arch/branch */ if (!gs_plugin_refine_item_metadata (plugin, app, cancellable, error)) return FALSE; /* check the installed state */ if (!gs_plugin_refine_item_state (plugin, app, cancellable, error)) return FALSE; /* version fallback */ if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_VERSION) { if (gs_app_get_version (app) == NULL) { const gchar *branch; branch = gs_app_get_xdgapp_branch (app); gs_app_set_version (app, branch); } } /* size */ if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_SIZE) { if (!gs_plugin_refine_item_size (plugin, app, cancellable, error)) return FALSE; } /* origin */ if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_ORIGIN) { if (!gs_plugin_refine_item_origin_ui (plugin, app, cancellable, error)) return FALSE; } return TRUE; }
/** * gs_plugin_app_upgrade_download: */ gboolean gs_plugin_app_upgrade_download (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); ProgressData data; g_autoptr(PkResults) results = NULL; /* only process this app if was created by this plugin */ if (g_strcmp0 (gs_app_get_management_plugin (app), "packagekit") != 0) return TRUE; data.app = app; data.plugin = plugin; /* check is distro-upgrade */ if (gs_app_get_kind (app) != AS_APP_KIND_OS_UPGRADE) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "app %s is not a distro upgrade", gs_app_get_id (app)); return FALSE; } /* ask PK to download enough packages to upgrade the system */ gs_app_set_state (app, AS_APP_STATE_INSTALLING); results = pk_task_upgrade_system_sync (priv->task, gs_app_get_version (app), PK_UPGRADE_KIND_ENUM_COMPLETE, cancellable, gs_plugin_packagekit_progress_cb, &data, error); if (!gs_plugin_packagekit_results_valid (results, error)) { gs_app_set_state_recover (app); return FALSE; } /* state is known */ gs_app_set_state (app, AS_APP_STATE_UPDATABLE); return TRUE; }
/** * gs_refine_item_management_plugin: */ static void gs_refine_item_management_plugin (GsApp *app, AsApp *item) { GPtrArray *bundles; const gchar *management_plugin = NULL; const gchar *runtime = NULL; guint i; /* find the default bundle kind */ bundles = as_app_get_bundles (item); for (i = 0; i < bundles->len; i++) { AsBundle *bundle = g_ptr_array_index (bundles, i); if (as_bundle_get_kind (bundle) == AS_BUNDLE_KIND_XDG_APP) { management_plugin = "XgdApp"; gs_app_add_source (app, as_bundle_get_id (bundle)); /* automatically add runtime */ runtime = as_bundle_get_runtime (bundle); if (runtime != NULL) { g_autoptr(GsApp) app2 = NULL; app2 = gs_appstream_create_runtime (app, runtime); if (app2 != NULL) { g_debug ("runtime for %s is %s", gs_app_get_id (app), runtime); gs_app_set_runtime (app, app2); } } break; } if (as_bundle_get_kind (bundle) == AS_BUNDLE_KIND_LIMBA) { management_plugin = "Limba"; gs_app_add_source (app, as_bundle_get_id (bundle)); break; } } /* fall back to PackageKit */ if (management_plugin == NULL && as_app_get_pkgname_default (item) != NULL) management_plugin = "PackageKit"; if (management_plugin != NULL) gs_app_set_management_plugin (app, management_plugin); }
gboolean gs_plugin_refine_app (GsPlugin *plugin, GsApp *app, GsPluginRefineFlags flags, GCancellable *cancellable, GError **error) { const gchar *key = "GnomeSoftware::FeatureTile-css"; guint i; for (i = 0; myapps[i].id != NULL; i++) { if (g_strcmp0 (gs_app_get_id (app), myapps[i].id) != 0) continue; if (gs_app_get_metadata_item (app, key) != NULL) continue; gs_app_set_metadata (app, key, myapps[i].css); } return TRUE; }
/** * gs_plugin_refine: */ gboolean gs_plugin_refine (GsPlugin *plugin, GList **list, GsPluginRefineFlags flags, GCancellable *cancellable, GError **error) { GsApp *app; GList *l; for (l = *list; l != NULL; l = l->next) { app = GS_APP (l->data); if (gs_app_get_name (app) == NULL) { if (g_strcmp0 (gs_app_get_id (app), "gnome-boxes") == 0) { gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "Boxes"); gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "A simple GNOME 3 application to access remote or virtual systems"); } } } return TRUE; }
gboolean gs_plugin_app_remove (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { g_autofree gchar *macaroon = NULL; g_auto(GStrv) discharges = NULL; /* We can only remove apps we know of */ if (g_strcmp0 (gs_app_get_management_plugin (app), "snap") != 0) return TRUE; get_macaroon (plugin, &macaroon, &discharges); gs_app_set_state (app, AS_APP_STATE_REMOVING); if (!gs_snapd_remove (macaroon, discharges, gs_app_get_id (app), progress_cb, app, cancellable, error)) { gs_app_set_state_recover (app); return FALSE; } gs_app_set_state (app, AS_APP_STATE_AVAILABLE); return TRUE; }
/** * gs_appstream_create_runtime: */ GsApp * gs_appstream_create_runtime (GsApp *parent, const gchar *runtime) { const gchar *id_parent; g_autofree gchar *id = NULL; g_autofree gchar *source = NULL; g_auto(GStrv) id_split = NULL; g_auto(GStrv) runtime_split = NULL; g_autoptr(GsApp) app = NULL; /* get the name/arch/branch */ runtime_split = g_strsplit (runtime, "/", -1); if (g_strv_length (runtime_split) != 3) return NULL; /* find the parent app ID prefix */ id_parent = gs_app_get_id (parent); if (id_parent == NULL) return NULL; id_split = g_strsplit (id_parent, ":", 2); if (g_strv_length (id_split) == 2) { id = g_strdup_printf ("%s:%s.runtime", id_split[0], runtime_split[0]); } else { id = g_strdup_printf ("%s.runtime", runtime_split[0]); } /* create the complete GsApp from the single string */ app = gs_app_new (id); source = g_strdup_printf ("runtime/%s", runtime); gs_app_add_source (app, source); gs_app_set_kind (app, AS_APP_KIND_RUNTIME); gs_app_set_version (app, id_split[2]); return g_steal_pointer (&app); }
static void gs_page_remove_app_response_cb (GtkDialog *dialog, gint response, GsPageHelper *helper) { GsPagePrivate *priv = gs_page_get_instance_private (helper->page); /* unmap the dialog */ gtk_widget_destroy (GTK_WIDGET (dialog)); /* not agreed */ if (response != GTK_RESPONSE_OK) { gs_page_helper_free (helper); return; } g_debug ("remove %s", gs_app_get_id (helper->app)); gs_plugin_loader_app_action_async (priv->plugin_loader, helper->app, helper->action, GS_PLUGIN_FAILURE_FLAGS_FATAL_ANY, helper->cancellable, gs_page_app_removed_cb, helper); }
gboolean gs_plugin_refine_app (GsPlugin *plugin, GsApp *app, GsPluginRefineFlags flags, GCancellable *cancellable, GError **error) { g_autofree gchar *macaroon = NULL; g_auto(GStrv) discharges = NULL; g_autoptr(JsonObject) result = NULL; /* not us */ if (g_strcmp0 (gs_app_get_management_plugin (app), "snap") != 0) return TRUE; get_macaroon (plugin, &macaroon, &discharges); result = gs_snapd_list_one (macaroon, discharges, gs_app_get_id (app), cancellable, error); if (result == NULL) return FALSE; refine_app (plugin, app, result, FALSE, cancellable); return TRUE; }
gboolean gs_plugin_review_submit (GsPlugin *plugin, GsApp *app, AsReview *review, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); g_autofree gchar *data = NULL; g_autofree gchar *uri = NULL; g_autofree gchar *version = NULL; g_autoptr(JsonBuilder) builder = NULL; g_autoptr(JsonGenerator) json_generator = NULL; g_autoptr(JsonNode) json_root = NULL; /* save as we don't re-request the review from the server */ as_review_set_reviewer_name (review, g_get_real_name ()); as_review_add_metadata (review, "app_id", gs_app_get_id (app)); as_review_add_metadata (review, "user_skey", gs_app_get_metadata_item (app, "ODRS::user_skey")); /* create object with review data */ builder = json_builder_new (); json_builder_begin_object (builder); json_builder_set_member_name (builder, "user_hash"); json_builder_add_string_value (builder, priv->user_hash); json_builder_set_member_name (builder, "user_skey"); json_builder_add_string_value (builder, as_review_get_metadata_item (review, "user_skey")); json_builder_set_member_name (builder, "app_id"); json_builder_add_string_value (builder, as_review_get_metadata_item (review, "app_id")); json_builder_set_member_name (builder, "locale"); json_builder_add_string_value (builder, gs_plugin_get_locale (plugin)); json_builder_set_member_name (builder, "distro"); json_builder_add_string_value (builder, priv->distro); json_builder_set_member_name (builder, "version"); version = gs_plugin_odrs_sanitize_version (as_review_get_version (review)); json_builder_add_string_value (builder, version); json_builder_set_member_name (builder, "user_display"); json_builder_add_string_value (builder, as_review_get_reviewer_name (review)); json_builder_set_member_name (builder, "summary"); json_builder_add_string_value (builder, as_review_get_summary (review)); json_builder_set_member_name (builder, "description"); json_builder_add_string_value (builder, as_review_get_description (review)); json_builder_set_member_name (builder, "rating"); json_builder_add_int_value (builder, as_review_get_rating (review)); json_builder_end_object (builder); /* export as a string */ json_root = json_builder_get_root (builder); json_generator = json_generator_new (); json_generator_set_pretty (json_generator, TRUE); json_generator_set_root (json_generator, json_root); data = json_generator_to_data (json_generator, NULL); /* clear cache */ if (!gs_plugin_odrs_invalidate_cache (review, error)) return FALSE; /* POST */ uri = g_strdup_printf ("%s/submit", priv->review_server); return gs_plugin_odrs_json_post (gs_plugin_get_soup_session (plugin), uri, data, error); }
static GPtrArray * gs_plugin_odrs_fetch_for_app (GsPlugin *plugin, GsApp *app, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); const gchar *version; guint status_code; g_autofree gchar *cachefn_basename = NULL; g_autofree gchar *cachefn = NULL; g_autofree gchar *data = NULL; g_autofree gchar *uri = NULL; g_autoptr(GFile) cachefn_file = NULL; g_autoptr(GPtrArray) reviews = NULL; g_autoptr(JsonBuilder) builder = NULL; g_autoptr(JsonGenerator) json_generator = NULL; g_autoptr(JsonNode) json_root = NULL; g_autoptr(SoupMessage) msg = NULL; /* look in the cache */ cachefn_basename = g_strdup_printf ("%s.json", gs_app_get_id (app)); cachefn = gs_utils_get_cache_filename ("reviews", cachefn_basename, GS_UTILS_CACHE_FLAG_WRITEABLE, error); if (cachefn == NULL) return NULL; cachefn_file = g_file_new_for_path (cachefn); if (gs_utils_get_file_age (cachefn_file) < ODRS_REVIEW_CACHE_AGE_MAX) { g_autofree gchar *json_data = NULL; if (!g_file_get_contents (cachefn, &json_data, NULL, error)) return NULL; g_debug ("got review data for %s from %s", gs_app_get_id (app), cachefn); return gs_plugin_odrs_parse_reviews (plugin, json_data, -1, error); } /* not always available */ version = gs_app_get_version (app); if (version == NULL) version = "unknown"; /* create object with review data */ builder = json_builder_new (); json_builder_begin_object (builder); json_builder_set_member_name (builder, "user_hash"); json_builder_add_string_value (builder, priv->user_hash); json_builder_set_member_name (builder, "app_id"); json_builder_add_string_value (builder, gs_app_get_id (app)); json_builder_set_member_name (builder, "locale"); json_builder_add_string_value (builder, gs_plugin_get_locale (plugin)); json_builder_set_member_name (builder, "distro"); json_builder_add_string_value (builder, priv->distro); json_builder_set_member_name (builder, "version"); json_builder_add_string_value (builder, version); json_builder_set_member_name (builder, "limit"); json_builder_add_int_value (builder, ODRS_REVIEW_NUMBER_RESULTS_MAX); json_builder_end_object (builder); /* export as a string */ json_root = json_builder_get_root (builder); json_generator = json_generator_new (); json_generator_set_pretty (json_generator, TRUE); json_generator_set_root (json_generator, json_root); data = json_generator_to_data (json_generator, NULL); if (data == NULL) return NULL; uri = g_strdup_printf ("%s/fetch", priv->review_server); msg = soup_message_new (SOUP_METHOD_POST, uri); soup_message_set_request (msg, "application/json; charset=utf-8", SOUP_MEMORY_COPY, data, strlen (data)); status_code = soup_session_send_message (gs_plugin_get_soup_session (plugin), msg); if (status_code != SOUP_STATUS_OK) { if (!gs_plugin_odrs_parse_success (msg->response_body->data, msg->response_body->length, error)) return NULL; /* not sure what to do here */ g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_DOWNLOAD_FAILED, "status code invalid"); gs_utils_error_add_unique_id (error, priv->cached_origin); return NULL; } reviews = gs_plugin_odrs_parse_reviews (plugin, msg->response_body->data, msg->response_body->length, error); if (reviews == NULL) return NULL; g_debug ("odrs returned: %s", msg->response_body->data); /* save to the cache */ if (!g_file_set_contents (cachefn, msg->response_body->data, msg->response_body->length, error)) return NULL; /* success */ return g_steal_pointer (&reviews); }