Compare commits

..

22 Commits

Author SHA1 Message Date
de798246b9 ci: run every 2 days
All checks were successful
Build and Deploy ytdlp-site / build-deploy (push) Successful in 35s
2025-10-23 23:02:41 +00:00
1b9fb93cf6 Update .gitea/workflows/build-deploy.yml
All checks were successful
Build and Deploy ytdlp-site / build-deploy (push) Successful in 4m47s
2025-10-23 00:36:12 +00:00
667f2a88ba go.mod: 1.23.0 -> 1.24.5
All checks were successful
Build and Deploy ytdlp-site / build-deploy (push) Successful in 4m15s
Signed-off-by: Carl Pearson <me@carlpearson.net>
2025-10-06 05:46:45 -06:00
ee4be382b9 improve logging
Some checks failed
Build and Deploy ytdlp-site / build-deploy (push) Has been cancelled
Signed-off-by: Carl Pearson <me@carlpearson.net>
2025-10-06 05:44:54 -06:00
12137b1fa8 rate -> kbps
Signed-off-by: Carl Pearson <me@carlpearson.net>
2025-10-06 05:44:40 -06:00
18d640ab1f remove unused user registration code
Some checks failed
Build and Deploy ytdlp-site / build-deploy (push) Has been cancelled
Signed-off-by: Carl Pearson <me@carlpearson.net>
2025-10-06 05:40:48 -06:00
fab6ba9216 Update build and deploy containers to trixie
All checks were successful
Build and Deploy ytdlp-site / build-deploy (push) Successful in 3m17s
2025-09-27 05:51:35 -06:00
36d3505746 fix deno install
All checks were successful
Build and Deploy ytdlp-site / build-deploy (push) Successful in 1m43s
2025-09-27 05:47:11 -06:00
5551ad78b9 better yt-dlp logging
All checks were successful
Build and Deploy ytdlp-site / build-deploy (push) Successful in 1m23s
2025-09-27 05:38:04 -06:00
204decf1dc Add deno to path
All checks were successful
Build and Deploy ytdlp-site / build-deploy (push) Successful in 26s
2025-09-24 08:47:56 -06:00
f3d454988a docker: install deno
Some checks failed
Build and Deploy ytdlp-site / build-deploy (push) Has been cancelled
2025-09-24 08:47:15 -06:00
e2ac4ec983 install deno
Some checks failed
Build and Deploy ytdlp-site / build-deploy (push) Has been cancelled
2025-09-24 08:46:19 -06:00
e1fd6fbeb7 ubuntu_install_docker: non-interactive frontend
All checks were successful
Build and Deploy ytdlp-site / build-deploy (push) Successful in 1m9s
2025-09-24 05:19:35 -06:00
61b7d4c2ca noninteractive docker setup
All checks were successful
Build and Deploy ytdlp-site / build-deploy (push) Successful in 1m12s
2025-09-24 05:17:07 -06:00
4b36be3819 Allow schedule to push to registry
Some checks failed
Build and Deploy ytdlp-site / build-deploy (push) Has been cancelled
2025-09-24 05:14:52 -06:00
f668f59f70 ci: github -> gitea
All checks were successful
Build and Deploy ytdlp-site / build-deploy (push) Successful in 1m12s
2025-09-01 04:27:47 -06:00
91a9c69cba ci: run every friday
All checks were successful
Build and Deploy ytdlp-site / build-deploy (push) Successful in 1m37s
2025-08-29 10:10:15 -06:00
2b00bec445 fix Docerfile capitalization
All checks were successful
Build and Deploy ytdlp-site / build-deploy (push) Successful in 1m35s
2025-08-29 09:42:27 -06:00
54c6740dfe remove sr.ht build config
Some checks failed
Build and Deploy ytdlp-site / build-deploy (push) Has been cancelled
2025-08-29 09:42:09 -06:00
5ef8692a3a ci: secrets
All checks were successful
Build and Deploy ytdlp-site / build-deploy (push) Successful in 2m12s
2025-08-29 09:33:27 -06:00
e5e1987bd1 ci: ubuntu
Some checks failed
Build and Deploy ytdlp-site / build-deploy (push) Failing after 1m38s
2025-08-29 09:18:38 -06:00
ff3b2765a7 ci: gitea
Some checks failed
Build and Deploy ytdlp-site / build-deploy (push) Has been cancelled
2025-08-29 09:15:54 -06:00
9 changed files with 104 additions and 70 deletions

