Feature: Get size by api for ptp btn and ggn (#66)

* chore: add package

* feat: get size by api for ptp and btn

* feat: download and parse torrent if not api

* feat: bypass tls check and load meta from file

* fix: no invite command needed for btn

* feat: add ggn api

* feat: imrpove logging

* feat: build request url

* feat: improve err logging
This commit is contained in:
Ludvig Lundgren 2022-01-05 23:52:29 +01:00 committed by GitHub
parent d2aa7c1e7e
commit 2ea2293745
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 2181 additions and 99 deletions

View file

@ -1,15 +1,14 @@
package client
import (
"crypto/md5"
"encoding/hex"
"errors"
"fmt"
"io"
"net/http"
"os"
"time"
"github.com/anacrolix/torrent/metainfo"
"github.com/rs/zerolog/log"
)
@ -18,6 +17,11 @@ type DownloadFileResponse struct {
FileName string
}
type DownloadTorrentFileResponse struct {
MetaInfo *metainfo.MetaInfo
TmpFileName string
}
type HttpClient struct {
http *http.Client
}
@ -33,42 +37,36 @@ func NewHttpClient() *HttpClient {
func (c *HttpClient) DownloadFile(url string, opts map[string]string) (*DownloadFileResponse, error) {
if url == "" {
return nil, nil
return nil, errors.New("download_file: url can't be empty")
}
// create md5 hash of url for tmp file
hash := md5.Sum([]byte(url))
hashString := hex.EncodeToString(hash[:])
tmpFileName := fmt.Sprintf("/tmp/%v", hashString)
// Create the file
out, err := os.Create(tmpFileName)
// Create tmp file
tmpFile, err := os.CreateTemp("", "autobrr-")
if err != nil {
log.Error().Stack().Err(err).Msgf("error creating temp file: %v", tmpFileName)
log.Error().Stack().Err(err).Msg("error creating temp file")
return nil, err
}
defer out.Close()
defer tmpFile.Close()
// Get the data
resp, err := http.Get(url)
if err != nil {
log.Error().Stack().Err(err).Msgf("error downloading file %v from %v", tmpFileName, url)
log.Error().Stack().Err(err).Msgf("error downloading file from %v", url)
return nil, err
}
defer resp.Body.Close()
// retry logic
if resp.StatusCode != 200 {
log.Error().Stack().Err(err).Msgf("error downloading file: %v - bad status: %d", tmpFileName, resp.StatusCode)
if resp.StatusCode != http.StatusOK {
log.Error().Stack().Err(err).Msgf("error downloading file from: %v - bad status: %d", url, resp.StatusCode)
return nil, err
}
// Write the body to file
_, err = io.Copy(out, resp.Body)
_, err = io.Copy(tmpFile, resp.Body)
if err != nil {
log.Error().Stack().Err(err).Msgf("error writing downloaded file: %v", tmpFileName)
log.Error().Stack().Err(err).Msgf("error writing downloaded file: %v", tmpFile.Name())
return nil, err
}
@ -76,7 +74,7 @@ func (c *HttpClient) DownloadFile(url string, opts map[string]string) (*Download
res := DownloadFileResponse{
Body: &resp.Body,
FileName: tmpFileName,
FileName: tmpFile.Name(),
}
if res.FileName == "" || res.Body == nil {
@ -84,7 +82,65 @@ func (c *HttpClient) DownloadFile(url string, opts map[string]string) (*Download
return nil, errors.New("error downloading file, no tmp file")
}
log.Debug().Msgf("successfully downloaded file: %v", tmpFileName)
log.Debug().Msgf("successfully downloaded file: %v", tmpFile.Name())
return &res, nil
}
func (c *HttpClient) DownloadTorrentFile(url string, opts map[string]string) (*DownloadTorrentFileResponse, error) {
if url == "" {
return nil, errors.New("download_file: url can't be empty")
}
// Create tmp file
tmpFile, err := os.CreateTemp("", "autobrr-")
if err != nil {
log.Error().Stack().Err(err).Msg("error creating temp file")
return nil, err
}
defer tmpFile.Close()
// Get the data
resp, err := http.Get(url)
if err != nil {
log.Error().Stack().Err(err).Msgf("error downloading file from %v", url)
return nil, err
}
defer resp.Body.Close()
// retry logic
if resp.StatusCode != http.StatusOK {
log.Error().Stack().Err(err).Msgf("error downloading file from: %v - bad status: %d", url, resp.StatusCode)
return nil, err
}
// Write the body to file
_, err = io.Copy(tmpFile, resp.Body)
if err != nil {
log.Error().Stack().Err(err).Msgf("error writing downloaded file: %v", tmpFile.Name())
return nil, err
}
meta, err := metainfo.Load(resp.Body)
if err != nil {
log.Error().Stack().Err(err).Msgf("metainfo could not load file contents: %v", tmpFile.Name())
return nil, err
}
// remove file if fail
res := DownloadTorrentFileResponse{
MetaInfo: meta,
TmpFileName: tmpFile.Name(),
}
if res.TmpFileName == "" || res.MetaInfo == nil {
log.Error().Stack().Err(err).Msgf("tmp file error - empty body: %v", url)
return nil, errors.New("error downloading file, no tmp file")
}
log.Debug().Msgf("successfully downloaded file: %v", tmpFile.Name())
return &res, nil
}