/**
 * gs_plugin_refine_item_origin:
 */
static gboolean
gs_plugin_refine_item_origin (GsPlugin *plugin,
			      GsApp *app,
			      GCancellable *cancellable,
			      GError **error)
{
	GsPluginData *priv = gs_plugin_get_data (plugin);
	guint i;
	g_autoptr(GPtrArray) xremotes = NULL;
	g_autoptr(AsProfileTask) ptask = NULL;

	/* already set */
	if (gs_app_get_origin (app) != NULL)
		return TRUE;

	/* ensure metadata exists */
	ptask = as_profile_start_literal (gs_plugin_get_profile (plugin),
					  "xdg-app::refine-origin");
	if (!gs_plugin_refine_item_metadata (plugin, app, cancellable, error))
		return FALSE;

	/* find list of remotes */
	g_debug ("looking for a remote for %s/%s/%s",
		 gs_app_get_xdgapp_name (app),
		 gs_app_get_xdgapp_arch (app),
		 gs_app_get_xdgapp_branch (app));
	xremotes = xdg_app_installation_list_remotes (priv->installation,
						      cancellable,
						      error);
	if (xremotes == NULL)
		return FALSE;
	for (i = 0; i < xremotes->len; i++) {
		const gchar *remote_name;
		XdgAppRemote *xremote = g_ptr_array_index (xremotes, i);
		g_autoptr(XdgAppRemoteRef) xref = NULL;
		remote_name = xdg_app_remote_get_name (xremote);
		g_debug ("looking at remote %s", remote_name);
		xref = xdg_app_installation_fetch_remote_ref_sync (priv->installation,
								   remote_name,
								   gs_app_get_xdgapp_kind (app),
								   gs_app_get_xdgapp_name (app),
								   gs_app_get_xdgapp_arch (app),
								   gs_app_get_xdgapp_branch (app),
								   cancellable,
								   NULL);
		if (xref != NULL) {
			g_debug ("found remote %s", remote_name);
			gs_app_set_origin (app, remote_name);
			return TRUE;
		}
	}
	g_set_error (error,
		     GS_PLUGIN_ERROR,
		     GS_PLUGIN_ERROR_NOT_SUPPORTED,
		     "Not found %s/%s/%s",
		     gs_app_get_xdgapp_name (app),
		     gs_app_get_xdgapp_arch (app),
		     gs_app_get_xdgapp_branch (app));
	return FALSE;
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
0
static void
gs_plugin_packagekit_progress_cb (PkProgress *progress,
				  PkProgressType type,
				  gpointer user_data)
{
	ProgressData *data = (ProgressData *) user_data;
	GsPlugin *plugin = data->plugin;

	if (type == PK_PROGRESS_TYPE_STATUS) {
		GsPluginStatus plugin_status;
		PkStatusEnum status;
		g_object_get (progress,
			      "status", &status,
			      NULL);

		/* profile */
		if (status == PK_STATUS_ENUM_SETUP) {
			data->ptask = as_profile_start_literal (gs_plugin_get_profile (plugin),
						"packagekit-refine::transaction");
		} else if (status == PK_STATUS_ENUM_FINISHED) {
			g_clear_pointer (&data->ptask, as_profile_task_free);
		}

		plugin_status = packagekit_status_enum_to_plugin_status (status);
		if (plugin_status != GS_PLUGIN_STATUS_UNKNOWN)
			gs_plugin_status_update (plugin, data->app, plugin_status);

	} else if (type == PK_PROGRESS_TYPE_PERCENTAGE) {
		gint percentage = pk_progress_get_percentage (progress);
		if (data->app != NULL && percentage >= 0 && percentage <= 100)
			gs_app_set_progress (data->app, (guint) percentage);
	}
}
/**
 * gs_plugin_refine_item_commit:
 */
static gboolean
gs_plugin_refine_item_commit (GsPlugin *plugin,
			      GsApp *app,
			      GCancellable *cancellable,
			      GError **error)
{
	GsPluginData *priv = gs_plugin_get_data (plugin);
	g_autoptr(AsProfileTask) ptask = NULL;
	g_autoptr(XdgAppRemoteRef) xref_remote = NULL;

	if (gs_app_get_xdgapp_commit (app) != NULL)
		return TRUE;
	if (gs_app_get_origin (app) == NULL) {
		g_debug ("no origin got commit, so refining origin first");
		if (!gs_plugin_refine_item_origin (plugin, app, cancellable, error))
			return FALSE;
	}

	ptask = as_profile_start_literal (gs_plugin_get_profile (plugin),
					  "xdg-app::fetch-remote-ref");
	xref_remote = xdg_app_installation_fetch_remote_ref_sync (priv->installation,
								  gs_app_get_origin (app),
								  gs_app_get_xdgapp_kind (app),
								  gs_app_get_xdgapp_name (app),
								  gs_app_get_xdgapp_arch (app),
								  gs_app_get_xdgapp_branch (app),
								  cancellable,
								  error);
	if (xref_remote == NULL)
		return FALSE;
	gs_app_set_xdgapp_commit (app, xdg_app_ref_get_commit (XDG_APP_REF (xref_remote)));
	return TRUE;
}
Exemplo n.º 5
0
static gboolean
gs_plugin_add_sources_related (GsPlugin *plugin,
			       GHashTable *hash,
			       GCancellable *cancellable,
			       GError **error)
{
	GsPluginData *priv = gs_plugin_get_data (plugin);
	guint i;
	GsApp *app;
	GsApp *app_tmp;
	PkBitfield filter;
	ProgressData data;
	const gchar *id;
	gboolean ret = TRUE;
	g_autoptr(GsAppList) installed = gs_app_list_new ();
	g_autoptr(PkResults) results = NULL;
	g_autoptr(AsProfileTask) ptask = NULL;

	data.app = NULL;
	data.plugin = plugin;
	data.ptask = NULL;

	ptask = as_profile_start_literal (gs_plugin_get_profile (plugin),
					  "packagekit::add-sources-related");
	g_assert (ptask != NULL);
	filter = pk_bitfield_from_enums (PK_FILTER_ENUM_INSTALLED,
					 PK_FILTER_ENUM_NEWEST,
					 PK_FILTER_ENUM_ARCH,
					 PK_FILTER_ENUM_NOT_COLLECTIONS,
					 -1);
	results = pk_client_get_packages (PK_CLIENT(priv->task),
					   filter,
					   cancellable,
					   gs_plugin_packagekit_progress_cb, &data,
					   error);
	if (!gs_plugin_packagekit_results_valid (results, error))
		return FALSE;
	ret = gs_plugin_packagekit_add_results (plugin,
						installed,
						results,
						error);
	if (!ret)
		return FALSE;
	for (i = 0; i < gs_app_list_length (installed); i++) {
		g_auto(GStrv) split = NULL;
		app = gs_app_list_index (installed, i);
		split = pk_package_id_split (gs_app_get_source_id_default (app));
		if (g_str_has_prefix (split[PK_PACKAGE_ID_DATA], "installed:")) {
			id = split[PK_PACKAGE_ID_DATA] + 10;
			app_tmp = g_hash_table_lookup (hash, id);
			if (app_tmp != NULL) {
				g_debug ("found package %s from %s",
					 gs_app_get_source_default (app), id);
				gs_app_add_related (app_tmp, app);
			}
		}
	}
	return TRUE;
}
/**
 * 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;
}
/**
 * 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;
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
0
static gboolean
gs_plugin_odrs_refine_reviews (GsPlugin *plugin,
			       GsApp *app,
			       GCancellable *cancellable,
			       GError **error)
{
	GsPluginData *priv = gs_plugin_get_data (plugin);
	AsReview *review;
	guint i;
	g_autoptr(AsProfileTask) ptask = NULL;
	g_autoptr(GPtrArray) reviews = NULL;

	/* profile */
	ptask = as_profile_start_literal (gs_plugin_get_profile (plugin),
					  "odrs::refine-reviews");
	g_assert (ptask != NULL);

	/* get from server */
	reviews = gs_plugin_odrs_fetch_for_app (plugin, app, error);
	if (reviews == NULL)
		return FALSE;
	for (i = 0; i < reviews->len; i++) {
		review = g_ptr_array_index (reviews, i);

		/* save this on the application object so we can use it for
		 * submitting a new review */
		if (i == 0) {
			gs_app_set_metadata (app, "ODRS::user_skey",
					     as_review_get_metadata_item (review, "user_skey"));
		}

		/* ignore invalid reviews */
		if (as_review_get_rating (review) == 0)
			continue;

		/* the user_hash matches, so mark this as our own review */
		if (g_strcmp0 (as_review_get_reviewer_id (review),
			       priv->user_hash) == 0) {
			as_review_set_flags (review, AS_REVIEW_FLAG_SELF);
		}
		gs_app_add_review (app, review);
	}
	return TRUE;
}
Exemplo n.º 10
0
/**
 * gs_plugin_setup:
 */
