diff --git a/ComfySharp.sln.DotSettings b/ComfySharp.sln.DotSettings
new file mode 100644
index 0000000..792e9ca
--- /dev/null
+++ b/ComfySharp.sln.DotSettings
@@ -0,0 +1,2 @@
+
+ PackageReference
\ No newline at end of file
diff --git a/ComfySharp/ComfyClient.cs b/ComfySharp/ComfyClient.cs
index c493e15..b85dc69 100644
--- a/ComfySharp/ComfyClient.cs
+++ b/ComfySharp/ComfyClient.cs
@@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations;
+using System.Dynamic;
using System.Net;
using System.Net.Http.Json;
using System.Text.Json;
@@ -8,7 +9,7 @@ namespace ComfySharp;
public class ComfyClient {
private HttpClient client;
- private List nodes;
+ private List nodes;
public string BaseUrl { get; set; }
@@ -18,7 +19,7 @@ public class ComfyClient {
BaseAddress = new Uri(baseUrl),
DefaultRequestHeaders = { { "User-Agent", "ComfySharp" } }
};
- nodes= new List();
+ nodes= new();
}
public async Task GetEmbeddings() {
@@ -49,10 +50,10 @@ public class ComfyClient {
if (req is { IsSuccessStatusCode: true, Content: not null }) {
var doc = await req.Content.ReadFromJsonAsync();
ObjectInfoParser.Parse(doc, out nodes);
-
}
-
- throw new NotImplementedException();
+
+ return null;
+ //throw new NotImplementedException();
}
public async Task GetImage(string filename) {
diff --git a/ComfySharp/ObjectInfoParser.cs b/ComfySharp/ObjectInfoParser.cs
index 1f5580a..58e9bda 100644
--- a/ComfySharp/ObjectInfoParser.cs
+++ b/ComfySharp/ObjectInfoParser.cs
@@ -1,75 +1,21 @@
-using System.Text.Json;
+using System.Dynamic;
+using System.Text.Json;
using ComfySharp.Types;
namespace ComfySharp;
public static class ObjectInfoParser {
- public static void Parse(JsonDocument document, out List nodes) {
- nodes = new List();
- foreach (var node in document.RootElement.EnumerateObject()) {
- Node n = new();
- n.Name = node.Name;
-
- foreach (var prop in node.Value.EnumerateObject()) {
- switch (prop.Name) {
- case "input":
- n.Input = new();
-
- foreach (var input in prop.Value.EnumerateObject()) {
- switch (input.Name) {
- case "required":
- foreach (var field in input.Value.EnumerateObject()) {
- InputField f = new();
- f.Name = field.Name;
- f.Type = Enum.Parse(field.Value.GetString() ?? "");
- n.Input.Required.Add(f);
- }
- break;
- case "optional":
- foreach (var field in input.Value.EnumerateObject()) {
- InputField f = new();
- f.Name = field.Name;
- f.Type = Enum.Parse(field.Value.GetString() ?? "");
- n.Input.Optional.Add(f);
- }
- break;
- case "hidden":
- foreach (var field in input.Value.EnumerateObject()) {
- InputField f = new();
- f.Name = field.Name;
- f.Type = Enum.Parse(field.Value.GetString() ?? "");
- n.Input.Hidden.Add(f);
- }
- break;
- }
- }
- break;
- case "output":
- foreach (var output in prop.Value.EnumerateObject()) {
- n.Outputs.Add(Enum.Parse(output.Value.GetString() ?? ""));
- n.OutputIsList.Add(output.Value.GetBoolean());
- n.OutputNames.Add(output.Name);
- }
- break;
- case "display_name":
- n.DisplayName = prop.Value.GetString() ?? "";
- break;
- case "description":
- n.Description = prop.Value.GetString() ?? "";
- break;
- case "category":
- n.Category = prop.Value.GetString() ?? "";
- break;
- case "output_node":
- n.IsOutputNode = prop.Value.GetBoolean();
- break;
- }
- }
- }
+
+ public static void Parse(JsonDocument document, out List nodes) {
+ NodeDBGenerator dbGenerator = new();
+ dbGenerator.GenerateNodes(document);
+ nodes = dbGenerator.GetNodes();
+ dbGenerator.GenerateClasses(document);
}
private static void ParseNode(JsonElement node, out Node n) {
n = new();
+
n.Name = node.GetProperty("name").GetString() ?? "";
n.Input = ParseInput(node.GetProperty("input"));
n.Outputs = ParseOutputs(node.GetProperty("output"));
@@ -80,4 +26,20 @@ public static class ObjectInfoParser {
n.Category = node.GetProperty("category").GetString() ?? "";
n.IsOutputNode = node.GetProperty("output_node").GetBoolean();
}
+ static private List ParseOutputNames(JsonElement getProperty) {
+ List outputNames = new();
+ foreach (var output in getProperty.EnumerateArray()) {
+ outputNames.Add(output.GetProperty("name").GetString() ?? "");
+ }
+ return outputNames;
+ }
+ static private List ParseOutputIsList(JsonElement getProperty) {
+ throw new NotImplementedException();
+ }
+ static private List ParseOutputs(JsonElement getProperty) {
+ throw new NotImplementedException();
+ }
+ static private Input ParseInput(JsonElement getProperty) {
+ throw new NotImplementedException();
+ }
}
\ No newline at end of file
diff --git a/ComfySharp/Types/NodeDBGenerator.cs b/ComfySharp/Types/NodeDBGenerator.cs
new file mode 100644
index 0000000..c0ea89b
--- /dev/null
+++ b/ComfySharp/Types/NodeDBGenerator.cs
@@ -0,0 +1,181 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.Json;
+using System.Dynamic;
+using System.Runtime.CompilerServices;
+
+namespace ComfySharp.Types;
+
+public class NodeDBGenerator {
+ private List nodes;
+
+ private List knownTypes = new();
+ public List GetKnownTypes() => knownTypes;
+
+ private Dictionary> knownEnums = new();
+ public Dictionary> GetKnownEnums() => knownEnums;
+
+ public int Count => nodes.Count;
+ private int typeFields = 0;
+ private int enumFields = 0;
+
+ public NodeDBGenerator() {
+ nodes = new();
+ }
+
+ public void ResetDb() => nodes.Clear();
+
+ ///
+ /// Adds a new type to the list of known types, avoids duplicates
+ ///
+ /// type name as string
+ private void AddKnownType(string type) {
+ if (!knownTypes.Contains(type)) {
+ knownTypes.Add(type);
+ Console.WriteLine("Added new known type: {0}", type);
+ } else {
+ Console.WriteLine("Type {0} already known, skipped.", type);
+ }
+ typeFields++;
+ }
+
+ ///
+ /// Adds or updates a known enum, avoids duplicates.
+ ///
+ /// enum type name as string
+ /// Collection of valid string values for this enum
+ private void AddKnownEnum(string type, ICollection values) {
+ if (!knownEnums.ContainsKey(type)) {
+ knownEnums.Add(type, values.ToList());
+ Console.WriteLine("Added new known enum: {0}", type);
+ }
+ else {
+ values.ToList().ForEach(value => {
+ if (!knownEnums[type].Contains(value)) {
+ knownEnums[type].Add(value);
+ Console.WriteLine("Added new value to known enum: {0}", value);
+ }
+ });
+ }
+ enumFields++;
+ }
+
+ public void GenerateClasses(JsonDocument document) {
+ foreach (var node in document.RootElement.EnumerateObject()) ScanNode(node);
+
+ Console.WriteLine("List of recognized Types:");
+ foreach (var knownType in knownTypes) {
+ Console.WriteLine(knownType);
+ }
+ Console.WriteLine("\nTotal amount of types iterated: {0}\n", typeFields);
+ Console.WriteLine("List of recognized Enums:");
+ foreach (var knownEnum in knownEnums) {
+ Console.WriteLine(knownEnum.Key);
+ foreach (var value in knownEnum.Value) {
+ Console.Write("\t{0}", value);
+ }
+ Console.WriteLine();
+ }
+ Console.WriteLine("\nTotal amount of enums iterated: {0}\n", enumFields);
+ }
+
+ ///
+ /// executed for a single node, progresses through the properties of the node
+ ///
+ private void ScanNode(JsonProperty node) {
+ // each of this are top level properties of the node
+ foreach (var property in node.Value.EnumerateObject()) {
+ //if this is a list of input properties:
+ if (property.Name == "input" && property.Value.ValueKind == JsonValueKind.Object) ScanInputs(property);
+ else if (property.Name == "output" && property.Value.ValueKind == JsonValueKind.Array) ScanOutputs(property);
+ }
+ }
+
+ ///
+ /// Executed on the input property inside a node
+ ///
+ private void ScanInputs(JsonProperty input) {
+ foreach (var inputType in input.Value.EnumerateObject()) {
+ //these are related to the nodes themselves and useless for us
+ if (inputType.Name == "hidden") continue;
+ // required and optionals have the same structure, so we can parse them the same way
+ if (inputType.Name == "required" || inputType.Name == "optional")
+ foreach (var inputProperty in inputType.Value.EnumerateObject()) ScanInputField(inputProperty);
+ }
+ }
+
+ ///
+ /// Executed for each of the elements inside a required or optional input
+ ///
+ private void ScanInputField(JsonProperty inputProperty) {
+ // if element 0 is a string, this is a type
+ if (inputProperty.Value[0].ValueKind == JsonValueKind.String)
+ AddKnownType(inputProperty.Value[0].ToString());
+ // else, if element 0 is an array, this is an enum
+ else if (inputProperty.Value[0].ValueKind == JsonValueKind.Array) {
+ List enumValues = new();
+ inputProperty.Value[0].EnumerateArray().ToList().ForEach(value => enumValues.Add(value.ToString()));
+ AddKnownEnum(inputProperty.Name, enumValues);
+
+ }
+ }
+
+ private void ScanOutputs(JsonProperty output) { }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void GenerateNode(JsonElement data) {
+ var node = new ExpandoObject();
+ Console.WriteLine("Generating node: {0}", data.GetProperty("name").GetString() ?? "");
+ foreach (var property in data.EnumerateObject()) {
+ Console.WriteLine("Adding new property: {0}\nType: {2}\nValue: {1}\n", property.Name, property.Value, property.Value.GetType());
+ node.TryAdd(property.Name, property.Value);
+ }
+ nodes.Add(node);
+ }
+
+ public void GenerateNode(JsonProperty node) {
+ GenerateNode(node.Value);
+ }
+
+ public void GenerateNodes(JsonDocument document) {
+ foreach (var node in document.RootElement.EnumerateObject()) {
+ GenerateNode(node.Value);
+ }
+ }
+
+ public void GenerateNodes(string json) {
+ var document = JsonDocument.Parse(json);
+ GenerateNodes(document);
+ }
+
+ public void GenerateNodes(ICollection elements) {
+ foreach (var element in elements) {
+ GenerateNode(element);
+ }
+ }
+
+ public void GenerateNodes(ICollection elements) {
+ foreach (var element in elements) {
+ GenerateNode(element);
+ }
+ }
+
+ public List GetNodes() => nodes;
+
+
+}