Beispiel #1
1
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;
}
Beispiel #6
0
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;
}
Beispiel #10
0
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;
}
Beispiel #11
0
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);
}
Beispiel #12
0
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;
}
Beispiel #19
0
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;
}
Beispiel #22
0
/**
 * 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;
}
Beispiel #26
0
/**
 * 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);
}
Beispiel #27
0
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;
}
Beispiel #29
0
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);
}
Beispiel #30
0
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);
}