int main (int argc, char *argv[]) { g_autoptr(GsEditor) self = NULL; setlocale (LC_ALL, ""); bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); gtk_init (&argc, &argv); self = g_new0 (GsEditor, 1); self->cancellable = g_cancellable_new (); self->builder = gtk_builder_new (); self->store = as_store_new (); as_store_set_add_flags (self->store, AS_STORE_ADD_FLAG_USE_UNIQUE_ID); self->store_global = as_store_new (); as_store_set_add_flags (self->store_global, AS_STORE_ADD_FLAG_USE_UNIQUE_ID); /* are we already activated? */ self->application = gtk_application_new ("org.gnome.Software.Editor", G_APPLICATION_HANDLES_COMMAND_LINE); g_signal_connect (self->application, "startup", G_CALLBACK (gs_editor_startup_cb), self); g_signal_connect (self->application, "command-line", G_CALLBACK (gs_editor_commandline_cb), self); /* run */ return g_application_run (G_APPLICATION (self->application), argc, argv); }
/** * asb_context_init: **/ static void asb_context_init (AsbContext *ctx) { AsbContextPrivate *priv = GET_PRIVATE (ctx); priv->plugin_loader = asb_plugin_loader_new (ctx); priv->packages = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); g_mutex_init (&priv->apps_mutex); priv->store_failed = as_store_new (); priv->store_ignore = as_store_new (); priv->store_old = as_store_new (); priv->max_threads = 1; priv->min_icon_size = 32; }
/** * asb_context_write_app_xml: **/ static void asb_context_write_app_xml (AsbContext *ctx) { AsbApp *app; AsbContextPrivate *priv = GET_PRIVATE (ctx); GList *l; /* log the XML in the log file */ for (l = priv->apps; l != NULL; l = l->next) { g_autoptr(GString) xml = NULL; g_autoptr(AsStore) store = NULL; /* we have an open log file? */ if (!ASB_IS_APP (l->data)) continue; /* just log raw XML */ app = ASB_APP (l->data); store = as_store_new (); as_store_set_api_version (store, 1.0f); as_store_add_app (store, AS_APP (app)); xml = as_store_to_xml (store, AS_NODE_TO_XML_FLAG_FORMAT_INDENT | AS_NODE_TO_XML_FLAG_FORMAT_MULTILINE); asb_package_log (asb_app_get_package (app), ASB_PACKAGE_LOG_LEVEL_NONE, "%s", xml->str); } }
/** * asb_context_write_xml: **/ static gboolean asb_context_write_xml (AsbContext *ctx, GError **error) { AsApp *app; AsbContextPrivate *priv = GET_PRIVATE (ctx); GList *l; g_autofree gchar *filename = NULL; g_autoptr(AsStore) store = NULL; g_autoptr(GFile) file = NULL; /* convert any vetod applications into dummy components */ for (l = priv->apps; l != NULL; l = l->next) { app = AS_APP (l->data); if (!ASB_IS_APP (app)) continue; if (as_app_get_vetos(app)->len == 0) continue; asb_context_add_app_ignore (ctx, asb_app_get_package (ASB_APP (app))); } /* add any non-vetoed applications */ store = as_store_new (); for (l = priv->apps; l != NULL; l = l->next) { app = AS_APP (l->data); if (as_app_get_vetos(app)->len > 0) continue; as_store_add_app (store, app); as_store_remove_app (priv->store_failed, app); /* remove from the ignore list if the application was useful */ if (ASB_IS_APP (app)) { AsbPackage *pkg = asb_app_get_package (ASB_APP (app)); g_autofree gchar *name_arch = NULL; name_arch = g_strdup_printf ("%s.%s", asb_package_get_name (pkg), asb_package_get_arch (pkg)); as_store_remove_app_by_id (priv->store_ignore, name_arch); } } filename = g_strdup_printf ("%s/%s.xml.gz", priv->output_dir, priv->basename); file = g_file_new_for_path (filename); g_print ("Writing %s...\n", filename); as_store_set_origin (store, priv->origin); as_store_set_api_version (store, priv->api_version); if (priv->flags & ASB_CONTEXT_FLAG_ADD_CACHE_ID) { g_autofree gchar *builder_id = asb_utils_get_builder_id (); as_store_set_builder_id (store, builder_id); } return as_store_to_file (store, file, AS_NODE_TO_XML_FLAG_ADD_HEADER | AS_NODE_TO_XML_FLAG_FORMAT_INDENT | AS_NODE_TO_XML_FLAG_FORMAT_MULTILINE, NULL, error); }
static AsApp * get_installed_appstream_app (GsPlugin *plugin, GsApp *app, GCancellable *cancellable, GError **error) { AsApp *as_app; GsPluginData *priv = gs_plugin_get_data (plugin); const char *deploy_dir; g_autoptr(AsStore) store = NULL; g_autoptr(FlatpakInstalledRef) ref = NULL; g_autoptr(GFile) appstream_file = NULL; g_autofree char *appstream_xml = NULL; g_autofree char *appstream_path = NULL; ref = flatpak_installation_get_installed_ref (priv->installation, FLATPAK_REF_KIND_APP, gs_app_get_flatpak_name (app), gs_app_get_flatpak_arch (app), gs_app_get_flatpak_branch (app), cancellable, error); if (!ref) return NULL; deploy_dir = flatpak_installed_ref_get_deploy_dir (ref); appstream_xml = g_strdup_printf ("%s.appdata.xml", gs_app_get_flatpak_name (app)); appstream_path = g_build_filename (deploy_dir, "files", "share", "app-info", "xmls", appstream_xml, NULL); appstream_file = g_file_new_for_path (appstream_path); store = as_store_new (); as_store_set_add_flags (store, AS_STORE_ADD_FLAG_USE_UNIQUE_ID | AS_STORE_ADD_FLAG_USE_MERGE_HEURISTIC); if (!as_store_from_file (store, appstream_file, NULL, cancellable, error)) return NULL; as_app = as_store_get_app_by_id (store, gs_app_get_id (app)); if (!as_app) g_set_error (error, AS_STORE_ERROR, AS_STORE_ERROR_FAILED, "Failed to get app %s from its own installation " "AppStream file.", gs_app_get_unique_id (app)); return g_object_ref (as_app); }
/** * cra_context_new: */ CraContext * cra_context_new (void) { CraContext *ctx; ctx = g_new0 (CraContext, 1); ctx->blacklisted_pkgs = cra_glob_value_array_new (); ctx->plugins = cra_plugin_loader_new (); ctx->packages = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); ctx->extra_pkgs = cra_glob_value_array_new (); g_mutex_init (&ctx->apps_mutex); ctx->old_md_cache = as_store_new (); /* add extra data */ cra_context_add_extra_pkg (ctx, "alliance-libs", "alliance"); cra_context_add_extra_pkg (ctx, "beneath-a-steel-sky*", "scummvm"); cra_context_add_extra_pkg (ctx, "coq-coqide", "coq"); cra_context_add_extra_pkg (ctx, "drascula*", "scummvm"); cra_context_add_extra_pkg (ctx, "efte-*", "efte-common"); cra_context_add_extra_pkg (ctx, "fcitx-*", "fcitx-data"); cra_context_add_extra_pkg (ctx, "flight-of-the-amazon-queen", "scummvm"); cra_context_add_extra_pkg (ctx, "gcin", "gcin-data"); cra_context_add_extra_pkg (ctx, "hotot-gtk", "hotot-common"); cra_context_add_extra_pkg (ctx, "hotot-qt", "hotot-common"); cra_context_add_extra_pkg (ctx, "java-1.7.0-openjdk-devel", "java-1.7.0-openjdk"); cra_context_add_extra_pkg (ctx, "kchmviewer-qt", "kchmviewer"); cra_context_add_extra_pkg (ctx, "libreoffice-*", "libreoffice-core"); cra_context_add_extra_pkg (ctx, "lure", "scummvm"); cra_context_add_extra_pkg (ctx, "nntpgrab-gui", "nntpgrab-core"); cra_context_add_extra_pkg (ctx, "projectM-*", "libprojectM-qt"); cra_context_add_extra_pkg (ctx, "scummvm-tools", "scummvm"); cra_context_add_extra_pkg (ctx, "speed-dreams", "speed-dreams-robots-base"); cra_context_add_extra_pkg (ctx, "switchdesk-gui", "switchdesk"); cra_context_add_extra_pkg (ctx, "transmission-*", "transmission-common"); cra_context_add_extra_pkg (ctx, "calligra-krita", "calligra-core"); /* add blacklisted packages */ cra_context_add_blacklist_pkg (ctx, "beneath-a-steel-sky-cd"); cra_context_add_blacklist_pkg (ctx, "anaconda"); cra_context_add_blacklist_pkg (ctx, "mate-control-center"); cra_context_add_blacklist_pkg (ctx, "lxde-common"); cra_context_add_blacklist_pkg (ctx, "xscreensaver-*"); cra_context_add_blacklist_pkg (ctx, "bmpanel2-cfg"); return ctx; }
/** * asb_task_process: * @task: A #AsbTask * @error_not_used: A #GError or %NULL * * Processes the task. * * Returns: %TRUE for success, %FALSE otherwise * * Since: 0.1.0 **/ gboolean asb_task_process (AsbTask *task, GError **error_not_used) { AsRelease *release; AsbApp *app; AsbPlugin *plugin = NULL; AsbTaskPrivate *priv = GET_PRIVATE (task); GList *apps = NULL; GList *l; GPtrArray *array; gboolean ret; gchar *cache_id; guint i; guint nr_added = 0; g_autoptr(GError) error = NULL; g_autofree gchar *basename = NULL; /* reset the profile timer */ asb_package_log_start (priv->pkg); /* ensure nevra read */ if (!asb_package_ensure (priv->pkg, ASB_PACKAGE_ENSURE_NEVRA, error_not_used)) return FALSE; g_debug ("starting: %s", asb_package_get_name (priv->pkg)); /* treat archive as a special case */ if (g_str_has_suffix (priv->filename, ".cab")) { AsApp *app_tmp; GPtrArray *apps_tmp; g_autoptr(AsStore) store = as_store_new (); g_autoptr(GFile) file = g_file_new_for_path (priv->filename); if (!as_store_from_file (store, file, NULL, NULL, &error)) { asb_package_log (priv->pkg, ASB_PACKAGE_LOG_LEVEL_WARNING, "Failed to parse %s: %s", asb_package_get_filename (priv->pkg), error->message); return TRUE; } apps_tmp = as_store_get_apps (store); for (i = 0; i < apps_tmp->len; i++) { g_autoptr(AsbApp) app2 = NULL; app_tmp = AS_APP (g_ptr_array_index (apps_tmp, i)); app2 = asb_app_new (priv->pkg, as_app_get_id (app_tmp)); as_app_subsume (AS_APP (app2), app_tmp); asb_context_add_app (priv->ctx, app2); /* set cache-id in case we want to use the metadata directly */ if (asb_context_get_flag (priv->ctx, ASB_CONTEXT_FLAG_ADD_CACHE_ID)) { cache_id = asb_utils_get_cache_id_for_filename (priv->filename); as_app_add_metadata (AS_APP (app2), "X-CacheID", cache_id); g_free (cache_id); } nr_added++; } g_debug ("added %i apps from archive", apps_tmp->len); goto skip; } /* ensure file list read */ if (!asb_package_ensure (priv->pkg, ASB_PACKAGE_ENSURE_FILES, error_not_used)) return FALSE; /* did we get a file match on any plugin */ basename = g_path_get_basename (priv->filename); asb_package_log (priv->pkg, ASB_PACKAGE_LOG_LEVEL_DEBUG, "Getting filename match for %s", basename); asb_task_add_suitable_plugins (task); if (priv->plugins_to_run->len == 0) { asb_context_add_app_ignore (priv->ctx, priv->pkg); goto out; } /* delete old tree if it exists */ ret = asb_utils_ensure_exists_and_empty (priv->tmpdir, &error); if (!ret) { asb_package_log (priv->pkg, ASB_PACKAGE_LOG_LEVEL_WARNING, "Failed to clear: %s", error->message); goto out; } /* explode tree */ g_debug ("decompressing files: %s", asb_package_get_name (priv->pkg)); asb_package_log (priv->pkg, ASB_PACKAGE_LOG_LEVEL_DEBUG, "Exploding tree for %s", asb_package_get_name (priv->pkg)); ret = asb_package_explode (priv->pkg, priv->tmpdir, asb_context_get_file_globs (priv->ctx), &error); if (!ret) { asb_package_log (priv->pkg, ASB_PACKAGE_LOG_LEVEL_WARNING, "Failed to explode: %s", error->message); g_clear_error (&error); goto skip; } /* add extra packages */ if (!asb_package_ensure (priv->pkg, ASB_PACKAGE_ENSURE_DEPS | ASB_PACKAGE_ENSURE_SOURCE, error_not_used)) return FALSE; ret = asb_task_explode_extra_packages (task, &error); if (!ret) { asb_package_log (priv->pkg, ASB_PACKAGE_LOG_LEVEL_WARNING, "Failed to explode extra file: %s", error->message); goto skip; } /* run plugins */ g_debug ("examining: %s", asb_package_get_name (priv->pkg)); for (i = 0; i < priv->plugins_to_run->len; i++) { GList *apps_tmp = NULL; plugin = g_ptr_array_index (priv->plugins_to_run, i); asb_package_log (priv->pkg, ASB_PACKAGE_LOG_LEVEL_DEBUG, "Processing %s with %s", basename, plugin->name); apps_tmp = asb_plugin_process (plugin, priv->pkg, priv->tmpdir, &error); if (apps_tmp == NULL) { asb_package_log (priv->pkg, ASB_PACKAGE_LOG_LEVEL_WARNING, "Failed to run process '%s': %s", plugin->name, error->message); g_clear_error (&error); } for (l = apps_tmp; l != NULL; l = l->next) { app = ASB_APP (l->data); asb_plugin_add_app (&apps, AS_APP (app)); } g_list_free_full (apps_tmp, g_object_unref); } if (apps == NULL) goto skip; /* print */ g_debug ("processing: %s", asb_package_get_name (priv->pkg)); for (l = apps; l != NULL; l = l->next) { app = l->data; /* never set */ if (as_app_get_id (AS_APP (app)) == NULL) { asb_package_log (priv->pkg, ASB_PACKAGE_LOG_LEVEL_INFO, "app id not set for %s", asb_package_get_name (priv->pkg)); continue; } /* copy data from pkg into app */ if (!asb_package_ensure (priv->pkg, ASB_PACKAGE_ENSURE_LICENSE | ASB_PACKAGE_ENSURE_RELEASES | ASB_PACKAGE_ENSURE_VCS | ASB_PACKAGE_ENSURE_URL, error_not_used)) return FALSE; if (asb_package_get_url (priv->pkg) != NULL && as_app_get_url_item (AS_APP (app), AS_URL_KIND_HOMEPAGE) == NULL) { as_app_add_url (AS_APP (app), AS_URL_KIND_HOMEPAGE, asb_package_get_url (priv->pkg)); } if (asb_package_get_license (priv->pkg) != NULL && as_app_get_project_license (AS_APP (app)) == NULL) { as_app_set_project_license (AS_APP (app), asb_package_get_license (priv->pkg)); } /* add the source name so we can suggest these together */ if (g_strcmp0 (asb_package_get_source_pkgname (priv->pkg), asb_package_get_name (priv->pkg)) != 0) { as_app_set_source_pkgname (AS_APP (app), asb_package_get_source_pkgname (priv->pkg)); } /* set all the releases on the app */ array = asb_package_get_releases (priv->pkg); for (i = 0; i < array->len; i++) { release = g_ptr_array_index (array, i); as_app_add_release (AS_APP (app), release); } /* run each refine plugin on each app */ ret = asb_plugin_loader_process_app (asb_context_get_plugin_loader (priv->ctx), priv->pkg, app, priv->tmpdir, &error); if (!ret) { asb_package_log (priv->pkg, ASB_PACKAGE_LOG_LEVEL_WARNING, "Failed to run process on %s: %s", as_app_get_id (AS_APP (app)), error->message); g_clear_error (&error); goto skip; } /* set cache-id in case we want to use the metadata directly */ if (asb_context_get_flag (priv->ctx, ASB_CONTEXT_FLAG_ADD_CACHE_ID)) { cache_id = asb_utils_get_cache_id_for_filename (priv->filename); as_app_add_metadata (AS_APP (app), "X-CacheID", cache_id); g_free (cache_id); } /* set the VCS information into the metadata */ if (asb_package_get_vcs (priv->pkg) != NULL) { as_app_add_metadata (AS_APP (app), "VersionControlSystem", asb_package_get_vcs (priv->pkg)); } /* save any screenshots early */ if (array->len == 0) { if (!asb_app_save_resources (ASB_APP (app), ASB_APP_SAVE_FLAG_SCREENSHOTS, error_not_used)) return FALSE; } /* all okay */ asb_context_add_app (priv->ctx, app); nr_added++; } skip: /* add a dummy element to the AppStream metadata so that we don't keep * parsing this every time */ if (asb_context_get_flag (priv->ctx, ASB_CONTEXT_FLAG_ADD_CACHE_ID) && nr_added == 0) asb_context_add_app_ignore (priv->ctx, priv->pkg); /* delete tree */ g_debug ("deleting temp files: %s", asb_package_get_name (priv->pkg)); if (!asb_utils_rmtree (priv->tmpdir, &error)) { asb_package_log (priv->pkg, ASB_PACKAGE_LOG_LEVEL_WARNING, "Failed to delete tree: %s", error->message); goto out; } /* write log */ g_debug ("writing log: %s", asb_package_get_name (priv->pkg)); if (!asb_package_log_flush (priv->pkg, &error)) { asb_package_log (priv->pkg, ASB_PACKAGE_LOG_LEVEL_WARNING, "Failed to write package log: %s", error->message); goto out; } out: /* clear loaded resources */ asb_package_close (priv->pkg, NULL); asb_package_clear (priv->pkg, ASB_PACKAGE_ENSURE_DEPS | ASB_PACKAGE_ENSURE_FILES); g_list_free_full (apps, (GDestroyNotify) g_object_unref); return TRUE; }
/** * fu_util_verify_update: **/ static gboolean fu_util_verify_update (FuUtilPrivate *priv, gchar **values, GError **error) { guint i; _cleanup_object_unref_ AsStore *store = NULL; _cleanup_object_unref_ GFile *xml_file = NULL; if (g_strv_length (values) < 2) { g_set_error_literal (error, FWUPD_ERROR, FWUPD_ERROR_INTERNAL, "Invalid arguments: expected 'filename.xml' 'filename.rom'"); return FALSE; } store = as_store_new (); /* open existing file */ xml_file = g_file_new_for_path (values[0]); if (g_file_query_exists (xml_file, NULL)) { if (!as_store_from_file (store, xml_file, NULL, NULL, error)) return FALSE; } /* add new values */ as_store_set_api_version (store, 0.9); for (i = 1; values[i] != NULL; i++) { _cleanup_free_ gchar *guid = NULL; _cleanup_free_ gchar *id = NULL; _cleanup_object_unref_ AsApp *app = NULL; _cleanup_object_unref_ AsRelease *rel = NULL; _cleanup_object_unref_ FuRom *rom = NULL; _cleanup_object_unref_ GFile *file = NULL; _cleanup_error_free_ GError *error_local = NULL; file = g_file_new_for_path (values[i]); rom = fu_rom_new (); g_print ("Processing %s...\n", values[i]); if (!fu_rom_load_file (rom, file, FU_ROM_LOAD_FLAG_BLANK_PPID, NULL, &error_local)) { g_print ("%s\n", error_local->message); continue; } /* add app to store */ app = as_app_new (); id = g_strdup_printf ("0x%04x:0x%04x", fu_rom_get_vendor (rom), fu_rom_get_model (rom)); guid = fu_guid_generate_from_string (id); as_app_set_id (app, guid, -1); as_app_set_id_kind (app, AS_ID_KIND_FIRMWARE); as_app_set_source_kind (app, AS_APP_SOURCE_KIND_INF); rel = as_release_new (); as_release_set_version (rel, fu_rom_get_version (rom), -1); as_release_set_checksum (rel, G_CHECKSUM_SHA1, fu_rom_get_checksum (rom), -1); as_app_add_release (app, rel); as_store_add_app (store, app); } if (!as_store_to_file (store, xml_file, AS_NODE_TO_XML_FLAG_ADD_HEADER | AS_NODE_TO_XML_FLAG_FORMAT_INDENT | AS_NODE_TO_XML_FLAG_FORMAT_MULTILINE, NULL, error)) return FALSE; return TRUE; }
/** * fu_util_verify_all: **/ static gboolean fu_util_verify_all (FuUtilPrivate *priv, GError **error) { AsApp *app; FuDevice *dev; const gchar *tmp; guint i; _cleanup_object_unref_ AsStore *store = NULL; _cleanup_ptrarray_unref_ GPtrArray *devices = NULL; _cleanup_ptrarray_unref_ GPtrArray *devices_tmp = NULL; /* get devices from daemon */ devices_tmp = fu_util_get_devices_internal (priv, error); if (devices_tmp == NULL) return FALSE; /* get results */ for (i = 0; i < devices_tmp->len; i++) { _cleanup_error_free_ GError *error_local = NULL; dev = g_ptr_array_index (devices_tmp, i); if (!fu_util_verify_internal (priv, fu_device_get_id (dev), &error_local)) { g_print ("Failed to verify %s: %s\n", fu_device_get_id (dev), error_local->message); } } /* only load firmware from the system */ store = as_store_new (); as_store_add_filter (store, AS_ID_KIND_FIRMWARE); if (!as_store_load (store, AS_STORE_LOAD_FLAG_APP_INFO_SYSTEM, NULL, error)) return FALSE; /* print */ devices = fu_util_get_devices_internal (priv, error); if (devices == NULL) return FALSE; for (i = 0; i < devices->len; i++) { const gchar *hash = NULL; const gchar *ver = NULL; _cleanup_free_ gchar *status = NULL; dev = g_ptr_array_index (devices, i); hash = fu_device_get_metadata (dev, FU_DEVICE_KEY_FIRMWARE_HASH); if (hash == NULL) continue; app = as_store_get_app_by_id (store, fu_device_get_guid (dev)); if (app == NULL) { status = g_strdup ("No metadata"); } else { AsRelease *rel; ver = fu_device_get_metadata (dev, FU_DEVICE_KEY_VERSION); rel = as_app_get_release (app, ver); if (rel == NULL) { status = g_strdup_printf ("No version %s", ver); } else { tmp = as_release_get_checksum (rel, G_CHECKSUM_SHA1); if (g_strcmp0 (tmp, hash) != 0) { status = g_strdup_printf ("Failed: for v%s expected %s", ver, tmp); } else { status = g_strdup ("OK"); } } } g_print ("%s\t%s\t%s\n", fu_device_get_guid (dev), hash, status); } return TRUE; }
/** * main: **/ int main (int argc, char **argv) { g_autoptr(GOptionContext) option_context = NULL; gboolean ret; gboolean verbose = FALSE; g_autoptr(GError) error = NULL; g_autofree gchar *basename = NULL; g_autofree gchar *icons_dir = NULL; g_autofree gchar *origin = NULL; g_autofree gchar *xml_basename = NULL; g_autofree gchar *output_dir = NULL; g_autofree gchar *prefix = NULL; g_autoptr(AsStore) store = NULL; g_autoptr(GFile) xml_dir = NULL; g_autoptr(GFile) xml_file = NULL; gint min_icon_size = 32; guint i; const GOptionEntry options[] = { { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, /* TRANSLATORS: command line option */ _("Show extra debugging information"), NULL }, { "prefix", '\0', 0, G_OPTION_ARG_FILENAME, &prefix, /* TRANSLATORS: command line option */ _("Set the prefix"), "DIR" }, { "output-dir", '\0', 0, G_OPTION_ARG_FILENAME, &output_dir, /* TRANSLATORS: command line option */ _("Set the output directory"), "DIR" }, { "icons-dir", '\0', 0, G_OPTION_ARG_FILENAME, &icons_dir, /* TRANSLATORS: command line option */ _("Set the icons directory"), "DIR" }, { "origin", '\0', 0, G_OPTION_ARG_STRING, &origin, /* TRANSLATORS: command line option */ _("Set the origin name"), "NAME" }, { "min-icon-size", '\0', 0, G_OPTION_ARG_INT, &min_icon_size, /* TRANSLATORS: command line option */ _("Set the minimum icon size in pixels"), "ICON_SIZE" }, { "basename", '\0', 0, G_OPTION_ARG_STRING, &basename, /* TRANSLATORS: command line option */ _("Set the basenames of the output files"), "NAME" }, { NULL} }; setlocale (LC_ALL, ""); bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); option_context = g_option_context_new (" - APP-IDS"); g_option_context_add_main_entries (option_context, options, NULL); ret = g_option_context_parse (option_context, &argc, &argv, &error); if (!ret) { /* TRANSLATORS: error message */ g_print ("%s: %s\n", _("Failed to parse arguments"), error->message); return EXIT_FAILURE; } if (verbose) g_setenv ("G_MESSAGES_DEBUG", "all", TRUE); /* set defaults */ if (prefix == NULL) prefix = g_strdup ("/usr"); if (output_dir == NULL) output_dir = g_build_filename (prefix, "share/app-info/xmls", NULL); if (icons_dir == NULL) icons_dir = g_build_filename (prefix, "share/app-info/icons", origin, NULL); if (origin == NULL) { g_print ("WARNING: Metadata origin not set, using 'example'\n"); origin = g_strdup ("example"); } if (basename == NULL) basename = g_strdup (origin); if (argc == 1) { g_autofree gchar *tmp = NULL; tmp = g_option_context_get_help (option_context, TRUE, NULL); g_print ("%s", tmp); return EXIT_FAILURE; } store = as_store_new (); as_store_set_api_version (store, 0.8); as_store_set_origin (store, origin); /* load each application specified */ for (i = 1; i < (guint) argc; i++) { const gchar *app_name = argv[i]; g_auto(GStrv) intl_domains = NULL; g_autoptr(AsApp) app_appdata = NULL; g_autoptr(AsApp) app_desktop = NULL; /* TRANSLATORS: we're generating the AppStream data */ g_print ("%s %s\n", _("Processing application"), app_name); app_appdata = load_appdata (prefix, app_name, &error); if (app_appdata == NULL) { /* TRANSLATORS: the .appdata.xml file could not * be loaded */ g_print ("%s: %s\n", _("Error loading AppData file"), error->message); return EXIT_FAILURE; } /* set translations */ if (!as_app_builder_search_translations (app_appdata, prefix, 25, AS_APP_BUILDER_FLAG_NONE, NULL, &error)) { /* TRANSLATORS: the .mo files could not be parsed */ g_print ("%s: %s\n", _("Error parsing translations"), error->message); return EXIT_FAILURE; } /* auto-add kudos */ if (!as_app_builder_search_kudos (app_appdata, prefix, AS_APP_BUILDER_FLAG_NONE, &error)) { /* TRANSLATORS: we could not auto-add the kudo */ g_print ("%s: %s\n", _("Error parsing kudos"), error->message); return EXIT_FAILURE; } /* auto-add provides */ if (!as_app_builder_search_provides (app_appdata, prefix, AS_APP_BUILDER_FLAG_NONE, &error)) { /* TRANSLATORS: we could not auto-add the provides */ g_print ("%s: %s\n", _("Error parsing provides"), error->message); return EXIT_FAILURE; } as_store_add_app (store, app_appdata); app_desktop = load_desktop (prefix, icons_dir, min_icon_size, app_name, as_app_get_id (app_appdata), &error); if (app_desktop == NULL) { /* TRANSLATORS: the .desktop file could not * be loaded */ g_print ("%s: %s\n", _("Error loading desktop file"), error->message); return EXIT_FAILURE; } as_store_add_app (store, app_desktop); } /* create output directory */ if (g_mkdir_with_parents (output_dir, 0755)) { int errsv = errno; g_print ("%s: %s\n", /* TRANSLATORS: this is when the folder could * not be created */ _("Error creating output directory"), strerror (errsv)); return EXIT_FAILURE; } xml_dir = g_file_new_for_path (output_dir); xml_basename = g_strconcat (basename, ".xml.gz", NULL); xml_file = g_file_get_child (xml_dir, xml_basename); /* TRANSLATORS: we've saving the XML file to disk */ g_print ("%s %s\n", _("Saving AppStream"), g_file_get_path (xml_file)); if (!as_store_to_file (store, xml_file, AS_NODE_TO_XML_FLAG_FORMAT_MULTILINE | AS_NODE_TO_XML_FLAG_FORMAT_INDENT | AS_NODE_TO_XML_FLAG_ADD_HEADER, NULL, &error)) { /* TRANSLATORS: this is when the destination file * cannot be saved for some reason */ g_print ("%s: %s\n", _("Error saving AppStream file"), error->message); return EXIT_FAILURE; } /* TRANSLATORS: information message */ g_print ("%s\n", _("Done!")); return EXIT_SUCCESS; }
/** * gs_plugin_file_to_app: */ gboolean gs_plugin_file_to_app (GsPlugin *plugin, GList **list, GFile *file, GCancellable *cancellable, GError **error) { g_autofree gchar *content_type = NULL; g_autofree gchar *id_prefixed = NULL; g_autoptr(GBytes) appstream_gz = NULL; g_autoptr(GBytes) icon_data = NULL; g_autoptr(GBytes) metadata = NULL; g_autoptr(GsApp) app = NULL; g_autoptr(XdgAppBundleRef) xref_bundle = NULL; const gchar *mimetypes[] = { "application/vnd.xdgapp", NULL }; /* does this match any of the mimetypes we support */ content_type = gs_utils_get_content_type (file, cancellable, error); if (content_type == NULL) return FALSE; if (!g_strv_contains (mimetypes, content_type)) return TRUE; /* load bundle */ xref_bundle = xdg_app_bundle_ref_new (file, error); if (xref_bundle == NULL) { g_prefix_error (error, "error loading bundle: "); return FALSE; } /* create a virtual ID */ id_prefixed = gs_plugin_xdg_app_build_id (XDG_APP_REF (xref_bundle)); /* load metadata */ app = gs_app_new (id_prefixed); gs_app_set_kind (app, AS_APP_KIND_DESKTOP); gs_app_set_state (app, AS_APP_STATE_AVAILABLE_LOCAL); gs_app_set_size_installed (app, xdg_app_bundle_ref_get_installed_size (xref_bundle)); gs_plugin_xdg_app_set_metadata (app, XDG_APP_REF (xref_bundle)); metadata = xdg_app_bundle_ref_get_metadata (xref_bundle); if (!gs_plugin_xdg_app_set_app_metadata (app, g_bytes_get_data (metadata, NULL), g_bytes_get_size (metadata), error)) return FALSE; /* load AppStream */ appstream_gz = xdg_app_bundle_ref_get_appstream (xref_bundle); if (appstream_gz != NULL) { g_autoptr(GZlibDecompressor) decompressor = NULL; g_autoptr(GInputStream) stream_gz = NULL; g_autoptr(GInputStream) stream_data = NULL; g_autoptr(GBytes) appstream = NULL; g_autoptr(AsStore) store = NULL; g_autofree gchar *id = NULL; AsApp *item; /* decompress data */ decompressor = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP); stream_gz = g_memory_input_stream_new_from_bytes (appstream_gz); if (stream_gz == NULL) return FALSE; stream_data = g_converter_input_stream_new (stream_gz, G_CONVERTER (decompressor)); appstream = g_input_stream_read_bytes (stream_data, 0x100000, /* 1Mb */ cancellable, error); if (appstream == NULL) return FALSE; store = as_store_new (); if (!as_store_from_bytes (store, appstream, cancellable, error)) return FALSE; /* find app */ id = g_strdup_printf ("%s.desktop", gs_app_get_xdgapp_name (app)); item = as_store_get_app_by_id (store, id); if (item == NULL) { g_set_error (error, GS_PLUGIN_ERROR, GS_PLUGIN_ERROR_FAILED, "application %s not found", id); return FALSE; } /* copy details from AppStream to app */ if (!gs_appstream_refine_app (plugin, app, item, error)) return FALSE; } /* load icon */ icon_data = xdg_app_bundle_ref_get_icon (xref_bundle, 64 * gs_plugin_get_scale (plugin)); if (icon_data == NULL) icon_data = xdg_app_bundle_ref_get_icon (xref_bundle, 64); if (icon_data != NULL) { g_autoptr(GInputStream) stream_icon = NULL; g_autoptr(GdkPixbuf) pixbuf = NULL; stream_icon = g_memory_input_stream_new_from_bytes (icon_data); pixbuf = gdk_pixbuf_new_from_stream (stream_icon, cancellable, error); if (pixbuf == NULL) return FALSE; gs_app_set_pixbuf (app, pixbuf); } else { g_autoptr(AsIcon) icon = NULL; icon = as_icon_new (); as_icon_set_kind (icon, AS_ICON_KIND_STOCK); as_icon_set_name (icon, "application-x-executable"); gs_app_set_icon (app, icon); } /* not quite true: this just means we can update this specific app */ if (xdg_app_bundle_ref_get_origin (xref_bundle)) gs_app_add_quirk (app, AS_APP_QUIRK_HAS_SOURCE); g_debug ("created local app: %s", gs_app_to_string (app)); gs_app_list_add (list, app); return TRUE; }
static gboolean gs_plugin_steam_refresh (GsPlugin *plugin, guint cache_age, GCancellable *cancellable, GError **error) { g_autoptr(AsStore) store = NULL; g_autoptr(GFile) file = NULL; g_autoptr(GPtrArray) apps = NULL; g_autofree gchar *fn = NULL; g_autofree gchar *fn_xml = NULL; /* check if exists */ fn = g_build_filename (g_get_user_data_dir (), "Steam", "appcache", "appinfo.vdf", NULL); if (!g_file_test (fn, G_FILE_TEST_EXISTS)) { g_debug ("no %s, so skipping", fn); return TRUE; } /* test cache age */ fn_xml = g_build_filename (g_get_user_data_dir (), "app-info", "xmls", "steam.xml.gz", NULL); file = g_file_new_for_path (fn_xml); if (cache_age > 0) { guint tmp; tmp = gs_utils_get_file_age (file); if (tmp < cache_age) { g_debug ("%s is only %u seconds old, so ignoring refresh", fn_xml, tmp); return TRUE; } } /* parse it */ apps = gs_plugin_steam_parse_appinfo_file (fn, error); if (apps == NULL) return FALSE; /* debug */ if (g_getenv ("GS_PLUGIN_STEAM_DEBUG") != NULL) gs_plugin_steam_dump_apps (apps); /* load existing AppStream XML */ store = as_store_new (); as_store_set_origin (store, "steam"); if (g_file_query_exists (file, cancellable)) { if (!as_store_from_file (store, file, NULL, cancellable, error)) return FALSE; } /* update any new applications */ if (!gs_plugin_steam_update_store (plugin, store, apps, error)) return FALSE; /* save new file */ if (!as_store_to_file (store, file, AS_NODE_TO_XML_FLAG_FORMAT_INDENT | AS_NODE_TO_XML_FLAG_FORMAT_MULTILINE, NULL, error)) { gs_utils_error_convert_appstream (error); return FALSE; } return TRUE; }