Пример #1
0
/**
 * gs_utils_symlink:
 * @target: the full path of the symlink to create
 * @linkpath: where the symlink should point to
 * @error: A #GError, or %NULL
 *
 * Creates a symlink that can cross filesystem boundaries.
 * Any parent directories needed for target to exist are also created.
 *
 * Returns: %TRUE for success
 **/
gboolean
gs_utils_symlink (const gchar *target, const gchar *linkpath, GError **error)
{
	if (!gs_mkdir_parent (target, error))
		return FALSE;
	if (symlink (target, linkpath) != 0) {
		g_set_error (error,
			     GS_PLUGIN_ERROR,
			     GS_PLUGIN_ERROR_WRITE_FAILED,
			     "failed to create symlink from %s to %s",
			     linkpath, target);
		return FALSE;
	}
	return TRUE;
}
Пример #2
0
static gboolean
gs_plugin_steam_download_icon (GsPlugin *plugin,
			       AsApp *app,
			       const gchar *uri,
			       GError **error)
{
	gsize data_len;
	g_autofree gchar *cache_basename = NULL;
	g_autofree gchar *cache_fn = NULL;
	g_autofree gchar *cache_png = NULL;
	g_autofree gchar *data = NULL;
	g_autoptr(AsIcon) icon = NULL;
	g_autoptr(GdkPixbuf) pb = NULL;

	/* download icons from the cdn */
	cache_basename = g_path_get_basename (uri);
	cache_fn = gs_utils_get_cache_filename ("steam",
						cache_basename,
						GS_UTILS_CACHE_FLAG_NONE,
						error);
	if (cache_fn == NULL)
		return FALSE;
	if (g_file_test (cache_fn, G_FILE_TEST_EXISTS)) {
		if (!g_file_get_contents (cache_fn, &data, &data_len, error)) {
			gs_utils_error_convert_gio (error);
			return FALSE;
		}
	} else {
		if (!gs_mkdir_parent (cache_fn, error))
			return FALSE;
		if (!gs_plugin_download_file (plugin,
					      NULL, /* GsApp */
					      uri,
					      cache_fn,
					      NULL, /* GCancellable */
					      error))
			return FALSE;
	}

	/* load the icon as large as possible */
	pb = gdk_pixbuf_new_from_file (cache_fn, error);
	if (pb == NULL) {
		gs_utils_error_convert_gdk_pixbuf (error);
		return FALSE;
	}

	/* too small? */
	if (gdk_pixbuf_get_width (pb) < 48 ||
	    gdk_pixbuf_get_height (pb) < 48) {
		g_set_error (error,
			     GS_PLUGIN_ERROR,
			     GS_PLUGIN_ERROR_INVALID_FORMAT,
			     "icon is too small %ix%i",
			     gdk_pixbuf_get_width (pb),
			     gdk_pixbuf_get_height (pb));
		return FALSE;
	}

	/* save to cache */
	memcpy (cache_basename + 40, ".png\0", 5);
	cache_png = gs_utils_get_cache_filename ("steam",
						 cache_basename,
						 GS_UTILS_CACHE_FLAG_WRITEABLE,
						 error);
	if (cache_png == NULL)
		return FALSE;
	if (!gdk_pixbuf_save (pb, cache_png, "png", error, NULL)) {
		gs_utils_error_convert_gdk_pixbuf (error);
		return FALSE;
	}

	/* add an icon */
	icon = as_icon_new ();
	as_icon_set_kind (icon, AS_ICON_KIND_LOCAL);
	as_icon_set_filename (icon, cache_png);
	as_app_add_icon (app, icon);
	return TRUE;
}
/**
 * gs_plugin_fedora_tagger_load_db:
 */
