Add tools to remove/keep filtered messages in the app

This commit is contained in:
chylex 2021-11-29 23:22:03 +01:00
parent 07af4ae00f
commit 378c54908e
No known key found for this signature in database
GPG Key ID: 4DE42C8F19A80548
9 changed files with 85 additions and 4 deletions

View File

@ -26,6 +26,8 @@ namespace DHT.Desktop.Main.Controls {
public event PropertyChangedEventHandler? FilterPropertyChanged;
public bool HasAnyFilters => FilterByDate || FilterByChannel || FilterByUser;
private bool filterByDate = false;
private DateTime? startDate = null;
private DateTime? endDate = null;
@ -64,7 +66,6 @@ namespace DHT.Desktop.Main.Controls {
set => Change(ref filterByUser, value);
}
public HashSet<ulong> IncludedUsers {
get => includedUsers ?? db.GetAllUsers().Select(user => user.Id).ToHashSet();
set => Change(ref includedUsers, value);

View File

@ -7,7 +7,7 @@
x:Class="DHT.Desktop.Main.MainWindow"
Title="Discord History Tracker"
Icon="avares://DiscordHistoryTracker/Resources/icon.ico"
Width="800" Height="450"
Width="800" Height="500"
MinWidth="480" MinHeight="240"
WindowStartupLocation="CenterScreen">

View File

@ -11,6 +11,12 @@
<pages:ViewerPageModel />
</Design.DataContext>
<UserControl.Styles>
<Style Selector="Expander">
<Setter Property="Margin" Value="0 25 0 0" />
</Style>
</UserControl.Styles>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal" VerticalAlignment="Top">
<Button Command="{Binding OnClickOpenViewer}" Margin="0 0 5 0">Open Viewer</Button>
@ -18,6 +24,15 @@
</StackPanel>
<TextBlock Text="{Binding ExportedMessageText}" Margin="0 20 0 0" />
<controls:FilterPanel DataContext="{Binding FilterModel}" />
<Expander Header="Database Tools">
<StackPanel Orientation="Vertical" Spacing="10">
<StackPanel Orientation="Vertical" Spacing="4">
<RadioButton GroupName="DatabaseToolFilterMode" IsEnabled="{Binding HasFilters}" IsChecked="{Binding DatabaseToolFilterModeKeep}">Keep Only Messages Matching Filters</RadioButton>
<RadioButton GroupName="DatabaseToolFilterMode" IsEnabled="{Binding HasFilters}" IsChecked="{Binding DatabaseToolFilterModeRemove}">Remove Messages Matching Filters</RadioButton>
</StackPanel>
<Button IsEnabled="{Binding HasFilters}" Command="{Binding OnClickApplyFiltersToDatabase}">Apply Filters to Database</Button>
</StackPanel>
</Expander>
</StackPanel>
</UserControl>

View File

@ -7,9 +7,11 @@ using System.Threading.Tasks;
using System.Web;
using Avalonia.Controls;
using DHT.Desktop.Common;
using DHT.Desktop.Dialogs;
using DHT.Desktop.Main.Controls;
using DHT.Desktop.Models;
using DHT.Desktop.Resources;
using DHT.Server.Data.Filters;
using DHT.Server.Database;
using DHT.Server.Database.Export;
@ -17,6 +19,16 @@ namespace DHT.Desktop.Main.Pages {
public class ViewerPageModel : BaseModel {
public string ExportedMessageText { get; private set; } = "";
public bool DatabaseToolFilterModeKeep { get; set; } = true;
public bool DatabaseToolFilterModeRemove { get; set; } = false;
private bool hasFilters = false;
public bool HasFilters {
get => hasFilters;
set => Change(ref hasFilters, value);
}
private FilterPanelModel FilterModel { get; }
private readonly Window window;
@ -37,6 +49,7 @@ namespace DHT.Desktop.Main.Pages {
private void OnFilterPropertyChanged(object? sender, PropertyChangedEventArgs e) {
UpdateStatistics();
HasFilters = FilterModel.HasAnyFilters;
}
private void OnDbStatisticsChanged(object? sender, PropertyChangedEventArgs e) {
@ -95,5 +108,20 @@ namespace DHT.Desktop.Main.Pages {
await File.WriteAllTextAsync(path, await GenerateViewerContents());
}
}
public async void OnClickApplyFiltersToDatabase() {
var filter = FilterModel.CreateFilter();
if (DatabaseToolFilterModeKeep) {
if (DialogResult.YesNo.Yes == await Dialog.ShowYesNo(window, "Keep Matching Messages in This Database", db.CountMessages(filter).Pluralize("message") + " will be kept, and the rest will be removed from this database. This action cannot be undone. Proceed?")) {
db.RemoveMessages(filter, MessageFilterRemovalMode.KeepMatching);
}
}
else if (DatabaseToolFilterModeRemove) {
if (DialogResult.YesNo.Yes == await Dialog.ShowYesNo(window, "Remove Matching Messages in This Database", db.CountMessages(filter).Pluralize("message") + " will be removed from this database. This action cannot be undone. Proceed?")) {
db.RemoveMessages(filter, MessageFilterRemovalMode.RemoveMatching);
}
}
}
}
}

View File

@ -0,0 +1,6 @@
namespace DHT.Server.Data.Filters {
public enum MessageFilterRemovalMode {
KeepMatching,
RemoveMatching
}
}

View File

@ -40,6 +40,8 @@ namespace DHT.Server.Database {
return new();
}
public void RemoveMessages(MessageFilter filter, MessageFilterRemovalMode mode) {}
public void Dispose() {
GC.SuppressFinalize(this);
}

View File

@ -20,5 +20,6 @@ namespace DHT.Server.Database {
void AddMessages(Message[] messages);
int CountMessages(MessageFilter? filter = null);
List<Message> GetMessages(MessageFilter? filter = null);
void RemoveMessages(MessageFilter filter, MessageFilterRemovalMode mode);
}
}

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Text;
using System.Threading.Tasks;
using DHT.Server.Collections;
using DHT.Server.Data;
@ -303,6 +304,24 @@ namespace DHT.Server.Database.Sqlite {
return list;
}
public void RemoveMessages(MessageFilter filter, MessageFilterRemovalMode mode) {
var whereClause = filter.GenerateWhereClause(invert: mode == MessageFilterRemovalMode.KeepMatching);
if (string.IsNullOrEmpty(whereClause)) {
return;
}
// Rider is being stupid...
StringBuilder build = new StringBuilder()
.Append("DELETE ")
.Append("FROM messages")
.Append(whereClause);
using var cmd = conn.Command(build.ToString());
cmd.ExecuteNonQuery();
UpdateMessageStatistics();
}
private MultiDictionary<ulong, Attachment> GetAllAttachments() {
var dict = new MultiDictionary<ulong, Attachment>();

View File

@ -4,7 +4,7 @@ using DHT.Server.Data.Filters;
namespace DHT.Server.Database.Sqlite {
public static class SqliteMessageFilter {
public static string GenerateWhereClause(this MessageFilter? filter) {
public static string GenerateWhereClause(this MessageFilter? filter, bool invert = false) {
if (filter == null) {
return "";
}
@ -31,7 +31,16 @@ namespace DHT.Server.Database.Sqlite {
conditions.Add("message_id IN (" + string.Join(",", filter.MessageIds) + ")");
}
return conditions.Count == 0 ? "" : " WHERE " + string.Join(" AND ", conditions);
if (conditions.Count == 0) {
return "";
}
if (invert) {
return " WHERE NOT (" + string.Join(" AND ", conditions) + ")";
}
else {
return " WHERE " + string.Join(" AND ", conditions);
}
}
}
}