Added .todo commands and added toned down version of .fairplay

This commit is contained in:
Kwoth
2024-04-25 22:33:12 +00:00
parent b34f383649
commit 6bc8e4b7d2
30 changed files with 12293 additions and 148 deletions

View File

@@ -16,6 +16,20 @@ Experimental changelog. Mostly based on [keepachangelog](https://keepachangelog.
- `.ga list` lists active giveaways on the current server
- `.ga reroll <id>` rerolls the winner on the completed giveaway. This only works for 24 hours after the giveaway has ended, or until the bot restarts.
- After the giveaway has started, user join the giveaway by adding a :tada: reaction
- Selfhosters - Added `.sqlselectcsv` which will return results in a csv file instead of an embed.
- Todo Commands
- `.todo add <name>` - adds a new todo
- `.todo delete <id>` - deletes a todo item
- `.todo done <id>` - completes a todo (marks it with a checkmark)
- `.todo list` - lists all todos
- `.todo edit <id> <new message>` - edits a todo item message
- Todo archive commands
- `.todo archive add <name>` - adds all current todos (completed and not completed) to the archived list, your current todo list will become cleared
- `.todo archive list` - lists all your archived todo lists
- `.todo archive show <id>` - shows the todo items from one of your archived lists
- `.todo archive delete <id>` - deletes and archived todo list
- `.queufairplay` / `.qfp` (music feature) re-added but it works differently
- Once you run it, it will reorganize currently queued songs so that they're in a fair order. It has no effect on any subsequently queued songs
### Changed

View File

@@ -0,0 +1,9 @@
namespace NadekoBot.Db.Models;
public sealed class ArchivedTodoListModel
{
public int Id { get; set; }
public ulong UserId { get; set; }
public string Name { get; set; }
public List<TodoModel> Items { get; set; }
}

View File

@@ -0,0 +1,12 @@
namespace NadekoBot.Db.Models;
public sealed class TodoModel
{
public int Id { get; set; }
public ulong UserId { get; set; }
public string Todo { get; set; }
public DateTime DateAdded { get; set; }
public bool IsDone { get; set; }
public int? ArchiveId { get; set; }
}

View File

@@ -1,4 +1,7 @@
#nullable disable
using System.Globalization;
using CsvHelper;
using CsvHelper.Configuration;
using NadekoBot.Modules.Administration.Services;
#if !GLOBAL_NADEKO
@@ -34,6 +37,43 @@ namespace NadekoBot.Modules.Administration
20);
}
[Cmd]
[OwnerOnly]
public async Task SqlSelectCsv([Leftover] string sql)
{
var result = _service.SelectSql(sql);
// create a file stream and write the data as csv
using var ms = new MemoryStream();
await using var sw = new StreamWriter(ms);
await using var csv = new CsvWriter(sw,
new CsvConfiguration(CultureInfo.InvariantCulture) { Delimiter = "," });
foreach (var cn in result.ColumnNames)
{
csv.WriteField(cn);
}
await csv.NextRecordAsync();
foreach (var row in result.Results)
{
foreach (var field in row)
{
csv.WriteField(field);
}
await csv.NextRecordAsync();
}
await csv.FlushAsync();
ms.Position = 0;
// send the file
await ctx.Channel.SendFileAsync(ms, $"query_result_{DateTime.UtcNow.Ticks}.csv");
}
[Cmd]
[OwnerOnly]
public async Task SqlExec([Leftover] string sql)

View File

@@ -7,6 +7,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CsvHelper" Version="31.0.2" />
<PackageReference Include="Discord.Net" Version="3.204.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
</ItemGroup>

View File

@@ -755,4 +755,15 @@ public sealed partial class Music : NadekoModule<IMusicService>
else
await ReplyConfirmLocalizedAsync(strs.music_autoplay_off);
}
[Cmd]
[RequireContext(ContextType.Guild)]
public async Task QueueFairplay()
{
var newValue = await _service.FairplayAsync(ctx.Guild.Id);
if (newValue)
await ReplyConfirmLocalizedAsync(strs.music_fairplay);
else
await ReplyErrorLocalizedAsync(strs.no_player);
}
}

View File

@@ -33,4 +33,5 @@ public interface IMusicService : IPlaceholderProvider
Task<QualityPreset> GetMusicQualityAsync(ulong guildId);
Task SetMusicQualityAsync(ulong guildId, QualityPreset preset);
Task<bool> ToggleQueueAutoPlayAsync(ulong guildId);
Task<bool> FairplayAsync(ulong guildId);
}

View File

@@ -362,10 +362,7 @@ public sealed class MusicService : IMusicService
return false;
await ModifySettingsInternalAsync(guildId,
(settings, chId) =>
{
settings.MusicChannelId = chId;
},
(settings, chId) => { settings.MusicChannelId = chId; },
channelId);
_outputChannels.AddOrUpdate(guildId, (channel, channel), (_, old) => (old.Default, channel));
@@ -376,10 +373,7 @@ public sealed class MusicService : IMusicService
public async Task UnsetMusicChannelAsync(ulong guildId)
{
await ModifySettingsInternalAsync(guildId,
(settings, _) =>
{
settings.MusicChannelId = null;
},
(settings, _) => { settings.MusicChannelId = null; },
(ulong?)null);
if (_outputChannels.TryGetValue(guildId, out var old))
@@ -389,10 +383,7 @@ public sealed class MusicService : IMusicService
public async Task SetRepeatAsync(ulong guildId, PlayerRepeatType repeatType)
{
await ModifySettingsInternalAsync(guildId,
(settings, type) =>
{
settings.PlayerRepeat = type;
},
(settings, type) => { settings.PlayerRepeat = type; },
repeatType);
if (TryGetMusicPlayer(guildId, out var mp))
@@ -405,10 +396,7 @@ public sealed class MusicService : IMusicService
throw new ArgumentOutOfRangeException(nameof(value));
await ModifySettingsInternalAsync(guildId,
(settings, newValue) =>
{
settings.Volume = newValue;
},
(settings, newValue) => { settings.Volume = newValue; },
value);
if (TryGetMusicPlayer(guildId, out var mp))
@@ -419,10 +407,7 @@ public sealed class MusicService : IMusicService
{
var newState = false;
await ModifySettingsInternalAsync(guildId,
(settings, _) =>
{
newState = settings.AutoDisconnect = !settings.AutoDisconnect;
},
(settings, _) => { newState = settings.AutoDisconnect = !settings.AutoDisconnect; },
default(object));
return newState;
@@ -437,10 +422,7 @@ public sealed class MusicService : IMusicService
public Task SetMusicQualityAsync(ulong guildId, QualityPreset preset)
=> ModifySettingsInternalAsync(guildId,
(settings, _) =>
{
settings.QualityPreset = preset;
},
(settings, _) => { settings.QualityPreset = preset; },
preset);
public async Task<bool> ToggleQueueAutoPlayAsync(ulong guildId)
@@ -456,5 +438,16 @@ public sealed class MusicService : IMusicService
return newValue;
}
public Task<bool> FairplayAsync(ulong guildId)
{
if (TryGetMusicPlayer(guildId, out var mp))
{
mp.SetFairplay();
return Task.FromResult(true);
}
return Task.FromResult(false);
}
#endregion
}

View File

@@ -37,4 +37,5 @@ public interface IMusicPlayer : IDisposable
void EnqueueTracks(IEnumerable<ITrackInfo> tracks, string queuer);
void SetRepeat(PlayerRepeatType type);
void ShuffleQueue();
void SetFairplay();
}

