diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..f57aeb4 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/Core/src/main/java/me/zacharias/chat/core/Core.java b/Core/src/main/java/me/zacharias/chat/core/Core.java index 769a02d..33a3f99 100644 --- a/Core/src/main/java/me/zacharias/chat/core/Core.java +++ b/Core/src/main/java/me/zacharias/chat/core/Core.java @@ -1,8 +1,6 @@ package me.zacharias.chat.core; -import me.zacharias.chat.core.memory.AddMemoryFunction; -import me.zacharias.chat.core.memory.GetMemoryFunction; -import me.zacharias.chat.core.memory.RemoveMemoryFunction; +import me.zacharias.chat.core.memory.*; import me.zacharias.chat.ollama.*; import me.zacharias.chat.ollama.exceptions.OllamaToolErrorException; import me.zacharias.chat.plugin.Plugin; @@ -14,6 +12,7 @@ import org.json.JSONObject; import java.io.*; import java.net.*; +import java.nio.charset.StandardCharsets; import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.time.LocalDateTime; @@ -53,7 +52,7 @@ public class Core { /** * The IP of the Ollama API. */ - private String ollamaIP = "localhost";//"192.168.5.184"; + private String ollamaIP = "192.168.5.178";//"192.168.5.184"; /** * The port of the Ollama API. */ @@ -79,7 +78,7 @@ public class Core { static { String data; - if(System.getenv("AI-CHAT-DEBUG") != null) { + if(System.getenv("AI_CHAT_DEBUG") != null) { data = "./data"; } else if(System.getProperty("os.name").toLowerCase().contains("windows")) { @@ -169,8 +168,14 @@ public class Core { Runtime.getRuntime().addShutdownHook(new Thread(() -> { scheduler.shutdownNow(); try { - logWriter.flush(); - logWriter.close(); + try { + logWriter.flush(); + logWriter.close(); + }catch (IOException ignore) + { + // This exception is kinda expected. Since it can often occur that the logWriter is already closed + System.out.println("Failed to flush log file, but that is not a problem."); + } LocalDateTime now = LocalDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd_HH-mm-ss"); @@ -227,6 +232,8 @@ public class Core { addTool(new AddMemoryFunction(), Source.CORE); addTool(new RemoveMemoryFunction(), Source.CORE); addTool(new GetMemoryFunction(), Source.CORE); + addTool(new GetMemoriesFunction(), Source.CORE); + addTool(new GetMemoryIdentitiesFunction(), Source.CORE); } else { throw new IllegalArgumentException("Ollama object is already set"); @@ -323,8 +330,10 @@ public class Core { String ollamaObjectString = ollamaObject.toString(); + ollamaObjectString = ollamaObjectString.replace("\n", "\\n"); + try(DataOutputStream wr = new DataOutputStream(connection.getOutputStream())) { - wr.writeBytes(ollamaObjectString); + wr.write(ollamaObjectString.getBytes(StandardCharsets.UTF_8)); wr.flush(); } @@ -341,6 +350,17 @@ public class Core { while ((line = reader.readLine()) != null) { response.append(line); // Adds every line to response till the end of file. } + }catch (Exception ex) + { + // If the server returns an error, we read the error stream instead + try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()))) { + String line; + while ((line = reader.readLine()) != null) { + response.append(line); + } + } catch (Exception e) { + System.err.println("Error reading error stream: " + e.getMessage()); + } } if (responseCode == HttpURLConnection.HTTP_OK) { @@ -382,7 +402,7 @@ public class Core { if(jsonObject.has("function")) { JSONObject function = jsonObject.getJSONObject("function"); - List> functions = funtionTools.stream().filter(func -> func.getKey().name().equalsIgnoreCase(function.getString("name"))).toList(); + List> functions = funtionTools.stream().filter(func -> (func.getKey().name()+func.getValue()).equalsIgnoreCase(function.getString("name"))).toList(); if(functions.isEmpty()) { ollamaObject.addMessage(new OllamaToolError("Function '"+function.getString("name")+"' does not exist")); @@ -404,7 +424,7 @@ public class Core { try { OllamaToolRespnce function1 = func.function(argumentArrayList.toArray(new OllamaFunctionArgument[0])); ollamaObject.addMessage(function1); - printMessageHandler.printMessage((supportColor?"\u001b[34m":"")+"Call "+func.name() + (printMessageHandler.color()?"\u001b[0m":"")); + printMessageHandler.printMessage((supportColor?"\u001b[34m":"")+"Call "+func.name() + (supportColor?"\u001b[0m":"")); writeLog("Successfully function call " + func.name() + " output: " + function1.getResponse()); } catch (OllamaToolErrorException e) { ollamaObject.addMessage(new OllamaToolError(e.getMessage())); @@ -427,11 +447,12 @@ public class Core { * @param responce the Ollama response */ private void checkIfResponceMessage(JSONObject responce) { - if(responce.getJSONObject("message").has("content") && !responce.getJSONObject("message").getString("content").isBlank()) + String message = responce.getJSONObject("message").getString("content"); + if(responce.getJSONObject("message").has("content") && !message.isBlank()) { - printMessageHandler.printMessage((supportColor?"\u001b[32m":"")+responce.getJSONObject("message").getString("content")+(supportColor?"\u001b[0m":"")); - writeLog("Response content: "+responce.getJSONObject("message").getString("content")); - ollamaObject.addMessage(new OllamaMessage(OllamaMessageRole.ASSISTANT, responce.getJSONObject("message").getString("content"))); + printMessageHandler.printMessage((supportColor?"\u001b[32m":"")+(LaunchOptions.getInstance().isShowFullMessage()? message : message.replaceAll("(?s).*?", "")) +(supportColor?"\u001b[0m":"")); + writeLog("Response content: "+ message); + ollamaObject.addMessage(new OllamaMessage(OllamaMessageRole.ASSISTANT, message)); } } @@ -468,8 +489,8 @@ public class Core { { throw new PluginLoadingException("Plugin does not contain a plugin.json file", file.getName()); } - JSONObject pluginJson = new JSONObject(new String(fs.getPath("/plugin.json").toFile().readAllBytes())); - Plugin plugin = loader.loadPlugin(pluginJson, fs); + //JSONObject pluginJson = new JSONObject(new String(fs.getPath("/plugin.json").toFile().readAllBytes())); + //Plugin plugin = loader.loadPlugin(pluginJson, fs); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/Core/src/main/java/me/zacharias/chat/core/LaunchOptions.java b/Core/src/main/java/me/zacharias/chat/core/LaunchOptions.java index 2f20d1d..61d59ed 100644 --- a/Core/src/main/java/me/zacharias/chat/core/LaunchOptions.java +++ b/Core/src/main/java/me/zacharias/chat/core/LaunchOptions.java @@ -20,6 +20,7 @@ public class LaunchOptions { private boolean serverMode; private boolean serverCredentialsEnabled; private boolean notDisplay = true; + private boolean showFullMessage = false; private int port = 39075; private String redirectOutput; private String serverCredentials; @@ -160,4 +161,20 @@ public class LaunchOptions { public void setNotDisplay(boolean notDisplay) { this.notDisplay = notDisplay; } + + /** + * Gets if the full message should be shown in the display. + * @return a boolean indicating if the full message should be shown. + */ + public boolean isShowFullMessage() { + return showFullMessage; + } + + /** + * Sets if the full message should be shown in the display. + * @param showFullMessage a boolean indicating if the full message should be shown. + */ + public void setShowFullMessage(boolean showFullMessage) { + this.showFullMessage = showFullMessage; + } } diff --git a/Core/src/main/java/me/zacharias/chat/core/files/FileHandler.java b/Core/src/main/java/me/zacharias/chat/core/files/FileHandler.java index 814566f..54deed2 100644 --- a/Core/src/main/java/me/zacharias/chat/core/files/FileHandler.java +++ b/Core/src/main/java/me/zacharias/chat/core/files/FileHandler.java @@ -4,6 +4,8 @@ import me.zacharias.chat.core.Core; import org.intellij.lang.annotations.MagicConstant; import java.io.*; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; import java.util.Arrays; /** @@ -18,19 +20,25 @@ public class FileHandler { /** * The directory used as base for this instance of {@link FileHandler}. This is where all files that can be read or writen will be located */ - private final File directory; + private final File/*System*/ directory; /** * Creates a new instance as well as setting the {@link #instance} to this new one * @param baseDirectory the directory to be used as base directory */ public FileHandler(@MagicConstant(valuesFromClass = FileHandlerLocation.class) String baseDirectory) { + try { + FileSystem fs = FileSystems.newFileSystem(new File(baseDirectory).toPath()); + //fs.getPath() + directory = new File(baseDirectory); + if (!directory.exists()) + directory.mkdirs(); - directory = new File(baseDirectory); - if(!directory.exists()) - directory.mkdirs(); - - instance = this; + instance = this; + }catch (Exception ex) + { + throw new FileHandlerException("Failed to create FileHandler instance with base directory \"" + baseDirectory + "\""); + } } /** diff --git a/Core/src/main/java/me/zacharias/chat/core/memory/AddMemoryFunction.java b/Core/src/main/java/me/zacharias/chat/core/memory/AddMemoryFunction.java index 6a4f89a..5e33657 100644 --- a/Core/src/main/java/me/zacharias/chat/core/memory/AddMemoryFunction.java +++ b/Core/src/main/java/me/zacharias/chat/core/memory/AddMemoryFunction.java @@ -30,6 +30,7 @@ public class AddMemoryFunction extends OllamaFunctionTool { public OllamaPerameter parameters() { return OllamaPerameter.builder() .addProperty("memory", OllamaPerameter.OllamaPerameterBuilder.Type.STRING, "The memory to remember", true) + .addProperty("identity", OllamaPerameter.OllamaPerameterBuilder.Type.STRING, "The identity of the memory to remember", true) .build(); } @@ -38,8 +39,25 @@ public class AddMemoryFunction extends OllamaFunctionTool { if (args.length == 0) { throw new OllamaToolErrorException(name(), "Missing memory argument"); } - String value = (String) args[0].value(); - memory.addMemory(value); - return new OllamaToolRespnce(name(), "Added "+value+" to the memory"); + + String memory = null; + String identity = null; + + for(OllamaFunctionArgument arg : args) { + if (arg.argument().equals("memory")) { + memory = (String) arg.value(); + } else if (arg.argument().equals("identity")) { + identity = (String) arg.value(); + } else { + throw new OllamaToolErrorException(name(), "Unknown argument: " + arg.argument()); + } + } + + if (memory == null || identity == null) { + throw new OllamaToolErrorException(name(), "Missing memory or identity argument"); + } + + this.memory.addMemory(identity, memory); + return new OllamaToolRespnce(name(), "Added "+identity+" to the memory"); } } diff --git a/Core/src/main/java/me/zacharias/chat/core/memory/CoreMemory.java b/Core/src/main/java/me/zacharias/chat/core/memory/CoreMemory.java index 0cfd809..0854ef4 100644 --- a/Core/src/main/java/me/zacharias/chat/core/memory/CoreMemory.java +++ b/Core/src/main/java/me/zacharias/chat/core/memory/CoreMemory.java @@ -1,5 +1,6 @@ package me.zacharias.chat.core.memory; +import me.zacharias.chat.core.Core; import org.json.JSONArray; import org.json.JSONObject; @@ -14,7 +15,7 @@ public class CoreMemory { /** * The singleton instance of CoreMemory. */ - private static CoreMemory instance = new CoreMemory("./cache/CoreMemory.json"); + private static final CoreMemory instance = new CoreMemory(Core.DATA + "/CoreMemory.json"); /** * Gets the singleton instance of CoreMemory. @@ -38,16 +39,7 @@ public class CoreMemory { while ((buffer = br.readLine()) != null) { data.append(buffer); } - JSONArray jsonArray = new JSONArray(data.toString()); - for(Object obj : jsonArray) { - if(obj instanceof String str) { - memory.add(str); - } - else - { - memory.add(obj.toString()); - } - } + memory = new JSONObject(data.toString()); }catch (Exception e) { e.printStackTrace(); } @@ -63,18 +55,14 @@ public class CoreMemory { f.delete(); } f.createNewFile(); + BufferedWriter bw = new BufferedWriter(new FileWriter(f)); - JSONArray jsonArray = new JSONArray(); - for(String str : memory) { - jsonArray.put(str); - } - - bw.write(jsonArray.toString()); + bw.write(memory.toString()); bw.close(); }catch (Exception e) { - + e.printStackTrace(); } } }); @@ -83,7 +71,7 @@ public class CoreMemory { /** * The memory. */ - private ArrayList memory = new ArrayList<>(); + private JSONObject memory = new JSONObject(); /** * The file to store the memory in. */ @@ -91,25 +79,50 @@ public class CoreMemory { /** * Gets the memory. - * @return The memory + * @return A list of memory identifies/names */ - public ArrayList getMemory() { - return memory; + public String[] getMemoriesIdentity() { + return memory.keySet().toArray(new String[0]); + } + + public String getMemory(String name) { + return memory.optString(name, null); } /** * Sets the memory. + * @param name The name/identity of the memory * @param memory The memory */ - public void addMemory(String memory) { - this.memory.add(memory); + public void addMemory(String name, String memory) { + this.memory.put(name, memory); } /** * Removes the memory. - * @param memory The memory to remove + * @param name The memory to remove */ - public void removeMemory(String memory) { - this.memory.remove(memory); + public void removeMemory(String name) { + this.memory.remove(name); + } + + /** + * Gets all memories as a JSON string. + * @return A JSON string of all memories + */ + public String getMemories() { + ArrayList memories = new ArrayList<>(); + for (String key : memory.keySet()) { + memories.add(key + ": " + memory.getString(key)); + } + return new JSONArray(memories).toString(); + } + + public ArrayList getMemoriesArray() { + ArrayList memories = new ArrayList<>(); + for (String key : memory.keySet()) { + memories.add(key + ": " + memory.getString(key)); + } + return memories; } } diff --git a/Core/src/main/java/me/zacharias/chat/core/memory/GetMemoriesFunction.java b/Core/src/main/java/me/zacharias/chat/core/memory/GetMemoriesFunction.java new file mode 100644 index 0000000..804bdf1 --- /dev/null +++ b/Core/src/main/java/me/zacharias/chat/core/memory/GetMemoriesFunction.java @@ -0,0 +1,28 @@ +package me.zacharias.chat.core.memory; + +import me.zacharias.chat.ollama.OllamaFunctionArgument; +import me.zacharias.chat.ollama.OllamaFunctionTool; +import me.zacharias.chat.ollama.OllamaPerameter; +import me.zacharias.chat.ollama.OllamaToolRespnce; + +public class GetMemoriesFunction extends OllamaFunctionTool { + @Override + public String name() { + return "get_memories"; + } + + @Override + public String description() { + return "Retrieves all the memories."; + } + + @Override + public OllamaPerameter parameters() { + return null; + } + + @Override + public OllamaToolRespnce function(OllamaFunctionArgument... args) { + return new OllamaToolRespnce(name(), CoreMemory.getInstance().getMemories()); + } +} diff --git a/Core/src/main/java/me/zacharias/chat/core/memory/GetMemoryFunction.java b/Core/src/main/java/me/zacharias/chat/core/memory/GetMemoryFunction.java index 096e635..b118aea 100644 --- a/Core/src/main/java/me/zacharias/chat/core/memory/GetMemoryFunction.java +++ b/Core/src/main/java/me/zacharias/chat/core/memory/GetMemoryFunction.java @@ -24,16 +24,18 @@ public class GetMemoryFunction extends OllamaFunctionTool { @Override public String description() { - return "Retrieves all the memory's"; + return "Retrieves the memory for a given identity."; } @Override public OllamaPerameter parameters() { - return null; + return OllamaPerameter.builder() + .addProperty("identity", OllamaPerameter.OllamaPerameterBuilder.Type.STRING, "The identity of the memory to retrieve", true) + .build(); } @Override public OllamaToolRespnce function(OllamaFunctionArgument... args) { - return new OllamaToolRespnce(name(), new JSONObject().put("memory_items", new JSONArray(memory.getMemory())).toString()); + return new OllamaToolRespnce(name(), memory.getMemory((String) (args[0].value()))); } } diff --git a/Core/src/main/java/me/zacharias/chat/core/memory/GetMemoryIdentitiesFunction.java b/Core/src/main/java/me/zacharias/chat/core/memory/GetMemoryIdentitiesFunction.java new file mode 100644 index 0000000..50eae58 --- /dev/null +++ b/Core/src/main/java/me/zacharias/chat/core/memory/GetMemoryIdentitiesFunction.java @@ -0,0 +1,31 @@ +package me.zacharias.chat.core.memory; + +import me.zacharias.chat.ollama.OllamaFunctionArgument; +import me.zacharias.chat.ollama.OllamaFunctionTool; +import me.zacharias.chat.ollama.OllamaPerameter; +import me.zacharias.chat.ollama.OllamaToolRespnce; +import org.json.JSONArray; + +public class GetMemoryIdentitiesFunction extends OllamaFunctionTool { + CoreMemory memory = CoreMemory.getInstance(); + + @Override + public String name() { + return "get_memory_identities"; + } + + @Override + public String description() { + return "Retrieves all the memory identities."; + } + + @Override + public OllamaPerameter parameters() { + return null; + } + + @Override + public OllamaToolRespnce function(OllamaFunctionArgument... args) { + return new OllamaToolRespnce(this.name(), new JSONArray(memory.getMemoriesIdentity()).toString()); + } +} diff --git a/Core/src/main/java/me/zacharias/chat/core/memory/RemoveMemoryFunction.java b/Core/src/main/java/me/zacharias/chat/core/memory/RemoveMemoryFunction.java index 78be5ad..6d6d61b 100644 --- a/Core/src/main/java/me/zacharias/chat/core/memory/RemoveMemoryFunction.java +++ b/Core/src/main/java/me/zacharias/chat/core/memory/RemoveMemoryFunction.java @@ -29,7 +29,7 @@ public class RemoveMemoryFunction extends OllamaFunctionTool { @Override public OllamaPerameter parameters() { return OllamaPerameter.builder() - .addProperty("memory", OllamaPerameter.OllamaPerameterBuilder.Type.STRING, "The memory to forget", true) + .addProperty("identity", OllamaPerameter.OllamaPerameterBuilder.Type.STRING, "The identity of the memory to forget", true) .build(); } diff --git a/Core/src/main/java/me/zacharias/chat/ollama/OllamaMessage.java b/Core/src/main/java/me/zacharias/chat/ollama/OllamaMessage.java index 959d41e..9bed926 100644 --- a/Core/src/main/java/me/zacharias/chat/ollama/OllamaMessage.java +++ b/Core/src/main/java/me/zacharias/chat/ollama/OllamaMessage.java @@ -29,7 +29,7 @@ public class OllamaMessage { public String toString() { JSONObject json = new JSONObject(); json.put("role", role.getRole()); - json.put("content", content); + json.put("content", content.replace("\n", "\\n")); return json.toString(); } } diff --git a/Core/src/main/java/me/zacharias/chat/ollama/utils/SystemMessage.java b/Core/src/main/java/me/zacharias/chat/ollama/utils/SystemMessage.java new file mode 100644 index 0000000..2f2da2e --- /dev/null +++ b/Core/src/main/java/me/zacharias/chat/ollama/utils/SystemMessage.java @@ -0,0 +1,15 @@ +package me.zacharias.chat.ollama.utils; + +import me.zacharias.chat.ollama.OllamaMessage; +import me.zacharias.chat.ollama.OllamaMessageRole; + +public class SystemMessage extends OllamaMessage { + /** + * Creates a new instance of OllamaMessage. + * + * @param systemMessage The content of the message + */ + public SystemMessage(String systemMessage) { + super(OllamaMessageRole.SYSTEM, systemMessage); + } +} diff --git a/Display/build.gradle b/Display/build.gradle index 0cc98fc..f3d6c25 100644 --- a/Display/build.gradle +++ b/Display/build.gradle @@ -8,7 +8,9 @@ version = '1.0-SNAPSHOT' dependencies { implementation project(":Core") implementation project(":MALAPITool") + implementation project(":GeniusAPI") implementation project(":API") + implementation project(":WikipediaTool") } test { diff --git a/Display/src/main/java/me/zacharias/chat/display/Display.java b/Display/src/main/java/me/zacharias/chat/display/Display.java index 8023650..a266614 100644 --- a/Display/src/main/java/me/zacharias/chat/display/Display.java +++ b/Display/src/main/java/me/zacharias/chat/display/Display.java @@ -8,6 +8,9 @@ import me.zacharias.chat.core.files.FileHandlerLocation; import me.zacharias.chat.core.memory.CoreMemory; import me.zacharias.chat.mal.api.MALAPITool; import me.zacharias.chat.ollama.*; +import me.zacharias.chat.ollama.utils.SystemMessage; +import me.zacharias.neuro.dock.genius.GeniusTools; +import me.zacharias.neuro.dock.wikipedia.WikipediaTool; import org.json.JSONObject; import java.io.*; @@ -51,13 +54,17 @@ public class Display { .keep_alive(10) //.stream(false) //.addFileTools(FileHandlerLocation.DATA_FILES) + .addMessages(new SystemMessage("You need to emulate feelings and emotions.")) .build()); core.enablePlugins(Core.PLUGIN_DIRECTORY); core.addTool(new TimeTool(), Core.Source.INTERNAL); - //core.addTool(new PythonRunner(core), Core.Source.INTERNAL); + // TODO: Well Docker failes when luanched.... Fuck + // core.addTool(new PythonRunner(core), Core.Source.INTERNAL); core.addTools(new MALAPITool().getOllamaTools()); + core.addTools(new GeniusTools().getGeniusTools()); + core.addTools(new WikipediaTool().getWikipediaToolsInstance()); APIApplication.start(); @@ -98,9 +105,12 @@ public class Display { case "help": System.out.print(""" Available commands: - /help Prints this help message. - /bye Exits the program. - /write Flushes the current log stream to file. + /help Prints this help message. + /bye Exits the program. + /write Flushes the current log stream to file. + /list Lists all available tools. + /working Prints the current working directories. + /peek Peeks the current memory. """); break; case "bye": @@ -114,7 +124,7 @@ public class Display { case "peek": CoreMemory coreMemory = CoreMemory.getInstance(); StringBuilder buffer = new StringBuilder("["); - ArrayList memory = new ArrayList<>(coreMemory.getMemory()); + ArrayList memory = new ArrayList<>(coreMemory.getMemoriesArray()); for(int i = 0; i < memory.size(); i++) { String mem = memory.get(i); buffer.append("\"").append(mem).append("\""); @@ -126,6 +136,29 @@ public class Display { writeLog("Memory peek: "+buffer.toString()); System.out.println(buffer.toString()); break; + case "list": + writeLog("Tools installed in this instance"); + + for(Pair funtion : core.getFuntionTools()) { + StringBuilder args = new StringBuilder(); + OllamaPerameter perameter = funtion.getKey().parameters(); + if (perameter != null) { + JSONObject obj = perameter.getProperties(); + for (String name : obj.keySet()) { + args.append(args.toString().isBlank() ? "" : ", ").append(obj.getJSONObject(name).getString("type")).append(Arrays.stream(perameter.getRequired()).anyMatch(str -> str.equalsIgnoreCase(name)) ? "" : "?").append(" ").append(name); + } + } + + System.out.println("> Function: " + funtion.getKey().name() + "(" + args + ") [" + funtion.getValue() + "]"); + writeLog("Function: " + funtion.getKey().name() + "(" + args + ") [" + funtion.getValue() + "]"); + } + break; + case "working": + System.out.println("Working directories:\n" + + " Data: " + Core.DATA_DIR.getAbsolutePath() + "\n" + + " DateFiles: " + FileHandlerLocation.DATA_FILES + "\n" + + " Plugins: " + Core.PLUGIN_DIRECTORY.getAbsolutePath()); + break; default: System.out.println("Unknown command: " + message); } diff --git a/GeniusAPI/src/test/java/LyricsFetch.java b/GeniusAPI/src/test/java/LyricsFetch.java new file mode 100644 index 0000000..9da6973 --- /dev/null +++ b/GeniusAPI/src/test/java/LyricsFetch.java @@ -0,0 +1,60 @@ +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.nodes.Node; +import org.jsoup.nodes.TextNode; +import org.jsoup.select.Elements; +import org.junit.jupiter.api.Test; + +import javax.swing.text.html.HTML; +import java.util.regex.MatchResult; +import java.util.regex.Pattern; + +import static me.zacharias.chat.core.Core.writeLog; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class LyricsFetch { + Pattern pattern = Pattern.compile("(?i)\\[(verse.*)|(chorus.*)|(bridge.*)|(outro.*)|(intro.*)]"); + + @Test + public void testFetchLyrics() throws Exception { + Document doc = Jsoup.connect("https://genius.com/Neuro-sama-life-lyrics") + .userAgent("Mozilla/5.0") + .get(); + + Elements containers = doc.select("div[data-lyrics-container=true]"); + + StringBuilder lyrics = new StringBuilder(); + + for (Element container : containers) { + for(Node n : container.childNodes()) + { + if(n instanceof Element e) { + if (e.attribute("data-exclude-from-selection") != null && e.attr("data-exclude-from-selection").equals("true")) { + continue; + } + else if(e.tagName().equalsIgnoreCase("br")) + { + lyrics.append("\n"); + } + else { + System.out.println(container.tagName()); + String s = e.text(); + lyrics.append(s.trim()); + } + } + else if(n instanceof TextNode tn) + { + String s = tn.text(); + if (!s.isBlank()) { + lyrics.append(s.trim()); + } + } + } + } + + System.out.println(lyrics.toString()); + assertNotNull(lyrics.toString()); + + } +} diff --git a/MALAPITool/src/main/java/me/zacharias/chat/mal/api/ParameterStringBuilder.java b/MALAPITool/src/main/java/me/zacharias/chat/mal/api/ParameterStringBuilder.java index acbcafc..d95ac5e 100644 --- a/MALAPITool/src/main/java/me/zacharias/chat/mal/api/ParameterStringBuilder.java +++ b/MALAPITool/src/main/java/me/zacharias/chat/mal/api/ParameterStringBuilder.java @@ -8,6 +8,8 @@ import java.util.Map; public class ParameterStringBuilder { public static String getParamsString(Map params) throws UnsupportedEncodingException { + if(params == null) + return ""; StringBuilder result = new StringBuilder(); for (Map.Entry entry : params.entrySet()) { diff --git a/launcher/src/main/java/me/zacharias/chat/launcher/Launcher.java b/launcher/src/main/java/me/zacharias/chat/launcher/Launcher.java index a9e4930..038b6a6 100644 --- a/launcher/src/main/java/me/zacharias/chat/launcher/Launcher.java +++ b/launcher/src/main/java/me/zacharias/chat/launcher/Launcher.java @@ -59,6 +59,7 @@ public class Launcher { -o --output Redirects the API Server output to another file -y Auto accepts to prompts, used for a seamless run. Not recomended when running as Display -d --dontLoadOld Don't load old messages + -f --full-message Shows the models ... block in the output --api Provides API docs """); return; @@ -71,6 +72,10 @@ public class Launcher { { options.setLoadOld(false); } + case "-f", "--full-message" -> + { + options.setShowFullMessage(true); + } default -> { System.out.println("Unknown option: " + arg+"\nUse --help for help"); diff --git a/settings.gradle b/settings.gradle index 4d6d8b9..4db86ea 100644 --- a/settings.gradle +++ b/settings.gradle @@ -2,4 +2,6 @@ rootProject.name = 'AI-test' include 'API', 'Core', 'Display', 'launcher' -include 'MALAPITool' \ No newline at end of file +include 'MALAPITool' +include 'GeniusAPI' +include 'WikipediaTool' \ No newline at end of file