Compare commits
8 Commits
d40dce624b
...
renovate/g
Author | SHA1 | Date | |
---|---|---|---|
3de219c25d | |||
77c8c099ae | |||
b1b895b9c1 | |||
0fbfee706c
|
|||
0474c2dcb6
|
|||
50784a6ab5
|
|||
a01a4febf5
|
|||
1c8cd6ed32
|
@ -1,28 +1,34 @@
|
|||||||
name: Build and publish the docker image
|
name: docker
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: ["custom"]
|
branches:
|
||||||
|
- "main"
|
||||||
|
paths-ignore:
|
||||||
|
- "README.md"
|
||||||
|
- "LICENSE.txt"
|
||||||
|
- "docker-compose.example.yml"
|
||||||
|
- "ups.json"
|
||||||
|
|
||||||
env:
|
env:
|
||||||
REGISTRY: git.ngn.tf
|
REGISTRY: git.ngn.tf
|
||||||
IMAGE: ${{gitea.repository}}
|
IMAGE: ${{gitea.repository}}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
docker:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: "https://github.com/actions/checkout@v4"
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Login to container repo
|
- name: Login to container repo
|
||||||
uses: "https://github.com/docker/login-action@v1"
|
uses: docker/login-action@v1
|
||||||
with:
|
with:
|
||||||
registry: ${{env.REGISTRY}}
|
registry: ${{env.REGISTRY}}
|
||||||
username: ${{gitea.actor}}
|
username: ${{gitea.actor}}
|
||||||
password: ${{secrets.PACKAGES_TOKEN}}
|
password: ${{secrets.PACKAGES_TOKEN}}
|
||||||
|
|
||||||
- name: Build image
|
- name: Build docker image
|
||||||
run: |
|
run: |
|
||||||
docker build . --tag ${{env.REGISTRY}}/${{env.IMAGE}}:latest
|
docker build . --tag ${{env.REGISTRY}}/${{env.IMAGE}}:latest
|
||||||
docker push ${{env.REGISTRY}}/${{env.IMAGE}}:latest
|
docker push ${{env.REGISTRY}}/${{env.IMAGE}}:latest
|
25
.gitea/workflows/ups.yml
Normal file
25
.gitea/workflows/ups.yml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
name: ups
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "@weekly"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ups:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt update -y
|
||||||
|
sudo apt install -y python3 python3-build python3-requests make
|
||||||
|
|
||||||
|
- name: Install ups
|
||||||
|
run: |
|
||||||
|
git clone https://git.ngn.tf/ngn/ups && cd ups
|
||||||
|
make && make install
|
||||||
|
|
||||||
|
- name: Run ups
|
||||||
|
run: PATH=~/.local/bin:$PATH ups-check
|
@ -10,7 +10,7 @@ RUN go mod download
|
|||||||
COPY . .
|
COPY . .
|
||||||
RUN make CGO_ENABLED=0
|
RUN make CGO_ENABLED=0
|
||||||
|
|
||||||
FROM alpine:3.21
|
FROM alpine:3.22
|
||||||
|
|
||||||
COPY --from=build /code/dumb .
|
COPY --from=build /code/dumb .
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
# [ngn.tf] | dumb
|
# dumb - frontend for Genius
|
||||||
|
|
||||||

|

|
||||||
|

