/**
 * as_app_validate_release:
 **/
static gboolean
as_app_validate_release (AsRelease *release, AsAppValidateHelper *helper, GError **error)
{
	const gchar *tmp;
	guint64 timestamp;
	guint number_para_max = 2;
	guint number_para_min = 1;

	/* relax the requirements a bit */
	if ((helper->flags & AS_APP_VALIDATE_FLAG_RELAX) > 0) {
		number_para_max = 4;
	}

	/* check version */
	tmp = as_release_get_version (release);
	if (tmp == NULL) {
		ai_app_validate_add (helper->probs,
				     AS_PROBLEM_KIND_ATTRIBUTE_MISSING,
				     "<release> has no version");
	}

	/* check timestamp */
	timestamp = as_release_get_timestamp (release);
	if (timestamp == 0) {
		ai_app_validate_add (helper->probs,
				     AS_PROBLEM_KIND_ATTRIBUTE_MISSING,
				     "<release> has no timestamp");
	}
	if (timestamp > 20120101 && timestamp < 20151231) {
		ai_app_validate_add (helper->probs,
				     AS_PROBLEM_KIND_ATTRIBUTE_INVALID,
				     "<release> timestamp should be a UNIX time");
	}

	/* check description */
	tmp = as_release_get_description (release, "C");
	if (tmp == NULL) {
		ai_app_validate_add (helper->probs,
				     AS_PROBLEM_KIND_ATTRIBUTE_MISSING,
				     "<release> has no description");
	} else {
		if (as_app_validate_has_hyperlink (tmp)) {
			ai_app_validate_add (helper->probs,
					     AS_PROBLEM_KIND_STYLE_INCORRECT,
					     "<release> description should be "
					     "prose and not contain hyperlinks");
		}
		if (!as_app_validate_description (tmp,
						  helper,
						  number_para_min,
						  number_para_max,
						  error))
			return FALSE;
	}
	return TRUE;
}
Exemplo n.º 2
0
/**
 * gs_appstream_is_recent_release:
 */
static gboolean
gs_appstream_is_recent_release (AsApp *app)
{
	AsRelease *release;
	GPtrArray *releases;
	guint secs;

	/* get newest release */
	releases = as_app_get_releases (app);
	if (releases->len == 0)
		return FALSE;
	release = g_ptr_array_index (releases, 0);

	/* is last build less than one year ago? */
	secs = (g_get_real_time () / G_USEC_PER_SEC) -
		as_release_get_timestamp (release);
	return secs / (60 * 60 * 24) < 365;
}
/**
 * cra_plugin_process_app:
 */
