Basic verb command

This commit is contained in:
Nikolay Kochulin 2019-11-16 18:08:32 +00:00
parent 313256da8d
commit c4dc24f6be
10 changed files with 203 additions and 10 deletions

View File

@ -0,0 +1,55 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using JetKarmaBot.Services;
using Perfusion;
using Telegram.Bot;
using Telegram.Bot.Args;
namespace JetKarmaBot.Commands
{
public class AwardTypeCommand : IChatCommand
{
public IReadOnlyCollection<string> Names => new[] { "at" };
public string Description => "Manage custom award types.";
public string DescriptionID => "jetkarmabot.at.help";
public VerbCommandRouter Router;
[Inject] TelegramBotClient Client { get; set; }
[Inject] Localization Locale { get; set; }
[Inject] KarmaContextFactory Db { get; set; }
public AwardTypeCommand(IContainer c, VerbCommandRouter r)
{
Router = r;
r.Add(c.GetInstance<AwardTypeManage.TestCommand>());
}
public IReadOnlyCollection<ChatCommandArgument> Arguments => new[] {
new ChatCommandArgument() {
Name="verb",
Required=true,
Type=ChatCommandArgumentType.String,
Description="The action to perform.",
DescriptionID="jetkarmabot.at.verbhelp"
}
};
public async Task<bool> Execute(CommandString cmd, MessageEventArgs args)
{
using (var db = Db.GetContext())
{
var currentLocale = Locale[(await db.Chats.FindAsync(args.Message.Chat.Id)).Locale];
if (!await Router.Process(cmd, args))
{
await Client.SendTextMessageAsync(
args.Message.Chat.Id,
currentLocale["jetkarmabot.at.err"],
replyToMessageId: args.Message.MessageId);
}
return true;
}
}
}
}

View File

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Telegram.Bot.Args;
namespace JetKarmaBot.Commands.AwardTypeManage
{
public class TestCommand : IChatCommand
{
public IReadOnlyCollection<string> Names => new[] { "test" };
public string Description => "test";
public string DescriptionID => "test";
public IReadOnlyCollection<ChatCommandArgument> Arguments => Array.Empty<ChatCommandArgument>();
public Task<bool> Execute(CommandString cmd, MessageEventArgs messageEventArgs)
{
throw new NotImplementedException();
}
}
}

View File

@ -84,18 +84,15 @@ namespace JetKarmaBot
async Task InitCommands(IContainer c)
{
c.Add<HelpCommand>();
c.Add<AwardCommand>();
c.Add<StatusCommand>();
c.Add<LocaleCommand>();
c.Add<CurrenciesCommand>();
c.Add<LeaderboardCommand>();
Commands = c.GetInstance<ChatCommandRouter>();
await Commands.Start();
foreach (IChatCommand cmd in c.GetInstances<IChatCommand>())
{
Commands.Add(cmd);
}
Commands.Add(c.GetInstance<HelpCommand>());
Commands.Add(c.GetInstance<AwardCommand>());
Commands.Add(c.GetInstance<StatusCommand>());
Commands.Add(c.GetInstance<LocaleCommand>());
Commands.Add(c.GetInstance<CurrenciesCommand>());
Commands.Add(c.GetInstance<LeaderboardCommand>());
Commands.Add(c.GetInstance<AwardTypeCommand>());
}
#endregion

View File

@ -29,6 +29,7 @@ namespace JetKarmaBot
var dbOptions = new DbContextOptionsBuilder<KarmaContext>()
.UseMySql(cfg.ConnectionString + (cfg.ConnectionString.EndsWith(";") ? "" : ";") + "TreatTinyAsBoolean=false");
c.AddInfo<Logger>(new LogInfo());
c.AddInfo<VerbCommandRouter>(new VerbInfo());
if (cfg.SqlDebug)
{
dbOptions = dbOptions.UseLoggerFactory(c.GetInstance<NLoggerFactory>());

View File

@ -19,4 +19,13 @@ namespace JetKarmaBot
+ (t.GenericTypeArguments.Length > 0 ? "<" + string.Join(",", t.GenericTypeArguments.Select(getTypeName)) + ">" : "");
}
}
public class VerbInfo : ObjectInfo
{
public override ObjectInfo Clone() => new VerbInfo();
public override object GetInstance(IContainer c, Type requester = null)
{
return c.ResolveObject(new VerbCommandRouter(requester != null ? requester.Name : "<type unspecified>"));
}
}
}

View File