gboolean
gs_plugin_setup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
{
	GsPluginData *priv = gs_plugin_get_data (plugin);
	g_autofree gchar *install_path = NULL;
	g_autoptr(AsProfileTask) ptask = NULL;
	g_autoptr(GFile) install_file = NULL;

	/* If we're running INSIDE the xdg-app environment we'll have the
	 * env var XDG_DATA_HOME set to "~/.var/app/org.gnome.Software/data"
	 * so specify the path manually to get the real data */
	install_path = g_build_filename (g_get_home_dir (),
					 ".local",
					 "share",
					 "xdg-app",
					 NULL);
	install_file = g_file_new_for_path (install_path);

	/* FIXME: this should default to system-wide, but we need a permissions
	 * helper to elevate privs */
	ptask = as_profile_start_literal (gs_plugin_get_profile (plugin),
					  "xdg-app::ensure-origin");
	priv->installation = xdg_app_installation_new_for_path (install_file,
									TRUE,
									cancellable,
									error);
	if (priv->installation == NULL)
		return FALSE;

	/* watch for changes */
	priv->monitor =
		xdg_app_installation_create_monitor (priv->installation,
						     cancellable,
						     error);
	if (priv->monitor == NULL)
		return FALSE;
	g_signal_connect (priv->monitor, "changed",
			  G_CALLBACK (gs_plugin_xdg_app_changed_cb), plugin);

	/* success */
	return TRUE;
}
Exemplo n.º 11
0
/**
 * gs_plugin_refine_item_origin_ui:
 */