View File

@@ -19,4 +19,5 @@ public interface IMusicQueue
IQueuedTrackInfo? MoveTrack(int from, int to);
void Shuffle(Random rng);
bool IsLast();
void ReorderFairly();
}

View File

@@ -61,10 +61,7 @@ public sealed class MusicPlayer : IMusicPlayer
_songBuffer = new PoopyBufferImmortalized(_vc.InputLength);
_thread = new(async () =>
{
await PlayLoop();
});
_thread = new(async () => { await PlayLoop(); });
_thread.Start();
}
@@ -283,7 +280,8 @@ public sealed class MusicPlayer : IMusicPlayer
var related = relatedSongs.Shuffle().FirstOrDefault();
if (related is not null)
{
var relatedTrack = await _trackResolveProvider.QuerySongAsync(related, MusicPlatform.Youtube);
var relatedTrack =
await _trackResolveProvider.QuerySongAsync(related, MusicPlatform.Youtube);
if (relatedTrack is not null)
EnqueueTrack(relatedTrack, "Autoplay");
}
@@ -525,4 +523,9 @@ public sealed class MusicPlayer : IMusicPlayer
}
private delegate void AdjustVolumeDelegate(Span<byte> data, float volume);
public void SetFairplay()
{
_queue.ReorderFairly();
}
}

View File

