2024-01-05 17:54:41 +01:00

88 lines
1.7 KiB
Go

/*
Helper to write EPUB files.
We create a zip with the magic EPUB mimetype.
*/
package epubzip
import (
"archive/zip"
"os"
"time"
)
type EPUBZip struct {
w *os.File
wz *zip.Writer
}
// create a new EPUB
func New(path string) (*EPUBZip, error) {
w, err := os.Create(path)
if err != nil {
return nil, err
}
wz := zip.NewWriter(w)
return &EPUBZip{w, wz}, nil
}
// close compress pipe and file.
func (e *EPUBZip) Close() error {
if err := e.wz.Close(); err != nil {
return err
}
return e.w.Close()
}
// Write mimetype, in a very specific way.
// This will be valid with epubcheck tools.
func (e *EPUBZip) WriteMagic() error {
t := time.Now()
fh := &zip.FileHeader{
Name: "mimetype",
Method: zip.Store,
Modified: t,
ModifiedTime: uint16(t.Second()/2 + t.Minute()<<5 + t.Hour()<<11),
ModifiedDate: uint16(t.Day() + int(t.Month())<<5 + (t.Year()-1980)<<9),
CompressedSize64: 20,
UncompressedSize64: 20,
CRC32: 0x2cab616f,
}
fh.SetMode(0600)
m, err := e.wz.CreateRaw(fh)
if err != nil {
return err
}
_, err = m.Write([]byte("application/epub+zip"))
return err
}
func (e *EPUBZip) Copy(fz *zip.File) error {
return e.wz.Copy(fz)
}
// Write image. They are already compressed, so we write them down directly.
func (e *EPUBZip) WriteRaw(raw *EPUBZipImage) error {
m, err := e.wz.CreateRaw(raw.Header)
if err != nil {
return err
}
_, err = m.Write(raw.Data)
return err
}
// Write file. Compressed it using deflate.
func (e *EPUBZip) WriteContent(file string, content []byte) error {
m, err := e.wz.CreateHeader(&zip.FileHeader{
Name: file,
Modified: time.Now(),
Method: zip.Deflate,
})
if err != nil {
return err
}
_, err = m.Write(content)
return err
}