Files
comicverse/editor/editor.go

115 lines
2.2 KiB
Go
Raw Normal View History

package editor
import (
"context"
"encoding/xml"
"errors"
"fmt"
"io"
"log/slog"
"sync"
"time"
"code.capytal.cc/capytal/comicverse/editor/epub"
"code.capytal.cc/capytal/comicverse/editor/storage"
"code.capytal.cc/loreddev/x/tinyssert"
"github.com/google/uuid"
"golang.org/x/text/language"
)
func New(
storage storage.Storage,
logger *slog.Logger,
assert tinyssert.Assertions,
) *Editor {
assert.NotZero(storage)
assert.NotZero(logger)
return &Editor{
storage: storage,
log: logger,
assert: assert,
}
}
type Editor struct {
storage storage.Storage
ctx context.Context
log *slog.Logger
assert tinyssert.Assertions
}
func (e *Editor) New(id uuid.UUID, title string, lang language.Tag) (*Container, error) {
f := fmt.Sprintf("%s/content.opf", id)
if e.storage.Exists(f) {
return nil, ErrAlreadyExists
}
pub := &Container{
id: id,
pkg: epub.Package{
Metadata: epub.Metadata{
ID: fmt.Sprintf("comicverse:%s", id),
Title: title,
Language: lang,
Date: time.Now(),
Modified: time.Now(),
},
},
log: e.log.WithGroup(fmt.Sprintf("publication:%s", id)),
assert: e.assert,
storage: storage.WithRoot(id.String(), e.storage),
}
err := pub.Flush()
if err != nil {
return nil, fmt.Errorf("editor: unable to flush changes of publication: %w", err)
}
return pub, nil
}
func (e *Editor) Open(id uuid.UUID) (*Container, error) {
content, err := e.storage.Open(fmt.Sprintf("%s/content.opf", id))
if errors.Is(err, storage.ErrNotExists) {
return nil, ErrNotExists
} else if err != nil {
return nil, fmt.Errorf("editor: unable to open package: %w", err)
}
b, err := io.ReadAll(content)
if err != nil {
return nil, fmt.Errorf("editor: unable to read contents of package: %w", err)
}
var pkg epub.Package
err = xml.Unmarshal(b, &pkg)
if err != nil {
return nil, fmt.Errorf("editor: unable to decode xml of package: %w", err)
}
c := &Container{
id: id,
pkg: pkg,
log: e.log.WithGroup(fmt.Sprintf("publication:%s", id)),
assert: e.assert,
storage: storage.WithRoot(id.String(), e.storage),
}
return c, nil
}
var (
ErrAlreadyExists = errors.New("editor: file already exists")
ErrNotExists = errors.New("editor: file doesn't exist")
)