@@ -1,4 +1,6 @@
namespace NadekoBot.Modules.Music;
using Microsoft.EntityFrameworkCore.ChangeTracking;
namespace NadekoBot.Modules.Music;
public sealed partial class MusicQueue
{
@@ -41,7 +43,7 @@ public sealed partial class MusicQueue : IMusicQueue
get
{
// just make sure the internal logic runs first
// to make sure that some potential indermediate value is not returned
// to make sure that some potential intermediate value is not returned
lock (_locker)
{
return index;
@@ -79,10 +81,12 @@ public sealed partial class MusicQueue : IMusicQueue
var added = new QueuedTrackInfo(trackInfo, queuer);
enqueuedAt = tracks.Count;
tracks.AddLast(added);
return added;
}
}
public IQueuedTrackInfo EnqueueNext(ITrackInfo trackInfo, string queuer, out int trackIndex)
{
lock (_locker)
@@ -295,6 +299,48 @@ public sealed partial class MusicQueue : IMusicQueue
}
}
public void ReorderFairly()
{
lock (_locker)
{
var groups = new Dictionary<string, int>();
var queuers = new List<Queue<QueuedTrackInfo>>();
foreach (var track in tracks.Skip(index).Concat(tracks.Take(index)))
{
if (!groups.TryGetValue(track.Queuer, out var qIndex))
{
queuers.Add(new Queue<QueuedTrackInfo>());
qIndex = queuers.Count - 1;
groups.Add(track.Queuer, qIndex);
}
queuers[qIndex].Enqueue(track);
}
tracks = new LinkedList<QueuedTrackInfo>();
index = 0;
while (true)
{
for (var i = 0; i < queuers.Count; i++)
{
var queue = queuers[i];
tracks.AddLast(queue.Dequeue());
if (queue.Count == 0)
{
queuers.RemoveAt(i);
i--;
}
}
if (queuers.Count == 0)
break;
}
}
}
public bool TryRemoveAt(int remoteAt, out IQueuedTrackInfo? trackInfo, out bool isCurrent)
{
lock (_locker)

View File

@@ -0,0 +1,8 @@
namespace NadekoBot.Modules.Utility;
public enum ArchiveTodoResult
{
MaxLimitReached,
NoTodos,
Success
}

View File

@@ -0,0 +1,7 @@
namespace NadekoBot.Modules.Utility;
public enum TodoAddResult
{
MaxLimitReached,
Success
}

View File

@@ -0,0 +1,206 @@
using NadekoBot.Db.Models;
namespace NadekoBot.Modules.Utility;
public partial class Utility
{
[Group("todo")]
public partial class Todo : NadekoModule<TodoService>
{
[Cmd]
public async Task TodoAdd([Leftover] string todo)
{
var result = await _service.AddAsync(ctx.User.Id, todo);
if (result == TodoAddResult.MaxLimitReached)
{
await ReplyErrorLocalizedAsync(strs.todo_add_max_limit);
return;
}
await ctx.OkAsync();
}
[Cmd]
public async Task TodoEdit(kwum todoId, [Leftover] string newMessage)
{
if (!await _service.EditAsync(ctx.User.Id, todoId, newMessage))
{
await ReplyErrorLocalizedAsync(strs.todo_not_found);
return;
}
await ctx.OkAsync();
}
[Cmd]
public async Task TodoList()
{
var todos = await _service.GetAllTodosAsync(ctx.User.Id);
if (todos.Length == 0)
{
await ReplyErrorLocalizedAsync(strs.todo_list_empty);
return;
}
await ShowTodosAsync(todos);
}
[Cmd]
public async Task TodoComplete(kwum todoId)
{
if (!await _service.CompleteTodoAsync(ctx.User.Id, todoId))
{
await ReplyErrorLocalizedAsync(strs.todo_not_found);
return;
}
await ctx.OkAsync();
}
[Cmd]
public async Task TodoDelete(kwum todoId)
{
if (!await _service.DeleteTodoAsync(ctx.User.Id, todoId))
{
await ReplyErrorLocalizedAsync(strs.todo_not_found);
return;
}
await ctx.OkAsync();
}
[Cmd]
public async Task TodoClear()
{
await _service.ClearTodosAsync(ctx.User.Id);
await ReplyConfirmLocalizedAsync(strs.todo_cleared);
}
private async Task ShowTodosAsync(TodoModel[] todos)
{
await ctx.SendPaginatedConfirmAsync(0,
(curPage) =>
{
var eb = _eb.Create()
.WithOkColor()
.WithTitle(GetText(strs.todo_list));
ShowTodoItem(todos, curPage, eb);
return eb;
},
todos.Length,
9);
}
private static void ShowTodoItem(IReadOnlyCollection<TodoModel> todos, int curPage, IEmbedBuilder eb)
{
foreach (var todo in todos.Skip(curPage * 9).Take(9))
{
// green circle and yellow circle emojis
eb.AddField($"-",
$"{(todo.IsDone
? ""
: "🟡")} {Format.Code(new kwum(todo.Id).ToString())} {todo.Todo}",
false);
}
}
[Group("archive")]
public partial class ArchiveCommands : NadekoModule<TodoService>
{
[Cmd]
public async Task TodoArchiveAdd([Leftover] string name)
{
var result = await _service.ArchiveTodosAsync(ctx.User.Id, name);
if (result == ArchiveTodoResult.NoTodos)
{
await ReplyErrorLocalizedAsync(strs.todo_no_todos);
return;
}
if (result == ArchiveTodoResult.MaxLimitReached)
{
await ReplyErrorLocalizedAsync(strs.todo_archive_max_limit);
return;
}
await ctx.OkAsync();
}
[Cmd]
public async Task TodoArchiveList(int page = 1)
{
if (--page < 0)
return;
var archivedTodoLists = await _service.GetArchivedTodosAsync(ctx.User.Id);
if (archivedTodoLists.Count == 0)
{
await ReplyErrorLocalizedAsync(strs.todo_archive_empty);
return;
}
await ctx.SendPaginatedConfirmAsync(page,
(curPage) =>
{
var eb = _eb.Create()
.WithTitle(GetText(strs.todo_archive_list))
.WithOkColor();
foreach (var archivedList in archivedTodoLists.Skip(curPage * 9).Take(9))
{
eb.AddField($"id: {archivedList.Id.ToString()}", archivedList.Name, true);
}
return eb;
},
archivedTodoLists.Count,
9,
true);
}
[Cmd]
public async Task TodoArchiveShow(int id)
{
var list = await _service.GetArchivedTodoListAsync(ctx.User.Id, id);
if (list == null || list.Items.Count == 0)
{
await ReplyErrorLocalizedAsync(strs.todo_archive_not_found);
return;
}
await ctx.SendPaginatedConfirmAsync(0,
(curPage) =>
{
var eb = _eb.Create()
.WithOkColor()
.WithTitle(GetText(strs.todo_list));
ShowTodoItem(list.Items, curPage, eb);
return eb;
},
list.Items.Count,
9);
}
[Cmd]
public async Task TodoArchiveDelete(int id)
{
if (!await _service.ArchiveDeleteAsync(ctx.User.Id, id))
{
await ctx.ErrorAsync();
return;
}
await ctx.OkAsync();
}
}
}
}

View File

@@ -0,0 +1,182 @@
using LinqToDB;
using LinqToDB.EntityFrameworkCore;
using NadekoBot.Db.Models;
namespace NadekoBot.Modules.Utility;
public sealed class TodoService
{
private const int ARCHIVE_MAX_COUNT = 9;
private const int TODO_MAX_COUNT = 27;
private readonly DbService _db;
public TodoService(DbService db)
{
_db = db;
}
public async Task<TodoAddResult> AddAsync(ulong userId, string todo)
{
await using var ctx = _db.GetDbContext();
if (await ctx
.GetTable<TodoModel>()
.Where(x => x.UserId == userId && x.ArchiveId == null)
.CountAsync() >= TODO_MAX_COUNT)
{
return TodoAddResult.MaxLimitReached;
}
await ctx
.GetTable<TodoModel>()
.InsertAsync(() => new TodoModel()
{
UserId = userId,
Todo = todo,
DateAdded = DateTime.UtcNow,
IsDone = false,
});
return TodoAddResult.Success;
}
public async Task<bool> EditAsync(ulong userId, int todoId, string newMessage)
{
await using var ctx = _db.GetDbContext();
return await ctx
.GetTable<TodoModel>()
.Where(x => x.UserId == userId && x.Id == todoId)
.Set(x => x.Todo, newMessage)
.UpdateAsync() > 0;
}
public async Task<TodoModel[]> GetAllTodosAsync(ulong userId)
{
await using var ctx = _db.GetDbContext();
return await ctx
.GetTable<TodoModel>()
.Where(x => x.UserId == userId && x.ArchiveId == null)
.ToArrayAsyncLinqToDB();
}
public async Task<bool> CompleteTodoAsync(ulong userId, int todoId)
{
await using var ctx = _db.GetDbContext();
var count = await ctx
.GetTable<TodoModel>()
.Where(x => x.UserId == userId && x.Id == todoId)
.Set(x => x.IsDone, true)
.UpdateAsync();
return count > 0;
}
public async Task<bool> DeleteTodoAsync(ulong userId, int todoId)
{
await using var ctx = _db.GetDbContext();
var count = await ctx
.GetTable<TodoModel>()
.Where(x => x.UserId == userId && x.Id == todoId)
.DeleteAsync();
return count > 0;
}
public async Task ClearTodosAsync(ulong userId)
{
await using var ctx = _db.GetDbContext();
await ctx
.GetTable<TodoModel>()
.Where(x => x.UserId == userId && x.ArchiveId == null)
.DeleteAsync();
}
public async Task<ArchiveTodoResult> ArchiveTodosAsync(ulong userId, string name)
{
// create a new archive
await using var ctx = _db.GetDbContext();
await using var tr = await ctx.Database.BeginTransactionAsync();
// check if the user reached the limit
var count = await ctx
.GetTable<ArchivedTodoListModel>()
.Where(x => x.UserId == userId)
.CountAsync();
if (count >= ARCHIVE_MAX_COUNT)
return ArchiveTodoResult.MaxLimitReached;
var inserted = await ctx
.GetTable<ArchivedTodoListModel>()
.InsertWithOutputAsync(() => new ArchivedTodoListModel()
{
UserId = userId,
Name = name,
});
// mark all existing todos as archived
var updated = await ctx
.GetTable<TodoModel>()
.Where(x => x.UserId == userId && x.ArchiveId == null)
.Set(x => x.ArchiveId, inserted.Id)
.UpdateAsync();
if (updated == 0)
{
await tr.RollbackAsync();
// // delete the empty archive
// await ctx
// .GetTable<ArchivedTodoListModel>()
// .Where(x => x.Id == inserted.Id)
// .DeleteAsync();
return ArchiveTodoResult.NoTodos;
}
await tr.CommitAsync();
return ArchiveTodoResult.Success;
}
public async Task<IReadOnlyCollection<ArchivedTodoListModel>> GetArchivedTodosAsync(ulong userId)
{
await using var ctx = _db.GetDbContext();
return await ctx
.GetTable<ArchivedTodoListModel>()
.Where(x => x.UserId == userId)
.ToArrayAsyncLinqToDB();
}
public async Task<ArchivedTodoListModel?> GetArchivedTodoListAsync(ulong userId, int archiveId)
{
await using var ctx = _db.GetDbContext();
return await ctx
.GetTable<ArchivedTodoListModel>()
.Where(x => x.UserId == userId && x.Id == archiveId)
.LoadWith(x => x.Items)
.FirstOrDefaultAsyncLinqToDB();
}
public async Task<bool> ArchiveDeleteAsync(ulong userId, int archiveId)
{
await using var ctx = _db.GetDbContext();
var count = await ctx
.GetTable<ArchivedTodoListModel>()
.Where(x => x.UserId == userId && x.Id == archiveId)
.DeleteAsync();
return count > 0;
}
}

