using System.Text.Json; using System.Text.Json.Nodes; using DashCaddy.Desktop.Models; namespace DashCaddy.Desktop.Services; public static class ComposeParser { public static List Parse(string yamlContent) { var services = new List(); // Simple YAML parsing - in production use YamlDotNet // For now, we'll do a basic JSON-based approach assuming compose is converted try { var json = JsonSerializer.Deserialize(yamlContent); // This won't work for YAML directly // Real implementation would use YamlDotNet } catch { // Fallback } return services; } public static List ParseJson(string jsonContent) { var compose = JsonSerializer.Deserialize(jsonContent, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); var services = new List(); if (compose?.Services != null) { foreach (var (name, svc) in compose.Services) { var port = ExtractPort(svc); var env = svc.Environment ?? new Dictionary(); services.Add(new ServiceModel { Id = Guid.NewGuid().ToString("N")[..8], Name = name, Type = "docker-compose", Image = svc.Image ?? "", Host = "localhost", Port = port, Environment = env, Volumes = svc.Volumes ?? new List(), Labels = svc.Labels ?? new Dictionary(), ComposeFile = jsonContent }); } } return services; } private static int ExtractPort(ComposeService svc) { if (svc.Ports != null) { foreach (var (key, value) in svc.Ports) { if (int.TryParse(key.Split(':')[0], out var hostPort)) return hostPort; if (int.TryParse(key, out var containerPort)) return containerPort; } } return 80; } } public static class TemplateRegistry { private static readonly Dictionary Templates = new() { ["plex"] = new ServiceTemplate { Id = "plex", Name = "Plex Media Server", Description = "Media server for movies, TV shows, and music", Icon = "📺", DefaultPort = 32400, Image = "plexinc/pms-docker:latest", Environment = new Dictionary { ["PLEX_CLAIM"] = "", ["TZ"] = "America/Los_Angeles" }, Volumes = new List { "E:/dockerdata/plex/config:/config", "E:/dockerdata/plex/transcode:/transcode", "E:/media:/data" }, RequiredVariables = new[] { "PLEX_CLAIM" } }, ["homeassistant"] = new ServiceTemplate { Id = "homeassistant", Name = "Home Assistant", Description = "Open source home automation platform", Icon = "🏠", DefaultPort = 8123, Image = "ghcr.io/home-assistant/home-assistant:stable", Environment = new Dictionary { ["TZ"] = "America/Los_Angeles" }, Volumes = new List { "E:/dockerdata/homeassistant:/config" }, NetworkMode = "host" }, ["jellyfin"] = new ServiceTemplate { Id = "jellyfin", Name = "Jellyfin", Description = "Free software media system", Icon = "🎬", DefaultPort = 8096, Image = "jellyfin/jellyfin:latest", Environment = new Dictionary { ["TZ"] = "America/Los_Angeles" }, Volumes = new List { "E:/dockerdata/jellyfin/config:/config", "E:/dockerdata/jellyfin/cache:/cache", "E:/media:/media" } }, ["portainer"] = new ServiceTemplate { Id = "portainer", Name = "Portainer", Description = "Docker container management UI", Icon = "🐳", DefaultPort = 9443, Image = "portainer/portainer-ce:latest", Volumes = new List { "E:/dockerdata/portainer:/data", "//./pipe/docker_engine:/var/run/docker.sock" } }, ["adguard"] = new ServiceTemplate { Id = "adguard", Name = "AdGuard Home", Description = "Network-wide ad blocking & DNS", Icon = "🛡️", DefaultPort = 3000, Image = "adguard/adguardhome:latest", Volumes = new List { "E:/dockerdata/adguard/work:/opt/adguardhome/work", "E:/dockerdata/adguard/conf:/opt/adguardhome/conf" }, Ports = new Dictionary { [53] = 53, [3000] = 3000 } }, ["uptime-kuma"] = new ServiceTemplate { Id = "uptime-kuma", Name = "Uptime Kuma", Description = "Self-hosted monitoring tool", Icon = "📊", DefaultPort = 3001, Image = "louislam/uptime-kuma:1", Volumes = new List { "E:/dockerdata/uptime-kuma:/app/data" } }, ["vaultwarden"] = new ServiceTemplate { Id = "vaultwarden", Name = "Vaultwarden (Bitwarden)", Description = "Self-hosted password manager", Icon = "🔐", DefaultPort = 8080, Image = "vaultwarden/server:latest", Environment = new Dictionary { ["SIGNUPS_ALLOWED"] = "true", ["INVITATIONS_ALLOWED"] = "true" }, Volumes = new List { "E:/dockerdata/vaultwarden:/data" } }, ["paperless"] = new ServiceTemplate { Id = "paperless", Name = "Paperless-ngx", Description = "Document management system", Icon = "📄", DefaultPort = 8000, Image = "ghcr.io/paperless-ngx/paperless-ngx:latest", Environment = new Dictionary { ["PAPERLESS_REDIS"] = "redis://localhost:6379", ["PAPERLESS_DBHOST"] = "localhost", ["PAPERLESS_DBNAME"] = "paperless", ["PAPERLESS_DBUSER"] = "paperless", ["PAPERLESS_DBPASS"] = "paperless" }, Volumes = new List { "E:/dockerdata/paperless/data:/usr/src/paperless/data", "E:/dockerdata/paperless/media:/usr/src/paperless/media", "E:/dockerdata/paperless/export:/usr/src/paperless/export", "E:/dockerdata/paperless/consume:/usr/src/paperless/consume" } } }; public static ServiceTemplate Get(string id) { return Templates.TryGetValue(id, out var template) ? template : null; } public static IEnumerable GetAll() { return Templates.Values; } } public class ServiceTemplate { public string Id { get; set; } public string Name { get; set; } public string Description { get; set; } public string Icon { get; set; } public int DefaultPort { get; set; } public string Image { get; set; } public Dictionary Environment { get; set; } = new(); public List Volumes { get; set; } = new(); public Dictionary Ports { get; set; } = new(); public string NetworkMode { get; set; } public string[] RequiredVariables { get; set; } = Array.Empty(); public ServiceModel Instantiate(Dictionary variables) { var env = new Dictionary(Environment); foreach (var (key, value) in variables) { env[key] = value; } var port = DefaultPort; if (Ports.Count > 0) { port = Ports.Keys.First(); } return new ServiceModel { Id = Guid.NewGuid().ToString("N")[..8], Name = Name, Type = "template", Image = Image, Host = "localhost", Port = port, Environment = env, Volumes = Volumes, Labels = new Dictionary { ["dashcaddy.template"] = Id, ["dashcaddy.managed"] = "true" } }; } }