~ubuntu-branches/ubuntu/precise/folks/precise-201306070638

« back to all changes in this revision

Viewing changes to tools/inspect/inspect.vala

  • Committer: Bazaar Package Importer
  • Author(s): Brian Curtis
  • Date: 2011-02-02 14:22:14 UTC
  • mfrom: (1.2.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20110202142214-ngpuu3mhjxyl430f
Tags: 0.3.4-0ubuntu1
* New Upstream Release
  - libfolks-telepathy.so exports private symbols
  - Add a HACKING file that outlines development policies and coding style
  - Review coding conventions in folks
  - Add folks command line application
  - libfolks hard-codes backend names for debugging
  - Print stack traces for failed tests to improve remote debugging
  - Add static aggregation tests
  - Logger service unavailable in make check
  - Add tests for LinkedHashSet
  - Use better interface names
* debian/control
  -changed Maintainer to XSBC-Original-Maintainer
  -added Maintainer of Ubuntu Core Developers
  -changed libfolks19* > libfolks20*
* debian
  -changed .install and .symbols files from 19 > 20

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2010 Collabora Ltd.
 
3
 *
 
4
 * This library is free software: you can redistribute it and/or modify
 
5
 * it under the terms of the GNU Lesser General Public License as published by
 
6
 * the Free Software Foundation, either version 2.1 of the License, or
 
7
 * (at your option) any later version.
 
8
 *
 
9
 * This library is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU Lesser General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU Lesser General Public License
 
15
 * along with this library.  If not, see <http://www.gnu.org/licenses/>.
 
16
 *
 
17
 * Authors:
 
18
 *       Philip Withnall <philip.withnall@collabora.co.uk>
 
19
 */
 
20
 
 
21
using Folks.Inspect.Commands;
 
22
using Folks;
 
23
using Readline;
 
24
using Gee;
 
25
using GLib;
 
26
 
 
27
/* We have to have a static global instance so that the readline callbacks can
 
28
 * access its data, since they don't pass closures around. */
 
29
static Inspect.Client main_client = null;
 
30
 
 
31
public class Folks.Inspect.Client : Object
 
32
{
 
33
  public HashMap<string, Command> commands;
 
34
  private MainLoop main_loop;
 
35
  private unowned Thread folks_thread;
 
36
  public IndividualAggregator aggregator { get; private set; }
 
37
  public BackendStore backend_store { get; private set; }
 
38
  public SignalManager signal_manager { get; private set; }
 
39
 
 
40
  public static int main (string[] args)
 
41
    {
 
42
      main_client = new Client ();
 
43
      main_client.run_interactive ();
 
44
 
 
45
      return 0;
 
46
    }
 
47
 
 
48
  private void *folks_thread_main ()
 
49
    {
 
50
      this.main_loop = new MainLoop ();
 
51
 
 
52
      this.signal_manager = new SignalManager ();
 
53
 
 
54
      this.aggregator = new IndividualAggregator ();
 
55
      this.aggregator.prepare ();
 
56
 
 
57
      this.backend_store = BackendStore.dup ();
 
58
      this.backend_store.backend_available.connect ((bs, b) => 
 
59
        {
 
60
          Backend backend = (Backend) b;
 
61
 
 
62
          backend.prepare.begin ((obj, result) =>
 
63
            {
 
64
              try
 
65
                {
 
66
                  backend.prepare.end (result);
 
67
                }
 
68
              catch (GLib.Error e)
 
69
                {
 
70
                  warning ("Error preparing Backend '%s': %s", backend.name,
 
71
                      e.message);
 
72
                }
 
73
            });
 
74
        });
 
75
 
 
76
      this.backend_store.load_backends ();
 
77
 
 
78
      this.main_loop.run ();
 
79
 
 
80
      return null;
 
81
    }
 
82
 
 
83
  public Client ()
 
84
    {
 
85
      Utils.init ();
 
86
 
 
87
      this.commands = new HashMap<string, Command> (str_hash, str_equal);
 
88
 
 
89
      /* Register the commands we support */
 
90
      /* FIXME: This should be automatic */
 
91
      this.commands.set ("quit", new Commands.Quit (this));
 
92
      this.commands.set ("help", new Commands.Help (this));
 
93
      this.commands.set ("individuals", new Commands.Individuals (this));
 
94
      this.commands.set ("personas", new Commands.Personas (this));
 
95
      this.commands.set ("backends", new Commands.Backends (this));
 
96
      this.commands.set ("persona-stores", new Commands.PersonaStores (this));
 
97
      this.commands.set ("signals", new Commands.Signals (this));
 
98
 
 
99
      try
 
100
        {
 
101
          this.folks_thread = Thread<void*>.create<void*> (
 
102
              this.folks_thread_main, true);
 
103
        }
 
104
      catch (ThreadError e)
 
105
        {
 
106
          stdout.printf ("Couldn't create aggregator thread: %s", e.message);
 
107
          Process.exit (1);
 
108
        }
 
109
    }
 
110
 
 
111
  public void run_interactive ()
 
112
    {
 
113
      /* Interactive mode: have a little shell which allows the data from
 
114
       * libfolks to be browsed and edited in real time. */
 
115
 
 
116
      /* Allow things to be set for folks-inspect in ~/.inputrc, and install our
 
117
       * own completion function. */
 
118
      Readline.readline_name = "folks-inspect";
 
119
      Readline.attempted_completion_function = Client.completion_cb;
 
120
 
 
121
      /* Main prompt loop */
 
122
      while (true)
 
123
        {
 
124
          string command_line = Readline.readline ("> ");
 
125
 
 
126
          if (command_line == null)
 
127
            continue;
 
128
 
 
129
          command_line = command_line.strip ();
 
130
          if (command_line == "")
 
131
            continue;
 
132
 
 
133
          string subcommand;
 
134
          string command_name;
 
135
          Command command = this.parse_command_line (command_line,
 
136
              out command_name, out subcommand);
 
137
 
 
138
          /* Run the command */
 
139
          if (command != null)
 
140
            command.run (subcommand);
 
141
          else
 
142
            stdout.printf ("Unrecognised command '%s'.\n", command_name);
 
143
 
 
144
          /* Store the command in the history, even if it failed */
 
145
          Readline.History.add (command_line);
 
146
        }
 
147
    }
 
148
 
 
149
  private static Command? parse_command_line (string command_line,
 
150
      out string command_name,
 
151
      out string? subcommand)
 
152
    {
 
153
      string[] parts = command_line.split (" ", 2);
 
154
 
 
155
      if (parts.length < 1)
 
156
        return null;
 
157
 
 
158
      command_name = parts[0];
 
159
      if (parts.length == 2 && parts[1] != "")
 
160
        subcommand = parts[1];
 
161
      else
 
162
        subcommand = null;
 
163
 
 
164
      /* Extract the first part of the command and see if it matches anything in
 
165
       * this.commands */
 
166
      return main_client.commands.get (parts[0]);
 
167
    }
 
168
 
 
169
  [CCode (array_length = false, array_null_terminated = true)]
 
170
  private static string[]? completion_cb (string word,
 
171
      int start,
 
172
      int end)
 
173
    {
 
174
      /* word is the word to complete, and start and end are its bounds inside
 
175
       * Readline.line_buffer, which contains the entire current line. */
 
176
 
 
177
      /* Command name completion */
 
178
      if (start == 0)
 
179
        {
 
180
          return Readline.completion_matches (word,
 
181
              Utils.command_name_completion_cb);
 
182
        }
 
183
 
 
184
      /* Command parameter completion is passed off to the Command objects */
 
185
      string command_name;
 
186
      string subcommand;
 
187
      Command command = Client.parse_command_line (Readline.line_buffer,
 
188
          out command_name,
 
189
          out subcommand);
 
190
 
 
191
      if (command != null)
 
192
        {
 
193
          if (subcommand == null)
 
194
            subcommand = "";
 
195
          return command.complete_subcommand (subcommand);
 
196
        }
 
197
 
 
198
      return null;
 
199
    }
 
200
}
 
201
 
 
202
private abstract class Folks.Inspect.Command
 
203
{
 
204
  protected Client client;
 
205
 
 
206
  public Command (Client client)
 
207
    {
 
208
      this.client = client;
 
209
    }
 
210
 
 
211
  public abstract string name { get; }
 
212
  public abstract string description { get; }
 
213
  public abstract string help { get; }
 
214
 
 
215
  public abstract void run (string? command_string);
 
216
 
 
217
  [CCode (array_length = false, array_null_terminated = true)]
 
218
  public virtual string[]? complete_subcommand (string subcommand)
 
219
    {
 
220
      /* Default implementation */
 
221
      return null;
 
222
    }
 
223
}