autobrr/pkg/newznab/feed.go
soup 0391629862
chore(license): update copyright year in headers (#1929)
* chore: update copyright year in license headers

* Revert "chore: update copyright year in license headers"

This reverts commit 3e58129c431b9a491089ce36b908f9bb6ba38ed3.

* chore: update copyright year in license headers

* fix: sort go imports

* fix: add missing license headers
2025-01-06 22:23:19 +01:00

147 lines
3.4 KiB
Go

// Copyright (c) 2021 - 2025, Ludvig Lundgren and the autobrr contributors.
// SPDX-License-Identifier: GPL-2.0-or-later
package newznab
import (
"encoding/xml"
"strconv"
"time"
"github.com/autobrr/autobrr/pkg/errors"
)
type Feed struct {
Channel Channel `xml:"channel"`
Raw string
}
func (f Feed) Len() int {
return len(f.Channel.Items)
}
type Channel struct {
Title string `xml:"title"`
Items []*FeedItem `xml:"item"`
}
type Response struct {
Channel struct {
Items []*FeedItem `xml:"item"`
} `xml:"channel"`
}
type FeedItem struct {
Title string `xml:"title,omitempty"`
GUID string `xml:"guid,omitempty"`
PubDate Time `xml:"pubDate,omitempty"`
Prowlarrindexer struct {
Text string `xml:",chardata"`
ID string `xml:"id,attr"`
} `xml:"prowlarrindexer,omitempty"`
Comments string `xml:"comments"`
Size string `xml:"size"`
Link string `xml:"link"`
Enclosure *Enclosure `xml:"enclosure,omitempty"`
Category []string `xml:"category,omitempty"`
Categories Categories
// attributes
TvdbId string `xml:"tvdb,omitempty"`
//TvMazeId string
ImdbId string `xml:"imdb,omitempty"`
TmdbId string `xml:"tmdb,omitempty"`
Attributes []ItemAttr `xml:"attr"`
}
type ItemAttr struct {
Name string `xml:"name,attr"`
Value string `xml:"value,attr"`
}
type Enclosure struct {
Url string `xml:"url,attr"`
Length string `xml:"length,attr"`
Type string `xml:"type,attr"`
}
func (f *FeedItem) MapCategoriesFromAttr() {
for _, attr := range f.Attributes {
if attr.Name == "category" {
catId, err := strconv.Atoi(attr.Value)
if err != nil {
continue
}
if catId > 0 && catId < 10000 {
f.Categories = append(f.Categories, ParentCategory(Category{ID: catId}))
}
} else if attr.Name == "size" {
if f.Size == "" && attr.Value != "" {
f.Size = attr.Value
}
}
}
}
func (f *FeedItem) MapCustomCategoriesFromAttr(categories []Category) {
for _, attr := range f.Attributes {
if attr.Name == "category" {
catId, err := strconv.Atoi(attr.Value)
if err != nil {
continue
}
if catId > 0 && catId < 10000 {
f.Categories = append(f.Categories, ParentCategory(Category{ID: catId}))
} else if catId > 10000 {
// categories 10000+ are custom indexer specific
for _, capCat := range categories {
if capCat.ID == catId {
f.Categories = append(f.Categories, Category{
ID: capCat.ID,
Name: capCat.Name,
})
break
}
}
}
}
}
}
// Time credits: https://github.com/mrobinsn/go-newznab/blob/cd89d9c56447859fa1298dc9a0053c92c45ac7ef/newznab/structs.go#L150
type Time struct {
time.Time
}
func (t *Time) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
if err := e.EncodeToken(start); err != nil {
return errors.Wrap(err, "failed to encode xml token")
}
if err := e.EncodeToken(xml.CharData([]byte(t.UTC().Format(time.RFC1123Z)))); err != nil {
return errors.Wrap(err, "failed to encode xml token")
}
if err := e.EncodeToken(xml.EndElement{Name: start.Name}); err != nil {
return errors.Wrap(err, "failed to encode xml token")
}
return nil
}
func (t *Time) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var raw string
err := d.DecodeElement(&raw, &start)
if err != nil {
return errors.Wrap(err, "could not decode element")
}
date, err := time.Parse(time.RFC1123Z, raw)
if err != nil {
return errors.Wrap(err, "could not parse date")
}
*t = Time{date}
return nil
}