Compare commits

..

6 Commits

Author SHA1 Message Date
8a82e51292 custom path based frontend 2024-12-05 09:58:48 +01:00
0946d374e3 more examples 2024-11-23 09:53:44 +01:00
Marco Piovanello
f68c29f838 Update README.md 2024-11-19 11:43:42 +01:00
Marco Piovanello
c46e39e736 code refactoring (#227) 2024-11-19 11:36:36 +01:00
Marco Piovanello
2885d6b5d8 Update README.md 2024-11-17 08:58:08 +01:00
Marco Piovanello
ab7932ae92 Editable templates (#225)
* editable templates

* removed unused import
2024-11-15 14:24:44 +01:00
8 changed files with 133 additions and 35 deletions

View File

@@ -1,3 +1,7 @@
> [!NOTE]
> A poll is up to decide the future of yt-dlp-web-ui frontend! If you're interested you can take part.
> https://github.com/marcopeocchi/yt-dlp-web-ui/discussions/223
# yt-dlp Web UI # yt-dlp Web UI
A not so terrible web ui for yt-dlp. A not so terrible web ui for yt-dlp.
@@ -151,6 +155,8 @@ Usage yt-dlp-webui:
session file path (default ".") session file path (default ".")
-user string -user string
Username required for auth Username required for auth
-web string
frontend web resources path
``` ```
### Config file ### Config file
@@ -180,7 +186,7 @@ password: my_random_secret
queue_size: 4 # min. 2 queue_size: 4 # min. 2
# [optional] Full path to the yt-dlp (default: "yt-dlp") # [optional] Full path to the yt-dlp (default: "yt-dlp")
downloaderPath: /usr/local/bin/yt-dlp #downloaderPath: /usr/local/bin/yt-dlp
# [optional] Enable file based logging with rotation (default: false) # [optional] Enable file based logging with rotation (default: false)
#enable_file_logging: false #enable_file_logging: false
@@ -193,6 +199,9 @@ downloaderPath: /usr/local/bin/yt-dlp
# [optional] Path where the sqlite database will be created/opened (default: "./local.db") # [optional] Path where the sqlite database will be created/opened (default: "./local.db")
#local_database_path #local_database_path
# [optional] Path where a custom frontend will be loaded (instead of the embedded one)
#frontend_path: ./web/solid-frontend
``` ```
### Systemd integration ### Systemd integration
@@ -258,6 +267,22 @@ It is **planned** to also expose a **gRPC** server.
For more information open an issue on GitHub and I will provide more info ASAP. For more information open an issue on GitHub and I will provide more info ASAP.
## Custom frontend
To load a custom frontend you need to specify its path either in the config file ([see config file](#config-file)) or via flags.
The frontend needs to follow this structure:
```
path/to/my/frontend
├── assets
│ ├── js-chunk-1.js (example)
│ ├── js-chunk-2.js (example)
│ ├── style.css (example)
└── index.html
```
`assets` is where the resources will be loaded.
`index.html` is the entrypoint.
## Nix ## Nix
This repo adds support for Nix(OS) in various ways through a `flake-parts` flake. This repo adds support for Nix(OS) in various ways through a `flake-parts` flake.
For more info, please refer to the [official documentation](https://nixos.org/learn/). For more info, please refer to the [official documentation](https://nixos.org/learn/).

View File

@@ -0,0 +1,27 @@
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://app:3033;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
client_max_body_size 20000m;
proxy_connect_timeout 5000;
proxy_send_timeout 5000;
proxy_read_timeout 5000;
send_timeout 5000;
}
}

View File

@@ -0,0 +1,15 @@
services:
app:
image: marcobaobao/yt-dlp-webui
volumes:
- ./downloads:/downloads
restart: unless-stopped
nginx:
image: nginx:alpine
restart: unless-stopped
volumes:
- ./app.conf:/etc/nginx/conf.d/app.conf
depends_on:
- app
ports:
- 80:80

View File

@@ -0,0 +1,33 @@
import { Button, CircularProgress } from '@mui/material'
import { useI18n } from '../hooks/useI18n'
import { useRPC } from '../hooks/useRPC'
import { useState } from 'react'
import { useToast } from '../hooks/toast'
const UpdateBinaryButton: React.FC = () => {
const { i18n } = useI18n()
const { client } = useRPC()
const { pushMessage } = useToast()
const [isLoading, setIsLoading] = useState(false)
const updateBinary = () => {
setIsLoading(true)
client
.updateExecutable()
.then(() => pushMessage(i18n.t('toastUpdated'), 'success'))
.then(() => setIsLoading(false))
}
return (
<Button
variant="contained"
endIcon={isLoading ? <CircularProgress size={16} color='secondary' /> : <></>}
onClick={updateBinary}
>
{i18n.t('updateBinButton')}
</Button>
)
}
export default UpdateBinaryButton

View File

@@ -191,4 +191,11 @@ export class RPCClient {
params: [] params: []
}) })
} }
public updateExecutable() {
return this.sendHTTP({
method: 'Service.UpdateExecutable',
params: []
})
}
} }

View File

