d2/lib/pptx/validate.go
Júlio César Batista e39b9c15c2
move xml to templates
2023-04-10 13:49:30 -03:00

82 lines
2 KiB
Go

package pptx
import (
"archive/zip"
"bytes"
"encoding/xml"
"fmt"
"io"
"strings"
)
func Validate(pptxContent []byte, nSlides int) error {
reader := bytes.NewReader(pptxContent)
zipReader, err := zip.NewReader(reader, reader.Size())
if err != nil {
fmt.Printf("error reading pptx content: %v", err)
}
expectedCount := getExpectedPptxFileCount(nSlides)
if len(zipReader.File) != expectedCount {
return fmt.Errorf("expected %d files, got %d", expectedCount, len(zipReader.File))
}
for i := 0; i < nSlides; i++ {
if err := checkFile(zipReader, fmt.Sprintf("ppt/slides/slide%d.xml", i+1)); err != nil {
return err
}
if err := checkFile(zipReader, fmt.Sprintf("ppt/slides/_rels/slide%d.xml.rels", i+1)); err != nil {
return err
}
if err := checkFile(zipReader, fmt.Sprintf("ppt/media/slide%dImage.png", i+1)); err != nil {
return err
}
}
for _, file := range zipReader.File {
if !strings.Contains(file.Name, ".xml") {
continue
}
// checks if the XML content is valid
f, err := file.Open()
if err != nil {
return fmt.Errorf("error opening %s: %v", file.Name, err)
}
decoder := xml.NewDecoder(f)
for {
if err := decoder.Decode(new(interface{})); err != nil {
if err == io.EOF {
break
}
return fmt.Errorf("error parsing xml content in %s: %v", file.Name, err)
}
}
defer f.Close()
}
return nil
}
func checkFile(reader *zip.Reader, fname string) error {
f, err := reader.Open(fname)
if err != nil {
return fmt.Errorf("error opening file %s: %v", fname, err)
}
defer f.Close()
if _, err = f.Stat(); err != nil {
return fmt.Errorf("error getting file info %s: %v", fname, err)
}
return nil
}
func getExpectedPptxFileCount(nSlides int) int {
reader := bytes.NewReader(PPTX_TEMPLATE)
zipReader, err := zip.NewReader(reader, reader.Size())
if err != nil {
return -1
}
baseFiles := len(zipReader.File)
presentationFiles := 5 // presentation, rels, app, core, content types
slideFiles := 3 * nSlides // slides, rels, images
return baseFiles + presentationFiles + slideFiles
}