Skip to content

Commit

Permalink
- Add Docker CI/CD
Browse files Browse the repository at this point in the history
- Implement UI for adding magnets
sirrobot01 committed Nov 28, 2024
1 parent df2aa4e commit 6912f99
Showing 52 changed files with 1,992 additions and 671 deletions.
52 changes: 52 additions & 0 deletions .air.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"

[build]
args_bin = []
bin = "./tmp/main"
cmd = "go build -o ./tmp/main ."
delay = 1000
exclude_dir = ["assets", "tmp", "vendor", "testdata", "data"]
exclude_file = []
exclude_regex = ["_test.go"]
exclude_unchanged = false
follow_symlink = false
full_bin = ""
include_dir = []
include_ext = ["go", "tpl", "tmpl", "html"]
include_file = []
kill_delay = "0s"
log = "build-errors.log"
poll = false
poll_interval = 0
post_cmd = []
pre_cmd = []
rerun = false
rerun_delay = 500
send_interrupt = false
stop_on_error = false

[color]
app = ""
build = "yellow"
main = "magenta"
runner = "green"
watcher = "cyan"

[log]
main_only = false
silent = false
time = false

[misc]
clean_on_exit = false

[proxy]
app_port = 0
enabled = false
proxy_port = 0

[screen]
clear_on_rebuild = false
keep_scroll = true
3 changes: 2 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -5,4 +5,5 @@ docker-compose.yml
.DS_Store
**/.idea/
*.magnet
**.torrent
**.torrent

55 changes: 55 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Docker Build and Push

on:
push:
branches:
- main
- beta

jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Get version
id: get_version
run: |
if [[ ${{ github.ref }} == 'refs/heads/main' ]]; then
# Extract version
VERSION=$(git describe --tags --abbrev=0)
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
fi
- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Build and push for beta branch
if: github.ref == 'refs/heads/beta'
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true
tags: cy01/blackhole:beta

- name: Build and push for main branch
if: github.ref == 'refs/heads/main'
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: true
tags: |
cy01/blackhole:latest
cy01/blackhole:${{ steps.get_version.outputs.VERSION }}
32 changes: 32 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Release

on:
push:
tags:
- '*'

permissions:
contents: write

jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.22'

- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v5
with:
distribution: goreleaser
version: latest
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -9,3 +9,4 @@ docker-compose.yml
*.log
*.log.*
dist/
tmp/**
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@ RUN CGO_ENABLED=0 GOOS=$(echo $TARGETPLATFORM | cut -d '/' -f1) GOARCH=$(echo $T
FROM scratch
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /blackhole /blackhole
COPY --from=builder /app/README.md /README.md

EXPOSE 8181

27 changes: 20 additions & 7 deletions cmd/main.go
Original file line number Diff line number Diff line change
@@ -2,39 +2,52 @@ package cmd

import (
"cmp"
"context"
"goBlack/common"
"goBlack/pkg/debrid"
"goBlack/pkg/proxy"
"goBlack/pkg/qbit"
"sync"
)

func Start(config *common.Config) {
func Start(ctx context.Context, config *common.Config) error {
maxCacheSize := cmp.Or(config.MaxCacheSize, 1000)
cache := common.NewCache(maxCacheSize)

deb := debrid.NewDebrid(config.Debrids, cache)

var wg sync.WaitGroup
errChan := make(chan error, 2)

if config.Proxy.Enabled {
p := proxy.NewProxy(*config, deb, cache)
wg.Add(1)
go func() {
defer wg.Done()
p.Start()
if err := proxy.NewProxy(*config, deb, cache).Start(ctx); err != nil {
errChan <- err
}
}()
}
if config.QBitTorrent.Port != "" {
qb := qbit.NewQBit(config, deb, cache)
wg.Add(1)
go func() {
defer wg.Done()
qb.Start()
if err := qbit.Start(ctx, config, deb, cache); err != nil {
errChan <- err
}
}()
}

// Wait indefinitely
wg.Wait()
go func() {
wg.Wait()
close(errChan)
}()

// Wait for context cancellation or completion or error
select {
case err := <-errChan:
return err
case <-ctx.Done():
return ctx.Err()
}
}
84 changes: 84 additions & 0 deletions common/config.go
Original file line number Diff line number Diff line change
@@ -2,8 +2,11 @@ package common

import (
"encoding/json"
"errors"
"fmt"
"log"
"os"
"sync"
)

type DebridConfig struct {
@@ -43,6 +46,82 @@ type Config struct {
QBitTorrent QBitTorrentConfig `json:"qbittorrent"`
}

func validateDebrids(debrids []DebridConfig) error {
if len(debrids) == 0 {
return errors.New("no debrids configured")
}

errChan := make(chan error, len(debrids))
var wg sync.WaitGroup

for _, debrid := range debrids {
// Basic field validation
if debrid.Host == "" {
return errors.New("debrid host is required")
}
if debrid.APIKey == "" {
return errors.New("debrid api key is required")
}
if debrid.Folder == "" {
return errors.New("debrid folder is required")
}

// Check folder existence concurrently
wg.Add(1)
go func(folder string) {
defer wg.Done()
if _, err := os.Stat(folder); os.IsNotExist(err) {
errChan <- fmt.Errorf("debrid folder does not exist: %s", folder)
}
}(debrid.Folder)
}

// Wait for all checks to complete
go func() {
wg.Wait()
close(errChan)
}()

// Return first error if any
if err := <-errChan; err != nil {
return err
}

return nil
}

func validateQbitTorrent(config *QBitTorrentConfig) error {
if config.DownloadFolder == "" {
return errors.New("qbittorent download folder is required")
}
if _, err := os.Stat(config.DownloadFolder); os.IsNotExist(err) {
return errors.New("qbittorent download folder does not exist")
}
return nil
}

func validateConfig(config *Config) error {
// Run validations concurrently
errChan := make(chan error, 2)

go func() {
errChan <- validateDebrids(config.Debrids)
}()

go func() {
errChan <- validateQbitTorrent(&config.QBitTorrent)
}()

// Check for errors
for i := 0; i < 2; i++ {
if err := <-errChan; err != nil {
return err
}
}

return nil
}

func LoadConfig(path string) (*Config, error) {
// Load the config file
file, err := os.Open(path)
@@ -67,5 +146,10 @@ func LoadConfig(path string) (*Config, error) {
config.Debrids = append(config.Debrids, config.Debrid)
}

// Validate the config
//if err := validateConfig(config); err != nil {
// return nil, err
//}

return config, nil
}
14 changes: 14 additions & 0 deletions common/logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package common

import (
"fmt"
"log"
"os"
)

func NewLogger(prefix string, output *os.File) *log.Logger {
f := fmt.Sprintf("[%s] ", prefix)
return log.New(output, f, log.LstdFlags)
}

var Logger = NewLogger("Main", os.Stdout)
7 changes: 7 additions & 0 deletions common/request.go
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@ package common

import (
"crypto/tls"
"encoding/json"
"fmt"
"golang.org/x/time/rate"
"io"
@@ -125,3 +126,9 @@ func ParseRateLimit(rateStr string) *rate.Limiter {
return nil
}
}

func JSONResponse(w http.ResponseWriter, data interface{}, code int) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(code)
json.NewEncoder(w).Encode(data)
}
Loading

0 comments on commit 6912f99

Please sign in to comment.