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:
JoeSmithStarkers
2020-08-21 17:57:07 +10:00
committed by GitHub
parent 6a3588e4e0
commit 85aa1d8790
7 changed files with 70 additions and 14 deletions

View File

@@ -100,6 +100,7 @@ func (e *Encoder) run(probeResult VideoFile, args []string) (string, error) {
} }
buf := make([]byte, 80) buf := make([]byte, 80)
lastProgress := 0.0
var errBuilder strings.Builder var errBuilder strings.Builder
for { for {
n, err := stderr.Read(buf) n, err := stderr.Read(buf)
@@ -108,7 +109,11 @@ func (e *Encoder) run(probeResult VideoFile, args []string) (string, error) {
time := GetTimeFromRegex(data) time := GetTimeFromRegex(data)
if time > 0 && probeResult.Duration > 0 { if time > 0 && probeResult.Duration > 0 {
progress := time / probeResult.Duration progress := time / probeResult.Duration
logger.Infof("Progress %.2f", progress)
if progress > lastProgress+0.01 {
logger.Infof("Progress %.2f", progress)
lastProgress = progress
}
} }
errBuilder.WriteString(data) errBuilder.WriteString(data)

View File

@@ -139,7 +139,7 @@ func (g *PreviewGenerator) generateImage(encoder *ffmpeg.Encoder) error {
if err := encoder.ScenePreviewVideoToImage(g.Info.VideoFile, 640, videoPreviewPath, tmpOutputPath); err != nil { if err := encoder.ScenePreviewVideoToImage(g.Info.VideoFile, 640, videoPreviewPath, tmpOutputPath); err != nil {
return err return err
} }
if err := os.Rename(tmpOutputPath, outputPath); err != nil { if err := utils.SafeMove(tmpOutputPath, outputPath); err != nil {
return err return err
} }
logger.Debug("created video preview image: ", outputPath) logger.Debug("created video preview image: ", outputPath)

View File

@@ -6,6 +6,7 @@ import (
"image/color" "image/color"
"io/ioutil" "io/ioutil"
"math" "math"
"os"
"path/filepath" "path/filepath"
"strings" "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) 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 { if err != nil {
return err return err
} }
defer spriteImage.Close()
spriteImageName := filepath.Base(g.ImageOutputPath) spriteImageName := filepath.Base(g.ImageOutputPath)
width := spriteImage.Bounds().Size().X / g.Columns image, _, err := image.DecodeConfig(spriteImage)
height := spriteImage.Bounds().Size().Y / g.Rows width := image.Width / g.Columns
height := image.Height / g.Rows
stepSize := float64(g.Info.NthFrame) / g.Info.FrameRate stepSize := float64(g.Info.NthFrame) / g.Info.FrameRate

View File

@@ -1,7 +1,6 @@
package manager package manager
import ( import (
"os"
"path/filepath" "path/filepath"
"strconv" "strconv"
"sync" "sync"
@@ -96,7 +95,7 @@ func (t *GenerateMarkersTask) generateMarker(videoFile *ffmpeg.VideoFile, scene
if err := encoder.SceneMarkerVideo(*videoFile, options); err != nil { if err := encoder.SceneMarkerVideo(*videoFile, options); err != nil {
logger.Errorf("[generator] failed to generate marker video: %s", err) logger.Errorf("[generator] failed to generate marker video: %s", err)
} else { } else {
_ = os.Rename(options.OutputPath, videoPath) _ = utils.SafeMove(options.OutputPath, videoPath)
logger.Debug("created marker video: ", 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 { if err := encoder.SceneMarkerImage(*videoFile, options); err != nil {
logger.Errorf("[generator] failed to generate marker image: %s", err) logger.Errorf("[generator] failed to generate marker image: %s", err)
} else { } else {
_ = os.Rename(options.OutputPath, imagePath) _ = utils.SafeMove(options.OutputPath, imagePath)
logger.Debug("created marker image: ", imagePath) logger.Debug("created marker image: ", imagePath)
} }
} }

View File

@@ -42,6 +42,11 @@ func (t *ScanTask) scanGallery() {
return return
} }
// Ignore directories.
if isDir, _ := utils.DirExists(t.FilePath); isDir {
return
}
ok, err := utils.IsZipFileUncompressed(t.FilePath) ok, err := utils.IsZipFileUncompressed(t.FilePath)
if err == nil && !ok { if err == nil && !ok {
logger.Warnf("%s is using above store (0) level compression.", t.FilePath) 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() qb := models.NewGalleryQueryBuilder()
gallery, _ := qb.FindByPath(t.FilePath) gallery, _ := qb.FindByPath(t.FilePath)
if gallery == nil { if gallery == nil {
// shouldn't happen , associate is run after scan is finished // associate is run after scan is finished
logger.Errorf("associate: gallery %s not found in DB", t.FilePath) // 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() wg.Done()
return return
} }
@@ -226,6 +232,11 @@ func (t *ScanTask) scanScene() {
return return
} }
// Ignore directories.
if isDir, _ := utils.DirExists(t.FilePath); isDir {
return
}
videoFile, err := ffmpeg.NewVideoFile(instance.FFProbePath, t.FilePath) videoFile, err := ffmpeg.NewVideoFile(instance.FFProbePath, t.FilePath)
if err != nil { if err != nil {
logger.Error(err.Error()) logger.Error(err.Error())

View File

@@ -1,13 +1,12 @@
package manager package manager
import ( import (
"os"
"sync"
"github.com/stashapp/stash/pkg/ffmpeg" "github.com/stashapp/stash/pkg/ffmpeg"
"github.com/stashapp/stash/pkg/logger" "github.com/stashapp/stash/pkg/logger"
"github.com/stashapp/stash/pkg/manager/config" "github.com/stashapp/stash/pkg/manager/config"
"github.com/stashapp/stash/pkg/models" "github.com/stashapp/stash/pkg/models"
"github.com/stashapp/stash/pkg/utils"
"sync"
) )
type GenerateTranscodeTask struct { 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()) logger.Errorf("[transcode] error generating transcode: %s", err.Error())
return return
} }

View File

@@ -3,6 +3,7 @@ package utils
import ( import (
"archive/zip" "archive/zip"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"math" "math"
"net/http" "net/http"
@@ -12,6 +13,7 @@ import (
"github.com/h2non/filetype" "github.com/h2non/filetype"
"github.com/h2non/filetype/types" "github.com/h2non/filetype/types"
"github.com/stashapp/stash/pkg/logger"
) )
// FileType uses the filetype package to determine the given file path's type // FileType uses the filetype package to determine the given file path's type
@@ -131,6 +133,43 @@ func GetHomeDirectory() string {
return currentUser.HomeDir 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 // IsZipFileUnmcompressed returns true if zip file in path is using 0 compression level
func IsZipFileUncompressed(path string) (bool, error) { func IsZipFileUncompressed(path string) (bool, error) {
r, err := zip.OpenReader(path) r, err := zip.OpenReader(path)