refactor: me.zacharias.chat → me.neurodock, org rename cleanup

- Renamed package from me.zacharias.chat to me.neurodock across all 8 modules
- Updated Gradle group from me.zacharias.neurodock to me.neurodock
- Updated README and other files to reflect new Gitea org URL (Chat_things → neurodock)

Dev note: 95 files touched. The Great Refactor is complete, long may it rest.
This commit is contained in:
2026-05-27 23:34:22 +02:00
parent 88c593c47d
commit f50c04c828
97 changed files with 301 additions and 315 deletions
@@ -0,0 +1,69 @@
package me.neurodock.genius.endpoints;
import me.neurodock.ollama.OllamaFunctionArgument;
import me.neurodock.ollama.OllamaPerameter;
import me.neurodock.ollama.OllamaToolResponse;
import me.neurodock.ollama.exceptions.OllamaToolErrorException;
import me.neurodock.genius.GeniusEndpoint;
import me.neurodock.genius.GeniusEndpointTool;
import me.neurodock.genius.GeniusTools;
import org.jetbrains.annotations.NotNull;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.Map;
import static me.neurodock.ollama.OllamaPerameter.OllamaPerameterBuilder.Type.STRING;
@GeniusEndpoint
public class FindSong extends GeniusEndpointTool {
public FindSong(GeniusTools geniusTools) {
super(geniusTools);
}
@Override
public @NotNull String name() {
return "findsong";
}
@Override
public String description() {
return "Finds a song by title from the Genius API.";
}
@Override
public @NotNull OllamaPerameter parameters() {
return OllamaPerameter.builder()
.addProperty("title", STRING, "The title, artitst, and song_id of the song to find.", true)
.build();
}
@Override
public @NotNull OllamaToolResponse function(OllamaFunctionArgument... args) {
String title = (String) args[0].value();
if (title == null || title.isEmpty()) {
throw new OllamaToolErrorException(this.name(), "Title cannot be null or empty.");
}
JSONObject response = this.geniusToolsInstance.getGeniusEndpoint("/search", Map.of("q", title));
JSONArray responseData = new JSONArray();
for(Object obj : response.getJSONObject("response").getJSONArray("hits")) {
if(obj instanceof JSONObject songResult) {
JSONObject song = songResult.getJSONObject("result");
JSONObject songData = new JSONObject();
songData.put("title", song.getString("title"));
songData.put("artist", song.getString("artist_names"));
songData.put("id", song.getInt("id"));
responseData.put(songData);
}
}
if (responseData.isEmpty()) {
throw new OllamaToolErrorException(this.name(), "No songs found for the given title.");
}
return new OllamaToolResponse(this.name(), responseData.toString());
}
}
@@ -0,0 +1,126 @@
package me.neurodock.genius.endpoints;
import me.neurodock.ollama.OllamaFunctionArgument;
import me.neurodock.ollama.OllamaPerameter;
import me.neurodock.ollama.OllamaToolResponse;
import me.neurodock.ollama.exceptions.OllamaToolErrorException;
import me.neurodock.genius.GeniusEndpoint;
import me.neurodock.genius.GeniusEndpointTool;
import me.neurodock.genius.GeniusTools;
import org.jetbrains.annotations.NotNull;
import org.json.JSONObject;
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 static me.neurodock.core.Core.writeLog;
/**
* This class is an Ollama tool that fetches the lyrics of a song by its ID from the Genius API.
* It extends the GeniusEndpointTool to utilize the GeniusTools instance for API calls and caching.
* <p>
* <h1>Legal Notice</h1>
* <p>
* I (the developer) do NOT own the rights to the lyrics fetched by this tool, nor do I endorse scraping lyrics from Genius.com,
* which may violate their Terms of Service.
* </p>
* <p>
* I disclaim any responsibility or liability for how this tool is used.
* Use this tool at your own risk, and please respect all applicable copyright laws and third-party terms.
* </p>
*/
@GeniusEndpoint
public class GetLyrics extends GeniusEndpointTool {
public GetLyrics(GeniusTools geniusTools) {
super(geniusTools);
}
@Override
public @NotNull String name() {
return "get_lyrics";
}
@Override
public String description() {
return "Gets the lyrics of a song by its ID from the Genius API.";
}
@Override
public @NotNull OllamaPerameter parameters() {
return OllamaPerameter.builder()
.addProperty("song_id", OllamaPerameter.OllamaPerameterBuilder.Type.INT, "The ID of the song to get lyrics for.", true)
.build();
}
@Override
public @NotNull OllamaToolResponse function(OllamaFunctionArgument... args) {
if(!( args[0].value() instanceof Integer)) {
throw new OllamaToolErrorException(this.name(), "The song_id must be an integer.");
}
String lyricsStr = geniusToolsInstance.hasCache((int) args[0].value());
if(lyricsStr != null)
{
return new OllamaToolResponse(this.name(), lyricsStr.trim());
}
JSONObject obj = geniusToolsInstance.getGeniusEndpoint("/songs/" + args[0].value(), null);
String lyrics_path = obj.getJSONObject("response").getJSONObject("song").getString("url");
try {
// WARNING: This request scrapes the lyrics from the Genius website.
// Which is against their Terms of Service. Use responsibly
Document doc = Jsoup.connect(lyrics_path)
.userAgent("insomnia/11.1.0") // TODO: replace with somthing else then insomnia! since we in no way support what ever Insomnia's User-Agent says we do
.header("host", "genius.com")
.header("accept", "*/*")
.get();
writeLog("Fetching lyrics from: " + lyrics_path);
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());
}
}
}
}
geniusToolsInstance.cacheLyrics((int) args[0].value(), lyrics.toString());
return new OllamaToolResponse(this.name(), lyrics.toString().trim());
}catch (Exception ex)
{
ex.printStackTrace();
throw new OllamaToolErrorException(this.name(), "Failed to fetch lyrics.");
}
}
}