gboolean
cra_plugin_process_app (CraPlugin *plugin,
			CraPackage *pkg,
			CraApp *app,
			const gchar *tmpdir,
			GError **error)
{
	const gchar *tmp;
	AsRelease *release;
	gchar **deps;
	gchar **filelist;
	GPtrArray *releases;
	guint i;
	guint secs;
	guint days;

	/* add extra categories */
	tmp = as_app_get_id (AS_APP (app));
	if (g_strcmp0 (tmp, "0install") == 0)
		as_app_add_category (AS_APP (app), "System", -1);
	if (g_strcmp0 (tmp, "alacarte") == 0)
		as_app_add_category (AS_APP (app), "System", -1);
	if (g_strcmp0 (tmp, "deja-dup") == 0)
		as_app_add_category (AS_APP (app), "Utility", -1);
	if (g_strcmp0 (tmp, "gddccontrol") == 0)
		as_app_add_category (AS_APP (app), "System", -1);
	if (g_strcmp0 (tmp, "nautilus") == 0)
		as_app_add_category (AS_APP (app), "System", -1);
	if (g_strcmp0 (tmp, "pessulus") == 0)
		as_app_add_category (AS_APP (app), "System", -1);
	if (g_strcmp0 (tmp, "pmdefaults") == 0)
		as_app_add_category (AS_APP (app), "System", -1);
	if (g_strcmp0 (tmp, "fwfstab") == 0)
		as_app_add_category (AS_APP (app), "System", -1);

	/* add extra project groups */
	if (g_strcmp0 (tmp, "nemo") == 0)
		as_app_set_project_group (AS_APP (app), "Cinnamon", -1);
	if (g_strcmp0 (tmp, "xfdashboard") == 0)
		as_app_set_project_group (AS_APP (app), "XFCE", -1);

	/* use the URL to guess the project group */
	tmp = cra_package_get_url (pkg);
	if (as_app_get_project_group (AS_APP (app)) == NULL && tmp != NULL) {
		tmp = cra_glob_value_search (plugin->priv->project_groups, tmp);
		if (tmp != NULL)
			as_app_set_project_group (AS_APP (app), tmp, -1);
	}

	/* use summary to guess the project group */
	tmp = as_app_get_comment (AS_APP (app), NULL);
	if (tmp != NULL && g_strstr_len (tmp, -1, "for KDE") != NULL)
		as_app_set_project_group (AS_APP (app), "KDE", -1);

	/* look for any installed docs */
	filelist = cra_package_get_filelist (pkg);
	for (i = 0; filelist[i] != NULL; i++) {
		if (g_str_has_prefix (filelist[i],
				      "/usr/share/help/")) {
			as_app_add_metadata (AS_APP (app),
					     "X-Kudo-InstallsUserDocs", "", -1);
			break;
		}
	}

	/* look for a shell search provider */
	for (i = 0; filelist[i] != NULL; i++) {
		if (g_str_has_prefix (filelist[i],
				      "/usr/share/gnome-shell/search-providers/")) {
			as_app_add_metadata (AS_APP (app),
					     "X-Kudo-SearchProvider", "", -1);
			break;
		}
	}

	/* look for a modern toolkit */
	deps = cra_package_get_deps (pkg);
	for (i = 0; deps != NULL && deps[i] != NULL; i++) {
		if (g_strcmp0 (deps[i], "libgtk-3.so.0") == 0) {
			as_app_add_metadata (AS_APP (app),
					     "X-Kudo-GTK3", "", -1);
			break;
		}
		if (g_strcmp0 (deps[i], "libQt5Core.so.5") == 0) {
			as_app_add_metadata (AS_APP (app),
					     "X-Kudo-QT5", "", -1);
			break;
		}
	}

	/* look for ancient toolkits */
	for (i = 0; deps != NULL && deps[i] != NULL; i++) {
		if (g_strcmp0 (deps[i], "libgtk-1.2.so.0") == 0) {
			cra_app_add_veto (app, "Uses obsolete GTK1 toolkit");
			break;
		}
		if (g_strcmp0 (deps[i], "libqt-mt.so.3") == 0) {
			cra_app_add_veto (app, "Uses obsolete QT3 toolkit");
			break;
		}
		if (g_strcmp0 (deps[i], "liblcms.so.1") == 0) {
			cra_app_add_veto (app, "Uses obsolete LCMS library");
			break;
		}
		if (g_strcmp0 (deps[i], "libelektra.so.4") == 0) {
			cra_app_add_veto (app, "Uses obsolete Elektra library");
			break;
		}
		if (g_strcmp0 (deps[i], "libXt.so.6") == 0) {
			cra_app_add_requires_appdata (app, "Uses obsolete X11 toolkit");
			break;
		}
		if (g_strcmp0 (deps[i], "wine-core") == 0) {
			cra_app_add_requires_appdata (app, "Uses wine");
			break;
		}
	}

	/* has the application been updated in the last year */
	releases = as_app_get_releases (AS_APP (app));
	for (i = 0; i < releases->len; i++) {
		release = g_ptr_array_index (releases, i);
		secs = (g_get_real_time () / G_USEC_PER_SEC) -
			as_release_get_timestamp (release);
		days = secs / (60 * 60 * 24);
		if (days < 365) {
			as_app_add_metadata (AS_APP (app),
					     "X-Kudo-RecentRelease", "", -1);
			break;
		}
	}

	/* has there been no upstream version recently */
	if (releases->len > 0 &&
	    as_app_get_id_kind (AS_APP (app)) == AS_ID_KIND_DESKTOP) {
		release = g_ptr_array_index (releases, 0);
		secs = (g_get_real_time () / G_USEC_PER_SEC) -
			as_release_get_timestamp (release);
		days = secs / (60 * 60 * 24);

		/* this is just too old for us to care about */
		if (days > 365 * 10) {
			cra_app_add_veto (app, "Dead upstream for %i years",
					  secs / (60 * 60 * 24 * 365));
		}

		/* we need AppData if the app needs saving */
		else if (days > 365 * 5) {
			cra_app_add_requires_appdata (app,
				"Dead upstream for > %i years", 5);
		}
	}

	/* do any extra screenshots exist */
	tmp = cra_package_get_config (pkg, "ScreenshotsExtra");
	if (tmp != NULL) {
		_cleanup_free_ gchar *dirname = NULL;
		dirname = g_build_filename (tmp, as_app_get_id (AS_APP (app)), NULL);
		if (g_file_test (dirname, G_FILE_TEST_EXISTS)) {
			if (!cra_plugin_hardcoded_add_screenshots (app, dirname, error))
				return FALSE;
		}
	}

	/* a ConsoleOnly category means we require AppData */
	if (as_app_has_category (AS_APP(app), "ConsoleOnly"))
		cra_app_add_requires_appdata (app, "ConsoleOnly");

	/* no categories means we require AppData */
	if (as_app_get_categories(AS_APP(app))->len == 0)
		cra_app_add_requires_appdata (app, "no Categories");

	return TRUE;
}
Exemplo n.º 4
0
static gboolean
as_app_validate_release (AsApp *app,
			 AsRelease *release,
			 AsAppValidateHelper *helper,
			 GError **error)
{
	const gchar *tmp;
	guint64 timestamp;
	guint number_para_max = 10;
	guint number_para_min = 1;
	gboolean required_timestamp = TRUE;

	/* relax the requirements a bit */
	if ((helper->flags & AS_APP_VALIDATE_FLAG_RELAX) > 0) {
		number_para_max = 20;
		required_timestamp = FALSE;
	}

	/* make the requirements more strict */
	if ((helper->flags & AS_APP_VALIDATE_FLAG_STRICT) > 0) {
		number_para_max = 4;
	}

	/* check version */
	tmp = as_release_get_version (release);
	if (tmp == NULL) {
		ai_app_validate_add (helper,
				     AS_PROBLEM_KIND_ATTRIBUTE_MISSING,
				     "<release> has no version");
	}

	/* check timestamp */
	timestamp = as_release_get_timestamp (release);
	if (required_timestamp && timestamp == 0) {
		ai_app_validate_add (helper,
				     AS_PROBLEM_KIND_ATTRIBUTE_MISSING,
				     "<release> has no timestamp");
	}
	if (timestamp > 20120101 && timestamp < 20251231) {
		ai_app_validate_add (helper,
				     AS_PROBLEM_KIND_ATTRIBUTE_INVALID,
				     "<release> timestamp should be a UNIX time");
	}

	/* check the timestamp is not in the future */
	if (timestamp > (guint64) g_get_real_time () / G_USEC_PER_SEC) {
		ai_app_validate_add (helper,
				     AS_PROBLEM_KIND_ATTRIBUTE_INVALID,
				     "<release> timestamp is in the future");
	}

	/* for firmware, check urgency */
	if (as_app_get_kind (app) == AS_APP_KIND_FIRMWARE &&
	    as_release_get_urgency (release) == AS_URGENCY_KIND_UNKNOWN) {
		ai_app_validate_add (helper,
				     AS_PROBLEM_KIND_ATTRIBUTE_INVALID,
				     "<release> urgency is required for firmware");
	}

	/* check description */
	tmp = as_release_get_description (release, "C");
	if (tmp != NULL) {
		if (as_app_validate_has_hyperlink (tmp)) {
			ai_app_validate_add (helper,
					     AS_PROBLEM_KIND_STYLE_INCORRECT,
					     "<release> description should be "
					     "prose and not contain hyperlinks [%s]",
					     tmp);
		}
		if (!as_app_validate_description (tmp,
						  helper,
						  number_para_min,
						  number_para_max,
						  TRUE,
						  error))
			return FALSE;
	}
	return TRUE;
}
/**
 * asb_plugin_process_app:
 */
