package services import ( "fmt" "io" "net/url" "path" "strings" "arma3-web-server/internal/models" "golang.org/x/net/html" ) func ParseModlistHTML(r io.Reader) (string, []models.ModEntry, error) { doc, err := html.Parse(r) if err != nil { return "", nil, fmt.Errorf("parse html: %w", err) } var mods []models.ModEntry seen := map[string]bool{} var walk func(*html.Node) walk = func(n *html.Node) { if n.Type == html.ElementNode && n.Data == "tr" { if name, id, ok := extractModRow(n); ok && id != "" { if !seen[id] { seen[id] = true mods = append(mods, models.ModEntry{ ID: id, Name: cleanModName(name), Enabled: true, }) } } } for c := n.FirstChild; c != nil; c = c.NextSibling { walk(c) } } walk(doc) if mods == nil { mods = []models.ModEntry{} } return "", mods, nil } func extractModRow(tr *html.Node) (name, id string, ok bool) { var cells []*html.Node for c := tr.FirstChild; c != nil; c = c.NextSibling { if c.Type == html.ElementNode && c.Data == "td" { cells = append(cells, c) } } if len(cells) < 3 { return "", "", false } name = extractText(cells[0]) for c := cells[2].FirstChild; c != nil; c = c.NextSibling { if c.Type == html.ElementNode && c.Data == "a" { id = extractWorkshopID(c) break } } if name == "" { return "", "", false } return name, id, true } func extractText(n *html.Node) string { var b strings.Builder var walk func(*html.Node) walk = func(n *html.Node) { if n.Type == html.TextNode { b.WriteString(n.Data) } for c := n.FirstChild; c != nil; c = c.NextSibling { walk(c) } } walk(n) return strings.TrimSpace(b.String()) } func extractWorkshopID(a *html.Node) string { for _, attr := range a.Attr { if attr.Key == "href" { u, err := url.Parse(attr.Val) if err != nil { continue } return u.Query().Get("id") } } return "" } func cleanModName(name string) string { name = strings.TrimSpace(name) name = strings.ReplaceAll(name, "/", "_") name = strings.ReplaceAll(name, "\\", "_") return name } func FileNameToModlistName(filename string) string { ext := path.Ext(filename) name := strings.TrimSuffix(filename, ext) name = strings.ReplaceAll(name, "_", " ") name = strings.ReplaceAll(name, "-", " ") return name }