static gboolean gs_plugin_fedora_distro_upgrades_refresh (GsPlugin *plugin, guint cache_age, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); /* check cache age */ if (cache_age > 0) { guint tmp; g_autoptr(GFile) file = g_file_new_for_path (priv->cachefn); tmp = gs_utils_get_file_age (file); if (tmp < cache_age) { g_debug ("%s is only %u seconds old", priv->cachefn, tmp); return TRUE; } } /* download new file */ if (!gs_plugin_download_file (plugin, NULL, FEDORA_PKGDB_COLLECTIONS_API_URI, priv->cachefn, cancellable, error)) { gs_utils_error_add_unique_id (error, priv->cached_origin); return FALSE; } /* success */ return TRUE; }
static gboolean gs_plugin_fwupd_install (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); const gchar *device_id; FwupdInstallFlags install_flags = 0; GFile *local_file; g_autofree gchar *filename = NULL; /* not set */ local_file = gs_app_get_local_file (app); if (local_file == NULL) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "not enough data for fwupd %s", filename); return FALSE; } /* file does not yet exist */ filename = g_file_get_path (local_file); if (!g_file_query_exists (local_file, cancellable)) { const gchar *uri = gs_fwupd_app_get_update_uri (app); gs_app_set_state (app, AS_APP_STATE_INSTALLING); if (!gs_plugin_download_file (plugin, app, uri, filename, cancellable, error)) return FALSE; } /* limit to single device? */ device_id = gs_fwupd_app_get_device_id (app); if (device_id == NULL) device_id = FWUPD_DEVICE_ID_ANY; /* set the last object */ g_set_object (&priv->app_current, app); /* only offline supported */ if (gs_app_get_metadata_item (app, "fwupd::OnlyOffline") != NULL) install_flags |= FWUPD_INSTALL_FLAG_OFFLINE; gs_app_set_state (app, AS_APP_STATE_INSTALLING); if (!fwupd_client_install (priv->client, device_id, filename, install_flags, cancellable, error)) { gs_plugin_fwupd_error_convert (error); gs_app_set_state_recover (app); return FALSE; } /* delete the file from the cache */ gs_app_set_state (app, AS_APP_STATE_INSTALLED); return g_file_delete (local_file, cancellable, error); }
static gboolean gs_plugin_odrs_refresh_ratings (GsPlugin *plugin, guint cache_age, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); g_autofree gchar *fn = NULL; g_autofree gchar *uri = NULL; g_autoptr(GsApp) app_dl = gs_app_new (gs_plugin_get_name (plugin)); /* check cache age */ fn = gs_utils_get_cache_filename ("ratings", "odrs.json", GS_UTILS_CACHE_FLAG_WRITEABLE, error); if (fn == NULL) return FALSE; if (cache_age > 0) { guint tmp; g_autoptr(GFile) file = NULL; file = g_file_new_for_path (fn); tmp = gs_utils_get_file_age (file); if (tmp < cache_age) { g_debug ("%s is only %u seconds old, so ignoring refresh", fn, tmp); return gs_plugin_odrs_load_ratings (plugin, fn, error); } } /* download the complete file */ uri = g_strdup_printf ("%s/ratings", priv->review_server); if (!gs_plugin_download_file (plugin, app_dl, uri, fn, cancellable, error)) { gs_utils_error_add_unique_id (error, priv->cached_origin); return FALSE; } return gs_plugin_odrs_load_ratings (plugin, fn, error); }
gboolean gs_plugin_download_app (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { GFile *local_file; g_autofree gchar *filename = 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; /* not set */ local_file = gs_app_get_local_file (app); if (local_file == NULL) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "not enough data for fwupd %s", filename); return FALSE; } /* file does not yet exist */ filename = g_file_get_path (local_file); if (!g_file_query_exists (local_file, cancellable)) { const gchar *uri = gs_fwupd_app_get_update_uri (app); if (!gs_plugin_download_file (plugin, app, uri, filename, cancellable, error)) return FALSE; } gs_app_set_size_download (app, 0); return TRUE; }
static gboolean gs_plugin_fwupd_refresh_remote (GsPlugin *plugin, FwupdRemote *remote, guint cache_age, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); GChecksumType checksum_kind; const gchar *url_sig = NULL; const gchar *url = NULL; g_autoptr(GError) error_local = NULL; g_autofree gchar *basename = NULL; g_autofree gchar *basename_sig = NULL; g_autofree gchar *cache_id = NULL; g_autofree gchar *checksum = NULL; g_autofree gchar *filename = NULL; g_autofree gchar *filename_sig = NULL; g_autoptr(GBytes) data = NULL; g_autoptr(GsApp) app_dl = gs_app_new (gs_plugin_get_name (plugin)); /* sanity check */ if (fwupd_remote_get_filename_cache_sig (remote) == NULL) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "remote %s has no cache signature", fwupd_remote_get_id (remote)); return FALSE; } /* check cache age */ if (cache_age > 0) { guint64 age = fwupd_remote_get_age (remote); guint tmp = age < G_MAXUINT ? (guint) age : G_MAXUINT; if (tmp < cache_age) { g_debug ("%s is only %u seconds old, so ignoring refresh", filename_sig, tmp); return TRUE; } } /* download the signature first, it's smaller */ cache_id = g_strdup_printf ("fwupd/remotes.d/%s", fwupd_remote_get_id (remote)); basename_sig = g_path_get_basename (fwupd_remote_get_filename_cache_sig (remote)); filename_sig = gs_utils_get_cache_filename (cache_id, basename_sig, GS_UTILS_CACHE_FLAG_WRITEABLE, error); /* download the signature first, it's smaller */ url_sig = fwupd_remote_get_metadata_uri_sig (remote); gs_app_set_summary_missing (app_dl, /* TRANSLATORS: status text when downloading */ _("Downloading firmware update signature…")); data = gs_plugin_download_data (plugin, app_dl, url_sig, cancellable, error); if (data == NULL) { gs_utils_error_add_origin_id (error, priv->cached_origin); return FALSE; } /* is the signature hash the same as we had before? */ checksum_kind = fwupd_checksum_guess_kind (fwupd_remote_get_checksum (remote)); checksum = g_compute_checksum_for_data (checksum_kind, (const guchar *) g_bytes_get_data (data, NULL), g_bytes_get_size (data)); if (g_strcmp0 (checksum, fwupd_remote_get_checksum (remote)) == 0) { g_debug ("signature of %s is unchanged", url_sig); return TRUE; } /* save to a file */ g_debug ("saving new remote signature to %s:", filename_sig); if (!g_file_set_contents (filename_sig, g_bytes_get_data (data, NULL), (guint) g_bytes_get_size (data), &error_local)) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_WRITE_FAILED, "Failed to save firmware signature: %s", error_local->message); return FALSE; } /* download the payload and save to file */ basename = g_path_get_basename (fwupd_remote_get_filename_cache (remote)); filename = gs_utils_get_cache_filename (cache_id, basename, GS_UTILS_CACHE_FLAG_WRITEABLE, error); if (filename == NULL) return FALSE; g_debug ("saving new firmware metadata to %s:", filename); gs_app_set_summary_missing (app_dl, /* TRANSLATORS: status text when downloading */ _("Downloading firmware update metadata…")); url = fwupd_remote_get_metadata_uri (remote); if (!gs_plugin_download_file (plugin, app_dl, url, filename, cancellable, error)) { gs_utils_error_add_origin_id (error, priv->cached_origin); return FALSE; } /* phew, lets send all this to fwupd */ if (!fwupd_client_update_metadata (priv->client, fwupd_remote_get_id (remote), filename, filename_sig, cancellable, error)) { gs_plugin_fwupd_error_convert (error); return FALSE; } return TRUE; }
static gboolean gs_plugin_steam_update_store_app (GsPlugin *plugin, AsStore *store, GHashTable *app, GError **error) { const gchar *name; GVariant *tmp; guint32 gameid; gchar *app_id; g_autofree gchar *cache_basename = NULL; g_autofree gchar *cache_fn = NULL; g_autofree gchar *gameid_str = NULL; g_autofree gchar *html = NULL; g_autofree gchar *uri = NULL; g_autoptr(AsApp) item = NULL; /* this is the key */ tmp = g_hash_table_lookup (app, "gameid"); if (tmp == NULL) return TRUE; gameid = g_variant_get_uint32 (tmp); /* valve use the name as the application ID, not the gameid */ tmp = g_hash_table_lookup (app, "name"); if (tmp == NULL) return TRUE; name = g_variant_get_string (tmp, NULL); app_id = g_strdup_printf ("%s.desktop", name); /* already exists */ if (as_store_get_app_by_id (store, app_id) != NULL) { g_debug ("already exists %" G_GUINT32_FORMAT ", skipping", gameid); return TRUE; } /* create application with the gameid as the key */ g_debug ("parsing steam %" G_GUINT32_FORMAT, gameid); item = as_app_new (); as_app_set_kind (item, AS_APP_KIND_DESKTOP); as_app_set_project_license (item, "Steam"); as_app_set_id (item, app_id); as_app_set_name (item, NULL, name); as_app_add_category (item, "Game"); as_app_add_kudo_kind (item, AS_KUDO_KIND_MODERN_TOOLKIT); as_app_set_comment (item, NULL, "Available on Steam"); /* this is for the GNOME Software plugin */ gameid_str = g_strdup_printf ("%" G_GUINT32_FORMAT, gameid); as_app_add_metadata (item, "X-Steam-GameID", gameid_str); as_app_add_metadata (item, "GnomeSoftware::Plugin", "steam"); /* ban certains apps based on the name */ if (g_strstr_len (name, -1, "Dedicated Server") != NULL) as_app_add_veto (item, "Dedicated Server"); /* oslist */ tmp = g_hash_table_lookup (app, "oslist"); if (tmp == NULL) { as_app_add_veto (item, "No operating systems listed"); } else if (g_strstr_len (g_variant_get_string (tmp, NULL), -1, "linux") == NULL) { as_app_add_veto (item, "No Linux support"); } /* url: homepage */ tmp = g_hash_table_lookup (app, "homepage"); if (tmp != NULL) as_app_add_url (item, AS_URL_KIND_HOMEPAGE, g_variant_get_string (tmp, NULL)); /* developer name */ tmp = g_hash_table_lookup (app, "developer"); if (tmp != NULL) as_app_set_developer_name (item, NULL, g_variant_get_string (tmp, NULL)); /* type */ tmp = g_hash_table_lookup (app, "type"); if (tmp != NULL) { const gchar *kind = g_variant_get_string (tmp, NULL); if (g_strcmp0 (kind, "DLC") == 0 || g_strcmp0 (kind, "Config") == 0 || g_strcmp0 (kind, "Tool") == 0) as_app_add_veto (item, "type is %s", kind); } /* don't bother saving apps with failures */ if (as_app_get_vetos(item)->len > 0) return TRUE; /* icons */ tmp = g_hash_table_lookup (app, "clienticns"); if (tmp != NULL) { g_autoptr(GError) error_local = NULL; g_autofree gchar *ic_uri = NULL; ic_uri = g_strdup_printf ("https://steamcdn-a.akamaihd.net/steamcommunity/public/images/apps/%" G_GUINT32_FORMAT "/%s.icns", gameid, g_variant_get_string (tmp, NULL)); if (!gs_plugin_steam_download_icon (plugin, item, ic_uri, &error_local)) { g_warning ("Failed to parse clienticns: %s", error_local->message); } } /* try clienticon */ if (as_app_get_icons(item)->len == 0) { tmp = g_hash_table_lookup (app, "clienticon"); if (tmp != NULL) { g_autoptr(GError) error_local = NULL; g_autofree gchar *ic_uri = NULL; ic_uri = g_strdup_printf ("http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/%" G_GUINT32_FORMAT "/%s.ico", gameid, g_variant_get_string (tmp, NULL)); if (!gs_plugin_steam_download_icon (plugin, item, ic_uri, &error_local)) { g_warning ("Failed to parse clienticon: %s", error_local->message); } } } /* fall back to a resized logo */ if (as_app_get_icons(item)->len == 0) { tmp = g_hash_table_lookup (app, "logo"); if (tmp != NULL) { AsIcon *icon = NULL; g_autofree gchar *ic_uri = NULL; ic_uri = g_strdup_printf ("http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/%" G_GUINT32_FORMAT "/%s.jpg", gameid, g_variant_get_string (tmp, NULL)); icon = as_icon_new (); as_icon_set_kind (icon, AS_ICON_KIND_REMOTE); as_icon_set_url (icon, ic_uri); as_app_add_icon (item, icon); } } /* size */ tmp = g_hash_table_lookup (app, "maxsize"); if (tmp != NULL) { /* string when over 16Gb... :/ */ if (g_strcmp0 (g_variant_get_type_string (tmp), "u") == 0) { g_autofree gchar *val = NULL; val = g_strdup_printf ("%" G_GUINT32_FORMAT, g_variant_get_uint32 (tmp)); as_app_add_metadata (item, "X-Steam-Size", val); } else { as_app_add_metadata (item, "X-Steam-Size", g_variant_get_string (tmp, NULL)); } } /* download page from the store */ cache_basename = g_strdup_printf ("%s.html", gameid_str); cache_fn = gs_utils_get_cache_filename ("steam", cache_basename, GS_UTILS_CACHE_FLAG_WRITEABLE, error); if (cache_fn == NULL) return FALSE; if (!g_file_test (cache_fn, G_FILE_TEST_EXISTS)) { g_autoptr(GsApp) app_dl = gs_app_new (gs_plugin_get_name (plugin)); uri = g_strdup_printf ("http://store.steampowered.com/app/%s/", gameid_str); if (!gs_plugin_download_file (plugin, app_dl, uri, cache_fn, NULL, /* GCancellable */ error)) return FALSE; } /* get screenshots and descriptions */ if (!g_file_get_contents (cache_fn, &html, NULL, error)) { gs_utils_error_convert_gio (error); return FALSE; } if (!gs_plugin_steam_update_screenshots (item, html, error)) return FALSE; if (!gs_plugin_steam_update_description (item, html, error)) return FALSE; /* add */ as_store_add_app (store, item); 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; }