View File

@@ -1,33 +0,0 @@
image: debian/bookworm
secrets:
- a19cbc4c-b6a1-414e-bf1c-1e06abc684eb
tasks:
- print-env: |
echo "$JOB_ID"
echo "$JOB_URL"
echo "$BUILD_SUBMITTER"
echo "$BUILD_REASON"
echo "$GIT_REF"
- setup-env: |
sudo timedatectl set-timezone America/Denver
echo "SLUG=ghcr.io/cwpearson/ytdlp-site" >> ~/.buildenv
echo "DATE=$(date +"%Y%m%d_%H%M")" >> ~/.buildenv
- prerequisites: |
bash ytdlp-site/.ci/debian_setup_docker.sh
- build: |
cd ytdlp-site
docker build . --file Dockerfile --build-arg GIT_SHA=$(git rev-parse HEAD) --tag "$SLUG:$DATE" --tag "$SLUG:latest"
- deploy: |
if [ "$GIT_REF" != "refs/heads/master" ]; then exit 0; fi
set +x
cat ~/.ghcr_token | docker login ghcr.io -u cwpearson --password-stdin
set -x
docker push "$SLUG:latest"
docker push "$SLUG:$DATE"
triggers:
- action: email
condition: failure
to: Carl Pearson <srht@carlpearson.net>

View File

@@ -1,3 +1,5 @@
export DEBIAN_FRONTEND=noninteractive
# Add Docker's official GPG key: # Add Docker's official GPG key:
sudo apt-get update sudo apt-get update
sudo apt-get install -y ca-certificates curl sudo apt-get install -y ca-certificates curl

View File

@@ -0,0 +1,19 @@
export DEBIAN_FRONTEND=noninteractive
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo usermod -aG docker $(whoami)

View File

@@ -0,0 +1,56 @@
name: Build and Deploy ytdlp-site
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:
schedule:
# Runs every 2 days at 2:30 AM UTC
- cron: '30 2 */2 * *'
env:
SLUG: git.carlpearson.net/cwpearson/ytdlp-site
TZ: America/Denver
jobs:
build-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Print environment info
run: |
echo "Job ID: ${{ github.run_id }}"
echo "Job URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
echo "Build Submitter: ${{ github.actor }}"
echo "Build Reason: ${{ github.event_name }}"
echo "Git Ref: ${{ github.ref }}"
- name: Setup environment
run: |
echo "DATE=$(date +"%Y%m%d_%H%M")" >> $GITHUB_ENV
echo "GIT_SHA=$(git rev-parse HEAD)" >> $GITHUB_ENV
- name: Install docker
run: |
bash .ci/ubuntu_setup_docker.sh
- name: Build Docker image
run: |
docker build . \
--file Dockerfile \
--build-arg GIT_SHA=${{ env.GIT_SHA }} \
--tag ${{ env.SLUG }}:${{ env.DATE }} \
--tag ${{ env.SLUG }}:latest
- name: Deploy to Container Registry
if: gitea.ref == 'refs/heads/master' && (gitea.event_name == 'push' || gitea.event_name == 'schedule')
run: |
echo "${{ secrets.GIT_PASSWORD }}" | docker login git.carlpearson.net -u "${{ secrets.GIT_USERNAME }}" --password-stdin
docker push ${{ env.SLUG }}:latest
docker push ${{ env.SLUG }}:${{ env.DATE }}

View File

