summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/import-pidgin.vala288
-rw-r--r--tools/import.vala215
-rw-r--r--tools/inspect.vala42
-rw-r--r--tools/inspect/command-backends.vala103
-rw-r--r--tools/inspect/command-debug.vala55
-rw-r--r--tools/inspect/command-help.vala96
-rw-r--r--tools/inspect/command-individuals.vala92
-rw-r--r--tools/inspect/command-linking.vala347
-rw-r--r--tools/inspect/command-persona-stores.vala109
-rw-r--r--tools/inspect/command-personas.vala92
-rw-r--r--tools/inspect/command-quit.vala57
-rw-r--r--tools/inspect/command-search.vala85
-rw-r--r--tools/inspect/command-set.vala199
-rw-r--r--tools/inspect/command-signals.vala262
-rw-r--r--tools/inspect/inspect.vala620
-rw-r--r--tools/inspect/meson.build35
-rw-r--r--tools/inspect/signal-manager.vala509
-rw-r--r--tools/inspect/utils.vala647
-rw-r--r--tools/meson.build44
19 files changed, 51 insertions, 3846 deletions
diff --git a/tools/import-pidgin.vala b/tools/import-pidgin.vala
deleted file mode 100644
index 0ea729b5..00000000
--- a/tools/import-pidgin.vala
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (C) 2010 Collabora Ltd.
- * Copyright (C) 2013 Philip Withnall
- *
- * This library is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Philip Withnall <philip.withnall@collabora.co.uk>
- */
-
-using GLib;
-using Gee;
-using Xml;
-using Folks;
-
-public class Folks.Importers.Pidgin : Folks.Importer
-{
- private PersonaStore destination_store;
- private uint persona_count = 0;
-
- public override async uint import (PersonaStore destination_store,
- string? source_filename) throws ImportError
- {
- this.destination_store = destination_store;
- string filename = source_filename;
-
- /* Default filename */
- if (filename == null || filename.strip () == "")
- {
- filename = Path.build_filename (Environment.get_home_dir (),
- ".purple", "blist.xml", null);
- }
-
- var file = File.new_for_path (filename);
- if (!file.query_exists ())
- {
- /* Translators: the parameter is a filename. */
- throw new ImportError.MALFORMED_INPUT (_("File %s does not exist."),
- filename);
- }
-
- FileInfo file_info;
- try
- {
- file_info = yield file.query_info_async (
- FileAttribute.ACCESS_CAN_READ, FileQueryInfoFlags.NONE,
- Priority.DEFAULT);
- }
- catch (GLib.Error e)
- {
- throw new ImportError.MALFORMED_INPUT (
- /* Translators: the first parameter is a filename, and the second
- * is an error message. */
- _("Failed to get information about file %s: %s"), filename,
- e.message);
- }
-
- if (!file_info.get_attribute_boolean (FileAttribute.ACCESS_CAN_READ))
- {
- /* Translators: the parameter is a filename. */
- throw new ImportError.MALFORMED_INPUT (_("File %s is not readable."),
- filename);
- }
-
- Xml.Doc* xml_doc = Parser.parse_file (filename);
-
- if (xml_doc == null)
- {
- throw new ImportError.MALFORMED_INPUT (
- /* Translators: the parameter is a filename. */
- _("The Pidgin buddy list file ‘%s’ could not be loaded."),
- filename);
- }
-
- /* Check the root node */
- Xml.Node *root_node = xml_doc->get_root_element ();
-
- if (root_node == null || root_node->name != "purple" ||
- root_node->get_prop ("version") != "1.0")
- {
- /* Free the document manually before throwing because the garbage
- * collector can't work on pointers. */
- delete xml_doc;
- throw new ImportError.MALFORMED_INPUT (
- /* Translators: the parameter is a filename. */
- _("The Pidgin buddy list file ‘%s’ could not be loaded: the root element could not be found or was not recognized."),
- filename);
- }
-
- /* Parse each <blist> child element */
- for (Xml.Node *iter = root_node->children; iter != null;
- iter = iter->next)
- {
- if (iter->type != ElementType.ELEMENT_NODE || iter->name != "blist")
- continue;
-
- yield this.parse_blist (iter);
- }
-
- /* Tidy up */
- delete xml_doc;
-
- stdout.printf (
- /* Translators: the first parameter is the number of buddies which
- * were successfully imported, and the second is a filename. */
- ngettext ("Imported %u buddy from ‘%s’.",
- "Imported %u buddies from ‘%s’.", this.persona_count) + "\n",
- this.persona_count, filename);
-
- /* Return the number of Personas we imported */
- return this.persona_count;
- }
-
- private async void parse_blist (Xml.Node *blist_node)
- {
- for (Xml.Node *iter = blist_node->children; iter != null;
- iter = iter->next)
- {
- if (iter->type != ElementType.ELEMENT_NODE || iter->name != "group")
- continue;
-
- yield this.parse_group (iter);
- }
- }
-
- private async void parse_group (Xml.Node *group_node)
- {
- string group_name = group_node->get_prop ("name");
-
- for (Xml.Node *iter = group_node->children; iter != null;
- iter = iter->next)
- {
- if (iter->type != ElementType.ELEMENT_NODE || iter->name != "contact")
- continue;
-
- Persona persona = yield this.parse_contact (iter);
-
- /* Skip the persona if creating them failed or if they don't support
- * groups. */
- if (persona == null || !(persona is GroupDetails))
- continue;
-
- try
- {
- GroupDetails group_details = (GroupDetails) persona;
- yield group_details.change_group (group_name, true);
- }
- catch (GLib.Error e)
- {
- stderr.printf (
- /* Translators: the first parameter is a persona identifier,
- * and the second is an error message. */
- _("Error changing group of contact ‘%s’: %s") + "\n",
- persona.iid, e.message);
- }
- }
- }
-
- private async Persona? parse_contact (Xml.Node *contact_node)
- {
- string alias = null;
- var im_addresses = new HashMultiMap<string, ImFieldDetails> ();
- string im_address_string = "";
-
- /* Parse the <buddy> elements beneath <contact> */
- for (Xml.Node *iter = contact_node->children; iter != null;
- iter = iter->next)
- {
- if (iter->type != ElementType.ELEMENT_NODE || iter->name != "buddy")
- continue;
-
- string blist_protocol = iter->get_prop ("proto");
- if (blist_protocol == null)
- continue;
-
- string tp_protocol =
- this.blist_protocol_to_tp_protocol (blist_protocol);
- if (tp_protocol == null)
- continue;
-
- /* Parse the <name> and <alias> elements beneath <buddy> */
- for (Xml.Node *subiter = iter->children; subiter != null;
- subiter = subiter->next)
- {
- if (subiter->type != ElementType.ELEMENT_NODE)
- continue;
-
- if (subiter->name == "alias")
- alias = subiter->get_content ();
- else if (subiter->name == "name")
- {
- /* The <name> element seems to give the contact ID, which
- * we need to insert into the Persona's im-addresses property
- * for the linking to work. */
- string im_address = subiter->get_content ();
- im_addresses.set (tp_protocol,
- new ImFieldDetails (im_address));
- im_address_string += " %s\n".printf (im_address);
- }
- }
- }
-
- /* Don't bother if there's no alias and only one IM address */
- if (im_addresses.size < 2 &&
- (alias == null || alias.strip () == "" ||
- alias.strip () == im_address_string.strip ()))
- {
- stdout.printf (
- /* Translators: the parameter is the buddy's IM address. */
- _("Ignoring buddy with no alias and only one IM address:\n%s"),
- im_address_string);
- return null;
- }
-
- /* Create or update the relevant Persona */
- var details = new GLib.HashTable<string, Value?> (str_hash, str_equal);
- Value im_addresses_value = Value (typeof (MultiMap));
- im_addresses_value.set_object (im_addresses);
- details.insert ("im-addresses", im_addresses_value);
-
- Persona persona;
- try
- {
- persona =
- yield this.destination_store.add_persona_from_details (details);
- }
- catch (PersonaStoreError e)
- {
- /* Translators: the first parameter is an alias, the second is a set
- * of IM addresses each on a new line, and the third is an error
- * message. */
- stderr.printf (
- _("Failed to create new contact for buddy with alias ‘%s’ and IM addresses:\n%s\nError: %s\n"),
- alias, im_address_string, e.message);
- return null;
- }
-
- /* Set the Persona's details */
- if (alias != null && persona is AliasDetails)
- ((AliasDetails) persona).alias = alias;
-
- /* Print progress */
- stdout.printf (
- /* Translators: the first parameter is a persona identifier, the
- * second is an alias for the persona, and the third is a set of IM
- * addresses each on a new line. */
- _("Created contact ‘%s’ for buddy with alias ‘%s’ and IM addresses:\n%s"),
- persona.uid, alias, im_address_string);
- this.persona_count++;
-
- return persona;
- }
-
- private string? blist_protocol_to_tp_protocol (string blist_protocol)
- {
- string tp_protocol = blist_protocol;
- if (blist_protocol.has_prefix ("prpl-"))
- tp_protocol = blist_protocol.substring (5);
-
- /* Convert protocol names from Pidgin to Telepathy. Other protocol names
- * should be OK now that we've taken off the "prpl-" prefix. See:
- * http://telepathy.freedesktop.org/spec/Connection_Manager.html#Protocol
- * and http://developer.pidgin.im/wiki/prpl_id. */
- if (tp_protocol == "bonjour")
- tp_protocol = "local-xmpp";
- else if (tp_protocol == "novell")
- tp_protocol = "groupwise";
- else if (tp_protocol == "gg")
- tp_protocol = "gadugadu";
- else if (tp_protocol == "meanwhile")
- tp_protocol = "sametime";
- else if (tp_protocol == "simple")
- tp_protocol = "sip";
-
- return tp_protocol;
- }
-}
diff --git a/tools/import.vala b/tools/import.vala
deleted file mode 100644
index 400dc539..00000000
--- a/tools/import.vala
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2010 Collabora Ltd.
- *
- * This library is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Philip Withnall <philip.withnall@collabora.co.uk>
- */
-
-using GLib;
-using Gee;
-using Xml;
-using Folks;
-
-/*
- * Command line application to import meta-contact information from various
- * places into libfolks' key file backend.
- *
- * Used as follows:
- * folks-import [--source=pidgin] [--source-filename=~/.purple/blist.xml]
- */
-
-public class Folks.ImportTool : Object
-{
- private static string source;
- private static string source_filename;
-
- private const string DEFAULT_SOURCE = "pidgin";
-
- private const OptionEntry[] options =
- {
- { "source", 's', 0, OptionArg.STRING, ref ImportTool.source,
- N_("Source backend name (default: ‘pidgin’)"), "name" },
- { "source-filename", 0, 0, OptionArg.FILENAME,
- ref ImportTool.source_filename,
- N_("Source filename (default: specific to source backend)"), null },
- { null }
- };
-
- public static int main (string[] args)
- {
- Intl.setlocale (LocaleCategory.ALL, "");
- Intl.bindtextdomain (BuildConf.GETTEXT_PACKAGE, BuildConf.LOCALE_DIR);
- Intl.textdomain (BuildConf.GETTEXT_PACKAGE);
-
- OptionContext context = new OptionContext (
- _("— import meta-contact information to libfolks"));
- context.add_main_entries (ImportTool.options, "folks");
-
- try
- {
- context.parse (ref args);
- }
- catch (OptionError e)
- {
- /* Translators: the parameter is an error message. */
- stderr.printf (_("Couldn’t parse command line options: %s") + "\n",
- e.message);
- return 1;
- }
-
- /* We only support importing from Pidgin at the moment */
- if (source == null || source.strip () == "")
- source = ImportTool.DEFAULT_SOURCE;
-
- /* FIXME: We need to create this, even though we don't use it, to prevent
- * debug message spew, as its constructor initialises the log handling.
- * bgo#629096 */
- IndividualAggregator aggregator = IndividualAggregator.dup ();
- aggregator = null;
-
- /* Create a main loop and start importing */
- MainLoop main_loop = new MainLoop ();
-
- bool success = false;
- ImportTool.import.begin ((o, r) =>
- {
- success = ImportTool.import.end (r);
- main_loop.quit ();
- });
-
- main_loop.run ();
-
- return success ? 0 : 1;
- }
-
- private static async bool import ()
- {
- BackendStore backend_store = BackendStore.dup ();
-
- try
- {
- yield backend_store.load_backends ();
- }
- catch (GLib.Error e1)
- {
- /* Translators: the parameter is an error message. */
- stderr.printf (_("Couldn’t load the backends: %s") + "\n",
- e1.message);
- return false;
- }
-
- /* Get the key-file backend */
- Backend kf_backend = backend_store.dup_backend_by_name ("key-file");
-
- if (kf_backend == null)
- {
- /* Translators: the parameter is a backend identifier. */
- stderr.printf (_("Couldn’t load the ‘%s’ backend.") + "\n",
- "key-file");
- return false;
- }
-
- try
- {
- yield kf_backend.prepare ();
- }
- catch (GLib.Error e2)
- {
- /* Translators: the first parameter is a backend identifier and the
- * second parameter is an error message. */
- stderr.printf (_("Couldn’t prepare the ‘%s’ backend: %s") + "\n",
- "key-file", e2.message);
- return false;
- }
-
- /* Get its only PersonaStore */
- PersonaStore destination_store = null;
- var stores = kf_backend.persona_stores.values;
-
- if (stores.size == 0)
- {
- stderr.printf (
- /* Translators: the parameter is a backend identifier. */
- _("Couldn’t load the ‘%s’ backend’s persona store.") + "\n",
- "key-file");
- return false;
- }
-
- try
- {
- /* Get the first persona store */
- foreach (var persona_store in stores)
- {
- destination_store = persona_store;
- break;
- }
-
- yield destination_store.prepare ();
- }
- catch (GLib.Error e3)
- {
- stderr.printf (
- /* Translators: the first parameter is a backend identifier and the
- * second parameter is an error message. */
- _("Couldn’t prepare the ‘%s’ backend’s persona store: %s") + "\n",
- e3.message);
- return false;
- }
-
- if (source == "pidgin")
- {
- Importer importer = new Importers.Pidgin ();
-
- try
- {
- /* Import! */
- yield importer.import (destination_store,
- ImportTool.source_filename);
- }
- catch (ImportError e)
- {
- /* Translators: the parameter is an error message. */
- stderr.printf (_("Error importing contacts: %s") + "\n",
- e.message);
- return false;
- }
-
- /* Wait for the PersonaStore to finish writing its changes to disk */
- yield destination_store.flush ();
-
- return true;
- }
- else
- {
- stderr.printf (
- /* Translators: both parameters are identifiers for backends. */
- _("Unrecognized source backend name ‘%s’. ‘%s’ is currently the only supported source backend.") + "\n",
- source, "pidgin");
- return false;
- }
- }
-}
-
-public errordomain Folks.ImportError
-{
- MALFORMED_INPUT,
-}
-
-public abstract class Folks.Importer : Object
-{
- public abstract async uint import (PersonaStore destination_store,
- string? source_filename) throws ImportError;
-}
diff --git a/tools/inspect.vala b/tools/inspect.vala
new file mode 100644
index 00000000..321172df
--- /dev/null
+++ b/tools/inspect.vala
@@ -0,0 +1,42 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ * Copyright 2023 Collabora, Ltd.
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+public class FolksInspect.Application : GLib.Application {
+ private Application () {
+ Object (application_id: "org.gnome.Folks.Inspect", flags: ApplicationFlags.NON_UNIQUE);
+ }
+
+ public override void activate () {
+ try {
+ var manager = new Folks.Manager.sync ();
+ print ("Found %u addressbooks:\n", manager.get_n_items ());
+ for (uint i = 0; i < manager.get_n_items (); i++) {
+ var store = (Folks.PersonaStore) manager.get_object (i);
+ print (" - %s\n", store.title);
+ }
+ } catch (Error e) {
+ error ("Unable to connect to Folks service: %s", e.message);
+ }
+ }
+
+ public static int main (string[] args) {
+ Application app = new Application ();
+ return app.run (args);
+ }
+}
diff --git a/tools/inspect/command-backends.vala b/tools/inspect/command-backends.vala
deleted file mode 100644
index d2418902..00000000
--- a/tools/inspect/command-backends.vala
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2010 Collabora Ltd.
- *
- * This library is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Philip Withnall <philip.withnall@collabora.co.uk>
- */
-
-using Folks;
-using Gee;
-using GLib;
-
-private class Folks.Inspect.Commands.Backends : Folks.Inspect.Command
-{
- public override string name
- {
- get { return "backends"; }
- }
-
- public override string description
- {
- get { return "Inspect the backends loaded by the aggregator."; }
- }
-
- public override string help
- {
- get
- {
- return "backends List all known backends.\n" +
- "backends [backend name] Display the details of the " +
- "specified backend and list its persona stores.";
- }
- }
-
- public Backends (Client client)
- {
- base (client);
- }
-
- public override async int run (string? command_string)
- {
- if (command_string == null)
- {
- /* List all the backends */
- Collection<Backend> backends =
- this.client.backend_store.list_backends ();
-
- Utils.print_line ("%u backends:", backends.size);
-
- Utils.indent ();
- foreach (Backend backend in backends)
- Utils.print_line ("%s", backend.name);
- Utils.unindent ();
- }
- else
- {
- /* Show the details of a particular backend */
- Backend backend =
- this.client.backend_store.dup_backend_by_name (command_string);
-
- if (backend == null)
- {
- Utils.print_line ("Unrecognised backend name '%s'.",
- command_string);
- return 1;
- }
-
- Utils.print_line ("Backend '%s' with %u persona stores " +
- "(type ID, ID ('display name')):",
- backend.name, backend.persona_stores.size);
-
- /* List the backend's persona stores */
- Utils.indent ();
- foreach (var store in backend.persona_stores.values)
- {
- Utils.print_line ("%s, %s ('%s')", store.type_id, store.id,
- store.display_name);
- }
- Utils.unindent ();
- }
-
- return 0;
- }
-
- public override string[]? complete_subcommand (string subcommand)
- {
- /* @subcommand should be a backend name */
- return Readline.completion_matches (subcommand,
- Utils.backend_name_completion_cb);
- }
-}
diff --git a/tools/inspect/command-debug.vala b/tools/inspect/command-debug.vala
deleted file mode 100644
index 08946c06..00000000
--- a/tools/inspect/command-debug.vala
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2011 Philip Withnall
- *
- * This library is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Philip Withnall <philip@tecnocode.co.uk>
- */
-
-using Folks;
-using GLib;
-
-private class Folks.Inspect.Commands.Debug : Folks.Inspect.Command
-{
- public override string name
- {
- get { return "debug"; }
- }
-
- public override string description
- {
- get { return "Print debugging output from libfolks."; }
- }
-
- public override string help
- {
- get
- {
- return "debug Print status information from libfolks.";
- }
- }
-
- public Debug (Client client)
- {
- base (client);
- }
-
- public override async int run (string? command_string)
- {
- var debug = Folks.Debug.dup ();
- debug.emit_print_status ();
- return 0;
- }
-}
diff --git a/tools/inspect/command-help.vala b/tools/inspect/command-help.vala
deleted file mode 100644
index f5e1e4f6..00000000
--- a/tools/inspect/command-help.vala
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2010 Collabora Ltd.
- *
- * This library is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Philip Withnall <philip.withnall@collabora.co.uk>
- */
-
-using Folks;
-using Gee;
-using GLib;
-
-private class Folks.Inspect.Commands.Help : Folks.Inspect.Command
-{
- public override string name
- {
- get { return "help"; }
- }
-
- public override string description
- {
- get { return "Get help on using the program."; }
- }
-
- public override string help
- {
- get
- {
- return "help Describe all the available " +
- "commands.\n" +
- "help [command name] Give more detailed help on the " +
- "specified command.";
- }
- }
-
- public Help (Client client)
- {
- base (client);
- }
-
- public override async int run (string? command_string)
- {
- if (command_string == null)
- {
- /* Help index */
- Utils.print_line ("Type 'help <command>' for more information " +
- "about a particular command.");
-
- MapIterator<string, Command> iter =
- this.client.commands.map_iterator ();
-
- Utils.indent ();
- while (iter.next () == true)
- {
- Utils.print_line ("%-20s %s", iter.get_key (),
- iter.get_value ().description);
- }
- Utils.unindent ();
- }
- else
- {
- /* Help for a given command */
- Command command = this.client.commands.get (command_string);
- if (command == null)
- {
- Utils.print_line ("Unrecognised command '%s'.", command_string);
- return 1;
- }
- else
- {
- Utils.print_line ("%s", command.help);
- }
- }
-
- return 0;
- }
-
- public override string[]? complete_subcommand (string subcommand)
- {
- /* @subcommand should be a command name */
- return Readline.completion_matches (subcommand,
- Utils.command_name_completion_cb);
- }
-}
diff --git a/tools/inspect/command-individuals.vala b/tools/inspect/command-individuals.vala
deleted file mode 100644
index db486e20..00000000
--- a/tools/inspect/command-individuals.vala
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2010 Collabora Ltd.
- *
- * This library is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Philip Withnall <philip.withnall@collabora.co.uk>
- */
-
-using Folks;
-using Gee;
-using GLib;
-
-private class Folks.Inspect.Commands.Individuals : Folks.Inspect.Command
-{
- public override string name
- {
- get { return "individuals"; }
- }
-
- public override string description
- {
- get
- {
- return "Inspect the individuals currently present in the aggregator";
- }
- }
-
- public override string help
- {
- get
- {
- return "individuals List all known " +
- "individuals.\n" +
- "individuals [individual ID] Display the details of the " +
- "specified individual and list its personas.";
- }
- }
-
- public Individuals (Client client)
- {
- base (client);
- }
-
- public override async int run (string? command_string)
- {
- if (command_string == null)
- {
- /* List all the individuals */
- foreach (var individual in this.client.aggregator.individuals.values)
- {
- Utils.print_individual (individual, false);
- Utils.print_blank_line ();
- }
- }
- else
- {
- /* Display the details of a single individual */
- var individual =
- this.client.aggregator.individuals.get (command_string);
-
- if (individual == null)
- {
- Utils.print_line ("Unrecognised individual ID '%s'.",
- command_string);
- return 1;
- }
-
- Utils.print_individual (individual, true);
- }
-
- return 0;
- }
-
- public override string[]? complete_subcommand (string subcommand)
- {
- /* @subcommand should be an individual ID */
- return Readline.completion_matches (subcommand,
- Utils.individual_id_completion_cb);
- }
-}
diff --git a/tools/inspect/command-linking.vala b/tools/inspect/command-linking.vala
deleted file mode 100644
index f3429609..00000000
--- a/tools/inspect/command-linking.vala
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Copyright (C) 2011 Philip Withnall
- *
- * This library is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Philip Withnall <philip@tecnocode.co.uk>
- */
-
-using Folks;
-using Gee;
-using GLib;
-
-private class Folks.Inspect.Commands.Linking : Folks.Inspect.Command
-{
- private const string[] _valid_subcommands =
- {
- "link-personas",
- "link-individuals",
- "unlink-individual",
- };
-
- public override string name
- {
- get { return "linking"; }
- }
-
- public override string description
- {
- get
- {
- return "Link and unlink personas";
- }
- }
-
- public override string help
- {
- get
- {
- return "linking link-personas [persona 1 UID] " +
- "[persona 2 UID] … " +
- "Link the given personas.\n" +
- "linking link-individuals [individual 1 ID] " +
- "[individual 2 ID] … " +
- "Link the personas in the given individuals.\n" +
- "linking unlink-individual " +
- "[individual ID] " +
- "Unlink the given individual.";
- }
- }
-
- public Linking (Client client)
- {
- base (client);
- }
-
- public override async int run (string? command_string)
- {
- string[] parts = {};
-
- if (command_string != null)
- {
- /* Parse subcommands */
- parts = command_string.split (" ");
- }
-
- if (!Utils.validate_subcommand (this.name, command_string, parts[0],
- Linking._valid_subcommands))
- return 1;
-
- if (parts[0] == "link-personas" || parts[0] == "link-individuals")
- {
- var personas = new HashSet<Persona> (); /* set of personas to link */
-
- if (parts.length < 2)
- {
- if (parts[0] == "link-personas")
- {
- Utils.print_line ("Must pass at least one persona to a " +
- "'link-personas' subcommand.");
- }
- else
- {
- Utils.print_line ("Must pass at least one individual to a " +
- "'link-individuals' subcommand.");
- }
-
- return 1;
- }
-
- /* Link the personas in the given individuals. We must have at least
- * one. */
- for (uint i = 1; i < parts.length; i++)
- {
- if (parts[i] == null || parts[i].strip () == "")
- {
- if (parts[0] == "link-personas")
- {
- Utils.print_line ("Unrecognised persona UID '%s'.",
- parts[i]);
- }
- else
- {
- Utils.print_line ("Unrecognised individual ID '%s'.",
- parts[i]);
- }
-
- return 1;
- }
-
- var found = false;
-
- if (parts[0] == "link-personas")
- {
- var uid = parts[i].strip ();
-
- foreach (var individual in
- this.client.aggregator.individuals.values)
- {
- foreach (Persona persona in individual.personas)
- {
- if (persona.uid == uid)
- {
- personas.add (persona);
- found = true;
- break;
- }
- }
-
- if (found == true)
- {
- break;
- }
- }
-
- if (found == false)
- {
- Utils.print_line ("Unrecognised persona UID '%s'.",
- parts[i]);
- return 1;
- }
- }
- else
- {
- var id = parts[i].strip ();
-
- foreach (var individual in
- this.client.aggregator.individuals.values)
- {
- if (individual.id == id)
- {
- foreach (Persona persona in individual.personas)
- {
- personas.add (persona);
- }
-
- found = true;
- break;
- }
- }
-
- if (found == false)
- {
- Utils.print_line ("Unrecognised individual ID '%s'.",
- parts[i]);
- return 1;
- }
- }
- }
-
- /* Link the personas */
- try
- {
- yield this.client.aggregator.link_personas (personas);
- }
- catch (IndividualAggregatorError e)
- {
- Utils.print_line ("Error (domain: %u, code: %u) linking %u " +
- "personas: %s",
- e.domain, e.code, personas.size, e.message);
- return 1;
- }
-
- /* We can't print out the individual which was produced, as
- * more than one may have been produced (due to anti-links)
- * or several others may have been consumed in the process.
- *
- * Chaos, really. */
- Utils.print_line ("Linking of %u personas was successful.",
- personas.size);
- }
- else if (parts[0] == "unlink-individual")
- {
- if (parts.length != 2)
- {
- Utils.print_line ("Must pass exactly one individual ID to an " +
- "'unlink-individual' subcommand.");
- return 1;
- }
-
- var ind = this.client.aggregator.individuals.get (parts[1]);
-
- if (ind == null)
- {
- Utils.print_line ("Unrecognised individual ID '%s'.", parts[1]);
- return 1;
- }
-
- /* Unlink the individual. */
- try
- {
- yield this.client.aggregator.unlink_individual (ind);
- }
- catch (Error e)
- {
- Utils.print_line ("Error (domain: %u, code: %u) unlinking " +
- "individual '%s': %s",
- e.domain, e.code, ind.id, e.message);
- return 1;
- }
-
- /* Success! */
- Utils.print_line ("Unlinking of individual '%s' was successful.",
- ind.id);
- }
- else
- {
- assert_not_reached ();
- }
-
- return 0;
- }
-
- /* FIXME: These can't be in the subcommand_name_completion_cb() function
- * because Vala doesn't allow static local variables. Erk. */
- [CCode (array_length = false, array_null_terminated = true)]
- private static string[] subcommand_completions;
- private static uint completion_count;
- private static string prefix;
-
- /* Complete a subcommand name (either “link-personas”, “link-individuals”
- * or “unlink-individual”), starting with @word. */
- public static string? subcommand_name_completion_cb (string word,
- int state)
- {
- /* Initialise state. I may have said this before, but whoever wrote the
- * readline API should be shot. */
- if (state == 0)
- {
- string[] parts = word.split (" ");
-
- if (parts.length > 0 &&
- (parts[0] == "link-personas" || parts[0] == "link-individuals"))
- {
- var last_part = parts[parts.length - 1];
-
- if (parts[0] == "link-personas")
- {
- subcommand_completions =
- Readline.completion_matches (last_part,
- Utils.persona_uid_completion_cb);
- }
- else
- {
- subcommand_completions =
- Readline.completion_matches (last_part,
- Utils.individual_id_completion_cb);
- }
-
- if (last_part == "")
- {
- prefix = word;
- }
- else
- {
- prefix = word[0:-last_part.length];
- }
- }
- else if (parts.length > 0 && parts[0] == "unlink-individual")
- {
- /* Only accepts one argument */
- if (parts.length != 2)
- {
- /* Clean up */
- subcommand_completions = null;
- completion_count = 0;
- prefix = "";
-
- return null;
- }
-
- subcommand_completions =
- Readline.completion_matches (parts[1],
- Utils.individual_id_completion_cb);
- prefix = "unlink-individual ";
- }
- else
- {
- subcommand_completions = Linking._valid_subcommands;
- prefix = "";
- }
-
- completion_count = 0;
- }
-
- while (completion_count < subcommand_completions.length)
- {
- var completion = subcommand_completions[completion_count];
- var candidate = prefix + completion;
- completion_count++;
-
- if (completion != null && completion != "" &&
- candidate.has_prefix (word))
- {
- return completion;
- }
- }
-
- /* Clean up */
- subcommand_completions = null;
- completion_count = 0;
- prefix = "";
-
- return null;
- }
-
- public override string[]? complete_subcommand (string subcommand)
- {
- /* @subcommand should be either “link-personas”, “link-individuals”
- * or “unlink-individual” */
- return Readline.completion_matches (subcommand,
- Linking.subcommand_name_completion_cb);
- }
-}
-
-/* vim: filetype=vala textwidth=80 tabstop=2 expandtab: */
diff --git a/tools/inspect/command-persona-stores.vala b/tools/inspect/command-persona-stores.vala
deleted file mode 100644
index 994e49be..00000000
--- a/tools/inspect/command-persona-stores.vala
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2010 Collabora Ltd.
- *
- * This library is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Philip Withnall <philip.withnall@collabora.co.uk>
- */
-
-using Folks;
-using Gee;
-using GLib;
-
-private class Folks.Inspect.Commands.PersonaStores : Folks.Inspect.Command
-{
- public override string name
- {
- get { return "persona-stores"; }
- }
-
- public override string description
- {
- get
- {
- return "Inspect the persona stores loaded by the aggregator";
- }
- }
-
- public override string help
- {
- get
- {
- return "persona-stores List all known " +
- "persona stores.\n" +
- "persona-stores [persona store ID] Display the details of " +
- "the specified persona store and list its personas.";
- }
- }
-
- public PersonaStores (Client client)
- {
- base (client);
- }
-
- public override async int run (string? command_string)
- {
- if (command_string == null)
- {
- /* List all the persona stores */
- Collection<Backend> backends =
- this.client.backend_store.list_backends ();
-
- foreach (Backend backend in backends)
- {
- var stores = backend.persona_stores;
-
- foreach (var persona_store in stores.values)
- {
- Utils.print_persona_store (persona_store, false);
- Utils.print_blank_line ();
- }
- }
- }
- else
- {
- /* Show the details of a particular persona store */
- Collection<Backend> backends =
- this.client.backend_store.list_backends ();
- PersonaStore store = null;
-
- foreach (Backend backend in backends)
- {
- var stores = backend.persona_stores;
- store = stores.get (command_string);
- if (store != null)
- break;
- }
-
- if (store == null)
- {
- Utils.print_line ("Unrecognised persona store ID '%s'.",
- command_string);
- return 1;
- }
-
- Utils.print_persona_store (store, true);
- }
-
- return 0;
- }
-
- public override string[]? complete_subcommand (string subcommand)
- {
- /* @subcommand should be a persona store ID */
- return Readline.completion_matches (subcommand,
- Utils.persona_store_id_completion_cb);
- }
-}
diff --git a/tools/inspect/command-personas.vala b/tools/inspect/command-personas.vala
deleted file mode 100644
index f7f87c01..00000000
--- a/tools/inspect/command-personas.vala
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2010 Collabora Ltd.
- *
- * This library is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Philip Withnall <philip.withnall@collabora.co.uk>
- */
-
-using Folks;
-using Gee;
-using GLib;
-
-private class Folks.Inspect.Commands.Personas : Folks.Inspect.Command
-{
- public override string name
- {
- get { return "personas"; }
- }
-
- public override string description
- {
- get
- {
- return "Inspect the personas currently present in the aggregator";
- }
- }
-
- public override string help
- {
- get
- {
- return "personas List all known personas.\n" +
- "personas [persona UID] Display the details of the " +
- "specified persona.";
- }
- }
-
- public Personas (Client client)
- {
- base (client);
- }
-
- public override async int run (string? command_string)
- {
- bool found_persona = false;
-
- foreach (var individual in this.client.aggregator.individuals.values)
- {
- foreach (Persona persona in individual.personas)
- {
- /* Either list all personas, or only list the one specified */
- if (command_string != null && persona.uid != command_string)
- continue;
-
- Utils.print_persona (persona);
-
- if (command_string == null)
- Utils.print_blank_line ();
- else
- found_persona = true;
- }
- }
-
- /* Return an error if the persona wasn’t found. */
- if (!found_persona && command_string != null)
- {
- Utils.print_line ("Unrecognised persona UID '%s'.", command_string);
- return 1;
- }
-
- return 0;
- }
-
- public override string[]? complete_subcommand (string subcommand)
- {
- /* @subcommand should be a persona UID */
- return Readline.completion_matches (subcommand,
- Utils.persona_uid_completion_cb);
- }
-}
diff --git a/tools/inspect/command-quit.vala b/tools/inspect/command-quit.vala
deleted file mode 100644
index 4a92ff69..00000000
--- a/tools/inspect/command-quit.vala
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2010 Collabora Ltd.
- *
- * This library is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Philip Withnall <philip.withnall@collabora.co.uk>
- */
-
-using Folks;
-using GLib;
-
-private class Folks.Inspect.Commands.Quit : Folks.Inspect.Command
-{
- public override string name
- {
- get { return "quit"; }
- }
-
- public override string description
- {
- get
- {
- return "Quit the program.";
- }
- }
-
- public override string help
- {
- get
- {
- return "quit Quit the program gracefully, like a cow lolloping " +
- "across a green field.";
- }
- }
-
- public Quit (Client client)
- {
- base (client);
- }
-
- public override async int run (string? command_string)
- {
- Process.exit (0);
- }
-}
diff --git a/tools/inspect/command-search.vala b/tools/inspect/command-search.vala
deleted file mode 100644
index 4c8d644b..00000000
--- a/tools/inspect/command-search.vala
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2010 Collabora Ltd.
- *
- * This library is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Alvaro Soliverez <alvaro.soliverez@collabora.co.uk>
- */
-
-using Folks;
-using Gee;
-using GLib;
-
-private class Folks.Inspect.Commands.Search : Folks.Inspect.Command
-{
- public override string name
- {
- get { return "search"; }
- }
-
- public override string description
- {
- get
- {
- return "Search the individuals currently present in the aggregator";
- }
- }
-
- public override string help
- {
- get
- {
- return "search [string] Search the name fields of " +
- "the known individuals for the given string";
- }
- }
-
- public Search (Client client)
- {
- base (client);
- }
-
- public override async int run (string? command_string)
- {
- if (command_string == null)
- {
- /* A search string is required */
- Utils.print_line ("Please enter a search string");
- }
- else
- {
- var query = new SimpleQuery (
- command_string, Query.MATCH_FIELDS_NAMES);
- var search_view = new SearchView (this.client.aggregator, query);
-
- try
- {
- yield search_view.prepare ();
- }
- catch (GLib.Error e)
- {
- GLib.warning ("Error when calling prepare: %s", e.message);
- }
-
- foreach (var individual in search_view.individuals)
- {
- Utils.print_line ("%s %s", individual.id,
- individual.display_name);
- }
- }
-
- return 0;
- }
-}
diff --git a/tools/inspect/command-set.vala b/tools/inspect/command-set.vala
deleted file mode 100644
index 846ab605..00000000
--- a/tools/inspect/command-set.vala
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2012 Jeremy Whiting <jeremy.whiting@collabora.com>
- *
- * This library is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Jeremy Whiting <jeremy.whiting@collabora.com>
- */
-
-using Folks;
-using Gee;
-using GLib;
-
-private class Folks.Inspect.Commands.Set : Folks.Inspect.Command
-{
- private const string[] _valid_subcommands =
- {
- "alias",
- };
-
- public override string name
- {
- get { return "set"; }
- }
-
- public override string description
- {
- get
- {
- return "Set an individual's properties";
- }
- }
-
- public override string help
- {
- get
- {
- return "set alias [individual UID] [new alias]" +
- " Set the alias of the given individual.";
- }
- }
-
- public Set (Client client)
- {
- base (client);
- }
-
- public override async int run (string? command_string)
- {
- string[] parts = {};
-
- if (command_string != null)
- {
- /* Parse subcommands */
- parts = command_string.split (" ");
- }
-
- if (!Utils.validate_subcommand (this.name, command_string, parts[0],
- Set._valid_subcommands))
- return 1;
-
- if (parts[0] == "alias")
- {
- if (parts.length < 3)
- {
- Utils.print_line ("Must pass at least one individual ID and a new alias to an " +
- "'alias' subcommand.");
-
- return 1;
- }
-
- /* To set an attribute on an individual, we must have at least one. */
- if (parts[1] == null || parts[1].strip () == "")
- {
- Utils.print_line ("Unrecognised individual ID '%s'.",
- parts[1]);
-
- return 1;
- }
-
- var id = parts[1].strip ();
-
- var individual = this.client.aggregator.individuals.get (id);
- if (individual == null)
- {
- Utils.print_line ("Unrecognized individual ID '%s'.", id);
- return 1;
- }
-
- try
- {
- var persona = yield this.client.aggregator.ensure_individual_property_writeable (individual, "alias");
-
- /* Since the individual may have changed, use the individual from the new persona. */
- persona.individual.alias = parts[2];
- Utils.print_line ("Setting of individual's alias to '%s' was successful.",
- parts[2]);
- }
- catch (Folks.IndividualAggregatorError e)
- {
- Utils.print_line ("Setting of individual's alias to '%s' failed.",
- parts[2]);
- return 1;
- }
- }
- else
- {
- assert_not_reached ();
- }
-
- return 0;
- }
-
- /* FIXME: These can't be in the subcommand_name_completion_cb() function
- * because Vala doesn't allow static local variables. Erk. */
- [CCode (array_length = false, array_null_terminated = true)]
- private static string[] subcommand_completions;
- private static uint completion_count;
- private static string prefix;
-
- /* Complete a subcommand name (“alias”), starting with @word. */
- public static string? subcommand_name_completion_cb (string word,
- int state)
- {
- if (state == 0)
- {
- string[] parts = word.split (" ");
-
- if (parts.length > 0 &&
- (parts[0] == "alias"))
- {
- var last_part = parts[parts.length - 1];
-
- if (parts[0] == "alias")
- {
- subcommand_completions =
- Readline.completion_matches (last_part,
- Utils.individual_id_completion_cb);
- }
-
- if (last_part == "")
- {
- prefix = word;
- }
- else
- {
- prefix = word[0:-last_part.length];
- }
- }
- else
- {
- subcommand_completions = Set._valid_subcommands;
- prefix = "";
- }
-
- completion_count = 0;
- }
-
- while (completion_count < subcommand_completions.length)
- {
- var completion = subcommand_completions[completion_count];
- var candidate = prefix + completion;
- completion_count++;
-
- if (completion != null && completion != "" &&
- candidate.has_prefix (word))
- {
- return completion;
- }
- }
-
- /* Clean up */
- subcommand_completions = null;
- completion_count = 0;
- prefix = "";
-
- return null;
- }
-
- public override string[]? complete_subcommand (string subcommand)
- {
- /* @subcommand should be “alias” */
- return Readline.completion_matches (subcommand,
- subcommand_name_completion_cb);
- }
-}
-
-/* vim: filetype=vala textwidth=80 tabstop=2 expandtab: */
diff --git a/tools/inspect/command-signals.vala b/tools/inspect/command-signals.vala
deleted file mode 100644
index 2bb54ef0..00000000
--- a/tools/inspect/command-signals.vala
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2010 Collabora Ltd.
- *
- * This library is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Philip Withnall <philip.withnall@collabora.co.uk>
- */
-
-using Folks;
-using Gee;
-using GLib;
-
-/*
- * signals — list signals we're currently connected to
- * signals connect ClassName — connect to all the signals on all the instances
- * of that class
- * signals connect ClassName::signal — connect to the given signal on all the
- * instances of that class
- * signals connect 0xdeadbeef — connect to all the signals on a particular class
- * instance
- * signals connect 0xdeadbeef::signal — connect to the given signal on a
- * particular class instance
- * signals disconnect (as above)
- * signals disconnect — signal handler ID
- * signals ClassName — list all the signals on all the instances of that class,
- * highlighting the ones we're currently connected to
- * signals 0xdeadbeef — list all the signals on a particular class instance,
- * highlighting the ones we're currently connected to
- * signals ClassName::signal — show the details of this signal
- * signals 0xdeadbeef::signal — show the details of this signal
- */
-
-private class Folks.Inspect.Commands.Signals : Folks.Inspect.Command
-{
- private const string[] _valid_subcommands =
- {
- "connect",
- "disconnect",
- };
-
- public override string name
- {
- get { return "signals"; }
- }
-
- public override string description
- {
- get
- {
- return "Allow connection to and display of signals emitted by " +
- "libfolks.";
- }
- }
-
- public override string help
- {
- get
- {
- return "signals " +
- "List signals we're currently connected to.\n" +
- "signals connect [class name] " +
- "Connect to all the signals on all the instances of that " +
- "class.\n" +
- "signals connect [class name]::[signal name] " +
- "Connect to the given signal on all the instances of that " +
- "class.\n" +
- "signals connect [object pointer] " +
- "Connect to all the signals on a particular class instance.\n" +
- "signals connect [object pointer]::[signal name] " +
- "Connect to the given signal on a particular class instance.\n" +
- "signals disconnect " +
- "(As for 'connect'.)\n" +
- "signals [class name] " +
- "List all the signals on all the instances of that class, " +
- "highlighting the ones we're currently connected to.\n" +
- "signals [object pointer] " +
- "List all the signals on a particular class instance, " +
- "highlighting the ones we're currently connected to.\n" +
- "signals [class name]::[signal name] " +
- "Show the details of this signal.\n" +
- "signals [object pointer]::[signal name] " +
- "Show the details of this signal.";
- }
- }
-
- public Signals (Client client)
- {
- base (client);
- }
-
- public override async int run (string? command_string)
- {
- if (command_string == null)
- {
- /* List all the signals we're connected to */
- this.client.signal_manager.list_signals (Type.INVALID, null);
- }
- else
- {
- /* Parse subcommands */
- string[] parts = command_string.split (" ", 2);
-
- if (!Utils.validate_subcommand (this.name, command_string, parts[0],
- Signals._valid_subcommands))
- return 1;
-
- Type class_type;
- Object class_instance;
- string signal_name;
- string detail_string;
-
- if (parts[0] == "connect" || parts[0] == "disconnect")
- {
- /* Connect to or disconnect from a signal */
- if (parts[1] == null || parts[1].strip () == "")
- {
- Utils.print_line ("Unrecognised signal identifier '%s'.",
- parts[1]);
- return 1;
- }
-
- if (this.parse_signal_id (parts[1].strip (), out class_type,
- out class_instance, out signal_name,
- out detail_string) == false)
- {
- return 1;
- }
-
- /* FIXME: Handle "disconnect <signal ID>" */
- if (parts[0] == "connect")
- {
- uint signal_count =
- this.client.signal_manager.connect_to_signal (class_type,
- class_instance, signal_name, detail_string);
- Utils.print_line ("Connected to %u signals.", signal_count);
- }
- else
- {
- uint signal_count =
- this.client.signal_manager.disconnect_from_signal (
- class_type, class_instance, signal_name,
- detail_string);
- Utils.print_line ("Disconnected from %u signals.",
- signal_count);
- }
- }
- else
- {
- /* List some of the signals we're connected to, or display
- * their details. */
- if (this.parse_signal_id (parts[0].strip (), out class_type,
- out class_instance, out signal_name,
- out detail_string) == false)
- {
- return 1;
- }
-
- if (signal_name == null)
- {
- this.client.signal_manager.list_signals (class_type,
- class_instance);
- }
- else
- {
- /* Get the class type from the instance */
- if (class_type == Type.INVALID)
- class_type = class_instance.get_type ();
-
- this.client.signal_manager.show_signal_details (class_type,
- signal_name, detail_string);
- }
- }
- }
-
- return 0;
- }
-
- public override string[]? complete_subcommand (string subcommand)
- {
- /* @subcommand should be a backend name */
- /* TODO */
- return Readline.completion_matches (subcommand,
- Utils.backend_name_completion_cb);
- }
-
- private bool parse_signal_id (string input,
- out Type class_type,
- out Object? class_instance,
- out string? signal_name,
- out string? detail_string)
- {
- /* We accept any of the following formats:
- * ClassName::signal-name
- * ClassName::signal-name::detail
- * 0xdeadbeef::signal-name
- * 0xdeadbeef::signal-name::detail
- * ClassName
- * 0xdeadbeef
- *
- * We output exactly one of class_type and class_instance, and optionally
- * output signal_name and/or detail_string as appropriate.
- */
- assert (input != null && input != "");
-
- /* Default output */
- class_type = Type.INVALID;
- class_instance = null;
- signal_name = null;
- detail_string = null;
-
- string[] parts = input.split ("::", 3);
- string class_name_or_instance = parts[0];
- string signal_name_inner = (parts.length > 1) ? parts[1] : null;
- string detail_string_inner = (parts.length > 2) ? parts[2] : null;
-
- if (signal_name_inner == "" || detail_string_inner == "")
- {
- Utils.print_line ("Invalid signal identifier '%s'.", input);
- return false;
- }
-
- if (class_name_or_instance.length > 2 &&
- class_name_or_instance[0] == '0' && class_name_or_instance[1] == 'x')
- {
- /* We have a class instance. The ‘0x’ prefix ensures it will be
- * parsed in base 16. */
- var address = uint64.parse (class_name_or_instance);
- class_instance = (Object) address;
- assert (class_instance.get_type ().is_object ());
- }
- else
- {
- /* We have a class name */
- class_type = Type.from_name (class_name_or_instance);
- if (class_type == Type.INVALID ||
- (class_type.is_instantiatable () == false &&
- class_type.is_interface () == false))
- {
- Utils.print_line ("Unrecognised class name '%s'.",
- class_name_or_instance);
- return false;
- }
- }
-
- signal_name = signal_name_inner;
- detail_string = detail_string_inner;
-
- return true;
- }
-}
diff --git a/tools/inspect/inspect.vala b/tools/inspect/inspect.vala
deleted file mode 100644
index c4860d76..00000000
--- a/tools/inspect/inspect.vala
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
- * Copyright (C) 2010 Collabora Ltd.
- * Copyright (C) 2012 Philip Withnall
- *
- * This library is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Philip Withnall <philip.withnall@collabora.co.uk>
- */
-
-using Folks.Inspect.Commands;
-using Folks;
-using Readline;
-using Gee;
-using GLib;
-using Posix;
-
-/* We have to have a static global instance so that the readline callbacks can
- * access its data, since they don't pass closures around. */
-static Inspect.Client main_client = null;
-
-public class Folks.Inspect.Client : Object
-{
- public HashMap<string, Command> commands;
- private static bool _is_readline_installed;
- private MainLoop main_loop;
- public IndividualAggregator aggregator { get; private set; }
- public BackendStore backend_store { get; private set; }
- public SignalManager signal_manager { get; private set; }
-
- /* To page or not to page? */
- private termios _original_termios_p;
- private bool _original_termios_p_valid = false;
- private bool _quit_after_pager_dies = false;
- private static Pid _pager_pid = 0;
- private IOChannel? _stdin_channel = null;
- private static uint _stdin_watch_id = 0;
- private FileStream? _pager_channel = null;
- private uint _pager_child_watch_id = 0;
-
- public static int main (string[] args)
- {
- int retval = 0;
-
- Intl.setlocale (LocaleCategory.ALL, "");
- Intl.bindtextdomain (BuildConf.GETTEXT_PACKAGE, BuildConf.LOCALE_DIR);
- Intl.textdomain (BuildConf.GETTEXT_PACKAGE);
-
- /* Parse command line options. */
- OptionContext context = new OptionContext ("[COMMAND]");
- context.set_summary ("Inspect meta-contact information in libfolks.");
-
- try
- {
- context.parse (ref args);
- }
- catch (OptionError e1)
- {
- GLib.stderr.printf ("Couldn’t parse command line options: %s\n",
- e1.message);
- return 1;
- }
-
- /* Create the client. */
- main_client = new Client ();
-
- /* Set up signal handling. */
-#if VALA_0_40
- Unix.signal_add (Posix.Signal.TERM, () =>
-#else
- Unix.signal_add (Posix.SIGTERM, () =>
-#endif
- {
- /* Propagate the signal to our pager process, if it's running. */
- if (Client._pager_pid != 0)
- {
- main_client._quit_after_pager_dies = true;
-#if VALA_0_40
- kill (Client._pager_pid, Posix.Signal.TERM);
-#else
- kill (Client._pager_pid, Posix.SIGTERM);
-#endif
- }
- else
- {
- /* Quit the client and let that exit the process. */
- main_client.quit ();
- }
-
- return false;
- });
-
- /* Run the command. */
- if (args.length == 1)
- {
- main_client.run_interactive.begin ();
- retval = 0;
- }
- else
- {
- GLib.assert (args.length > 1);
-
- /* Drop the first argument and parse the rest as a command line. If
- * the first argument is ‘--’ then the command was passed after some
- * flags. */
- string command_line;
- if (args[1] == "--")
- {
- command_line = string.joinv (" ", args[2:0]);
- }
- else
- {
- command_line = string.joinv (" ", args[1:0]);
- }
-
- main_client.run_non_interactive.begin (command_line, (obj, res) =>
- {
- retval = main_client.run_non_interactive.end (res);
- main_client.quit ();
- });
- }
-
- main_client.main_loop.run ();
-
- return retval;
- }
-
- public Client ()
- {
- Utils.init ();
-
- this.commands = new HashMap<string, Command> ();
-
- /* Register the commands we support */
- /* FIXME: This should be automatic */
- this.commands.set ("quit", new Commands.Quit (this));
- this.commands.set ("help", new Commands.Help (this));
- this.commands.set ("individuals", new Commands.Individuals (this));
- this.commands.set ("linking", new Commands.Linking (this));
- this.commands.set ("personas", new Commands.Personas (this));
- this.commands.set ("backends", new Commands.Backends (this));
- this.commands.set ("persona-stores", new Commands.PersonaStores (this));
- this.commands.set ("set", new Commands.Set (this));
- this.commands.set ("signals", new Commands.Signals (this));
- this.commands.set ("debug", new Commands.Debug (this));
- this.commands.set ("search", new Commands.Search (this));
-
- /* Create various bits of folks machinery. */
- this.main_loop = new MainLoop ();
- this.signal_manager = new SignalManager ();
- this.backend_store = BackendStore.dup ();
- this.aggregator = IndividualAggregator.dup ();
- }
-
- public void quit ()
- {
- /* Stop paging. */
- this._stop_paged_output ();
-
- /* Uninstall readline, if it's installed. */
- if (Client._is_readline_installed)
- {
- this._uninstall_readline_and_stdin ();
- }
-
- /* Restore the user's original terminal settings, since the pager might've
- * fiddled with them. */
- if (this._original_termios_p_valid)
- {
- tcsetattr (Posix.STDIN_FILENO, Posix.TCSADRAIN,
- this._original_termios_p);
- }
-
- /* Kill the main loop. */
- this.main_loop.quit ();
- }
-
- private async void _wait_for_quiescence () throws GLib.Error
- {
- var has_yielded = false;
- var signal_id = this.aggregator.notify["is-quiescent"].connect (
- (obj, pspec) =>
- {
- if (has_yielded == true)
- {
- this._wait_for_quiescence.callback ();
- }
- });
-
- try
- {
- yield this.aggregator.prepare ();
-
- if (this.aggregator.is_quiescent == false)
- {
- has_yielded = true;
- yield;
- }
- }
- finally
- {
- this.aggregator.disconnect (signal_id);
- GLib.assert (this.aggregator.is_quiescent == true);
- }
- }
-
- public async int run_non_interactive (string command_line)
- {
- /* Non-interactive mode: run a single command and output the results.
- * We do this all from the main thread, in a main loop, waiting for
- * quiescence before running the command. */
-
- /* Check we can parse the command first. */
- string subcommand;
- string command_name;
- var command = Client.parse_command_line (command_line, out command_name,
- out subcommand);
-
- if (command == null)
- {
- GLib.stdout.printf ("Unrecognised command ‘%s’.\n", command_name);
- return 1;
- }
-
- /* Wait until we reach quiescence, or the results will probably be
- * useless. */
- try
- {
- yield this._wait_for_quiescence ();
- }
- catch (GLib.Error e1)
- {
- GLib.stderr.printf ("Error preparing aggregator: %s\n", e1.message);
- return 1;
- }
-
- /* Run the command */
- int retval = yield command.run (subcommand);
- this.quit ();
-
- return retval;
- }
-
- public async int run_interactive ()
- {
- /* Interactive mode: have a little shell which allows the data from
- * libfolks to be browsed and edited in real time. We do this by watching
- * stdin in our main loop, and passing character notifications to
- * readline. The main loop also processes all the folks events, thus
- * preventing us having to run a second thread. */
-
- /* Copy the user's original terminal settings. */
- if (tcgetattr (Posix.STDIN_FILENO, out this._original_termios_p) == 0)
- {
- this._original_termios_p_valid = true;
- }
-
- /* Handle SIGINT. */
-#if VALA_0_40
- Unix.signal_add (Posix.Signal.INT, () =>
-#else
- Unix.signal_add (Posix.SIGINT, () =>
-#endif
- {
- if (Client._is_readline_installed == false)
- {
- return true;
- }
-
- /* Tidy up. */
- Readline.free_line_state ();
- Readline.cleanup_after_signal ();
- Readline.reset_after_signal ();
-
- /* Display a fresh prompt. */
- GLib.stdout.printf ("^C");
- Readline.crlf ();
- Readline.reset_line_state ();
- Readline.replace_line ("", 0);
- Readline.redisplay ();
-
- return true;
- });
-
- /* Allow things to be set for folks-inspect in ~/.inputrc, and install our
- * own completion function. */
- Readline.readline_name = "folks-inspect";
- Readline.attempted_completion_function = Client.completion_cb;
- Readline.catch_signals = 0; /* go away, readline */
-
- /* Install readline and the stdin handler. */
- this._stdin_channel = new IOChannel.unix_new (GLib.stdin.fileno ());
- this._install_readline_and_stdin ();
-
- /* Run the aggregator and the main loop. */
- this.aggregator.prepare.begin ();
-
- return 0;
- }
-
- private void _install_readline_and_stdin ()
- {
- /* stdin handler. */
- Client._stdin_watch_id = this._stdin_channel.add_watch (IOCondition.IN,
- this._stdin_handler_cb);
-
- /* Callback for each character appearing on stdin. */
- Readline.callback_handler_install ("> ", Client._readline_handler_cb);
- Client._is_readline_installed = true;
- }
-
- private void _uninstall_readline_and_stdin ()
- {
- Readline.callback_handler_remove ();
- Client._is_readline_installed = false;
-
- Source.remove (Client._stdin_watch_id);
- Client._stdin_watch_id = 0;
- }
-
- /* This should only ever be called while readline is installed. */
- private bool _stdin_handler_cb (IOChannel source, IOCondition cond)
- {
- /* At least a single character is available on stdin, so let readline
- * consume it. */
- if ((cond & IOCondition.IN) != 0)
- {
- Readline.callback_read_char ();
- return true;
- }
-
- assert_not_reached ();
- }
-
- private static void _readline_handler_cb (string? _command_line)
- {
- if (_command_line == null)
- {
- /* EOF. If we've entered some text, don't do anything. Otherwise,
- * quit. */
- if (Readline.line_buffer != "")
- {
- Readline.ding ();
- return;
- }
-
- /* Quit. */
- main_client.quit ();
-
- return;
- }
-
- var command_line = (!) _command_line;
-
- command_line = command_line.strip ();
- if (command_line == "")
- {
- /* If the user's entered a blank line, just display a new prompt
- * without doing anything else. */
- return;
- }
-
- string subcommand;
- string command_name;
- Command command = Client.parse_command_line (command_line,
- out command_name, out subcommand);
-
- /* Run the command */
- if (command != null)
- {
- if (command_name != "quit")
- {
- /* Start paging output. This is stopped when the pager dies. */
- main_client._start_paged_output ();
- }
-
- command.run.begin (subcommand, (obj, res) =>
- {
- command.run.end (res);
-
- if (main_client._pager_channel != null)
- {
- /* Close the stream to the pager so it knows it's
- * reached EOF. */
- main_client._pager_channel = null;
- Utils.output_filestream = GLib.stdout;
- }
- else
- {
- /* Failed to start the pager in the first place. */
- Readline.reset_line_state ();
- Readline.replace_line ("", 0);
- Readline.redisplay ();
- }
- });
-
- }
- else
- {
- GLib.stdout.printf ("Unrecognised command ‘%s’.\n", command_name);
- }
-
- /* Store the command in the history, even if it failed */
- Readline.History.add (command_line);
- }
-
- private void _start_paged_output ()
- {
- /* If the output is not a TTY (because it's a pipe or a file or a
- * toaster) we don't page. */
- if (!isatty (1))
- {
- return;
- }
-
- var pager = Environment.get_variable ("PAGER");
- if (pager != null && pager == "")
- {
- return;
- }
-
- if (pager == null)
- {
- pager = "less -FRSX";
- }
-
- /* Convert command to null terminated array */
- string[] args;
- try
- {
- GLib.Shell.parse_argv (pager, out args);
- }
- catch (GLib.ShellError e)
- {
- warning ("Error parsing pager arguments: %s", e.message);
- return;
- }
-
- /* Remove the readline and stdin handlers while the pager is running. */
- this._uninstall_readline_and_stdin ();
-
- /* Store the readline terminal state so that we can restore them
- * after the pager has exited. */
- Readline.prep_terminal (1);
-
- /* Spawn the pager. */
- int pager_fd = 0;
-
- try
- {
- GLib.Process.spawn_async_with_pipes (null,
- args,
- null,
- GLib.SpawnFlags.LEAVE_DESCRIPTORS_OPEN |
- GLib.SpawnFlags.SEARCH_PATH |
- GLib.SpawnFlags.DO_NOT_REAP_CHILD /* we use a ChildWatch */,
- null,
- out Client._pager_pid,
- out pager_fd, // Std input
- null, // Std out
- null); // Std error
- }
- catch (SpawnError e2)
- {
- warning ("Error spawning pager: %s", e2.message);
-
- /* Reinstall the readline handler and stdin handler. */
- this._install_readline_and_stdin ();
-
- return;
- }
-
- /* Redirect our output to the pager. */
- this._pager_channel = FileStream.fdopen (pager_fd, "w");
- Utils.output_filestream = this._pager_channel;
-
- /* Watch for when the pager exits. */
- this._pager_child_watch_id = ChildWatch.add (Client._pager_pid,
- (pid, status) =>
- {
- /* $PAGER died or was killed. */
- this._stop_paged_output ();
-
- /* Reset the readline state ready to display a new prompt. If the
- * pager exited as the result of a signal, it probably didn't
- * tidy up after itself (e.g. ``less`` leaves a colon prompt
- * behind on the current line), so move to a new line. Doing this
- * normally just looks a bit weird. */
- if (Process.if_signaled (status))
- {
- Readline.crlf ();
- }
-
- Readline.reset_line_state ();
- Readline.replace_line ("", 0);
-
- /* Are we supposed to quit (e.g. due to receiving a SIGTERM)? */
- if (this._quit_after_pager_dies)
- {
- main_client.quit ();
- return;
- }
-
- /* Reinstall the readline handler and stdin handler. */
- this._install_readline_and_stdin ();
- });
- }
-
- private void _stop_paged_output ()
- {
- if (Client._pager_pid == 0)
- {
- return;
- }
-
- Process.close_pid (Client._pager_pid);
- Source.remove (this._pager_child_watch_id);
-
- this._pager_channel = null;
- Utils.output_filestream = GLib.stdout;
- Client._pager_pid = 0;
- this._pager_child_watch_id = 0;
-
- /* Reset the terminal state (e.g. ECHO, which can get left turned
- * off if the pager was killed uncleanly). */
- Readline.deprep_terminal ();
- Readline.free_line_state ();
- Readline.cleanup_after_signal ();
- Readline.reset_after_signal ();
- }
-
- private static Command? parse_command_line (string command_line,
- out string command_name,
- out string? subcommand)
- {
- /* Default output */
- command_name = "";
- subcommand = null;
-
- string[] parts = command_line.split (" ", 2);
-
- if (parts.length < 1)
- return null;
-
- command_name = parts[0];
- if (parts.length == 2 && parts[1] != "")
- subcommand = parts[1];
- else
- subcommand = null;
-
- /* Extract the first part of the command and see if it matches anything in
- * this.commands */
- return main_client.commands.get (parts[0]);
- }
-
- [CCode (array_length = false, array_null_terminated = true)]
- private static string[]? completion_cb (string word,
- int start,
- int end)
- {
- /* word is the word to complete, and start and end are its bounds inside
- * Readline.line_buffer, which contains the entire current line. */
-
- /* Command name completion */
- if (start == 0)
- {
- return Readline.completion_matches (word,
- Utils.command_name_completion_cb);
- }
-
- /* Command parameter completion is passed off to the Command objects */
- string command_name;
- string subcommand;
- Command command = Client.parse_command_line (Readline.line_buffer,
- out command_name,
- out subcommand);
-
- if (command != null)
- {
- if (subcommand == null)
- subcommand = "";
- return command.complete_subcommand (subcommand);
- }
-
- return null;
- }
-}
-
-public abstract class Folks.Inspect.Command
-{
- protected Client client;
-
- protected Command (Client client)
- {
- this.client = client;
- }
-
- public abstract string name { get; }
- public abstract string description { get; }
- public abstract string help { get; }
-
- public abstract async int run (string? command_string);
-
- public virtual string[]? complete_subcommand (string subcommand)
- {
- /* Default implementation */
- return null;
- }
-}
diff --git a/tools/inspect/meson.build b/tools/inspect/meson.build
deleted file mode 100644
index d9203291..00000000
--- a/tools/inspect/meson.build
+++ /dev/null
@@ -1,35 +0,0 @@
-folks_inspect_sources = [
- 'command-backends.vala',
- 'command-debug.vala',
- 'command-help.vala',
- 'command-individuals.vala',
- 'command-linking.vala',
- 'command-persona-stores.vala',
- 'command-personas.vala',
- 'command-quit.vala',
- 'command-search.vala',
- 'command-set.vala',
- 'command-signals.vala',
- 'inspect.vala',
- 'signal-manager.vala',
- 'utils.vala',
-]
-
-folks_inspect_deps = [
- build_conf_dep,
- libfolks_dep,
- posix_dep,
- readline_dep,
-]
-
-folks_inspect_c_flags = [
- '-include', 'config.h',
-]
-
-folks_inspect = executable('folks-inspect',
- folks_inspect_sources,
- dependencies: folks_inspect_deps,
- c_args: folks_inspect_c_flags,
- include_directories: config_h_dir,
- install: true,
-)
diff --git a/tools/inspect/signal-manager.vala b/tools/inspect/signal-manager.vala
deleted file mode 100644
index 7c5b17a0..00000000
--- a/tools/inspect/signal-manager.vala
+++ /dev/null
@@ -1,509 +0,0 @@
-/*
- * Copyright (C) 2010 Collabora Ltd.
- *
- * This library is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Philip Withnall <philip.withnall@collabora.co.uk>
- */
-
-using Folks;
-using Gee;
-using GLib;
-
-public class Folks.Inspect.SignalManager : Object
-{
- /* Map from class type → map from signal ID to hook ID */
- private HashMap<Type, HashMap<uint, ulong>> signals_by_class_type;
- /* Map from class instance → map from signal ID to hook ID */
- private HashMap<Object, HashMap<uint, ulong>> signals_by_class_instance;
-
- public SignalManager ()
- {
- this.signals_by_class_type =
- new HashMap<Type, HashMap<uint, ulong>> ();
- this.signals_by_class_instance =
- new HashMap<Object, HashMap<uint, ulong>> ();
- }
-
- public void list_signals (Type class_type,
- Object? class_instance)
- {
- if (class_type != Type.INVALID)
- {
- /* List the signals we're connected to via emission hooks on this
- * class type */
- HashMap<uint, ulong> hook_ids =
- this.signals_by_class_type.get (class_type);
-
- Utils.print_line ("Signals on all instances of class type '%s':",
- class_type.name ());
- Utils.indent ();
- this.list_signals_for_type (class_type, hook_ids);
- Utils.unindent ();
- }
- else if (class_instance != null)
- {
- /* List the signals we're connected to on this class instance */
- HashMap<uint, ulong> signal_handler_ids =
- this.signals_by_class_instance.get (class_instance);
-
- Utils.print_line ("Signals on instance %p of class type '%s':",
- class_instance, class_instance.get_type ().name ());
- Utils.indent ();
- this.list_signals_for_type (class_instance.get_type (),
- signal_handler_ids);
- Utils.unindent ();
- }
- else
- {
- /* List all the signals we're connected to on everything */
- MapIterator<Type, HashMap<uint, ulong>> class_type_iter =
- this.signals_by_class_type.map_iterator ();
-
- Utils.print_line ("Connected signals on all instances of classes:");
-
- Utils.indent ();
- while (class_type_iter.next () == true)
- {
- HashMap<uint, ulong> hook_ids = class_type_iter.get_value ();
- MapIterator<uint, ulong> hook_iter = hook_ids.map_iterator ();
-
- string class_name = class_type_iter.get_key ().name ();
- while (hook_iter.next () == true)
- {
- Utils.print_line ("%s::%s — connected", class_name,
- Signal.name (hook_iter.get_key ()));
- }
- }
- Utils.unindent ();
-
- MapIterator<Object, HashMap<uint, ulong>> class_instance_iter =
- this.signals_by_class_instance.map_iterator ();
-
- Utils.print_line ("Connected signals on specific instances of " +
- "classes:");
-
- Utils.indent ();
- while (class_instance_iter.next () == true)
- {
- HashMap<uint, ulong> signal_handler_ids =
- class_instance_iter.get_value ();
- MapIterator<uint, ulong> signal_handler_iter =
- signal_handler_ids.map_iterator ();
-
- string class_name =
- class_instance_iter.get_key ().get_type ().name ();
- while (signal_handler_iter.next () == true)
- {
- Utils.print_line ("%s::%s — connected", class_name,
- Signal.name (signal_handler_iter.get_key ()));
- }
- }
- Utils.unindent ();
- }
- }
-
- public void show_signal_details (Type class_type,
- string? signal_name,
- string? detail_string)
- {
- uint signal_id = Signal.lookup (signal_name, class_type);
- if (signal_id == 0)
- {
- Utils.print_line ("Unrecognised signal name '%s' on class '%s'.",
- signal_name, class_type.name ());
- return;
- }
-
- /* Query the signal's information */
- SignalQuery query_info;
- Signal.query (signal_id, out query_info);
-
- /* Print the query response */
- Utils.print_line ("Signal ID %u", query_info.signal_id);
- Utils.print_line ("Signal name %s", query_info.signal_name);
- Utils.print_line ("Emitting type %s", query_info.itype.name ());
- Utils.print_line ("Signal flags %s",
- SignalManager.signal_flags_to_string (query_info.signal_flags));
- Utils.print_line ("Return type %s", query_info.return_type.name ());
- Utils.print_line ("Parameter types:");
- Utils.indent ();
- for (uint i = 0; i < query_info.n_params; i++)
- Utils.print_line ("%-4u %s", i, query_info.param_types[i].name ());
- Utils.unindent ();
- }
-
- public uint connect_to_signal (Type class_type,
- Object? class_instance,
- string? signal_name,
- string? detail_string)
- {
- /* We return the number of signals we connected to */
- if (class_type != Type.INVALID && signal_name != null)
- {
- /* Connecting to a given signal on all instances of a class */
- uint signal_id = Signal.lookup (signal_name, class_type);
- if (signal_id == 0)
- {
- Utils.print_line ("Unrecognised signal name '%s' on class '%s'.",
- signal_name, class_type.name ());
- return 0;
- }
-
- if (this.add_emission_hook (class_type, signal_id,
- detail_string) == false)
- {
- Utils.print_line ("Not allowed to connect to signal '%s' on " +
- "class '%s'.", signal_name, class_type.name ());
- return 0;
- }
-
- return 1;
- }
- else if (class_type != Type.INVALID && signal_name == null)
- {
- /* Connecting to all signals on all instances of a class */
- uint[] signal_ids = Signal.list_ids (class_type);
- uint signal_count = 0;
-
- foreach (uint signal_id in signal_ids)
- {
- if (this.add_emission_hook (class_type, signal_id, null) == true)
- signal_count++;
- }
-
- return signal_count;
- }
- else if (class_instance != null && signal_name != null)
- {
- /* Connecting to a given signal on a given class instance */
- uint signal_id =
- Signal.lookup (signal_name, class_instance.get_type ());
- if (signal_id == 0)
- {
- Utils.print_line ("Unrecognised signal name '%s' on instance " +
- "%p of class '%s'.", signal_name, class_instance,
- class_instance.get_type ().name ());
- return 0;
- }
-
- this.add_signal_handler (class_instance, signal_id, detail_string);
-
- return 1;
- }
- else if (class_instance != null && signal_name == null)
- {
- /* Connecting to all signals on a given class instance */
- uint[] signal_ids = Signal.list_ids (class_instance.get_type ());
- uint signal_count = 0;
-
- foreach (uint signal_id in signal_ids)
- {
- signal_count++;
- this.add_signal_handler (class_instance, signal_id, null);
- }
-
- return signal_count;
- }
-
- assert_not_reached ();
- }
-
- public uint disconnect_from_signal (Type class_type,
- Object? class_instance,
- string? signal_name,
- string? detail_string)
- {
- /* We return the number of signals we disconnected from */
- if (class_type != Type.INVALID && signal_name != null)
- {
- /* Disconnecting from a given signal on all instances of a class */
- uint signal_id = Signal.lookup (signal_name, class_type);
- if (signal_id == 0)
- {
- Utils.print_line ("Unrecognised signal name '%s' on class '%s'.",
- signal_name, class_type.name ());
- return 0;
- }
-
- if (this.remove_emission_hook (class_type, signal_id) == false)
- {
- Utils.print_line ("Could not remove hook for signal '%s' on " +
- "class '%s'.", signal_name, class_type.name ());
- return 0;
- }
-
- return 1;
- }
- else if (class_type != Type.INVALID && signal_name == null)
- {
- /* Disconnecting from all signals on all instances of a class */
- uint[] signal_ids = Signal.list_ids (class_type);
- uint signal_count = 0;
-
- foreach (uint signal_id in signal_ids)
- {
- if (this.remove_emission_hook (class_type, signal_id) == true)
- signal_count--;
- }
-
- return signal_count;
- }
- else if (class_instance != null && signal_name != null)
- {
- /* Disconnecting from a given signal on a given class instance */
- uint signal_id =
- Signal.lookup (signal_name, class_instance.get_type ());
- if (signal_id == 0)
- {
- Utils.print_line ("Unrecognised signal name '%s' on instance " +
- "%p of class '%s'.", signal_name, class_instance,
- class_instance.get_type ().name ());
- return 0;
- }
-
- this.remove_signal_handler (class_instance, signal_id);
-
- return 1;
- }
- else if (class_instance != null && signal_name == null)
- {
- /* Disconnecting from all signals on a given class instance */
- uint[] signal_ids = Signal.list_ids (class_instance.get_type ());
- uint signal_count = 0;
-
- foreach (uint signal_id in signal_ids)
- {
- if (this.remove_signal_handler (class_instance, signal_id))
- signal_count--;
- }
-
- return signal_count;
- }
-
- assert_not_reached ();
- }
-
- private void list_signals_for_type (Type type,
- HashMap<uint, ulong>? signal_id_map)
- {
- uint[] signal_ids = Signal.list_ids (type);
-
- /* Print information about the signals on this type */
- if (signal_ids != null)
- {
- string type_name = type.name ();
- foreach (uint signal_id in signal_ids)
- {
- unowned string signal_name = Signal.name (signal_id);
-
- if (signal_id_map != null &&
- signal_id_map.has_key (signal_id) == true)
- {
- Utils.print_line ("%s::%s — connected",
- type_name, signal_name);
- }
- else
- {
- Utils.print_line ("%s::%s",
- type_name, signal_name);
- }
- }
- }
-
- /* Recurse to the type's interfaces */
- Type[] interfaces = type.interfaces ();
- foreach (Type interface_type in interfaces)
- this.list_signals_for_type (interface_type, signal_id_map);
-
- /* Chain up to the type's parent */
- Type parent_type = type.parent ();
- if (parent_type != Type.INVALID)
- this.list_signals_for_type (parent_type, signal_id_map);
- }
-
- /* FIXME: This is necessary because if we do sizeof(Closure), Vala will
- * generate the following C code: sizeof(GClosure*).
- * This is not what we want. */
- [CCode (cname = "sizeof (GClosure)")] extern const int CLOSURE_STRUCT_SIZE;
-
- private void add_signal_handler (Object class_instance,
- uint signal_id,
- string? detail_string)
- {
- Closure closure = new Closure (SignalManager.CLOSURE_STRUCT_SIZE, this);
- closure.set_meta_marshal (null, SignalManager.signal_meta_marshaller);
-
- Quark detail_quark = 0;
- if (detail_string != null)
- detail_quark = Quark.try_string (detail_string);
-
- ulong signal_handler_id = Signal.connect_closure_by_id (class_instance,
- signal_id, detail_quark, closure, false);
-
- /* Store the signal handler ID so we can list or remove it later */
- HashMap<uint, ulong> signal_handler_ids =
- this.signals_by_class_instance.get (class_instance);
- if (signal_handler_ids == null)
- {
- signal_handler_ids = new HashMap<uint, ulong> ();
- this.signals_by_class_instance.set (class_instance,
- signal_handler_ids);
- }
-
- signal_handler_ids.set (signal_id, signal_handler_id);
- }
-
- private bool remove_signal_handler (Object class_instance,
- uint signal_id)
- {
- HashMap<uint, ulong> signal_handler_ids =
- this.signals_by_class_instance.get (class_instance);
-
- if (signal_handler_ids == null ||
- signal_handler_ids.has_key (signal_id) == false)
- {
- return false;
- }
-
- ulong signal_handler_id = signal_handler_ids.get (signal_id);
- SignalHandler.disconnect (class_instance, signal_handler_id);
- signal_handler_ids.unset (signal_id);
-
- return true;
- }
-
- private static void signal_meta_marshaller (Closure closure,
- out Value? return_value,
- Value[] param_values,
- void *invocation_hint,
- void *marshal_data)
- {
- SignalInvocationHint* hint = (SignalInvocationHint*) invocation_hint;
-
- /* Default output */
- return_value = null;
-
- SignalQuery query_info;
- Signal.query (hint->signal_id, out query_info);
-
- Utils.print_line ("Signal '%s::%s' emitted with parameters:",
- query_info.itype.name (), query_info.signal_name);
-
- Utils.indent ();
- uint i = 0;
- foreach (Value param_value in param_values)
- {
- Utils.print_line ("%-4u %-10s %s", i++, param_value.type ().name (),
- Utils.transform_value_to_string (param_value));
- }
- Utils.unindent ();
- }
-
- private bool add_emission_hook (Type class_type,
- uint signal_id,
- string? detail_string)
- {
- Quark detail_quark = 0;
- if (detail_string != null)
- detail_quark = Quark.try_string (detail_string);
-
- /* Query the signal to check it supports emission hooks */
- SignalQuery query;
- Signal.query (signal_id, out query);
-
- /* FIXME: It would be nice if we could find some way to support NO_HOOKS
- * signals. */
- if ((query.signal_flags & SignalFlags.NO_HOOKS) != 0)
- return false;
-
- ulong hook_id = Signal.add_emission_hook (signal_id,
-#if VALA_0_42
- detail_quark, this.emission_hook_cb);
-#else
- detail_quark, this.emission_hook_cb, null);
-#endif
-
- /* Store the hook ID so we can list or remove it later */
- HashMap<uint, ulong> hook_ids =
- this.signals_by_class_type.get (class_type);
- if (hook_ids == null)
- {
- hook_ids = new HashMap<uint, ulong> ();
- this.signals_by_class_type.set (class_type, hook_ids);
- }
-
- hook_ids.set (signal_id, hook_id);
-
- return true;
- }
-
- private bool remove_emission_hook (Type class_type,
- uint signal_id)
- {
- HashMap<uint, ulong> hook_ids =
- this.signals_by_class_type.get (class_type);
-
- if (hook_ids == null || hook_ids.has_key (signal_id) == false)
- return false;
-
- ulong hook_id = hook_ids.get (signal_id);
- Signal.remove_emission_hook (signal_id, hook_id);
- hook_ids.unset (signal_id);
-
- return true;
- }
-
- private bool emission_hook_cb (SignalInvocationHint hint,
- Value[] param_values)
- {
- SignalQuery query_info;
- Signal.query (hint.signal_id, out query_info);
-
- Utils.print_line ("Signal '%s::%s' emitted with parameters:",
- query_info.itype.name (), query_info.signal_name);
-
- Utils.indent ();
- uint i = 0;
- foreach (Value param_value in param_values)
- {
- Utils.print_line ("%-4u %-10s %s", i++, param_value.type ().name (),
- Utils.transform_value_to_string (param_value));
- }
- Utils.unindent ();
-
- return true;
- }
-
- private static string signal_flags_to_string (SignalFlags flags)
- {
- string output = "";
-
- if ((flags & SignalFlags.RUN_FIRST) != 0)
- output += "G_SIGNAL_RUN_FIRST";
- if ((flags & SignalFlags.RUN_LAST) != 0)
- output += ((output != "") ? " | " : "") + "G_SIGNAL_RUN_LAST";
- if ((flags & SignalFlags.RUN_CLEANUP) != 0)
- output += ((output != "") ? " | " : "") + "G_SIGNAL_RUN_CLEANUP";
- if ((flags & SignalFlags.DETAILED) != 0)
- output += ((output != "") ? " | " : "") + "G_SIGNAL_DETAILED";
- if ((flags & SignalFlags.ACTION) != 0)
- output += ((output != "") ? " | " : "") + "G_SIGNAL_ACTION";
- if ((flags & SignalFlags.NO_HOOKS) != 0)
- output += ((output != "") ? " | " : "") + "G_SIGNAL_NO_HOOKS";
-
- return output;
- }
-}
diff --git a/tools/inspect/utils.vala b/tools/inspect/utils.vala
deleted file mode 100644
index 4bdffbd9..00000000
--- a/tools/inspect/utils.vala
+++ /dev/null
@@ -1,647 +0,0 @@
-/*
- * Copyright (C) 2010 Collabora Ltd.
- *
- * This library is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Philip Withnall <philip.withnall@collabora.co.uk>
- */
-
-using Folks;
-using Gee;
-using GLib;
-
-private class Folks.Inspect.Utils
-{
- /* The current indentation level, in spaces */
- private static uint indentation = 0;
- private static string indentation_string = "";
-
- /* The FILE we're printing output to. */
- public static unowned FileStream output_filestream = GLib.stdout;
-
- public static void init ()
- {
- Utils.indentation_string = "";
- Utils.indentation = 0;
- Utils.output_filestream = GLib.stdout;
-
- /* Register some general transformation functions */
- Value.register_transform_func (typeof (Object), typeof (string),
- Utils.transform_object_to_string);
- Value.register_transform_func (typeof (Folks.PersonaStore),
- typeof (string), Utils.transform_persona_store_to_string);
- Value.register_transform_func (typeof (string[]), typeof (string),
- Utils.transform_string_array_to_string);
- Value.register_transform_func (typeof (DateTime), typeof (string),
- Utils.transform_date_time_to_string);
- }
-
- private static void transform_object_to_string (Value src,
- out Value dest)
- {
- var output = "%p".printf (src.get_object ());
- dest = (owned) output;
- }
-
- private static void transform_persona_store_to_string (Value src,
- out Value dest)
- {
- var store = (Folks.PersonaStore) src;
- var output = "%p: %s, %s (%s)".printf (store, store.type_id,
- store.id, store.display_name);
- dest = (owned) output;
- }
-
- private static void transform_string_array_to_string (Value src,
- out Value dest)
- {
- unowned string[] array = (string[]) src;
- string output = "{ ";
- bool first = true;
- foreach (unowned string element in array)
- {
- if (first == false)
- output += ", ";
- output += "'%s'".printf (element);
- first = false;
- }
- output += " }";
- dest = (owned) output;
- }
-
- private static void transform_date_time_to_string (Value src, out Value dest)
- {
- unowned DateTime? date_time = (DateTime?) src;
- string output = "(null)";
- if (date_time != null)
- {
- output = ((!) date_time).format ("%FT%T%z");
- }
-
- dest = (owned) output;
- }
-
- public static void indent ()
- {
- /* We indent in increments of two spaces */
- Utils.indentation += 2;
- Utils.indentation_string = string.nfill (Utils.indentation, ' ');
- }
-
- public static void unindent ()
- {
- Utils.indentation -= 2;
- Utils.indentation_string = string.nfill (Utils.indentation, ' ');
- }
-
- [PrintfFormat ()]
- public static void print_line (string format, ...)
- {
- /* FIXME: store the va_list temporarily to work around bgo#638308 */
- var valist = va_list ();
- string output = format.vprintf (valist);
- var str = "%s%s".printf (Utils.indentation_string, output);
- Utils.output_filestream.puts (str);
- }
-
- public static void print_blank_line ()
- {
- Utils.output_filestream.puts ("");
- }
-
- public static void print_individual (Individual individual,
- bool show_personas)
- {
- Utils.print_line ("Individual '%s' with %u personas:",
- individual.id, individual.personas.size);
-
- /* List the Individual's properties */
- var properties = individual.get_class ().list_properties ();
-
- Utils.indent ();
- foreach (unowned ParamSpec pspec in properties)
- {
- Value prop_value;
- string output_string;
-
- /* Ignore the personas property if we're printing the personas out */
- if (show_personas == true && pspec.get_name () == "personas")
- continue;
-
- prop_value = Value (pspec.value_type);
- individual.get_property (pspec.get_name (), ref prop_value);
-
- output_string = Utils.property_to_string (individual.get_type (),
- pspec.get_name (), prop_value);
-
- Utils.print_line ("%-20s %s", pspec.get_nick (), output_string);
- }
-
- if (show_personas == true)
- {
- Utils.print_blank_line ();
- Utils.print_line ("Personas:");
-
- Utils.indent ();
- foreach (Persona persona in individual.personas)
- Utils.print_persona (persona);
- Utils.unindent ();
- }
- Utils.unindent ();
- }
-
- public static void print_persona (Persona persona)
- {
- Utils.print_line ("Persona '%s':", persona.uid);
-
- /* List the Persona's properties */
- var properties = persona.get_class ().list_properties ();
-
- Utils.indent ();
- foreach (unowned ParamSpec pspec in properties)
- {
- Value prop_value;
- string output_string;
-
- prop_value = Value (pspec.value_type);
- persona.get_property (pspec.get_name (), ref prop_value);
-
- output_string = Utils.property_to_string (persona.get_type (),
- pspec.get_name (), prop_value);
-
- Utils.print_line ("%-20s %s", pspec.get_nick (), output_string);
- }
- Utils.unindent ();
- }
-
- public static void print_persona_store (PersonaStore store,
- bool show_personas)
- {
- if (store.is_prepared == false)
- {
- Utils.print_line ("Persona store '%s':", store.id);
- Utils.indent ();
- Utils.print_line ("Not prepared.");
- Utils.unindent ();
-
- return;
- }
-
- Utils.print_line ("Persona store '%s' with %u personas:",
- store.id, store.personas.size);
-
- /* List the store's properties */
- var properties = store.get_class ().list_properties ();
-
- Utils.indent ();
- foreach (unowned ParamSpec pspec in properties)
- {
- Value prop_value;
- string output_string;
-
- /* Ignore the personas property if we're printing the personas out */
- if (show_personas == true && pspec.get_name () == "personas")
- continue;
-
- prop_value = Value (pspec.value_type);
- store.get_property (pspec.get_name (), ref prop_value);
-
- output_string = Utils.property_to_string (store.get_type (),
- pspec.get_name (), prop_value);
-
- Utils.print_line ("%-20s %s", pspec.get_nick (), output_string);
- }
-
- if (show_personas == true)
- {
- Utils.print_blank_line ();
- Utils.print_line ("Personas:");
-
- Utils.indent ();
- foreach (var persona in store.personas.values)
- {
- Utils.print_persona (persona);
- }
- Utils.unindent ();
- }
- Utils.unindent ();
- }
-
- private static string property_to_string (Type object_type,
- string prop_name,
- Value prop_value)
- {
- string output_string;
-
- /* Overrides for various known properties */
- if (object_type.is_a (typeof (Individual)) && prop_name == "personas")
- {
- unowned var personas = (Set<Persona>) prop_value.get_object ();
- return "List of %u personas".printf (personas.size);
- }
- else if (object_type.is_a (typeof (PersonaStore)) &&
- prop_name == "personas")
- {
- unowned var personas =
- (Map<string, Persona>) prop_value.get_object ();
- return "Set of %u personas".printf (personas.size);
- }
- else if (prop_name == "groups" ||
- prop_name == "local-ids" ||
- prop_name == "supported-fields" ||
- prop_name == "anti-links")
- {
- unowned var groups = (Set<string>) prop_value.get_object ();
- output_string = "{ ";
- bool first = true;
-
- foreach (var group in groups)
- {
- if (first == false)
- output_string += ", ";
- output_string += "'%s'".printf (group);
- first = false;
- }
-
- output_string += " }";
- return output_string;
- }
- else if (prop_name == "avatar")
- {
- string ret = null;
- unowned var avatar = (LoadableIcon) prop_value.get_object ();
-
- if (avatar != null &&
- avatar is FileIcon && ((FileIcon) avatar).get_file () != null)
- {
- ret = "%p (file: %s)".printf (avatar,
- ((FileIcon) avatar).get_file ().get_uri ());
- }
- else if (avatar != null)
- {
- ret = "%p".printf (avatar);
- }
-
- return ret;
- }
- else if (prop_name == "file")
- {
- string ret = null;
- unowned File? file = (File) prop_value.get_object ();
-
- if (file != null)
- {
- ret = "%p (file: %s)".printf (file, file.get_uri ());
- }
-
- return ret;
- }
- else if (prop_name == "im-addresses" ||
- prop_name == "web-service-addresses")
- {
- unowned var prop_list =
- (MultiMap<string, AbstractFieldDetails<string>>)
- prop_value.get_object ();
- output_string = "{ ";
- bool first = true;
-
- foreach (var k in prop_list.get_keys ())
- {
- if (first == false)
- output_string += ", ";
- output_string += "'%s' : { ".printf (k);
- first = false;
-
- var v = prop_list.get (k);
- bool _first = true;
- foreach (var a in v)
- {
- if (_first == false)
- output_string += ", ";
- output_string += "'%s'".printf (a.value);
- _first = false;
- }
-
- output_string += " }";
- }
-
- output_string += " }";
- return output_string;
- }
- else if (prop_name == "email-addresses" ||
- prop_name == "phone-numbers" ||
- prop_name == "urls")
- {
- output_string = "{ ";
- bool first = true;
- unowned var prop_list =
- (Set<AbstractFieldDetails<string>>) prop_value.get_object ();
-
- foreach (var p in prop_list)
- {
- if (!first)
- {
- output_string += ", ";
- }
- output_string += p.value;
- first = false;
- }
- output_string += " }";
-
- return output_string;
- }
- else if (prop_name == "birthday")
- {
- unowned DateTime dobj = (DateTime) prop_value.get_boxed ();
- if (dobj != null)
- return dobj.to_string ();
- else
- return "";
- }
- else if (prop_name == "postal-addresses")
- {
- output_string = "{ ";
- bool first = true;
- unowned var prop_list =
- (Set<PostalAddressFieldDetails>) prop_value.get_object ();
-
- foreach (var p in prop_list)
- {
- if (!first)
- {
- output_string += ". ";
- }
- output_string += p.value.to_string ();
- first = false;
- }
- output_string += " }";
-
- return output_string;
- }
- else if (prop_name == "notes")
- {
- unowned var notes =
- prop_value.get_object () as Set<NoteFieldDetails>;
-
- output_string = "{ ";
- bool first = true;
-
- foreach (var note in notes)
- {
- if (!first)
- {
- output_string += ", ";
- }
- output_string += note.id;
- first = false;
- }
- output_string += " }";
-
- return output_string;
- }
- else if (prop_name == "roles")
- {
- unowned var roles = (Set<RoleFieldDetails>) prop_value.get_object ();
-
- output_string = "{ ";
- bool first = true;
-
- foreach (var role in roles)
- {
- if (!first)
- {
- output_string += ", ";
- }
- output_string += role.value.to_string ();
- first = false;
- }
- output_string += " }";
-
- return output_string;
- }
- else if (prop_name == "structured-name")
- {
- unowned StructuredName sn = (StructuredName) prop_value.get_object ();
- string ret = null;
- if (sn != null)
- ret = sn.to_string ();
- return ret;
- }
-
- return Utils.transform_value_to_string (prop_value);
- }
-
- public static string transform_value_to_string (Value prop_value)
- {
- if (Value.type_transformable (prop_value.type (), typeof (string)))
- {
- /* Convert to a string value */
- Value string_value = Value (typeof (string));
- prop_value.transform (ref string_value);
- return string_value.get_string ();
- }
- else
- {
- /* Can't convert the property value to a string */
- return "Can't convert from type '%s' to '%s'".printf (
- prop_value.type ().name (), typeof (string).name ());
- }
- }
-
- /* FIXME: This can't be in the command_completion_cb() function because Vala
- * doesn't allow static local variables. Erk. */
- private static MapIterator<string, Command>? command_name_iter = null;
-
- /* Complete a command name, starting with @word. */
- public static string? command_name_completion_cb (string word,
- int state)
- {
- /* Initialise state. Whoever wrote the readline API should be shot. */
- if (state == 0)
- Utils.command_name_iter = main_client.commands.map_iterator ();
-
- while (Utils.command_name_iter.next () == true)
- {
- string command_name = Utils.command_name_iter.get_key ();
- if (command_name.has_prefix (word))
- return command_name;
- }
-
- /* Clean up */
- Utils.command_name_iter = null;
- return null;
- }
-
- /* FIXME: This can't be in the individual_id_completion_cb() function because
- * Vala doesn't allow static local variables. Erk. */
- private static MapIterator<string, Individual>? individual_id_iter = null;
-
- /* Complete an individual's ID, starting with @word. */
- public static string? individual_id_completion_cb (string word,
- int state)
- {
- /* Initialise state. Whoever wrote the readline API should be shot. */
- if (state == 0)
- {
- Utils.individual_id_iter =
- main_client.aggregator.individuals.map_iterator ();
- }
-
- while (Utils.individual_id_iter.next () == true)
- {
- var id = Utils.individual_id_iter.get_key ();
- if (id.has_prefix (word))
- return id;
- }
-
- /* Clean up */
- Utils.individual_id_iter = null;
- return null;
- }
-
- /* FIXME: This can't be in the individual_id_completion_cb() function because
- * Vala doesn't allow static local variables. Erk. */
- private static Iterator<Persona>? persona_uid_iter = null;
-
- /* Complete an individual's ID, starting with @word. */
- public static string? persona_uid_completion_cb (string word,
- int state)
- {
- /* Initialise state. Whoever wrote the readline API should be shot. */
- if (state == 0)
- {
- Utils.individual_id_iter =
- main_client.aggregator.individuals.map_iterator ();
- Utils.persona_uid_iter = null;
- }
-
- while (Utils.persona_uid_iter != null ||
- Utils.individual_id_iter.next () == true)
- {
- var individual = Utils.individual_id_iter.get_value ();
-
- if (Utils.persona_uid_iter == null)
- {
- assert (individual != null);
- Utils.persona_uid_iter = individual.personas.iterator ();
- }
-
- while (Utils.persona_uid_iter.next ())
- {
- var persona = Utils.persona_uid_iter.get ();
- if (persona.uid.has_prefix (word))
- return persona.uid;
- }
-
- /* Clean up */
- Utils.persona_uid_iter = null;
- }
-
- /* Clean up */
- Utils.individual_id_iter = null;
- return null;
- }
-
- /* FIXME: This can't be in the backend_name_completion_cb() function because
- * Vala doesn't allow static local variables. Erk. */
- private static Iterator<Backend>? backend_name_iter = null;
-
- /* Complete an individual's ID, starting with @word. */
- public static string? backend_name_completion_cb (string word,
- int state)
- {
- /* Initialise state. Whoever wrote the readline API should be shot. */
- if (state == 0)
- {
- Utils.backend_name_iter =
- main_client.backend_store.list_backends ().iterator ();
- }
-
- while (Utils.backend_name_iter.next () == true)
- {
- Backend backend = Utils.backend_name_iter.get ();
- if (backend.name.has_prefix (word))
- return backend.name;
- }
-
- /* Clean up */
- Utils.backend_name_iter = null;
- return null;
- }
-
- /* FIXME: This can't be in the persona_store_id_completion_cb() function
- * because Vala doesn't allow static local variables. Erk. */
- private static MapIterator<string, PersonaStore>? persona_store_id_iter =
- null;
-
- /* Complete a persona store's ID, starting with @word. */
- public static string? persona_store_id_completion_cb (string word,
- int state)
- {
- /* Initialise state. Whoever wrote the readline API should be shot. */
- if (state == 0)
- {
- Utils.backend_name_iter =
- main_client.backend_store.list_backends ().iterator ();
- Utils.persona_store_id_iter = null;
- }
-
- while (Utils.persona_store_id_iter != null ||
- Utils.backend_name_iter.next () == true)
- {
- if (Utils.persona_store_id_iter == null)
- {
- Backend backend = Utils.backend_name_iter.get ();
- Utils.persona_store_id_iter =
- backend.persona_stores.map_iterator ();
- }
-
- while (Utils.persona_store_id_iter.next () == true)
- {
- var id = Utils.persona_store_id_iter.get_key ();
- if (id.has_prefix (word))
- return id;
- }
-
- /* Clean up */
- Utils.persona_store_id_iter = null;
- }
-
- /* Clean up */
- Utils.backend_name_iter = null;
- return null;
- }
-
- /* Command validation code for commands which take a well-known set of
- * subcommands. */
- public static bool validate_subcommand (string command,
- string? command_string, string? subcommand, string[] valid_subcommands)
- {
- if (subcommand != null && subcommand in valid_subcommands)
- return true;
-
- /* Print an error. */
- Utils.print_line ("Unrecognised '%s' command '%s'.", command,
- (command_string != null) ? command_string : "");
-
- Utils.print_line ("Valid commands:");
- Utils.indent ();
- foreach (var c in valid_subcommands)
- Utils.print_line ("%s", c);
- Utils.unindent ();
-
- return false;
- }
-}
diff --git a/tools/meson.build b/tools/meson.build
index f91ffde0..a9ba4155 100644
--- a/tools/meson.build
+++ b/tools/meson.build
@@ -1,37 +1,11 @@
-# folks-inspect
-if inspect_tool_enabled
- subdir('inspect')
-endif
+add_languages('vala')
-# folks-import
-if import_tool_enabled
- folks_import_sources = [
- 'import.vala',
- 'import-pidgin.vala',
- ]
-
- folks_import_deps = [
- build_conf_dep,
- gee_dep,
- gobject_dep,
+executable(
+ 'folks-inspect',
+ 'inspect.vala',
+ dependencies: [
+ gio_dep,
glib_dep,
- libfolks_dep,
- libxml_dep,
- ]
-
- folks_import_vala_flags = [
- ]
-
- folks_import_c_flags = [
- '-include', 'config.h',
- ]
-
- folks_import = executable('folks-import',
- folks_import_sources,
- dependencies: folks_import_deps,
- vala_args: folks_import_vala_flags,
- c_args: folks_import_c_flags,
- include_directories: config_h_dir,
- install: true,
- )
-endif
+ folks_dep,
+ ],
+) \ No newline at end of file