remove globals

This commit is contained in:
sentriz
2020-05-03 04:43:00 +01:00
parent 9bf80f4b18
commit ee9335f71e
11 changed files with 188 additions and 163 deletions

View File

@@ -236,6 +236,7 @@ type Flash struct {
Type FlashType
}
//nolint:gochecknoinits
func init() {
gob.Register(&Flash{})
}

View File

@@ -82,7 +82,7 @@ func (c *Controller) ServeHome(r *http.Request) *Response {
c.DB.
Where("user_id=?", user.ID).
Find(&data.TranscodePreferences)
for profile := range encode.Profiles {
for profile := range encode.Profiles() {
data.TranscodeProfiles = append(data.TranscodeProfiles, profile)
}
//

View File

@@ -72,7 +72,7 @@ func serveTrackRaw(w http.ResponseWriter, r *http.Request, opts serveTrackOption
}
func serveTrackEncode(w http.ResponseWriter, r *http.Request, opts serveTrackOptions) {
profile := encode.Profiles[opts.pref.Profile]
profile := encode.Profiles()[opts.pref.Profile]
bitrate := encode.GetBitrate(opts.maxBitrate, profile)
trackPath := path.Join(opts.musicPath, opts.track.RelPath())
cacheKey := encode.CacheKey(trackPath, opts.pref.Profile, bitrate)

View File

@@ -7,7 +7,7 @@ import (
"go.senan.xyz/gonic/version"
)
var (
const (
apiVersion = "1.9.0"
xmlns = "http://subsonic.org/restapi"
)

View File

@@ -31,9 +31,8 @@ func wrapMigrations(migrs ...gormigrate.Migration) []*gormigrate.Migration {
return ret
}
var (
dbMaxOpenConns = 1
dbOptions = url.Values{
func defaultOptions() url.Values {
return url.Values{
// with this, multiple connections share a single data and schema cache.
// see https://www.sqlite.org/sharedcache.html
"cache": {"shared"},
@@ -43,7 +42,7 @@ var (
"_journal_mode": {"WAL"},
"_foreign_keys": {"true"},
}
)
}
type DB struct {
*gorm.DB
@@ -55,13 +54,13 @@ func New(path string) (*DB, error) {
Scheme: "file",
Opaque: path,
}
url.RawQuery = dbOptions.Encode()
url.RawQuery = defaultOptions().Encode()
db, err := gorm.Open("sqlite3", url.String())
if err != nil {
return nil, fmt.Errorf("with gorm: %w", err)
}
db.SetLogger(log.New(os.Stdout, "gorm ", 0))
db.DB().SetMaxOpenConns(dbMaxOpenConns)
db.DB().SetMaxOpenConns(1)
migrOptions := &gormigrate.Options{
TableName: "migrations",
IDColumnName: "id",
@@ -69,13 +68,13 @@ func New(path string) (*DB, error) {
UseTransaction: false,
}
migr := gormigrate.New(db, migrOptions, wrapMigrations(
migrationInitSchema,
migrationCreateInitUser,
migrationMergePlaylist,
migrationCreateTranscode,
migrationAddGenre,
migrationUpdateTranscodePrefIDX,
migrationAddAlbumIDX,
migrateInitSchema(),
migrateCreateInitUser(),
migrateMergePlaylist(),
migrateCreateTranscode(),
migrateAddGenre(),
migrateUpdateTranscodePrefIDX(),
migrateAddAlbumIDX(),
))
if err = migr.Migrate(); err != nil {
return nil, fmt.Errorf("migrating to latest version: %w", err)

View File

@@ -9,8 +9,8 @@ import (
// $ date '+%Y%m%d%H%M'
// not really a migration
var migrationInitSchema = gormigrate.Migration{
func migrateInitSchema() gormigrate.Migration {
return gormigrate.Migration{
ID: "202002192100",
Migrate: func(tx *gorm.DB) error {
return tx.AutoMigrate(
@@ -26,9 +26,10 @@ var migrationInitSchema = gormigrate.Migration{
Error
},
}
}
// not really a migration
var migrationCreateInitUser = gormigrate.Migration{
func migrateCreateInitUser() gormigrate.Migration {
return gormigrate.Migration{
ID: "202002192019",
Migrate: func(tx *gorm.DB) error {
const (
@@ -50,8 +51,10 @@ var migrationCreateInitUser = gormigrate.Migration{
Error
},
}
}
var migrationMergePlaylist = gormigrate.Migration{
func migrateMergePlaylist() gormigrate.Migration {
return gormigrate.Migration{
ID: "202002192222",
Migrate: func(tx *gorm.DB) error {
if !tx.HasTable("playlist_items") {
@@ -70,8 +73,10 @@ var migrationMergePlaylist = gormigrate.Migration{
Error
},
}
}
var migrationCreateTranscode = gormigrate.Migration{
func migrateCreateTranscode() gormigrate.Migration {
return gormigrate.Migration{
ID: "202003111222",
Migrate: func(tx *gorm.DB) error {
return tx.AutoMigrate(
@@ -80,8 +85,10 @@ var migrationCreateTranscode = gormigrate.Migration{
Error
},
}
}
var migrationAddGenre = gormigrate.Migration{
func migrateAddGenre() gormigrate.Migration {
return gormigrate.Migration{
ID: "202003121330",
Migrate: func(tx *gorm.DB) error {
return tx.AutoMigrate(
@@ -92,8 +99,10 @@ var migrationAddGenre = gormigrate.Migration{
Error
},
}
}
var migrationUpdateTranscodePrefIDX = gormigrate.Migration{
func migrateUpdateTranscodePrefIDX() gormigrate.Migration {
return gormigrate.Migration{
ID: "202003241509",
Migrate: func(tx *gorm.DB) error {
var hasIDX int
@@ -131,8 +140,10 @@ var migrationUpdateTranscodePrefIDX = gormigrate.Migration{
return nil
},
}
}
var migrationAddAlbumIDX = gormigrate.Migration{
func migrateAddAlbumIDX() gormigrate.Migration {
return gormigrate.Migration{
ID: "202004302006",
Migrate: func(tx *gorm.DB) error {
return tx.AutoMigrate(
@@ -141,3 +152,4 @@ var migrationAddAlbumIDX = gormigrate.Migration{
Error
},
}
}

View File

@@ -94,8 +94,8 @@ func (t *Track) Ext() string {
}
func (t *Track) MIME() string {
ext := t.Ext()
return mime.Types[ext]
v, _ := mime.FromExtension(t.Ext())
return v
}
func (t *Track) RelPath() string {

View File

@@ -13,6 +13,10 @@ import (
"github.com/cespare/xxhash"
)
const (
buffLen = 4096
)
type Profile struct {
Format string
Bitrate int
@@ -20,15 +24,14 @@ type Profile struct {
forceRG bool
}
var (
Profiles = map[string]*Profile{
func Profiles() map[string]Profile {
return map[string]Profile{
"mp3": {"mp3", 128, []string{"-c:a", "libmp3lame"}, false},
"mp3_rg": {"mp3", 128, []string{"-c:a", "libmp3lame"}, true},
"opus": {"opus", 96, []string{"-c:a", "libopus", "-vbr", "constrained"}, false},
"opus_rg": {"opus", 96, []string{"-c:a", "libopus", "-vbr", "constrained"}, true},
}
bufLen = 4096
)
}
// copy command output to http response body using io.copy (simpler, but may increase ttfb)
//nolint:deadcode,unused
@@ -45,7 +48,7 @@ func copyCmdOutput(out, cache io.Writer, pipeReader io.Reader) {
// copy command output to http response manually with a buffer (should reduce ttfb)
//nolint:deadcode,unused
func writeCmdOutput(out, cache io.Writer, pipeReader io.ReadCloser) {
buffer := make([]byte, bufLen)
buffer := make([]byte, buffLen)
for {
n, err := pipeReader.Read(buffer)
if err != nil {
@@ -70,7 +73,7 @@ func writeCmdOutput(out, cache io.Writer, pipeReader io.ReadCloser) {
}
// pre-format the ffmpeg command with needed options
func ffmpegCommand(filePath string, profile *Profile, bitrate string) *exec.Cmd {
func ffmpegCommand(filePath string, profile Profile, bitrate string) *exec.Cmd {
args := []string{
"-v", "0",
"-i", filePath,
@@ -94,7 +97,7 @@ func ffmpegCommand(filePath string, profile *Profile, bitrate string) *exec.Cmd
return exec.Command("/usr/bin/ffmpeg", args...) //nolint:gosec
}
func Encode(out io.Writer, trackPath, cachePath string, profile *Profile, bitrate string) error {
func Encode(out io.Writer, trackPath, cachePath string, profile Profile, bitrate string) error {
// prepare the command and file descriptors
cmd := ffmpegCommand(trackPath, profile, bitrate)
pipeReader, pipeWriter := io.Pipe()
@@ -126,13 +129,13 @@ func Encode(out io.Writer, trackPath, cachePath string, profile *Profile, bitrat
// CacheKey generates the filename for the new transcode save
func CacheKey(sourcePath string, profile, bitrate string) string {
format := Profiles[profile].Format
format := Profiles()[profile].Format
hash := xxhash.Sum64String(sourcePath)
return fmt.Sprintf("%x-%s-%s.%s", hash, profile, bitrate, format)
}
// GetBitrate checks if the client forces bitrate lower than set in profile
func GetBitrate(clientBitrate int, profile *Profile) string {
func GetBitrate(clientBitrate int, profile Profile) string {
bitrate := profile.Bitrate
if clientBitrate != 0 && clientBitrate < bitrate {
bitrate = clientBitrate

View File

@@ -10,16 +10,15 @@ import (
"net/url"
"sort"
"strconv"
"time"
"go.senan.xyz/gonic/server/db"
)
var (
const (
baseURL = "https://ws.audioscrobbler.com/2.0/"
client = &http.Client{
Timeout: 10 * time.Second,
}
)
var (
ErrLastFM = errors.New("last.fm error")
)
@@ -27,7 +26,7 @@ var (
func getParamSignature(params url.Values, secret string) string {
// the parameters must be in order before hashing
paramKeys := make([]string, 0)
paramKeys := make([]string, 0, len(params))
for k := range params {
paramKeys = append(paramKeys, k)
}
@@ -45,7 +44,7 @@ func getParamSignature(params url.Values, secret string) string {
func makeRequest(method string, params url.Values) (LastFM, error) {
req, _ := http.NewRequest(method, baseURL, nil)
req.URL.RawQuery = params.Encode()
resp, err := client.Do(req)
resp, err := http.DefaultClient.Do(req)
if err != nil {
return LastFM{}, fmt.Errorf("get: %w", err)
}

View File

@@ -1,6 +1,10 @@
package mime
var Types = map[string]string{
// this package is at such a high level in the hierarchy because
// it's used by both `server/db` and `server/scanner`
func FromExtension(ext string) (string, bool) {
types := map[string]string{
"mp3": "audio/mpeg",
"flac": "audio/x-flac",
"aac": "audio/x-aac",
@@ -9,3 +13,6 @@ var Types = map[string]string{
"ogg": "audio/ogg",
"opus": "audio/ogg",
}
v, ok := types[ext]
return v, ok
}

View File

@@ -44,7 +44,7 @@ func decoded(in string) string {
// isScanning acts as an atomic boolean semaphore. we don't
// want to have more than one scan going on at a time
var isScanning int32
var isScanning int32 //nolint:gochecknoglobals
func IsScanning() bool {
return atomic.LoadInt32(&isScanning) == 1
@@ -224,7 +224,8 @@ type item struct {
stat os.FileInfo
}
var coverFilenames = map[string]struct{}{
func isCover(filename string) bool {
known := map[string]struct{}{
"cover.png": {},
"cover.jpg": {},
"cover.jpeg": {},
@@ -238,6 +239,9 @@ var coverFilenames = map[string]struct{}{
"front.jpg": {},
"front.jpeg": {},
}
_, ok := known[filename]
return ok
}
// ## begin callbacks
// ## begin callbacks
@@ -267,8 +271,8 @@ func (s *Scanner) callbackItem(fullPath string, info *godirwalk.Dirent) error {
if isDir {
return s.handleFolder(it)
}
lowerFilename := strings.ToLower(filename)
if _, ok := coverFilenames[lowerFilename]; ok {
filenameLow := strings.ToLower(filename)
if isCover(filenameLow) {
s.curCover = filename
return nil
}
@@ -276,7 +280,7 @@ func (s *Scanner) callbackItem(fullPath string, info *godirwalk.Dirent) error {
if ext == "" {
return nil
}
if _, ok := mime.Types[ext[1:]]; ok {
if _, ok := mime.FromExtension(ext[1:]); ok {
return s.handleTrack(it)
}
return nil