Add language chooser feature to chats

This commit is contained in:
Nikolay Kochulin 2018-12-26 18:13:34 +03:00
parent 12b90d010f
commit bff68a9748
8 changed files with 125 additions and 58 deletions

View File

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Telegram.Bot; using Telegram.Bot;
@ -14,9 +14,10 @@ namespace JetKarmaBot.Commands
public bool Execute(CommandString cmd, MessageEventArgs args) public bool Execute(CommandString cmd, MessageEventArgs args)
{ {
var currentLocale = Locale[Db.Chats[args.Message.Chat.Id].Locale];
if (args.Message.ReplyToMessage == null) if (args.Message.ReplyToMessage == null)
{ {
Client.SendTextMessageAsync(args.Message.Chat.Id, Locale["jetkarmabot.award.errawardnoreply", "en-US"]); Client.SendTextMessageAsync(args.Message.Chat.Id, currentLocale["jetkarmabot.award.errawardnoreply"]);
return true; return true;
} }
@ -29,7 +30,7 @@ namespace JetKarmaBot.Commands
{ {
Client.SendTextMessageAsync( Client.SendTextMessageAsync(
args.Message.Chat.Id, args.Message.Chat.Id,
Locale["jetkarmabot.award.errawardself", "en-US"], currentLocale["jetkarmabot.award.errawardself"],
replyToMessageId: args.Message.MessageId); replyToMessageId: args.Message.MessageId);
return true; return true;
} }
@ -39,8 +40,8 @@ namespace JetKarmaBot.Commands
Client.SendTextMessageAsync( Client.SendTextMessageAsync(
args.Message.Chat.Id, args.Message.Chat.Id,
awarding awarding
? Locale["jetkarmabot.award.errawardbot", "en-US"] ? currentLocale["jetkarmabot.award.errawardbot"]
: Locale["jetkarmabot.award.errrevokebot", "en-US"], : currentLocale["jetkarmabot.award.errrevokebot"],
replyToMessageId: args.Message.MessageId); replyToMessageId: args.Message.MessageId);
return true; return true;
} }
@ -52,10 +53,10 @@ namespace JetKarmaBot.Commands
Db.AddAward(awardTypeId, awarder.Id, recipient.Id, args.Message.Chat.Id, awarding ? 1 : -1); Db.AddAward(awardTypeId, awarder.Id, recipient.Id, args.Message.Chat.Id, awarding ? 1 : -1);
string message = awarding string message = awarding
? string.Format(Locale["jetkarmabot.award.awardmessage", "en-US"], awardType.Name, "@" + recipient.Username) ? string.Format(currentLocale["jetkarmabot.award.awardmessage"], awardType.Name, "@" + recipient.Username)
: string.Format(Locale["jetkarmabot.award.revokemessage", "en-US"], awardType.Name, "@" + recipient.Username); : string.Format(currentLocale["jetkarmabot.award.revokemessage"], awardType.Name, "@" + recipient.Username);
var response = message + "\n" + String.Format(Locale["jetkarmabot.award.statustext", "en-US"], "@" + recipient.Username, Db.CountUserAwards(recipient.Id, awardTypeId), awardType.Symbol); var response = message + "\n" + String.Format(currentLocale["jetkarmabot.award.statustext"], "@" + recipient.Username, Db.CountUserAwards(recipient.Id, awardTypeId), awardType.Symbol);
Client.SendTextMessageAsync( Client.SendTextMessageAsync(
args.Message.Chat.Id, args.Message.Chat.Id,

View File

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Telegram.Bot;
using Telegram.Bot.Args;
using Telegram.Bot.Types;
using Perfusion;
namespace JetKarmaBot.Commands
{
class ChangeLanguageCommand : IChatCommand
{
public IReadOnlyCollection<string> Names => new[] { "changelanguage", "lang" };
public bool Execute(CommandString cmd, MessageEventArgs args)
{
var currentLocale = Locale[Db.Chats[args.Message.Chat.Id].Locale];
if (cmd.Parameters.Length < 1)
{
Client.SendTextMessageAsync(
args.Message.Chat.Id,
currentLocale["jetkarmabot.changelanguage.noparams"],
replyToMessageId: args.Message.MessageId);
return true;
}
Db.ChangeChatLocale(Db.Chats[args.Message.Chat.Id], cmd.Parameters[0]);
currentLocale = Locale[Db.Chats[args.Message.Chat.Id].Locale];
Client.SendTextMessageAsync(
args.Message.Chat.Id,
currentLocale["jetkarmabot.changelanguage.justchanged"],
replyToMessageId: args.Message.MessageId);
return true;
}
[Inject(true)] Db Db { get; set; }
[Inject(true)] TelegramBotClient Client { get; set; }
[Inject(true)] Localization Locale { get; set; }
}
}

View File

@ -1,4 +1,4 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
@ -15,6 +15,7 @@ namespace JetKarmaBot.Commands
public bool Execute(CommandString cmd, MessageEventArgs args) public bool Execute(CommandString cmd, MessageEventArgs args)
{ {
var currentLocale = Locale[Db.Chats[args.Message.Chat.Id].Locale];
var asker = args.Message.From; var asker = args.Message.From;
var awardTypeName = cmd.Parameters.FirstOrDefault(); var awardTypeName = cmd.Parameters.FirstOrDefault();
@ -24,7 +25,7 @@ namespace JetKarmaBot.Commands
{ {
var awards = Db.CountAllUserAwards(asker.Id); var awards = Db.CountAllUserAwards(asker.Id);
response = Locale["jetkarmabot.status.listalltext", "en-US"] + "\n" response = currentLocale["jetkarmabot.status.listalltext"] + "\n"
+ string.Join("\n", awards.Select(a => $" - {Db.AwardTypes[a.AwardTypeId].Symbol} {a.Amount}")); + string.Join("\n", awards.Select(a => $" - {Db.AwardTypes[a.AwardTypeId].Symbol} {a.Amount}"));
} }
@ -33,7 +34,7 @@ namespace JetKarmaBot.Commands
var awardTypeId = Db.GetAwardTypeId(cmd.Parameters.FirstOrDefault()); var awardTypeId = Db.GetAwardTypeId(cmd.Parameters.FirstOrDefault());
var awardType = Db.AwardTypes[awardTypeId]; var awardType = Db.AwardTypes[awardTypeId];
response = string.Format(Locale["jetkarmabot.status.listspecifictext", "en-US"], Db.CountUserAwards(asker.Id, awardTypeId), awardType.Symbol); response = string.Format(currentLocale["jetkarmabot.status.listspecifictext"], Db.CountUserAwards(asker.Id, awardTypeId), awardType.Symbol);
} }
Client.SendTextMessageAsync( Client.SendTextMessageAsync(

View File

@ -1,4 +1,4 @@
using JetKarmaBot.Commands; using JetKarmaBot.Commands;
using Perfusion; using Perfusion;
using System; using System;
using System.Net; using System.Net;
@ -63,6 +63,7 @@ namespace JetKarmaBot
Commands.Add(c.ResolveObject(new StartCommand())); Commands.Add(c.ResolveObject(new StartCommand()));
Commands.Add(c.ResolveObject(new AwardCommand(Me))); Commands.Add(c.ResolveObject(new AwardCommand(Me)));
Commands.Add(c.ResolveObject(new StatusCommand())); Commands.Add(c.ResolveObject(new StatusCommand()));
Commands.Add(c.ResolveObject(new ChangeLanguageCommand()));
} }
#endregion #endregion

View File

@ -15,17 +15,17 @@ namespace JetKarmaBot
public void AddChat(Chat chat) public void AddChat(Chat chat)
{ {
lock (m_SyncRoot) lock (m_SyncRoot)
if (!m_Chats.ContainsKey(chat.ChatId)) if (!m_Chats.ContainsKey(chat.ChatId))
{ {
Conn.Execute(@"INSERT INTO chat Conn.Execute(@"INSERT INTO chat
(chatid) (chatid,locale)
VALUES VALUES
(@ChatId)", (@ChatId,@Locale)",
chat); chat);
m_Chats.Add(chat.ChatId, chat); m_Chats.Add(chat.ChatId, chat);
} }
} }
Dictionary<long, User> m_Users; Dictionary<long, User> m_Users;
public IReadOnlyDictionary<long, User> Users => m_Users; public IReadOnlyDictionary<long, User> Users => m_Users;
public void AddUser(User user) public void AddUser(User user)
@ -37,7 +37,7 @@ namespace JetKarmaBot
(userid) (userid)
VALUES VALUES
(@UserId)", (@UserId)",
user); user);
m_Users.Add(user.UserId, user); m_Users.Add(user.UserId, user);
} }
} }
@ -49,10 +49,22 @@ namespace JetKarmaBot
public int CountUserAwards(long userId, byte awardTypeId) public int CountUserAwards(long userId, byte awardTypeId)
{ {
return Conn.QuerySingle<int?> return Conn.QuerySingle<int?>
( (
"SELECT SUM(amount) FROM award WHERE toid = @userId AND awardtypeid = @awardTypeId", "SELECT SUM(amount) FROM award WHERE toid = @userId AND awardtypeid = @awardTypeId",
new { userId, awardTypeId } new { userId, awardTypeId }
) ?? 0; ) ?? 0;
}
public void ChangeChatLocale(Chat chat, string locale)
{
lock (m_SyncRoot)
{
chat.Locale = locale;
Conn.Execute(@"UPDATE chat
SET locale=@Locale
WHERE chatid=@ChatID",
chat);
}
} }
public struct UserAwardsReport public struct UserAwardsReport
@ -64,26 +76,23 @@ namespace JetKarmaBot
public IEnumerable<UserAwardsReport> CountAllUserAwards(long userId) public IEnumerable<UserAwardsReport> CountAllUserAwards(long userId)
{ {
return Conn.Query<UserAwardsReport> return Conn.Query<UserAwardsReport>
( (
@"SELECT SUM(amount) AS amount, t.awardtypeid @"SELECT SUM(amount) AS amount, t.awardtypeid
FROM award a FROM award a
JOIN awardtype t on a.awardtypeid = t.awardtypeid JOIN awardtype t on a.awardtypeid = t.awardtypeid
WHERE toid = @userId WHERE toid = @userId
GROUP BY awardtypeid;", GROUP BY awardtypeid;",
new { userId } new { userId }
); );
} }
public byte GetAwardTypeId(string name) => AwardTypesByCommandName.GetOrDefault(name)?.AwardTypeId ?? DefaultAwardTypeId;
public byte GetAwardTypeId(string name)
=> AwardTypesByCommandName.GetOrDefault(name)?.AwardTypeId ?? DefaultAwardTypeId;
public bool AddAward(byte awardTypeId, long fromId, long toId, long chatId, int amount) public bool AddAward(byte awardTypeId, long fromId, long toId, long chatId, int amount)
{ {
AddChat(new Chat() { ChatId = chatId }); AddChat(new Chat() { ChatId = chatId });
AddUser(new User() { UserId = fromId}); AddUser(new User() { UserId = fromId });
AddUser(new User() { UserId = toId }); AddUser(new User() { UserId = toId });
int affected = Conn.ExecuteScalar<int>( int affected = Conn.ExecuteScalar<int>(
@"INSERT INTO award @"INSERT INTO award
@ -98,6 +107,7 @@ namespace JetKarmaBot
public class Chat public class Chat
{ {
public long ChatId { get; set; } public long ChatId { get; set; }
public string Locale { get; set; }
} }
public class User public class User
@ -151,6 +161,6 @@ namespace JetKarmaBot
} }
#endregion #endregion
void Log (string Message) => Console.WriteLine($"[{nameof(Db)}]: {Message}"); void Log(string Message) => Console.WriteLine($"[{nameof(Db)}]: {Message}");
} }
} }

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
using System.IO; using System.IO;
@ -31,24 +32,34 @@ namespace JetKarmaBot
Log("Initialized!"); Log("Initialized!");
} }
public string this[string name, string locale] public Locale this[string locale]
{ {
get => GetString(name, locale); get => new Locale(locales[locale], locale);
}
public string GetString(string name, string locale)
{
if (!locales[locale].ContainsKey(name))
{
Log(name + " doesn't exist in this localization");
locales[locale][name] = "unknown";
File.WriteAllText("lang/" + locale + ".json", JObject.FromObject(locales[locale]).ToString());
return "unknown";
}
else
{
return locales[locale][name];
}
} }
void Log(string Message) => Console.WriteLine($"[{nameof(Localization)}]: {Message}"); void Log(string Message) => Console.WriteLine($"[{nameof(Localization)}]: {Message}");
public class Locale
{
private Dictionary<string, string> locale;
private string localeName;
public Locale(Dictionary<string, string> locale, string localeName)
{
this.locale = locale;
this.localeName = localeName;
}
public string this[string name]
{
get
{
if (!locale.ContainsKey(name))
{
return "unknown";
}
else
{
return locale[name];
}
}
}
}
} }
} }

