HAG_BIB_Projekt/PrototypWPFHAG/SearchWindow.xaml.cs

376 lines
13 KiB
C#

using MahApps.Metro.Controls;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Web;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
namespace PrototypWPFHAG
{
/// <summary>
/// Interaktionslogik für SearchWindow.xaml
/// </summary>
public class DocumentResponse
{
[JsonPropertyName("documents")]
public List<SearchResult> Documents { get; set; }
}
public partial class SearchWindow : MetroWindow
{
public readonly HttpClient _httpClient;
private bool _isSearchInProgress;
private readonly PdfServiceClient _pdfServiceClient = new();
private const string BaseUrl = "http://localhost:8000"; // Microservice-URL
private string _selectedPdfPath;
private List<string> _selectedPdfPaths = new List<string>();
public SearchWindow()
{
InitializeComponent();
_httpClient = new HttpClient
{
BaseAddress = new Uri(BaseUrl),
Timeout = TimeSpan.FromSeconds(30)
};
}
private void BackToLogIn_Click(object sender, RoutedEventArgs e)
{
MainWindow loginWindow = new();
loginWindow.Show(); // Open new window
this.Close(); // Close this window
}
private async void SearchButton_Click(object sender, RoutedEventArgs e)
{
if (_isSearchInProgress) return;
try
{
_isSearchInProgress = true;
SearchButton.IsEnabled = false;
if (SearchByIdRadio.IsChecked == true)
{
await SearchByIdAsync();
}
else
{
await SearchBySimilarityAsync();
}
}
catch (Exception ex)
{
MessageBox.Show($"Fehler bei der Suche: {ex.Message}",
"Fehler",
MessageBoxButton.OK,
MessageBoxImage.Error);
}
finally
{
_isSearchInProgress = false;
SearchButton.IsEnabled = true;
}
}
private async Task SearchByIdAsync()
{
if (!int.TryParse(SearchTextBox.Text, out int documentId))
{
MessageBox.Show("Bitte eine gültige ID eingeben");
return;
}
try
{
var response = await _httpClient.GetAsync($"/documents/{documentId}");
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<DocumentDetail>(json);
await Dispatcher.InvokeAsync(() =>
{
SearchResultsListBox.ItemsSource = new List<DocumentDetail> { result };
ContentTextBox.Text = result.Content;
SearchResultsListBox.DisplayMemberPath = "DocumentName";
});
}
catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.NotFound)
{
MessageBox.Show("Dokument nicht gefunden");
}
catch (Exception ex)
{
MessageBox.Show($"Fehler: {ex.Message}");
}
}
private async Task SearchBySimilarityAsync()
{
try
{
var encodedQuery = HttpUtility.UrlEncode(SearchTextBox.Text);
var response = await _httpClient.GetAsync($"/documents/search/similarity?query={encodedQuery}");
var json = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ApiResponse>(json);
await Dispatcher.InvokeAsync(() =>
{
SearchResultsListBox.ItemsSource = result?.Documents;
SearchResultsListBox.DisplayMemberPath = "DocumentName";
});
}
catch (Exception ex)
{
MessageBox.Show($"Fehler: {ex.Message}");
}
}
private void PdfDropCanvas_DragEnter(object sender, DragEventArgs e)
{
// Nur PDF-Dateien erlauben
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
var files = (string[])e.Data.GetData(DataFormats.FileDrop);
if (files.Any(f => System.IO.Path.GetExtension(f).Equals(".pdf", StringComparison.OrdinalIgnoreCase)))
{
e.Effects = DragDropEffects.Copy;
DropHintText.Visibility = Visibility.Collapsed; // Platzhalter ausblenden
}
}
else
{
e.Effects = DragDropEffects.None;
}
e.Handled = true;
}
private void ChoosePdfButton_Click(object sender, RoutedEventArgs e)
{
var openFileDialog = new Microsoft.Win32.OpenFileDialog
{
Filter = "PDF Files (*.pdf)|*.pdf",
Multiselect = true
};
if (openFileDialog.ShowDialog() == true)
{
_selectedPdfPaths.AddRange(openFileDialog.FileNames);
PdfIcon.Visibility = Visibility.Visible;
PdfFileNameText.Text = string.Join(", ", _selectedPdfPaths.Select(System.IO.Path.GetFileName));
PdfFileNameText.Visibility = Visibility.Visible;
DropHintText.Visibility = Visibility.Collapsed;
}
}
private void PdfDropCanvas_Drop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
var pdfFiles = files.Where(f => System.IO.Path.GetExtension(f).Equals(".pdf", StringComparison.OrdinalIgnoreCase)).ToList();
if (pdfFiles.Any())
{
_selectedPdfPaths.AddRange(pdfFiles);
// 更新UI以显示所有文件
PdfIcon.Visibility = Visibility.Visible;
PdfFileNameText.Text = string.Join(", ", _selectedPdfPaths.Select(System.IO.Path.GetFileName));
PdfFileNameText.Visibility = Visibility.Visible;
DropHintText.Visibility = Visibility.Collapsed;
}
}
}
// Response-Klassen
public class ApiResponse
{
[JsonPropertyName("success")]
public bool Success { get; set; }
[JsonPropertyName("document")]
public DocumentDetail Document { get; set; }
[JsonPropertyName("documents")]
public List<DocumentDetail> Documents { get; set; }
}
public class DocumentDetail : INotifyPropertyChanged
{
[JsonPropertyName("id")]
public int Id { get; set; }
[JsonPropertyName("document_name")]
public string DocumentName { get; set; }
[JsonPropertyName("content")]
public string Content { get; set; }
[JsonPropertyName("distance")]
public double Distance { get; set; }
private bool _isSelected;
public bool IsSelected
{
get => _isSelected;
set
{
if (_isSelected != value)
{
_isSelected = value;
OnPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class ApiError
{
public string Detail { get; set; }
}
private async void UploadButton_Click(object sender, RoutedEventArgs e)
{
if (!_selectedPdfPaths.Any())
{
MessageBox.Show("Keine PDF ausgewählt!");
return;
}
UploadProgressBar.Visibility = Visibility.Visible;
UploadProgressBar.Value = 0;
UploadStatusText.Text = "Upload läuft...";
try
{
using var formData = new MultipartFormDataContent();
foreach (var pdfPath in _selectedPdfPaths)
{
var fileContent = new StreamContent(File.OpenRead(pdfPath));
formData.Add(fileContent, "files", Path.GetFileName(pdfPath));
}
var response = await _httpClient.PostAsync("/upload-pdfs/", formData);
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<ApiResponse>(json);
if (result?.Success == true)
{
UploadStatusText.Text = "Upload erfolgreich!";
}
}
catch (Exception ex)
{
UploadStatusText.Text = $"Fehler: {ex.Message}";
}
finally
{
UploadProgressBar.Visibility = Visibility.Collapsed;
_selectedPdfPaths.Clear();
PdfIcon.Visibility = Visibility.Collapsed;
PdfFileNameText.Visibility = Visibility.Collapsed;
DropHintText.Visibility = Visibility.Visible;
}
}
private async void DeleteButton_Click(object sender, RoutedEventArgs e)
{
if (SearchResultsListBox.SelectedItems.Count == 0)
{
MessageBox.Show("Bitte Dokumente auswählen.");
return;
}
var result = MessageBox.Show(
$"{SearchResultsListBox.SelectedItems.Count} Dokument(e) löschen?",
"Bestätigung",
MessageBoxButton.YesNo,
MessageBoxImage.Warning
);
if (result != MessageBoxResult.Yes) return;
var deletedIds = new List<int>();
var errorIds = new List<int>();
foreach (var item in SearchResultsListBox.SelectedItems.Cast<DocumentDetail>().ToList())
{
try
{
var response = await _httpClient.DeleteAsync($"/documents/{item.Id}");
if (response.IsSuccessStatusCode)
{
deletedIds.Add(item.Id);
}
else
{
errorIds.Add(item.Id);
}
}
catch
{
errorIds.Add(item.Id);
}
}
// Aktualisiere die Liste
if (SearchByIdRadio.IsChecked == true)
{
await SearchByIdAsync();
}
else
{
await SearchBySimilarityAsync();
}
// Feedback
var message = new StringBuilder();
if (deletedIds.Count > 0) message.AppendLine($"{deletedIds.Count} Dokument(e) gelöscht.");
if (errorIds.Count > 0) message.AppendLine($"{errorIds.Count} Dokument(e) konnten nicht gelöscht werden.");
MessageBox.Show(message.ToString());
}
private async void SearchResultsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (SearchResultsListBox.SelectedItem is DocumentDetail selected)
{
try
{
var response = await _httpClient.GetAsync($"/documents/{selected.Id}/markdown");
var content = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<JsonElement>(content);
ContentTextBox.Text = result.GetProperty("document")
.GetProperty("content")
.GetString();
}
catch (Exception ex)
{
ContentTextBox.Text = $"Fehler: {ex.Message}";
}
}
}
}
}