static gboolean
gs_plugin_refine_item_origin_ui (GsPlugin *plugin,
				 GsApp *app,
				 GCancellable *cancellable,
				 GError **error)
{
	GsPluginData *priv = gs_plugin_get_data (plugin);
	const gchar *origin;
	guint i;
	g_autoptr(GPtrArray) xremotes = NULL;
	g_autoptr(AsProfileTask) ptask = NULL;

	/* already set */
	origin = gs_app_get_origin_ui (app);
	if (origin != NULL)
		return TRUE;

	/* find list of remotes */
	ptask = as_profile_start_literal (gs_plugin_get_profile (plugin),
					  "xdg-app::refine-origin-ui");
	xremotes = xdg_app_installation_list_remotes (priv->installation,
						      cancellable,
						      error);
	if (xremotes == NULL)
		return FALSE;
	for (i = 0; i < xremotes->len; i++) {
		XdgAppRemote *xremote = g_ptr_array_index (xremotes, i);
		if (g_strcmp0 (gs_app_get_origin (app),
			       xdg_app_remote_get_name (xremote)) == 0) {
			gs_app_set_origin_ui (app, xdg_app_remote_get_title (xremote));
			break;
		}
	}

	return TRUE;
}
Exemplo n.º 12
0
/**
 * gs_plugin_refine_item_size:
 */
static gboolean
gs_plugin_refine_item_size (GsPlugin *plugin,
			    GsApp *app,
			    GCancellable *cancellable,
			    GError **error)
{
	GsPluginData *priv = gs_plugin_get_data (plugin);
	gboolean ret;
	guint64 download_size;
	guint64 installed_size;
	g_autoptr(AsProfileTask) ptask = NULL;
	g_autoptr(GError) error_local = NULL;

	/* already set */
	if (gs_app_get_size_installed (app) > 0 &&
	    gs_app_get_size_download (app) > 0)
		return TRUE;

	/* need commit */
	if (!gs_plugin_refine_item_commit (plugin, app, cancellable, error))
		return FALSE;

	/* need runtime */
	if (!gs_plugin_refine_item_runtime (plugin, app, cancellable, error))
		return FALSE;

	/* calculate the platform size too if the app is not installed */
	if (gs_app_get_state (app) == AS_APP_STATE_AVAILABLE &&
	    gs_app_get_xdgapp_kind (app) == XDG_APP_REF_KIND_APP) {
		GsApp *app_runtime;

		/* find out what runtime the application depends on */
		if (!gs_plugin_refine_item_runtime (plugin,
						    app,
						    cancellable,
						    error))
			return FALSE;

		/* is the app_runtime already installed? */
		app_runtime = gs_app_get_runtime (app);
		if (!gs_plugin_refine_item_state (plugin,
						  app_runtime,
						  cancellable,
						  error))
			return FALSE;
		if (gs_app_get_state (app_runtime) == AS_APP_STATE_INSTALLED) {
			g_debug ("runtime %s is already installed, so not adding size",
				 gs_app_get_id (app_runtime));
		} else {
			if (!gs_plugin_refine_item_size (plugin,
							 app_runtime,
							 cancellable,
							 error))
				return FALSE;
		}
	}

	/* just get the size of the runtime */
	ptask = as_profile_start_literal (gs_plugin_get_profile (plugin),
					  "xdg-app::refine-size");
	ret = xdg_app_installation_fetch_remote_size_sync (priv->installation,
							   gs_app_get_origin (app),
							   gs_app_get_xdgapp_commit (app),
							   &download_size,
							   &installed_size,
							   cancellable, &error_local);
	if (!ret) {
		g_warning ("libxdgapp failed to return application size: %s",
			   error_local->message);
		gs_app_set_size_installed (app, GS_APP_SIZE_UNKNOWABLE);
		gs_app_set_size_download (app, GS_APP_SIZE_UNKNOWABLE);
	} else {
		gs_app_set_size_installed (app, installed_size);
		gs_app_set_size_download (app, download_size);
	}
	return TRUE;
}