@@ -1,11 +1,15 @@
FROM golang:1.23.3-bookworm AS builder FROM golang:1.25.1-trixie AS builder
ARG GIT_SHA="<not provided>" ARG GIT_SHA="<not provided>"
# install yt-dlp
RUN apt-get update && apt-get install -y --no-install-recommends --no-install-suggests wget RUN apt-get update && apt-get install -y --no-install-recommends --no-install-suggests wget
RUN wget -q -d https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_linux -O /usr/local/bin/yt-dlp \ RUN wget -q -d https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_linux -O /usr/local/bin/yt-dlp \
&& chmod +x /usr/local/bin/yt-dlp && chmod +x /usr/local/bin/yt-dlp
# install deno
RUN apt-get update && apt-get install -y --no-install-recommends --no-install-suggests curl unzip
RUN curl -fsSL https://deno.land/install.sh | sh
ADD *.go /src/. ADD *.go /src/.
ADD config /src/config ADD config /src/config
ADD database /src/database ADD database /src/database
@@ -13,24 +17,30 @@ ADD ffmpeg /src/ffmpeg
ADD handlers /src/handlers ADD handlers /src/handlers
ADD media /src/media ADD media /src/media
ADD originals /src/originals ADD originals /src/originals
Add playlists /src/playlists ADD playlists /src/playlists
ADD transcodes /src/transcodes ADD transcodes /src/transcodes
ADD users /src/users ADD users /src/users
Add ytdlp /src/ytdlp ADD ytdlp /src/ytdlp
ADD go.mod /src/. ADD go.mod /src/.
RUN cd /src && go mod tidy RUN cd /src && go mod tidy
RUN cd /src && go build -ldflags "-X ytdlp-site/config.gitSHA=${GIT_SHA} -X ytdlp-site/config.buildDate=$(date +%Y-%m-%d)" -o server *.go RUN cd /src && go build -ldflags "-X ytdlp-site/config.gitSHA=${GIT_SHA} -X ytdlp-site/config.buildDate=$(date +%Y-%m-%d)" -o server *.go
FROM debian:bookworm-slim FROM debian:trixie-slim
RUN apt-get update \ RUN apt-get update \
&& apt-get install -y --no-install-recommends --no-install-suggests \ && apt-get install -y --no-install-recommends --no-install-suggests \
ffmpeg \ ffmpeg \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
# copy yt-dlp
COPY --from=0 /usr/local/bin/yt-dlp /usr/local/bin/yt-dlp COPY --from=0 /usr/local/bin/yt-dlp /usr/local/bin/yt-dlp
COPY --from=0 /src/server /opt/server COPY --from=0 /src/server /opt/server
# copy deno
COPY --from=0 /root/.deno /root/.deno
ENV PATH="/root/.deno/bin:$PATH"
ADD templates /opt/templates ADD templates /opt/templates
ADD static /opt/static ADD static /opt/static

6
go.mod
View File

@@ -1,8 +1,8 @@
module ytdlp-site module ytdlp-site
go 1.23 go 1.24
toolchain go1.23.0 toolchain go1.24.5
require ( require (
github.com/google/uuid v1.6.0 github.com/google/uuid v1.6.0
@@ -10,6 +10,7 @@ require (
github.com/labstack/echo/v4 v4.10.2 github.com/labstack/echo/v4 v4.10.2
github.com/sirupsen/logrus v1.9.3 github.com/sirupsen/logrus v1.9.3
golang.org/x/crypto v0.9.0 golang.org/x/crypto v0.9.0
golang.org/x/sys v0.8.0
gorm.io/driver/sqlite v1.5.1 gorm.io/driver/sqlite v1.5.1
gorm.io/gorm v1.25.1 gorm.io/gorm v1.25.1
) )
@@ -26,7 +27,6 @@ require (
github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect
golang.org/x/net v0.10.0 // indirect golang.org/x/net v0.10.0 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect golang.org/x/text v0.9.0 // indirect
golang.org/x/time v0.3.0 // indirect golang.org/x/time v0.3.0 // indirect
) )

View File

