/** * gs_plugin_xdg_app_reviews_invalidate_cache: */ static gboolean gs_plugin_xdg_app_reviews_invalidate_cache (GsReview *review, GError **error) { g_autofree gchar *cachedir = NULL; g_autofree gchar *cachefn = NULL; g_autoptr(GFile) cachefn_file = NULL; /* look in the cache */ cachedir = gs_utils_get_cachedir ("reviews", error); if (cachedir == NULL) return FALSE; cachefn = g_strdup_printf ("%s/%s.json", cachedir, gs_review_get_metadata_item (review, "app_id")); cachefn_file = g_file_new_for_path (cachefn); if (!g_file_query_exists (cachefn_file, NULL)) return TRUE; return g_file_delete (cachefn_file, NULL, error); }
/** * gs_refine_item_pixbuf: */ static void gs_refine_item_pixbuf (GsPlugin *plugin, GsApp *app, AsApp *item) { AsIcon *icon; gboolean ret; g_autoptr(GError) error = NULL; g_autofree gchar *fn = NULL; g_autofree gchar *cachedir = NULL; icon = as_app_get_icon_default (item); switch (as_icon_get_kind (icon)) { case AS_ICON_KIND_REMOTE: gs_app_set_icon (app, icon); if (as_icon_get_filename (icon) == NULL) { cachedir = gs_utils_get_cachedir ("icons", NULL); fn = g_build_filename (cachedir, as_icon_get_name (icon), NULL); as_icon_set_filename (icon, fn); as_icon_set_prefix (icon, cachedir); } if (g_file_test (fn, G_FILE_TEST_EXISTS)) { as_icon_set_kind (icon, AS_ICON_KIND_LOCAL); ret = gs_app_load_icon (app, plugin->scale, &error); if (!ret) { g_warning ("failed to load icon %s: %s", as_icon_get_name (icon), error->message); return; } } break; case AS_ICON_KIND_STOCK: case AS_ICON_KIND_LOCAL: gs_app_set_icon (app, icon); /* does not exist, so try to find using the icon theme */ if (as_icon_get_kind (icon) == AS_ICON_KIND_LOCAL && as_icon_get_filename (icon) == NULL) as_icon_set_kind (icon, AS_ICON_KIND_STOCK); /* load */ ret = gs_app_load_icon (app, plugin->scale, &error); if (!ret) { g_warning ("failed to load %s icon %s: %s", as_icon_kind_to_string (as_icon_get_kind (icon)), as_icon_get_name (icon), error->message); return; } break; case AS_ICON_KIND_CACHED: if (plugin->scale == 2) icon = as_app_get_icon_for_size (item, 128, 128); if (icon == NULL) icon = as_app_get_icon_for_size (item, 64, 64); if (icon == NULL) { g_warning ("failed to find cached icon %s", as_icon_get_name (icon)); return; } if (!as_icon_load (icon, AS_ICON_LOAD_FLAG_SEARCH_SIZE, &error)) { g_warning ("failed to load cached icon %s: %s", as_icon_get_name (icon), error->message); return; } gs_app_set_pixbuf (app, as_icon_get_pixbuf (icon)); break; default: g_warning ("icon kind unknown for %s", as_app_get_id (item)); break; } }
/** * xdg_app_review_fetch_for_app: */ static GPtrArray * xdg_app_review_fetch_for_app (GsPlugin *plugin, GsApp *app, GError **error) { const gchar *version; guint karma_min; guint status_code; g_autofree gchar *cachedir = NULL; g_autofree gchar *cachefn = NULL; g_autofree gchar *data = NULL; g_autofree gchar *uri = NULL; g_autoptr(GFile) cachefn_file = NULL; g_autoptr(GPtrArray) reviews = NULL; g_autoptr(JsonBuilder) builder = NULL; g_autoptr(JsonGenerator) json_generator = NULL; g_autoptr(JsonNode) json_root = NULL; g_autoptr(SoupMessage) msg = NULL; /* look in the cache */ cachedir = gs_utils_get_cachedir ("reviews", error); if (cachedir == NULL) return NULL; cachefn = g_strdup_printf ("%s/%s.json", cachedir, gs_app_get_id_no_prefix (app)); cachefn_file = g_file_new_for_path (cachefn); if (gs_utils_get_file_age (cachefn_file) < XDG_APP_REVIEW_CACHE_AGE_MAX) { g_autofree gchar *json_data = NULL; if (!g_file_get_contents (cachefn, &json_data, NULL, error)) return NULL; g_debug ("got review data for %s from %s", gs_app_get_id_no_prefix (app), cachefn); return xdg_app_review_parse_reviews (json_data, -1, error); } /* not always available */ version = gs_app_get_version (app); if (version == NULL) version = "unknown"; /* create object with review data */ builder = json_builder_new (); json_builder_begin_object (builder); json_builder_set_member_name (builder, "user_hash"); json_builder_add_string_value (builder, plugin->priv->user_hash); json_builder_set_member_name (builder, "app_id"); json_builder_add_string_value (builder, gs_app_get_id_no_prefix (app)); json_builder_set_member_name (builder, "locale"); json_builder_add_string_value (builder, plugin->locale); json_builder_set_member_name (builder, "distro"); json_builder_add_string_value (builder, plugin->priv->distro); json_builder_set_member_name (builder, "version"); json_builder_add_string_value (builder, version); json_builder_set_member_name (builder, "limit"); json_builder_add_int_value (builder, XDG_APP_REVIEW_NUMBER_RESULTS_MAX); json_builder_set_member_name (builder, "karma"); karma_min = g_settings_get_int (plugin->priv->settings, "review-karma-required"); json_builder_add_int_value (builder, karma_min); json_builder_end_object (builder); /* export as a string */ json_root = json_builder_get_root (builder); json_generator = json_generator_new (); json_generator_set_pretty (json_generator, TRUE); json_generator_set_root (json_generator, json_root); data = json_generator_to_data (json_generator, NULL); if (data == NULL) return NULL; uri = g_strdup_printf ("%s/fetch", plugin->priv->review_server); msg = soup_message_new (SOUP_METHOD_POST, uri); soup_message_set_request (msg, "application/json", SOUP_MEMORY_COPY, data, strlen (data)); status_code = soup_session_send_message (plugin->soup_session, msg); if (status_code != SOUP_STATUS_OK) { if (!xdg_app_review_parse_success (msg->response_body->data, msg->response_body->length, error)) return NULL; /* not sure what to do here */ g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "status code invalid"); return NULL; } reviews = xdg_app_review_parse_reviews (msg->response_body->data, msg->response_body->length, error); if (reviews == NULL) return NULL; g_debug ("xdg-app-review returned: %s", msg->response_body->data); /* save to the cache */ if (!g_file_set_contents (cachefn, msg->response_body->data, msg->response_body->length, error)) return NULL; /* success */ return g_steal_pointer (&reviews); }
/** * xdg_app_review_get_ratings: */ static GArray * xdg_app_review_get_ratings (GsPlugin *plugin, GsApp *app, GError **error) { GArray *ratings; guint status_code; g_autofree gchar *cachedir = NULL; g_autofree gchar *cachefn = NULL; g_autofree gchar *data = NULL; g_autofree gchar *uri = NULL; g_autoptr(GFile) cachefn_file = NULL; g_autoptr(SoupMessage) msg = NULL; /* look in the cache */ cachedir = gs_utils_get_cachedir ("ratings", error); if (cachedir == NULL) return NULL; cachefn = g_strdup_printf ("%s/%s.json", cachedir, gs_app_get_id_no_prefix (app)); cachefn_file = g_file_new_for_path (cachefn); if (gs_utils_get_file_age (cachefn_file) < XDG_APP_REVIEW_CACHE_AGE_MAX) { g_autofree gchar *json_data = NULL; if (!g_file_get_contents (cachefn, &json_data, NULL, error)) return NULL; g_debug ("got ratings data for %s from %s", gs_app_get_id_no_prefix (app), cachefn); return xdg_app_review_parse_ratings (json_data, -1, error); } /* create the GET data *with* the machine hash so we can later * review the application ourselves */ uri = g_strdup_printf ("%s/ratings/%s", plugin->priv->review_server, gs_app_get_id_no_prefix (app)); msg = soup_message_new (SOUP_METHOD_GET, uri); status_code = soup_session_send_message (plugin->soup_session, msg); if (status_code != SOUP_STATUS_OK) { if (!xdg_app_review_parse_success (msg->response_body->data, msg->response_body->length, error)) return NULL; /* not sure what to do here */ g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "status code invalid"); return NULL; } g_debug ("xdg-app-review returned: %s", msg->response_body->data); ratings = xdg_app_review_parse_ratings (msg->response_body->data, msg->response_body->length, error); if (ratings == NULL) return NULL; /* save to the cache */ if (!g_file_set_contents (cachefn, msg->response_body->data, msg->response_body->length, error)) return NULL; return ratings; }