mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 12:24:38 +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)
|
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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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())
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user