mirror of
https://github.com/krau/SaveAny-Bot.git
synced 2026-05-10 17:52:44 +08:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3f7380341 | ||
|
|
6c6ee77067 | ||
|
|
f00aa189e3 | ||
|
|
48ceb87e29 | ||
|
|
cd663d05ca | ||
|
|
a778b0fa8c |
60
.github/workflows/build-docker.yml
vendored
Normal file
60
.github/workflows/build-docker.yml
vendored
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
name: Build and Publish Docker Image
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "v*"
|
||||||
|
|
||||||
|
env:
|
||||||
|
REGISTRY: ghcr.io
|
||||||
|
IMAGE_NAME: ${{ github.repository }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-push:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Login to GitHub Container Registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Extract metadata for Docker
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||||
|
tags: |
|
||||||
|
type=semver,pattern={{version}}
|
||||||
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
|
type=sha
|
||||||
|
type=raw,value=latest
|
||||||
|
type=ref,event=branch
|
||||||
|
type=ref,event=tag
|
||||||
|
labels: |
|
||||||
|
org.opencontainers.image.title=${{ env.IMAGE_NAME }}
|
||||||
|
org.opencontainers.image.source=https://github.com/krau/SaveAny-Bot
|
||||||
|
org.opencontainers.image.url=https://github.com/krau/SaveAny-Bot
|
||||||
|
|
||||||
|
- name: Build and push Docker image
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
push: true
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
@@ -23,7 +23,7 @@ jobs:
|
|||||||
- name: Setup node
|
- name: Setup node
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 20
|
node-version: 22
|
||||||
|
|
||||||
- run: npx changelogithub
|
- run: npx changelogithub
|
||||||
env:
|
env:
|
||||||
18
Dockerfile
Normal file
18
Dockerfile
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
FROM golang:alpine AS builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY go.* ./
|
||||||
|
RUN go mod download
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN CGO_ENABLED=0 GOOS=linux go build -o saveany-bot .
|
||||||
|
|
||||||
|
FROM alpine:latest
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY --from=builder /app/saveany-bot .
|
||||||
|
|
||||||
|
CMD ["./saveany-bot"]
|
||||||
25
README.md
25
README.md
@@ -29,6 +29,31 @@ chmod +x saveany-bot
|
|||||||
./saveany-bot
|
./saveany-bot
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 添加为 systemd 服务
|
||||||
|
|
||||||
|
创建文件 `/etc/systemd/system/saveany-bot.service` 并写入以下内容:
|
||||||
|
|
||||||
|
```
|
||||||
|
[Unit]
|
||||||
|
Description=SaveAnyBot
|
||||||
|
After=systemd-user-sessions.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
WorkingDirectory=/yourpath/
|
||||||
|
ExecStart=/yourpath/saveany-bot
|
||||||
|
Restart=on-failure
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
|
|
||||||
|
设为开机启动并启动服务:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl enable --now saveany-bot
|
||||||
|
```
|
||||||
|
|
||||||
## 更新
|
## 更新
|
||||||
|
|
||||||
使用 `upgrade` 或 `up` 升级到最新版
|
使用 `upgrade` 或 `up` 升级到最新版
|
||||||
|
|||||||
@@ -18,5 +18,5 @@ func Run(_ *cobra.Command, _ []string) {
|
|||||||
quit := make(chan os.Signal, 1)
|
quit := make(chan os.Signal, 1)
|
||||||
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
||||||
sig := <-quit
|
sig := <-quit
|
||||||
logger.L.Info(sig, "exit")
|
logger.L.Info(sig, ", exit")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,13 +3,14 @@ package config
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Workers int `toml:"workers" mapstructure:"workers"`
|
Workers int `toml:"workers" mapstructure:"workers"`
|
||||||
Retry int `toml:"retry" mapstructure:"retry"` // Retry times for failed tasks
|
Retry int `toml:"retry" mapstructure:"retry"`
|
||||||
|
|
||||||
Temp tempConfig `toml:"temp" mapstructure:"temp"`
|
Temp tempConfig `toml:"temp" mapstructure:"temp"`
|
||||||
Log logConfig `toml:"log" mapstructure:"log"`
|
Log logConfig `toml:"log" mapstructure:"log"`
|
||||||
@@ -79,7 +80,12 @@ var Cfg *Config
|
|||||||
func Init() {
|
func Init() {
|
||||||
viper.SetConfigName("config")
|
viper.SetConfigName("config")
|
||||||
viper.AddConfigPath(".")
|
viper.AddConfigPath(".")
|
||||||
|
viper.AddConfigPath("/etc/saveany/")
|
||||||
viper.SetConfigType("toml")
|
viper.SetConfigType("toml")
|
||||||
|
viper.SetEnvPrefix("SAVEANY")
|
||||||
|
viper.AutomaticEnv()
|
||||||
|
replacer := strings.NewReplacer(".", "_")
|
||||||
|
viper.SetEnvKeyReplacer(replacer)
|
||||||
|
|
||||||
viper.SetDefault("workers", 3)
|
viper.SetDefault("workers", 3)
|
||||||
viper.SetDefault("retry", 3)
|
viper.SetDefault("retry", 3)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
@@ -86,17 +87,36 @@ func (a *Alist) Init() {
|
|||||||
go refreshToken(reqClient)
|
go refreshToken(reqClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type putResponse struct {
|
||||||
|
Code int `json:"code"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
Data struct {
|
||||||
|
Task struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
State int `json:"state"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Progress int `json:"progress"`
|
||||||
|
Error string `json:"error"`
|
||||||
|
} `json:"task"`
|
||||||
|
} `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
func (a *Alist) Save(ctx context.Context, filePath, storagePath string) error {
|
func (a *Alist) Save(ctx context.Context, filePath, storagePath string) error {
|
||||||
storagePath = path.Join(basePath, storagePath)
|
storagePath = path.Join(basePath, storagePath)
|
||||||
file, err := os.Open(filePath)
|
file, err := os.Open(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
fileBytes, err := io.ReadAll(file)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
resp, err := reqClient.R().
|
resp, err := reqClient.R().
|
||||||
SetContext(ctx).
|
SetContext(ctx).
|
||||||
SetBody(file).
|
SetBodyBytes(fileBytes).
|
||||||
SetHeaders(map[string]string{
|
SetHeaders(map[string]string{
|
||||||
"File-Path": url.PathEscape(storagePath),
|
"File-Path": url.QueryEscape(storagePath),
|
||||||
"As-Task": "true",
|
"As-Task": "true",
|
||||||
}).Put("/api/fs/put")
|
}).Put("/api/fs/put")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -105,5 +125,12 @@ func (a *Alist) Save(ctx context.Context, filePath, storagePath string) error {
|
|||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return fmt.Errorf("failed to save file to Alist: %s", resp.Status)
|
return fmt.Errorf("failed to save file to Alist: %s", resp.Status)
|
||||||
}
|
}
|
||||||
|
var putResp putResponse
|
||||||
|
if err := json.Unmarshal(resp.Bytes(), &putResp); err != nil {
|
||||||
|
return fmt.Errorf("failed to unmarshal put response: %v", err)
|
||||||
|
}
|
||||||
|
if putResp.Code != http.StatusOK {
|
||||||
|
return fmt.Errorf("failed to save file to Alist: %d, %s", putResp.Code, putResp.Message)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user