website/pkg/models/exporting/exporting.go

74 lines
1.7 KiB
Go

package exporting
import (
"archive/zip"
"encoding/json"
"errors"
"fmt"
"os"
"path"
"strings"
"code.nonshy.com/nonshy/website/pkg/log"
"code.nonshy.com/nonshy/website/pkg/models"
"code.nonshy.com/nonshy/website/pkg/photo"
)
// ExportUser creates a data export archive of ALL data stored about a user account..
func ExportUser(user *models.User, filename string) error {
if !strings.HasSuffix(filename, ".zip") {
return errors.New("output file should be a .zip file")
}
// Prepare the output zip writer.
fh, err := os.Create(filename)
if err != nil {
return fmt.Errorf("creating output file (%s): %s", filename, err)
}
zw := zip.NewWriter(fh)
defer zw.Close()
// Export all their database tables into the zip.
return ExportModels(zw, user)
}
// ZipJson serializes a JSON file into the zipfile.
func ZipJson(zw *zip.Writer, filename string, v any) error {
fh, err := zw.Create(filename)
if err != nil {
return err
}
encoder := json.NewEncoder(fh)
encoder.SetIndent("", " ")
return encoder.Encode(v)
}
// ZipPhoto copies a user photo into the ZIP archive.
func ZipPhoto(zw *zip.Writer, prefix, filename string) error {
var (
diskPath = photo.DiskPath(filename)
data, err = os.ReadFile(diskPath)
)
if err != nil {
if os.IsNotExist(err) {
// Not fatal but log it.
log.Error("ZipPhoto(%s): read from disk: %s", diskPath, err)
return nil
}
return fmt.Errorf("ZipPhoto(%s): read from disk: %s", diskPath, err)
}
outfh, err := zw.Create(path.Join(prefix, filename))
if err != nil {
return fmt.Errorf("ZipPhoto(%s): create in zip: %s", filename, err)
}
log.Info("Add photo to zip: %s", filename)
_, err = outfh.Write(data)
return err
}