diff options
author | Philip Withnall <philip@tecnocode.co.uk> | 2011-07-27 23:44:43 +0100 |
---|---|---|
committer | Philip Withnall <philip@tecnocode.co.uk> | 2011-07-27 23:52:46 +0100 |
commit | 7af3da6ca4342e1f951e29962bf63ccebcb69213 (patch) | |
tree | 63699462892ee4c3741a9c8716856c719a076c91 /tools | |
parent | e532982f321ff623a476d6c211eba2895dc14199 (diff) |
inspect: Add a linking command
Diffstat (limited to 'tools')
-rw-r--r-- | tools/inspect/Makefile.am | 1 | ||||
-rw-r--r-- | tools/inspect/command-linking.vala | 280 | ||||
-rw-r--r-- | tools/inspect/inspect.vala | 1 |
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)); |