View File

@@ -63,6 +63,9 @@ public abstract class NadekoContext : DbContext
public DbSet<StickyRole> StickyRoles { get; set; }
public DbSet<TodoModel> Todos { get; set; }
public DbSet<ArchivedTodoListModel> TodosArchive { get; set; }
#region Mandatory Provider-Specific Values
@@ -512,6 +515,23 @@ public abstract class NadekoContext : DbContext
.IsUnique());
#endregion
#region Todo
modelBuilder.Entity<TodoModel>()
.HasKey(x => x.Id);
modelBuilder.Entity<TodoModel>()
.HasIndex(x => x.UserId)
.IsUnique(false);
modelBuilder.Entity<ArchivedTodoListModel>()
.HasMany(x => x.Items)
.WithOne()
.HasForeignKey(x => x.ArchiveId)
.OnDelete(DeleteBehavior.Cascade);
#endregion
}
#if DEBUG

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,77 @@
using System;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace NadekoBot.Db.Migrations.Mysql
{
/// <inheritdoc />
public partial class todolist : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "todosarchive",
columns: table => new
{
id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
userid = table.Column<ulong>(type: "bigint unsigned", nullable: false),
name = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("pk_todosarchive", x => x.id);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "todos",
columns: table => new
{
id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
userid = table.Column<ulong>(type: "bigint unsigned", nullable: false),
todo = table.Column<string>(type: "longtext", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
dateadded = table.Column<DateTime>(type: "datetime(6)", nullable: false),
isdone = table.Column<bool>(type: "tinyint(1)", nullable: false),
archiveid = table.Column<int>(type: "int", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("pk_todos", x => x.id);
table.ForeignKey(
name: "fk_todos_todosarchive_archiveid",
column: x => x.archiveid,
principalTable: "todosarchive",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateIndex(
name: "ix_todos_archiveid",
table: "todos",
column: "archiveid");
migrationBuilder.CreateIndex(
name: "ix_todos_userid",
table: "todos",
column: "userid");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "todos");
migrationBuilder.DropTable(
name: "todosarchive");
}
}
}

View File

@@ -2800,6 +2800,30 @@ namespace NadekoBot.Db.Migrations.Mysql
b.ToTable("xpsettings", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.ArchivedTodoListModel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasColumnName("id");
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("longtext")
.HasColumnName("name");
b.Property<ulong>("UserId")
.HasColumnType("bigint unsigned")
.HasColumnName("userid");
b.HasKey("Id")
.HasName("pk_todosarchive");
b.ToTable("todosarchive", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.AutoPublishChannel", b =>
{
b.Property<int>("Id")
@@ -3246,6 +3270,48 @@ namespace NadekoBot.Db.Migrations.Mysql
b.ToTable("streamonlinemessages", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.TodoModel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasColumnName("id");
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
b.Property<int?>("ArchiveId")
.HasColumnType("int")
.HasColumnName("archiveid");
b.Property<DateTime>("DateAdded")
.HasColumnType("datetime(6)")
.HasColumnName("dateadded");
b.Property<bool>("IsDone")
.HasColumnType("tinyint(1)")
.HasColumnName("isdone");
b.Property<string>("Todo")
.IsRequired()
.HasColumnType("longtext")
.HasColumnName("todo");
b.Property<ulong>("UserId")
.HasColumnType("bigint unsigned")
.HasColumnName("userid");
b.HasKey("Id")
.HasName("pk_todos");
b.HasIndex("ArchiveId")
.HasDatabaseName("ix_todos_archiveid");
b.HasIndex("UserId")
.HasDatabaseName("ix_todos_userid");
b.ToTable("todos", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.XpShopOwnedItem", b =>
{
b.Property<int>("Id")
@@ -3781,6 +3847,15 @@ namespace NadekoBot.Db.Migrations.Mysql
.HasConstraintName("fk_giveawayuser_giveawaymodel_giveawayid");
});
modelBuilder.Entity("NadekoBot.Db.Models.TodoModel", b =>
{
b.HasOne("NadekoBot.Db.Models.ArchivedTodoListModel", null)
.WithMany("Items")
.HasForeignKey("ArchiveId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_todos_todosarchive_archiveid");
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.AntiSpamSetting", b =>
{
b.Navigation("IgnoredChannels");
@@ -3889,6 +3964,11 @@ namespace NadekoBot.Db.Migrations.Mysql
b.Navigation("RoleRewards");
});
modelBuilder.Entity("NadekoBot.Db.Models.ArchivedTodoListModel", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("NadekoBot.Db.Models.ClubInfo", b =>
{
b.Navigation("Applicants");

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,73 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace NadekoBot.Db.Migrations
{
/// <inheritdoc />
public partial class todolist : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "todosarchive",
columns: table => new
{
id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
userid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
name = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("pk_todosarchive", x => x.id);
});
migrationBuilder.CreateTable(
name: "todos",
columns: table => new
{
id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
userid = table.Column<decimal>(type: "numeric(20,0)", nullable: false),
todo = table.Column<string>(type: "text", nullable: false),
dateadded = table.Column<DateTime>(type: "timestamp without time zone", nullable: false),
isdone = table.Column<bool>(type: "boolean", nullable: false),
archiveid = table.Column<int>(type: "integer", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("pk_todos", x => x.id);
table.ForeignKey(
name: "fk_todos_todosarchive_archiveid",
column: x => x.archiveid,
principalTable: "todosarchive",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "ix_todos_archiveid",
table: "todos",
column: "archiveid");
migrationBuilder.CreateIndex(
name: "ix_todos_userid",
table: "todos",
column: "userid");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "todos");
migrationBuilder.DropTable(
name: "todosarchive");
}
}
}

View File

@@ -2800,6 +2800,30 @@ namespace NadekoBot.Db.Migrations
b.ToTable("xpsettings", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.ArchivedTodoListModel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text")
.HasColumnName("name");
b.Property<decimal>("UserId")
.HasColumnType("numeric(20,0)")
.HasColumnName("userid");
b.HasKey("Id")
.HasName("pk_todosarchive");
b.ToTable("todosarchive", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.AutoPublishChannel", b =>
{
b.Property<int>("Id")
@@ -3243,6 +3267,48 @@ namespace NadekoBot.Db.Migrations
b.ToTable("streamonlinemessages", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.TodoModel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int?>("ArchiveId")
.HasColumnType("integer")
.HasColumnName("archiveid");
b.Property<DateTime>("DateAdded")
.HasColumnType("timestamp without time zone")
.HasColumnName("dateadded");
b.Property<bool>("IsDone")
.HasColumnType("boolean")
.HasColumnName("isdone");
b.Property<string>("Todo")
.IsRequired()
.HasColumnType("text")
.HasColumnName("todo");
b.Property<decimal>("UserId")
.HasColumnType("numeric(20,0)")
.HasColumnName("userid");
b.HasKey("Id")
.HasName("pk_todos");
b.HasIndex("ArchiveId")
.HasDatabaseName("ix_todos_archiveid");
b.HasIndex("UserId")
.HasDatabaseName("ix_todos_userid");
b.ToTable("todos", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.XpShopOwnedItem", b =>
{
b.Property<int>("Id")
@@ -3778,6 +3844,15 @@ namespace NadekoBot.Db.Migrations
.HasConstraintName("fk_giveawayuser_giveawaymodel_giveawayid");
});
modelBuilder.Entity("NadekoBot.Db.Models.TodoModel", b =>
{
b.HasOne("NadekoBot.Db.Models.ArchivedTodoListModel", null)
.WithMany("Items")
.HasForeignKey("ArchiveId")
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("fk_todos_todosarchive_archiveid");
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.AntiSpamSetting", b =>
{
b.Navigation("IgnoredChannels");
@@ -3886,6 +3961,11 @@ namespace NadekoBot.Db.Migrations
b.Navigation("RoleRewards");
});
modelBuilder.Entity("NadekoBot.Db.Models.ArchivedTodoListModel", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("NadekoBot.Db.Models.ClubInfo", b =>
{
b.Navigation("Applicants");

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,72 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace NadekoBot.Db.Migrations.Sqlite
{
/// <inheritdoc />
public partial class todolist : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "TodosArchive",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
UserId = table.Column<ulong>(type: "INTEGER", nullable: false),
Name = table.Column<string>(type: "TEXT", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_TodosArchive", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Todos",
columns: table => new
{
Id = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
UserId = table.Column<ulong>(type: "INTEGER", nullable: false),
Todo = table.Column<string>(type: "TEXT", nullable: false),
DateAdded = table.Column<DateTime>(type: "TEXT", nullable: false),
IsDone = table.Column<bool>(type: "INTEGER", nullable: false),
ArchiveId = table.Column<int>(type: "INTEGER", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Todos", x => x.Id);
table.ForeignKey(
name: "FK_Todos_TodosArchive_ArchiveId",
column: x => x.ArchiveId,
principalTable: "TodosArchive",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Todos_ArchiveId",
table: "Todos",
column: "ArchiveId");
migrationBuilder.CreateIndex(
name: "IX_Todos_UserId",
table: "Todos",
column: "UserId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Todos");
migrationBuilder.DropTable(
name: "TodosArchive");
}
}
}

View File

@@ -43,7 +43,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId")
.IsUnique();
b.ToTable("AntiAltSetting");
b.ToTable("AntiAltSetting", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.AntiRaidSetting", b =>
@@ -75,7 +75,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId")
.IsUnique();
b.ToTable("AntiRaidSetting");
b.ToTable("AntiRaidSetting", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.AntiSpamIgnore", b =>
@@ -97,7 +97,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("AntiSpamSettingId");
b.ToTable("AntiSpamIgnore");
b.ToTable("AntiSpamIgnore", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.AntiSpamSetting", b =>
@@ -129,7 +129,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId")
.IsUnique();
b.ToTable("AntiSpamSetting");
b.ToTable("AntiSpamSetting", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.AutoCommand", b =>
@@ -167,7 +167,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasKey("Id");
b.ToTable("AutoCommands");
b.ToTable("AutoCommands", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.AutoTranslateChannel", b =>
@@ -195,7 +195,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildId");
b.ToTable("AutoTranslateChannels");
b.ToTable("AutoTranslateChannels", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.AutoTranslateUser", b =>
@@ -223,7 +223,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasAlternateKey("ChannelId", "UserId");
b.ToTable("AutoTranslateUsers");
b.ToTable("AutoTranslateUsers", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.BanTemplate", b =>
@@ -249,7 +249,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildId")
.IsUnique();
b.ToTable("BanTemplates");
b.ToTable("BanTemplates", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.BlacklistEntry", b =>
@@ -269,7 +269,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasKey("Id");
b.ToTable("Blacklist");
b.ToTable("Blacklist", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.CommandAlias", b =>
@@ -294,7 +294,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId");
b.ToTable("CommandAlias");
b.ToTable("CommandAlias", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.CommandCooldown", b =>
@@ -319,7 +319,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId");
b.ToTable("CommandCooldown");
b.ToTable("CommandCooldown", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.CurrencyTransaction", b =>
@@ -357,7 +357,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("UserId");
b.ToTable("CurrencyTransactions");
b.ToTable("CurrencyTransactions", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.DelMsgOnCmdChannel", b =>
@@ -382,7 +382,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId");
b.ToTable("DelMsgOnCmdChannel");
b.ToTable("DelMsgOnCmdChannel", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.DiscordPermOverride", b =>
@@ -408,7 +408,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildId", "Command")
.IsUnique();
b.ToTable("DiscordPermOverrides");
b.ToTable("DiscordPermOverrides", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.ExcludedItem", b =>
@@ -433,7 +433,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("XpSettingsId");
b.ToTable("ExcludedItem");
b.ToTable("ExcludedItem", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.FeedSub", b =>
@@ -462,7 +462,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasAlternateKey("GuildConfigId", "Url");
b.ToTable("FeedSub");
b.ToTable("FeedSub", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.FilterChannelId", b =>
@@ -484,7 +484,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId");
b.ToTable("FilterChannelId");
b.ToTable("FilterChannelId", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.FilterLinksChannelId", b =>
@@ -506,7 +506,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId");
b.ToTable("FilterLinksChannelId");
b.ToTable("FilterLinksChannelId", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.FilterWordsChannelId", b =>
@@ -528,7 +528,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId");
b.ToTable("FilterWordsChannelId");
b.ToTable("FilterWordsChannelId", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.FilteredWord", b =>
@@ -550,7 +550,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId");
b.ToTable("FilteredWord");
b.ToTable("FilteredWord", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.GCChannelId", b =>
@@ -572,7 +572,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId");
b.ToTable("GCChannelId");
b.ToTable("GCChannelId", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.GamblingStats", b =>
@@ -598,7 +598,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("Feature")
.IsUnique();
b.ToTable("GamblingStats");
b.ToTable("GamblingStats", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.GroupName", b =>
@@ -624,7 +624,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId", "Number")
.IsUnique();
b.ToTable("GroupName");
b.ToTable("GroupName", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.GuildConfig", b =>
@@ -759,7 +759,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("WarnExpireHours");
b.ToTable("GuildConfigs");
b.ToTable("GuildConfigs", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.IgnoredLogItem", b =>
@@ -785,7 +785,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("LogSettingId", "LogItemId", "ItemType")
.IsUnique();
b.ToTable("IgnoredLogChannels");
b.ToTable("IgnoredLogChannels", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.IgnoredVoicePresenceChannel", b =>
@@ -807,7 +807,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("LogSettingId");
b.ToTable("IgnoredVoicePresenceCHannels");
b.ToTable("IgnoredVoicePresenceCHannels", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.ImageOnlyChannel", b =>
@@ -833,7 +833,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("ChannelId")
.IsUnique();
b.ToTable("ImageOnlyChannels");
b.ToTable("ImageOnlyChannels", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.LogSetting", b =>
@@ -907,7 +907,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildId")
.IsUnique();
b.ToTable("LogSettings");
b.ToTable("LogSettings", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.MusicPlayerSettings", b =>
@@ -944,7 +944,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildId")
.IsUnique();
b.ToTable("MusicPlayerSettings");
b.ToTable("MusicPlayerSettings", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.MusicPlaylist", b =>
@@ -967,7 +967,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasKey("Id");
b.ToTable("MusicPlaylists");
b.ToTable("MusicPlaylists", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.MutedUserId", b =>
@@ -989,7 +989,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId");
b.ToTable("MutedUserId");
b.ToTable("MutedUserId", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.NadekoExpression", b =>
@@ -1027,7 +1027,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasKey("Id");
b.ToTable("Expressions");
b.ToTable("Expressions", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.NsfwBlacklistedTag", b =>
@@ -1049,7 +1049,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildId");
b.ToTable("NsfwBlacklistedTags");
b.ToTable("NsfwBlacklistedTags", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.Permissionv2", b =>
@@ -1089,7 +1089,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId");
b.ToTable("Permissions");
b.ToTable("Permissions", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.PlantedCurrency", b =>
@@ -1126,7 +1126,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("MessageId")
.IsUnique();
b.ToTable("PlantedCurrency");
b.ToTable("PlantedCurrency", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.PlaylistSong", b =>
@@ -1160,7 +1160,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("MusicPlaylistId");
b.ToTable("PlaylistSong");
b.ToTable("PlaylistSong", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.Poll", b =>
@@ -1186,7 +1186,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildId")
.IsUnique();
b.ToTable("Poll");
b.ToTable("Poll", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.PollAnswer", b =>
@@ -1211,7 +1211,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("PollId");
b.ToTable("PollAnswer");
b.ToTable("PollAnswer", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.PollVote", b =>
@@ -1236,7 +1236,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("PollId");
b.ToTable("PollVote");
b.ToTable("PollVote", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.Quote", b =>
@@ -1272,7 +1272,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("Keyword");
b.ToTable("Quotes");
b.ToTable("Quotes", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.ReactionRoleV2", b =>
@@ -1313,7 +1313,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("MessageId", "Emote")
.IsUnique();
b.ToTable("ReactionRoles");
b.ToTable("ReactionRoles", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.Reminder", b =>
@@ -1350,7 +1350,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("When");
b.ToTable("Reminders");
b.ToTable("Reminders", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.Repeater", b =>
@@ -1385,7 +1385,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasKey("Id");
b.ToTable("Repeaters");
b.ToTable("Repeaters", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.RewardedUser", b =>
@@ -1414,7 +1414,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("PlatformUserId")
.IsUnique();
b.ToTable("RewardedUsers");
b.ToTable("RewardedUsers", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.RotatingPlayingStatus", b =>
@@ -1434,7 +1434,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasKey("Id");
b.ToTable("RotatingStatus");
b.ToTable("RotatingStatus", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.SelfAssignedRole", b =>
@@ -1465,7 +1465,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildId", "RoleId")
.IsUnique();
b.ToTable("SelfAssignableRoles");
b.ToTable("SelfAssignableRoles", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.ShopEntry", b =>
@@ -1511,7 +1511,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId");
b.ToTable("ShopEntry");
b.ToTable("ShopEntry", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.ShopEntryItem", b =>
@@ -1533,7 +1533,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("ShopEntryId");
b.ToTable("ShopEntryItem");
b.ToTable("ShopEntryItem", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.SlowmodeIgnoredRole", b =>
@@ -1555,7 +1555,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId");
b.ToTable("SlowmodeIgnoredRole");
b.ToTable("SlowmodeIgnoredRole", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.SlowmodeIgnoredUser", b =>
@@ -1577,7 +1577,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId");
b.ToTable("SlowmodeIgnoredUser");
b.ToTable("SlowmodeIgnoredUser", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.StickyRole", b =>
@@ -1604,7 +1604,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildId", "UserId")
.IsUnique();
b.ToTable("StickyRoles");
b.ToTable("StickyRoles", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.StreamRoleBlacklistedUser", b =>
@@ -1629,7 +1629,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("StreamRoleSettingsId");
b.ToTable("StreamRoleBlacklistedUser");
b.ToTable("StreamRoleBlacklistedUser", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.StreamRoleSettings", b =>
@@ -1661,7 +1661,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId")
.IsUnique();
b.ToTable("StreamRoleSettings");
b.ToTable("StreamRoleSettings", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.StreamRoleWhitelistedUser", b =>
@@ -1686,7 +1686,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("StreamRoleSettingsId");
b.ToTable("StreamRoleWhitelistedUser");
b.ToTable("StreamRoleWhitelistedUser", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.UnbanTimer", b =>
@@ -1711,7 +1711,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId");
b.ToTable("UnbanTimer");
b.ToTable("UnbanTimer", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.UnmuteTimer", b =>
@@ -1736,7 +1736,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId");
b.ToTable("UnmuteTimer");
b.ToTable("UnmuteTimer", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.UnroleTimer", b =>
@@ -1764,7 +1764,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId");
b.ToTable("UnroleTimer");
b.ToTable("UnroleTimer", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.UserXpStats", b =>
@@ -1804,7 +1804,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("UserId", "GuildId")
.IsUnique();
b.ToTable("UserXpStats");
b.ToTable("UserXpStats", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.VcRoleInfo", b =>
@@ -1829,7 +1829,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId");
b.ToTable("VcRoleInfo");
b.ToTable("VcRoleInfo", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.WaifuInfo", b =>
@@ -1864,7 +1864,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("WaifuId")
.IsUnique();
b.ToTable("WaifuInfo");
b.ToTable("WaifuInfo", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.WaifuItem", b =>
@@ -1889,7 +1889,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("WaifuInfoId");
b.ToTable("WaifuItem");
b.ToTable("WaifuItem", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.WaifuUpdate", b =>
@@ -1921,7 +1921,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("UserId");
b.ToTable("WaifuUpdates");
b.ToTable("WaifuUpdates", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.Warning", b =>
@@ -1964,7 +1964,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("UserId");
b.ToTable("Warnings");
b.ToTable("Warnings", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.WarningPunishment", b =>
@@ -1995,7 +1995,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId");
b.ToTable("WarningPunishment");
b.ToTable("WarningPunishment", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.XpCurrencyReward", b =>
@@ -2020,7 +2020,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("XpSettingsId");
b.ToTable("XpCurrencyReward");
b.ToTable("XpCurrencyReward", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.XpRoleReward", b =>
@@ -2049,7 +2049,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("XpSettingsId", "Level")
.IsUnique();
b.ToTable("XpRoleReward");
b.ToTable("XpRoleReward", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.XpSettings", b =>
@@ -2072,7 +2072,25 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId")
.IsUnique();
b.ToTable("XpSettings");
b.ToTable("XpSettings", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.ArchivedTodoListModel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<ulong>("UserId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.ToTable("TodosArchive", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.AutoPublishChannel", b =>
@@ -2095,7 +2113,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildId")
.IsUnique();
b.ToTable("AutoPublishChannel");
b.ToTable("AutoPublishChannel", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.BankUser", b =>
@@ -2118,7 +2136,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("UserId")
.IsUnique();
b.ToTable("BankUsers");
b.ToTable("BankUsers", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.ClubApplicants", b =>
@@ -2133,7 +2151,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("UserId");
b.ToTable("ClubApplicants");
b.ToTable("ClubApplicants", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.ClubBans", b =>
@@ -2148,7 +2166,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("UserId");
b.ToTable("ClubBans");
b.ToTable("ClubBans", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.ClubInfo", b =>
@@ -2184,7 +2202,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("OwnerId")
.IsUnique();
b.ToTable("Clubs");
b.ToTable("Clubs", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.DiscordUser", b =>
@@ -2243,7 +2261,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("UserId");
b.ToTable("DiscordUser");
b.ToTable("DiscordUser", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.FollowedStream", b =>
@@ -2277,7 +2295,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GuildConfigId");
b.ToTable("FollowedStream");
b.ToTable("FollowedStream", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.GiveawayModel", b =>
@@ -2304,7 +2322,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasKey("Id");
b.ToTable("GiveawayModel");
b.ToTable("GiveawayModel", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.GiveawayUser", b =>
@@ -2328,7 +2346,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("GiveawayId", "UserId")
.IsUnique();
b.ToTable("GiveawayUser");
b.ToTable("GiveawayUser", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.PatronQuota", b =>
@@ -2355,7 +2373,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("UserId");
b.ToTable("PatronQuotas");
b.ToTable("PatronQuotas", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.PatronUser", b =>
@@ -2381,7 +2399,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("UniquePlatformUserId")
.IsUnique();
b.ToTable("Patrons");
b.ToTable("Patrons", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.StreamOnlineMessage", b =>
@@ -2407,7 +2425,38 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasKey("Id");
b.ToTable("StreamOnlineMessages");
b.ToTable("StreamOnlineMessages", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.TodoModel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int?>("ArchiveId")
.HasColumnType("INTEGER");
b.Property<DateTime>("DateAdded")
.HasColumnType("TEXT");
b.Property<bool>("IsDone")
.HasColumnType("INTEGER");
b.Property<string>("Todo")
.IsRequired()
.HasColumnType("TEXT");
b.Property<ulong>("UserId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("ArchiveId");
b.HasIndex("UserId");
b.ToTable("Todos", (string)null);
});
modelBuilder.Entity("NadekoBot.Db.Models.XpShopOwnedItem", b =>
@@ -2437,7 +2486,7 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.HasIndex("UserId", "ItemType", "ItemKey")
.IsUnique();
b.ToTable("XpShopOwnedItem");
b.ToTable("XpShopOwnedItem", (string)null);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.AntiAltSetting", b =>
@@ -2882,6 +2931,14 @@ namespace NadekoBot.Db.Migrations.Sqlite
.IsRequired();
});
modelBuilder.Entity("NadekoBot.Db.Models.TodoModel", b =>
{
b.HasOne("NadekoBot.Db.Models.ArchivedTodoListModel", null)
.WithMany("Items")
.HasForeignKey("ArchiveId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Nadeko.Bot.Db.Models.AntiSpamSetting", b =>
{
b.Navigation("IgnoredChannels");
@@ -2990,6 +3047,11 @@ namespace NadekoBot.Db.Migrations.Sqlite
b.Navigation("RoleRewards");
});
modelBuilder.Entity("NadekoBot.Db.Models.ArchivedTodoListModel", b =>
{
b.Navigation("Items");
});
modelBuilder.Entity("NadekoBot.Db.Models.ClubInfo", b =>
{
b.Navigation("Applicants");

View File

@@ -513,6 +513,8 @@ queuerepeat:
queueautoplay:
- queueautoplay
- qap
queuefairplay:
- qfp
save:
- save
streamrole:
@@ -1165,6 +1167,8 @@ sqlexec:
- sqlexec
sqlselect:
- sqlselect
sqlselectcsv:
- sqlselectcsv
deletewaifus:
- deletewaifus
deletewaifu:
@@ -1404,3 +1408,37 @@ giveawayreroll:
- reroll
giveawaylist:
- list
# todos
todoadd:
- add
- a
todolist:
- list
- ls
tododelete:
- delete
- del
- remove
- rm
todoclear:
- clear
- clr
- cls
todocomplete:
- complete
- done
- finish
todoarchiveadd:
- add
- create
- new
todoarchiveshow:
- show
todoarchivelist:
- list
- ls
todoarchivedelete:
- delete
- del
- remove
- rm

View File

@@ -1419,8 +1419,8 @@ log:
args:
- "userpresence"
- "userbanned"
fairplay:
desc: "Toggles fairplay. While enabled, the bot will prioritize songs from users who didn't have their song recently played instead of the song's position in the queue."
queuefairplay:
desc: "Triggers fairplay. The song queue will be re-ordered in a fair manner. No effect on newly added songs."
args:
- ""
define:
@@ -2045,6 +2045,10 @@ sqlselect:
desc: "Executes provided sql query and returns the results. Dangerous."
args:
- "SELECT * FROM DiscordUser LIMIT 5"
sqlselectcsv:
desc: "Executes provided sql query and returns the results in a csv file. Dangerous."
args:
- "SELECT * FROM DiscordUser LIMIT 5"
deletewaifus:
desc: "Deletes everything from WaifuUpdates, WaifuItem and WaifuInfo tables."
args:
@@ -2412,3 +2416,43 @@ giveawaylist:
desc: "Lists all active giveaways."
args:
- ""
todolist:
desc: "Lists all todos."
args:
- ""
todoadd:
desc: "Adds a new todo."
args:
- "I need to do this"
todoedit:
desc: "Edits a todo with the specified ID."
args:
- "abc This is an updated entry"
todocomplete:
desc: "Marks a todo with the specified ID as done."
args:
- "4a"
tododelete:
desc: "Deletes a todo with the specified ID."
args:
- "abc"
todoclear:
desc: "Deletes all unarchived todos."
args:
- ""
todoarchiveadd:
desc: "Creates a new archive with the specified name using current todos."
args:
- "Day 1"
todoarchivelist:
desc: "Lists all archived todo lists."
args:
- ""
todoarchiveshow:
desc: "Shows the archived todo list with the specified ID."
args:
- "3c"
todoarchivedelete:
desc: "Deletes the archived todo list with the specified ID."
args:
- "99"

View File

@@ -377,6 +377,7 @@
"id": "Id",
"now_playing": "Now playing",
"no_player": "No active music player.",
"music_fairplay": "Music queue has been fairly reordered.",
"no_search_results": "No search results.",
"player_queue": "Player queue - Page {0}/{1}",
"playing_track": "Playing track #{0}",
@@ -1077,4 +1078,14 @@
"giveaway_starting": "Starting giveaway...",
"winner": "Winner",
"giveaway_list": "List of active giveways",
"todo_list_empty": "Your todo list is empty." ,
"todo_list": "Todo List",
"todo_add_max_limit": "You've reached the maximum amount of todos you can have.",
"todo_not_found": "Todo not found.",
"todo_cleared": "All unarchived todos have been cleared.",
"todo_no_todos": "There are no todos in your todo list.",
"todo_archive_max_limit": "You've reached the maximum amount of archived todos you can have.",
"todo_archive_empty": "You have no archived todos.",
"todo_archive_list": "Archived Todo Lists",
"todo_archive_not_found": "Archived todo list not found."
}