static gboolean
gs_plugin_fedora_tagger_load_db (GsPlugin *plugin, GError **error)
{
	const gchar *statement;
	gboolean rebuild_ratings = FALSE;
	char *error_msg = NULL;
	gint rc;
	gint64 mtime = 0;
	gint64 now;
	_cleanup_error_free_ GError *error_local = NULL;

	g_debug ("trying to open database '%s'", plugin->priv->db_path);
	if (!gs_mkdir_parent (plugin->priv->db_path, error))
		return FALSE;
	rc = sqlite3_open (plugin->priv->db_path, &plugin->priv->db);
	if (rc != SQLITE_OK) {
		g_set_error (error,
			     GS_PLUGIN_ERROR,
			     GS_PLUGIN_ERROR_FAILED,
			     "Can't open fedora-tagger database: %s",
			     sqlite3_errmsg (plugin->priv->db));
		return FALSE;
	}

	/* we don't need to keep doing fsync */
	sqlite3_exec (plugin->priv->db, "PRAGMA synchronous=OFF",
		      NULL, NULL, NULL);

	/* create ratings if required */
	rc = sqlite3_exec (plugin->priv->db,
			   "SELECT vote_count FROM ratings LIMIT 1",
			   gs_plugin_fedora_tagger_timestamp_cb, &mtime,
			   &error_msg);
	if (rc != SQLITE_OK) {
		g_debug ("creating table to repair: %s", error_msg);
		sqlite3_free (error_msg);
		statement = "DROP TABLE IF EXISTS ratings;";
		sqlite3_exec (plugin->priv->db, statement, NULL, NULL, NULL);
		statement = "CREATE TABLE ratings ("
			    "pkgname TEXT PRIMARY KEY,"
			    "rating INTEGER DEFAULT 0,"
			    "vote_count INTEGER DEFAULT 0,"
			    "user_count INTEGER DEFAULT 0,"
			    "confidence INTEGER DEFAULT 0);";
		sqlite3_exec (plugin->priv->db, statement, NULL, NULL, NULL);
		rebuild_ratings = TRUE;
	}

	/* create timestamps if required */
	rc = sqlite3_exec (plugin->priv->db,
			   "SELECT value FROM timestamps WHERE key = 'mtime' LIMIT 1",
			   gs_plugin_fedora_tagger_timestamp_cb, &mtime,
			   &error_msg);
	if (rc != SQLITE_OK) {
		g_debug ("creating table to repair: %s", error_msg);
		sqlite3_free (error_msg);
		statement = "CREATE TABLE timestamps ("
			    "key TEXT PRIMARY KEY,"
			    "value INTEGER DEFAULT 0);";
		sqlite3_exec (plugin->priv->db, statement, NULL, NULL, NULL);

		/* reset the timestamp */
		if (!gs_plugin_fedora_tagger_set_timestamp (plugin, "ctime", error))
			return FALSE;
	}

	/* no data */
	now = g_get_real_time () / G_USEC_PER_SEC;
	if (mtime == 0 || rebuild_ratings) {
		g_debug ("No fedora-tagger data");
		/* this should not be fatal */
		if (!gs_plugin_fedora_tagger_download (plugin, &error_local)) {
			g_warning ("Failed to get fedora-tagger data: %s",
				   error_local->message);
			return TRUE;
		}
	} else if (now - mtime > GS_PLUGIN_FEDORA_TAGGER_AGE_MAX) {
		g_debug ("fedora-tagger data was %" G_GINT64_FORMAT
			 " days old, so regetting",
			 (now - mtime) / ( 60 * 60 * 24));
		if (!gs_plugin_fedora_tagger_download (plugin, error))
			return FALSE;
	} else {
		g_debug ("fedora-tagger data %" G_GINT64_FORMAT
			 " days old, so no need to redownload",
			 (now - mtime) / ( 60 * 60 * 24));
	}
	return TRUE;
}
static gboolean
load_database (GsPlugin *plugin, GCancellable *cancellable, GError **error)
{
	GsPluginData *priv = gs_plugin_get_data (plugin);
	const gchar *statement;
	gboolean rebuild_ratings = FALSE;
	char *error_msg = NULL;
	gint result;
	gint64 stats_mtime = 0;
	gint64 now;
	g_autoptr(GError) error_local = NULL;

	g_debug ("trying to open database '%s'", priv->db_path);
	if (!gs_mkdir_parent (priv->db_path, error))
		return FALSE;
	result = sqlite3_open (priv->db_path, &priv->db);
	if (result != SQLITE_OK) {
		g_set_error (error,
			     GS_PLUGIN_ERROR,
			     GS_PLUGIN_ERROR_FAILED,
			     "Can't open Ubuntu review statistics database: %s",
			     sqlite3_errmsg (priv->db));
		return FALSE;
	}

	/* We don't need to keep doing fsync */
	sqlite3_exec (priv->db, "PRAGMA synchronous=OFF",
		      NULL, NULL, NULL);

	/* Create a table to store the stats */
	result = sqlite3_exec (priv->db, "SELECT * FROM review_stats LIMIT 1", NULL, NULL, &error_msg);
	if (result != SQLITE_OK) {
		g_debug ("creating table to repair: %s", error_msg);
		sqlite3_free (error_msg);
		statement = "CREATE TABLE review_stats ("
			    "package_name TEXT PRIMARY KEY,"
			    "one_star_count INTEGER DEFAULT 0,"
			    "two_star_count INTEGER DEFAULT 0,"
			    "three_star_count INTEGER DEFAULT 0,"
			    "four_star_count INTEGER DEFAULT 0,"
			    "five_star_count INTEGER DEFAULT 0);";
		sqlite3_exec (priv->db, statement, NULL, NULL, NULL);
		rebuild_ratings = TRUE;
	}

	/* Create a table to store local reviews */
	result = sqlite3_exec (priv->db, "SELECT * FROM reviews LIMIT 1", NULL, NULL, &error_msg);
	if (result != SQLITE_OK) {
		g_debug ("creating table to repair: %s", error_msg);
		sqlite3_free (error_msg);
		statement = "CREATE TABLE reviews ("
			    "package_name TEXT PRIMARY KEY,"
			    "id TEXT,"
			    "version TEXT,"
			    "date TEXT,"
			    "rating INTEGER,"
			    "summary TEXT,"
			    "text TEXT);";
		sqlite3_exec (priv->db, statement, NULL, NULL, NULL);
		rebuild_ratings = TRUE;
	}

	/* Create a table to store timestamps */
	result = sqlite3_exec (priv->db,
			       "SELECT value FROM timestamps WHERE key = 'stats_mtime' LIMIT 1",
			       get_timestamp_sqlite_cb, &stats_mtime,
			       &error_msg);
	if (result != SQLITE_OK) {
		g_debug ("creating table to repair: %s", error_msg);
		sqlite3_free (error_msg);
		statement = "CREATE TABLE timestamps ("
			    "key TEXT PRIMARY KEY,"
			    "value INTEGER DEFAULT 0);";
		sqlite3_exec (priv->db, statement, NULL, NULL, NULL);

		/* Set the time of database creation */
		if (!set_timestamp (plugin, "stats_ctime", error))
			return FALSE;
	}

	/* Download data if we have none or it is out of date */
	now = g_get_real_time () / G_USEC_PER_SEC;
	if (stats_mtime == 0 || rebuild_ratings) {
		g_debug ("No Ubuntu review statistics");
		if (!download_review_stats (plugin, cancellable, &error_local)) {
			g_warning ("Failed to get Ubuntu review statistics: %s",
				   error_local->message);
			return TRUE;
		}
	} else if (now - stats_mtime > REVIEW_STATS_AGE_MAX) {
		g_debug ("Ubuntu review statistics was %" G_GINT64_FORMAT
			 " days old, so regetting",
			 (now - stats_mtime) / ( 60 * 60 * 24));
		if (!download_review_stats (plugin, cancellable, error))
			return FALSE;
	} else {
		g_debug ("Ubuntu review statistics %" G_GINT64_FORMAT
			 " days old, so no need to redownload",
			 (now - stats_mtime) / ( 60 * 60 * 24));
	}
	return TRUE;
}