68 lines
1.8 KiB
Go
68 lines
1.8 KiB
Go
package api
|
|
|
|
import (
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
)
|
|
|
|
// uuidToString renders a pgtype.UUID as a canonical hyphenated string.
|
|
// Returns "" when the UUID is invalid (unset). Duplicated from the subsonic
|
|
// package intentionally — the two packages must not depend on each other.
|
|
func uuidToString(u pgtype.UUID) string {
|
|
if !u.Valid {
|
|
return ""
|
|
}
|
|
b := u.Bytes
|
|
const hex = "0123456789abcdef"
|
|
out := make([]byte, 36)
|
|
j := 0
|
|
for i, x := range b {
|
|
if i == 4 || i == 6 || i == 8 || i == 10 {
|
|
out[j] = '-'
|
|
j++
|
|
}
|
|
out[j] = hex[x>>4]
|
|
out[j+1] = hex[x&0x0f]
|
|
j += 2
|
|
}
|
|
return string(out)
|
|
}
|
|
|
|
// parseUUID accepts the canonical hyphenated form produced by uuidToString.
|
|
// Returns ok=false on any malformed input so handlers can 400 cleanly.
|
|
func parseUUID(s string) (pgtype.UUID, bool) {
|
|
var u pgtype.UUID
|
|
if err := u.Scan(s); err != nil {
|
|
return pgtype.UUID{}, false
|
|
}
|
|
return u, u.Valid
|
|
}
|
|
|
|
// yearFromDate returns the 4-digit year from a pgtype.Date, or 0 when the
|
|
// date is unset. Album release years are optional at scan time.
|
|
func yearFromDate(d pgtype.Date) int {
|
|
if !d.Valid {
|
|
return 0
|
|
}
|
|
return d.Time.Year()
|
|
}
|
|
|
|
// durationMsToSec converts millisecond durations (as stored in tracks.duration_ms)
|
|
// to seconds, rounding to nearest. Callers display seconds; sub-second precision
|
|
// is not useful in UI.
|
|
func durationMsToSec(ms int32) int {
|
|
return int((ms + 500) / 1000)
|
|
}
|
|
|
|
// coverURL returns the /api relative URL for an album's cover art. The
|
|
// endpoint ships in Plan 3; until then it 404s, and the SPA does not wire
|
|
// <img src> to it.
|
|
func coverURL(albumID pgtype.UUID) string {
|
|
return "/api/albums/" + uuidToString(albumID) + "/cover"
|
|
}
|
|
|
|
// streamURL returns the /api relative URL for a track's audio stream. The
|
|
// endpoint ships in Plan 3.
|
|
func streamURL(trackID pgtype.UUID) string {
|
|
return "/api/tracks/" + uuidToString(trackID) + "/stream"
|
|
}
|