Help verb command + change to IChatCommand

This commit is contained in:
Nikolay Kochulin 2019-11-16 19:45:25 +00:00
parent c4dc24f6be
commit 84a96745c9
15 changed files with 52 additions and 47 deletions

View File

@ -12,12 +12,14 @@ using Telegram.Bot.Args;
namespace JetKarmaBot namespace JetKarmaBot
{ {
public class ChatCommandRouter public class ChatCommandRouter : ICommandRouter
{ {
public Telegram.Bot.Types.User Me { get; private set; } public Telegram.Bot.Types.User Me { get; private set; }
[Inject] private Logger log; [Inject] private Logger log;
[Inject] private TelegramBotClient Client { get; set; } [Inject] private TelegramBotClient Client { get; set; }
public string Prefix => "/";
public async Task Start() public async Task Start()
{ {
Me = await Client.GetMeAsync(); Me = await Client.GetMeAsync();
@ -41,7 +43,7 @@ namespace JetKarmaBot
if (commands.ContainsKey(cmd.Command)) if (commands.ContainsKey(cmd.Command))
{ {
log.Debug($"Handling message via {commands[cmd.Command].GetType().Name}"); log.Debug($"Handling message via {commands[cmd.Command].GetType().Name}");
return commands[cmd.Command].Execute(cmd, args); return commands[cmd.Command].Execute(this, cmd, args);
} }
} }
catch (Exception e) catch (Exception e)
@ -66,7 +68,7 @@ namespace JetKarmaBot
} }
} }
internal string GetHelpText(Locale loc) public string GetHelpText(Locale loc)
{ {
List<string> pieces = new List<string>(); List<string> pieces = new List<string>();
foreach (IChatCommand c in commands.Values.Distinct()) foreach (IChatCommand c in commands.Values.Distinct())
@ -83,7 +85,7 @@ namespace JetKarmaBot
return string.Join("\n", pieces); return string.Join("\n", pieces);
} }
internal string GetHelpTextFor(string commandname, Locale loc) public string GetHelpTextFor(string commandname, Locale loc)
{ {
IChatCommand c = commands[commandname]; IChatCommand c = commands[commandname];
string build = ""; string build = "";

View File

@ -18,7 +18,7 @@ namespace JetKarmaBot.Commands
[Inject] [Inject]
private Logger log; private Logger log;
public async Task<bool> Execute(CommandString cmd, MessageEventArgs args) public async Task<bool> Execute(ICommandRouter route, CommandString cmd, MessageEventArgs args)
{ {
using (var db = Db.GetContext()) using (var db = Db.GetContext())
{ {

View File

@ -23,7 +23,9 @@ namespace JetKarmaBot.Commands
public AwardTypeCommand(IContainer c, VerbCommandRouter r) public AwardTypeCommand(IContainer c, VerbCommandRouter r)
{ {
Router = r; Router = r;
Router.SuperCommand = "at";
r.Add(c.GetInstance<AwardTypeManage.TestCommand>()); r.Add(c.GetInstance<AwardTypeManage.TestCommand>());
r.Add(c.GetInstance<HelpCommand>());
} }
public IReadOnlyCollection<ChatCommandArgument> Arguments => new[] { public IReadOnlyCollection<ChatCommandArgument> Arguments => new[] {
@ -36,12 +38,13 @@ namespace JetKarmaBot.Commands
} }
}; };
public async Task<bool> Execute(CommandString cmd, MessageEventArgs args) public async Task<bool> Execute(ICommandRouter route, CommandString cmd, MessageEventArgs args)
{ {
Router.SuperRouter = route;
using (var db = Db.GetContext()) using (var db = Db.GetContext())
{ {
var currentLocale = Locale[(await db.Chats.FindAsync(args.Message.Chat.Id)).Locale]; var currentLocale = Locale[(await db.Chats.FindAsync(args.Message.Chat.Id)).Locale];
if (!await Router.Process(cmd, args)) if (!await Router.Process(route, cmd, args))
{ {
await Client.SendTextMessageAsync( await Client.SendTextMessageAsync(
args.Message.Chat.Id, args.Message.Chat.Id,

View File

@ -15,7 +15,7 @@ namespace JetKarmaBot.Commands.AwardTypeManage
public IReadOnlyCollection<ChatCommandArgument> Arguments => Array.Empty<ChatCommandArgument>(); public IReadOnlyCollection<ChatCommandArgument> Arguments => Array.Empty<ChatCommandArgument>();
public Task<bool> Execute(CommandString cmd, MessageEventArgs messageEventArgs) public Task<bool> Execute(ICommandRouter route, CommandString cmd, MessageEventArgs messageEventArgs)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

View File

@ -15,7 +15,7 @@ namespace JetKarmaBot.Commands
[Inject] [Inject]
private Logger log; private Logger log;
public async Task<bool> Execute(CommandString cmd, MessageEventArgs args) public async Task<bool> Execute(ICommandRouter route, CommandString cmd, MessageEventArgs args)
{ {
using (var db = Db.GetContext()) using (var db = Db.GetContext())
{ {

View File

@ -23,7 +23,7 @@ namespace JetKarmaBot.Commands
public IReadOnlyCollection<ChatCommandArgument> Arguments => new ChatCommandArgument[] { public IReadOnlyCollection<ChatCommandArgument> Arguments => new ChatCommandArgument[] {
}; };
public async Task<bool> Execute(CommandString cmd, MessageEventArgs args) public async Task<bool> Execute(ICommandRouter route, CommandString cmd, MessageEventArgs args)
{ {
using (var db = Db.GetContext()) using (var db = Db.GetContext())
{ {

View File

@ -13,7 +13,6 @@ namespace JetKarmaBot.Commands
[Inject] KarmaContextFactory Db; [Inject] KarmaContextFactory Db;
[Inject] TelegramBotClient Client { get; set; } [Inject] TelegramBotClient Client { get; set; }
[Inject] Localization Locale { get; set; } [Inject] Localization Locale { get; set; }
[Inject] ChatCommandRouter Router;
public IReadOnlyCollection<string> Names => new[] { "help" }; public IReadOnlyCollection<string> Names => new[] { "help" };
public string Description => "Displays help text for all(one) command(s)"; public string Description => "Displays help text for all(one) command(s)";
@ -29,7 +28,7 @@ namespace JetKarmaBot.Commands
} }
}; };
public async Task<bool> Execute(CommandString cmd, MessageEventArgs args) public async Task<bool> Execute(ICommandRouter route, CommandString cmd, MessageEventArgs args)
{ {
using (var db = Db.GetContext()) using (var db = Db.GetContext())
{ {
@ -38,7 +37,7 @@ namespace JetKarmaBot.Commands
{ {
await Client.SendTextMessageAsync( await Client.SendTextMessageAsync(
args.Message.Chat.Id, args.Message.Chat.Id,
Router.GetHelpText(currentLocale), route.GetHelpText(currentLocale),
replyToMessageId: args.Message.MessageId, replyToMessageId: args.Message.MessageId,
parseMode: ParseMode.Html); parseMode: ParseMode.Html);
return true; return true;
@ -47,7 +46,7 @@ namespace JetKarmaBot.Commands
{ {
await Client.SendTextMessageAsync( await Client.SendTextMessageAsync(
args.Message.Chat.Id, args.Message.Chat.Id,
Router.GetHelpTextFor(cmd.Parameters[0], currentLocale), route.GetHelpTextFor(cmd.Parameters[0], currentLocale),
replyToMessageId: args.Message.MessageId, replyToMessageId: args.Message.MessageId,
parseMode: ParseMode.Html); parseMode: ParseMode.Html);
return true; return true;

View File

@ -11,7 +11,7 @@ namespace JetKarmaBot.Commands
string DescriptionID { get; } string DescriptionID { get; }
IReadOnlyCollection<ChatCommandArgument> Arguments { get; } IReadOnlyCollection<ChatCommandArgument> Arguments { get; }
Task<bool> Execute(CommandString cmd, MessageEventArgs messageEventArgs); Task<bool> Execute(ICommandRouter route, CommandString cmd, MessageEventArgs messageEventArgs);
} }
public struct ChatCommandArgument public struct ChatCommandArgument

View File

@ -17,7 +17,7 @@ namespace JetKarmaBot.Commands
{ {
public IReadOnlyCollection<string> Names => new[] { "leaderboard" }; public IReadOnlyCollection<string> Names => new[] { "leaderboard" };
public async Task<bool> Execute(CommandString cmd, MessageEventArgs args) public async Task<bool> Execute(ICommandRouter route, CommandString cmd, MessageEventArgs args)
{ {
using (var db = Db.GetContext()) using (var db = Db.GetContext())
{ {

View File

@ -17,7 +17,7 @@ namespace JetKarmaBot.Commands
{ {
public IReadOnlyCollection<string> Names => new[] { "status" }; public IReadOnlyCollection<string> Names => new[] { "status" };
public async Task<bool> Execute(CommandString cmd, MessageEventArgs args) public async Task<bool> Execute(ICommandRouter route, CommandString cmd, MessageEventArgs args)
{ {
using (var db = Db.GetContext()) using (var db = Db.GetContext())
{ {

View File

@ -0,0 +1,12 @@
using JetKarmaBot.Commands;
namespace JetKarmaBot
{
public interface ICommandRouter
{
string GetHelpText(Locale loc);
string GetHelpTextFor(string commandname, Locale loc);
void Add(IChatCommand c);
string Prefix { get; }
}
}

View File

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

View File

@ -19,13 +19,4 @@ namespace JetKarmaBot
+ (t.GenericTypeArguments.Length > 0 ? "<" + string.Join(",", t.GenericTypeArguments.Select(getTypeName)) + ">" : ""); + (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

@ -9,22 +9,20 @@ using Telegram.Bot.Args;
namespace JetKarmaBot namespace JetKarmaBot
{ {
public class VerbCommandRouter public class VerbCommandRouter : ICommandRouter
{ {
Dictionary<string, IChatCommand> commands = new Dictionary<string, IChatCommand>(); Dictionary<string, IChatCommand> commands = new Dictionary<string, IChatCommand>();
[Inject] private Logger log; [Inject] private Logger log;
string superCommand; public string SuperCommand { get; set; }
public VerbCommandRouter(string supercommand) public string Prefix => SuperRouter.Prefix + SuperCommand + " ";
{ public ICommandRouter SuperRouter { get; set; }
superCommand = supercommand;
}
public Task<bool> Process(CommandString cs, MessageEventArgs args) public Task<bool> Process(ICommandRouter route, CommandString cs, MessageEventArgs args)
{ {
log.Debug($"(verb for {superCommand}) Processing verb"); log.Debug($"(verb for {SuperCommand}) Processing verb");
if (cs.Parameters.Length < 1) if (cs.Parameters.Length < 1)
{ {
log.Debug($"(verb for {superCommand}) too few arguments"); log.Debug($"(verb for {SuperCommand}) too few arguments");
return Task.FromResult(false); return Task.FromResult(false);
} }
CommandString ncs = new CommandString(cs.Parameters[0], cs.Parameters.Skip(1).ToArray()); CommandString ncs = new CommandString(cs.Parameters[0], cs.Parameters.Skip(1).ToArray());
@ -32,13 +30,13 @@ namespace JetKarmaBot
{ {
if (commands.ContainsKey(ncs.Command)) if (commands.ContainsKey(ncs.Command))
{ {
log.Debug($"(verb for {superCommand}) Handling via {commands[ncs.Command].GetType().Name}"); log.Debug($"(verb for {SuperCommand}) Handling via {commands[ncs.Command].GetType().Name}");
return commands[ncs.Command].Execute(ncs, args); return commands[ncs.Command].Execute(this, ncs, args);
} }
} }
catch (Exception e) catch (Exception e)
{ {
log.Error($"(verb for {superCommand}) Error while handling verb {ncs.Command}!"); log.Error($"(verb for {SuperCommand}) Error while handling verb {ncs.Command}!");
log.Error(e); log.Error(e);
return Task.FromResult(true); //Don't trigger message return Task.FromResult(true); //Don't trigger message
} }
@ -48,17 +46,17 @@ namespace JetKarmaBot
public void Add(IChatCommand c) public void Add(IChatCommand c)
{ {
log.ConditionalTrace($"(verb for {superCommand}) Adding command {c.GetType().Name}"); log.ConditionalTrace($"(verb for {SuperCommand}) Adding command {c.GetType().Name}");
foreach (var name in c.Names) foreach (var name in c.Names)
{ {
log.ConditionalTrace($"(verb for {superCommand}) Mounting {c.GetType().Name} to {name}"); log.ConditionalTrace($"(verb for {SuperCommand}) Mounting {c.GetType().Name} to {name}");
if (commands.ContainsKey(name)) if (commands.ContainsKey(name))
throw new Exception($"command collision for name {name}, commands {commands[name].GetType()} and {c.GetType()}"); throw new Exception($"command collision for name {name}, commands {commands[name].GetType()} and {c.GetType()}");
commands[name] = c; commands[name] = c;
} }
} }
internal string GetHelpText(Locale loc) public string GetHelpText(Locale loc)
{ {
List<string> pieces = new List<string>(); List<string> pieces = new List<string>();
foreach (IChatCommand c in commands.Values.Distinct()) foreach (IChatCommand c in commands.Values.Distinct())
@ -67,24 +65,24 @@ namespace JetKarmaBot
List<string> names = c.Names.ToList(); List<string> names = c.Names.ToList();
for (int i = 0; i < names.Count - 1; i++) for (int i = 0; i < names.Count - 1; i++)
{ {
build = build + "/" + names[i] + "\n"; build = build + Prefix + 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>"; build += Prefix + names[names.Count - 1] + " " + string.Join(" ", c.Arguments.Select(x => (!x.Required ? "[" : "") + x.Name + (!x.Required ? "]" : ""))) + " <i>" + getLocalizedCMDDesc(c, loc) + "</i>";
pieces.Add(build); pieces.Add(build);
} }
return string.Join("\n", pieces); return string.Join("\n", pieces);
} }
internal string GetHelpTextFor(string commandname, Locale loc) public string GetHelpTextFor(string commandname, Locale loc)
{ {
IChatCommand c = commands[commandname]; IChatCommand c = commands[commandname];
string build = ""; string build = "";
List<string> names = c.Names.ToList(); List<string> names = c.Names.ToList();
for (int i = 0; i < names.Count - 1; i++) for (int i = 0; i < names.Count - 1; i++)
{ {
build = build + "/" + names[i] + "\n"; build = build + Prefix + 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 += Prefix + 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>")); build += string.Join("\n", c.Arguments.Select(ca => (!ca.Required ? "[" : "") + ca.Name + (!ca.Required ? "]" : "") + ": <i>" + getLocalizedCMDArgDesc(ca, loc) + "</i>"));
return build; return build;
} }

View File

@ -40,6 +40,7 @@
"jetkarmabot.leaderboard.specifictext": "Leaderboard for {0}:", "jetkarmabot.leaderboard.specifictext": "Leaderboard for {0}:",
"jetkarmabot.at.help": "Manages custom award types.", "jetkarmabot.at.help": "Manages custom award types.",
"jetkarmabot.at.verbhelp": "The action to perform.", "jetkarmabot.at.verbhelp": "The action to perform.",
"jetkarmabot.verbhelp": "Displays help text for all(one) verb(s)",
"jetkarmabot.star.nominative": "star", "jetkarmabot.star.nominative": "star",
"jetkarmabot.star.accusative": "star" "jetkarmabot.star.accusative": "star"
} }