83 lines
2 KiB
Go
83 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
|
||
|
|
}
|