Compare commits
11 Commits
feat-openi
...
326-securi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7539d8abf | ||
|
|
8a73079fad | ||
| f578f44cfd | |||
| cbe16c5c6c | |||
| 3cebaf7f61 | |||
|
|
2d2cb1dc3a | ||
|
|
43bcc40907 | ||
|
|
2af27e51be | ||
|
|
8c18242aaf | ||
|
|
66bebb2529 | ||
|
|
e223e030ac |
@@ -24,11 +24,12 @@ COPY --from=ui /usr/src/yt-dlp-webui/frontend /usr/src/yt-dlp-webui/frontend
|
|||||||
RUN CGO_ENABLED=0 GOOS=linux go build -o yt-dlp-webui
|
RUN CGO_ENABLED=0 GOOS=linux go build -o yt-dlp-webui
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
# dependencies ----------------------------------------------------------------
|
# Runtime ---------------------------------------------------------------------
|
||||||
FROM alpine:edge
|
FROM python:3.13.2-alpine3.21
|
||||||
|
|
||||||
RUN apk update && \
|
RUN apk update && \
|
||||||
apk add ffmpeg yt-dlp ca-certificates curl wget psmisc
|
apk add ffmpeg ca-certificates curl wget gnutls --no-cache && \
|
||||||
|
pip install "yt-dlp[default,curl-cffi,mutagen,pycryptodomex,phantomjs,secretstorage]"
|
||||||
|
|
||||||
VOLUME /downloads /config
|
VOLUME /downloads /config
|
||||||
|
|
||||||
@@ -39,4 +40,4 @@ COPY --from=build /usr/src/yt-dlp-webui/yt-dlp-webui /app
|
|||||||
ENV JWT_SECRET=secret
|
ENV JWT_SECRET=secret
|
||||||
|
|
||||||
EXPOSE 3033
|
EXPOSE 3033
|
||||||
ENTRYPOINT [ "./yt-dlp-webui" , "--out", "/downloads", "--conf", "/config/config.yml", "--db", "/config/local.db" ]
|
ENTRYPOINT [ "./yt-dlp-webui" , "--out", "/downloads", "--conf", "/config/config.yml", "--db", "/config/local.db" ]
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ docker pull ghcr.io/marcopiovanello/yt-dlp-web-ui:latest
|
|||||||
## Community stuff
|
## Community stuff
|
||||||
Feel free to join :)
|
Feel free to join :)
|
||||||
|
|
||||||
[](https://discord.gg/WRnVWr4y)
|
[Discord](https://discord.gg/GZAX5FfGzE)
|
||||||
|
|
||||||
## Some screeshots
|
## Some screeshots
|
||||||

|

|
||||||
|
|||||||
@@ -121,14 +121,18 @@ export const appTitleState = atomWithStorage(
|
|||||||
export const serverAddressAndPortState = atom((get) => {
|
export const serverAddressAndPortState = atom((get) => {
|
||||||
if (get(servedFromReverseProxySubDirState)) {
|
if (get(servedFromReverseProxySubDirState)) {
|
||||||
return `${get(serverAddressState)}/${get(servedFromReverseProxySubDirState)}/`
|
return `${get(serverAddressState)}/${get(servedFromReverseProxySubDirState)}/`
|
||||||
.replaceAll('"', '') // TODO: atomWithStorage put extra double quotes on strings
|
.replaceAll('"', '') // XXX: atomWithStorage uses JSON.stringify to serialize
|
||||||
|
.replaceAll('//', '/') // which puts extra double quotes.
|
||||||
}
|
}
|
||||||
if (get(servedFromReverseProxyState)) {
|
if (get(servedFromReverseProxyState)) {
|
||||||
return `${get(serverAddressState)}`
|
return `${get(serverAddressState)}`
|
||||||
.replaceAll('"', '')
|
.replaceAll('"', '')
|
||||||
}
|
}
|
||||||
return `${get(serverAddressState)}:${get(serverPortState)}`
|
|
||||||
|
const sap = `${get(serverAddressState)}:${get(serverPortState)}`
|
||||||
.replaceAll('"', '')
|
.replaceAll('"', '')
|
||||||
|
|
||||||
|
return sap.endsWith('/') ? sap.slice(0, -1) : sap
|
||||||
})
|
})
|
||||||
|
|
||||||
export const serverURL = atom((get) =>
|
export const serverURL = atom((get) =>
|
||||||
@@ -137,12 +141,16 @@ export const serverURL = atom((get) =>
|
|||||||
|
|
||||||
export const rpcWebSocketEndpoint = atom((get) => {
|
export const rpcWebSocketEndpoint = atom((get) => {
|
||||||
const proto = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
|
const proto = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
|
||||||
return `${proto}//${get(serverAddressAndPortState)}/rpc/ws`
|
const sap = get(serverAddressAndPortState)
|
||||||
|
|
||||||
|
return `${proto}//${sap.endsWith('/') ? sap.slice(0, -1) : sap}/rpc/ws`
|
||||||
})
|
})
|
||||||
|
|
||||||
export const rpcHTTPEndpoint = atom((get) => {
|
export const rpcHTTPEndpoint = atom((get) => {
|
||||||
const proto = window.location.protocol
|
const proto = window.location.protocol
|
||||||
return `${proto}//${get(serverAddressAndPortState)}/rpc/http`
|
const sap = get(serverAddressAndPortState)
|
||||||
|
|
||||||
|
return `${proto}//${sap.endsWith('/') ? sap.slice(0, -1) : sap}/rpc/http`
|
||||||
})
|
})
|
||||||
|
|
||||||
export const serverSideCookiesState = atom<Promise<string>>(async (get) => await pipe(
|
export const serverSideCookiesState = atom<Promise<string>>(async (get) => await pipe(
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ const HomeSpeedDial: React.FC<Props> = ({ onDownloadOpen, onEditorOpen }) => {
|
|||||||
ariaLabel="Home speed dial"
|
ariaLabel="Home speed dial"
|
||||||
sx={{ position: 'absolute', bottom: 64, right: 24 }}
|
sx={{ position: 'absolute', bottom: 64, right: 24 }}
|
||||||
icon={<SpeedDialIcon />}
|
icon={<SpeedDialIcon />}
|
||||||
|
onClick={onDownloadOpen}
|
||||||
>
|
>
|
||||||
<SpeedDialAction
|
<SpeedDialAction
|
||||||
icon={listView ? <ViewAgendaIcon /> : <FormatListBulleted />}
|
icon={listView ? <ViewAgendaIcon /> : <FormatListBulleted />}
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
import { tryCatch } from 'fp-ts/TaskEither'
|
import { tryCatch } from 'fp-ts/TaskEither'
|
||||||
|
import * as J from 'fp-ts/Json'
|
||||||
|
import * as E from 'fp-ts/Either'
|
||||||
|
import { pipe } from 'fp-ts/lib/function'
|
||||||
|
|
||||||
async function fetcher<T>(url: string, opt?: RequestInit): Promise<T> {
|
async function fetcher(url: string, opt?: RequestInit, controller?: AbortController): Promise<string> {
|
||||||
const jwt = localStorage.getItem('token')
|
const jwt = localStorage.getItem('token')
|
||||||
|
|
||||||
if (opt && !opt.headers) {
|
if (opt && !opt.headers) {
|
||||||
@@ -14,17 +17,27 @@ async function fetcher<T>(url: string, opt?: RequestInit): Promise<T> {
|
|||||||
headers: {
|
headers: {
|
||||||
...opt?.headers,
|
...opt?.headers,
|
||||||
'X-Authentication': jwt ?? ''
|
'X-Authentication': jwt ?? ''
|
||||||
}
|
},
|
||||||
|
signal: controller?.signal
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
throw await res.text()
|
throw await res.text()
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.json() as T
|
|
||||||
|
|
||||||
|
return res.text()
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ffetch = <T>(url: string, opt?: RequestInit) => tryCatch(
|
export const ffetch = <T>(url: string, opt?: RequestInit, controller?: AbortController) => tryCatch(
|
||||||
() => fetcher<T>(url, opt),
|
async () => pipe(
|
||||||
|
await fetcher(url, opt, controller),
|
||||||
|
J.parse,
|
||||||
|
E.match(
|
||||||
|
(l) => l as T,
|
||||||
|
(r) => r as T
|
||||||
|
)
|
||||||
|
),
|
||||||
(e) => `error while fetching: ${e}`
|
(e) => `error while fetching: ${e}`
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ func (p *Process) Start() {
|
|||||||
|
|
||||||
baseParams := []string{
|
baseParams := []string{
|
||||||
strings.Split(p.Url, "?list")[0], //no playlist
|
strings.Split(p.Url, "?list")[0], //no playlist
|
||||||
|
"--no-exec",
|
||||||
"--newline",
|
"--newline",
|
||||||
"--no-colors",
|
"--no-colors",
|
||||||
"--no-playlist",
|
"--no-playlist",
|
||||||
|
|||||||
Reference in New Issue
Block a user