101 lines
2.8 KiB
Go
101 lines
2.8 KiB
Go
package internal
|
|
|
|
import (
|
|
"crypto/md5"
|
|
"encoding/base64"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// NewDiagram returns a new diagram.
|
|
func NewDiagram(description []byte, imgType string) *Diagram {
|
|
// Debug: Log what we received
|
|
fmt.Printf("DEBUG: Received %d bytes\n", len(description))
|
|
fmt.Printf("DEBUG: Raw bytes: %q\n", string(description))
|
|
fmt.Printf("DEBUG: Contains newlines: %t\n", strings.Contains(string(description), "\n"))
|
|
|
|
trimmed := strings.TrimSpace(string(description))
|
|
fmt.Printf("DEBUG: After TrimSpace: %q\n", trimmed)
|
|
fmt.Printf("DEBUG: Still contains newlines: %t\n", strings.Contains(trimmed, "\n"))
|
|
|
|
// Decode NEWLINE markers back to actual newlines for complex diagrams
|
|
if strings.Contains(trimmed, " NEWLINE ") {
|
|
trimmed = strings.ReplaceAll(trimmed, " NEWLINE ", "\n")
|
|
fmt.Printf("DEBUG: After NEWLINE decoding: %q\n", trimmed)
|
|
fmt.Printf("DEBUG: Now contains newlines: %t\n", strings.Contains(trimmed, "\n"))
|
|
}
|
|
|
|
// Decode pipe separators back to newlines for quadrant charts
|
|
if strings.Contains(trimmed, " | ") {
|
|
trimmed = strings.ReplaceAll(trimmed, " | ", "\n")
|
|
fmt.Printf("DEBUG: After pipe decoding: %q\n", trimmed)
|
|
fmt.Printf("DEBUG: Now contains newlines: %t\n", strings.Contains(trimmed, "\n"))
|
|
}
|
|
|
|
return &Diagram{
|
|
description: []byte(trimmed),
|
|
lastTouched: time.Now(),
|
|
mu: &sync.RWMutex{},
|
|
imgType: imgType,
|
|
}
|
|
}
|
|
|
|
// Diagram represents a single diagram.
|
|
type Diagram struct {
|
|
// id is the ID of the Diagram
|
|
id string
|
|
// description is the description of the diagram.
|
|
description []byte
|
|
// Output is the filepath to the output file.
|
|
Output string
|
|
// mu is a mutex to protect the last touched value.
|
|
mu *sync.RWMutex
|
|
// lastTouched is the time that the diagram was last used.
|
|
lastTouched time.Time
|
|
// the type of image to generate svg or png
|
|
imgType string
|
|
}
|
|
|
|
// Touch updates the last touched time of the diagram.
|
|
func (d *Diagram) Touch() {
|
|
d.mu.Lock()
|
|
defer d.mu.Unlock()
|
|
d.lastTouched = time.Now()
|
|
}
|
|
|
|
// TouchedInDuration returns true if the diagram has been touched in the given duration.
|
|
func (d *Diagram) TouchedInDuration(duration time.Duration) bool {
|
|
d.mu.Lock()
|
|
defer d.mu.Unlock()
|
|
return time.Now().Add(-duration).Before(d.lastTouched)
|
|
}
|
|
|
|
// ID returns an ID for the diagram.
|
|
// The ID is set from the diagram description.
|
|
func (d *Diagram) ID() (string, error) {
|
|
if d.id != "" {
|
|
return d.id, nil
|
|
}
|
|
|
|
encoded := base64.StdEncoding.EncodeToString(d.description)
|
|
hash := md5.Sum([]byte(encoded))
|
|
d.id = hex.EncodeToString(hash[:]) + d.imgType
|
|
|
|
return d.id, nil
|
|
}
|
|
|
|
// Description returns the diagram description.
|
|
func (d *Diagram) Description() []byte {
|
|
return d.description
|
|
}
|
|
|
|
// Description returns the diagram description.
|
|
func (d *Diagram) WithDescription(description []byte) *Diagram {
|
|
d.description = description
|
|
d.id = ""
|
|
return d
|
|
}
|