summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorPhilip Withnall <philip@tecnocode.co.uk>2011-07-27 23:44:43 +0100
committerPhilip Withnall <philip@tecnocode.co.uk>2011-07-27 23:52:46 +0100
commit7af3da6ca4342e1f951e29962bf63ccebcb69213 (patch)
tree63699462892ee4c3741a9c8716856c719a076c91 /tools
parente532982f321ff623a476d6c211eba2895dc14199 (diff)
inspect: Add a linking command
Diffstat (limited to 'tools')
-rw-r--r--tools/inspect/Makefile.am1
-rw-r--r--tools/inspect/command-linking.vala280
-rw-r--r--tools/inspect/inspect.vala1
3 files changed, 282 insertions, 0 deletions
diff --git a/tools/inspect/Makefile.am b/tools/inspect/Makefile.am
index fd935dfd..6acfaeae 100644
--- a/tools/inspect/Makefile.am
+++ b/tools/inspect/Makefile.am
@@ -14,6 +14,7 @@ folks_inspect_SOURCES = \
command-debug.vala \
command-help.vala \
command-individuals.vala \
+ command-linking.vala \
command-persona-stores.vala \
command-personas.vala \
command-quit.vala \
diff --git a/tools/inspect/command-linking.vala b/tools/inspect/command-linking.vala
new file mode 100644
index 00000000..e1cc34b3
--- /dev/null
+++ b/tools/inspect/command-linking.vala
@@ -0,0 +1,280 @@
+/*
+ * 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
+{
+ 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 unlink-individual [individual ID] " +
+ "Unlink the given individual.";
+ }
+ }
+
+ public Linking (Client client)
+ {
+ base (client);
+ }
+
+ public override void run (string? command_string)
+ {
+ string[] parts = {};
+
+ if (command_string != null)
+ {
+ /* Parse subcommands */
+ parts = command_string.split (" ");
+ }
+
+ if (parts.length < 1 ||
+ (parts[0] != "link-personas" && parts[0] != "unlink-individual"))
+ {
+ Utils.print_line ("Unrecognised 'linking' command '%s'.",
+ command_string);
+ return;
+ }
+
+ if (parts[0] == "link-personas")
+ {
+ var personas = new HashSet<Persona> (); /* set of personas to link */
+
+ if (parts.length < 2)
+ {
+ Utils.print_line ("Must pass at least one persona to a " +
+ "'link-personas' subcommand.");
+ return;
+ }
+
+ /* Link the given personas. We must have at least one. */
+ for (uint i = 1; i < parts.length; i++)
+ {
+ if (parts[i] == null || parts[i].strip () == "")
+ {
+ Utils.print_line ("Unrecognised persona UID '%s'.", parts[i]);
+ return;
+ }
+
+ var found = false;
+ 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;
+ }
+ }
+
+ /* Link the personas */
+ this.client.aggregator.link_personas.begin (personas, (obj, res) =>
+ {
+ try
+ {
+ this.client.aggregator.link_personas.end (res);
+ }
+ catch (IndividualAggregatorError e)
+ {
+ Utils.print_line ("Error (domain: %u, code: %u) linking %u " +
+ "personas: %s",
+ e.domain, e.code, personas.size, e.message);
+ }
+
+ /* 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;
+ }
+
+ var ind = this.client.aggregator.individuals.get (parts[1]);
+
+ if (ind == null)
+ {
+ Utils.print_line ("Unrecognised individual ID '%s'.", parts[1]);
+ return;
+ }
+
+ /* Unlink the individual. */
+ this.client.aggregator.unlink_individual.begin (ind, (obj, res) =>
+ {
+ try
+ {
+ this.client.aggregator.unlink_individual.end (res);
+ }
+ catch (Error e)
+ {
+ Utils.print_line ("Error (domain: %u, code: %u) unlinking " +
+ "individual '%s': %s",
+ e.domain, e.code, ind.id, e.message);
+ }
+
+ /* Success! */
+ Utils.print_line ("Unlinking of individual '%s' was successful.",
+ ind.id);
+ });
+ }
+ else
+ {
+ assert_not_reached ();
+ }
+ }
+
+ /* 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” 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")
+ {
+ var last_part = parts[parts.length - 1];
+
+ subcommand_completions =
+ Readline.completion_matches (last_part,
+ Utils.persona_uid_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 =
+ { "link-personas", "unlink-individual", null };
+ 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” or “unlink-individual” */
+ return Readline.completion_matches (subcommand,
+ this.subcommand_name_completion_cb);
+ }
+}
+
+/* vim: filetype=vala textwidth=80 tabstop=2 expandtab: */
diff --git a/tools/inspect/inspect.vala b/tools/inspect/inspect.vala
index db11141c..f76d80c9 100644
--- a/tools/inspect/inspect.vala
+++ b/tools/inspect/inspect.vala
@@ -91,6 +91,7 @@ public class Folks.Inspect.Client : Object
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));