summaryrefslogtreecommitdiffstats
path: root/subprojects/extensions-tool/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--subprojects/extensions-tool/src/main.c408
1 files changed, 408 insertions, 0 deletions
diff --git a/subprojects/extensions-tool/src/main.c b/subprojects/extensions-tool/src/main.c
new file mode 100644
index 0000000..c33058d
--- /dev/null
+++ b/subprojects/extensions-tool/src/main.c
@@ -0,0 +1,408 @@
+/* main.c
+ *
+ * Copyright 2018 Florian Müllner <fmuellner@gnome.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+#include <gio/gio.h>
+#include <glib/gi18n.h>
+#include <locale.h>
+
+#include "config.h"
+#include "commands.h"
+#include "common.h"
+
+static const char *
+extension_state_to_string (ExtensionState state)
+{
+ switch (state)
+ {
+ case STATE_ENABLED:
+ return "ENABLED";
+ case STATE_DISABLED:
+ return "DISABLED";
+ case STATE_ERROR:
+ return "ERROR";
+ case STATE_OUT_OF_DATE:
+ return "OUT OF DATE";
+ case STATE_DOWNLOADING:
+ return "DOWNLOADING";
+ case STATE_INITIALIZED:
+ return "INITIALIZED";
+ case STATE_UNINSTALLED:
+ return "UNINSTALLED";
+ }
+ return "UNKNOWN";
+}
+
+static void
+print_nothing (const char *message)
+{
+}
+
+static gboolean
+quiet_cb (const gchar *option_name,
+ const gchar *value,
+ gpointer data,
+ GError **error)
+{
+ g_set_printerr_handler (print_nothing);
+ return TRUE;
+}
+
+GOptionGroup *
+get_option_group ()
+{
+ GOptionEntry entries[] = {
+ { .long_name = "quiet", .short_name = 'q',
+ .description = _("Do not print error messages"),
+ .arg = G_OPTION_ARG_CALLBACK, .arg_data = &quiet_cb,
+ .flags = G_OPTION_FLAG_NO_ARG | G_OPTION_FLAG_IN_MAIN },
+ { NULL }
+ };
+ GOptionGroup *group;
+
+ group = g_option_group_new ("Common", "common options", "common options", NULL, NULL);
+ g_option_group_add_entries (group, entries);
+
+ return group;
+}
+
+void
+show_help (GOptionContext *context, const char *message)
+{
+ g_autofree char *help = NULL;
+
+ if (message)
+ g_printerr ("gnome-extensions: %s\n\n", message);
+
+ help = g_option_context_get_help (context, TRUE, NULL);
+ g_printerr ("%s", help);
+}
+
+GDBusProxy *
+get_shell_proxy (GError **error)
+{
+ return g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ "org.gnome.Shell.Extensions",
+ "/org/gnome/Shell/Extensions",
+ "org.gnome.Shell.Extensions",
+ NULL,
+ error);
+}
+
+GSettings *
+get_shell_settings (void)
+{
+ g_autoptr (GSettingsSchema) schema = NULL;
+ GSettingsSchemaSource *schema_source;
+
+ schema_source = g_settings_schema_source_get_default ();
+ schema = g_settings_schema_source_lookup (schema_source,
+ "org.gnome.shell",
+ TRUE);
+
+ if (schema == NULL)
+ return NULL;
+
+ return g_settings_new_full (schema, NULL, NULL);
+}
+
+GVariant *
+get_extension_property (GDBusProxy *proxy,
+ const char *uuid,
+ const char *property)
+{
+ g_autoptr (GVariant) response = NULL;
+ g_autoptr (GVariant) asv = NULL;
+ g_autoptr (GVariantDict) info = NULL;
+ g_autoptr (GError) error = NULL;
+
+ response = g_dbus_proxy_call_sync (proxy,
+ "GetExtensionInfo",
+ g_variant_new ("(s)", uuid),
+ 0,
+ -1,
+ NULL,
+ &error);
+ if (response == NULL)
+ {
+ g_printerr (_("Failed to connect to GNOME Shell"));
+ return NULL;
+ }
+
+ asv = g_variant_get_child_value (response, 0);
+ info = g_variant_dict_new (asv);
+
+ if (!g_variant_dict_contains (info, "uuid"))
+ {
+ g_printerr (_("Extension “%s” doesn't exist\n"), uuid);
+ return NULL;
+ }
+
+ return g_variant_dict_lookup_value (info, property, NULL);
+}
+
+gboolean
+settings_list_add (GSettings *settings,
+ const char *key,
+ const char *value)
+{
+ g_auto(GStrv) list = NULL;
+ g_auto(GStrv) new_value = NULL;
+ guint n_values;
+ int i;
+
+ if (!g_settings_is_writable (settings, key))
+ return FALSE;
+
+ list = g_settings_get_strv (settings, key);
+
+ if (g_strv_contains ((const char **)list, value))
+ return TRUE;
+
+ n_values = g_strv_length (list);
+ new_value = g_new0 (char *, n_values + 2);
+ for (i = 0; i < n_values; i++)
+ new_value[i] = g_strdup (list[i]);
+ new_value[i] = g_strdup (value);
+
+ g_settings_set_strv (settings, key, (const char **)new_value);
+ g_settings_sync ();
+
+ return TRUE;
+}
+
+gboolean
+settings_list_remove (GSettings *settings,
+ const char *key,
+ const char *value)
+{
+ g_auto(GStrv) list = NULL;
+ g_auto(GStrv) new_value = NULL;
+ const char **s;
+ guint n_values;
+ int i;
+
+ if (!g_settings_is_writable (settings, key))
+ return FALSE;
+
+ list = g_settings_get_strv (settings, key);
+
+ if (!g_strv_contains ((const char **)list, value))
+ return TRUE;
+
+ n_values = g_strv_length (list);
+ new_value = g_new0 (char *, n_values);
+ i = 0;
+ for (s = (const char **)list; *s != NULL; s++)
+ if (!g_str_equal (*s, value))
+ new_value[i++] = g_strdup (*s);
+
+ g_settings_set_strv (settings, key, (const char **)new_value);
+ g_settings_sync ();
+
+ return TRUE;
+}
+
+void
+print_extension_info (GVariantDict *info,
+ DisplayFormat format)
+{
+ const char *uuid, *name, *desc, *path, *url, *author;
+ double state, version;
+
+ g_variant_dict_lookup (info, "uuid", "&s", &uuid);
+ g_print ("%s\n", uuid);
+
+ if (format == DISPLAY_ONELINE)
+ return;
+
+ g_variant_dict_lookup (info, "name", "&s", &name);
+ g_print (" %s: %s\n", _("Name"), name);
+
+ g_variant_dict_lookup (info, "description", "&s", &desc);
+ g_print (" %s: %s\n", _("Description"), desc);
+
+ g_variant_dict_lookup (info, "path", "&s", &path);
+ g_print (" %s: %s\n", _("Path"), path);
+
+ if (g_variant_dict_lookup (info, "url", "&s", &url))
+ g_print (" %s: %s\n", _("URL"), url);
+
+ if (g_variant_dict_lookup (info, "original-author", "&s", &author))
+ g_print (" %s: %s\n", _("Original author"), author);
+
+ if (g_variant_dict_lookup (info, "version", "d", &version))
+ g_print (" %s: %.0f\n", _("Version"), version);
+
+ g_variant_dict_lookup (info, "state", "d", &state);
+ g_print (" %s: %s\n", _("State"), extension_state_to_string (state));
+}
+
+gboolean
+file_delete_recursively (GFile *file,
+ GError **error)
+{
+ g_autoptr (GFileEnumerator) file_enum = NULL;
+ GFile *child;
+
+ file_enum = g_file_enumerate_children (file, NULL, 0, NULL, NULL);
+ if (file_enum)
+ while (TRUE)
+ {
+ if (!g_file_enumerator_iterate (file_enum, NULL, &child, NULL, error))
+ return FALSE;
+
+ if (child == NULL)
+ break;
+
+ if (!file_delete_recursively (child, error))
+ return FALSE;
+ }
+
+ return g_file_delete (file, NULL, error);
+}
+
+
+static int
+handle_version (int argc, char *argv[], gboolean do_help)
+{
+ if (do_help || argc > 1)
+ {
+ if (!do_help)
+ g_printerr ("gnome-extensions: %s\n\n", _("“version” takes no arguments"));
+
+ g_printerr ("%s\n", _("Usage:"));
+ g_printerr (" gnome-extensions version\n");
+ g_printerr ("\n");
+ g_printerr ("%s\n", _("Print version information and exit."));
+
+ return do_help ? 0 : 2;
+ }
+
+ g_print ("%s\n", VERSION);
+
+ return 0;
+}
+
+static void
+usage (void)
+{
+ g_autofree char *help_command = NULL;
+
+ help_command = g_strdup_printf ("gnome-extensions help %s", _("COMMAND"));
+
+ g_printerr ("%s\n", _("Usage:"));
+ g_printerr (" gnome-extensions %s %s\n", _("COMMAND"), _("[ARGS…]"));
+ g_printerr ("\n");
+ g_printerr ("%s\n", _("Commands:"));
+ g_printerr (" help %s\n", _("Print help"));
+ g_printerr (" version %s\n", _("Print version"));
+ g_printerr (" enable %s\n", _("Enable extension"));
+ g_printerr (" disable %s\n", _("Disable extension"));
+ g_printerr (" reset %s\n", _("Reset extension"));
+ g_printerr (" uninstall %s\n", _("Uninstall extension"));
+ g_printerr (" list %s\n", _("List extensions"));
+ g_printerr (" info %s\n", _("Show extension info"));
+ g_printerr (" show %s\n", _("Show extension info"));
+ g_printerr (" prefs %s\n", _("Open extension preferences"));
+ g_printerr (" create %s\n", _("Create extension"));
+ g_printerr (" pack %s\n", _("Package extension"));
+ g_printerr (" install %s\n", _("Install extension bundle"));
+ g_printerr ("\n");
+ g_printerr (_("Use “%s” to get detailed help.\n"), help_command);
+}
+
+int
+main (int argc, char *argv[])
+{
+ const char *command;
+ gboolean do_help = FALSE;
+
+ setlocale (LC_ALL, "");
+ textdomain (GETTEXT_PACKAGE);
+ bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
+
+#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+#endif
+
+ if (argc < 2)
+ {
+ usage ();
+ return 1;
+ }
+
+ command = argv[1];
+ argc--;
+ argv++;
+
+ if (g_str_equal (command, "help"))
+ {
+ if (argc == 1)
+ {
+ usage ();
+ return 0;
+ }
+ else
+ {
+ command = argv[1];
+ do_help = TRUE;
+ }
+ }
+ else if (g_str_equal (command, "--help"))
+ {
+ usage ();
+ return 0;
+ }
+ else if (g_str_equal (command, "--version"))
+ {
+ command = "version";
+ }
+
+ if (g_str_equal (command, "version"))
+ return handle_version (argc, argv, do_help);
+ else if (g_str_equal (command, "enable"))
+ return handle_enable (argc, argv, do_help);
+ else if (g_str_equal (command, "disable"))
+ return handle_disable (argc, argv, do_help);
+ else if (g_str_equal (command, "reset"))
+ return handle_reset (argc, argv, do_help);
+ else if (g_str_equal (command, "list"))
+ return handle_list (argc, argv, do_help);
+ else if (g_str_equal (command, "info"))
+ return handle_info (argc, argv, do_help);
+ else if (g_str_equal (command, "show"))
+ return handle_info (argc, argv, do_help);
+ else if (g_str_equal (command, "prefs"))
+ return handle_prefs (argc, argv, do_help);
+ else if (g_str_equal (command, "create"))
+ return handle_create (argc, argv, do_help);
+ else if (g_str_equal (command, "pack"))
+ return handle_pack (argc, argv, do_help);
+ else if (g_str_equal (command, "install"))
+ return handle_install (argc, argv, do_help);
+ else if (g_str_equal (command, "uninstall"))
+ return handle_uninstall (argc, argv, do_help);
+ else
+ usage ();
+
+ return 1;
+}