예제 #1
0
        //Color
        async void Color()
        {
            if (_client == null)
            {
                Setup();
            }
            if (!_client.IsInitialized)
            {
                Karuta.Write("Not connected to lights.");
                return;
            }
            LightCommand cmd    = new LightCommand();
            List <Light> lights = new List <Light>();

            lights.AddRange(await _client.GetLightsAsync());
            foreach (Light l in lights)
            {
                State state = l.State;
                if (state.IsReachable == false || state.IsReachable == null)
                {
                    continue;
                }
                Karuta.Write("\nLight: " + l.Name + " H:" + state.Hue + " S:" + state.Saturation + " B:" + state.Brightness);
            }
        }
예제 #2
0
        public LightingCommand() : base("lights", "Controls lighting via phillips Lighting")
        {
            _default = Setup;
            _user    = Karuta.REGISTY.GetString("lightUser");
            bool?auto = Karuta.REGISTY.GetBool("lightAutostart");

            _autoStart = (auto == null) ? false : (auto == true) ? true : false;

            LoadLightColors();
            RegisterKeyword("on", On);
            RegisterKeyword("off", Off);
            RegisterKeyword("getColors", Color);
            RegisterKeyword("keepColors", KeepColor);
            RegisterKeyword("stop", StopColorKeeper);
            RegisterKeyword("saveColors", SaveColor);
            RegisterKeyword("autostart", () =>
            {
                _autoStart = !_autoStart;
                Karuta.REGISTY.SetValue("lightAutostart", _autoStart);
                Karuta.Write("Autostart " + ((_autoStart) ? "enabled" : "disabled"));
            }, "enable/disable autostart");

            RegisterOption('h', Hue);
            RegisterOption('s', Saturation);
            RegisterOption('b', Brightness);

            init = () =>
            {
                //	if (_autoStart)
                //		KeepColor();
            };
        }
예제 #3
0
        async void Init()
        {
            Karuta.LOGGER.Log("Starting Discord Bot..", _appName);
            try
            {
                ImgurSetup();
            }
            catch (Exception e)
            {
                Karuta.LOGGER.LogError($"Unable to initiate Imgur Connection: {e.Message}", _appName);
            }
            client = new DiscordClient();
            if (string.IsNullOrWhiteSpace(_token))
            {
                _token = Karuta.GetInput("Enter discord token");
                Karuta.REGISTY.SetValue("discordToken", _token);
            }

            client.MessageReceived += MessageRecieved;
            client.UserJoined      += UserJoined;
            try
            {
                await client.Connect(_token, TokenType.Bot);

                client.SetGame("World Domination");
                //SendToAllConsoles("Bot Online");
            }catch (Exception e)
            {
                Karuta.LOGGER.LogWarning($"Unable to initiate connection to discord: {e.Message}", _appName);
                Karuta.LOGGER.LogError(e.StackTrace, _appName, true);
                Karuta.Write("Unable to connect to discord...");
            }
        }
예제 #4
0
 public HelpCommand() : base("help", "show this screen")
 {
     _default = Help;
     init     = () =>
     {
         foreach (CommandIdentity c in Karuta.commandIDs)
         {
             //Karuta.Write(c.name);
             RegisterKeyword(c.name, () =>
             {
                 Karuta.Write("\t" + c.name + "\t" + c.helpMessage);
                 Karuta.Write("\tOptions:");
                 foreach (Option o in c.options)
                 {
                     Karuta.Write("\t\t -" + o.key + "\t" + o.usage);
                 }
                 Karuta.Write("\tKeywords:");
                 foreach (Keyword k in c.keywords)
                 {
                     Karuta.Write("\t\t " + k.keyword + "\t" + k.usage);
                 }
             });
         }
     };
     //RegisterOption('c', c => this.c = c);
 }
예제 #5
0
        public override void Run(string[] args)
        {
            if (args.Length == 1)
            {
                Karuta.Write("The available commands are:");

                /*foreach(Command c in Karuta.commands.Values)
                 * {
                 *      Karuta.Write("\t" + c.name + "\t" + c.helpMessage);
                 *      if (c.usageMessage != null)
                 *              Karuta.Write("\t\tUsage: " + c.usageMessage);
                 * }*/
            }
            else
            {
                for (int i = 1; i < args.Length; i++)
                {
                    if (Karuta.commands.ContainsKey(args[i]))
                    {
                        /*Command c = Karuta.commands[args[i]];
                         * Karuta.Write("\t" + c.name + "\t" + c.helpMessage);
                         * if (c.usageMessage != null)
                         *      Karuta.Write("\t\tUsage: " + c.usageMessage);*/
                    }
                    else
                    {
                        Karuta.Write("No such command '" + args[i] + "'");
                    }
                }
            }
        }
