/** * gs_plugin_add_unvoted_reviews: */ gboolean gs_plugin_add_unvoted_reviews (GsPlugin *plugin, GList **list, GCancellable *cancellable, GError **error) { const gchar *app_id_last = NULL; guint status_code; guint i; g_autofree gchar *uri = NULL; g_autoptr(GFile) cachefn_file = NULL; g_autoptr(GPtrArray) reviews = NULL; g_autoptr(GsApp) app_current = NULL; g_autoptr(SoupMessage) msg = NULL; /* create the GET data *with* the machine hash so we can later * review the application ourselves */ uri = g_strdup_printf ("%s/moderate/%s", plugin->priv->review_server, plugin->priv->user_hash); 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 FALSE; /* not sure what to do here */ g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "status code invalid"); return FALSE; } g_debug ("xdg-app-review returned: %s", msg->response_body->data); reviews = xdg_app_review_parse_reviews (msg->response_body->data, msg->response_body->length, error); if (reviews == NULL) return FALSE; /* look at all the reviews; faking application objects */ for (i = 0; i < reviews->len; i++) { GsReview *review; const gchar *app_id; /* same app? */ review = g_ptr_array_index (reviews, i); app_id = gs_review_get_metadata_item (review, "app_id"); if (g_strcmp0 (app_id, app_id_last) != 0) { g_clear_object (&app_current); app_current = gs_app_new (app_id); gs_plugin_add_app (list, app_current); app_id_last = app_id; } gs_app_add_review (app_current, review); } return TRUE; }
/** * gs_plugin_add_updates: */ gboolean gs_plugin_add_updates (GsPlugin *plugin, GList **list, GCancellable *cancellable, GError **error) { GsApp *app; /* update UI as this might take some time */ gs_plugin_status_update (plugin, NULL, GS_PLUGIN_STATUS_WAITING); /* spin */ g_usleep (2 * G_USEC_PER_SEC); /* add a normal application */ app = gs_app_new ("gnome-boxes"); gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "Boxes"); gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "Do not segfault when using newer versons of libvirt."); gs_app_set_kind (app, GS_APP_KIND_NORMAL); gs_app_set_id_kind (app, AS_ID_KIND_DESKTOP); gs_plugin_add_app (list, app); g_object_unref (app); /* add an OS update */ app = gs_app_new ("libvirt-glib-devel;0.0.1;noarch;fedora"); gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "libvirt-glib-devel"); gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "Fix several memory leaks."); gs_app_set_kind (app, GS_APP_KIND_PACKAGE); gs_app_set_id_kind (app, AS_ID_KIND_DESKTOP); gs_plugin_add_app (list, app); g_object_unref (app); /* add a second OS update */ app = gs_app_new ("gnome-boxes-libs;0.0.1;i386;updates-testing"); gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "gnome-boxes-libs"); gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "Do not segfault when using newer versons of libvirt."); gs_app_set_kind (app, GS_APP_KIND_PACKAGE); gs_app_set_id_kind (app, AS_ID_KIND_DESKTOP); gs_plugin_add_app (list, app); g_object_unref (app); return TRUE; }
/** * gs_plugin_add_popular: */ gboolean gs_plugin_add_popular (GsPlugin *plugin, GList **list, GCancellable *cancellable, GError **error) { g_autoptr(GsApp) app = gs_app_new ("gnome-power-manager"); gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "Power Manager"); gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "Power Management Program"); gs_app_set_state (app, AS_APP_STATE_AVAILABLE); gs_app_set_kind (app, GS_APP_KIND_NORMAL); gs_plugin_add_app (list, app); gs_app_set_id_kind (app, AS_ID_KIND_DESKTOP); return TRUE; }
/** * gs_plugin_add_category_apps: */ gboolean gs_plugin_add_category_apps (GsPlugin *plugin, GsCategory *category, GList **list, GCancellable *cancellable, GError **error) { g_autoptr(GsApp) app = gs_app_new ("gnome-boxes"); gs_app_set_name (app, GS_APP_QUALITY_NORMAL, "Boxes"); gs_app_set_summary (app, GS_APP_QUALITY_NORMAL, "View and use virtual machines"); gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, "http://www.box.org"); gs_app_set_kind (app, GS_APP_KIND_NORMAL); gs_app_set_state (app, AS_APP_STATE_AVAILABLE); gs_app_set_pixbuf (app, gdk_pixbuf_new_from_file ("/usr/share/icons/hicolor/48x48/apps/gnome-boxes.png", NULL)); gs_app_set_id_kind (app, AS_ID_KIND_DESKTOP); gs_plugin_add_app (list, app); return TRUE; }
/** * gs_plugin_add_featured_app: */ static gboolean gs_plugin_add_featured_app (GList **list, GKeyFile *kf, const gchar *id, GError **error) { _cleanup_free_ gchar *background = NULL; _cleanup_free_ gchar *stroke_color = NULL; _cleanup_free_ gchar *text_color = NULL; _cleanup_free_ gchar *text_shadow = NULL; _cleanup_object_unref_ GsApp *app = NULL; background = g_key_file_get_string (kf, id, "background", error); if (background == NULL) return FALSE; stroke_color = g_key_file_get_string (kf, id, "stroke", error); if (stroke_color == NULL) return FALSE; text_color = g_key_file_get_string (kf, id, "text", error); if (text_color == NULL) return FALSE; /* optional */ text_shadow = g_key_file_get_string (kf, id, "text-shadow", NULL); /* add app */ app = gs_app_new (id); gs_app_add_kudo (app, GS_APP_KUDO_FEATURED_RECOMMENDED); gs_app_set_metadata (app, "Featured::background", background); gs_app_set_metadata (app, "Featured::stroke-color", stroke_color); gs_app_set_metadata (app, "Featured::text-color", text_color); if (text_shadow != NULL) gs_app_set_metadata (app, "Featured::text-shadow", text_shadow); gs_plugin_add_app (list, app); return TRUE; }
/** * gs_plugin_filename_to_app: */ gboolean gs_plugin_filename_to_app (GsPlugin *plugin, GList **list, const gchar *filename, GCancellable *cancellable, GError **error) { const gchar *package_id; gboolean supported; PkDetails *item; ProgressData data; g_autoptr (PkResults) results = NULL; g_autofree gchar *basename = NULL; g_autofree gchar *license_spdx = NULL; g_auto(GStrv) files = NULL; g_auto(GStrv) split = NULL; g_autoptr(GPtrArray) array = NULL; g_autoptr(GsApp) app = NULL; /* does this match any of the mimetypes we support */ if (!gs_plugin_packagekit_refresh_content_type_matches (filename, &supported, cancellable, error)) return FALSE; if (!supported) return TRUE; data.plugin = plugin; data.ptask = NULL; /* get details */ files = g_strsplit (filename, "\t", -1); pk_client_set_cache_age (PK_CLIENT (plugin->priv->task), G_MAXUINT); results = pk_client_get_details_local (PK_CLIENT (plugin->priv->task), files, cancellable, gs_plugin_packagekit_progress_cb, &data, error); if (results == NULL) return FALSE; /* get results */ array = pk_results_get_details_array (results); if (array->len == 0) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "no details for %s", filename); return FALSE; } if (array->len > 1) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "too many details [%i] for %s", array->len, filename); return FALSE; } /* create application */ item = g_ptr_array_index (array, 0); app = gs_app_new (NULL); package_id = pk_details_get_package_id (item); split = pk_package_id_split (package_id); basename = g_path_get_basename (filename); gs_app_set_management_plugin (app, "PackageKit"); gs_app_set_kind (app, GS_APP_KIND_PACKAGE); gs_app_set_state (app, AS_APP_STATE_AVAILABLE_LOCAL); if (pk_details_get_summary (item)) gs_app_set_name (app, GS_APP_QUALITY_LOWEST, pk_details_get_summary (item)); else gs_app_set_name (app, GS_APP_QUALITY_LOWEST, split[PK_PACKAGE_ID_NAME]); gs_app_set_version (app, split[PK_PACKAGE_ID_VERSION]); gs_app_set_metadata (app, "PackageKit::local-filename", filename); gs_app_set_origin (app, basename); gs_app_add_source (app, split[PK_PACKAGE_ID_NAME]); gs_app_add_source_id (app, package_id); gs_plugin_packagekit_refresh_set_text (app, pk_details_get_description (item)); gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, pk_details_get_url (item)); gs_app_set_size (app, pk_details_get_size (item)); license_spdx = as_utils_license_to_spdx (pk_details_get_license (item)); gs_app_set_licence (app, license_spdx, GS_APP_QUALITY_LOWEST); /* look for a desktop file so we can use a valid application id */ if (!gs_plugin_packagekit_refresh_guess_app_id (plugin, app, filename, cancellable, error)) return FALSE; gs_plugin_add_app (list, app); return TRUE; }
/** * gs_plugin_add_updates: */ gboolean gs_plugin_add_updates (GsPlugin *plugin, GList **list, GCancellable *cancellable, GError **error) { g_autoptr(GList) updates = NULL; GList *l; g_autoptr(GError) error_local = NULL; updates = li_manager_get_update_list (plugin->priv->mgr, &error_local); if (error_local != NULL) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "Failed to list updates: %s", error_local->message); return FALSE; } for (l = updates; l != NULL; l = l->next) { LiPkgInfo *old_pki; LiPkgInfo *new_pki; const gchar *cptkind_str; g_autoptr(GsApp) app = NULL; LiUpdateItem *uitem = LI_UPDATE_ITEM (l->data); old_pki = li_update_item_get_installed_pkg (uitem); new_pki = li_update_item_get_available_pkg (uitem); cptkind_str = li_pkg_info_get_component_kind (old_pki); if ((cptkind_str != NULL) && (g_strcmp0 (cptkind_str, "desktop") == 0)) { g_autofree gchar *tmp = NULL; /* type=desktop AppStream components result in a Limba bundle name which has the .desktop stripped away. * We need to re-add it for GNOME Software. * In any other case, the Limba bundle name equals the AppStream ID of the component it contains */ tmp = g_strdup_printf ("%s.desktop", li_pkg_info_get_name (old_pki)); app = gs_app_new (tmp); gs_app_set_kind (app, AS_APP_KIND_DESKTOP); } else { app = gs_app_new (li_pkg_info_get_name (old_pki)); } gs_app_set_management_plugin (app, "Limba"); gs_app_set_state (app, AS_APP_STATE_UPDATABLE_LIVE); gs_app_set_kind (app, AS_APP_KIND_GENERIC); gs_plugin_add_app (list, app); gs_app_set_name (app, GS_APP_QUALITY_LOWEST, li_pkg_info_get_name (old_pki)); gs_app_set_summary (app, GS_APP_QUALITY_LOWEST, li_pkg_info_get_name (old_pki)); gs_app_set_version (app, li_pkg_info_get_version (old_pki)); gs_app_set_update_version (app, li_pkg_info_get_version (new_pki)); gs_app_add_source (app, li_pkg_info_get_id (old_pki)); gs_plugin_add_app (list, app); } return TRUE; }
int main (int argc, char **argv) { GList *list = NULL; GList *categories = NULL; GOptionContext *context; gboolean prefer_local = FALSE; gboolean ret; gboolean show_results = FALSE; guint64 refine_flags = GS_PLUGIN_REFINE_FLAGS_DEFAULT; gint i; gint repeat = 1; int status = 0; _cleanup_error_free_ GError *error = NULL; _cleanup_free_ gchar *refine_flags_str = NULL; _cleanup_object_unref_ GsApp *app = NULL; _cleanup_object_unref_ GsPluginLoader *plugin_loader = NULL; _cleanup_object_unref_ GsProfile *profile = NULL; const GOptionEntry options[] = { { "show-results", '\0', 0, G_OPTION_ARG_NONE, &show_results, "Show the results for the action", NULL }, { "refine-flags", '\0', 0, G_OPTION_ARG_STRING, &refine_flags_str, "Set any refine flags required for the action", NULL }, { "repeat", '\0', 0, G_OPTION_ARG_INT, &repeat, "Repeat the action this number of times", NULL }, { "prefer-local", '\0', 0, G_OPTION_ARG_NONE, &prefer_local, "Prefer local file sources to AppStream", NULL }, { NULL} }; setlocale (LC_ALL, ""); g_setenv ("G_MESSAGES_DEBUG", "all", TRUE); bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); gtk_init (&argc, &argv); context = g_option_context_new (NULL); g_option_context_set_summary (context, "GNOME Software Test Program"); g_option_context_add_main_entries (context, options, NULL); g_option_context_add_group (context, gtk_get_option_group (TRUE)); ret = g_option_context_parse (context, &argc, &argv, &error); if (!ret) { g_print ("Failed to parse options: %s\n", error->message); goto out; } /* prefer local sources */ if (prefer_local) g_setenv ("GNOME_SOFTWARE_PREFER_LOCAL", "true", TRUE); /* parse any refine flags */ refine_flags = gs_cmd_parse_refine_flags (refine_flags_str, &error); if (refine_flags == G_MAXUINT64) { g_print ("Flag unknown: %s\n", error->message); goto out; } profile = gs_profile_new (); gs_profile_start (profile, "GsCmd"); /* load plugins */ plugin_loader = gs_plugin_loader_new (); gs_plugin_loader_set_location (plugin_loader, "./plugins/.libs"); ret = gs_plugin_loader_setup (plugin_loader, &error); if (!ret) { g_print ("Failed to setup plugins: %s\n", error->message); goto out; } gs_plugin_loader_dump_state (plugin_loader); /* do action */ if (argc == 2 && g_strcmp0 (argv[1], "installed") == 0) { for (i = 0; i < repeat; i++) { if (list != NULL) gs_plugin_list_free (list); list = gs_plugin_loader_get_installed (plugin_loader, refine_flags, NULL, &error); if (list == NULL) { ret = FALSE; break; } } } else if (argc == 3 && g_strcmp0 (argv[1], "search") == 0) { for (i = 0; i < repeat; i++) { if (list != NULL) gs_plugin_list_free (list); list = gs_plugin_loader_search (plugin_loader, argv[2], refine_flags, NULL, &error); if (list == NULL) { ret = FALSE; break; } } } else if (argc == 3 && g_strcmp0 (argv[1], "refine") == 0) { app = gs_app_new (argv[2]); for (i = 0; i < repeat; i++) { ret = gs_plugin_loader_app_refine (plugin_loader, app, refine_flags, NULL, &error); if (!ret) break; } } else if (argc == 3 && g_strcmp0 (argv[1], "filename-to-app") == 0) { app = gs_plugin_loader_filename_to_app (plugin_loader, argv[2], refine_flags, NULL, &error); if (app == NULL) { ret = FALSE; } else { gs_plugin_add_app (&list, app); } } else if (argc == 2 && g_strcmp0 (argv[1], "updates") == 0) { for (i = 0; i < repeat; i++) { if (list != NULL) gs_plugin_list_free (list); list = gs_plugin_loader_get_updates (plugin_loader, refine_flags, NULL, &error); if (list == NULL) { ret = FALSE; break; } } } else if (argc == 2 && g_strcmp0 (argv[1], "sources") == 0) { list = gs_plugin_loader_get_sources (plugin_loader, refine_flags, NULL, &error); if (list == NULL) ret = FALSE; } else if (argc == 2 && g_strcmp0 (argv[1], "popular") == 0) { for (i = 0; i < repeat; i++) { if (list != NULL) gs_plugin_list_free (list); list = gs_plugin_loader_get_popular (plugin_loader, refine_flags, NULL, &error); if (list == NULL) { ret = FALSE; break; } } } else if (argc == 2 && g_strcmp0 (argv[1], "featured") == 0) { for (i = 0; i < repeat; i++) { if (list != NULL) gs_plugin_list_free (list); list = gs_plugin_loader_get_featured (plugin_loader, refine_flags, NULL, &error); if (list == NULL) { ret = FALSE; break; } } } else if (argc == 2 && g_strcmp0 (argv[1], "get-categories") == 0) { for (i = 0; i < repeat; i++) { if (categories != NULL) gs_plugin_list_free (categories); categories = gs_plugin_loader_get_categories (plugin_loader, refine_flags, NULL, &error); if (categories == NULL) { ret = FALSE; break; } } } else if (argc == 3 && g_strcmp0 (argv[1], "get-category-apps") == 0) { _cleanup_object_unref_ GsCategory *category = NULL; _cleanup_strv_free_ gchar **split = NULL; split = g_strsplit (argv[2], "/", 2); if (g_strv_length (split) == 1) { category = gs_category_new (NULL, split[0], NULL); } else { _cleanup_object_unref_ GsCategory *parent = NULL; parent = gs_category_new (NULL, split[0], NULL); category = gs_category_new (parent, split[1], NULL); } for (i = 0; i < repeat; i++) { if (list != NULL) gs_plugin_list_free (list); list = gs_plugin_loader_get_category_apps (plugin_loader, category, refine_flags, NULL, &error); if (list == NULL) { ret = FALSE; break; } } } else if (argc == 2 && g_strcmp0 (argv[1], "refresh") == 0) { ret = gs_plugin_loader_refresh (plugin_loader, 0, GS_PLUGIN_REFRESH_FLAGS_UPDATES, NULL, &error); } else { ret = FALSE; g_set_error_literal (&error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "Did not recognise option, use 'installed', " "'updates', 'popular', 'get-categories', " "'get-category-apps', 'filename-to-app', " "'sources', 'refresh' or 'search'"); } if (!ret) { g_print ("Failed: %s\n", error->message); goto out; } if (show_results) { gs_cmd_show_results_apps (list); gs_cmd_show_results_categories (categories); } out: gs_profile_stop (profile, "GsCmd"); gs_profile_dump (profile); g_option_context_free (context); gs_plugin_list_free (list); gs_plugin_list_free (categories); return status; }
/** * gs_plugin_add_updates_historical: */ gboolean gs_plugin_add_updates_historical (GsPlugin *plugin, GList **list, GCancellable *cancellable, GError **error) { gboolean ret; guint i; _cleanup_strv_free_ gchar **package_ids = NULL; _cleanup_free_ gchar *error_details = NULL; _cleanup_free_ gchar *packages = NULL; _cleanup_keyfile_unref_ GKeyFile *key_file = NULL; /* was any offline update attempted */ if (!g_file_test (PK_OFFLINE_UPDATE_RESULTS_FILENAME, G_FILE_TEST_EXISTS)) return TRUE; /* open the file */ key_file = g_key_file_new (); ret = g_key_file_load_from_file (key_file, PK_OFFLINE_UPDATE_RESULTS_FILENAME, G_KEY_FILE_NONE, error); if (!ret) return FALSE; /* only return results if successful */ ret = g_key_file_get_boolean (key_file, PK_OFFLINE_UPDATE_RESULTS_GROUP, "Success", NULL); if (!ret) { error_details = g_key_file_get_string (key_file, PK_OFFLINE_UPDATE_RESULTS_GROUP, "ErrorDetails", error); if (error_details == NULL) return FALSE; g_set_error_literal (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, error_details); return FALSE; } /* get list of package-ids */ packages = g_key_file_get_string (key_file, PK_OFFLINE_UPDATE_RESULTS_GROUP, "Packages", NULL); if (packages == NULL) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_NOT_SUPPORTED, "No 'Packages' in %s", PK_OFFLINE_UPDATE_RESULTS_FILENAME); return FALSE; } package_ids = g_strsplit (packages, ",", -1); for (i = 0; package_ids[i] != NULL; i++) { _cleanup_object_unref_ GsApp *app = NULL; _cleanup_strv_free_ gchar **split = NULL; app = gs_app_new (NULL); split = g_strsplit (package_ids[i], ";", 4); gs_app_add_source (app, split[0]); gs_app_set_update_version (app, split[1]); gs_app_set_management_plugin (app, "PackageKit"); gs_app_add_source_id (app, package_ids[i]); gs_app_set_state (app, AS_APP_STATE_UPDATABLE); gs_app_set_kind (app, GS_APP_KIND_PACKAGE); gs_plugin_add_app (list, app); } return TRUE; }