View File

@ -7,5 +7,7 @@
"jetkarmabot.award.revokemessage": "Revoked a {0} from {1}!", "jetkarmabot.award.revokemessage": "Revoked a {0} from {1}!",
"jetkarmabot.award.statustext": "{0} is at {1}{2} now.", "jetkarmabot.award.statustext": "{0} is at {1}{2} now.",
"jetkarmabot.status.listalltext": "Your badges report:", "jetkarmabot.status.listalltext": "Your badges report:",
"jetkarmabot.status.listspecifictext": "You are at {0}{1} now." "jetkarmabot.status.listspecifictext": "You are at {0}{1} now.",
"jetkarmabot.changelanguage.noparams": "Sorry, but I don't speak the null language.",
"jetkarmabot.changelanguage.justchanged": "good"
} }

View File

@ -7,5 +7,7 @@
"jetkarmabot.award.revokemessage": "Отнял \"{0}\" у {1}!", "jetkarmabot.award.revokemessage": "Отнял \"{0}\" у {1}!",
"jetkarmabot.award.statustext": "У {0} теперь {1}{2}.", "jetkarmabot.award.statustext": "У {0} теперь {1}{2}.",
"jetkarmabot.status.listalltext": "У вас :", "jetkarmabot.status.listalltext": "У вас :",
"jetkarmabot.status.listspecifictext": "У вас сейчас {0}{1}." "jetkarmabot.status.listspecifictext": "У вас сейчас {0}{1}.",
"jetkarmabot.changelanguage.noparams": "Простите, но я не могу говорить на нуллевом языке.",
"jetkarmabot.changelanguage.justchanged": "хорошо"
} }