mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 20:34:37 +03:00
Replace os.Rename with util.SafeMove to allow cross device moving to not fail. (#745)
Fixed annoyingly noisy transcoding progress log messages. Fixed minor minor issue with directories than are named "blah.mp4" being detected as files to be scanned.
This commit is contained in:
@@ -100,6 +100,7 @@ func (e *Encoder) run(probeResult VideoFile, args []string) (string, error) {
|
||||
}
|
||||
|
||||
buf := make([]byte, 80)
|
||||
lastProgress := 0.0
|
||||
var errBuilder strings.Builder
|
||||
for {
|
||||
n, err := stderr.Read(buf)
|
||||
@@ -108,7 +109,11 @@ func (e *Encoder) run(probeResult VideoFile, args []string) (string, error) {
|
||||
time := GetTimeFromRegex(data)
|
||||
if time > 0 && probeResult.Duration > 0 {
|
||||
progress := time / probeResult.Duration
|
||||
logger.Infof("Progress %.2f", progress)
|
||||
|
||||
if progress > lastProgress+0.01 {
|
||||
logger.Infof("Progress %.2f", progress)
|
||||
lastProgress = progress
|
||||
}
|
||||
}
|
||||
|
||||
errBuilder.WriteString(data)
|
||||
|
||||
@@ -139,7 +139,7 @@ func (g *PreviewGenerator) generateImage(encoder *ffmpeg.Encoder) error {
|
||||
if err := encoder.ScenePreviewVideoToImage(g.Info.VideoFile, 640, videoPreviewPath, tmpOutputPath); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.Rename(tmpOutputPath, outputPath); err != nil {
|
||||
if err := utils.SafeMove(tmpOutputPath, outputPath); err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Debug("created video preview image: ", outputPath)
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"image/color"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
@@ -120,13 +121,15 @@ func (g *SpriteGenerator) generateSpriteVTT(encoder *ffmpeg.Encoder) error {
|
||||
}
|
||||
logger.Infof("[generator] generating sprite vtt for %s", g.Info.VideoFile.Path)
|
||||
|
||||
spriteImage, err := imaging.Open(g.ImageOutputPath)
|
||||
spriteImage, err := os.Open(g.ImageOutputPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer spriteImage.Close()
|
||||
spriteImageName := filepath.Base(g.ImageOutputPath)
|
||||
width := spriteImage.Bounds().Size().X / g.Columns
|
||||
height := spriteImage.Bounds().Size().Y / g.Rows
|
||||
image, _, err := image.DecodeConfig(spriteImage)
|
||||
width := image.Width / g.Columns
|
||||
height := image.Height / g.Rows
|
||||
|
||||
stepSize := float64(g.Info.NthFrame) / g.Info.FrameRate
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package manager
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"sync"
|
||||
@@ -96,7 +95,7 @@ func (t *GenerateMarkersTask) generateMarker(videoFile *ffmpeg.VideoFile, scene
|
||||
if err := encoder.SceneMarkerVideo(*videoFile, options); err != nil {
|
||||
logger.Errorf("[generator] failed to generate marker video: %s", err)
|
||||
} else {
|
||||
_ = os.Rename(options.OutputPath, videoPath)
|
||||
_ = utils.SafeMove(options.OutputPath, videoPath)
|
||||
logger.Debug("created marker video: ", videoPath)
|
||||
}
|
||||
}
|
||||
@@ -109,7 +108,7 @@ func (t *GenerateMarkersTask) generateMarker(videoFile *ffmpeg.VideoFile, scene
|
||||
if err := encoder.SceneMarkerImage(*videoFile, options); err != nil {
|
||||
logger.Errorf("[generator] failed to generate marker image: %s", err)
|
||||
} else {
|
||||
_ = os.Rename(options.OutputPath, imagePath)
|
||||
_ = utils.SafeMove(options.OutputPath, imagePath)
|
||||
logger.Debug("created marker image: ", imagePath)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,11 @@ func (t *ScanTask) scanGallery() {
|
||||
return
|
||||
}
|
||||
|
||||
// Ignore directories.
|
||||
if isDir, _ := utils.DirExists(t.FilePath); isDir {
|
||||
return
|
||||
}
|
||||
|
||||
ok, err := utils.IsZipFileUncompressed(t.FilePath)
|
||||
if err == nil && !ok {
|
||||
logger.Warnf("%s is using above store (0) level compression.", t.FilePath)
|
||||
@@ -95,8 +100,9 @@ func (t *ScanTask) associateGallery(wg *sync.WaitGroup) {
|
||||
qb := models.NewGalleryQueryBuilder()
|
||||
gallery, _ := qb.FindByPath(t.FilePath)
|
||||
if gallery == nil {
|
||||
// shouldn't happen , associate is run after scan is finished
|
||||
logger.Errorf("associate: gallery %s not found in DB", t.FilePath)
|
||||
// associate is run after scan is finished
|
||||
// should only happen if gallery is a directory or an io error occurs during hashing
|
||||
logger.Warnf("associate: gallery %s not found in DB", t.FilePath)
|
||||
wg.Done()
|
||||
return
|
||||
}
|
||||
@@ -226,6 +232,11 @@ func (t *ScanTask) scanScene() {
|
||||
return
|
||||
}
|
||||
|
||||
// Ignore directories.
|
||||
if isDir, _ := utils.DirExists(t.FilePath); isDir {
|
||||
return
|
||||
}
|
||||
|
||||
videoFile, err := ffmpeg.NewVideoFile(instance.FFProbePath, t.FilePath)
|
||||
if err != nil {
|
||||
logger.Error(err.Error())
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
package manager
|
||||
|
||||
import (
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"github.com/stashapp/stash/pkg/ffmpeg"
|
||||
"github.com/stashapp/stash/pkg/logger"
|
||||
"github.com/stashapp/stash/pkg/manager/config"
|
||||
"github.com/stashapp/stash/pkg/models"
|
||||
"github.com/stashapp/stash/pkg/utils"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type GenerateTranscodeTask struct {
|
||||
@@ -79,7 +78,7 @@ func (t *GenerateTranscodeTask) Start(wg *sync.WaitGroup) {
|
||||
}
|
||||
}
|
||||
|
||||
if err := os.Rename(outputPath, instance.Paths.Scene.GetTranscodePath(sceneHash)); err != nil {
|
||||
if err := utils.SafeMove(outputPath, instance.Paths.Scene.GetTranscodePath(sceneHash)); err != nil {
|
||||
logger.Errorf("[transcode] error generating transcode: %s", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package utils
|
||||
import (
|
||||
"archive/zip"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"net/http"
|
||||
@@ -12,6 +13,7 @@ import (
|
||||
|
||||
"github.com/h2non/filetype"
|
||||
"github.com/h2non/filetype/types"
|
||||
"github.com/stashapp/stash/pkg/logger"
|
||||
)
|
||||
|
||||
// FileType uses the filetype package to determine the given file path's type
|
||||
@@ -131,6 +133,43 @@ func GetHomeDirectory() string {
|
||||
return currentUser.HomeDir
|
||||
}
|
||||
|
||||
func SafeMove(src, dst string) error {
|
||||
err := os.Rename(src, dst)
|
||||
|
||||
if err != nil {
|
||||
logger.Errorf("[Util] unable to rename: \"%s\" due to %s. Falling back to copying.", src, err.Error())
|
||||
|
||||
in, err := os.Open(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer in.Close()
|
||||
|
||||
out, err := os.Create(dst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
_, err = io.Copy(out, in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = out.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = os.Remove(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsZipFileUnmcompressed returns true if zip file in path is using 0 compression level
|
||||
func IsZipFileUncompressed(path string) (bool, error) {
|
||||
r, err := zip.OpenReader(path)
|
||||
|
||||
Reference in New Issue
Block a user