|
||||||
|
|
||||||
A fork of the [dumb](https://github.com/rramiachraf/dumb) project, with my personal changes.
|
A fork of the [dumb](https://github.com/rramiachraf/dumb) project, with my
|
||||||
|
personal changes.
|
||||||
|
@ -58,6 +58,8 @@ type customPerformance struct {
|
|||||||
func (s *Song) parseLyrics(doc *goquery.Document) error {
|
func (s *Song) parseLyrics(doc *goquery.Document) error {
|
||||||
var htmlError error
|
var htmlError error
|
||||||
|
|
||||||
|
doc.Find("[class^=LyricsHeader]").Remove()
|
||||||
|
|
||||||
doc.Find("[data-lyrics-container='true']").Each(func(i int, ss *goquery.Selection) {
|
doc.Find("[data-lyrics-container='true']").Each(func(i int, ss *goquery.Selection) {
|
||||||
h, err := ss.Html()
|
h, err := ss.Html()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
2
go.mod
2
go.mod
@ -6,7 +6,7 @@ toolchain go1.23.4
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/PuerkitoBio/goquery v1.10.1
|
github.com/PuerkitoBio/goquery v1.10.1
|
||||||
github.com/a-h/templ v0.3.819
|
github.com/a-h/templ v0.3.906
|
||||||
github.com/allegro/bigcache/v3 v3.1.0
|
github.com/allegro/bigcache/v3 v3.1.0
|
||||||
github.com/gorilla/handlers v1.5.2
|
github.com/gorilla/handlers v1.5.2
|
||||||
github.com/gorilla/mux v1.8.1
|
github.com/gorilla/mux v1.8.1
|
||||||
|
@ -47,7 +47,7 @@ func annotations(l *utils.Logger) http.HandlerFunc {
|
|||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
_, err = buf.ReadFrom(resp.Body)
|
_, err = buf.ReadFrom(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Error("Error paring genius api response: %s", err.Error())
|
l.Errorf("Error paring genius api response: %s", err.Error())
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
utils.RenderTemplate(w, views.ErrorPage(500, "something went wrong"), l)
|
utils.RenderTemplate(w, views.ErrorPage(500, "something went wrong"), l)
|
||||||
return
|
return
|
||||||
@ -56,7 +56,7 @@ func annotations(l *utils.Logger) http.HandlerFunc {
|
|||||||
var data data.AnnotationsResponse
|
var data data.AnnotationsResponse
|
||||||
err = json.Unmarshal(buf.Bytes(), &data)
|
err = json.Unmarshal(buf.Bytes(), &data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.Error("could not unmarshal json: %s\n", err)
|
l.Errorf("could not unmarshal json: %s\n", err)
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
utils.RenderTemplate(w, views.ErrorPage(500, "something went wrong"), l)
|
utils.RenderTemplate(w, views.ErrorPage(500, "something went wrong"), l)
|
||||||
return
|
return
|
||||||
@ -69,7 +69,7 @@ func annotations(l *utils.Logger) http.HandlerFunc {
|
|||||||
encoder := json.NewEncoder(w)
|
encoder := json.NewEncoder(w)
|
||||||
|
|
||||||
if err = encoder.Encode(&annotation); err != nil {
|
if err = encoder.Encode(&annotation); err != nil {
|
||||||
l.Error("Error sending response: %s", err.Error())
|
l.Errorf("Error sending response: %s", err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/PuerkitoBio/goquery"
|
"github.com/PuerkitoBio/goquery"
|
||||||
@ -25,6 +26,7 @@ func TestLyrics(t *testing.T) {
|
|||||||
func testLyrics(t *testing.T, url string) {
|
func testLyrics(t *testing.T, url string) {
|
||||||
title := "The Silver Seas"
|
title := "The Silver Seas"
|
||||||
artist := "Catch Yer Own Train"
|
artist := "Catch Yer Own Train"
|
||||||
|
firstLyricLine := "[Verse 1]"
|
||||||
|
|
||||||
r, err := http.NewRequest(http.MethodGet, url, nil)
|
r, err := http.NewRequest(http.MethodGet, url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -46,6 +48,7 @@ func testLyrics(t *testing.T, url string) {
|
|||||||
|
|
||||||
docArtist := doc.Find("#metadata-info h1").Text()
|
docArtist := doc.Find("#metadata-info h1").Text()
|
||||||
docTitle := doc.Find("#metadata-info h2").Text()
|
docTitle := doc.Find("#metadata-info h2").Text()
|
||||||
|
docLyrics := doc.Find("#lyrics").Text()
|
||||||
|
|
||||||
if docTitle != title {
|
if docTitle != title {
|
||||||
t.Fatalf("expected %q, got %q\n", title, docTitle)
|
t.Fatalf("expected %q, got %q\n", title, docTitle)
|
||||||
@ -54,4 +57,8 @@ func testLyrics(t *testing.T, url string) {
|
|||||||
if docArtist != artist {
|
if docArtist != artist {
|
||||||
t.Fatalf("expected %q, got %q\n", artist, docArtist)
|
t.Fatalf("expected %q, got %q\n", artist, docArtist)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !strings.HasPrefix(docLyrics, firstLyricLine) {
|
||||||
|
t.Fatalf("expected lyrics to start with %q, got %q\n", firstLyricLine, docLyrics)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ func imageProxy(l *utils.Logger) http.HandlerFunc {
|
|||||||
w.Header().Set("Content-type", mime.TypeByExtension("."+ext))
|
w.Header().Set("Content-type", mime.TypeByExtension("."+ext))
|
||||||
w.Header().Add("Cache-Control", "max-age=1296000")
|
w.Header().Add("Cache-Control", "max-age=1296000")
|
||||||
if _, err = io.Copy(w, res.Body); err != nil {
|
if _, err = io.Copy(w, res.Body); err != nil {
|
||||||
l.Error("unable to write image, %s", err.Error())
|
l.Errorf("unable to write image, %s", err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
4
main.go
4
main.go
@ -39,7 +39,7 @@ func main() {
|
|||||||
|
|
||||||
if port == 0 {
|
if port == 0 {
|
||||||
port = 5555
|
port = 5555
|
||||||
logger.Info("using default port %d", port)
|
logger.Infof("using default port %d", port)
|
||||||
}
|
}
|
||||||
|
|
||||||
l, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
|
l, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
|
||||||
@ -47,7 +47,7 @@ func main() {
|
|||||||
logger.Fatal(err.Error())
|
logger.Fatal(err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info("server is listening on port %d", port)
|
logger.Infof("server is listening on port %d", port)
|
||||||
|
|
||||||
if err := server.Serve(l); err != nil {
|
if err := server.Serve(l); err != nil {
|
||||||
logger.Fatal(err.Error())
|
logger.Fatal(err.Error())
|
||||||
|
5
ups.json
Normal file
5
ups.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"upstream": "https://github.com/rramiachraf/dumb",
|
||||||
|
"provider": "github",
|
||||||
|
"commit": "f5df91fffe50283295f82488e4ec63a4be23f04e"
|
||||||
|
}
|
@ -18,15 +18,27 @@ func NewLogger(w io.WriteCloser) *Logger {
|
|||||||
return &Logger{slog: sl}
|
return &Logger{slog: sl}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Error(f string, args ...any) {
|
func (l *Logger) Errorf(f string, args ...any) {
|
||||||
l.slog.Error(fmt.Sprintf(f, args...))
|
l.slog.Error(fmt.Sprintf(f, args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Info(f string, args ...any) {
|
func (l *Logger) Error(e string) {
|
||||||
|
l.Errorf("%s", e)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Logger) Infof(f string, args ...any) {
|
||||||
l.slog.Info(fmt.Sprintf(f, args...))
|
l.slog.Info(fmt.Sprintf(f, args...))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) Fatal(f string, args ...any) {
|
func (l *Logger) Info(m string) {
|
||||||
l.Error(f, args...)
|
l.Infof("%s", m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Logger) Fatalf(f string, args ...any) {
|
||||||
|
l.Errorf(f, args...)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *Logger) Fatal(e string) {
|
||||||
|
l.Fatalf("%s", e)
|
||||||
|
}
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
|
|
||||||
func RenderTemplate(w http.ResponseWriter, t templ.Component, l *Logger) {
|
func RenderTemplate(w http.ResponseWriter, t templ.Component, l *Logger) {
|
||||||
if err := t.Render(context.Background(), w); err != nil {
|
if err := t.Render(context.Background(), w); err != nil {
|
||||||
l.Error("unable to render template %s", err)
|
l.Errorf("unable to render template %s", err)
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
_, err := w.Write([]byte{})
|
_, err := w.Write([]byte{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Reference in New Issue
Block a user