From 646023350e20f0432d8f092c1c8975fb5a7a26b3 Mon Sep 17 00:00:00 2001 From: Miguel Date: Thu, 18 Apr 2024 17:22:19 +0200 Subject: [PATCH] Add project files. --- App.xaml | 13 ++ App.xaml.cs | 14 ++ AssemblyInfo.cs | 10 ++ GTPAsk.csproj | 18 +++ GTPAsk.sln | 25 ++++ MainWindow.xaml | 44 ++++++ MainWindow.xaml.cs | 356 +++++++++++++++++++++++++++++++++++++++++++++ instrucciones.csv | 58 ++++++++ 8 files changed, 538 insertions(+) create mode 100644 App.xaml create mode 100644 App.xaml.cs create mode 100644 AssemblyInfo.cs create mode 100644 GTPAsk.csproj create mode 100644 GTPAsk.sln create mode 100644 MainWindow.xaml create mode 100644 MainWindow.xaml.cs create mode 100644 instrucciones.csv diff --git a/App.xaml b/App.xaml new file mode 100644 index 0000000..750a4c6 --- /dev/null +++ b/App.xaml @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/App.xaml.cs b/App.xaml.cs new file mode 100644 index 0000000..b325e1c --- /dev/null +++ b/App.xaml.cs @@ -0,0 +1,14 @@ +using System.Configuration; +using System.Data; +using System.Windows; + +namespace GTPAsk +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + } + +} diff --git a/AssemblyInfo.cs b/AssemblyInfo.cs new file mode 100644 index 0000000..b0ec827 --- /dev/null +++ b/AssemblyInfo.cs @@ -0,0 +1,10 @@ +using System.Windows; + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] diff --git a/GTPAsk.csproj b/GTPAsk.csproj new file mode 100644 index 0000000..bb40f66 --- /dev/null +++ b/GTPAsk.csproj @@ -0,0 +1,18 @@ + + + + WinExe + net8.0-windows + enable + enable + true + + + + + + + + + + diff --git a/GTPAsk.sln b/GTPAsk.sln new file mode 100644 index 0000000..0b638cc --- /dev/null +++ b/GTPAsk.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34330.188 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GTPAsk", "GTPAsk.csproj", "{6342C8D0-40D6-4DAF-A0E4-8EFA577F435F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6342C8D0-40D6-4DAF-A0E4-8EFA577F435F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6342C8D0-40D6-4DAF-A0E4-8EFA577F435F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6342C8D0-40D6-4DAF-A0E4-8EFA577F435F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6342C8D0-40D6-4DAF-A0E4-8EFA577F435F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0BC503E4-ABF3-4126-8CFF-5FEDFA7D2BEE} + EndGlobalSection +EndGlobal diff --git a/MainWindow.xaml b/MainWindow.xaml new file mode 100644 index 0000000..0cbc0cf --- /dev/null +++ b/MainWindow.xaml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs new file mode 100644 index 0000000..08a65e0 --- /dev/null +++ b/MainWindow.xaml.cs @@ -0,0 +1,356 @@ +using System.Net.Http; +using System.Text; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using System; +using System.Threading.Tasks; +using Newtonsoft.Json; +using System.IO; +using LanguageDetection; +using ToastNotifications; +using ToastNotifications.Lifetime; +using ToastNotifications.Messages; +using ToastNotifications.Position; +using System.Windows.Threading; +using System; +using System.Runtime.InteropServices; +using System; + + + +namespace GTPAsk +{ + public partial class MainWindow // Asumiendo que estás dentro de una clase de WPF + { + private readonly string openAiApiKey = "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"; + private readonly string instruccionesCSV = @"D:\Proyectos\VisualStudio\GTPAsk\instrucciones.csv"; + private Notifier _notifier; + + + private Dictionary languageMap = new Dictionary + { + { "en", "Inglés" }, + { "es", "Español" }, + { "it", "Italiano" }, + { "pt", "Portugués" } + // Agrega más idiomas según sea necesario + }; + + + + [StructLayout(LayoutKind.Sequential)] + internal struct INPUT + { + public uint type; + public InputUnion U; + public static int Size => Marshal.SizeOf(typeof(INPUT)); + } + + [StructLayout(LayoutKind.Explicit)] + internal struct InputUnion + { + [FieldOffset(0)] public MOUSEINPUT mi; + [FieldOffset(0)] public KEYBDINPUT ki; + [FieldOffset(0)] public HARDWAREINPUT hi; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct MOUSEINPUT + { + public int dx; + public int dy; + public uint mouseData; + public uint dwFlags; + public uint time; + public IntPtr dwExtraInfo; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct KEYBDINPUT + { + public ushort wVk; + public ushort wScan; + public uint dwFlags; + public uint time; + public IntPtr dwExtraInfo; + } + + [StructLayout(LayoutKind.Sequential)] + internal struct HARDWAREINPUT + { + public uint uMsg; + public ushort wParamL; + public ushort wParamH; + } + + [DllImport("user32.dll", SetLastError = true)] + private static extern uint SendInput(uint nInputs, [MarshalAs(UnmanagedType.LPArray), In] INPUT[] pInputs, int cbSize); + + [DllImport("user32.dll")] + private static extern IntPtr GetMessageExtraInfo(); + + // VK and KEYEVENTF Constants + const uint INPUT_KEYBOARD = 1; + const ushort VK_TAB = 0x09; + const ushort VK_MENU = 0x12; // ALT key + const uint KEYEVENTF_KEYDOWN = 0x0000; + const uint KEYEVENTF_KEYUP = 0x0002; + + static void VolverAUltimaAplicaicon() + { + // Simulate ALT key down + SendKeyboardInput(VK_MENU, KEYEVENTF_KEYDOWN); + // Simulate TAB key down and up + SendKeyboardInput(VK_TAB, KEYEVENTF_KEYDOWN); + SendKeyboardInput(VK_TAB, KEYEVENTF_KEYUP); + // Simulate ALT key up + SendKeyboardInput(VK_MENU, KEYEVENTF_KEYUP); + } + + private static void SendKeyboardInput(ushort key, uint flag) + { + INPUT[] inputs = new INPUT[] + { + new INPUT + { + type = INPUT_KEYBOARD, + U = new InputUnion + { + ki = new KEYBDINPUT + { + wVk = key, + wScan = 0, + dwFlags = flag, + time = 0, + dwExtraInfo = GetMessageExtraInfo(), + } + } + } + }; + + SendInput((uint)inputs.Length, inputs, INPUT.Size); + } + + private void NotifyUserWithCursor() + { + // Establecer el cursor personalizado + var customCursor = new Cursor(Application.GetResourceStream(new Uri("/;component/Resource/Images/BusyCursor.cur", UriKind.RelativeOrAbsolute)).Stream); + Mouse.OverrideCursor = customCursor; + + // Crear un temporizador para revertir el cursor después de 3 segundos + var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(3) }; + timer.Tick += (sender, args) => + { + // Revertir al cursor predeterminado + Mouse.OverrideCursor = Cursors.Arrow; + timer.Stop(); + }; + timer.Start(); + } + + private string DetectarIdioma(string TextoACorregir) + { + LanguageDetector detector = new LanguageDetector(); + detector.AddLanguages("en", "es", "it", "pt"); + string detectedLanguageCode = detector.Detect(TextoACorregir); + + string detectedLanguageName = languageMap.ContainsKey(detectedLanguageCode) + ? languageMap[detectedLanguageCode] + : "Desconocido"; + + return detectedLanguageName; + } + + private void LoadClipboardContent() + { + if (Clipboard.ContainsText()) + { + string idioma; + TextoDesdePortapapeles.Text = Clipboard.GetText(); + + idioma = DetectarIdioma(TextoDesdePortapapeles.Text); + statusTextBox.Text = "Idioma: " + idioma; + _notifier.ShowInformation("Idioma detectado: " + idioma); + + // Verificar si la tecla Control está presionada +// if (!Keyboard.IsKeyDown(Key.LeftCtrl) && !Keyboard.IsKeyDown(Key.RightCtrl)) +// { + CorregirTexto(); +// } + + } + } + + private async void CorregirTexto() + { + statusTextBox.Text = "Llamando a la API de OpenAI..."; + var TextoACorregir = TextoDesdePortapapeles.Text; + var Instrucciones = TB_Instrucciones.Text; + var idioma = DetectarIdioma(TextoACorregir); + + // Verificar si el texto de modifiableTextBox no está en defaultTextComboBox + if (!CB_ListaInstrucciones.Items.Contains(Instrucciones)) + { + CB_ListaInstrucciones.Items.Add(Instrucciones); + } + + if (idioma == "Desconocido") + { + _notifier.ShowError("No se puede detectar el idioma del texto."); + statusTextBox.Text = "No se puede detectar el idioma del texto."; + return; + } + + TextoACorregir = "El resultado debe estar en " + DetectarIdioma(TextoACorregir) + ". " + Instrucciones + "\"" + TextoACorregir + "\""; + + VolverAUltimaAplicaicon(); // Hacer ALT-TAB + + var Respuesta = await CallOpenAiApi(TextoACorregir); + + // Elimina comillas al principio y al final si existen + Respuesta = Respuesta.Trim('\"'); + + resultTextBox.Text = Respuesta; + Clipboard.SetText(Respuesta); + + // Mostrar notificación + _notifier.ShowInformation("La respuesta está lista."); + + statusTextBox.Text = "Respuesta recibida."; + NotifyUserWithCursor(); + + // Configurar y comenzar el temporizador para cerrar la aplicación + DispatcherTimer closeTimer = new DispatcherTimer + { + Interval = TimeSpan.FromSeconds(10) // Establece el intervalo a 5 segundos + }; + closeTimer.Tick += CloseTimer_Tick; // Suscribirse al evento Tick + closeTimer.Start(); + + } + + private async void ExecuteButton_Click(object sender, RoutedEventArgs e) + { + CorregirTexto(); + } + + + private async Task CallOpenAiApi(string input) + { + var httpClient = new HttpClient(); + httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {openAiApiKey}"); + + var requestData = new + { + model = "gpt-4", + messages = new[] + { + new { role = "system", content = "Este es un mensaje del sistema inicializando la conversación" }, + new { role = "user", content = input } + } + }; + + var content = new StringContent(JsonConvert.SerializeObject(requestData), Encoding.UTF8, "application/json"); + var response = await httpClient.PostAsync("https://api.openai.com/v1/chat/completions", content); + + response.EnsureSuccessStatusCode(); + var jsonResponse = await response.Content.ReadAsStringAsync(); + dynamic data = JsonConvert.DeserializeObject(jsonResponse); + return data.choices[0].message.content; + } + + private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (CB_ListaInstrucciones.SelectedItem != null) + { + var selectedItem = CB_ListaInstrucciones.SelectedItem.ToString(); + + // Actualizar modifiableTextBox + TB_Instrucciones.Text = selectedItem; + } + } + private void LoadComboBoxItems() + { + try + { + var lines = File.ReadAllLines(instruccionesCSV); + foreach (var line in lines) + { + CB_ListaInstrucciones.Items.Add(line); + } + if (CB_ListaInstrucciones.Items.Count > 0) + { + CB_ListaInstrucciones.SelectedIndex = CB_ListaInstrucciones.Items.Count - 1; + } + } + catch (FileNotFoundException) + { + CB_ListaInstrucciones.Items.Add("Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: "); + CB_ListaInstrucciones.SelectedIndex = 0; + } + } + + protected override void OnClosed(EventArgs e) + { + statusTextBox.Text = "Guardando cambios..."; + _notifier.Dispose(); + base.OnClosed(e); + SaveComboBoxItems(); + } + + private void SaveComboBoxItems() + { + var lines = new List(); + foreach (var item in CB_ListaInstrucciones.Items) + { + lines.Add(item.ToString()); + } + File.WriteAllLines(instruccionesCSV, lines); + } + + private void MainWindow_Loaded(object sender, RoutedEventArgs e) + { + + _notifier = new Notifier(cfg => + { + cfg.PositionProvider = new PrimaryScreenPositionProvider( + corner: Corner.BottomRight, // Puedes cambiar esto a la esquina que prefieras + offsetX: 10, + offsetY: 10); + + cfg.LifetimeSupervisor = new TimeAndCountBasedLifetimeSupervisor( + notificationLifetime: TimeSpan.FromSeconds(3), + maximumNotificationCount: MaximumNotificationCount.FromCount(5)); + + cfg.Dispatcher = Application.Current.Dispatcher; + }); + + + LoadClipboardContent(); + LoadComboBoxItems(); + } + + private void CloseTimer_Tick(object sender, EventArgs e) + { + DispatcherTimer timer = (DispatcherTimer)sender; + timer.Stop(); // Detener el temporizador + timer.Tick -= CloseTimer_Tick; // Desuscribirse del evento + + this.Close(); // Cerrar la ventana actual + } + + public MainWindow() + { + InitializeComponent(); + this.Loaded += MainWindow_Loaded; + + } + } +} diff --git a/instrucciones.csv b/instrucciones.csv new file mode 100644 index 0000000..0164c1f --- /dev/null +++ b/instrucciones.csv @@ -0,0 +1,58 @@ +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +Texto por defecto +Texto por defecto +Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: +