gboolean
asb_plugin_process_app (AsbPlugin *plugin,
			AsbPackage *pkg,
			AsbApp *app,
			const gchar *tmpdir,
			GError **error)
{
	const gchar *tmp;
	AsRelease *release;
	GPtrArray *deps;
	gchar **filelist;
	GPtrArray *releases;
	guint i;
	gint64 secs;
	guint days;

	/* add extra categories */
	tmp = as_app_get_id (AS_APP (app));
	if (g_strcmp0 (tmp, "0install.desktop") == 0)
		as_app_add_category (AS_APP (app), "System", -1);
	if (g_strcmp0 (tmp, "alacarte.desktop") == 0)
		as_app_add_category (AS_APP (app), "System", -1);
	if (g_strcmp0 (tmp, "deja-dup.desktop") == 0)
		as_app_add_category (AS_APP (app), "Utility", -1);
	if (g_strcmp0 (tmp, "gddccontrol.desktop") == 0)
		as_app_add_category (AS_APP (app), "System", -1);
	if (g_strcmp0 (tmp, "nautilus.desktop") == 0)
		as_app_add_category (AS_APP (app), "System", -1);
	if (g_strcmp0 (tmp, "pessulus.desktop") == 0)
		as_app_add_category (AS_APP (app), "System", -1);
	if (g_strcmp0 (tmp, "pmdefaults.desktop") == 0)
		as_app_add_category (AS_APP (app), "System", -1);
	if (g_strcmp0 (tmp, "fwfstab.desktop") == 0)
		as_app_add_category (AS_APP (app), "System", -1);
	if (g_strcmp0 (tmp, "bmpanel2cfg.desktop") == 0)
		as_app_add_category (AS_APP (app), "System", -1);
	if (g_strcmp0 (tmp, "wallpapoz.desktop") == 0)
		as_app_add_category (AS_APP (app), "System", -1);
	if (g_strcmp0 (tmp, "superkaramba.desktop") == 0)
		as_app_add_category (AS_APP (app), "System", -1);

	/* add extra project groups */
	if (g_strcmp0 (tmp, "nemo.desktop") == 0)
		as_app_set_project_group (AS_APP (app), "Cinnamon", -1);
	if (g_strcmp0 (tmp, "xfdashboard.desktop") == 0)
		as_app_set_project_group (AS_APP (app), "XFCE", -1);

	/* use the URL to guess the project group */
	tmp = asb_package_get_url (pkg);
	if (as_app_get_project_group (AS_APP (app)) == NULL && tmp != NULL) {
		tmp = asb_glob_value_search (plugin->priv->project_groups, tmp);
		if (tmp != NULL)
			as_app_set_project_group (AS_APP (app), tmp, -1);
	}

	/* use summary to guess the project group */
	tmp = as_app_get_comment (AS_APP (app), NULL);
	if (tmp != NULL && g_strstr_len (tmp, -1, "for KDE") != NULL)
		as_app_set_project_group (AS_APP (app), "KDE", -1);

	/* look for any installed docs */
	filelist = asb_package_get_filelist (pkg);
	for (i = 0; filelist[i] != NULL; i++) {
		if (asb_plugin_match_glob ("/usr/share/help/*", filelist[i])) {
			as_app_add_kudo_kind (AS_APP (app),
					      AS_KUDO_KIND_USER_DOCS);
			break;
		}
	}

	/* look for a shell search provider */
	for (i = 0; filelist[i] != NULL; i++) {
		if (asb_plugin_match_glob ("/usr/share/gnome-shell/search-providers/*",
					   filelist[i])) {
			as_app_add_kudo_kind (AS_APP (app),
					      AS_KUDO_KIND_SEARCH_PROVIDER);
			break;
		}
	}

	/* look for a high contrast icon */
	for (i = 0; filelist[i] != NULL; i++) {
		if (asb_plugin_match_glob ("/usr/share/icons/HighContrast/*",
					   filelist[i])) {
			as_app_add_kudo_kind (AS_APP (app),
					      AS_KUDO_KIND_HIGH_CONTRAST);
			break;
		}
		if (asb_plugin_match_glob ("/usr/share/icons/hicolor/symbolic/apps/*.svg",
					   filelist[i])) {
			as_app_add_kudo_kind (AS_APP (app),
					      AS_KUDO_KIND_HIGH_CONTRAST);
			break;
		}
	}

	/* look for a modern toolkit */
	deps = asb_package_get_deps (pkg);
	for (i = 0; i < deps->len; i++) {
		tmp = g_ptr_array_index (deps, i);
		if (g_strcmp0 (tmp, "libgtk-3.so.0") == 0 ||
		    g_strcmp0 (tmp, "libQt5Core.so.5") == 0) {
			as_app_add_kudo_kind (AS_APP (app),
					      AS_KUDO_KIND_MODERN_TOOLKIT);
			break;
		}
	}

	/* look for ancient toolkits */
	for (i = 0; i < deps->len; i++) {
		tmp = g_ptr_array_index (deps, i);
		if (g_strcmp0 (tmp, "libgtk-1.2.so.0") == 0) {
			as_app_add_veto (AS_APP (app), "Uses obsolete GTK1 toolkit");
			break;
		}
		if (g_strcmp0 (tmp, "libglib-1.2.so.0") == 0) {
			as_app_add_veto (AS_APP (app), "Uses obsolete GLib library");
			break;
		}
		if (g_strcmp0 (tmp, "libqt-mt.so.3") == 0) {
			as_app_add_veto (AS_APP (app), "Uses obsolete QT3 toolkit");
			break;
		}
		if (g_strcmp0 (tmp, "liblcms.so.1") == 0) {
			as_app_add_veto (AS_APP (app), "Uses obsolete LCMS library");
			break;
		}
		if (g_strcmp0 (tmp, "libelektra.so.4") == 0) {
			as_app_add_veto (AS_APP (app), "Uses obsolete Elektra library");
			break;
		}
		if (g_strcmp0 (tmp, "libXt.so.6") == 0) {
			asb_app_add_requires_appdata (app, "Uses obsolete X11 toolkit");
			break;
		}
		if (g_strcmp0 (tmp, "Xvfb") == 0) {
			asb_app_add_requires_appdata (app, "Uses obsolete Xvfb");
			break;
		}
		if (g_strcmp0 (tmp, "wine-core") == 0) {
			asb_app_add_requires_appdata (app, "Uses wine");
			break;
		}
	}

	/* has the application been updated in the last year */
	releases = as_app_get_releases (AS_APP (app));
	if (asb_context_get_api_version (plugin->ctx) < 0.8) {
		for (i = 0; i < releases->len; i++) {
			release = g_ptr_array_index (releases, i);
			secs = (g_get_real_time () / G_USEC_PER_SEC) -
				as_release_get_timestamp (release);
			days = secs / (60 * 60 * 24);
			if (secs > 0 && days < 365) {
				as_app_add_metadata (AS_APP (app),
						     "X-Kudo-RecentRelease", "", -1);
				break;
			}
		}
	}

	/* has there been no upstream version recently */
	if (releases->len > 0 &&
	    as_app_get_id_kind (AS_APP (app)) == AS_ID_KIND_DESKTOP) {
		release = g_ptr_array_index (releases, 0);
		secs = (g_get_real_time () / G_USEC_PER_SEC) -
			as_release_get_timestamp (release);
		days = secs / (60 * 60 * 24);
		/* we need AppData if the app needs saving */
		if (secs > 0 && days > 365 * 5) {
			asb_app_add_requires_appdata (app,
				"Dead upstream for > %i years", 5);
		}
	}

	/* a ConsoleOnly category means we require AppData */
	if (as_app_has_category (AS_APP(app), "ConsoleOnly"))
		asb_app_add_requires_appdata (app, "ConsoleOnly");

	/* no categories means we require AppData */
	if (as_app_get_id_kind (AS_APP (app)) == AS_ID_KIND_DESKTOP &&
	    as_app_get_categories(AS_APP(app))->len == 0)
		asb_app_add_requires_appdata (app, "no Categories");

	return TRUE;
}