@@ -1,5 +1,4 @@
import { import {
Button,
Checkbox, Checkbox,
Container, Container,
FormControl, FormControl,
@@ -18,6 +17,7 @@ import {
Typography, Typography,
capitalize capitalize
} from '@mui/material' } from '@mui/material'
import { useAtom } from 'jotai'
import { Suspense, useEffect, useMemo, useState } from 'react' import { Suspense, useEffect, useMemo, useState } from 'react'
import { import {
Subject, Subject,
@@ -44,11 +44,10 @@ import {
themeState themeState
} from '../atoms/settings' } from '../atoms/settings'
import CookiesTextField from '../components/CookiesTextField' import CookiesTextField from '../components/CookiesTextField'
import UpdateBinaryButton from '../components/UpdateBinaryButton'
import { useToast } from '../hooks/toast' import { useToast } from '../hooks/toast'
import { useI18n } from '../hooks/useI18n' import { useI18n } from '../hooks/useI18n'
import { useRPC } from '../hooks/useRPC'
import { validateDomain, validateIP } from '../utils' import { validateDomain, validateIP } from '../utils'
import { useAtom } from 'jotai'
// NEED ABSOLUTELY TO BE SPLIT IN MULTIPLE COMPONENTS // NEED ABSOLUTELY TO BE SPLIT IN MULTIPLE COMPONENTS
export default function Settings() { export default function Settings() {
@@ -72,7 +71,6 @@ export default function Settings() {
const [invalidIP, setInvalidIP] = useState(false) const [invalidIP, setInvalidIP] = useState(false)
const { i18n } = useI18n() const { i18n } = useI18n()
const { client } = useRPC()
const { pushMessage } = useToast() const { pushMessage } = useToast()
@@ -140,13 +138,6 @@ export default function Settings() {
setTheme(event.target.value as Theme) setTheme(event.target.value as Theme)
} }
/**
* Updates yt-dlp binary via RPC
*/
const updateBinary = () => {
client.updateExecutable().then(() => pushMessage(i18n.t('toastUpdated'), 'success'))
}
return ( return (
<Container maxWidth="xl" sx={{ mt: 4, mb: 8 }}> <Container maxWidth="xl" sx={{ mt: 4, mb: 8 }}>
<Paper <Paper
@@ -352,14 +343,8 @@ export default function Settings() {
</Suspense> </Suspense>
</Grid> </Grid>
<Grid> <Grid>
<Stack direction="row"> <Stack direction="row" sx={{ pt: 2 }}>
<Button <UpdateBinaryButton />
sx={{ mr: 1, mt: 3 }}
variant="contained"
onClick={() => updateBinary()}
>
{i18n.t('updateBinButton')}
</Button>
</Stack> </Stack>
</Grid> </Grid>
</Paper> </Paper>

View File

@@ -23,6 +23,7 @@ var (
downloaderPath string downloaderPath string
sessionFilePath string sessionFilePath string
localDatabasePath string localDatabasePath string
frontendPath string
requireAuth bool requireAuth bool
username string username string
@@ -52,6 +53,7 @@ func init() {
flag.StringVar(&downloaderPath, "driver", "yt-dlp", "yt-dlp executable path") flag.StringVar(&downloaderPath, "driver", "yt-dlp", "yt-dlp executable path")
flag.StringVar(&sessionFilePath, "session", ".", "session file path") flag.StringVar(&sessionFilePath, "session", ".", "session file path")
flag.StringVar(&localDatabasePath, "db", "local.db", "local database path") flag.StringVar(&localDatabasePath, "db", "local.db", "local database path")
flag.StringVar(&frontendPath, "web", "", "frontend web resources path")
flag.BoolVar(&enableFileLogging, "fl", false, "enable outputting logs to a file") flag.BoolVar(&enableFileLogging, "fl", false, "enable outputting logs to a file")
flag.StringVar(&logFile, "lf", "yt-dlp-webui.log", "set log file location") flag.StringVar(&logFile, "lf", "yt-dlp-webui.log", "set log file location")
@@ -69,6 +71,10 @@ func main() {
log.Fatalln(err) log.Fatalln(err)
} }
if frontendPath != "" {
frontend = os.DirFS(frontendPath)
}
c := config.Instance() c := config.Instance()
{ {

View File

@@ -9,26 +9,26 @@ import (
) )
type Config struct { type Config struct {
LogPath string `yaml:"log_path"` LogPath string `yaml:"log_path"`
EnableFileLogging bool `yaml:"enable_file_logging"` EnableFileLogging bool `yaml:"enable_file_logging"`
BaseURL string `yaml:"base_url"` BaseURL string `yaml:"base_url"`
Host string `yaml:"host"` Host string `yaml:"host"`
Port int `yaml:"port"` Port int `yaml:"port"`
DownloadPath string `yaml:"downloadPath"` DownloadPath string `yaml:"downloadPath"`
DownloaderPath string `yaml:"downloaderPath"` DownloaderPath string `yaml:"downloaderPath"`
RequireAuth bool `yaml:"require_auth"` RequireAuth bool `yaml:"require_auth"`
Username string `yaml:"username"` Username string `yaml:"username"`
Password string `yaml:"password"` Password string `yaml:"password"`
QueueSize int `yaml:"queue_size"` QueueSize int `yaml:"queue_size"`
LocalDatabasePath string `yaml:"local_database_path"` LocalDatabasePath string `yaml:"local_database_path"`
SessionFilePath string `yaml:"session_file_path"` SessionFilePath string `yaml:"session_file_path"`
path string path string // private
UseOpenId bool `yaml:"use_openid"` UseOpenId bool `yaml:"use_openid"`
OpenIdProviderURL string `yaml:"openid_provider_url"` OpenIdProviderURL string `yaml:"openid_provider_url"`
OpenIdClientId string `yaml:"openid_client_id"` OpenIdClientId string `yaml:"openid_client_id"`
OpenIdClientSecret string `yaml:"openid_client_secret"` OpenIdClientSecret string `yaml:"openid_client_secret"`
OpenIdRedirectURL string `yaml:"openid_redirect_url"` OpenIdRedirectURL string `yaml:"openid_redirect_url"`
FrontendPath string `yaml:"frontend_path"`
} }
var ( var (