mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-04-09 21:41:38 +00:00
Refactoring of file filter (#681)
Some checks are pending
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg,updater, dmg) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis,updater, nsis) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage,deb,updater, appimage,deb) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Build and Release / Determine run mode (push) Waiting to run
Build and Release / Read metadata (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg,updater, dmg) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis,updater, nsis) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage,deb,updater, appimage,deb) (push) Blocked by required conditions
Some checks are pending
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg,updater, dmg) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis,updater, nsis) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage,deb,updater, appimage,deb) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Build and Release / Determine run mode (push) Waiting to run
Build and Release / Read metadata (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg,updater, dmg) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis,updater, nsis) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage,deb,updater, appimage,deb) (push) Blocked by required conditions
This commit is contained in:
parent
a65291c5eb
commit
e49973497c
@ -7135,29 +7135,47 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::RAG::RAGPROCESSES::AISRCSELWITHRETCTXVAL::T304
|
|||||||
-- AI source selection with AI retrieval context validation
|
-- AI source selection with AI retrieval context validation
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RAG::RAGPROCESSES::AISRCSELWITHRETCTXVAL::T3775725978"] = "AI source selection with AI retrieval context validation"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RAG::RAGPROCESSES::AISRCSELWITHRETCTXVAL::T3775725978"] = "AI source selection with AI retrieval context validation"
|
||||||
|
|
||||||
-- Executable Files
|
-- Text
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T2217313358"] = "Executable Files"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1041509726"] = "Text"
|
||||||
|
|
||||||
-- All Source Code Files
|
-- Office Files
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T2460199369"] = "All Source Code Files"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1063218378"] = "Office Files"
|
||||||
|
|
||||||
-- All Audio Files
|
-- Executable
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T2575722901"] = "All Audio Files"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1364437037"] = "Executable"
|
||||||
|
|
||||||
-- All Video Files
|
-- Mail
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T2850789856"] = "All Video Files"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1399880782"] = "Mail"
|
||||||
|
|
||||||
-- PDF Files
|
-- Source like
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T3108466742"] = "PDF Files"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1487238587"] = "Source like"
|
||||||
|
|
||||||
-- All Image Files
|
-- Image
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T4086723714"] = "All Image Files"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1494001562"] = "Image"
|
||||||
|
|
||||||
-- Text Files
|
-- Video
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T639143005"] = "Text Files"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1533528076"] = "Video"
|
||||||
|
|
||||||
-- All Office Files
|
-- Source Code
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T709668067"] = "All Office Files"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1569048941"] = "Source Code"
|
||||||
|
|
||||||
|
-- Config
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1779622119"] = "Config"
|
||||||
|
|
||||||
|
-- Audio
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T2291602489"] = "Audio"
|
||||||
|
|
||||||
|
-- Custom
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T2502277006"] = "Custom"
|
||||||
|
|
||||||
|
-- Media
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T3507473059"] = "Media"
|
||||||
|
|
||||||
|
-- Source like prefix
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T378481461"] = "Source like prefix"
|
||||||
|
|
||||||
|
-- Document
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T4165204724"] = "Document"
|
||||||
|
|
||||||
-- Pandoc Installation
|
-- Pandoc Installation
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::PANDOCAVAILABILITYSERVICE::T185447014"] = "Pandoc Installation"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::PANDOCAVAILABILITYSERVICE::T185447014"] = "Pandoc Installation"
|
||||||
|
|||||||
@ -76,34 +76,28 @@ public record FileAttachment(FileAttachmentType Type, string FileName, string Fi
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines the file attachment type based on the file extension.
|
/// Determines the file attachment type based on the file extension.
|
||||||
/// Uses centrally defined file type filters from <see cref="FileTypeFilter"/>.
|
/// Uses centrally defined file type filters from <see cref="FileTypes"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="filePath">The file path to analyze.</param>
|
/// <param name="filePath">The file path to analyze.</param>
|
||||||
/// <returns>The corresponding FileAttachmentType.</returns>
|
/// <returns>The corresponding FileAttachmentType.</returns>
|
||||||
private static FileAttachmentType DetermineFileType(string filePath)
|
private static FileAttachmentType DetermineFileType(string filePath)
|
||||||
{
|
{
|
||||||
var extension = Path.GetExtension(filePath).TrimStart('.').ToLowerInvariant();
|
// Check if it's an executable:
|
||||||
|
if (FileTypes.IsAllowedPath(filePath, FileTypes.EXECUTABLES))
|
||||||
if (FileTypeFilter.Executables.FilterExtensions.Contains(extension))
|
|
||||||
return FileAttachmentType.FORBIDDEN;
|
return FileAttachmentType.FORBIDDEN;
|
||||||
|
|
||||||
// Check if it's an image file:
|
// Check if it's an image file:
|
||||||
if (FileTypeFilter.AllImages.FilterExtensions.Contains(extension))
|
if (FileTypes.IsAllowedPath(filePath, FileTypes.IMAGE))
|
||||||
return FileAttachmentType.IMAGE;
|
return FileAttachmentType.IMAGE;
|
||||||
|
|
||||||
// Check if it's an audio file:
|
// Check if it's an audio file:
|
||||||
if (FileTypeFilter.AllAudio.FilterExtensions.Contains(extension))
|
if (FileTypes.IsAllowedPath(filePath, FileTypes.AUDIO))
|
||||||
return FileAttachmentType.AUDIO;
|
return FileAttachmentType.AUDIO;
|
||||||
|
|
||||||
// Check if it's an allowed document file (PDF, Text, or Office):
|
// Check if it's an allowed document file (PDF, Text, LaTeX, or Office):
|
||||||
if (FileTypeFilter.PDF.FilterExtensions.Contains(extension) ||
|
if (FileTypes.IsAllowedPath(filePath, FileTypes.DOCUMENT))
|
||||||
FileTypeFilter.Text.FilterExtensions.Contains(extension) ||
|
|
||||||
FileTypeFilter.AllOffice.FilterExtensions.Contains(extension) ||
|
|
||||||
FileTypeFilter.AllSourceCode.FilterExtensions.Contains(extension) ||
|
|
||||||
FileTypeFilter.IsAllowedSourceLikeFileName(filePath))
|
|
||||||
return FileAttachmentType.DOCUMENT;
|
return FileAttachmentType.DOCUMENT;
|
||||||
|
|
||||||
// All other file types are forbidden:
|
|
||||||
return FileAttachmentType.FORBIDDEN;
|
return FileAttachmentType.FORBIDDEN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -23,7 +23,7 @@ public partial class SelectFile : MSGComponentBase
|
|||||||
public string FileDialogTitle { get; set; } = "Select File";
|
public string FileDialogTitle { get; set; } = "Select File";
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public FileTypeFilter? Filter { get; set; }
|
public FileTypeFilter[]? Filter { get; set; }
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public Func<string, string?> Validation { get; set; } = _ => null;
|
public Func<string, string?> Validation { get; set; } = _ => null;
|
||||||
@ -32,7 +32,7 @@ public partial class SelectFile : MSGComponentBase
|
|||||||
public RustService RustService { get; set; } = null!;
|
public RustService RustService { get; set; } = null!;
|
||||||
|
|
||||||
[Inject]
|
[Inject]
|
||||||
protected ILogger<SelectDirectory> Logger { get; init; } = null!;
|
protected ILogger<SelectFile> Logger { get; init; } = null!;
|
||||||
|
|
||||||
private static readonly Dictionary<string, object?> SPELLCHECK_ATTRIBUTES = new();
|
private static readonly Dictionary<string, object?> SPELLCHECK_ATTRIBUTES = new();
|
||||||
|
|
||||||
|
|||||||
@ -7137,29 +7137,47 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::RAG::RAGPROCESSES::AISRCSELWITHRETCTXVAL::T304
|
|||||||
-- AI-based data source selection with AI retrieval context validation
|
-- AI-based data source selection with AI retrieval context validation
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RAG::RAGPROCESSES::AISRCSELWITHRETCTXVAL::T3775725978"] = "KI-basierte Datenquellen-Auswahl mit Validierung des Abrufkontexts"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RAG::RAGPROCESSES::AISRCSELWITHRETCTXVAL::T3775725978"] = "KI-basierte Datenquellen-Auswahl mit Validierung des Abrufkontexts"
|
||||||
|
|
||||||
-- Executable Files
|
-- Text
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T2217313358"] = "Ausführbare Dateien"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1041509726"] = "Text"
|
||||||
|
|
||||||
-- All Source Code Files
|
-- Office Files
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T2460199369"] = "Alle Quellcodedateien"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1063218378"] = "Office-Dateien"
|
||||||
|
|
||||||
-- All Audio Files
|
-- Executable
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T2575722901"] = "Alle Audiodateien"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1364437037"] = "Ausführbare Dateien"
|
||||||
|
|
||||||
-- All Video Files
|
-- Mail
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T2850789856"] = "Alle Videodateien"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1399880782"] = "E-Mail"
|
||||||
|
|
||||||
-- PDF Files
|
-- Source like
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T3108466742"] = "PDF-Dateien"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1487238587"] = "Source Code ähnlich"
|
||||||
|
|
||||||
-- All Image Files
|
-- Image
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T4086723714"] = "Alle Bilddateien"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1494001562"] = "Bild"
|
||||||
|
|
||||||
-- Text Files
|
-- Video
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T639143005"] = "Textdateien"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1533528076"] = "Video"
|
||||||
|
|
||||||
-- All Office Files
|
-- Source Code
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T709668067"] = "Alle Office-Dateien"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1569048941"] = "Quellcode"
|
||||||
|
|
||||||
|
-- Config
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1779622119"] = "Konfiguration"
|
||||||
|
|
||||||
|
-- Audio
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T2291602489"] = "Audio"
|
||||||
|
|
||||||
|
-- Custom
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T2502277006"] = "Benutzerdefiniert"
|
||||||
|
|
||||||
|
-- Media
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T3507473059"] = "Medien"
|
||||||
|
|
||||||
|
-- Source like prefix
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T378481461"] = "Source Code ähnlicher Prefix"
|
||||||
|
|
||||||
|
-- Document
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T4165204724"] = "Dokument"
|
||||||
|
|
||||||
-- Pandoc Installation
|
-- Pandoc Installation
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::PANDOCAVAILABILITYSERVICE::T185447014"] = "Pandoc-Installation"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::PANDOCAVAILABILITYSERVICE::T185447014"] = "Pandoc-Installation"
|
||||||
|
|||||||
@ -7137,29 +7137,47 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::RAG::RAGPROCESSES::AISRCSELWITHRETCTXVAL::T304
|
|||||||
-- AI-based data source selection with AI retrieval context validation
|
-- AI-based data source selection with AI retrieval context validation
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RAG::RAGPROCESSES::AISRCSELWITHRETCTXVAL::T3775725978"] = "AI-based data source selection with AI retrieval context validation"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RAG::RAGPROCESSES::AISRCSELWITHRETCTXVAL::T3775725978"] = "AI-based data source selection with AI retrieval context validation"
|
||||||
|
|
||||||
-- Executable Files
|
-- Text
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T2217313358"] = "Executable Files"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1041509726"] = "Text"
|
||||||
|
|
||||||
-- All Source Code Files
|
-- Office Files
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T2460199369"] = "All Source Code Files"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1063218378"] = "Office Files"
|
||||||
|
|
||||||
-- All Audio Files
|
-- Executable
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T2575722901"] = "All Audio Files"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1364437037"] = "Executable"
|
||||||
|
|
||||||
-- All Video Files
|
-- Mail
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T2850789856"] = "All Video Files"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1399880782"] = "Mail"
|
||||||
|
|
||||||
-- PDF Files
|
-- Source like
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T3108466742"] = "PDF Files"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1487238587"] = "Source like"
|
||||||
|
|
||||||
-- All Image Files
|
-- Image
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T4086723714"] = "All Image Files"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1494001562"] = "Image"
|
||||||
|
|
||||||
-- Text Files
|
-- Video
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T639143005"] = "Text Files"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1533528076"] = "Video"
|
||||||
|
|
||||||
-- All Office Files
|
-- Source Code
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPEFILTER::T709668067"] = "All Office Files"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1569048941"] = "Source Code"
|
||||||
|
|
||||||
|
-- Config
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T1779622119"] = "Config"
|
||||||
|
|
||||||
|
-- Audio
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T2291602489"] = "Audio"
|
||||||
|
|
||||||
|
-- Custom
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T2502277006"] = "Custom"
|
||||||
|
|
||||||
|
-- Media
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T3507473059"] = "Media"
|
||||||
|
|
||||||
|
-- Source like prefix
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T378481461"] = "Source like prefix"
|
||||||
|
|
||||||
|
-- Document
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::RUST::FILETYPES::T4165204724"] = "Document"
|
||||||
|
|
||||||
-- Pandoc Installation
|
-- Pandoc Installation
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::PANDOCAVAILABILITYSERVICE::T185447014"] = "Pandoc Installation"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::SERVICES::PANDOCAVAILABILITYSERVICE::T185447014"] = "Pandoc Installation"
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
using AIStudio.Chat;
|
using AIStudio.Chat;
|
||||||
using AIStudio.Dialogs;
|
using AIStudio.Dialogs;
|
||||||
using AIStudio.Tools.PluginSystem;
|
using AIStudio.Tools.PluginSystem;
|
||||||
|
using AIStudio.Tools.Rust;
|
||||||
using AIStudio.Tools.Services;
|
using AIStudio.Tools.Services;
|
||||||
|
|
||||||
using DialogOptions = AIStudio.Dialogs.DialogOptions;
|
using DialogOptions = AIStudio.Dialogs.DialogOptions;
|
||||||
@ -16,7 +17,7 @@ public static class PandocExport
|
|||||||
|
|
||||||
public static async Task<bool> ToMicrosoftWord(RustService rustService, IDialogService dialogService, string dialogTitle, IContent markdownContent)
|
public static async Task<bool> ToMicrosoftWord(RustService rustService, IDialogService dialogService, string dialogTitle, IContent markdownContent)
|
||||||
{
|
{
|
||||||
var response = await rustService.SaveFile(dialogTitle, new("Microsoft Word", ["docx"]));
|
var response = await rustService.SaveFile(dialogTitle, [FileTypes.MS_WORD]);
|
||||||
if (response.UserCancelled)
|
if (response.UserCancelled)
|
||||||
{
|
{
|
||||||
LOGGER.LogInformation("User cancelled the save dialog.");
|
LOGGER.LogInformation("User cancelled the save dialog.");
|
||||||
|
|||||||
@ -1,125 +1,49 @@
|
|||||||
// ReSharper disable NotAccessedPositionalProperty.Global
|
|
||||||
|
|
||||||
using AIStudio.Tools.PluginSystem;
|
|
||||||
|
|
||||||
namespace AIStudio.Tools.Rust;
|
namespace AIStudio.Tools.Rust;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a file type filter for file selection dialogs.
|
/// Represents a file type that can optionally contain child file types.
|
||||||
|
/// Use the static helpers <see cref="Leaf"/>, <see cref="Parent"/> and <see cref="Composite"/> to build readable trees.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="FilterName">The name of the filter.</param>
|
/// <param name="FilterName">Display name of the type (e.g., "Document").</param>
|
||||||
/// <param name="FilterExtensions">The file extensions associated with the filter.</param>
|
/// <param name="FilterExtensions">File extensions belonging to this type (without dot).</param>
|
||||||
public readonly record struct FileTypeFilter(string FilterName, string[] FilterExtensions)
|
/// <param name="Children">Nested file types that are included when this type is selected.</param>
|
||||||
|
public sealed record FileTypeFilter(string FilterName, string[] FilterExtensions, IReadOnlyList<FileTypeFilter> Children)
|
||||||
{
|
{
|
||||||
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(FileTypeFilter).Namespace, nameof(FileTypeFilter));
|
/// <summary>
|
||||||
|
/// Factory for a leaf node.
|
||||||
|
/// Example: <c>FileType.Leaf(".NET", "cs", "razor")</c>
|
||||||
|
/// </summary>
|
||||||
|
public static FileTypeFilter Leaf(string name, params string[] extensions) =>
|
||||||
|
new(name, extensions, []);
|
||||||
|
|
||||||
private static string[] AllowedSourceLikeFileNames =>
|
/// <summary>
|
||||||
[
|
/// Factory for a parent node that only has children.
|
||||||
"Dockerfile",
|
/// Example: <c>FileType.Parent("Source Code", dotnet, java)</c>
|
||||||
"Containerfile",
|
/// </summary>
|
||||||
"Jenkinsfile",
|
public static FileTypeFilter Parent(string name, params FileTypeFilter[]? children) =>
|
||||||
"Makefile",
|
new(name, [], children ?? []);
|
||||||
"GNUmakefile",
|
|
||||||
"Procfile",
|
|
||||||
"Vagrantfile",
|
|
||||||
"Tiltfile",
|
|
||||||
"Justfile",
|
|
||||||
"Brewfile",
|
|
||||||
"Caddyfile",
|
|
||||||
"Gemfile",
|
|
||||||
"Podfile",
|
|
||||||
"Fastfile",
|
|
||||||
"Appfile",
|
|
||||||
"Rakefile",
|
|
||||||
"Dangerfile",
|
|
||||||
"BUILD",
|
|
||||||
"WORKSPACE",
|
|
||||||
"BUCK",
|
|
||||||
];
|
|
||||||
|
|
||||||
private static string[] AllowedSourceLikeFileNamePrefixes =>
|
/// <summary>
|
||||||
[
|
/// Factory for a composite node that has its own extensions in addition to children.
|
||||||
"Dockerfile",
|
/// </summary>
|
||||||
"Containerfile",
|
public static FileTypeFilter Composite(string name, string[] extensions, params FileTypeFilter[] children) =>
|
||||||
"Jenkinsfile",
|
new(name, extensions, children);
|
||||||
"Procfile",
|
|
||||||
"Caddyfile",
|
|
||||||
];
|
|
||||||
|
|
||||||
public static bool IsAllowedSourceLikeFileName(string filePath)
|
/// <summary>
|
||||||
|
/// Collects all extensions for this type, including children.
|
||||||
|
/// </summary>
|
||||||
|
public IEnumerable<string> FlattenExtensions()
|
||||||
{
|
{
|
||||||
var fileName = Path.GetFileName(filePath);
|
return this.FilterExtensions
|
||||||
if (string.IsNullOrWhiteSpace(fileName))
|
.Concat(this.Children.SelectMany(child => child.FlattenExtensions()))
|
||||||
return false;
|
.Distinct(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
if (AllowedSourceLikeFileNames.Any(name => string.Equals(name, fileName, StringComparison.OrdinalIgnoreCase)))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return AllowedSourceLikeFileNamePrefixes.Any(prefix => fileName.StartsWith(prefix, StringComparison.OrdinalIgnoreCase));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FileTypeFilter PDF => new(TB("PDF Files"), ["pdf"]);
|
public bool ContainsType(FileTypeFilter target)
|
||||||
|
{
|
||||||
|
if (this == target)
|
||||||
|
return true;
|
||||||
|
|
||||||
public static FileTypeFilter Text => new(TB("Text Files"), ["txt", "md"]);
|
return this.Children.Any(child => child.ContainsType(target));
|
||||||
|
}
|
||||||
public static FileTypeFilter AllOffice => new(TB("All Office Files"), ["docx", "xlsx", "pptx", "doc", "xls", "ppt", "pdf"]);
|
|
||||||
|
|
||||||
public static FileTypeFilter AllImages => new(TB("All Image Files"), ["jpg", "jpeg", "png", "gif", "bmp", "tiff", "svg", "webp", "heic"]);
|
|
||||||
|
|
||||||
public static FileTypeFilter AllVideos => new(TB("All Video Files"), ["mp4", "m4v", "avi", "mkv", "mov", "wmv", "flv", "webm"]);
|
|
||||||
|
|
||||||
public static FileTypeFilter AllAudio => new(TB("All Audio Files"), ["mp3", "wav", "wave", "aac", "flac", "ogg", "m4a", "wma", "alac", "aiff", "m4b"]);
|
|
||||||
|
|
||||||
public static FileTypeFilter AllSourceCode => new(TB("All Source Code Files"),
|
|
||||||
[
|
|
||||||
// .NET
|
|
||||||
"cs", "vb", "fs", "razor", "aspx", "cshtml", "csproj",
|
|
||||||
|
|
||||||
// Java:
|
|
||||||
"java",
|
|
||||||
|
|
||||||
// Python:
|
|
||||||
"py",
|
|
||||||
|
|
||||||
// JavaScript/TypeScript:
|
|
||||||
"js", "ts",
|
|
||||||
|
|
||||||
// C/C++:
|
|
||||||
"c", "cpp", "h", "hpp",
|
|
||||||
|
|
||||||
// Ruby:
|
|
||||||
"rb",
|
|
||||||
|
|
||||||
// Go:
|
|
||||||
"go",
|
|
||||||
|
|
||||||
// Rust:
|
|
||||||
"rs",
|
|
||||||
|
|
||||||
// Lua:
|
|
||||||
"lua",
|
|
||||||
|
|
||||||
// PHP:
|
|
||||||
"php",
|
|
||||||
|
|
||||||
// HTML/CSS:
|
|
||||||
"html", "css",
|
|
||||||
|
|
||||||
// Swift/Kotlin:
|
|
||||||
"swift", "kt",
|
|
||||||
|
|
||||||
// Shell scripts:
|
|
||||||
"sh", "bash",
|
|
||||||
|
|
||||||
// Logging files:
|
|
||||||
"log",
|
|
||||||
|
|
||||||
// JSON/YAML/XML:
|
|
||||||
"json", "yaml", "yml", "xml",
|
|
||||||
|
|
||||||
// Config files:
|
|
||||||
"ini", "cfg", "toml", "plist",
|
|
||||||
]);
|
|
||||||
|
|
||||||
public static FileTypeFilter Executables => new(TB("Executable Files"), ["exe", "app", "bin", "appimage"]);
|
|
||||||
}
|
}
|
||||||
130
app/MindWork AI Studio/Tools/Rust/FileTypes.cs
Normal file
130
app/MindWork AI Studio/Tools/Rust/FileTypes.cs
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
using AIStudio.Tools.PluginSystem;
|
||||||
|
// ReSharper disable MemberCanBePrivate.Global
|
||||||
|
|
||||||
|
namespace AIStudio.Tools.Rust;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Central definition of supported file types with parent/child relationships and helpers
|
||||||
|
/// to build extension whitelists (e.g., for file pickers or validation).
|
||||||
|
/// </summary>
|
||||||
|
public static class FileTypes
|
||||||
|
{
|
||||||
|
private static string TB(string fallbackEn) => I18N.I.T(fallbackEn, typeof(FileTypeFilter).Namespace, nameof(FileTypeFilter));
|
||||||
|
|
||||||
|
public static readonly FileTypeFilter SOURCE_LIKE_FILE_NAMES = FileTypeFilter.Leaf(TB("Source like"),
|
||||||
|
"Dockerfile", "Containerfile", "Jenkinsfile", "Makefile", "GNUmakefile", "Procfile", "Vagrantfile",
|
||||||
|
"Tiltfile", "Justfile", "Brewfile", "Caddyfile", "Gemfile", "Podfile", "Fastfile", "Appfile", "Rakefile", "Dangerfile",
|
||||||
|
"BUILD", "WORKSPACE", "BUCK");
|
||||||
|
|
||||||
|
public static readonly FileTypeFilter SOURCE_LIKE_FILE_NAME_PREFIXES = FileTypeFilter.Leaf(TB("Source like prefix"),
|
||||||
|
"Dockerfile", "Containerfile", "Jenkinsfile", "Procfile", "Caddyfile");
|
||||||
|
|
||||||
|
// Source code hierarchy: SourceCode -> (.NET, Java, Python, Web, C/C++, Config, ...)
|
||||||
|
public static readonly FileTypeFilter DOTNET = FileTypeFilter.Leaf(".NET", "cs", "razor", "vb", "fs", "aspx", "cshtml", "csproj");
|
||||||
|
public static readonly FileTypeFilter JAVA = FileTypeFilter.Leaf("Java", "java");
|
||||||
|
public static readonly FileTypeFilter PYTHON = FileTypeFilter.Leaf("Python", "py");
|
||||||
|
public static readonly FileTypeFilter JAVASCRIPT = FileTypeFilter.Leaf("JavaScript/TypeScript", "js", "ts");
|
||||||
|
public static readonly FileTypeFilter CFAMILY = FileTypeFilter.Leaf("C/C++", "c", "cpp", "h", "hpp");
|
||||||
|
public static readonly FileTypeFilter RUBY = FileTypeFilter.Leaf("Ruby", "rb");
|
||||||
|
public static readonly FileTypeFilter GO = FileTypeFilter.Leaf("Go", "go");
|
||||||
|
public static readonly FileTypeFilter RUST = FileTypeFilter.Leaf("Rust", "rs");
|
||||||
|
public static readonly FileTypeFilter LUA = FileTypeFilter.Leaf("Lua", "lua");
|
||||||
|
public static readonly FileTypeFilter PHP = FileTypeFilter.Leaf("PHP", "php");
|
||||||
|
public static readonly FileTypeFilter WEB = FileTypeFilter.Leaf("HTML/CSS", "html", "css");
|
||||||
|
public static readonly FileTypeFilter APP = FileTypeFilter.Leaf("Swift/Kotlin", "swift", "kt");
|
||||||
|
public static readonly FileTypeFilter SHELL = FileTypeFilter.Leaf("Shell", "sh", "bash", "zsh");
|
||||||
|
public static readonly FileTypeFilter LOG = FileTypeFilter.Leaf("Log", "log");
|
||||||
|
public static readonly FileTypeFilter JSON = FileTypeFilter.Leaf("JSON", "json");
|
||||||
|
public static readonly FileTypeFilter XML = FileTypeFilter.Leaf("XML", "xml");
|
||||||
|
public static readonly FileTypeFilter YAML = FileTypeFilter.Leaf("YAML", "yaml", "yml");
|
||||||
|
public static readonly FileTypeFilter CONFIG = FileTypeFilter.Leaf(TB("Config"), "ini", "cfg", "toml", "plist");
|
||||||
|
|
||||||
|
public static readonly FileTypeFilter SOURCE_CODE = FileTypeFilter.Parent(TB("Source Code"),
|
||||||
|
DOTNET, JAVA, PYTHON, JAVASCRIPT, CFAMILY, RUBY, GO, RUST, LUA, PHP, WEB, APP, SHELL, LOG, JSON, XML, YAML, CONFIG, SOURCE_LIKE_FILE_NAMES, SOURCE_LIKE_FILE_NAME_PREFIXES);
|
||||||
|
|
||||||
|
// Document hierarchy
|
||||||
|
public static readonly FileTypeFilter PDF = FileTypeFilter.Leaf("PDF", "pdf");
|
||||||
|
public static readonly FileTypeFilter TEXT = FileTypeFilter.Leaf(TB("Text"), "txt", "md", "rtf");
|
||||||
|
public static readonly FileTypeFilter MS_WORD = FileTypeFilter.Leaf("Microsoft Word", "docx", "doc");
|
||||||
|
public static readonly FileTypeFilter WORD = FileTypeFilter.Composite("Word", ["odt"], MS_WORD);
|
||||||
|
public static readonly FileTypeFilter EXCEL = FileTypeFilter.Leaf("Excel", "xls", "xlsx");
|
||||||
|
public static readonly FileTypeFilter POWER_POINT = FileTypeFilter.Leaf("PowerPoint", "ppt", "pptx");
|
||||||
|
public static readonly FileTypeFilter MAIL = FileTypeFilter.Leaf(TB("Mail"), "eml", "msg", "mbox");
|
||||||
|
public static readonly FileTypeFilter LATEX = FileTypeFilter.Leaf("LaTeX", "tex", "bib", "sty", "cls", "log");
|
||||||
|
|
||||||
|
public static readonly FileTypeFilter OFFICE_FILES = FileTypeFilter.Parent(TB("Office Files"),
|
||||||
|
WORD, EXCEL, POWER_POINT, PDF);
|
||||||
|
public static readonly FileTypeFilter DOCUMENT = FileTypeFilter.Parent(TB("Document"),
|
||||||
|
TEXT, OFFICE_FILES, SOURCE_CODE, LATEX);
|
||||||
|
|
||||||
|
// Media hierarchy
|
||||||
|
public static readonly FileTypeFilter IMAGE = FileTypeFilter.Leaf(TB("Image"),
|
||||||
|
"jpg", "jpeg", "png", "gif", "bmp", "tiff", "svg", "webp", "heic");
|
||||||
|
public static readonly FileTypeFilter AUDIO = FileTypeFilter.Leaf(TB("Audio"),
|
||||||
|
"mp3", "wav", "wave", "aac", "flac", "ogg", "m4a", "wma", "alac", "aiff", "m4b");
|
||||||
|
public static readonly FileTypeFilter VIDEO = FileTypeFilter.Leaf(TB("Video"),
|
||||||
|
"mp4", "m4v", "avi", "mkv", "mov", "wmv", "flv", "webm");
|
||||||
|
|
||||||
|
public static readonly FileTypeFilter MEDIA = FileTypeFilter.Parent(TB("Media"), IMAGE, AUDIO, VIDEO);
|
||||||
|
|
||||||
|
// Other standalone types
|
||||||
|
public static readonly FileTypeFilter EXECUTABLES = FileTypeFilter.Leaf(TB("Executable"), "exe", "app", "bin", "appimage");
|
||||||
|
|
||||||
|
public static FileTypeFilter? AsOneFileType(params FileTypeFilter[]? types)
|
||||||
|
{
|
||||||
|
if (types == null || types.Length == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (types.Length == 1)
|
||||||
|
return types[0];
|
||||||
|
|
||||||
|
return FileTypeFilter.Composite(TB("Custom"), OnlyAllowTypes(types));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string[] OnlyAllowTypes(params FileTypeFilter[] types)
|
||||||
|
{
|
||||||
|
if (types.Length == 0)
|
||||||
|
return [];
|
||||||
|
|
||||||
|
return types
|
||||||
|
.Where(t => t != SOURCE_LIKE_FILE_NAMES && t != SOURCE_LIKE_FILE_NAME_PREFIXES)
|
||||||
|
.SelectMany(t => t.FlattenExtensions())
|
||||||
|
.Select(ext => ext.ToLowerInvariant())
|
||||||
|
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||||
|
.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validates a file path against the provided filters.
|
||||||
|
/// Supports extension-based matching and source-like file names (e.g. Dockerfile).
|
||||||
|
/// </summary>
|
||||||
|
public static bool IsAllowedPath(string filePath, params FileTypeFilter[]? types)
|
||||||
|
{
|
||||||
|
if (types == null || types.Length == 0 || string.IsNullOrWhiteSpace(filePath))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var extension = Path.GetExtension(filePath).TrimStart('.');
|
||||||
|
if (!string.IsNullOrWhiteSpace(extension))
|
||||||
|
{
|
||||||
|
if (OnlyAllowTypes(types).Contains(extension, StringComparer.OrdinalIgnoreCase))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var fileName = Path.GetFileName(filePath);
|
||||||
|
if (string.IsNullOrWhiteSpace(fileName))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (types.Any(t => t.ContainsType(SOURCE_LIKE_FILE_NAMES)))
|
||||||
|
{
|
||||||
|
if (SOURCE_LIKE_FILE_NAMES.FilterExtensions.Contains(fileName))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (types.Any(t => t.ContainsType(SOURCE_LIKE_FILE_NAME_PREFIXES))){
|
||||||
|
if (SOURCE_LIKE_FILE_NAME_PREFIXES.FilterExtensions.Any(prefix => fileName.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -17,13 +17,13 @@ public sealed partial class RustService
|
|||||||
return await result.Content.ReadFromJsonAsync<DirectorySelectionResponse>(this.jsonRustSerializerOptions);
|
return await result.Content.ReadFromJsonAsync<DirectorySelectionResponse>(this.jsonRustSerializerOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<FileSelectionResponse> SelectFile(string title, FileTypeFilter? filter = null, string? initialFile = null)
|
public async Task<FileSelectionResponse> SelectFile(string title, FileTypeFilter[]? filter = null, string? initialFile = null)
|
||||||
{
|
{
|
||||||
var payload = new SelectFileOptions
|
var payload = new SelectFileOptions
|
||||||
{
|
{
|
||||||
Title = title,
|
Title = title,
|
||||||
PreviousFile = initialFile is null ? null : new (initialFile),
|
PreviousFile = initialFile is null ? null : new (initialFile),
|
||||||
Filter = filter
|
Filter = FileTypes.AsOneFileType(filter)
|
||||||
};
|
};
|
||||||
|
|
||||||
var result = await this.http.PostAsJsonAsync("/select/file", payload, this.jsonRustSerializerOptions);
|
var result = await this.http.PostAsJsonAsync("/select/file", payload, this.jsonRustSerializerOptions);
|
||||||
@ -36,13 +36,13 @@ public sealed partial class RustService
|
|||||||
return await result.Content.ReadFromJsonAsync<FileSelectionResponse>(this.jsonRustSerializerOptions);
|
return await result.Content.ReadFromJsonAsync<FileSelectionResponse>(this.jsonRustSerializerOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<FilesSelectionResponse> SelectFiles(string title, FileTypeFilter? filter = null, string? initialFile = null)
|
public async Task<FilesSelectionResponse> SelectFiles(string title, FileTypeFilter[]? filter = null, string? initialFile = null)
|
||||||
{
|
{
|
||||||
var payload = new SelectFileOptions
|
var payload = new SelectFileOptions
|
||||||
{
|
{
|
||||||
Title = title,
|
Title = title,
|
||||||
PreviousFile = initialFile is null ? null : new (initialFile),
|
PreviousFile = initialFile is null ? null : new (initialFile),
|
||||||
Filter = filter
|
Filter = FileTypes.AsOneFileType(filter)
|
||||||
};
|
};
|
||||||
|
|
||||||
var result = await this.http.PostAsJsonAsync("/select/files", payload, this.jsonRustSerializerOptions);
|
var result = await this.http.PostAsJsonAsync("/select/files", payload, this.jsonRustSerializerOptions);
|
||||||
@ -59,17 +59,17 @@ public sealed partial class RustService
|
|||||||
/// Initiates a dialog to let the user select a file for a writing operation.
|
/// Initiates a dialog to let the user select a file for a writing operation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="title">The title of the save file dialog.</param>
|
/// <param name="title">The title of the save file dialog.</param>
|
||||||
/// <param name="filter">An optional file type filter for filtering specific file formats.</param>
|
/// <param name="filter">Optional file type filters for filtering specific file formats.</param>
|
||||||
/// <param name="initialFile">An optional initial file path to pre-fill in the dialog.</param>
|
/// <param name="initialFile">An optional initial file path to pre-fill in the dialog.</param>
|
||||||
/// <returns>A <see cref="FileSaveResponse"/> object containing information about whether the user canceled the
|
/// <returns>A <see cref="FileSaveResponse"/> object containing information about whether the user canceled the
|
||||||
/// operation and whether the select operation was successful.</returns>
|
/// operation and whether the select operation was successful.</returns>
|
||||||
public async Task<FileSaveResponse> SaveFile(string title, FileTypeFilter? filter = null, string? initialFile = null)
|
public async Task<FileSaveResponse> SaveFile(string title, FileTypeFilter[]? filter = null, string? initialFile = null)
|
||||||
{
|
{
|
||||||
var payload = new SaveFileOptions
|
var payload = new SaveFileOptions
|
||||||
{
|
{
|
||||||
Title = title,
|
Title = title,
|
||||||
PreviousFile = initialFile is null ? null : new (initialFile),
|
PreviousFile = initialFile is null ? null : new (initialFile),
|
||||||
Filter = filter
|
Filter = FileTypes.AsOneFileType(filter)
|
||||||
};
|
};
|
||||||
|
|
||||||
var result = await this.http.PostAsJsonAsync("/save/file", payload, this.jsonRustSerializerOptions);
|
var result = await this.http.PostAsJsonAsync("/save/file", payload, this.jsonRustSerializerOptions);
|
||||||
|
|||||||
@ -43,8 +43,7 @@ public static class FileExtensionValidation
|
|||||||
/// <returns>True if valid, false if invalid (error/warning already sent via MessageBus).</returns>
|
/// <returns>True if valid, false if invalid (error/warning already sent via MessageBus).</returns>
|
||||||
public static async Task<bool> IsExtensionValidWithNotifyAsync(UseCase useCae, string filePath, bool validateMediaFileTypes = true, Settings.Provider? provider = null)
|
public static async Task<bool> IsExtensionValidWithNotifyAsync(UseCase useCae, string filePath, bool validateMediaFileTypes = true, Settings.Provider? provider = null)
|
||||||
{
|
{
|
||||||
var ext = Path.GetExtension(filePath).TrimStart('.').ToLowerInvariant();
|
if (FileTypes.IsAllowedPath(filePath, FileTypes.EXECUTABLES))
|
||||||
if(FileTypeFilter.Executables.FilterExtensions.Contains(ext))
|
|
||||||
{
|
{
|
||||||
await MessageBus.INSTANCE.SendError(new(
|
await MessageBus.INSTANCE.SendError(new(
|
||||||
Icons.Material.Filled.AppBlocking,
|
Icons.Material.Filled.AppBlocking,
|
||||||
@ -53,7 +52,7 @@ public static class FileExtensionValidation
|
|||||||
}
|
}
|
||||||
|
|
||||||
var capabilities = provider?.GetModelCapabilities() ?? new();
|
var capabilities = provider?.GetModelCapabilities() ?? new();
|
||||||
if (FileTypeFilter.AllImages.FilterExtensions.Contains(ext))
|
if (FileTypes.IsAllowedPath(filePath, FileTypes.IMAGE))
|
||||||
{
|
{
|
||||||
switch (useCae)
|
switch (useCae)
|
||||||
{
|
{
|
||||||
@ -88,7 +87,7 @@ public static class FileExtensionValidation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(FileTypeFilter.AllVideos.FilterExtensions.Contains(ext))
|
if (FileTypes.IsAllowedPath(filePath, FileTypes.VIDEO))
|
||||||
{
|
{
|
||||||
await MessageBus.INSTANCE.SendWarning(new(
|
await MessageBus.INSTANCE.SendWarning(new(
|
||||||
Icons.Material.Filled.FeaturedVideo,
|
Icons.Material.Filled.FeaturedVideo,
|
||||||
@ -96,7 +95,7 @@ public static class FileExtensionValidation
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(FileTypeFilter.AllAudio.FilterExtensions.Contains(ext))
|
if (FileTypes.IsAllowedPath(filePath, FileTypes.AUDIO))
|
||||||
{
|
{
|
||||||
await MessageBus.INSTANCE.SendWarning(new(
|
await MessageBus.INSTANCE.SendWarning(new(
|
||||||
Icons.Material.Filled.AudioFile,
|
Icons.Material.Filled.AudioFile,
|
||||||
@ -123,7 +122,7 @@ public static class FileExtensionValidation
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Array.Exists(FileTypeFilter.AllImages.FilterExtensions, x => x.Equals(ext, StringComparison.OrdinalIgnoreCase)))
|
if (FileTypes.IsAllowedPath(filePath, FileTypes.IMAGE))
|
||||||
{
|
{
|
||||||
await MessageBus.INSTANCE.SendError(new(
|
await MessageBus.INSTANCE.SendError(new(
|
||||||
Icons.Material.Filled.ImageNotSupported,
|
Icons.Material.Filled.ImageNotSupported,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user