/** * gs_appstream_refine_add_screenshots: */ static void gs_appstream_refine_add_screenshots (GsApp *app, AsApp *item) { AsScreenshot *ss; GPtrArray *images_as; GPtrArray *screenshots_as; guint i; /* do we have any to add */ screenshots_as = as_app_get_screenshots (item); if (screenshots_as->len == 0) return; /* does the app already have some */ gs_app_add_kudo (app, GS_APP_KUDO_HAS_SCREENSHOTS); if (gs_app_get_screenshots(app)->len > 0) return; /* add any we know */ for (i = 0; i < screenshots_as->len && i < GS_APPSTREAM_MAX_SCREENSHOTS; i++) { ss = g_ptr_array_index (screenshots_as, i); images_as = as_screenshot_get_images (ss); if (images_as->len == 0) continue; if (as_screenshot_get_kind (ss) == AS_SCREENSHOT_KIND_UNKNOWN) continue; gs_app_add_screenshot (app, ss); } }
void gs_page_update_app (GsPage *page, GsApp *app, GCancellable *cancellable) { GsPagePrivate *priv = gs_page_get_instance_private (page); GsPageHelper *helper; /* non-firmware applications do not have to be prepared */ helper = g_slice_new0 (GsPageHelper); helper->action = GS_PLUGIN_ACTION_UPDATE; helper->app = g_object_ref (app); helper->page = g_object_ref (page); helper->cancellable = g_object_ref (cancellable); /* tell the user what they have to do */ if (gs_app_get_kind (app) == AS_APP_KIND_FIRMWARE && gs_app_has_quirk (app, AS_APP_QUIRK_NEEDS_USER_ACTION)) { GPtrArray *screenshots = gs_app_get_screenshots (app); if (screenshots->len > 0) { AsScreenshot *ss = g_ptr_array_index (screenshots, 0); if (as_screenshot_get_caption (ss, NULL) != NULL) { gs_page_needs_user_action (helper, ss); return; } } } /* generic fallback */ gs_plugin_loader_app_action_async (priv->plugin_loader, helper->app, helper->action, GS_PLUGIN_FAILURE_FLAGS_FATAL_ANY, helper->cancellable, gs_page_app_installed_cb, helper); }
gboolean gs_plugin_refine_app (GsPlugin *plugin, GsApp *app, GsPluginRefineFlags flags, GCancellable *cancellable, GError **error) { GsPluginData *priv = gs_plugin_get_data (plugin); g_autoptr(SnapdClient) client = NULL; const gchar *name; g_autoptr(SnapdSnap) local_snap = NULL; g_autoptr(SnapdSnap) store_snap = NULL; SnapdSnap *snap; const gchar *developer_name; g_autofree gchar *description = NULL; /* not us */ if (g_strcmp0 (gs_app_get_management_plugin (app), "snap") != 0) return TRUE; client = get_client (plugin, error); if (client == NULL) return FALSE; /* get information from local snaps and store */ local_snap = snapd_client_get_snap_sync (client, gs_app_get_metadata_item (app, "snap::name"), cancellable, NULL); if (local_snap == NULL || (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_SCREENSHOTS) != 0) store_snap = get_store_snap (plugin, gs_app_get_metadata_item (app, "snap::name"), cancellable, NULL); if (local_snap == NULL && store_snap == NULL) return TRUE; if (local_snap != NULL) gs_app_set_state (app, AS_APP_STATE_INSTALLED); else gs_app_set_state (app, AS_APP_STATE_AVAILABLE); /* use store information for basic metadata over local information */ snap = store_snap != NULL ? store_snap : local_snap; name = snapd_snap_get_title (snap); if (name == NULL || g_strcmp0 (name, "") == 0) name = snapd_snap_get_name (snap); gs_app_set_name (app, GS_APP_QUALITY_NORMAL, name); gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, snapd_snap_get_summary (snap)); description = gs_plugin_snap_get_description_safe (snap); if (description != NULL) gs_app_set_description (app, GS_APP_QUALITY_NORMAL, description); gs_app_set_license (app, GS_APP_QUALITY_NORMAL, snapd_snap_get_license (snap)); developer_name = snapd_snap_get_publisher_display_name (snap); if (developer_name == NULL) developer_name = snapd_snap_get_publisher_username (snap); gs_app_set_developer_name (app, developer_name); if (snapd_snap_get_publisher_validation (snap) == SNAPD_PUBLISHER_VALIDATION_VERIFIED) gs_app_add_quirk (app, GS_APP_QUIRK_DEVELOPER_VERIFIED); snap = local_snap != NULL ? local_snap : store_snap; gs_app_set_version (app, snapd_snap_get_version (snap)); switch (snapd_snap_get_snap_type (snap)) { case SNAPD_SNAP_TYPE_APP: gs_app_set_kind (app, AS_APP_KIND_DESKTOP); break; case SNAPD_SNAP_TYPE_KERNEL: case SNAPD_SNAP_TYPE_GADGET: case SNAPD_SNAP_TYPE_OS: gs_app_set_kind (app, AS_APP_KIND_RUNTIME); break; default: case SNAPD_SNAP_TYPE_UNKNOWN: gs_app_set_kind (app, AS_APP_KIND_UNKNOWN); break; } /* add information specific to installed snaps */ if (local_snap != NULL) { SnapdApp *snap_app; GDateTime *install_date; install_date = snapd_snap_get_install_date (local_snap); gs_app_set_size_installed (app, snapd_snap_get_installed_size (local_snap)); gs_app_set_install_date (app, install_date != NULL ? g_date_time_to_unix (install_date) : GS_APP_INSTALL_DATE_UNKNOWN); snap_app = get_primary_app (local_snap); if (snap_app != NULL) { gs_app_set_metadata (app, "snap::launch-name", snapd_app_get_name (snap_app)); gs_app_set_metadata (app, "snap::launch-desktop", snapd_app_get_desktop_file (snap_app)); } else { gs_app_add_quirk (app, GS_APP_QUIRK_NOT_LAUNCHABLE); } } /* add information specific to store snaps */ if (store_snap != NULL) { gs_app_set_origin (app, priv->store_name); gs_app_set_size_download (app, snapd_snap_get_download_size (store_snap)); if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_SCREENSHOTS && gs_app_get_screenshots (app)->len == 0) refine_screenshots (app, store_snap); } /* load icon if requested */ if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON && gs_app_get_pixbuf (app) == NULL) load_icon (plugin, client, app, gs_app_get_metadata_item (app, "snap::name"), local_snap, store_snap, cancellable); return TRUE; }
static void refine_screenshots (GsApp *app, SnapdSnap *snap) { GPtrArray *media, *screenshots; guint i; media = snapd_snap_get_media (snap); for (i = 0; i < media->len; i++) { SnapdMedia *m = media->pdata[i]; const gchar *url; g_autofree gchar *filename = NULL; g_autoptr(AsScreenshot) ss = NULL; g_autoptr(AsImage) image = NULL; if (g_strcmp0 (snapd_media_get_media_type (m), "screenshot") != 0) continue; /* skip screenshots used for banner when app is featured */ url = snapd_media_get_url (m); filename = g_path_get_basename (url); if (is_banner_image (filename) || is_banner_icon_image (filename)) continue; ss = as_screenshot_new (); as_screenshot_set_kind (ss, AS_SCREENSHOT_KIND_NORMAL); image = as_image_new (); as_image_set_url (image, snapd_media_get_url (m)); as_image_set_kind (image, AS_IMAGE_KIND_SOURCE); as_image_set_width (image, snapd_media_get_width (m)); as_image_set_height (image, snapd_media_get_height (m)); as_screenshot_add_image (ss, image); gs_app_add_screenshot (app, ss); } if (gs_app_get_screenshots (app)->len > 0) return; /* fallback to old screenshots data */ G_GNUC_BEGIN_IGNORE_DEPRECATIONS screenshots = snapd_snap_get_screenshots (snap); G_GNUC_END_IGNORE_DEPRECATIONS for (i = 0; i < screenshots->len; i++) { SnapdScreenshot *screenshot = screenshots->pdata[i]; const gchar *url; g_autofree gchar *filename = NULL; g_autoptr(AsScreenshot) ss = NULL; g_autoptr(AsImage) image = NULL; /* skip screenshots used for banner when app is featured */ url = snapd_screenshot_get_url (screenshot); filename = g_path_get_basename (url); if (is_banner_image (filename) || is_banner_icon_image (filename)) continue; ss = as_screenshot_new (); as_screenshot_set_kind (ss, AS_SCREENSHOT_KIND_NORMAL); image = as_image_new (); as_image_set_url (image, snapd_screenshot_get_url (screenshot)); as_image_set_kind (image, AS_IMAGE_KIND_SOURCE); as_image_set_width (image, snapd_screenshot_get_width (screenshot)); as_image_set_height (image, snapd_screenshot_get_height (screenshot)); as_screenshot_add_image (ss, image); gs_app_add_screenshot (app, ss); } }
static void refine_app (GsPlugin *plugin, GsApp *app, JsonObject *package, gboolean from_search, GCancellable *cancellable) { g_autofree gchar *macaroon = NULL; g_auto(GStrv) discharges = NULL; const gchar *status, *icon_url, *launch_name = NULL; g_autoptr(GdkPixbuf) icon_pixbuf = NULL; gint64 size = -1; get_macaroon (plugin, &macaroon, &discharges); status = json_object_get_string_member (package, "status"); if (g_strcmp0 (status, "installed") == 0 || g_strcmp0 (status, "active") == 0) { const gchar *update_available; update_available = json_object_has_member (package, "update_available") ? json_object_get_string_member (package, "update_available") : NULL; if (update_available) gs_app_set_state (app, AS_APP_STATE_UPDATABLE); else { if (gs_app_get_state (app) == AS_APP_STATE_AVAILABLE) gs_app_set_state (app, AS_APP_STATE_UNKNOWN); gs_app_set_state (app, AS_APP_STATE_INSTALLED); } } else if (g_strcmp0 (status, "not installed") == 0 || g_strcmp0 (status, "available") == 0) { gs_app_set_state (app, AS_APP_STATE_AVAILABLE); } gs_app_set_name (app, GS_APP_QUALITY_HIGHEST, json_object_get_string_member (package, "summary")); gs_app_set_summary (app, GS_APP_QUALITY_HIGHEST, json_object_get_string_member (package, "summary")); gs_app_set_description (app, GS_APP_QUALITY_HIGHEST, json_object_get_string_member (package, "description")); gs_app_set_version (app, json_object_get_string_member (package, "version")); if (json_object_has_member (package, "installed-size")) { size = json_object_get_int_member (package, "installed-size"); if (size > 0) gs_app_set_size_installed (app, (guint64) size); } if (json_object_has_member (package, "download-size")) { size = json_object_get_int_member (package, "download-size"); if (size > 0) gs_app_set_size_download (app, (guint64) size); } gs_app_add_quirk (app, AS_APP_QUIRK_PROVENANCE); icon_url = json_object_get_string_member (package, "icon"); if (g_str_has_prefix (icon_url, "/")) { g_autofree gchar *icon_data = NULL; gsize icon_data_length; g_autoptr(GError) error = NULL; icon_data = gs_snapd_get_resource (macaroon, discharges, icon_url, &icon_data_length, cancellable, &error); if (icon_data != NULL) { g_autoptr(GdkPixbufLoader) loader = NULL; loader = gdk_pixbuf_loader_new (); gdk_pixbuf_loader_write (loader, (guchar *) icon_data, icon_data_length, NULL); gdk_pixbuf_loader_close (loader, NULL); icon_pixbuf = g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader)); } else g_printerr ("Failed to get icon: %s\n", error->message); } else { g_autoptr(SoupMessage) message = NULL; g_autoptr(GdkPixbufLoader) loader = NULL; message = soup_message_new (SOUP_METHOD_GET, icon_url); if (message != NULL) { soup_session_send_message (gs_plugin_get_soup_session (plugin), message); loader = gdk_pixbuf_loader_new (); gdk_pixbuf_loader_write (loader, (guint8 *) message->response_body->data, (gsize) message->response_body->length, NULL); gdk_pixbuf_loader_close (loader, NULL); icon_pixbuf = g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader)); } } if (icon_pixbuf) { gs_app_set_pixbuf (app, icon_pixbuf); } else { g_autoptr(AsIcon) icon = as_icon_new (); as_icon_set_kind (icon, AS_ICON_KIND_STOCK); as_icon_set_name (icon, "package-x-generic"); gs_app_add_icon (app, icon); } if (json_object_has_member (package, "screenshots") && gs_app_get_screenshots (app)->len <= 0) { JsonArray *screenshots; guint i; screenshots = json_object_get_array_member (package, "screenshots"); for (i = 0; i < json_array_get_length (screenshots); i++) { JsonObject *screenshot = json_array_get_object_element (screenshots, i); g_autoptr(AsScreenshot) ss = NULL; g_autoptr(AsImage) image = NULL; ss = as_screenshot_new (); as_screenshot_set_kind (ss, AS_SCREENSHOT_KIND_NORMAL); image = as_image_new (); as_image_set_url (image, json_object_get_string_member (screenshot, "url")); as_image_set_kind (image, AS_IMAGE_KIND_SOURCE); as_screenshot_add_image (ss, image); gs_app_add_screenshot (app, ss); } } if (!from_search) { JsonArray *apps; apps = json_object_get_array_member (package, "apps"); if (apps && json_array_get_length (apps) > 0) launch_name = json_object_get_string_member (json_array_get_object_element (apps, 0), "name"); if (launch_name) gs_app_set_metadata (app, "snap::launch-name", launch_name); else gs_app_add_quirk (app, AS_APP_QUIRK_NOT_LAUNCHABLE); } }