mirror of
https://github.com/SamueleLorefice/ComfySharp
synced 2026-01-14 23:35:56 +00:00
Revamped parsing part 1
This commit is contained in:
2
ComfySharp.sln.DotSettings
Normal file
2
ComfySharp.sln.DotSettings
Normal file
@@ -0,0 +1,2 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/Environment/Hierarchy/NuGetOptions/DefaultPackageManagementFormat/@EntryValue">PackageReference</s:String></wpf:ResourceDictionary>
|
||||
@@ -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<Node> nodes;
|
||||
private List<ExpandoObject> nodes;
|
||||
|
||||
public string BaseUrl { get; set; }
|
||||
|
||||
@@ -18,7 +19,7 @@ public class ComfyClient {
|
||||
BaseAddress = new Uri(baseUrl),
|
||||
DefaultRequestHeaders = { { "User-Agent", "ComfySharp" } }
|
||||
};
|
||||
nodes= new List<Node>();
|
||||
nodes= new();
|
||||
}
|
||||
|
||||
public async Task<string[]?> GetEmbeddings() {
|
||||
@@ -49,10 +50,10 @@ public class ComfyClient {
|
||||
if (req is { IsSuccessStatusCode: true, Content: not null }) {
|
||||
var doc = await req.Content.ReadFromJsonAsync<JsonDocument>();
|
||||
ObjectInfoParser.Parse(doc, out nodes);
|
||||
|
||||
}
|
||||
|
||||
throw new NotImplementedException();
|
||||
|
||||
return null;
|
||||
//throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public async Task<byte[]?> GetImage(string filename) {
|
||||
|
||||
@@ -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<Node> nodes) {
|
||||
nodes = new List<Node>();
|
||||
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<PrimitiveType>(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<PrimitiveType>(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<PrimitiveType>(field.Value.GetString() ?? "");
|
||||
n.Input.Hidden.Add(f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "output":
|
||||
foreach (var output in prop.Value.EnumerateObject()) {
|
||||
n.Outputs.Add(Enum.Parse<PrimitiveType>(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<ExpandoObject> 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<string> ParseOutputNames(JsonElement getProperty) {
|
||||
List<string> outputNames = new();
|
||||
foreach (var output in getProperty.EnumerateArray()) {
|
||||
outputNames.Add(output.GetProperty("name").GetString() ?? "");
|
||||
}
|
||||
return outputNames;
|
||||
}
|
||||
static private List<bool> ParseOutputIsList(JsonElement getProperty) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
static private List<PrimitiveType> ParseOutputs(JsonElement getProperty) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
static private Input ParseInput(JsonElement getProperty) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
181
ComfySharp/Types/NodeDBGenerator.cs
Normal file
181
ComfySharp/Types/NodeDBGenerator.cs
Normal file
@@ -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<ExpandoObject> nodes;
|
||||
|
||||
private List<string> knownTypes = new();
|
||||
public List<string> GetKnownTypes() => knownTypes;
|
||||
|
||||
private Dictionary<string, List<string>> knownEnums = new();
|
||||
public Dictionary<string, List<string>> GetKnownEnums() => knownEnums;
|
||||
|
||||
public int Count => nodes.Count;
|
||||
private int typeFields = 0;
|
||||
private int enumFields = 0;
|
||||
|
||||
public NodeDBGenerator() {
|
||||
nodes = new();
|
||||
}
|
||||
|
||||
public void ResetDb() => nodes.Clear();
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new type to the list of known types, avoids duplicates
|
||||
/// </summary>
|
||||
/// <param name="type">type name as string</param>
|
||||
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++;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds or updates a known enum, avoids duplicates.
|
||||
/// </summary>
|
||||
/// <param name="type">enum type name as string</param>
|
||||
/// <param name="values">Collection of valid string values for this enum</param>
|
||||
private void AddKnownEnum(string type, ICollection<string> 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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// executed for a single node, progresses through the properties of the node
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executed on the input property inside a node
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executed for each of the elements inside a required or optional input
|
||||
/// </summary>
|
||||
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<string> 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<JsonElement> elements) {
|
||||
foreach (var element in elements) {
|
||||
GenerateNode(element);
|
||||
}
|
||||
}
|
||||
|
||||
public void GenerateNodes(ICollection<JsonProperty> elements) {
|
||||
foreach (var element in elements) {
|
||||
GenerateNode(element);
|
||||
}
|
||||
}
|
||||
|
||||
public List<ExpandoObject> GetNodes() => nodes;
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user