@ -0,0 +1,102 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using JetKarmaBot.Commands;
using NLog;
using Perfusion;
using Telegram.Bot.Args;
namespace JetKarmaBot
{
public class VerbCommandRouter
{
Dictionary<string, IChatCommand> commands = new Dictionary<string, IChatCommand>();
[Inject] private Logger log;
string superCommand;
public VerbCommandRouter(string supercommand)
{
superCommand = supercommand;
}
public Task<bool> Process(CommandString cs, MessageEventArgs args)
{
log.Debug($"(verb for {superCommand}) Processing verb");
if (cs.Parameters.Length < 1)
{
log.Debug($"(verb for {superCommand}) too few arguments");
return Task.FromResult(false);
}
CommandString ncs = new CommandString(cs.Parameters[0], cs.Parameters.Skip(1).ToArray());
try
{
if (commands.ContainsKey(ncs.Command))
{
log.Debug($"(verb for {superCommand}) Handling via {commands[ncs.Command].GetType().Name}");
return commands[ncs.Command].Execute(ncs, args);
}
}
catch (Exception e)
{
log.Error($"(verb for {superCommand}) Error while handling verb {ncs.Command}!");
log.Error(e);
return Task.FromResult(true); //Don't trigger message
}
return Task.FromResult(false);
}
public void Add(IChatCommand c)
{
log.ConditionalTrace($"(verb for {superCommand}) Adding command {c.GetType().Name}");
foreach (var name in c.Names)
{
log.ConditionalTrace($"(verb for {superCommand}) Mounting {c.GetType().Name} to {name}");
if (commands.ContainsKey(name))
throw new Exception($"command collision for name {name}, commands {commands[name].GetType()} and {c.GetType()}");
commands[name] = c;
}
}
internal string GetHelpText(Locale loc)
{
List<string> pieces = new List<string>();
foreach (IChatCommand c in commands.Values.Distinct())
{
string build = "";
List<string> names = c.Names.ToList();
for (int i = 0; i < names.Count - 1; i++)
{
build = build + "/" + names[i] + "\n";
}
build += "/" + names[names.Count - 1] + " " + string.Join(" ", c.Arguments.Select(x => (!x.Required ? "[" : "") + x.Name + (!x.Required ? "]" : ""))) + " <i>" + getLocalizedCMDDesc(c, loc) + "</i>";
pieces.Add(build);
}
return string.Join("\n", pieces);
}
internal string GetHelpTextFor(string commandname, Locale loc)
{
IChatCommand c = commands[commandname];
string build = "";
List<string> names = c.Names.ToList();
for (int i = 0; i < names.Count - 1; i++)
{
build = build + "/" + names[i] + "\n";
}
build += "/" + names[names.Count - 1] + " " + string.Join(" ", c.Arguments.Select(x => (!x.Required ? "[" : "") + x.Name + (!x.Required ? "]" : ""))) + " <i>" + getLocalizedCMDDesc(c, loc) + "</i>\n";
build += string.Join("\n", c.Arguments.Select(ca => (!ca.Required ? "[" : "") + ca.Name + (!ca.Required ? "]" : "") + ": <i>" + getLocalizedCMDArgDesc(ca, loc) + "</i>"));
return build;
}
private string getLocalizedCMDDesc(IChatCommand cmd, Locale loc)
{
if (loc.ContainsKey(cmd.DescriptionID)) return loc[cmd.DescriptionID];
else return cmd.Description;
}
private string getLocalizedCMDArgDesc(ChatCommandArgument arg, Locale loc)
{
if (loc.ContainsKey(arg.DescriptionID)) return loc[arg.DescriptionID];
else return arg.Description;
}
}
}

View File

@ -39,6 +39,8 @@
"jetkarmabot.leaderboard.help": "Табліца лідэраў па колькасці ўзнагарод",
"jetkarmabot.leaderboard.awardtypehelp": "Тып ўзнагароды, па якой падасца справаздачу.",
"jetkarmabot.leaderboard.specifictext": "Перадавікі ў намінацыі \"{0}\":",
"jetkarmabot.at.help": "Кіруе карыстацкімі тыпамі узнагарод.",
"jetkarmabot.at.verbhelp": "Дзеянне, якое выканаць.",
"jetkarmabot.star.nominative": "зорачка",
"jetkarmabot.star.accusative": "зорачку"
}

View File

@ -38,6 +38,8 @@
"jetkarmabot.leaderboard.help": "Shows the people with the most of a specific award.",
"jetkarmabot.leaderboard.awardtypehelp": "The awardtype to show a leaderboard for.",
"jetkarmabot.leaderboard.specifictext": "Leaderboard for {0}:",
"jetkarmabot.at.help": "Manages custom award types.",
"jetkarmabot.at.verbhelp": "The action to perform.",
"jetkarmabot.star.nominative": "star",
"jetkarmabot.star.accusative": "star"
}

View File

@ -38,6 +38,8 @@
"jetkarmabot.leaderboard.help": "Таблица лидеров по количеству наград",
"jetkarmabot.leaderboard.awardtypehelp": "Тип награды, по которой покажется отчет.",
"jetkarmabot.leaderboard.specifictext": "Передовики в номинации \"{0}\":",
"jetkarmabot.at.help": "Управляет пользовательскими типами наград.",
"jetkarmabot.at.verbhelp": "Действие, которое выполнить.",
"jetkarmabot.star.nominative": "звездочка",
"jetkarmabot.star.accusative": "звездочку"
}