diff --git a/frontend/src/assets/i18n.yaml b/frontend/src/assets/i18n.yaml index 0f6288b..85071b3 100644 --- a/frontend/src/assets/i18n.yaml +++ b/frontend/src/assets/i18n.yaml @@ -63,6 +63,7 @@ languages: livestreamDownloadInfo: | This will monitor yet to start livestream. Each process will be executed with --wait-for-video 10. If an already started livestream is provided it will be still downloaded but its progress will not be tracked. + Once started the livestream will be migrated to the downloads page. livestreamExperimentalWarning: This feature is still experimental. Something might break! german: urlInput: Video URL @@ -123,6 +124,7 @@ languages: livestreamDownloadInfo: | This will monitor yet to start livestream. Each process will be executed with --wait-for-video 10. If an already started livestream is provided it will be still downloaded but its progress will not be tracked. + Once started the livestream will be migrated to the downloads page. livestreamExperimentalWarning: This feature is still experimental. Something might break! french: urlInput: URL vidéo de YouTube ou d'un autre service pris en charge @@ -185,6 +187,7 @@ languages: livestreamDownloadInfo: | This will monitor yet to start livestream. Each process will be executed with --wait-for-video 10. If an already started livestream is provided it will be still downloaded but its progress will not be tracked. + Once started the livestream will be migrated to the downloads page. livestreamExperimentalWarning: This feature is still experimental. Something might break! italian: urlInput: URL Video (uno per linea) @@ -244,6 +247,7 @@ languages: livestreamDownloadInfo: | This will monitor yet to start livestream. Each process will be executed with --wait-for-video 10. If an already started livestream is provided it will be still downloaded but its progress will not be tracked. + Once started the livestream will be migrated to the downloads page. livestreamExperimentalWarning: This feature is still experimental. Something might break! chinese: urlInput: 视频 URL @@ -304,6 +308,7 @@ languages: livestreamDownloadInfo: | This will monitor yet to start livestream. Each process will be executed with --wait-for-video 10. If an already started livestream is provided it will be still downloaded but its progress will not be tracked. + Once started the livestream will be migrated to the downloads page. livestreamExperimentalWarning: This feature is still experimental. Something might break! spanish: urlInput: URL de YouTube u otro servicio compatible @@ -362,6 +367,7 @@ languages: livestreamDownloadInfo: | This will monitor yet to start livestream. Each process will be executed with --wait-for-video 10. If an already started livestream is provided it will be still downloaded but its progress will not be tracked. + Once started the livestream will be migrated to the downloads page. livestreamExperimentalWarning: This feature is still experimental. Something might break! russian: urlInput: URL-адрес YouTube или любого другого поддерживаемого сервиса @@ -420,6 +426,7 @@ languages: livestreamDownloadInfo: | This will monitor yet to start livestream. Each process will be executed with --wait-for-video 10. If an already started livestream is provided it will be still downloaded but its progress will not be tracked. + Once started the livestream will be migrated to the downloads page. livestreamExperimentalWarning: This feature is still experimental. Something might break! korean: urlInput: YouTube나 다른 지원되는 사이트의 URL @@ -478,6 +485,7 @@ languages: livestreamDownloadInfo: | This will monitor yet to start livestream. Each process will be executed with --wait-for-video 10. If an already started livestream is provided it will be still downloaded but its progress will not be tracked. + Once started the livestream will be migrated to the downloads page. livestreamExperimentalWarning: This feature is still experimental. Something might break! japanese: urlInput: YouTubeまたはサポート済み動画のURL @@ -537,6 +545,7 @@ languages: livestreamDownloadInfo: | This will monitor yet to start livestream. Each process will be executed with --wait-for-video 10. If an already started livestream is provided it will be still downloaded but its progress will not be tracked. + Once started the livestream will be migrated to the downloads page. livestreamExperimentalWarning: This feature is still experimental. Something might break! catalan: urlInput: URL de YouTube o d'un altre servei compatible @@ -595,6 +604,7 @@ languages: livestreamDownloadInfo: | This will monitor yet to start livestream. Each process will be executed with --wait-for-video 10. If an already started livestream is provided it will be still downloaded but its progress will not be tracked. + Once started the livestream will be migrated to the downloads page. livestreamExperimentalWarning: This feature is still experimental. Something might break! ukrainian: urlInput: URL-адреса YouTube або будь-якого іншого підтримуваного сервісу @@ -653,6 +663,7 @@ languages: livestreamDownloadInfo: | This will monitor yet to start livestream. Each process will be executed with --wait-for-video 10. If an already started livestream is provided it will be still downloaded but its progress will not be tracked. + Once started the livestream will be migrated to the downloads page. livestreamExperimentalWarning: This feature is still experimental. Something might break! polish: urlInput: Adres URL YouTube lub innej obsługiwanej usługi @@ -711,6 +722,7 @@ languages: livestreamDownloadInfo: | This will monitor yet to start livestream. Each process will be executed with --wait-for-video 10. If an already started livestream is provided it will be still downloaded but its progress will not be tracked. + Once started the livestream will be migrated to the downloads page. livestreamExperimentalWarning: This feature is still experimental. Something might break! swedish: urlInput: Videolänk (en per rad) @@ -775,4 +787,5 @@ languages: livestreamDownloadInfo: | This will monitor yet to start livestream. Each process will be executed with --wait-for-video 10. If an already started livestream is provided it will be still downloaded but its progress will not be tracked. + Once started the livestream will be migrated to the downloads page. livestreamExperimentalWarning: This feature is still experimental. Something might break! diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts index d530b35..2571b01 100644 --- a/frontend/src/types/index.ts +++ b/frontend/src/types/index.ts @@ -39,10 +39,11 @@ type DownloadInfo = { } export enum ProcessStatus { - Pending = 0, - Downloading, - Completed, - Errored, + PENDING = 0, + DOWNLOADING, + COMPLETED, + ERRORED, + LIVESTREAM, } type DownloadProgress = { diff --git a/frontend/src/utils.ts b/frontend/src/utils.ts index 171b4a7..15a92b7 100644 --- a/frontend/src/utils.ts +++ b/frontend/src/utils.ts @@ -56,14 +56,16 @@ export function isRPCResponse(object: any): object is RPCResponse { export function mapProcessStatus(status: ProcessStatus) { switch (status) { - case ProcessStatus.Pending: + case ProcessStatus.PENDING: return 'Pending' - case ProcessStatus.Downloading: + case ProcessStatus.DOWNLOADING: return 'Downloading' - case ProcessStatus.Completed: + case ProcessStatus.COMPLETED: return 'Completed' - case ProcessStatus.Errored: + case ProcessStatus.ERRORED: return 'Error' + case ProcessStatus.LIVESTREAM: + return 'Livestream' default: return 'Pending' } diff --git a/go.mod b/go.mod index 9e25139..438a979 100644 --- a/go.mod +++ b/go.mod @@ -11,11 +11,11 @@ require ( github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.3 github.com/reactivex/rxgo/v2 v2.5.0 - golang.org/x/oauth2 v0.21.0 - golang.org/x/sync v0.7.0 - golang.org/x/sys v0.22.0 + golang.org/x/oauth2 v0.22.0 + golang.org/x/sync v0.8.0 + golang.org/x/sys v0.24.0 gopkg.in/yaml.v3 v3.0.1 - modernc.org/sqlite v1.31.1 + modernc.org/sqlite v1.32.0 ) require ( @@ -32,9 +32,9 @@ require ( github.com/stretchr/objx v0.5.2 // indirect github.com/stretchr/testify v1.9.0 // indirect github.com/teivah/onecontext v1.3.0 // indirect - golang.org/x/crypto v0.25.0 // indirect - modernc.org/gc/v3 v3.0.0-20240722195230-4a140ff9c08e // indirect - modernc.org/libc v1.55.7 // indirect + golang.org/x/crypto v0.26.0 // indirect + modernc.org/gc/v3 v3.0.0-20240801135723-a856999a2e4a // indirect + modernc.org/libc v1.59.9 // indirect modernc.org/mathutil v1.6.0 // indirect modernc.org/memory v1.8.0 // indirect modernc.org/strutil v1.2.0 // indirect diff --git a/go.sum b/go.sum index a16990e..1d56a62 100644 --- a/go.sum +++ b/go.sum @@ -63,6 +63,8 @@ go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= @@ -72,14 +74,20 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= +golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -98,17 +106,23 @@ modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= modernc.org/ccgo/v4 v4.19.2 h1:lwQZgvboKD0jBwdaeVCTouxhxAyN6iawF3STraAal8Y= modernc.org/ccgo/v4 v4.19.2/go.mod h1:ysS3mxiMV38XGRTTcgo0DQTeTmAO4oCmJl1nX9VFI3s= modernc.org/ccgo/v4 v4.20.5 h1:s04akhT2dysD0DFOlv9fkQ6oUTLPYgMnnDk9oaqjszM= +modernc.org/ccgo/v4 v4.20.7 h1:skrinQsjxWfvj6nbC3ztZPJy+NuwmB3hV9zX/pthNYQ= modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw= modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= modernc.org/gc/v2 v2.4.3 h1:Ik4ZcMbC7aY4ZDPUhzXVXi7GMub9QcXLTfXn3mWpNw8= +modernc.org/gc/v2 v2.5.0 h1:bJ9ChznK1L1mUtAQtxi0wi5AtAs5jQuw4PrPHO5pb6M= modernc.org/gc/v3 v3.0.0-20240722195230-4a140ff9c08e h1:WPC4v0rNIFb2PY+nBBEEKyugPPRHPzUgyN3xZPpGK58= modernc.org/gc/v3 v3.0.0-20240722195230-4a140ff9c08e/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= +modernc.org/gc/v3 v3.0.0-20240801135723-a856999a2e4a h1:CfbpOLEo2IwNzJdMvE8aiRbPMxoTpgAJeyePh0SmO8M= +modernc.org/gc/v3 v3.0.0-20240801135723-a856999a2e4a/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U= modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w= modernc.org/libc v1.55.7 h1:/5PMGAF3tyZhK72WpoqeLNtgUUpYMrnhT+Gm/5tVDgs= modernc.org/libc v1.55.7/go.mod h1:JXguUpMkbw1gknxspNE9XaG+kk9hDAAnBxpA6KGLiyA= +modernc.org/libc v1.59.9 h1:k+nNDDakwipimgmJ1D9H466LhFeSkaPPycAs1OZiDmY= +modernc.org/libc v1.59.9/go.mod h1:EY/egGEU7Ju66eU6SBqCNYaFUDuc4npICkMWnU5EE3A= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= @@ -119,6 +133,8 @@ modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= diff --git a/server/internal/message_queue.go b/server/internal/message_queue.go index 9267f0f..4ae100b 100644 --- a/server/internal/message_queue.go +++ b/server/internal/message_queue.go @@ -64,7 +64,8 @@ func (m *MessageQueue) downloadConsumer() { if p.Progress.Status != StatusCompleted { if p.Livestream { - go p.Start() // livestreams have higher priorty and will ignore the queue + // livestreams have higher priorty and they ignore the semaphore + go p.Start() } else { p.Start() } diff --git a/server/internal/process.go b/server/internal/process.go index fdd71f2..25f96a7 100644 --- a/server/internal/process.go +++ b/server/internal/process.go @@ -168,10 +168,6 @@ func (p *Process) Start() { ETA: progress.Eta, } - if p.Livestream { - p.Progress.Status = StatusLivestream - } - slog.Info("progress", slog.String("id", p.getShortId()), slog.String("url", p.Url), diff --git a/server/server.go b/server/server.go index 7b38680..037a5e4 100644 --- a/server/server.go +++ b/server/server.go @@ -51,11 +51,13 @@ type serverConfig struct { mdb *internal.MemoryDB db *sql.DB mq *internal.MessageQueue + lm *livestream.Monitor } func RunBlocking(cfg *RunConfig) { var mdb internal.MemoryDB + // ---- LOGGING --------------------------------------------------- logWriters := []io.Writer{ os.Stdout, logging.NewObservableLogger(), // for web-ui @@ -84,6 +86,7 @@ func RunBlocking(cfg *RunConfig) { // make the new logger the default one with all the new writers slog.SetDefault(logger) + // ---------------------------------------------------------------- db, err := sql.Open("sqlite", cfg.DBPath) if err != nil { @@ -99,9 +102,12 @@ func RunBlocking(cfg *RunConfig) { panic(err) } mq.SetupConsumers() - go mdb.Restore(mq) + lm := livestream.NewMonitor(mq, &mdb) + go lm.Schedule() + go lm.Restore() + srv := newServer(serverConfig{ frontend: cfg.App, swagger: cfg.Swagger, @@ -110,6 +116,7 @@ func RunBlocking(cfg *RunConfig) { mdb: &mdb, mq: mq, db: db, + lm: lm, }) go gracefulShutdown(srv, &mdb) @@ -140,18 +147,14 @@ func RunBlocking(cfg *RunConfig) { } func newServer(c serverConfig) *http.Server { - lm := livestream.NewMonitor(c.mq, c.mdb) - go lm.Schedule() - go lm.Restore() - go func() { for { - lm.Persist() + c.lm.Persist() time.Sleep(time.Minute * 5) } }() - service := ytdlpRPC.Container(c.mdb, c.mq, lm) + service := ytdlpRPC.Container(c.mdb, c.mq, c.lm) rpc.Register(service) r := chi.NewRouter() @@ -236,6 +239,7 @@ func gracefulShutdown(srv *http.Server, db *internal.MemoryDB) { defer func() { db.Persist() + stop() srv.Shutdown(context.Background()) }()