示例#1
0
        public static async Task Main(string[] args)
        {
            var options = new DocoptNet.Docopt().Apply(Usage, args, version: "File system sorter sample app 1.0", exit: true);

            var inbox    = options["<directory>"].ToString();
            var outbox   = options["--output"].ToString();
            var errorBox = options["--failures"]?.ToString()
                           ?? Path.Combine(options["<directory>"].ToString(), "failures");

            EnsureDirectoryExists(inbox);
            EnsureDirectoryExists(outbox);
            EnsureDirectoryExists(errorBox);

            var cancellation = new CancellationTokenSource();

            Console.CancelKeyPress += (s, e) =>
            {
                Console.WriteLine("Cancelling processing...");
                cancellation.Cancel();
            };

            var fileSorter = new FileSorter(outbox, errorBox);

            // Creates an EventingDocumentSource wrapping a FileSystemWatcher emitting
            // a new document into the pipeline whenever a document is created in the
            // inbox path.
            var filesystem = FileSystem.WatchForChanges(inbox, cancellation.Token);

            var pipeline = await WaivesApi.CreatePipelineAsync(new WaivesOptions
            {
                ClientId     = "clientId",
                ClientSecret = "clientSecret"
            }, cancellation.Token);

            pipeline.WithDocumentsFrom(filesystem)
            .ClassifyWith(options["<classifier>"].ToString())
            .Then(d => fileSorter.MoveDocument(d))
            .OnDocumentError(e => fileSorter.HandleFailure(e))
            .OnPipelineCompleted(() => Console.WriteLine("Processing completed, press any key to exit."));

            try
            {
                await pipeline.RunAsync(cancellation.Token);
            }
            catch (PipelineException ex)
            {
                Console.WriteLine(ex);
            }
        }
示例#2
0
        /// <summary>
        /// Runs a command with the given console context.
        /// </summary>
        /// <param name="command">The command (including raw arguments) to parse and run.</param>
        /// <param name="console">The <see cref="ConsoleContext"/> to run the command in.</param>
        /// <returns>Whether the command was actually found.</returns>
        public bool RunCommand(string command, ConsoleContext console)
        {
            //First we need to parse the command string into something we can actually use as a query.
            var query = ParseCommand(command);

            //If query is null, don't try to run a command. There was no command.
            if (query == null)
            {
                return(false);
            }
            //If we get to this stage, the query is OK. Let's find a local command.
            var local = _localCommands.FirstOrDefault(x => x.Name == query.Name);

            //If this is null we'll send it off to the server. Well, I haven't implemented the server yet so we'll just return false.
            if (local == null)
            {
                if (!_server.Connected)
                {
                    return(false);
                }
                using (var memstr = new MemoryStream())
                {
                    using (var writer = new BinaryWriter(memstr, Encoding.UTF8))
                    {
                        writer.Write(query.Name);
                        writer.Write(query.ArgumentTokens.Length);
                        foreach (var token in query.ArgumentTokens)
                        {
                            writer.Write(token);
                        }
                        writer.Flush();
                        ManualResetEvent commandDone = new ManualResetEvent(false);

                        Action <ServerBroadcastType, BinaryReader> terminalOutput = (req, r) =>
                        {
                            if (req != ServerBroadcastType.TerminalOutput)
                            {
                                return;
                            }
                            int    count = r.ReadInt32();
                            byte[] data  = r.ReadBytes(count);
                            string str   = Encoding.UTF8.GetString(data);
                            console.Write(str);
                            if (str.ToCharArray().Contains((char)0x02))
                            {
                                commandDone.Set();
                            }
                        };
                        _server.BroadcastReceived += terminalOutput;

                        Stream remoteSlave = null;
                        Thread t           = null;

                        _server.SendMessage(ServerMessageType.TRM_INVOKE, memstr.ToArray(), (res, reader) =>
                        {
                            if (res != ServerResponseType.REQ_SUCCESS)
                            {
                                console.WriteLine("Unexpected, unknown error.");
                                return;
                            }
                            int remoteSlaveId = reader.ReadInt32();

                            remoteSlave = _remoteStreams.Open(remoteSlaveId);

                            t = new Thread(() =>
                            {
                                while (true)
                                {
                                    try
                                    {
                                        char input = (char)console.StandardInput.BaseStream.ReadByte();
                                        remoteSlave.WriteByte((byte)input);
                                    }
                                    catch (TerminationRequestException)
                                    {
                                        remoteSlave.WriteByte(0x02);
                                        remoteSlave.WriteByte((byte)'\n');
                                    }
                                }
                            });

                            t.Start();
                        }).Wait();

                        commandDone.WaitOne();

                        CommandSucceeded?.Invoke(query.Name);

                        _server.BroadcastReceived -= terminalOutput;

                        t.Abort();
                        remoteSlave.Close();
                    }
                }
                return(true);
            }
            else
            {
                //So we have a command query, a console context, and a command.
                //What do we need next? Well, we need our argument dictionary.
                //We can use Docopt.Net and the ITerminalCommand.Usages property to get that.
                //First let's create a Dictionary<string, object> to store our arguments.
                var argumentStore = new Dictionary <string, object>();

                //Next, we retrieve the usage string from the command.
                //The engine creates usage strings during initialization.
                var usage = _usages[local.Name];

                //Then we pass it off to Docopt.
                var docoptArgs = new DocoptNet.Docopt().Apply(usage, query.ArgumentTokens, true, local.Name, false, false);
                //Now we just CTRL+C and CTRL+V from the debug console.
                foreach (var arg in docoptArgs)
                {
                    if (arg.Value != null)
                    {
                        argumentStore.Add(arg.Key, arg.Value.Value);
                    }
                    else
                    {
                        argumentStore.Add(arg.Key, null);
                    }
                }
                //Now we run the command - check for errors!
                try
                {
                    local.Run(console, argumentStore);
                    CommandSucceeded?.Invoke(query.Name);
                }
                catch (TerminationRequestException)
                {
                    console.WriteLine("Killed.");
                    return(true);
                }
                return(true);
            }
        }