131 lines
3.2 KiB
Go
131 lines
3.2 KiB
Go
package handlers
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"seanime/internal/api/anilist"
|
|
"seanime/internal/updater"
|
|
"seanime/internal/util"
|
|
|
|
"github.com/labstack/echo/v4"
|
|
)
|
|
|
|
// HandleDownloadTorrentFile
|
|
//
|
|
// @summary downloads torrent files to the destination folder
|
|
// @route /api/v1/download-torrent-file [POST]
|
|
// @returns bool
|
|
func (h *Handler) HandleDownloadTorrentFile(c echo.Context) error {
|
|
|
|
type body struct {
|
|
DownloadUrls []string `json:"download_urls"`
|
|
Destination string `json:"destination"`
|
|
Media *anilist.BaseAnime `json:"media"`
|
|
}
|
|
|
|
var b body
|
|
if err := c.Bind(&b); err != nil {
|
|
return h.RespondWithError(c, err)
|
|
}
|
|
|
|
errs := make([]error, 0)
|
|
for _, url := range b.DownloadUrls {
|
|
err := downloadTorrentFile(url, b.Destination)
|
|
if err != nil {
|
|
errs = append(errs, err)
|
|
}
|
|
}
|
|
|
|
if len(errs) == 1 {
|
|
return h.RespondWithError(c, errs[0])
|
|
} else if len(errs) > 1 {
|
|
return h.RespondWithError(c, errors.New("failed to download multiple files"))
|
|
}
|
|
|
|
return h.RespondWithData(c, true)
|
|
}
|
|
|
|
func downloadTorrentFile(url string, dest string) (err error) {
|
|
|
|
defer util.HandlePanicInModuleWithError("handlers/download/downloadTorrentFile", &err)
|
|
|
|
// Get the file name from the URL
|
|
fileName := filepath.Base(url)
|
|
filePath := filepath.Join(dest, fileName)
|
|
|
|
// Get the data
|
|
resp, err := http.Get(url)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
// Check if the request was successful (status code 200)
|
|
if resp.StatusCode != http.StatusOK {
|
|
return fmt.Errorf("failed to download file, %s", resp.Status)
|
|
}
|
|
|
|
// Create the destination folder if it doesn't exist
|
|
err = os.MkdirAll(dest, 0755)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Create the file
|
|
out, err := os.Create(filePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer out.Close()
|
|
|
|
// Write the body to file
|
|
_, err = io.Copy(out, resp.Body)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
type DownloadReleaseResponse struct {
|
|
Destination string `json:"destination"`
|
|
Error string `json:"error,omitempty"`
|
|
}
|
|
|
|
// HandleDownloadRelease
|
|
//
|
|
// @summary downloads selected release asset to the destination folder.
|
|
// @desc Downloads the selected release asset to the destination folder and extracts it if possible.
|
|
// @desc If the extraction fails, the error message will be returned in the successful response.
|
|
// @desc The successful response will contain the destination path of the extracted files.
|
|
// @desc It only returns an error if the download fails.
|
|
// @route /api/v1/download-release [POST]
|
|
// @returns handlers.DownloadReleaseResponse
|
|
func (h *Handler) HandleDownloadRelease(c echo.Context) error {
|
|
|
|
type body struct {
|
|
DownloadUrl string `json:"download_url"`
|
|
Destination string `json:"destination"`
|
|
}
|
|
|
|
var b body
|
|
if err := c.Bind(&b); err != nil {
|
|
return h.RespondWithError(c, err)
|
|
}
|
|
|
|
path, err := h.App.Updater.DownloadLatestRelease(b.DownloadUrl, b.Destination)
|
|
|
|
if err != nil {
|
|
if errors.Is(err, updater.ErrExtractionFailed) {
|
|
return h.RespondWithData(c, DownloadReleaseResponse{Destination: path, Error: err.Error()})
|
|
}
|
|
return h.RespondWithError(c, err)
|
|
}
|
|
|
|
return h.RespondWithData(c, DownloadReleaseResponse{Destination: path})
|
|
}
|