chore: 初始化 Cloudreve 源码仓库
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
package mediameta
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/gob"
|
||||
"errors"
|
||||
"io"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/driver"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/manager/entitysource"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/logging"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/request"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/setting"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
type (
|
||||
Extractor interface {
|
||||
// Exts returns the supported file extensions.
|
||||
Exts() []string
|
||||
// Extract extracts the media meta from the given source.
|
||||
Extract(ctx context.Context, ext string, source entitysource.EntitySource, opts ...optionFunc) ([]driver.MediaMeta, error)
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
ErrFileTooLarge = errors.New("file too large")
|
||||
)
|
||||
|
||||
func init() {
|
||||
gob.Register([]driver.MediaMeta{})
|
||||
}
|
||||
|
||||
func NewExtractorManager(ctx context.Context, settings setting.Provider, l logging.Logger, client request.Client) Extractor {
|
||||
e := &extractorManager{
|
||||
settings: settings,
|
||||
extMap: make(map[string][]Extractor),
|
||||
}
|
||||
|
||||
extractors := []Extractor{}
|
||||
|
||||
if e.settings.MediaMetaExifEnabled(ctx) {
|
||||
exifE := newExifExtractor(settings, l)
|
||||
extractors = append(extractors, exifE)
|
||||
}
|
||||
|
||||
if e.settings.MediaMetaMusicEnabled(ctx) {
|
||||
musicE := newMusicExtractor(settings, l)
|
||||
extractors = append(extractors, musicE)
|
||||
}
|
||||
|
||||
if e.settings.MediaMetaFFProbeEnabled(ctx) {
|
||||
ffprobeE := newFFProbeExtractor(settings, l)
|
||||
extractors = append(extractors, ffprobeE)
|
||||
}
|
||||
|
||||
if e.settings.MediaMetaGeocodingEnabled(ctx) {
|
||||
geocodingE := newGeocodingExtractor(settings, l, client)
|
||||
extractors = append(extractors, geocodingE)
|
||||
}
|
||||
|
||||
for _, extractor := range extractors {
|
||||
for _, ext := range extractor.Exts() {
|
||||
if e.extMap[ext] == nil {
|
||||
e.extMap[ext] = []Extractor{}
|
||||
}
|
||||
e.extMap[ext] = append(e.extMap[ext], extractor)
|
||||
}
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
type extractorManager struct {
|
||||
settings setting.Provider
|
||||
extMap map[string][]Extractor
|
||||
}
|
||||
|
||||
func (e *extractorManager) Exts() []string {
|
||||
return lo.Keys(e.extMap)
|
||||
}
|
||||
|
||||
func (e *extractorManager) Extract(ctx context.Context, ext string, source entitysource.EntitySource, opts ...optionFunc) ([]driver.MediaMeta, error) {
|
||||
if extractor, ok := e.extMap[ext]; ok {
|
||||
res := []driver.MediaMeta{}
|
||||
for _, e := range extractor {
|
||||
_, _ = source.Seek(0, io.SeekStart)
|
||||
data, err := e.Extract(ctx, ext, source, append(opts, WithExtracted(res))...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res = append(res, data...)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
} else {
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
type option struct {
|
||||
extracted []driver.MediaMeta
|
||||
language string
|
||||
}
|
||||
|
||||
type optionFunc func(*option)
|
||||
|
||||
func (f optionFunc) apply(o *option) {
|
||||
f(o)
|
||||
}
|
||||
|
||||
func WithExtracted(extracted []driver.MediaMeta) optionFunc {
|
||||
return optionFunc(func(o *option) {
|
||||
o.extracted = extracted
|
||||
})
|
||||
}
|
||||
|
||||
func WithLanguage(language string) optionFunc {
|
||||
return optionFunc(func(o *option) {
|
||||
o.language = language
|
||||
})
|
||||
}
|
||||
|
||||
// checkFileSize checks if the file size exceeds the limit.
|
||||
func checkFileSize(localLimit, remoteLimit int64, source entitysource.EntitySource) error {
|
||||
if source.IsLocal() && localLimit > 0 && source.Entity().Size() > localLimit {
|
||||
return ErrFileTooLarge
|
||||
}
|
||||
|
||||
if !source.IsLocal() && remoteLimit > 0 && source.Entity().Size() > remoteLimit {
|
||||
return ErrFileTooLarge
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user