@@ -22,7 +22,6 @@ import (
"ytdlp-site/originals" "ytdlp-site/originals"
"ytdlp-site/playlists" "ytdlp-site/playlists"
"ytdlp-site/transcodes" "ytdlp-site/transcodes"
"ytdlp-site/users"
"ytdlp-site/ytdlp" "ytdlp-site/ytdlp"
) )
@@ -36,23 +35,6 @@ type DisplayVideoClip struct {
Stop string Stop string
} }
func registerHandler(c echo.Context) error {
return c.Render(http.StatusOK, "register.html", nil)
}
func registerPostHandler(c echo.Context) error {
username := c.FormValue("username")
password := c.FormValue("password")
err := users.Create(db, username, password)
if err != nil {
return c.String(http.StatusInternalServerError, "Error creating user")
}
return c.Redirect(http.StatusSeeOther, "/login")
}
func homeHandler(c echo.Context) error { func homeHandler(c echo.Context) error {
_, err := handlers.GetUser(c) _, err := handlers.GetUser(c)
if err != nil { if err != nil {
@@ -623,7 +605,7 @@ func startDownload(originalID uint, videoURL string, audioOnly bool) {
cmd.Dir = tempDir cmd.Dir = tempDir
err = cmd.Run() err = cmd.Run()
if err != nil { if err != nil {
log.Errorln("yt-dlp failed") log.Errorf("yt-dlp run error: %v")
originals.SetStatus(originalID, originals.StatusFailed) originals.SetStatus(originalID, originals.StatusFailed)
return return
} }

16
main.go
View File

@@ -1,7 +1,6 @@
package main package main
import ( import (
"fmt"
"html/template" "html/template"
"io" "io"
golog "log" golog "log"
@@ -95,24 +94,25 @@ func main() {
sqlDB.SetMaxOpenConns(1) sqlDB.SetMaxOpenConns(1)
// Migrate the schema // Migrate the schema
db.AutoMigrate(&originals.Original{}, &playlists.Playlist{}, if err := db.AutoMigrate(&originals.Original{}, &playlists.Playlist{},
&media.Video{}, &media.Audio{}, &media.VideoClip{}, &media.Video{}, &media.Audio{}, &media.VideoClip{},
&users.User{}, &TempURL{}, &transcodes.Transcode{}) &users.User{}, &TempURL{}, &transcodes.Transcode{}); err != nil {
log.Fatal(err)
}
database.Init(db, log) database.Init(db, log)
defer database.Fini() defer database.Fini()
err = handlers.Init(log) err = handlers.Init(log)
if err != nil { if err != nil {
panic(fmt.Sprintf("%v", err)) log.Fatal(err)
} }
defer handlers.Fini() defer handlers.Fini()
go PeriodicCleanup() go PeriodicCleanup()
// create a user // create a user
err = ensureAdminAccount(db) if err = ensureAdminAccount(db); err != nil {
if err != nil { log.Fatal("create admin account error:", err)
panic(fmt.Sprintf("failed to create admin user: %v", err))
} }
// Initialize Echo // Initialize Echo
@@ -132,8 +132,6 @@ func main() {
e.GET("/", homeHandler) e.GET("/", homeHandler)
e.GET("/login", handlers.LoginGet) e.GET("/login", handlers.LoginGet)
e.POST("/login", handlers.LoginPost) e.POST("/login", handlers.LoginPost)
// e.GET("/register", registerHandler)
// e.POST("/register", registerPostHandler)
e.GET("/logout", handlers.LogoutGet) e.GET("/logout", handlers.LogoutGet)
e.GET("/download", downloadHandler, handlers.AuthMiddleware) e.GET("/download", downloadHandler, handlers.AuthMiddleware)
e.POST("/download", downloadPostHandler, handlers.AuthMiddleware) e.POST("/download", downloadPostHandler, handlers.AuthMiddleware)

View File

@@ -277,7 +277,7 @@ func cleanupTranscodes() {
err := db.Where("status = ?", "pending"). err := db.Where("status = ?", "pending").
Order("CASE " + Order("CASE " +
"WHEN dst_kind = 'video' AND height = 540 THEN 0 " + "WHEN dst_kind = 'video' AND height = 540 THEN 0 " +
"WHEN dst_kind = 'audio' AND rate = 96 THEN 0 " + "WHEN dst_kind = 'audio' AND kbps = 96 THEN 0 " +
"ELSE 1 END").First(&trans).Error "ELSE 1 END").First(&trans).Error
// err := db.First(&trans, "status = ?", "pending").Error // err := db.First(&trans, "status = ?", "pending").Error
if err == gorm.ErrRecordNotFound { if err == gorm.ErrRecordNotFound {