Compare commits
3 Commits
215-files-
...
219-format
| Author | SHA1 | Date | |
|---|---|---|---|
| 4a87ea559a | |||
|
|
846fb294d0 | ||
|
|
baa25afa27 |
10
Makefile
10
Makefile
@@ -4,17 +4,15 @@ default:
|
|||||||
go run main.go
|
go run main.go
|
||||||
|
|
||||||
fe:
|
fe:
|
||||||
cd frontend && pnpm build
|
cd frontend && pnpm install && pnpm build
|
||||||
|
|
||||||
dev:
|
dev:
|
||||||
cd frontend && pnpm dev
|
cd frontend && pnpm install && pnpm dev
|
||||||
|
|
||||||
all:
|
all: fe
|
||||||
$(MAKE) fe && cd ..
|
|
||||||
CGO_ENABLED=0 go build -o yt-dlp-webui main.go
|
CGO_ENABLED=0 go build -o yt-dlp-webui main.go
|
||||||
|
|
||||||
multiarch:
|
multiarch: fe
|
||||||
$(MAKE) fe
|
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o build/yt-dlp-webui_linux-amd64 main.go
|
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o build/yt-dlp-webui_linux-amd64 main.go
|
||||||
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o build/yt-dlp-webui_linux-arm64 main.go
|
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o build/yt-dlp-webui_linux-arm64 main.go
|
||||||
|
|||||||
8
frontend/pnpm-lock.yaml
generated
8
frontend/pnpm-lock.yaml
generated
@@ -59,7 +59,7 @@ importers:
|
|||||||
version: 18.3.3
|
version: 18.3.3
|
||||||
'@types/react-dom':
|
'@types/react-dom':
|
||||||
specifier: ^18.2.18
|
specifier: ^18.2.18
|
||||||
version: 18.2.18
|
version: 18.3.1
|
||||||
'@types/react-helmet':
|
'@types/react-helmet':
|
||||||
specifier: ^6.1.11
|
specifier: ^6.1.11
|
||||||
version: 6.1.11
|
version: 6.1.11
|
||||||
@@ -689,8 +689,8 @@ packages:
|
|||||||
'@types/prop-types@15.7.11':
|
'@types/prop-types@15.7.11':
|
||||||
resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==}
|
resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==}
|
||||||
|
|
||||||
'@types/react-dom@18.2.18':
|
'@types/react-dom@18.3.1':
|
||||||
resolution: {integrity: sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==}
|
resolution: {integrity: sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==}
|
||||||
|
|
||||||
'@types/react-helmet@6.1.11':
|
'@types/react-helmet@6.1.11':
|
||||||
resolution: {integrity: sha512-0QcdGLddTERotCXo3VFlUSWO3ztraw8nZ6e3zJSgG7apwV5xt+pJUS8ewPBqT4NYB1optGLprNQzFleIY84u/g==}
|
resolution: {integrity: sha512-0QcdGLddTERotCXo3VFlUSWO3ztraw8nZ6e3zJSgG7apwV5xt+pJUS8ewPBqT4NYB1optGLprNQzFleIY84u/g==}
|
||||||
@@ -1711,7 +1711,7 @@ snapshots:
|
|||||||
|
|
||||||
'@types/prop-types@15.7.11': {}
|
'@types/prop-types@15.7.11': {}
|
||||||
|
|
||||||
'@types/react-dom@18.2.18':
|
'@types/react-dom@18.3.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/react': 18.3.3
|
'@types/react': 18.3.3
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ import { useRPC } from '../hooks/useRPC'
|
|||||||
import type { DLMetadata } from '../types'
|
import type { DLMetadata } from '../types'
|
||||||
import { toFormatArgs } from '../utils'
|
import { toFormatArgs } from '../utils'
|
||||||
import ExtraDownloadOptions from './ExtraDownloadOptions'
|
import ExtraDownloadOptions from './ExtraDownloadOptions'
|
||||||
|
import { useToast } from '../hooks/toast'
|
||||||
|
import LoadingBackdrop from './LoadingBackdrop'
|
||||||
|
|
||||||
const Transition = forwardRef(function Transition(
|
const Transition = forwardRef(function Transition(
|
||||||
props: TransitionProps & {
|
props: TransitionProps & {
|
||||||
@@ -67,6 +69,7 @@ const DownloadDialog: FC<Props> = ({ open, onClose, onDownloadStart }) => {
|
|||||||
const [pickedVideoFormat, setPickedVideoFormat] = useState('')
|
const [pickedVideoFormat, setPickedVideoFormat] = useState('')
|
||||||
const [pickedAudioFormat, setPickedAudioFormat] = useState('')
|
const [pickedAudioFormat, setPickedAudioFormat] = useState('')
|
||||||
const [pickedBestFormat, setPickedBestFormat] = useState('')
|
const [pickedBestFormat, setPickedBestFormat] = useState('')
|
||||||
|
const [isFormatsLoading, setIsFormatsLoading] = useState(false)
|
||||||
|
|
||||||
const [customArgs, setCustomArgs] = useRecoilState(customArgsState)
|
const [customArgs, setCustomArgs] = useRecoilState(customArgsState)
|
||||||
|
|
||||||
@@ -82,6 +85,7 @@ const DownloadDialog: FC<Props> = ({ open, onClose, onDownloadStart }) => {
|
|||||||
|
|
||||||
const { i18n } = useI18n()
|
const { i18n } = useI18n()
|
||||||
const { client } = useRPC()
|
const { client } = useRPC()
|
||||||
|
const { pushMessage } = useToast()
|
||||||
|
|
||||||
const urlInputRef = useRef<HTMLInputElement>(null)
|
const urlInputRef = useRef<HTMLInputElement>(null)
|
||||||
const customFilenameInputRef = useRef<HTMLInputElement>(null)
|
const customFilenameInputRef = useRef<HTMLInputElement>(null)
|
||||||
@@ -129,11 +133,28 @@ const DownloadDialog: FC<Props> = ({ open, onClose, onDownloadStart }) => {
|
|||||||
setPickedVideoFormat('')
|
setPickedVideoFormat('')
|
||||||
setPickedBestFormat('')
|
setPickedBestFormat('')
|
||||||
|
|
||||||
|
|
||||||
|
if (isPlaylist) {
|
||||||
|
pushMessage('Format selection on playlist is not supported', 'warning')
|
||||||
|
resetInput()
|
||||||
|
onClose()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsFormatsLoading(true)
|
||||||
|
|
||||||
client.formats(url)
|
client.formats(url)
|
||||||
?.then(formats => {
|
?.then(formats => {
|
||||||
|
if (formats.result._type === 'playlist') {
|
||||||
|
pushMessage('Format selection on playlist is not supported. Downloading as playlist.', 'info')
|
||||||
|
resetInput()
|
||||||
|
onClose()
|
||||||
|
return
|
||||||
|
}
|
||||||
setDownloadFormats(formats.result)
|
setDownloadFormats(formats.result)
|
||||||
resetInput()
|
resetInput()
|
||||||
})
|
})
|
||||||
|
.then(() => setIsFormatsLoading(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleUrlChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleUrlChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
@@ -175,10 +196,7 @@ const DownloadDialog: FC<Props> = ({ open, onClose, onDownloadStart }) => {
|
|||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
TransitionComponent={Transition}
|
TransitionComponent={Transition}
|
||||||
>
|
>
|
||||||
<Backdrop
|
<LoadingBackdrop isLoading={isPending || isFormatsLoading} />
|
||||||
sx={{ color: '#fff', zIndex: (theme) => theme.zIndex.drawer + 1 }}
|
|
||||||
open={isPending}
|
|
||||||
/>
|
|
||||||
<AppBar sx={{ position: 'relative' }}>
|
<AppBar sx={{ position: 'relative' }}>
|
||||||
<Toolbar>
|
<Toolbar>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
|||||||
@@ -69,9 +69,11 @@ export type RPCParams = {
|
|||||||
|
|
||||||
export type DLMetadata = {
|
export type DLMetadata = {
|
||||||
formats: Array<DLFormat>
|
formats: Array<DLFormat>
|
||||||
|
_type: string
|
||||||
best: DLFormat
|
best: DLFormat
|
||||||
thumbnail: string
|
thumbnail: string
|
||||||
title: string
|
title: string
|
||||||
|
entries: Array<DLMetadata>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DLFormat = {
|
export type DLFormat = {
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -1,4 +1,4 @@
|
|||||||
module github.com/marcopeocchi/yt-dlp-web-ui
|
module github.com/marcopeocchi/yt-dlp-web-ui/v3
|
||||||
|
|
||||||
go 1.23
|
go 1.23
|
||||||
|
|
||||||
|
|||||||
8
main.go
8
main.go
@@ -8,10 +8,10 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/cli"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/cli"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/config"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/config"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/openid"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/openid"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/config"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
var lockFilePath = filepath.Join(config.Instance().Dir(), ".db.lock")
|
var lockFilePath = filepath.Join(config.Instance().Dir(), ".db.lock")
|
||||||
|
|||||||
56
server/formats/parser.go
Normal file
56
server/formats/parser.go
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package formats
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"log/slog"
|
||||||
|
"os/exec"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ParseURL(url string) (*Metadata, error) {
|
||||||
|
cmd := exec.Command(config.Instance().DownloaderPath, url, "-J")
|
||||||
|
|
||||||
|
stdout, err := cmd.Output()
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("failed to retrieve metadata", slog.String("err", err.Error()))
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
slog.Info(
|
||||||
|
"retrieving metadata",
|
||||||
|
slog.String("caller", "getFormats"),
|
||||||
|
slog.String("url", url),
|
||||||
|
)
|
||||||
|
|
||||||
|
info := &Metadata{URL: url}
|
||||||
|
best := &Format{}
|
||||||
|
|
||||||
|
var (
|
||||||
|
wg sync.WaitGroup
|
||||||
|
decodingError error
|
||||||
|
)
|
||||||
|
|
||||||
|
wg.Add(2)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
decodingError = json.Unmarshal(stdout, &info)
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
decodingError = json.Unmarshal(stdout, &best)
|
||||||
|
wg.Done()
|
||||||
|
}()
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
if decodingError != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
info.Best = *best
|
||||||
|
|
||||||
|
return info, nil
|
||||||
|
}
|
||||||
28
server/formats/types.go
Normal file
28
server/formats/types.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package formats
|
||||||
|
|
||||||
|
// Used to deser the formats in the -J output
|
||||||
|
type Metadata struct {
|
||||||
|
Type string `json:"_type"`
|
||||||
|
Formats []Format `json:"formats"`
|
||||||
|
Best Format `json:"best"`
|
||||||
|
Thumbnail string `json:"thumbnail"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
Entries []Metadata `json:"entries"` // populated if url is playlist
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Metadata) IsPlaylist() bool {
|
||||||
|
return m.Type == "playlist"
|
||||||
|
}
|
||||||
|
|
||||||
|
// A skimmed yt-dlp format node
|
||||||
|
type Format struct {
|
||||||
|
Format_id string `json:"format_id"`
|
||||||
|
Format_note string `json:"format_note"`
|
||||||
|
FPS float32 `json:"fps"`
|
||||||
|
Resolution string `json:"resolution"`
|
||||||
|
VCodec string `json:"vcodec"`
|
||||||
|
ACodec string `json:"acodec"`
|
||||||
|
Size float32 `json:"filesize_approx"`
|
||||||
|
Language string `json:"language"`
|
||||||
|
}
|
||||||
@@ -17,8 +17,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/config"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/config"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/internal"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/golang-jwt/jwt/v5"
|
"github.com/golang-jwt/jwt/v5"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/config"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
const TOKEN_COOKIE_NAME = "jwt-yt-dlp-webui"
|
const TOKEN_COOKIE_NAME = "jwt-yt-dlp-webui"
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ type ProgressTemplate struct {
|
|||||||
Eta float32 `json:"eta"`
|
Eta float32 `json:"eta"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type PostprocessTemplate struct {
|
type PostprocessTemplate struct {
|
||||||
FilePath string `json:"filepath"`
|
FilePath string `json:"filepath"`
|
||||||
}
|
}
|
||||||
@@ -45,27 +44,6 @@ type DownloadInfo struct {
|
|||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used to deser the formats in the -J output
|
|
||||||
type DownloadFormats struct {
|
|
||||||
Formats []Format `json:"formats"`
|
|
||||||
Best Format `json:"best"`
|
|
||||||
Thumbnail string `json:"thumbnail"`
|
|
||||||
Title string `json:"title"`
|
|
||||||
URL string `json:"url"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// A skimmed yt-dlp format node
|
|
||||||
type Format struct {
|
|
||||||
Format_id string `json:"format_id"`
|
|
||||||
Format_note string `json:"format_note"`
|
|
||||||
FPS float32 `json:"fps"`
|
|
||||||
Resolution string `json:"resolution"`
|
|
||||||
VCodec string `json:"vcodec"`
|
|
||||||
ACodec string `json:"acodec"`
|
|
||||||
Size float32 `json:"filesize_approx"`
|
|
||||||
Language string `json:"language"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// struct representing the response sent to the client
|
// struct representing the response sent to the client
|
||||||
// as JSON-RPC result field
|
// as JSON-RPC result field
|
||||||
type ProcessResponse struct {
|
type ProcessResponse struct {
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/config"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/config"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/internal"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/config"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/config"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/internal"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func setupTest() {
|
func setupTest() {
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/config"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/config"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/internal"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Monitor struct {
|
type Monitor struct {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/config"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
// In-Memory Thread-Safe Key-Value Storage with optional persistence
|
// In-Memory Thread-Safe Key-Value Storage with optional persistence
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import (
|
|||||||
"log/slog"
|
"log/slog"
|
||||||
|
|
||||||
evbus "github.com/asaskevich/EventBus"
|
evbus "github.com/asaskevich/EventBus"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/config"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/config"
|
||||||
"golang.org/x/sync/semaphore"
|
"golang.org/x/sync/semaphore"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/config"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
type metadata struct {
|
type metadata struct {
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import (
|
|||||||
"log/slog"
|
"log/slog"
|
||||||
"regexp"
|
"regexp"
|
||||||
"slices"
|
"slices"
|
||||||
"sync"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"os"
|
"os"
|
||||||
@@ -19,7 +18,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/config"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
const downloadTemplate = `download:
|
const downloadTemplate = `download:
|
||||||
@@ -261,54 +260,6 @@ func (p *Process) Kill() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the available format for this URL
|
|
||||||
//
|
|
||||||
// TODO: Move out from process.go
|
|
||||||
func (p *Process) GetFormats() (DownloadFormats, error) {
|
|
||||||
cmd := exec.Command(config.Instance().DownloaderPath, p.Url, "-J")
|
|
||||||
|
|
||||||
stdout, err := cmd.Output()
|
|
||||||
if err != nil {
|
|
||||||
slog.Error("failed to retrieve metadata", slog.String("err", err.Error()))
|
|
||||||
return DownloadFormats{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
slog.Info(
|
|
||||||
"retrieving metadata",
|
|
||||||
slog.String("caller", "getFormats"),
|
|
||||||
slog.String("url", p.Url),
|
|
||||||
)
|
|
||||||
|
|
||||||
info := DownloadFormats{URL: p.Url}
|
|
||||||
best := Format{}
|
|
||||||
|
|
||||||
var (
|
|
||||||
wg sync.WaitGroup
|
|
||||||
decodingError error
|
|
||||||
)
|
|
||||||
|
|
||||||
wg.Add(2)
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
decodingError = json.Unmarshal(stdout, &info)
|
|
||||||
wg.Done()
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
decodingError = json.Unmarshal(stdout, &best)
|
|
||||||
wg.Done()
|
|
||||||
}()
|
|
||||||
|
|
||||||
wg.Wait()
|
|
||||||
|
|
||||||
if decodingError != nil {
|
|
||||||
return DownloadFormats{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
info.Best = best
|
|
||||||
|
|
||||||
return info, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Process) GetFileName(o *DownloadOutput) error {
|
func (p *Process) GetFileName(o *DownloadOutput) error {
|
||||||
cmd := exec.Command(
|
cmd := exec.Command(
|
||||||
config.Instance().DownloaderPath,
|
config.Instance().DownloaderPath,
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ import (
|
|||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/config"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/config"
|
||||||
middlewares "github.com/marcopeocchi/yt-dlp-web-ui/server/middleware"
|
middlewares "github.com/marcopeocchi/yt-dlp-web-ui/v3/server/middleware"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/openid"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/openid"
|
||||||
)
|
)
|
||||||
|
|
||||||
var upgrader = websocket.Upgrader{
|
var upgrader = websocket.Upgrader{
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/coreos/go-oidc/v3/oidc"
|
"github.com/coreos/go-oidc/v3/oidc"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/config"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/config"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package rest
|
|||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/internal"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ContainerArgs struct {
|
type ContainerArgs struct {
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ package rest
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/config"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/config"
|
||||||
middlewares "github.com/marcopeocchi/yt-dlp-web-ui/server/middleware"
|
middlewares "github.com/marcopeocchi/yt-dlp-web-ui/v3/server/middleware"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/openid"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/openid"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Container(args *ContainerArgs) *Handler {
|
func Container(args *ContainerArgs) *Handler {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/internal"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Handler struct {
|
type Handler struct {
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/config"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/config"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/internal"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/internal"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/internal/livestream"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/internal/livestream"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ package rpc
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/config"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/config"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/internal"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/internal"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/internal/livestream"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/internal/livestream"
|
||||||
middlewares "github.com/marcopeocchi/yt-dlp-web-ui/server/middleware"
|
middlewares "github.com/marcopeocchi/yt-dlp-web-ui/v3/server/middleware"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/openid"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/openid"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Dependency injection container.
|
// Dependency injection container.
|
||||||
|
|||||||
@@ -4,10 +4,11 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
|
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/internal"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/formats"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/internal/livestream"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/internal"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/sys"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/internal/livestream"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/updater"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/sys"
|
||||||
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/updater"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
@@ -21,12 +22,6 @@ type Pending []string
|
|||||||
|
|
||||||
type NoArgs struct{}
|
type NoArgs struct{}
|
||||||
|
|
||||||
type Args struct {
|
|
||||||
Id string
|
|
||||||
URL string
|
|
||||||
Params []string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exec spawns a Process.
|
// Exec spawns a Process.
|
||||||
// The result of the execution is the newly spawned process Id.
|
// The result of the execution is the newly spawned process Id.
|
||||||
func (s *Service) Exec(args internal.DownloadRequest, result *string) error {
|
func (s *Service) Exec(args internal.DownloadRequest, result *string) error {
|
||||||
@@ -91,7 +86,7 @@ func (s *Service) KillAllLivestream(args NoArgs, result *struct{}) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Progess retrieves the Progress of a specific Process given its Id
|
// Progess retrieves the Progress of a specific Process given its Id
|
||||||
func (s *Service) Progess(args Args, progress *internal.DownloadProgress) error {
|
func (s *Service) Progess(args internal.DownloadRequest, progress *internal.DownloadProgress) error {
|
||||||
proc, err := s.db.Get(args.Id)
|
proc, err := s.db.Get(args.Id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -102,13 +97,20 @@ func (s *Service) Progess(args Args, progress *internal.DownloadProgress) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Progess retrieves available format for a given resource
|
// Progess retrieves available format for a given resource
|
||||||
func (s *Service) Formats(args Args, meta *internal.DownloadFormats) error {
|
func (s *Service) Formats(args internal.DownloadRequest, meta *formats.Metadata) error {
|
||||||
var (
|
var err error
|
||||||
err error
|
|
||||||
p = internal.Process{Url: args.URL}
|
metadata, err := formats.ParseURL(args.URL)
|
||||||
)
|
if err != nil && metadata == nil {
|
||||||
*meta, err = p.GetFormats()
|
|
||||||
return err
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if metadata.IsPlaylist() {
|
||||||
|
go internal.PlaylistDetect(args, s.mq, s.db)
|
||||||
|
}
|
||||||
|
|
||||||
|
*meta = *metadata
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pending retrieves a slice of all Pending/Running processes ids
|
// Pending retrieves a slice of all Pending/Running processes ids
|
||||||
|
|||||||
@@ -19,16 +19,16 @@ import (
|
|||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/go-chi/cors"
|
"github.com/go-chi/cors"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/config"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/config"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/dbutil"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/dbutil"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/handlers"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/handlers"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/internal"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/internal"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/internal/livestream"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/internal/livestream"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/logging"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/logging"
|
||||||
middlewares "github.com/marcopeocchi/yt-dlp-web-ui/server/middleware"
|
middlewares "github.com/marcopeocchi/yt-dlp-web-ui/v3/server/middleware"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/openid"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/openid"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/rest"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/rest"
|
||||||
ytdlpRPC "github.com/marcopeocchi/yt-dlp-web-ui/server/rpc"
|
ytdlpRPC "github.com/marcopeocchi/yt-dlp-web-ui/v3/server/rpc"
|
||||||
|
|
||||||
_ "modernc.org/sqlite"
|
_ "modernc.org/sqlite"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/config"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/config"
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/internal"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/internal"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package updater
|
|||||||
import (
|
import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
|
||||||
"github.com/marcopeocchi/yt-dlp-web-ui/server/config"
|
"github.com/marcopeocchi/yt-dlp-web-ui/v3/server/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Update using the builtin function of yt-dlp
|
// Update using the builtin function of yt-dlp
|
||||||
|
|||||||
Reference in New Issue
Block a user