/** * 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; }
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; }