diff --git a/App.xaml b/App.xaml index dd3d3a5..c6f9ce0 100644 --- a/App.xaml +++ b/App.xaml @@ -3,6 +3,6 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:GTPCorrgir"> - - + + diff --git a/App.xaml.cs b/App.xaml.cs index 4c0915a..3839a81 100644 --- a/App.xaml.cs +++ b/App.xaml.cs @@ -18,14 +18,16 @@ namespace GTPCorrgir gtpask GTP = new gtpask(); NotifyIcon notificacion; System.Windows.Forms.Timer timer; - int segundos = 0; bool CorreccionFinalizada = false; Stopwatch stopwatch = new Stopwatch(); + private notificacion notificationWindow; + protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); + stopwatch.Start(); if (System.Windows.Clipboard.ContainsText()) @@ -34,7 +36,7 @@ namespace GTPCorrgir } // Muestra notificación inicial y comienza el cronómetro en el hilo de la UI - MostrarNotificacion("Espera", "Corrigiendo texto..."); + ShowCustomNotification("Espera", "Corrigiendo texto..."); IniciarCronometro(); // Ejecuta la tarea de corrección en un hilo secundario @@ -59,7 +61,8 @@ namespace GTPCorrgir if (GTP.TextoCorregido != null) { System.Windows.Clipboard.SetText(GTP.TextoCorregido); - MostrarNotificacion("Corrección Lista", GTP.TextoCorregido); + ShowCustomNotification("Se puede pegar", $" Correccion en : {Math.Round(stopwatch.ElapsedMilliseconds / 1000.0, 1)} s" ); + Thread.Sleep(5000); // Espera 5 segundos } else { @@ -71,6 +74,17 @@ namespace GTPCorrgir }); } + private void ShowCustomNotification(string title, string message) + { + if (notificationWindow == null) + { + notificationWindow = new notificacion(); + notificationWindow.Show(); + } + + notificationWindow.UpdateNotification(title, message); + } + private void MostrarNotificacion(string titulo, string mensaje) { notificacion = new NotifyIcon @@ -83,10 +97,11 @@ namespace GTPCorrgir notificacion.ShowBalloonTip(1000); } + private void IniciarCronometro() { timer = new System.Windows.Forms.Timer(); - timer.Interval = 1000; // 1000 milisegundos (1 segundo) + timer.Interval = 100; // 1000 milisegundos (1 segundo) timer.Tick += ActualizarCronometro; timer.Start(); } @@ -94,9 +109,9 @@ namespace GTPCorrgir private void ActualizarCronometro(object sender, EventArgs e) { if (!CorreccionFinalizada) { - segundos++; - notificacion.BalloonTipText = $"Texto en {GTP.IdiomaDetectado} pasados: {Math.Round(stopwatch.ElapsedMilliseconds/1000.0,1)} s"; - notificacion.ShowBalloonTip(1000); + //notificacion.BalloonTipText = $"Texto en {GTP.IdiomaDetectado} pasados: {Math.Round(stopwatch.ElapsedMilliseconds/1000.0,1)} s"; + //notificacion.ShowBalloonTip(1000); + ShowCustomNotification("Trabajando..", $"Texto en {GTP.IdiomaDetectado} pasados: {Math.Round(stopwatch.ElapsedMilliseconds / 1000.0, 1)} s"); } } diff --git a/Obsidean.cs b/Obsidean.cs new file mode 100644 index 0000000..5c9fafe --- /dev/null +++ b/Obsidean.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.IO; +using Newtonsoft.Json.Linq; +using System.Text.RegularExpressions; + + +namespace GTPCorrgir +{ + internal class Obsidean + { + static HashSet technicalTerms; + + static string GetObsidianConfigPath() + { + string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); + return Path.Combine(appDataPath, "obsidian", "obsidian.json"); + } + + static string GetVaultPath(string vaultName) + { + try + { + string pathToJsonFile = GetObsidianConfigPath(); + string jsonContent = File.ReadAllText(pathToJsonFile); + JObject jsonObject = JObject.Parse(jsonContent); + JObject vaults = (JObject)jsonObject["vaults"]; + + foreach (var vault in vaults) + { + // 'vault' es un KeyValuePair + // 'vault.Key' es la clave (ID del vault), 'vault.Value' es el valor (detalles del vault como JToken) + string path = (string)vault.Value["path"]; + if (!string.IsNullOrEmpty(path)) + { + // Añadir una barra al final asegura que Path.GetDirectoryName funcione correctamente + string lastDirectoryName = Path.GetFileName(Path.GetDirectoryName(path.TrimEnd('\\') + "\\")); + + if (lastDirectoryName.Equals(vaultName, StringComparison.OrdinalIgnoreCase)) + { + return path; + } + } + } + } + catch (Exception ex) + { + Console.WriteLine("Error al leer o parsear el archivo JSON: " + ex.Message); + } + return null; + } + + public void LeerPalabrasTecnicas() + { + // "C:\Users\migue\OneDrive\Miguel\Obsidean\Trabajo\VM\Palabras Tecnicas\Lista.md" + string pathToMarkdown = GetVaultPath("VM"); + if (!string.IsNullOrEmpty(pathToMarkdown)) + { + string pathToLista = pathToMarkdown + "\\Palabras Tecnicas\\Lista.md"; + string[] lines = File.ReadAllLines(pathToLista); + technicalTerms = ExtractTechnicalTerms(lines); + } + + // Ahora puedes usar technicalTerms para tu lógica de corrección + } + + public HashSet ExtractTechnicalTerms(string[] lines) + { + var terms = new HashSet(); + foreach (var line in lines) + { + // Suponiendo que cada línea contiene un término técnico + terms.Add(line.Trim()); + } + return terms; + } + + public string MarkTechnicalTerms(string text) + { + // Utilizar Regex para identificar palabras individualmente + return Regex.Replace(text, @"\b(\w+)\b", match => + { + string word = match.Groups[1].Value; + // Verificar si la palabra está en el conjunto de términos técnicos + if (technicalTerms.Contains(word)) + { + return $"[[{word}]]"; // Encerrar la palabra en corchetes si es técnica + } + return word; // Devolver la palabra sin modificar si no es técnica + }); + } + } + +} diff --git a/Ollama/Modelfile b/Ollama/Modelfile new file mode 100644 index 0000000..d400c33 --- /dev/null +++ b/Ollama/Modelfile @@ -0,0 +1,6 @@ +FROM llama3 + +# set the system message +SYSTEM """ +You are an engineer who works in industrial automation. You correct the texts in a simple and concise way when asked without explanations. Respond in the language that was told please. Response in json format. +""" \ No newline at end of file diff --git a/gtpask.cs b/gtpask.cs index 0075853..8e2e3db 100644 --- a/gtpask.cs +++ b/gtpask.cs @@ -7,29 +7,44 @@ using System.Threading.Tasks; using System.Windows.Threading; using LanguageDetection; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace GTPCorrgir { internal class gtpask { private readonly string openAiApiKey = "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"; - private readonly string accionGTP = "Me puedes corregir el siguiente texto y mejorarlo para que se comprenda mejor: "; private Dictionary languageMap = new Dictionary { - { "en", "Inglés" }, - { "es", "Español" }, - { "it", "Italiano" }, - { "pt", "Portugués" } + { "en", "English" }, + { "es", "Spanish" }, + { "it", "Italian" }, + { "pt", "Portuguese" } // Agrega más idiomas según sea necesario }; + public string IdiomaDetectado; public string TextoACorregir; public string TextoCorregido; + public string TextodeSistema; + + + private string CrearMensajeDeSistema() + { + return "You are an engineer working in industrial automation. Your task is to review texts and rewrite them in a simple and concise manner, making sure to preserve important technical terms specially if they are in English. Please rewrite the following text in " + IdiomaDetectado + " and respond in the following JSON format: { 'Rewritten_text': 'Your text here' }."; + } + + private string CrearMensajeDeUsuario(string texto) + { + return "Please rewrite and improve the following text to make it clearer and more concise the words inside brackets are technical words: \"" + texto + "\""; + } + private string DetectarIdioma(string TextoACorregir) { LanguageDetector detector = new LanguageDetector(); - detector.AddLanguages("en", "es", "it", "pt"); + + detector.AddLanguages("en", "es", "it"); string detectedLanguageCode = detector.Detect(TextoACorregir); string detectedLanguageName = languageMap.ContainsKey(detectedLanguageCode) @@ -51,8 +66,7 @@ namespace GTPCorrgir } public async Task CorregirTexto() - { - var Instrucciones = accionGTP; + { if (DetectarIdioma()) { if (IdiomaDetectado == "Desconocido" || this.TextoACorregir.Length == 0) @@ -62,18 +76,55 @@ namespace GTPCorrgir return; } - TextoACorregir = "El resultado debe estar en " + IdiomaDetectado + ". " + Instrucciones + "\"" + TextoACorregir + "\""; + var md = new Obsidean(); + md.LeerPalabrasTecnicas(); - TextoCorregido = await CallOpenAiApi(TextoACorregir); - //TextoCorregido = await CallOllamaApi(TextoACorregir); + TextoACorregir = md.MarkTechnicalTerms(TextoACorregir); + + //TextoCorregido = await CallOpenAiApi(TextoACorregir); + string RespuestaLLM = await CallOllamaApi(TextoACorregir); + + TextoCorregido = ExtractCorrectedText(RespuestaLLM); // Elimina comillas al principio y al final si existen TextoCorregido = TextoCorregido.Trim('\"'); } } + + static string ExtractCorrectedText(string input) + { + try + { + // Encuentra el índice del inicio y del final del JSON + int startJson = input.IndexOf('{'); + int endJson = input.IndexOf('}') + 1; + + if (startJson == -1 || endJson == -1 || endJson <= startJson) + { + throw new Exception("No valid JSON found in the input string."); + } + + // Extrae solo la parte JSON de la entrada + string jsonString = input.Substring(startJson, endJson - startJson); + + // Parsea el JSON y extrae el campo "Rewritten_text" + JObject jsonObject = JObject.Parse(jsonString); + string rewrittenText = (string)jsonObject["Rewritten_text"]; + return rewrittenText; + } + catch (Exception ex) + { + Console.WriteLine("An error occurred: " + ex.Message); + return null; + } + } + private async Task CallOllamaApi(string input) { var httpClient = new HttpClient(); + string Mensaje_Sistema = CrearMensajeDeSistema(); + string Mensaje_Usuario = CrearMensajeDeUsuario(input); + httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {openAiApiKey}"); var requestData = new @@ -81,7 +132,8 @@ namespace GTPCorrgir model = "llama3", messages = new[] { - new { role = "user", content = input }, + new { role = "system", content = Mensaje_Sistema }, + new { role = "user", content = Mensaje_Usuario } }, stream = false }; @@ -114,9 +166,13 @@ namespace GTPCorrgir } } + private async Task CallOpenAiApi(string input) { var httpClient = new HttpClient(); + string Mensaje_Sistema = CrearMensajeDeSistema(); + string Mensaje_Usuario = CrearMensajeDeUsuario(input); + httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {openAiApiKey}"); var requestData = new @@ -124,8 +180,8 @@ namespace GTPCorrgir model = "gpt-4", messages = new[] { - new { role = "system", content = "Este es un mensaje del sistema inicializando la conversación" }, - new { role = "user", content = input } + new { role = "system", content = Mensaje_Sistema }, + new { role = "user", content = Mensaje_Usuario } } }; diff --git a/notificacion.xaml b/notificacion.xaml new file mode 100644 index 0000000..93b8ae2 --- /dev/null +++ b/notificacion.xaml @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/notificacion.xaml.cs b/notificacion.xaml.cs new file mode 100644 index 0000000..cb6680c --- /dev/null +++ b/notificacion.xaml.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +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.Shapes; + +namespace GTPCorrgir +{ + /// + /// Interaction logic for notificacion.xaml + /// + public partial class notificacion : Window + { + public notificacion() + { + InitializeComponent(); + PositionWindow(); + } + private void PositionWindow() + { + // Obtener la posición del cursor + var cursorPosition = System.Windows.Forms.Cursor.Position; + + // Determinar en qué pantalla está el cursor + var screen = Screen.FromPoint(cursorPosition); + + // Configurar la ubicación de la ventana para que aparezca en la esquina inferior derecha + this.Left = screen.WorkingArea.Right - this.Width; + this.Top = screen.WorkingArea.Bottom - this.Height; + } + public void UpdateNotification(string title, string message) + { + TitleText.Text = title; + MessageText.Text = message; + } + } +}