contentserver/repo/history.go
2019-05-27 12:11:16 +02:00

110 lines
2.3 KiB
Go

package repo
import (
"bytes"
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"path"
"sort"
"strings"
"time"
)
const (
historyRepoJSONPrefix = "contentserver-repo-"
historyRepoJSONSuffix = ".json"
maxHistoryVersions = 20
)
type history struct {
varDir string
}
func newHistory(varDir string) *history {
return &history{
varDir: varDir,
}
}
func (h *history) add(jsonBytes []byte) error {
var (
// historiy file name
filename = path.Join(h.varDir, historyRepoJSONPrefix+time.Now().Format(time.RFC3339Nano)+historyRepoJSONSuffix)
err = ioutil.WriteFile(filename, jsonBytes, 0644)
)
if err != nil {
return err
}
// current filename
return ioutil.WriteFile(h.getCurrentFilename(), jsonBytes, 0644)
}
func (h *history) getHistory() (files []string, err error) {
fileInfos, err := ioutil.ReadDir(h.varDir)
if err != nil {
return
}
currentName := h.getCurrentFilename()
for _, f := range fileInfos {
if !f.IsDir() {
filename := f.Name()
if filename != currentName && (strings.HasPrefix(filename, historyRepoJSONPrefix) && strings.HasSuffix(filename, historyRepoJSONSuffix)) {
files = append(files, path.Join(h.varDir, filename))
}
}
}
sort.Sort(sort.Reverse(sort.StringSlice(files)))
return
}
func (h *history) cleanup() error {
files, err := h.getFilesForCleanup(maxHistoryVersions)
if err != nil {
return err
}
for _, f := range files {
err := os.Remove(f)
if err != nil {
return fmt.Errorf("could not remove file %s : %s", f, err.Error())
}
}
return nil
}
func (h *history) getFilesForCleanup(historyVersions int) (files []string, err error) {
contentFiles, err := h.getHistory()
if err != nil {
return nil, errors.New("could not generate file cleanup list: " + err.Error())
}
if len(contentFiles) > historyVersions {
for i := historyVersions; i < len(contentFiles); i++ {
// ignore current repository file to fall back on
if contentFiles[i] == h.getCurrentFilename() {
continue
}
files = append(files, contentFiles[i])
}
}
return files, nil
}
func (h *history) getCurrentFilename() string {
return path.Join(h.varDir, historyRepoJSONPrefix+"current"+historyRepoJSONSuffix)
}
func (h *history) getCurrent(buf *bytes.Buffer) (err error) {
f, err := os.Open(h.getCurrentFilename())
if err != nil {
return err
}
defer f.Close()
_, err = io.Copy(buf, f)
return err
}