readysite / website / internal / content / seed / migrations.go
2.1 KB
migrations.go
package seed

import (
	"log"
	"strings"

	"github.com/readysite/readysite/website/models"
)

// Migrations runs one-time data migrations.
func Migrations() {
	fixEscapedHTMLContent()
}

// fixEscapedHTMLContent fixes double-escaped JSON sequences in page and partial content.
// This is a one-time migration to fix content created before the unescapeHTML fix was added.
func fixEscapedHTMLContent() {
	// Check if migration already ran by looking for escaped content
	contents, err := models.PageContents.Search("WHERE HTML LIKE '%\\n%' OR HTML LIKE '%\\\"%' LIMIT 1")
	if err != nil || len(contents) == 0 {
		// No escaped content found or error - either already migrated or no content
		// Also check partials
		partials, err := models.Partials.Search("WHERE HTML LIKE '%\\n%' OR HTML LIKE '%\\\"%' LIMIT 1")
		if err != nil || len(partials) == 0 {
			return // Nothing to fix
		}
	}

	log.Println("Running migration: fixing escaped HTML content...")

	// Fix page contents
	allContents, err := models.PageContents.All()
	if err == nil {
		fixed := 0
		for _, c := range allContents {
			if strings.Contains(c.HTML, `\n`) || strings.Contains(c.HTML, `\"`) {
				c.HTML = unescapeHTML(c.HTML)
				if err := models.PageContents.Update(c); err == nil {
					fixed++
				}
			}
		}
		if fixed > 0 {
			log.Printf("Fixed %d page content(s)", fixed)
		}
	}

	// Fix partials
	allPartials, err := models.Partials.All()
	if err == nil {
		fixed := 0
		for _, p := range allPartials {
			if strings.Contains(p.HTML, `\n`) || strings.Contains(p.HTML, `\"`) {
				p.HTML = unescapeHTML(p.HTML)
				if err := models.Partials.Update(p); err == nil {
					fixed++
				}
			}
		}
		if fixed > 0 {
			log.Printf("Fixed %d partial(s)", fixed)
		}
	}

	log.Println("Migration complete: escaped HTML content fixed")
}

// unescapeHTML fixes double-escaped JSON sequences in HTML content.
func unescapeHTML(s string) string {
	if !strings.Contains(s, `\n`) && !strings.Contains(s, `\"`) {
		return s
	}

	s = strings.ReplaceAll(s, `\n`, "\n")
	s = strings.ReplaceAll(s, `\r`, "\r")
	s = strings.ReplaceAll(s, `\t`, "\t")
	s = strings.ReplaceAll(s, `\"`, `"`)
	s = strings.ReplaceAll(s, `\\`, `\`)

	return s
}
← Back