예제 #6
0
        public void ImgurSetup()
        {
            string imgID  = Karuta.REGISTY.GetString("imgur_id");
            string imgSec = Karuta.REGISTY.GetString("imgur_secret");

            if (string.IsNullOrWhiteSpace(imgID) || string.IsNullOrWhiteSpace(imgSec))
            {
                Karuta.Write("Please enter Imgur API information:");
                imgID  = Karuta.GetInput("Imgur API ID");
                imgSec = Karuta.GetInput("Imgur API Sec");
            }
            Karuta.LOGGER.Log("Connecting to imgur...", _appName);
            try
            {
                _imgurClient  = new ImgurClient(imgID, imgSec);
                albumEndpoint = new AlbumEndpoint(_imgurClient);
            }
            catch (Exception e)
            {
                Karuta.Write("Failed to connect");
                Karuta.Write(e.Message);
                _imgurClient = null;
            }

            Karuta.REGISTY.SetValue("imgur_id", imgID);
            Karuta.REGISTY.SetValue("imgur_secret", imgSec);
        }
예제 #7
0
        //private StreamReader responseReader;

        public override void Run(string[] args)
        {
            WebRequest request;

            if (args.Length == 3)
            {
                string req = GetValueOfOption(args, 'r');
                if (req == null)
                {
                    Karuta.Write("A request parameter must be provided");
                    return;
                }
                try
                {
                    request = WebRequest.Create(serverURL + req);
                    Stream response = request.GetResponse().GetResponseStream();
                    using (StreamReader responseReader = new StreamReader(response))
                        Karuta.Write(responseReader.ReadToEnd());
                } catch (Exception e)
                {
                    Karuta.Write(e.Message);
                }
                return;
            }
            try
            {
                request = WebRequest.Create(serverURL + "/status/sessions");
                WebHeaderCollection header = new WebHeaderCollection();
                if (_authToken == null)
                {
                    _authToken = GetAuthToken();
                }
                Karuta.Write("Auth: " + _authToken);
                header.Add("X-Plex-Token", _authToken);
                request.Headers = header;
                using (Stream response = request.GetResponse().GetResponseStream())
                {
                    using (StreamReader responseReader = new StreamReader(response))
                    {
                        Karuta.Write(responseReader.ReadToEnd());
                        using (XmlReader reader = XmlReader.Create(new StringReader(responseReader.ReadToEnd())))
                        {
                            reader.ReadToFollowing("Track");
                            reader.MoveToAttribute("title");
                            string title = reader.Value;
                            reader.MoveToAttribute("originalTitle");
                            string artist = reader.Value;
                            Karuta.Write("Now Playing:");
                            Karuta.Write("\t" + artist + " - " + title);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Karuta.Write(e.Message);
            }
            Close();
        }
예제 #8
0
        async void Save()
        {
            await _channel.SendMessage("Saving Data...");

            Karuta.InvokeCommand("save", new List <string>());
            Karuta.Write("Data is saved:");
            _bot.SaveData();
            await _channel.SendMessage("Saved!");
        }
예제 #9
0
        //Brightness
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
        async void Brightness(string b)
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
        {
            if (_client == null)
            {
                Setup();
            }
            if (!_client.IsInitialized)
            {
                Karuta.Write("Not connected to lights.");
                return;
            }
        }
예제 #10
0
 //Keep Colors
 private void KeepColor()
 {
     if (string.IsNullOrWhiteSpace(_user))
     {
         _client = new LocalHueClient(_url);
         _client.Initialize(_user);
     }
     if (_client == null)
     {
         Setup();
     }
     if (!_client.IsInitialized)
     {
         Karuta.Write("Not connected to lights.");
         return;
     }
     if (_colorKeeper != null)
     {
         Karuta.Write("Color Keeper is already running!");
         return;
     }
     if (_lightColors?.Count == 0)
     {
         Karuta.Write("No colors saved.");
         return;
     }
     _colorKeeper = Karuta.StartTimer("Lights Color Keeper", async info =>
     {
         foreach (Light l in await _client.GetLightsAsync())
         {
             State state = l.State;
             if (state.Saturation == _defaultColor.s && state.Hue == _defaultColor.h && state.Brightness == (byte)_defaultColor.b)
             {
                 try
                 {
                     Color curColor   = _lightColors[l.Id];
                     LightCommand cmd = new LightCommand();
                     cmd.Hue          = curColor.h;
                     cmd.Saturation   = curColor.s;
                     await _client.SendCommandAsync(cmd, new string[] { l.Id });
                 }catch (Exception e)
                 {
                     Karuta.LOGGER.LogWarning(e.Message, nameof(LightCommand));
                 }
             }
         }
     }, 0, 1000);
 }
예제 #11
0
        //Turns Lights off
        async void Off()
        {
            if (_client == null)
            {
                Setup();
            }
            if (!_client.IsInitialized)
            {
                Karuta.Write("Not connected to lights.");
                return;
            }
            LightCommand cmd = new LightCommand();

            cmd.On = false;
            await _client.SendCommandAsync(cmd);
        }
예제 #12
0
        public DiscordBot() : base("discord", "a discord bot")
        {
            //Thread.CurrentThread.Name = "DiscordBot";
            _default = Init;
            _token   = Karuta.REGISTY.GetString("discordToken");
            bool?auto = Karuta.REGISTY.GetBool("discordAutostart");

            _autoStart = (auto == null) ? false : (auto == true) ? true : false;
            RegisterKeyword("stop", Stop, "stops the bot");
            RegisterKeyword("autostart", () =>
            {
                _autoStart = !_autoStart;
                Karuta.REGISTY.SetValue("discordAutostart", _autoStart);
                Karuta.Write($"Autostart {((_autoStart) ? "enabled" : "disabled")}");
            }, "enable/disable autostart");

            RegisterOption('t', s =>
            {
                _token = s;
                Karuta.REGISTY.SetValue("discordToken", _token);
                Karuta.Write("Token Saved");
            }, "set the token");

            interpreter = new DiscordCommandInterpreter <DiscordCommand>()
            {
                adminUserID = _adminUserID,
                rateLimit   = 5
            };

            RegisterSystemCommands();

            LoadData();

            interpreter.Init();

            init = () =>
            {
                if (_autoStart)
                {
                    _default();
                }
            };
        }
예제 #13
0
        //Save current Colors
        private async void SaveColor()
        {
            if (_client == null)
            {
                Setup();
            }
            if (!_client.IsInitialized)
            {
                Karuta.Write("Not connected to lights.");
                return;
            }
            List <Light> lights = new List <Light>();

            lights.AddRange(await _client.GetLightsAsync());
            foreach (Light l in lights)
            {
                State state = l.State;
                if (state.IsReachable == true)
                {
                    if (_lightColors.ContainsKey(l.Id))
                    {
                        _lightColors[l.Id] = new Color((int)state.Hue, (int)state.Saturation, state.Brightness);
                    }
                    else
                    {
                        _lightColors.Add(l.Id, new Color((int)state.Hue, (int)state.Saturation, state.Brightness));
                    }
                }
            }
            string data = "";

            foreach (string s in _lightColors.Keys)
            {
                if (data != "")
                {
                    data += "|";
                }
                data += s + "`" + _lightColors[s].ToString();
            }
            Karuta.REGISTY.SetValue("lightColors", data);
            Karuta.Write("Colors Saved!");
        }
예제 #14
0
        public TestCommand() : base("test", "test")
        {
            _default = () =>
            {
                Karuta.Write((DateTime.Now - DateTime.Now.AddSeconds(25)).TotalSeconds);
                Karuta.CreateThread("testThread", () => Karuta.Write("Test")).Abort();
            };

            RegisterOption('t', t =>
            {
                int time;
                if (int.TryParse(t, out time))
                {
                    Timer timer = new Timer(info =>
                    {
                        Karuta.Write(DateTime.Now.Second);
                    }, null, 0, time);
                }
            });
        }
예제 #15
0
 public override void Stop()
 {
     /*if(client != null)
      * {
      *      foreach(Server s in client.Servers)
      *      {
      *              Karuta.Write(s.Name);
      *              foreach(Channel c in s.FindChannels("console", null, true))
      *              {
      *                      await c.SendMessage("Bot shutting down...");
      *              }
      *      }
      * }
      * Thread.Sleep(2 * 1000);*/
     Karuta.Write("Shutting down...");
     Karuta.LOGGER.Log("Shutting down bot...", _appName);
     client?.Disconnect();
     client = null;
     SaveData();
 }
예제 #16
0
        public override void Run(string[] args)
        {
            if (args.Length < 4)
            {
                Karuta.Write("too few arguments");
                return;
            }
            string size = GetValueOfOption(args, 's');

            if (size == null)
            {
                Karuta.Write("no size provided");
                return;
            }
            int    optionPos      = GetIndexOfOption(args, 's');
            int    valueStackSize = GetValueStackSize(args, optionPos);
            string shape;

            if (optionPos + valueStackSize > args.Length)
            {
                shape = args[optionPos + valueStackSize + 1];
            }
            else
            {
                shape = args[optionPos - 2];
            }
            if (shape == null)
            {
                Karuta.Write("Error");
                return;
            }
            if (validShapes.Contains(shape))
            {
                DrawShape(shape);
            }
            else
            {
                Karuta.Write("Invalid Shape");
                Karuta.Write(usageMessage);
            }
        }
예제 #17
0
        void ListAll()
        {
            if (_threads.Count != 0)
            {
                Karuta.Write("\tThreads:");
                Karuta.Write("\t\tName \t\t Thread State");
                foreach (Thread t in _threads.Values)
                {
                    Karuta.Write($"\t\t{t.Name}\t\t{t.ThreadState}");
                }
            }

            if (_timers.Count != 0)
            {
                Karuta.Write("\tTimers:");
                foreach (string t in _timers.Keys)
                {
                    Karuta.Write($"\t\t{t}");
                }
            }
        }
예제 #18
0
 //Setup
 async void Setup()
 {
     _client = new LocalHueClient(_url);
     try
     {
         if (_user == "" || _user == null)
         {
             _user = await _client.RegisterAsync("Karuta.lighting", "Karuta");
         }
         else
         {
             _client.Initialize(_user);
         }
     }catch (Exception e)
     {
         Karuta.Write(e.Message);
         Karuta.Write(e.StackTrace);
     }
     Karuta.REGISTY.SetValue("lightuser", _user);
     List <Light> light = new List <Light>();
 }
예제 #19
0
 void Help()
 {
     if (c != null)
     {
         CommandIdentity cmd = (from CommandIdentity cID in Karuta.commandIDs where cID.name == c select cID).First();
         if (cmd != null)
         {
             Karuta.Write("\t" + cmd.name + "\t" + cmd.helpMessage);
             Karuta.Write("\tOptions:");
             foreach (Option o in cmd.options)
             {
                 Karuta.Write("\t\t -" + o.key + "\t" + o.usage);
             }
             Karuta.Write("\tKeywords:");
             foreach (Keyword k in cmd.keywords)
             {
                 Karuta.Write("\t\t " + k.keyword + "\t" + k.usage);
             }
         }
         else
         {
             Karuta.Write("No such command '" + c + "'");
         }
         c = null;
     }
     else
     {
         Karuta.Write("The available commands are:");
         foreach (CommandIdentity c in Karuta.commandIDs)
         {
             Karuta.Write("\t" + c.name + "\t" + c.helpMessage);
             //if (c.usageMessage != null)
             //	Karuta.Write("\t\tUsage: " + c.usageMessage);
         }
     }
 }
예제 #20
0
        public override void Run(string[] args)
        {
            if (args.Length == 1)
            {
                Karuta.Say("The current username is: " + Karuta.user);
                return;
            }
            if (args.Length < 3)
            {
                Karuta.Write("Not enough parameters");
                Karuta.Write(usageMessage);
                return;
            }
            string user = GetValueOfOption(args, 's');

            if (user == null)
            {
                Karuta.Write("Username must be specified");
                Karuta.Write(usageMessage);
                return;
            }
            Karuta.Say("Setting username to: " + user);
            Karuta.user = user;
        }
예제 #21
0
        public virtual ICommand Parse(List <string> args)
        {
            //Find keyword to execute
            Keyword selectedKeyword = null;

            if ((_keywords.Count == 0 && _options.Count == 0) || args.Count == 0)
            {
                return(Execute());
            }

            Debug.Print("Raw Args");
            Debug.Print(string.Join(" ", from s in args select s));
            Debug.Print("Keyword parse START");
            if (_keywords.Count != 0)
            {
                //Select and assign the keyword if it exists
                //IList<Keyword> kl = (from arg in args where _keywords.ContainsKey(arg) select _keywords[arg]).ToList();
                //selectedKeyword = (kl.Count == 0) ? null : kl.First();
                if (_keywords.TryGetValue(args[0], out selectedKeyword))
                {
                    args.Remove(selectedKeyword.keyword);
                }
            }
            Debug.Print("Keyword parse END");
            Debug.Print($">{string.Join(", ", from s in args select s)}");
            //Find options to set
            if (args.Count != 0)
            {
                IList <string> emptyArgs = (from empty in args where string.IsNullOrWhiteSpace(empty) select empty).ToList();

                foreach (string arg in emptyArgs)
                {
                    args.Remove(arg);
                }
                Debug.Print($">{string.Join(", ", from s in args select s)}");

                string optKeys = "";

                Debug.Print("Option flags parse START");
                //Find options flags
                optKeys = string.Join("", from o in args where o.Contains("-") select o.Remove(0, 1));

                List <string> removalQ = new List <string>();
                removalQ.AddRange(from a in args where a.Contains("-") select a);

                foreach (string a in removalQ)
                {
                    args.Remove(a);
                }
                Debug.Print("Option flags parse END");
                Debug.Print($">{string.Join(", ", from s in args select s)}");
                Debug.Print($">{string.Join(", ", from s in args select s)}");

                int index = 0;
                Debug.Print("Option parse START");
                //Execute each option and pass pararemter if needed
                foreach (char key in optKeys)
                {
                    Option opt;
                    if (!_options.TryGetValue(key, out opt))
                    {
                        throw new CommandParsingExeception($"No such option -{key.ToString()} {optKeys}");
                    }
                    if (opt.isParamLess)
                    {
                        opt.Execute();
                    }
                    else
                    {
                        if (args.Count <= index)
                        {
                            Karuta.Write("No value provided for option: " + opt.key);
                        }
                        else
                        {
                            opt.Execute(args[index++]);
                        }
                    }
                }
                Debug.Print("Option parse END");
                Debug.Print($">{string.Join(", ", from s in args select s)}");
            }
            Debug.Print("EXECUTE");
            //Execute keyword if found
            if (selectedKeyword != null)
            {
                selectedKeyword.Execute();
                return(this);
            }
            //Execute default
            return(Execute());
        }
예제 #22
0
        async void Remove()
        {
            //Validate
            List <string> imageLinks = new List <string>();
            Uri           url        = new Uri(_url);

            if (!_removeEntirely)
            {
                if (_name == null || _url == null || _url == "" || _name == "")
                {
                    await _channel.SendMessage("An image name and url must be specified");

                    return;
                }
                if (_url.Contains('`') || _url.Contains('{'))
                {
                    await _channel.SendMessage("Invalid URL");

                    return;
                }

                if (url.Host == "i.imgur.com")
                {
                    if (_bot.validExtensions.Contains(Path.GetExtension(url.AbsolutePath)))
                    {
                        imageLinks.Add(_url);
                    }
                }
                else if (url.Host != "imgur.com")
                {
                    await _channel.SendMessage("Only imgur images are allowed");

                    return;
                }
            }
            else if (_name == null || _name == "")
            {
                await _channel.SendMessage("An image name must be specified");

                return;
            }
            //Resolve Link
            if (imageLinks.Count == 0 && !_removeEntirely)
            {
                imageLinks = await _bot.ResolveImgurUrl(url);
            }
            if (_bot.interpreter.CommandExists(_name))
            {
                int removed = 0, skipped = 0;
                if (_removeEntirely)
                {
                    _bot.interpreter.RemoveCommand(_name);
                }
                else
                {
                    if (_bot.interpreter.GetCommand(_name).GetType() != typeof(DiscordImageCommand))
                    {
                        await _channel.SendMessage("This is not an image command");
                    }
                    DiscordImageCommand cmd = ((DiscordImageCommand)_bot.interpreter.GetCommand(_name));
                    foreach (string i in cmd.images)
                    {
                        Karuta.Write(i);
                    }
                    foreach (string u in imageLinks)
                    {
                        if (cmd.RemoveImage(u))
                        {
                            removed++;
                        }
                        else
                        {
                            skipped++;
                        }
                    }
                    foreach (string i in cmd.images)
                    {
                        Karuta.Write(i);
                    }
                    if (cmd.images.Count == 0)
                    {
                        _bot.interpreter.RemoveCommand(_name);
                    }
                }
                await _channel.SendMessage($"{removed} Image{((removed > 1) ? "s" : "")} removed");

                if (skipped != 0)
                {
                    await _channel.SendMessage($"{skipped} Image{((skipped > 1) ? "s" : "")} were not found, and skipped");
                }
            }
            else
            {
                await _channel.SendMessage("that image command does not exsist");
            }
            _bot.interpreter.GetCommandOfType <HelpCommand>()?.init();
            _bot.SaveData();
            Karuta.InvokeCommand("save", new List <string>());
            _removeEntirely = false;
            _url            = _name = null;
        }
예제 #23
0
        async void Add()
        {
            //Validate
            if (string.IsNullOrWhiteSpace(_name) && string.IsNullOrWhiteSpace(_url))
            {
                await _channel.SendMessage($"An image name and url must be specified, use !help {name} for more info");

                return;
            }

            if ((_url.Contains('`') || _url.Contains('{')))
            {
                await _channel.SendMessage("Invalid URL");

                return;
            }

            List <string> imageLinks = new List <string>();
            Uri           url        = new Uri(_url);

            if (url.Host == "i.imgur.com")
            {
                if (_bot.validExtensions.Contains(Path.GetExtension(url.AbsolutePath)))
                {
                    imageLinks.Add(_url);
                }
            }
            else if (url.Host != "imgur.com")
            {
                await _channel.SendMessage("Only imgur images are allowed");

                return;
            }

            //Resolve Link
            if (imageLinks.Count == 0)
            {
                imageLinks = await _bot.ResolveImgurUrl(url);
            }
            //Add Command
            if (_bot.interpreter.CommandExists(_name))
            {
                DiscordCommand c = _bot.interpreter.GetCommand(_name);
                if (c?.GetType() == typeof(DiscordImageCommand))
                {
                    DiscordImageCommand cmd = (DiscordImageCommand)c;
                    int dupeCount           = 0;
                    int addCount            = 0;
                    if (!string.IsNullOrWhiteSpace(_help))
                    {
                        cmd.SetHelpMessage(_help);
                    }
                    foreach (string link in imageLinks)
                    {
                        if (cmd.images.Contains(link))
                        {
                            dupeCount++;
                            continue;
                        }
                        cmd.AddImage(link);
                        addCount++;
                    }
                    if (dupeCount > 0)
                    {
                        await _channel.SendMessage($"{dupeCount} Image{((dupeCount > 1) ? "s" : "")} already existed and were not added");
                    }
                    await _channel.SendMessage($"{addCount} Image{((addCount > 1) ? "s" : "")} Added");

                    //await _channel.SendMessage(cmd.ToString());
                }
                else
                {
                    await _channel.SendMessage("This name cannot be used");
                }
            }
            else
            {
                //Karuta.Write(count);
                DiscordImageCommand img = (_help != default(string)) ? new DiscordImageCommand(_name, _help)
                {
                    images = imageLinks
                } :new DiscordImageCommand(_name)
                {
                    images = imageLinks
                };
                _bot.interpreter.RegisterCommand(img);
                img.init?.Invoke();
                _bot.interpreter.GetCommandOfType <DiscordHelpCommand>()?.init();
                await _channel.SendMessage($"{imageLinks.Count} Image{((imageLinks.Count > 1) ? "s" : "")} Command Added");

                Karuta.Write(img.ToString());
            }
            //foreach (string c in bot.commands.Keys)
            //	_channel.SendMessage(c);
            _bot.SaveData();
            Karuta.InvokeCommand("save", new List <string>());
            _url = _name = null;
        }