feat: add media store and store medias
This commit is contained in:
80
backend/common/media_store/store.go
Normal file
80
backend/common/media_store/store.go
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
package media_store
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Store []UUIDMap
|
||||||
|
|
||||||
|
type UUIDMap struct {
|
||||||
|
UUID string
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStore(path string) (*Store, error) {
|
||||||
|
mapFile := filepath.Join(path, "map.json")
|
||||||
|
log.Infof("read in from: %s", mapFile)
|
||||||
|
if _, err := os.Stat(mapFile); err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
if err := os.WriteFile(mapFile, []byte("[]"), os.ModePerm); err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "write file: %s", mapFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := os.ReadFile(mapFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "read file: %s", mapFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
var store Store
|
||||||
|
err = json.Unmarshal(b, &store)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "unmarshal json: %s", mapFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &store, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) Save(path string) error {
|
||||||
|
mapFile := filepath.Join(path, "map.json")
|
||||||
|
b, err := json.Marshal(s)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "marshal json: %s", mapFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.WriteFile(mapFile, b, os.ModePerm); err != nil {
|
||||||
|
return errors.Wrapf(err, "write file: %s", mapFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) Add(uuid, name string) {
|
||||||
|
*s = append(*s, UUIDMap{UUID: uuid, Name: name})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Store) UUIDs() []string {
|
||||||
|
var uuids []string
|
||||||
|
for _, m := range *s {
|
||||||
|
uuids = append(uuids, m.UUID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return uuids
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exists
|
||||||
|
func (s *Store) Exists(name string) bool {
|
||||||
|
for _, m := range *s {
|
||||||
|
if m.Name == name {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
package discover
|
package discover
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"backend/common/media_store"
|
||||||
"backend/modules/medias"
|
"backend/modules/medias"
|
||||||
|
"backend/pkg/path"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/samber/lo"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -21,11 +21,6 @@ type DiscoverMedias struct {
|
|||||||
log *log.Entry `inject:"false"`
|
log *log.Entry `inject:"false"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type MediaUuidMap struct {
|
|
||||||
UUID string
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare
|
// Prepare
|
||||||
func (d *DiscoverMedias) Prepare() error {
|
func (d *DiscoverMedias) Prepare() error {
|
||||||
d.log = log.WithField("module", "DiscoverMedias")
|
d.log = log.WithField("module", "DiscoverMedias")
|
||||||
@@ -38,36 +33,15 @@ func (d *DiscoverMedias) RunE(from, to string) error {
|
|||||||
return errors.New("from or to is empty")
|
return errors.New("from or to is empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
mapFile := filepath.Join(to, "map.json")
|
store, err := media_store.NewStore(to)
|
||||||
d.log.Infof("read in from: %s", mapFile)
|
|
||||||
if _, err := os.Stat(mapFile); err != nil {
|
|
||||||
if os.IsNotExist(err) {
|
|
||||||
if err := os.WriteFile(mapFile, []byte("[]"), os.ModePerm); err != nil {
|
|
||||||
return errors.Wrapf(err, "write file: %s", mapFile)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err := os.ReadFile(mapFile)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "read file: %s", mapFile)
|
return errors.Wrapf(err, "new store: %s", to)
|
||||||
}
|
|
||||||
|
|
||||||
var store []MediaUuidMap
|
|
||||||
err = json.Unmarshal(b, &store)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrapf(err, "unmarshal json: %s", mapFile)
|
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
d.runCleanup(to, store)
|
d.runCleanup(to)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
storeMap := make(map[string]string)
|
dirs, err := path.GetSubDirs(from)
|
||||||
for _, item := range store {
|
|
||||||
storeMap[item.Name] = item.UUID
|
|
||||||
}
|
|
||||||
|
|
||||||
dirs, err := d.getSubDirs(from)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "get sub dirs: %s", from)
|
return errors.Wrapf(err, "get sub dirs: %s", from)
|
||||||
}
|
}
|
||||||
@@ -75,7 +49,7 @@ func (d *DiscoverMedias) RunE(from, to string) error {
|
|||||||
for _, dir := range dirs {
|
for _, dir := range dirs {
|
||||||
d.log.Infof("Discover medias in: %s", dir)
|
d.log.Infof("Discover medias in: %s", dir)
|
||||||
|
|
||||||
if _, ok := storeMap[dir]; ok {
|
if exists := store.Exists(dir); exists {
|
||||||
d.log.Infof("Skip dir: %s", dir)
|
d.log.Infof("Skip dir: %s", dir)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -103,47 +77,15 @@ func (d *DiscoverMedias) RunE(from, to string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
store = append(store, MediaUuidMap{
|
store.Add(uuid, dir)
|
||||||
UUID: uuid,
|
if err := store.Save(to); err != nil {
|
||||||
Name: dir,
|
return errors.Wrapf(err, "store save: %s", to)
|
||||||
})
|
|
||||||
|
|
||||||
b, err := json.Marshal(store)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrapf(err, "marshal json: %s", mapFile)
|
|
||||||
}
|
}
|
||||||
if err := os.WriteFile(mapFile, b, os.ModePerm); err != nil {
|
|
||||||
return errors.Wrapf(err, "write file: %s", mapFile)
|
|
||||||
}
|
|
||||||
storeMap[dir] = uuid
|
|
||||||
d.log.Infof("Store map: %s", storeMap)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DiscoverMedias) getSubDirs(root string) ([]string, error) {
|
|
||||||
fd, err := os.Open(root)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(err, "open root directory: %s", root)
|
|
||||||
}
|
|
||||||
defer fd.Close()
|
|
||||||
|
|
||||||
entries, err := fd.Readdir(-1)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(err, "read root directory: %s", root)
|
|
||||||
}
|
|
||||||
|
|
||||||
var paths []string
|
|
||||||
for _, entry := range entries {
|
|
||||||
if entry.IsDir() {
|
|
||||||
paths = append(paths, entry.Name())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return paths, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *DiscoverMedias) globVideo(root string) []string {
|
func (d *DiscoverMedias) globVideo(root string) []string {
|
||||||
files := []string{}
|
files := []string{}
|
||||||
|
|
||||||
@@ -247,23 +189,27 @@ func (d *DiscoverMedias) ffmpegAudioToM3U8(input string, output string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DiscoverMedias) runCleanup(to string, store []MediaUuidMap) {
|
func (d *DiscoverMedias) runCleanup(to string) {
|
||||||
uuids := lo.Map(store, func(item MediaUuidMap, _ int) string {
|
store, err := media_store.NewStore(to)
|
||||||
return item.UUID
|
if err != nil {
|
||||||
})
|
d.log.Errorf("new store: %s", to)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
dirs, err := d.getSubDirs(to)
|
dirs, err := path.GetSubDirs(to)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
d.log.Errorf("get sub dirs: %s", to)
|
d.log.Errorf("get sub dirs: %s", to)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, dir := range dirs {
|
for _, dir := range dirs {
|
||||||
if !lo.Contains(uuids, dir) {
|
if store.Exists(dir) {
|
||||||
d.log.Infof("Remove dir: %s", dir)
|
continue
|
||||||
if err := os.RemoveAll(filepath.Join(to, dir)); err != nil {
|
}
|
||||||
d.log.Errorf("Remove dir: %s", dir)
|
|
||||||
}
|
d.log.Infof("Remove dir: %s", dir)
|
||||||
|
if err := os.RemoveAll(filepath.Join(to, dir)); err != nil {
|
||||||
|
d.log.Errorf("Remove dir: %s", dir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,15 +36,6 @@ func Test_DiscoverMedias(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *DiscoverMediasTestSuite) Test_getSubDirs() {
|
|
||||||
Convey("Test_getSubDirs", t.T(), func() {
|
|
||||||
dirs, err := t.Svc.getSubDirs("/mnt/yangpingliang/动态曲谱")
|
|
||||||
So(err, ShouldBeNil)
|
|
||||||
|
|
||||||
t.T().Logf("Dirs: %+v", dirs)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *DiscoverMediasTestSuite) Test_getVideo() {
|
func (t *DiscoverMediasTestSuite) Test_getVideo() {
|
||||||
Convey("Test_getVideo", t.T(), func() {
|
Convey("Test_getVideo", t.T(), func() {
|
||||||
dirs := t.Svc.globVideo("/mnt/yangpingliang/动态曲谱/河北梆子伴奏《李慧娘》依然还我生前摸样")
|
dirs := t.Svc.globVideo("/mnt/yangpingliang/动态曲谱/河北梆子伴奏《李慧娘》依然还我生前摸样")
|
||||||
|
|||||||
25
backend/modules/tasks/store/store_medias.go
Normal file
25
backend/modules/tasks/store/store_medias.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package store
|
||||||
|
|
||||||
|
import (
|
||||||
|
"backend/modules/medias"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
// @provider
|
||||||
|
type StoreMedias struct {
|
||||||
|
mediasSvc *medias.Service
|
||||||
|
log *log.Entry `inject:"false"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare
|
||||||
|
func (d *StoreMedias) Prepare() error {
|
||||||
|
d.log = log.WithField("module", "StoreMedias")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *StoreMedias) RunE(targetPath string) error {
|
||||||
|
d.log.Infof("Store medias from: %s ", targetPath)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
29
backend/pkg/path/fs.go
Normal file
29
backend/pkg/path/fs.go
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package path
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetSubDirs(root string) ([]string, error) {
|
||||||
|
fd, err := os.Open(root)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "open root directory: %s", root)
|
||||||
|
}
|
||||||
|
defer fd.Close()
|
||||||
|
|
||||||
|
entries, err := fd.Readdir(-1)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "read root directory: %s", root)
|
||||||
|
}
|
||||||
|
|
||||||
|
var paths []string
|
||||||
|
for _, entry := range entries {
|
||||||
|
if entry.IsDir() {
|
||||||
|
paths = append(paths, entry.Name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return paths, nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user