mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Remove sqlx
This commit is contained in:
parent
cc3b6f268a
commit
a112ecb8e9
@ -1,4 +1,4 @@
|
|||||||
# FROM golang:1.21 as build
|
# FROM golang:1.22 as build
|
||||||
FROM debian:trixie-slim as build
|
FROM debian:trixie-slim as build
|
||||||
# those were copied from https://github.com/docker-library/golang/blob/master/Dockerfile-linux.template
|
# those were copied from https://github.com/docker-library/golang/blob/master/Dockerfile-linux.template
|
||||||
ENV GOTOOLCHAIN=local
|
ENV GOTOOLCHAIN=local
|
||||||
@ -53,6 +53,7 @@ RUN set -x && apt-get update \
|
|||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=build /app/transcoder /app/transcoder
|
COPY --from=build /app/transcoder /app/transcoder
|
||||||
|
COPY ./migrations /app/migrations
|
||||||
|
|
||||||
# flags for nvidia acceleration on docker < 25.0
|
# flags for nvidia acceleration on docker < 25.0
|
||||||
ENV NVIDIA_VISIBLE_DEVICES="all"
|
ENV NVIDIA_VISIBLE_DEVICES="all"
|
||||||
|
@ -4,7 +4,6 @@ go 1.22
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/golang-migrate/migrate/v4 v4.17.1
|
github.com/golang-migrate/migrate/v4 v4.17.1
|
||||||
github.com/jmoiron/sqlx v1.4.0
|
|
||||||
github.com/labstack/echo/v4 v4.12.0
|
github.com/labstack/echo/v4 v4.12.0
|
||||||
github.com/lib/pq v1.10.9
|
github.com/lib/pq v1.10.9
|
||||||
gopkg.in/vansante/go-ffprobe.v2 v2.2.0
|
gopkg.in/vansante/go-ffprobe.v2 v2.2.0
|
||||||
@ -29,5 +28,3 @@ require (
|
|||||||
golang.org/x/text v0.14.0
|
golang.org/x/text v0.14.0
|
||||||
golang.org/x/time v0.5.0 // indirect
|
golang.org/x/time v0.5.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/jmoiron/sqlx v1.4.0 => github.com/kmpm/sqlx v1.3.5-0.20220614102404-845a9a7f1301
|
|
||||||
|
@ -17,8 +17,6 @@ github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKoh
|
|||||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||||
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
|
||||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||||
@ -30,13 +28,10 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY
|
|||||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||||
github.com/kmpm/sqlx v1.3.5-0.20220614102404-845a9a7f1301 h1:BX43DPpHzm4o6tYs3W+92d0F3iCD5/n4zKjv1FV8Ews=
|
|
||||||
github.com/kmpm/sqlx v1.3.5-0.20220614102404-845a9a7f1301/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
|
|
||||||
github.com/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+kI0=
|
github.com/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+kI0=
|
||||||
github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM=
|
github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM=
|
||||||
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
||||||
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
|
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
|
||||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
|
||||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
@ -44,9 +39,6 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk
|
|||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
|
||||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
|
||||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
|
||||||
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
||||||
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||||
|
@ -21,13 +21,7 @@ func (s *MetadataService) ExtractSubs(info *MediaInfo) (interface{}, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return set(nil, err)
|
return set(nil, err)
|
||||||
}
|
}
|
||||||
_, err = s.database.NamedExec(
|
_, err = s.database.Exec(`update info set ver_extract = $2 where sha = $1`, info.Sha, ExtractVersion)
|
||||||
`update info set ver_extract = :version where sha = :sha`,
|
|
||||||
map[string]interface{}{
|
|
||||||
"sha": info.Sha,
|
|
||||||
"version": ExtractVersion,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
return set(nil, err)
|
return set(nil, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,10 +18,10 @@ import (
|
|||||||
const InfoVersion = 1
|
const InfoVersion = 1
|
||||||
|
|
||||||
type Versions struct {
|
type Versions struct {
|
||||||
Info int32 `db:"ver_info"`
|
Info int32
|
||||||
Extract int32 `db:"ver_extract"`
|
Extract int32
|
||||||
Thumbs int32 `db:"ver_thumbs"`
|
Thumbs int32
|
||||||
Keyframes int32 `db:"ver_keyframes"`
|
Keyframes int32
|
||||||
}
|
}
|
||||||
|
|
||||||
type MediaInfo struct {
|
type MediaInfo struct {
|
||||||
@ -32,7 +32,7 @@ type MediaInfo struct {
|
|||||||
/// The extension currently used to store this video file
|
/// The extension currently used to store this video file
|
||||||
Extension string `json:"extension"`
|
Extension string `json:"extension"`
|
||||||
/// The whole mimetype (defined as the RFC 6381). ex: `video/mp4; codecs="avc1.640028, mp4a.40.2"`
|
/// The whole mimetype (defined as the RFC 6381). ex: `video/mp4; codecs="avc1.640028, mp4a.40.2"`
|
||||||
MimeCodec *string `json:"mimeCodec" db:"mime_codec"`
|
MimeCodec *string `json:"mimeCodec"`
|
||||||
/// The file size of the video file.
|
/// The file size of the video file.
|
||||||
Size int64 `json:"size"`
|
Size int64 `json:"size"`
|
||||||
/// The length of the media in seconds.
|
/// The length of the media in seconds.
|
||||||
@ -59,7 +59,7 @@ type MediaInfo struct {
|
|||||||
|
|
||||||
type Video struct {
|
type Video struct {
|
||||||
/// The index of this track on the media.
|
/// The index of this track on the media.
|
||||||
Index uint32 `json:"index" db:"idx"`
|
Index uint32 `json:"index"`
|
||||||
/// The title of the stream.
|
/// The title of the stream.
|
||||||
Title *string `json:"title"`
|
Title *string `json:"title"`
|
||||||
/// The language of this stream (as a ISO-639-2 language code)
|
/// The language of this stream (as a ISO-639-2 language code)
|
||||||
@ -67,7 +67,7 @@ type Video struct {
|
|||||||
/// The human readable codec name.
|
/// The human readable codec name.
|
||||||
Codec string `json:"codec"`
|
Codec string `json:"codec"`
|
||||||
/// The codec of this stream (defined as the RFC 6381).
|
/// The codec of this stream (defined as the RFC 6381).
|
||||||
MimeCodec *string `json:"mimeCodec" db:"mime_codec"`
|
MimeCodec *string `json:"mimeCodec"`
|
||||||
/// The max quality of this video track.
|
/// The max quality of this video track.
|
||||||
Quality Quality `json:"quality"`
|
Quality Quality `json:"quality"`
|
||||||
/// The width of the video stream
|
/// The width of the video stream
|
||||||
@ -83,7 +83,7 @@ type Video struct {
|
|||||||
|
|
||||||
type Audio struct {
|
type Audio struct {
|
||||||
/// The index of this track on the media.
|
/// The index of this track on the media.
|
||||||
Index uint32 `json:"index" db:"idx"`
|
Index uint32 `json:"index"`
|
||||||
/// The title of the stream.
|
/// The title of the stream.
|
||||||
Title *string `json:"title"`
|
Title *string `json:"title"`
|
||||||
/// The language of this stream (as a IETF-BCP-47 language code)
|
/// The language of this stream (as a IETF-BCP-47 language code)
|
||||||
@ -91,9 +91,9 @@ type Audio struct {
|
|||||||
/// The human readable codec name.
|
/// The human readable codec name.
|
||||||
Codec string `json:"codec"`
|
Codec string `json:"codec"`
|
||||||
/// The codec of this stream (defined as the RFC 6381).
|
/// The codec of this stream (defined as the RFC 6381).
|
||||||
MimeCodec *string `json:"mimeCodec" db:"mime_codec"`
|
MimeCodec *string `json:"mimeCodec"`
|
||||||
/// Is this stream the default one of it's type?
|
/// Is this stream the default one of it's type?
|
||||||
IsDefault bool `json:"isDefault" db:"is_default"`
|
IsDefault bool `json:"isDefault"`
|
||||||
|
|
||||||
/// Keyframes of this video
|
/// Keyframes of this video
|
||||||
Keyframes *Keyframe `json:"-"`
|
Keyframes *Keyframe `json:"-"`
|
||||||
@ -101,7 +101,7 @@ type Audio struct {
|
|||||||
|
|
||||||
type Subtitle struct {
|
type Subtitle struct {
|
||||||
/// The index of this track on the media.
|
/// The index of this track on the media.
|
||||||
Index *uint32 `json:"index" db:"idx"`
|
Index *uint32 `json:"index"`
|
||||||
/// The title of the stream.
|
/// The title of the stream.
|
||||||
Title *string `json:"title"`
|
Title *string `json:"title"`
|
||||||
/// The language of this stream (as a IETF-BCP-47 language code)
|
/// The language of this stream (as a IETF-BCP-47 language code)
|
||||||
@ -111,11 +111,11 @@ type Subtitle struct {
|
|||||||
/// The extension for the codec.
|
/// The extension for the codec.
|
||||||
Extension *string `json:"extension"`
|
Extension *string `json:"extension"`
|
||||||
/// Is this stream the default one of it's type?
|
/// Is this stream the default one of it's type?
|
||||||
IsDefault bool `json:"isDefault" db:"is_default"`
|
IsDefault bool `json:"isDefault"`
|
||||||
/// Is this stream tagged as forced?
|
/// Is this stream tagged as forced?
|
||||||
IsForced bool `json:"isForced" db:"is_forced"`
|
IsForced bool `json:"isForced"`
|
||||||
/// Is this an external subtitle (as in stored in a different file)
|
/// Is this an external subtitle (as in stored in a different file)
|
||||||
IsExternal bool `json:"isExternal" db:"is_external"`
|
IsExternal bool `json:"isExternal"`
|
||||||
/// Where the subtitle is stored (either in library if IsExternal is true or in transcoder cache if false)
|
/// Where the subtitle is stored (either in library if IsExternal is true or in transcoder cache if false)
|
||||||
/// Null if the subtitle can't be extracted (unsupported format)
|
/// Null if the subtitle can't be extracted (unsupported format)
|
||||||
Path *string `json:"path"`
|
Path *string `json:"path"`
|
||||||
@ -125,9 +125,9 @@ type Subtitle struct {
|
|||||||
|
|
||||||
type Chapter struct {
|
type Chapter struct {
|
||||||
/// The start time of the chapter (in second from the start of the episode).
|
/// The start time of the chapter (in second from the start of the episode).
|
||||||
StartTime float32 `json:"startTime" db:"start_time"`
|
StartTime float32 `json:"startTime"`
|
||||||
/// The end time of the chapter (in second from the start of the episode).
|
/// The end time of the chapter (in second from the start of the episode).
|
||||||
EndTime float32 `json:"endTime" db:"end_time"`
|
EndTime float32 `json:"endTime"`
|
||||||
/// The name of this chapter. This should be a human-readable name that could be presented to the user.
|
/// The name of this chapter. This should be a human-readable name that could be presented to the user.
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
/// The type value is used to mark special chapters (openning/credits...)
|
/// The type value is used to mark special chapters (openning/credits...)
|
||||||
|
@ -118,17 +118,15 @@ func (s *MetadataService) GetKeyframes(info *MediaInfo, isVideo bool, idx int32)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = s.database.NamedExec(
|
_, err = s.database.Exec(
|
||||||
fmt.Sprint(
|
fmt.Sprint(
|
||||||
`update %s set keyframes = :keyframes, ver_keyframes = :version where sha = :sha and idx = :idx`,
|
`update %s set keyframes = $3, ver_keyframes = $4 where sha = $1 and idx = $2`,
|
||||||
table,
|
table,
|
||||||
),
|
),
|
||||||
map[string]interface{}{
|
info.Sha,
|
||||||
"sha": info.Sha,
|
idx,
|
||||||
"idx": idx,
|
kf.Keyframes,
|
||||||
"keyframes": kf.Keyframes,
|
KeyframeVersion,
|
||||||
"version": KeyframeVersion,
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Couldn't store keyframes on database: %v", err)
|
log.Printf("Couldn't store keyframes on database: %v", err)
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package src
|
package src
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
@ -8,12 +10,11 @@ import (
|
|||||||
"github.com/golang-migrate/migrate/v4"
|
"github.com/golang-migrate/migrate/v4"
|
||||||
"github.com/golang-migrate/migrate/v4/database/postgres"
|
"github.com/golang-migrate/migrate/v4/database/postgres"
|
||||||
_ "github.com/golang-migrate/migrate/v4/source/file"
|
_ "github.com/golang-migrate/migrate/v4/source/file"
|
||||||
"github.com/jmoiron/sqlx"
|
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MetadataService struct {
|
type MetadataService struct {
|
||||||
database *sqlx.DB
|
database *sql.DB
|
||||||
lock RunLock[string, *MediaInfo]
|
lock RunLock[string, *MediaInfo]
|
||||||
thumbLock RunLock[string, interface{}]
|
thumbLock RunLock[string, interface{}]
|
||||||
extractLock RunLock[string, interface{}]
|
extractLock RunLock[string, interface{}]
|
||||||
@ -29,25 +30,25 @@ func NewMetadataService() (*MetadataService, error) {
|
|||||||
url.QueryEscape(os.Getenv("POSTGRES_PORT")),
|
url.QueryEscape(os.Getenv("POSTGRES_PORT")),
|
||||||
url.QueryEscape(os.Getenv("POSTGRES_DB")),
|
url.QueryEscape(os.Getenv("POSTGRES_DB")),
|
||||||
)
|
)
|
||||||
db, err := sqlx.Open("postgres", con)
|
db, err := sql.Open("postgres", con)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
db.MustExec("create schema if not exists gocoder")
|
_, err = db.Exec("create schema if not exists gocoder")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
driver, err := postgres.WithInstance(db.DB, &postgres.Config{})
|
driver, err := postgres.WithInstance(db, &postgres.Config{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
m, err := migrate.NewWithDatabaseInstance("file://./migrations", "postgres", driver)
|
m, err := migrate.NewWithDatabaseInstance("file://migrations", "postgres", driver)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
err = m.Up()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
m.Up()
|
||||||
|
|
||||||
return &MetadataService{
|
return &MetadataService{
|
||||||
database: db,
|
database: db,
|
||||||
@ -77,15 +78,17 @@ func (s *MetadataService) GetMetadata(path string, sha string) (*MediaInfo, erro
|
|||||||
for _, audio := range ret.Audios {
|
for _, audio := range ret.Audios {
|
||||||
audio.Keyframes = nil
|
audio.Keyframes = nil
|
||||||
}
|
}
|
||||||
s.database.NamedExec(`
|
tx, err := s.database.Begin()
|
||||||
update videos set keyframes = nil where sha = :sha;
|
if err != nil {
|
||||||
update audios set keyframes = nil where sha = :sha;
|
return nil, err
|
||||||
update info set ver_keyframes = 0 where sha = :sha;
|
}
|
||||||
`,
|
tx.Exec(`update videos set keyframes = nil where sha = $1`, sha)
|
||||||
map[string]interface{}{
|
tx.Exec(`update audios set keyframes = nil where sha = $1`, sha)
|
||||||
"sha": sha,
|
tx.Exec(`update info set ver_keyframes = 0 where sha = $1`, sha)
|
||||||
},
|
err = tx.Commit()
|
||||||
)
|
if err != nil {
|
||||||
|
fmt.Printf("error deleteing old keyframes from database: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret, nil
|
return ret, nil
|
||||||
@ -93,58 +96,100 @@ func (s *MetadataService) GetMetadata(path string, sha string) (*MediaInfo, erro
|
|||||||
|
|
||||||
func (s *MetadataService) getMetadata(path string, sha string) (*MediaInfo, error) {
|
func (s *MetadataService) getMetadata(path string, sha string) (*MediaInfo, error) {
|
||||||
var ret MediaInfo
|
var ret MediaInfo
|
||||||
rows, err := s.database.Queryx(`
|
err := s.database.QueryRow(
|
||||||
select * from info as i where i.sha=$1;
|
`select i.sha, i.path, i.extension, i.mime_codec, i.size, i.duration, i.container,
|
||||||
select * from videos as v where v.sha=$1;
|
i.fonts, i.ver_info, i.ver_extract, i.ver_thumbs, i.ver_keyframes
|
||||||
select * from audios as a where a.sha=$1;
|
from info as i where i.sha=$1`,
|
||||||
select * from subtitles as s where s.sha=$1;
|
sha,
|
||||||
select * from chapters as c where c.sha=$1;
|
).Scan(
|
||||||
`,
|
ret.Sha, ret.Path, ret.Extension, ret.MimeCodec, ret.Size, ret.Duration, ret.Container,
|
||||||
|
ret.Fonts, ret.Versions.Info, ret.Versions.Extract, ret.Versions.Thumbs, ret.Versions.Keyframes,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err == sql.ErrNoRows || (ret.Versions.Info < InfoVersion && ret.Versions.Info != 0) {
|
||||||
|
return s.storeFreshMetadata(path, sha)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rows, err := s.database.Query(
|
||||||
|
`select v.idx, v.title, v.language, v.codec, v.mime_codec, v.width, v.height, v.bitrate, v.keyframes
|
||||||
|
from videos as v where v.sha=$1`,
|
||||||
sha,
|
sha,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
for rows.Next() {
|
||||||
|
var v Video
|
||||||
if !rows.Next() {
|
err := rows.Scan(v.Index, v.Title, v.Language, v.Codec, v.MimeCodec, v.Width, v.Height, v.Bitrate, v.Keyframes)
|
||||||
if err = rows.Err(); err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return s.storeFreshMetadata(path, sha)
|
v.Quality = QualityFromHeight(v.Height)
|
||||||
}
|
ret.Videos = append(ret.Videos, v)
|
||||||
rows.StructScan(ret)
|
|
||||||
|
|
||||||
if ret.Versions.Info != InfoVersion {
|
|
||||||
return s.storeFreshMetadata(path, sha)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rows.NextResultSet()
|
rows, err = s.database.Query(
|
||||||
|
`select a.idx, a.title, a.language, a.codec, a.mime_codec, a.is_default, a.keyframes
|
||||||
|
from audios as a where a.sha=$1`,
|
||||||
|
sha,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var video Video
|
var a Audio
|
||||||
rows.StructScan(video)
|
err := rows.Scan(a.Index, a.Title, a.Language, a.Codec, a.MimeCodec, a.IsDefault, a.Keyframes)
|
||||||
ret.Videos = append(ret.Videos, video)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ret.Audios = append(ret.Audios, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
rows.NextResultSet()
|
rows, err = s.database.Query(
|
||||||
|
`select s.idx, s.title, s.language, s.codec, s.extension, s.is_default, s.is_forced, s.is_external, s.path
|
||||||
|
from subtitles as s where s.sha=$1`,
|
||||||
|
sha,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var audio Audio
|
var s Subtitle
|
||||||
rows.StructScan(audio)
|
err := rows.Scan(s.Index, s.Title, s.Language, s.Codec, s.Extension, s.IsDefault, s.IsForced, s.IsExternal, s.Path)
|
||||||
ret.Audios = append(ret.Audios, audio)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if s.Extension != nil {
|
||||||
|
link := fmt.Sprintf(
|
||||||
|
"%s/%s/subtitle/%d.%s",
|
||||||
|
Settings.RoutePrefix,
|
||||||
|
base64.StdEncoding.EncodeToString([]byte(ret.Path)),
|
||||||
|
s.Index,
|
||||||
|
*s.Extension,
|
||||||
|
)
|
||||||
|
s.Link = &link
|
||||||
|
}
|
||||||
|
ret.Subtitles = append(ret.Subtitles, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
rows.NextResultSet()
|
rows, err = s.database.Query(
|
||||||
for rows.Next() {
|
`select c.start_time, c.end_time, c.name, c.type
|
||||||
var subtitle Subtitle
|
from chapters as c where c.sha=$1`,
|
||||||
rows.StructScan(subtitle)
|
sha,
|
||||||
ret.Subtitles = append(ret.Subtitles, subtitle)
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
rows.NextResultSet()
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var chapter Chapter
|
var c Chapter
|
||||||
rows.StructScan(chapter)
|
err := rows.Scan(c.StartTime, c.EndTime, c.Name, c.Type)
|
||||||
ret.Chapters = append(ret.Chapters, chapter)
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ret.Chapters = append(ret.Chapters, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ret, nil
|
return &ret, nil
|
||||||
@ -161,38 +206,38 @@ func (s *MetadataService) storeFreshMetadata(path string, sha string) (*MediaInf
|
|||||||
return set(nil, err)
|
return set(nil, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
tx := s.database.MustBegin()
|
tx, err := s.database.Begin()
|
||||||
tx.NamedExec(
|
tx.Exec(
|
||||||
`insert into info(sha, path, extension, mime_codec, size, duration, container, fonts, ver_info)
|
`insert into info(sha, path, extension, mime_codec, size, duration, container, fonts, ver_info)
|
||||||
values (:sha, :path, :extension, :mime_codec, :size, :duration, :container, :fonts, :ver_info)`,
|
values ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
|
||||||
ret,
|
ret.Sha, ret.Path, ret.Extension, ret.MimeCodec, ret.Size, ret.Duration, ret.Container, ret.Fonts, ret.Versions.Info,
|
||||||
)
|
)
|
||||||
for _, video := range ret.Videos {
|
for _, v := range ret.Videos {
|
||||||
tx.NamedExec(
|
tx.Exec(
|
||||||
`insert into videos(sha, idx, title, language, codec, mime_codec, width, height, bitrate)
|
`insert into videos(sha, idx, title, language, codec, mime_codec, width, height, bitrate)
|
||||||
values (:sha, :idx, :title, :language, :codec, :mime_codec, :width, :height, :bitrate)`,
|
values ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
|
||||||
video,
|
ret.Sha, v.Index, v.Title, v.Language, v.Codec, v.MimeCodec, v.Width, v.Height, v.Bitrate,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
for _, audio := range ret.Audios {
|
for _, a := range ret.Audios {
|
||||||
tx.NamedExec(
|
tx.Exec(
|
||||||
`insert into audios(sha, idx, title, language, codec, mime_codec, is_default)
|
`insert into audios(sha, idx, title, language, codec, mime_codec, is_default)
|
||||||
values (:sha, :idx, :title, :language, :codec, :mime_codec, :is_default)`,
|
values ($1, $2, $3, $4, $5, $6, $7)`,
|
||||||
audio,
|
ret.Sha, a.Index, a.Title, a.Language, a.Codec, a.MimeCodec, a.IsDefault,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
for _, subtitle := range ret.Subtitles {
|
for _, s := range ret.Subtitles {
|
||||||
tx.NamedExec(
|
tx.Exec(
|
||||||
`insert into subtitles(sha, idx, title, language, codec, extension, is_default, is_forced, is_external, path)
|
`insert into subtitles(sha, idx, title, language, codec, extension, is_default, is_forced, is_external, path)
|
||||||
values (:sha, :idx, :title, :language, :codec, :extension, :is_default, :is_forced, :is_external, :path)`,
|
values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)`,
|
||||||
subtitle,
|
ret.Sha, s.Index, s.Title, s.Language, s.Codec, s.Extension, s.IsDefault, s.IsForced, s.IsExternal, s.Path,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
for _, chapter := range ret.Chapters {
|
for _, c := range ret.Chapters {
|
||||||
tx.NamedExec(
|
tx.Exec(
|
||||||
`insert into chapters(sha, start_time, end_time, name, type)
|
`insert into chapters(sha, start_time, end_time, name, type)
|
||||||
values (:sha, :start_time, :end_time, :name, :type)`,
|
values ($1, $2, $3, $4, $5)`,
|
||||||
chapter,
|
ret.Sha, c.StartTime, c.EndTime, c.Name, c.Type,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
err = tx.Commit()
|
err = tx.Commit()
|
||||||
|
@ -68,13 +68,7 @@ func (s *MetadataService) ExtractThumbs(path string, sha string) (interface{}, e
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return set(nil, err)
|
return set(nil, err)
|
||||||
}
|
}
|
||||||
_, err = s.database.NamedExec(
|
_, err = s.database.Exec(`update info set ver_thumbs = $2 where sha = $1`, sha, ThumbsVersion)
|
||||||
`update info set ver_thumbs = :version where sha = :sha`,
|
|
||||||
map[string]interface{}{
|
|
||||||
"sha": sha,
|
|
||||||
"version": ThumbsVersion,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
return set(nil, err)
|
return set(nil, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user