mirror of
https://github.com/idanoo/autobrr
synced 2025-07-23 08:49:13 +00:00
feat(releases): support magnet links (#730)
* feat(releases): support magnet links * feat(feeds): support magnet links * feat(actions): log messages * fix: component warning * fix: check hasprefix instead of hassuffix for magnet * feat(release): resolve magnet uri from link * fix(actions): deluge use magnet uri * fix(macros): add `MagnetURI` var * fix(actions): run magnet resolving before macros * feat(feeds): set download type on creation
This commit is contained in:
parent
c6101cc765
commit
ca196f0bf1
32 changed files with 770 additions and 260 deletions
|
@ -41,7 +41,7 @@ type Feed struct {
|
|||
Capabilities []string `json:"capabilities"`
|
||||
ApiKey string `json:"api_key"`
|
||||
Cookie string `json:"cookie"`
|
||||
Settings map[string]string `json:"settings"`
|
||||
Settings *FeedSettingsJSON `json:"settings"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
IndexerID int `json:"indexer_id,omitempty"`
|
||||
|
@ -50,6 +50,10 @@ type Feed struct {
|
|||
LastRunData string `json:"last_run_data"`
|
||||
}
|
||||
|
||||
type FeedSettingsJSON struct {
|
||||
DownloadType FeedDownloadType `json:"download_type"`
|
||||
}
|
||||
|
||||
type FeedIndexer struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
|
@ -63,6 +67,13 @@ const (
|
|||
FeedTypeRSS FeedType = "RSS"
|
||||
)
|
||||
|
||||
type FeedDownloadType string
|
||||
|
||||
const (
|
||||
FeedDownloadTypeMagnet FeedDownloadType = "MAGNET"
|
||||
FeedDownloadTypeTorrent FeedDownloadType = "TORRENT"
|
||||
)
|
||||
|
||||
type FeedCacheItem struct {
|
||||
Bucket string `json:"bucket"`
|
||||
Key string `json:"key"`
|
||||
|
|
|
@ -17,6 +17,7 @@ type Macro struct {
|
|||
TorrentHash string
|
||||
TorrentUrl string
|
||||
TorrentDataRawBytes []byte
|
||||
MagnetURI string
|
||||
Indexer string
|
||||
Title string
|
||||
Resolution string
|
||||
|
@ -44,6 +45,7 @@ func NewMacro(release Release) Macro {
|
|||
TorrentPathName: release.TorrentTmpFile,
|
||||
TorrentDataRawBytes: release.TorrentDataRawBytes,
|
||||
TorrentHash: release.TorrentHash,
|
||||
MagnetURI: release.MagnetURI,
|
||||
Indexer: release.Indexer,
|
||||
Title: release.Title,
|
||||
Resolution: release.Resolution,
|
||||
|
|
|
@ -46,6 +46,7 @@ type Release struct {
|
|||
Timestamp time.Time `json:"timestamp"`
|
||||
InfoURL string `json:"info_url"`
|
||||
TorrentURL string `json:"download_url"`
|
||||
MagnetURI string `json:"-"`
|
||||
GroupID string `json:"group_id"`
|
||||
TorrentID string `json:"torrent_id"`
|
||||
TorrentTmpFile string `json:"-"`
|
||||
|
@ -290,6 +291,10 @@ func (r *Release) DownloadTorrentFile() error {
|
|||
}
|
||||
|
||||
func (r *Release) downloadTorrentFile(ctx context.Context) error {
|
||||
if r.HasMagnetUri() {
|
||||
return fmt.Errorf("error trying to download magnet link: %s", r.MagnetURI)
|
||||
}
|
||||
|
||||
if r.TorrentURL == "" {
|
||||
return errors.New("download_file: url can't be empty")
|
||||
} else if r.TorrentTmpFile != "" {
|
||||
|
@ -389,6 +394,81 @@ func (r *Release) downloadTorrentFile(ctx context.Context) error {
|
|||
return errFunc
|
||||
}
|
||||
|
||||
// HasMagnetUri check uf MagnetURI is set or empty
|
||||
func (r *Release) HasMagnetUri() bool {
|
||||
return r.MagnetURI != ""
|
||||
}
|
||||
|
||||
type magnetRoundTripper struct{}
|
||||
|
||||
func (rt *magnetRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) {
|
||||
if r.URL.Scheme == "magnet" {
|
||||
responseBody := r.URL.String()
|
||||
respReader := io.NopCloser(strings.NewReader(responseBody))
|
||||
|
||||
resp := &http.Response{
|
||||
Status: http.StatusText(http.StatusOK),
|
||||
StatusCode: http.StatusOK,
|
||||
Body: respReader,
|
||||
ContentLength: int64(len(responseBody)),
|
||||
Header: map[string][]string{
|
||||
"Content-Type": {"text/plain"},
|
||||
"Location": {responseBody},
|
||||
},
|
||||
Proto: "HTTP/2.0",
|
||||
ProtoMajor: 2,
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
return http.DefaultTransport.RoundTrip(r)
|
||||
}
|
||||
|
||||
func (r *Release) ResolveMagnetUri(ctx context.Context) error {
|
||||
if r.MagnetURI == "" {
|
||||
return nil
|
||||
} else if strings.HasPrefix(r.MagnetURI, "magnet:?") {
|
||||
return nil
|
||||
}
|
||||
|
||||
client := http.Client{
|
||||
Transport: &magnetRoundTripper{},
|
||||
Timeout: time.Second * 60,
|
||||
}
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, r.MagnetURI, nil)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not build request to resolve magnet uri")
|
||||
}
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("User-Agent", "autobrr")
|
||||
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not make request to resolve magnet uri")
|
||||
}
|
||||
|
||||
defer res.Body.Close()
|
||||
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return errors.New("unexpected status code: %d", res.StatusCode)
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "could not read response body")
|
||||
}
|
||||
|
||||
magnet := string(body)
|
||||
if magnet != "" {
|
||||
r.MagnetURI = magnet
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Release) addRejection(reason string) {
|
||||
r.Rejections = append(r.Rejections, reason)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue