New instructions since newest go version does not work well with v1 of linters
This commit is contained in:
Bob 2026-04-26 22:01:07 -07:00
parent 361e514f79
commit b06200adf5
8 changed files with 20 additions and 220 deletions

View file

@ -3,6 +3,7 @@
## Pre-requisites
* [Go](https://golang.org/dl/)
* Version 1.24.* (v1.26.x is unable to run the linter)
* [GolangCI](https://golangci-lint.run/) - A meta-linter which runs several linters in parallel
* To install, follow the [local installation instructions](https://golangci-lint.run/welcome/install/#local-installation)
* Install v1, NOT v2

View file

@ -636,13 +636,14 @@ func (f *scanFilter) Accept(ctx context.Context, path string, info fs.FileInfo,
return false
}
if isVideoFile && (s.ExcludeVideo || matchFileRegex(path, f.videoExcludeRegex)) {
switch {
case isVideoFile && (s.ExcludeVideo || matchFileRegex(path, f.videoExcludeRegex)):
logger.Debugf("Skipping %s as it matches video exclusion patterns", path)
return false
} else if isAudioFile && (s.ExcludeAudio || matchFileRegex(path, f.audioExcludeRegex)) {
case isAudioFile && (s.ExcludeAudio || matchFileRegex(path, f.audioExcludeRegex)):
logger.Debugf("Skipping %s as it matches audio exclusion patterns", path)
return false
} else if (isImageFile || isZipFile) && (s.ExcludeImage || matchFileRegex(path, f.imageExcludeRegex)) {
case (isImageFile || isZipFile) && (s.ExcludeImage || matchFileRegex(path, f.imageExcludeRegex)):
logger.Debugf("Skipping %s as it matches image exclusion patterns", path)
return false
}

View file

@ -5,7 +5,6 @@ package audio
import (
"context"
"fmt"
"math"
"github.com/stashapp/stash/pkg/models"
"github.com/stashapp/stash/pkg/models/json"
@ -169,17 +168,3 @@ func GetDependentGroupIDs(ctx context.Context, audio *models.Audio) ([]int, erro
return ret, nil
}
func getPrecision(num float64) int {
if num == 0 {
return 0
}
e := 1.0
p := 0
for (math.Round(num*e) / e) != num {
e *= 10
p++
}
return p
}

View file

@ -1,169 +0,0 @@
// TODO(audio): this file is currently not used, DELETE when you know it isn't needed
// Package generate provides functions to generate media assets from audios.
package generate
import (
"bytes"
"errors"
"fmt"
"os"
"os/exec"
"strings"
"github.com/stashapp/stash/pkg/ffmpeg"
"github.com/stashapp/stash/pkg/fsutil"
)
const (
mp3Pattern = "*.mp3"
jpgPattern = "*.jpg"
txtPattern = "*.txt"
)
type Paths interface {
TempFile(pattern string) (*os.File, error)
}
type AudioPaths interface {
Paths
GetTranscodePath(checksum string) string
}
type FFMpegConfig interface {
GetTranscodeInputArgs() []string
GetTranscodeOutputArgs() []string
}
type Generator struct {
Encoder *ffmpeg.FFMpeg
FFMpegConfig FFMpegConfig
LockManager *fsutil.ReadLockManager
AudioPaths AudioPaths
Overwrite bool
}
type generateFn func(lockCtx *fsutil.LockContext, tmpFn string) error
func (g Generator) tempFile(p Paths, pattern string) (*os.File, error) {
tmpFile, err := p.TempFile(pattern) // tmp output in case the process ends abruptly
if err != nil {
return nil, fmt.Errorf("creating temporary file: %w", err)
}
_ = tmpFile.Close()
return tmpFile, err
}
// generateFile performs a generate operation by generating a temporary file using p and pattern, then
// moving it to output on success.
func (g Generator) generateFile(lockCtx *fsutil.LockContext, p Paths, pattern string, output string, generateFn generateFn) error {
tmpFile, err := g.tempFile(p, pattern) // tmp output in case the process ends abruptly
if err != nil {
return err
}
tmpFn := tmpFile.Name()
defer func() {
_ = os.Remove(tmpFn)
}()
if err := generateFn(lockCtx, tmpFn); err != nil {
return err
}
// check if generated empty file
stat, err := os.Stat(tmpFn)
if err != nil {
return fmt.Errorf("error getting file stat: %w", err)
}
if stat.Size() == 0 {
return fmt.Errorf("ffmpeg command produced no output")
}
if err := fsutil.SafeMove(tmpFn, output); err != nil {
return fmt.Errorf("moving %s to %s failed: %w", tmpFn, output, err)
}
return nil
}
// generateBytes performs a generate operation by generating a temporary file using p and pattern, returns the contents, then deletes it.
func (g Generator) generateBytes(lockCtx *fsutil.LockContext, p Paths, pattern string, generateFn generateFn) ([]byte, error) {
tmpFile, err := g.tempFile(p, pattern) // tmp output in case the process ends abruptly
if err != nil {
return nil, err
}
tmpFn := tmpFile.Name()
defer func() {
_ = os.Remove(tmpFn)
}()
if err := generateFn(lockCtx, tmpFn); err != nil {
return nil, err
}
defer os.Remove(tmpFn)
return os.ReadFile(tmpFn)
}
// generate runs ffmpeg with the given args and waits for it to finish.
// Returns an error if the command fails. If the command fails, the return
// value will be of type *exec.ExitError.
func (g Generator) generate(ctx *fsutil.LockContext, args []string) error {
cmd := g.Encoder.Command(ctx, args)
var stderr bytes.Buffer
cmd.Stderr = &stderr
if err := cmd.Start(); err != nil {
return fmt.Errorf("error starting command: %w", err)
}
ctx.AttachCommand(cmd)
if err := cmd.Wait(); err != nil {
var exitErr *exec.ExitError
if errors.As(err, &exitErr) {
exitErr.Stderr = stderr.Bytes()
err = exitErr
}
return fmt.Errorf("error running ffmpeg command <%s>: %w", strings.Join(args, " "), err)
}
return nil
}
// GenerateOutput runs ffmpeg with the given args and returns it standard output.
func (g Generator) generateOutput(lockCtx *fsutil.LockContext, args []string) ([]byte, error) {
cmd := g.Encoder.Command(lockCtx, args)
var stdout bytes.Buffer
cmd.Stdout = &stdout
var stderr bytes.Buffer
cmd.Stderr = &stderr
if err := cmd.Start(); err != nil {
return nil, fmt.Errorf("error starting command: %w", err)
}
lockCtx.AttachCommand(cmd)
if err := cmd.Wait(); err != nil {
var exitErr *exec.ExitError
if errors.As(err, &exitErr) {
exitErr.Stderr = stderr.Bytes()
err = exitErr
}
return nil, fmt.Errorf("error running ffmpeg command <%s>: %w", strings.Join(args, " "), err)
}
if stdout.Len() == 0 {
return nil, fmt.Errorf("ffmpeg command produced no output: <%s>", strings.Join(args, " "))
}
return stdout.Bytes(), nil
}

View file

@ -37,18 +37,3 @@ func migrateAudioFiles(oldName, newName string) {
}
}
}
func migrateAudioFolder(oldName, newName string) {
oldExists, err := fsutil.DirExists(oldName)
if err != nil && !os.IsNotExist(err) {
logger.Errorf("Error checking existence of %s: %s", oldName, err.Error())
return
}
if oldExists {
logger.Infof("renaming %s to %s", oldName, newName)
if err := os.Rename(oldName, newName); err != nil {
logger.Errorf("error renaming %s to %s: %s", oldName, newName, err.Error())
}
}
}

View file

@ -119,7 +119,7 @@ func (h *ScanHandler) Handle(ctx context.Context, f models.File, oldFile models.
h.PluginCache.RegisterPostHooks(ctx, newAudio.ID, hook.AudioCreatePost, nil, nil)
existing = []*models.Audio{&newAudio}
// existing = []*models.Audio{&newAudio}
}
if oldFile != nil {

View file

@ -58,26 +58,25 @@ func isValidCodec(codecName string, supportedCodecs []string) bool {
return false
}
func isValidAudio(audio ProbeAudioCodec, validCodecs []ProbeAudioCodec) bool {
// if audio codec is missing or unsupported by ffmpeg we can't do anything about it
// report it as valid so that the file can at least be streamed directly if the video codec is supported
if audio == MissingUnsupported {
return true
}
// func isValidAudio(audio ProbeAudioCodec, validCodecs []ProbeAudioCodec) bool {
// // if audio codec is missing or unsupported by ffmpeg we can't do anything about it
// // report it as valid so that the file can at least be streamed directly if the video codec is supported
// if audio == MissingUnsupported {
// return true
// }
for _, c := range validCodecs {
if c == audio {
return true
}
}
// for _, c := range validCodecs {
// if c == audio {
// return true
// }
// }
return false
}
// return false
// }
// IsValidAudioForContainer returns true if the audio codec is valid for the container.
func IsValidAudioForContainer(audio ProbeAudioCodec, format Container) bool {
switch format {
case Mp3Container:
if format == Mp3Container {
return true
// TODO(audio): do we need to check ProbeAudioCodec for audio containers?
// return isValidAudio(audio, validAudioForMp3)

View file

@ -284,8 +284,6 @@ var (
fkColumn: audiosPerformersJoinTable.Col(performerIDColumn),
}
audiosGalleriesTableMgr = galleriesScenesTableMgr.invert()
audiosGroupsTableMgr = &audiosGroupsTable{
table: table{
table: audiosGroupsJoinTable,