Files
remark42/backend/app/migrator/migrator.go
T

88 lines
2.7 KiB
Go

// Package migrator provides import/export functionality. It defines Importer and Exporter interfaces
// amd implements for disqus (importer only) and "native" remark (both importer and exporter).
// Also implements AutoBackup scheduler running exports as backups and saving them locally.
package migrator
import (
"io"
"os"
log "github.com/go-pkgz/lgr"
"github.com/pkg/errors"
"github.com/umputun/remark42/backend/app/store"
"github.com/umputun/remark42/backend/app/store/service"
)
// Importer defines interface to convert posts from external sources
type Importer interface {
Import(r io.Reader, siteID string) (int, error)
}
// Exporter defines interface to export comments from internal store
type Exporter interface {
Export(w io.Writer, siteID string) (int, error)
}
// Mapper defines interface to convert data in import procedure
type Mapper interface {
URL(url string) string
}
// MapperMaker defines function that reads rules from reader and
// returns new Mapper with loaded rules. If rules are not valid
// it returns error.
type MapperMaker func(reader io.Reader) (Mapper, error)
// Store defines minimal interface needed to export and import comments
type Store interface {
Create(comment store.Comment) (commentID string, err error)
Find(locator store.Locator, sort string, user store.User) ([]store.Comment, error)
List(siteID string, limit int, skip int) ([]store.PostInfo, error)
DeleteAll(siteID string) error
Metas(siteID string) (umetas []service.UserMetaData, pmetas []service.PostMetaData, err error)
SetMetas(siteID string, umetas []service.UserMetaData, pmetas []service.PostMetaData) error
}
// ImportParams defines everything needed to run import
type ImportParams struct {
DataStore Store
InputFile string
Provider string
SiteID string
}
var adminUser = store.User{Admin: true}
// ImportComments imports from given provider format and saves to store
func ImportComments(p ImportParams) (int, error) {
log.Printf("[INFO] import from %s (%s) to %s", p.InputFile, p.Provider, p.SiteID)
var importer Importer
switch p.Provider {
case "disqus":
importer = &Disqus{DataStore: p.DataStore}
case "wordpress":
importer = &WordPress{DataStore: p.DataStore}
case "commento":
importer = &Commento{DataStore: p.DataStore}
case "native":
importer = &Native{DataStore: p.DataStore}
default:
return 0, errors.Errorf("unsupported import provider %s", p.Provider)
}
fh, err := os.Open(p.InputFile)
if err != nil {
return 0, errors.Wrapf(err, "can't open import file %s", p.InputFile)
}
defer func() {
if err = fh.Close(); err != nil {
log.Printf("[WARN] can't close %s, %s", p.InputFile, err)
}
}()
return importer.Import(fh, p.SiteID)
}