mirror of
https://gitlab.com/Kwoth/nadekobot.git
synced 2024-10-02 20:13:13 +00:00
.atl / .at reworked
This commit is contained in:
parent
fcc49dbbdb
commit
3c0768a372
15 changed files with 3207 additions and 137 deletions
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -9,6 +9,18 @@ Experimental changelog. Mostly based on [keepachangelog](https://keepachangelog.
|
|||
- Added slots.currencyFontColor to gambling.yml
|
||||
- Added `.qexport` and `.qimport` commands which allow you to export and import quotes just like `.crsexport`
|
||||
|
||||
### Changed
|
||||
- `.at` and `.atl` commands reworked
|
||||
- Persist restarts
|
||||
- Will now only translate non-commands
|
||||
- You can switch between `.at del` and `.at` without clearing the user language registrations
|
||||
- Disabling `.at` will clear all user language registrations on that channel
|
||||
- Users can't register languages if the `.at` is not enabled
|
||||
- Looks much nicer
|
||||
- Bot will now reply to user messages with a translation if `del` is disabled
|
||||
- Bot will make an embed with original and translated text with user avatar and name if `del` is enabled
|
||||
- If the bot is unable to delete messages while having `del` enabled, it will reset back to the no-del behavior for the current session
|
||||
|
||||
### Fixed
|
||||
- `.crypto` now supports top 5000 coins
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ using NadekoBot.Common.ModuleBehaviors;
|
|||
using NadekoBot.Common.Configs;
|
||||
using NadekoBot.Db;
|
||||
using NadekoBot.Modules.Administration.Services;
|
||||
using NadekoBot.Modules.Searches;
|
||||
using Serilog;
|
||||
|
||||
namespace NadekoBot
|
||||
|
|
12
src/NadekoBot/Db/Models/AutoTranslateChannel.cs
Normal file
12
src/NadekoBot/Db/Models/AutoTranslateChannel.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace NadekoBot.Services.Database.Models
|
||||
{
|
||||
public class AutoTranslateChannel : DbEntity
|
||||
{
|
||||
public ulong GuildId { get; set; }
|
||||
public ulong ChannelId { get; set; }
|
||||
public bool AutoDelete { get; set; }
|
||||
public IList<AutoTranslateUser> Users { get; set; } = new List<AutoTranslateUser>();
|
||||
}
|
||||
}
|
11
src/NadekoBot/Db/Models/AutoTranslateUser.cs
Normal file
11
src/NadekoBot/Db/Models/AutoTranslateUser.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
namespace NadekoBot.Services.Database.Models
|
||||
{
|
||||
public class AutoTranslateUser : DbEntity
|
||||
{
|
||||
public int ChannelId { get; set; }
|
||||
public AutoTranslateChannel Channel { get; set; }
|
||||
public ulong UserId { get; set; }
|
||||
public string Source { get; set; }
|
||||
public string Target { get; set; }
|
||||
}
|
||||
}
|
|
@ -60,6 +60,8 @@ namespace NadekoBot.Services.Database
|
|||
public DbSet<WaifuInfo> WaifuInfo { get; set; }
|
||||
public DbSet<ImageOnlyChannel> ImageOnlyChannels { get; set; }
|
||||
public DbSet<NsfwBlacklistedTag> NsfwBlacklistedTags { get; set; }
|
||||
public DbSet<AutoTranslateChannel> AutoTranslateChannels { get; set; }
|
||||
public DbSet<AutoTranslateUser> AutoTranslateUsers { get; set; }
|
||||
|
||||
public NadekoContext(DbContextOptions<NadekoContext> options) : base(options)
|
||||
{
|
||||
|
@ -368,6 +370,21 @@ namespace NadekoBot.Services.Database
|
|||
modelBuilder.Entity<NsfwBlacklistedTag>(nbt => nbt
|
||||
.HasIndex(x => x.GuildId)
|
||||
.IsUnique(false));
|
||||
|
||||
var atch = modelBuilder.Entity<AutoTranslateChannel>();
|
||||
atch.HasIndex(x => x.GuildId)
|
||||
.IsUnique(false);
|
||||
|
||||
atch.HasIndex(x => x.ChannelId)
|
||||
.IsUnique();
|
||||
|
||||
atch
|
||||
.HasMany(x => x.Users)
|
||||
.WithOne(x => x.Channel)
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
modelBuilder.Entity<AutoTranslateUser>(atu => atu
|
||||
.HasAlternateKey(x => new { x.ChannelId, x.UserId }));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
2725
src/NadekoBot/Migrations/20211213145407_atl-rework.Designer.cs
generated
Normal file
2725
src/NadekoBot/Migrations/20211213145407_atl-rework.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
71
src/NadekoBot/Migrations/20211213145407_atl-rework.cs
Normal file
71
src/NadekoBot/Migrations/20211213145407_atl-rework.cs
Normal file
|
@ -0,0 +1,71 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace NadekoBot.Migrations
|
||||
{
|
||||
public partial class atlrework : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AutoTranslateChannels",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
GuildId = table.Column<ulong>(type: "INTEGER", nullable: false),
|
||||
ChannelId = table.Column<ulong>(type: "INTEGER", nullable: false),
|
||||
AutoDelete = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
DateAdded = table.Column<DateTime>(type: "TEXT", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AutoTranslateChannels", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AutoTranslateUsers",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
ChannelId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
UserId = table.Column<ulong>(type: "INTEGER", nullable: false),
|
||||
Source = table.Column<string>(type: "TEXT", nullable: true),
|
||||
Target = table.Column<string>(type: "TEXT", nullable: true),
|
||||
DateAdded = table.Column<DateTime>(type: "TEXT", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AutoTranslateUsers", x => x.Id);
|
||||
table.UniqueConstraint("AK_AutoTranslateUsers_ChannelId_UserId", x => new { x.ChannelId, x.UserId });
|
||||
table.ForeignKey(
|
||||
name: "FK_AutoTranslateUsers_AutoTranslateChannels_ChannelId",
|
||||
column: x => x.ChannelId,
|
||||
principalTable: "AutoTranslateChannels",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AutoTranslateChannels_ChannelId",
|
||||
table: "AutoTranslateChannels",
|
||||
column: "ChannelId",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_AutoTranslateChannels_GuildId",
|
||||
table: "AutoTranslateChannels",
|
||||
column: "GuildId");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "AutoTranslateUsers");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "AutoTranslateChannels");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -340,6 +340,62 @@ namespace NadekoBot.Migrations
|
|||
b.ToTable("AutoCommands");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.AutoTranslateChannel", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("AutoDelete")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<ulong>("ChannelId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<ulong>("GuildId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ChannelId")
|
||||
.IsUnique();
|
||||
|
||||
b.HasIndex("GuildId");
|
||||
|
||||
b.ToTable("AutoTranslateChannels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.AutoTranslateUser", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ChannelId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime?>("DateAdded")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Source")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Target")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<ulong>("UserId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasAlternateKey("ChannelId", "UserId");
|
||||
|
||||
b.ToTable("AutoTranslateUsers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.BanTemplate", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
|
@ -2194,6 +2250,17 @@ namespace NadekoBot.Migrations
|
|||
b.Navigation("GuildConfig");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.AutoTranslateUser", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Services.Database.Models.AutoTranslateChannel", "Channel")
|
||||
.WithMany("Users")
|
||||
.HasForeignKey("ChannelId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Channel");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.CommandAlias", b =>
|
||||
{
|
||||
b.HasOne("NadekoBot.Services.Database.Models.GuildConfig", null)
|
||||
|
@ -2541,6 +2608,11 @@ namespace NadekoBot.Migrations
|
|||
b.Navigation("IgnoredChannels");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.AutoTranslateChannel", b =>
|
||||
{
|
||||
b.Navigation("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("NadekoBot.Services.Database.Models.GuildConfig", b =>
|
||||
{
|
||||
b.Navigation("AntiAltSetting");
|
||||
|
|
13
src/NadekoBot/Modules/Searches/Services/AtlExtensions.cs
Normal file
13
src/NadekoBot/Modules/Searches/Services/AtlExtensions.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using NadekoBot.Services.Database.Models;
|
||||
|
||||
namespace NadekoBot.Modules.Searches
|
||||
{
|
||||
public static class AtlExtensions
|
||||
{
|
||||
public static Task<AutoTranslateChannel> GetByChannelId(this IQueryable<AutoTranslateChannel> set, ulong channelId)
|
||||
=> set.FirstOrDefaultAsyncLinqToDB(x => x.ChannelId == channelId);
|
||||
}
|
||||
}
|
14
src/NadekoBot/Modules/Searches/Services/ITranslateService.cs
Normal file
14
src/NadekoBot/Modules/Searches/Services/ITranslateService.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NadekoBot.Modules.Searches
|
||||
{
|
||||
public interface ITranslateService
|
||||
{
|
||||
public Task<string> Translate(string source, string target, string text = null);
|
||||
Task<bool> ToggleAtl(ulong guildId, ulong channelId, bool autoDelete);
|
||||
IEnumerable<string> GetLanguages();
|
||||
Task<bool?> RegisterUserAsync(ulong userId, ulong channelId, string @from, string to);
|
||||
Task<bool> UnregisterUser(ulong channelId, ulong userId);
|
||||
}
|
||||
}
|
|
@ -1,10 +1,6 @@
|
|||
using Discord;
|
||||
using Discord.WebSocket;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NadekoBot.Common;
|
||||
using NadekoBot.Common;
|
||||
using NadekoBot.Modules.Searches.Common;
|
||||
using NadekoBot.Services;
|
||||
using NadekoBot.Services.Database.Models;
|
||||
using NadekoBot.Extensions;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
@ -13,18 +9,14 @@ using SixLabors.ImageSharp.Drawing.Processing;
|
|||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AngleSharp.Html.Dom;
|
||||
using AngleSharp.Html.Parser;
|
||||
using NadekoBot.Db;
|
||||
using NadekoBot.Modules.Administration;
|
||||
using Serilog;
|
||||
using HorizontalAlignment = SixLabors.Fonts.HorizontalAlignment;
|
||||
using Image = SixLabors.ImageSharp.Image;
|
||||
|
@ -34,71 +26,31 @@ namespace NadekoBot.Modules.Searches.Services
|
|||
public class SearchesService : INService
|
||||
{
|
||||
private readonly IHttpClientFactory _httpFactory;
|
||||
private readonly DiscordSocketClient _client;
|
||||
private readonly IGoogleApiService _google;
|
||||
private readonly DbService _db;
|
||||
private readonly IImageCache _imgs;
|
||||
private readonly IDataCache _cache;
|
||||
private readonly FontProvider _fonts;
|
||||
private readonly IBotCredentials _creds;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
private readonly NadekoRandom _rng;
|
||||
|
||||
public ConcurrentDictionary<ulong, bool> TranslatedChannels { get; } = new ConcurrentDictionary<ulong, bool>();
|
||||
// (userId, channelId)
|
||||
public ConcurrentDictionary<(ulong UserId, ulong ChannelId), string> UserLanguages { get; } = new ConcurrentDictionary<(ulong, ulong), string>();
|
||||
|
||||
public List<WoWJoke> WowJokes { get; } = new List<WoWJoke>();
|
||||
public List<MagicItem> MagicItems { get; } = new List<MagicItem>();
|
||||
private readonly List<string> _yomamaJokes;
|
||||
|
||||
public SearchesService(DiscordSocketClient client, IGoogleApiService google,
|
||||
DbService db, Bot bot, IDataCache cache, IHttpClientFactory factory,
|
||||
FontProvider fonts, IBotCredentials creds, IEmbedBuilderService eb)
|
||||
public SearchesService(IGoogleApiService google,
|
||||
IDataCache cache,
|
||||
IHttpClientFactory factory,
|
||||
FontProvider fonts,
|
||||
IBotCredentials creds)
|
||||
{
|
||||
_httpFactory = factory;
|
||||
_client = client;
|
||||
_google = google;
|
||||
_db = db;
|
||||
_imgs = cache.LocalImages;
|
||||
_cache = cache;
|
||||
_fonts = fonts;
|
||||
_creds = creds;
|
||||
_eb = eb;
|
||||
_rng = new NadekoRandom();
|
||||
|
||||
//translate commands
|
||||
_client.MessageReceived += (msg) =>
|
||||
{
|
||||
var _ = Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!(msg is SocketUserMessage umsg))
|
||||
return;
|
||||
|
||||
if (!TranslatedChannels.TryGetValue(umsg.Channel.Id, out var autoDelete))
|
||||
return;
|
||||
|
||||
var key = (umsg.Author.Id, umsg.Channel.Id);
|
||||
|
||||
if (!UserLanguages.TryGetValue(key, out string langs))
|
||||
return;
|
||||
|
||||
var text = await Translate(langs, umsg.Resolve(TagHandling.Ignore))
|
||||
.ConfigureAwait(false);
|
||||
if (autoDelete)
|
||||
try { await umsg.DeleteAsync().ConfigureAwait(false); } catch { }
|
||||
|
||||
await umsg.Channel.SendConfirmAsync(_eb, $"{umsg.Author.Mention} `:` "
|
||||
+ text.Replace("<@ ", "<@", StringComparison.InvariantCulture)
|
||||
.Replace("<@! ", "<@!", StringComparison.InvariantCulture)).ConfigureAwait(false);
|
||||
}
|
||||
catch { }
|
||||
});
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
|
||||
//joke commands
|
||||
if (File.Exists("data/wowjokes.json"))
|
||||
{
|
||||
|
@ -340,19 +292,6 @@ namespace NadekoBot.Modules.Searches.Services
|
|||
_rng.Next(1, max).ToString("000") + ".png";
|
||||
}
|
||||
|
||||
public async Task<string> Translate(string langs, string text = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
throw new ArgumentException("Text is empty or null", nameof(text));
|
||||
var langarr = langs.ToLowerInvariant().Split('>');
|
||||
if (langarr.Length != 2)
|
||||
throw new ArgumentException("Langs does not have 2 parts separated by a >", nameof(langs));
|
||||
var from = langarr[0];
|
||||
var to = langarr[1];
|
||||
text = text?.Trim();
|
||||
return (await _google.Translate(text, from, to).ConfigureAwait(false)).SanitizeMentions(true);
|
||||
}
|
||||
|
||||
private readonly object yomamaLock = new object();
|
||||
private int yomamaJokeIndex = 0;
|
||||
public Task<string> GetYomamaJoke()
|
||||
|
|
216
src/NadekoBot/Modules/Searches/Services/TranslateService.cs
Normal file
216
src/NadekoBot/Modules/Searches/Services/TranslateService.cs
Normal file
|
@ -0,0 +1,216 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using Discord.Net;
|
||||
using LinqToDB;
|
||||
using LinqToDB.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NadekoBot.Common.ModuleBehaviors;
|
||||
using NadekoBot.Extensions;
|
||||
using NadekoBot.Services;
|
||||
|
||||
namespace NadekoBot.Modules.Searches
|
||||
{
|
||||
public sealed class TranslateService : ITranslateService, ILateExecutor, IReadyExecutor, INService
|
||||
{
|
||||
private readonly IGoogleApiService _google;
|
||||
private readonly DbService _db;
|
||||
private readonly IEmbedBuilderService _eb;
|
||||
private readonly Bot _bot;
|
||||
|
||||
private readonly ConcurrentDictionary<ulong, bool> _atcs = new();
|
||||
private readonly ConcurrentDictionary<ulong, ConcurrentDictionary<ulong, (string From, string To)>> _users = new();
|
||||
|
||||
public TranslateService(IGoogleApiService google,
|
||||
DbService db,
|
||||
IEmbedBuilderService eb,
|
||||
Bot bot)
|
||||
{
|
||||
_google = google;
|
||||
_db = db;
|
||||
_eb = eb;
|
||||
_bot = bot;
|
||||
}
|
||||
|
||||
public async Task OnReadyAsync()
|
||||
{
|
||||
var ctx = _db.GetDbContext();
|
||||
|
||||
var guilds = _bot.AllGuildConfigs.Select(x => x.GuildId).ToList();
|
||||
var cs = await ctx.AutoTranslateChannels
|
||||
.Include(x => x.Users)
|
||||
.Where(x => guilds.Contains(x.GuildId))
|
||||
.ToListAsyncEF();
|
||||
|
||||
foreach (var c in cs)
|
||||
{
|
||||
_atcs[c.ChannelId] = c.AutoDelete;
|
||||
_users[c.ChannelId] = new(c.Users.ToDictionary(x => x.UserId, x => (x.Source, x.Target)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public async Task LateExecute(IGuild guild, IUserMessage msg)
|
||||
{
|
||||
if (msg is IUserMessage { Channel: ITextChannel tch } um)
|
||||
{
|
||||
if (!_atcs.TryGetValue(tch.Id, out var autoDelete))
|
||||
return;
|
||||
|
||||
if (!_users.TryGetValue(tch.Id, out var users)
|
||||
|| !users.TryGetValue(um.Author.Id, out var langs))
|
||||
return;
|
||||
|
||||
var output = await _google.Translate(msg.Content, langs.From, langs.To);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(output))
|
||||
return;
|
||||
|
||||
var embed = _eb.Create()
|
||||
.WithOkColor();
|
||||
|
||||
if (autoDelete)
|
||||
{
|
||||
embed
|
||||
.WithAuthor(um.Author.ToString(), um.Author.GetAvatarUrl())
|
||||
.AddField(langs.From, um.Content)
|
||||
.AddField(langs.To, output);
|
||||
|
||||
await tch.EmbedAsync(embed);
|
||||
|
||||
try
|
||||
{
|
||||
await um.DeleteAsync();
|
||||
}
|
||||
catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.Forbidden)
|
||||
{
|
||||
_atcs.TryUpdate(tch.Id, false, true);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
await um.ReplyAsync(embed: embed
|
||||
.AddField(langs.To, output)
|
||||
.Build());
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<string> Translate(string source, string target, string text = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
throw new ArgumentException("Text is empty or null", nameof(text));
|
||||
|
||||
var res = await _google.Translate(text, source, target).ConfigureAwait(false);
|
||||
return res.SanitizeMentions(true);
|
||||
}
|
||||
|
||||
public async Task<bool> ToggleAtl(ulong guildId, ulong channelId, bool autoDelete)
|
||||
{
|
||||
var ctx = _db.GetDbContext();
|
||||
|
||||
var old = await ctx.AutoTranslateChannels
|
||||
.ToLinqToDBTable()
|
||||
.FirstOrDefaultAsyncLinqToDB(x => x.ChannelId == channelId);
|
||||
|
||||
if (old is null)
|
||||
{
|
||||
ctx.AutoTranslateChannels
|
||||
.Add(new()
|
||||
{
|
||||
GuildId = guildId,
|
||||
ChannelId = channelId,
|
||||
AutoDelete = autoDelete,
|
||||
});
|
||||
|
||||
await ctx.SaveChangesAsync();
|
||||
|
||||
_atcs[channelId] = autoDelete;
|
||||
_users[channelId] = new();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// if autodelete value is different, update the autodelete value
|
||||
// instead of disabling
|
||||
if (old.AutoDelete != autoDelete)
|
||||
{
|
||||
old.AutoDelete = autoDelete;
|
||||
await ctx.SaveChangesAsync();
|
||||
_atcs[channelId] = autoDelete;
|
||||
return true;
|
||||
}
|
||||
|
||||
await ctx.AutoTranslateChannels
|
||||
.ToLinqToDBTable()
|
||||
.DeleteAsync(x => x.ChannelId == channelId);
|
||||
|
||||
await ctx.SaveChangesAsync();
|
||||
_atcs.TryRemove(channelId, out _);
|
||||
_users.TryRemove(channelId, out _);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public async Task<bool?> RegisterUserAsync(ulong userId, ulong channelId, string from, string to)
|
||||
{
|
||||
var ctx = _db.GetDbContext();
|
||||
var ch = await ctx.AutoTranslateChannels
|
||||
.ToLinqToDBTable()
|
||||
.GetByChannelId(channelId);
|
||||
|
||||
if (ch is null)
|
||||
return null;
|
||||
|
||||
var user = ch.Users
|
||||
.FirstOrDefault(x => x.UserId == userId);
|
||||
|
||||
if (user is null)
|
||||
{
|
||||
ch.Users.Add(user = new()
|
||||
{
|
||||
Source = from,
|
||||
Target = to,
|
||||
UserId = userId,
|
||||
});
|
||||
|
||||
await ctx.SaveChangesAsync();
|
||||
|
||||
var dict = _users.GetOrAdd(channelId, new ConcurrentDictionary<ulong, (string, string)>());
|
||||
dict[userId] = (from, to);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ctx.AutoTranslateUsers.Remove(user);
|
||||
await ctx.SaveChangesAsync();
|
||||
|
||||
if (_users.TryGetValue(channelId, out var inner))
|
||||
inner.TryRemove(userId, out _);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> UnregisterUser(ulong channelId, ulong userId)
|
||||
{
|
||||
var ctx = _db.GetDbContext();
|
||||
var rows = await ctx.AutoTranslateUsers
|
||||
.ToLinqToDBTable()
|
||||
.DeleteAsync(x => x.UserId == userId &&
|
||||
x.Channel.ChannelId == channelId);
|
||||
|
||||
if (_users.TryGetValue(channelId, out var inner))
|
||||
inner.TryRemove(userId, out _);
|
||||
|
||||
await ctx.SaveChangesAsync();
|
||||
return rows > 0;
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetLanguages() => _google.Languages;
|
||||
}
|
||||
}
|
|
@ -2,35 +2,29 @@
|
|||
using Discord.Commands;
|
||||
using NadekoBot.Extensions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
using NadekoBot.Common.Attributes;
|
||||
using NadekoBot.Services;
|
||||
using NadekoBot.Modules.Searches.Services;
|
||||
|
||||
namespace NadekoBot.Modules.Searches
|
||||
{
|
||||
public partial class Searches
|
||||
{
|
||||
[Group]
|
||||
public class TranslateCommands : NadekoSubmodule
|
||||
public class TranslateCommands : NadekoSubmodule<ITranslateService>
|
||||
{
|
||||
private readonly SearchesService _searches;
|
||||
private readonly IGoogleApiService _google;
|
||||
|
||||
public TranslateCommands(SearchesService searches, IGoogleApiService google)
|
||||
{
|
||||
_searches = searches;
|
||||
_google = google;
|
||||
}
|
||||
|
||||
[NadekoCommand, Aliases]
|
||||
public async Task Translate(string langs, [Leftover] string text = null)
|
||||
public async Task Translate(string from, string to, [Leftover] string text = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ctx.Channel.TriggerTypingAsync().ConfigureAwait(false);
|
||||
var translation = await _searches.Translate(langs, text).ConfigureAwait(false);
|
||||
await SendConfirmAsync(GetText(strs.translation) + " " + langs, translation).ConfigureAwait(false);
|
||||
var translation = await _service.Translate(from, to, text).ConfigureAwait(false);
|
||||
|
||||
var embed = _eb.Create(ctx)
|
||||
.WithOkColor()
|
||||
.AddField(from, text, false)
|
||||
.AddField(to, translation, false);
|
||||
|
||||
await ctx.Channel.EmbedAsync(embed);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -38,27 +32,6 @@ namespace NadekoBot.Modules.Searches
|
|||
}
|
||||
}
|
||||
|
||||
//[NadekoCommand, Usage, Description, Aliases]
|
||||
//[OwnerOnly]
|
||||
//public async Task Obfuscate([Leftover] string txt)
|
||||
//{
|
||||
// var lastItem = "en";
|
||||
// foreach (var item in _google.Languages.Except(new[] { "en" }).Where(x => x.Length < 4))
|
||||
// {
|
||||
// var txt2 = await _searches.Translate(lastItem + ">" + item, txt);
|
||||
// await ctx.Channel.EmbedAsync(_eb.Create()
|
||||
// .WithOkColor()
|
||||
// .WithTitle(lastItem + ">" + item)
|
||||
// .AddField("Input", txt)
|
||||
// .AddField("Output", txt2));
|
||||
// txt = txt2;
|
||||
// await Task.Delay(500);
|
||||
// lastItem = item;
|
||||
// }
|
||||
// txt = await _searches.Translate(lastItem + ">en", txt);
|
||||
// await SendConfirmAsync("Final output:\n\n" + txt);
|
||||
//}
|
||||
|
||||
public enum AutoDeleteAutoTranslate
|
||||
{
|
||||
Del,
|
||||
|
@ -68,56 +41,49 @@ namespace NadekoBot.Modules.Searches
|
|||
[NadekoCommand, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
[UserPerm(GuildPerm.Administrator)]
|
||||
[BotPerm(ChannelPerm.ManageMessages)]
|
||||
[OwnerOnly]
|
||||
public async Task AutoTranslate(AutoDeleteAutoTranslate autoDelete = AutoDeleteAutoTranslate.Nodel)
|
||||
{
|
||||
var channel = (ITextChannel)ctx.Channel;
|
||||
|
||||
if (autoDelete == AutoDeleteAutoTranslate.Del)
|
||||
{
|
||||
_searches.TranslatedChannels.AddOrUpdate(channel.Id, true, (key, val) => true);
|
||||
await ReplyConfirmLocalizedAsync(strs.atl_ad_started).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_searches.TranslatedChannels.TryRemove(channel.Id, out _))
|
||||
{
|
||||
await ReplyConfirmLocalizedAsync(strs.atl_stopped).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
if (_searches.TranslatedChannels.TryAdd(channel.Id, autoDelete == AutoDeleteAutoTranslate.Del))
|
||||
var toggle = await _service.ToggleAtl(ctx.Guild.Id, ctx.Channel.Id, autoDelete == AutoDeleteAutoTranslate.Del);
|
||||
if (toggle)
|
||||
{
|
||||
await ReplyConfirmLocalizedAsync(strs.atl_started).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
await ReplyConfirmLocalizedAsync(strs.atl_stopped).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
[NadekoCommand, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task AutoTransLang([Leftover] string langs = null)
|
||||
public async Task AutoTransLang()
|
||||
{
|
||||
var ucp = (ctx.User.Id, ctx.Channel.Id);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(langs))
|
||||
if (await _service.UnregisterUser(ctx.Channel.Id, ctx.User.Id))
|
||||
{
|
||||
if (_searches.UserLanguages.TryRemove(ucp, out langs))
|
||||
await ReplyConfirmLocalizedAsync(strs.atl_removed).ConfigureAwait(false);
|
||||
await ReplyConfirmLocalizedAsync(strs.atl_removed).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
[NadekoCommand, Aliases]
|
||||
[RequireContext(ContextType.Guild)]
|
||||
public async Task AutoTransLang(string from, string to)
|
||||
{
|
||||
var succ = await _service.RegisterUserAsync(ctx.User.Id, ctx.Channel.Id, from, to);
|
||||
|
||||
if (succ is null)
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.atl_not_enabled);
|
||||
return;
|
||||
}
|
||||
|
||||
var langarr = langs.ToLowerInvariant().Split('>');
|
||||
if (langarr.Length != 2)
|
||||
return;
|
||||
var from = langarr[0];
|
||||
var to = langarr[1];
|
||||
|
||||
if (!_google.Languages.Contains(from) || !_google.Languages.Contains(to))
|
||||
|
||||
if (succ is false)
|
||||
{
|
||||
await ReplyErrorLocalizedAsync(strs.invalid_lang).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
_searches.UserLanguages.AddOrUpdate(ucp, langs, (key, val) => langs);
|
||||
|
||||
await ReplyConfirmLocalizedAsync(strs.atl_set(from, to));
|
||||
}
|
||||
|
||||
|
@ -125,7 +91,7 @@ namespace NadekoBot.Modules.Searches
|
|||
[RequireContext(ContextType.Guild)]
|
||||
public async Task Translangs()
|
||||
{
|
||||
await ctx.Channel.SendTableAsync(_google.Languages, str => $"{str,-15}", 3).ConfigureAwait(false);
|
||||
await ctx.Channel.SendTableAsync(_service.GetLanguages(), str => $"{str,-15}", 3).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1306,7 +1306,7 @@ poll:
|
|||
autotranslang:
|
||||
desc: "Sets your source and target language to be used with `{0}at`. Specify no parameters to remove previously set value."
|
||||
args:
|
||||
- "en>fr"
|
||||
- "en fr"
|
||||
autotranslate:
|
||||
desc: "Starts automatic translation of all messages by users who set their `{0}atl` in this channel. You can set \"del\" parameter to automatically delete all translated user messages."
|
||||
args:
|
||||
|
|
|
@ -450,6 +450,7 @@
|
|||
"atl_set": "Your auto-translate language has been set to {0}>{1}",
|
||||
"atl_started": "Started automatic translation of messages on this channel.",
|
||||
"atl_stopped": "Stopped automatic translation of messages on this channel.",
|
||||
"atl_not_enabled": "Automatic translation is not enabled on this channel.",
|
||||
"bad_input_format": "Bad input format, or something went wrong.",
|
||||
"card_not_found": "Couldn't find that card.",
|
||||
"catfact": "fact",
|
||||
|
|
Loading…
Reference in a new issue