Fixed rutracker after changing stucture of the atom file of theirs own

This commit is contained in:
Yevhen Odynets
2026-08-31 20:24:07 +03:00
parent fedb470da6
commit e11c82bd76
3 changed files with 88 additions and 42 deletions
+2 -1
View File
@@ -12,4 +12,5 @@ fabric.properties
tmp/ tmp/
vendor/ vendor/
config/secret.yaml config/secret.yaml
*.md *.md
mdb
+30 -11
View File
@@ -42,22 +42,19 @@ func (s *Rutracker) GetTopic(topics []string) ([]model.ExternalSources, error) {
for _, e := range topic.Entry { for _, e := range topic.Entry {
var es model.ExternalSources var es model.ExternalSources
u, _ := url.Parse(e.Link.Href)
es.Type = constant.ScopeRuTracker es.Type = constant.ScopeRuTracker
es.TypeId, _ = strconv.Atoi(u.Query().Get("t")) es.TypeId = topicId(e)
es.Title = e.Title es.Title = e.Title
es.TypeSubsectionId, _ = strconv.Atoi(t) es.TypeSubsectionId, _ = strconv.Atoi(t)
es.Releaser = e.Author.Name es.Releaser = e.Author.Name
es.Created = carbon.Parse(e.Updated, "Europe/Kyiv") es.Created = carbon.Parse(e.Updated, "Europe/Kyiv")
esModel := table.ExternalSources{Columns: columns} esModel := table.ExternalSources{Columns: columns}
fmt.Printf("%+v\n\n\n", es)
entry := esModel.InsertOnDuplicate(es, s.db) entry := esModel.InsertOnDuplicate(es, s.db)
entries = append(entries, entry) entries = append(entries, entry)
///fmt.Println(entries)
fmt.Printf("%+v\n\n\n", entry)
} }
} }
@@ -67,22 +64,44 @@ func (s *Rutracker) GetTopic(topics []string) ([]model.ExternalSources, error) {
func fetch(endpoint string) (*resource.RutrackerAtomTopic, error) { func fetch(endpoint string) (*resource.RutrackerAtomTopic, error) {
resp, err := http.Get(endpoint) resp, err := http.Get(endpoint)
if err != nil { if err != nil {
slog.Error("couldn't fetch data", endpoint, err.Error()) slog.Error("couldn't fetch data", "endpoint", endpoint, "err", err.Error())
return nil, err return nil, err
} }
defer func(Body io.ReadCloser) { defer func(Body io.ReadCloser) {
err = Body.Close() if cerr := Body.Close(); cerr != nil {
if err != nil { slog.Error("couldn't close response body", "endpoint", endpoint, "err", cerr.Error())
fmt.Println("Body.Close")
} }
}(resp.Body) }(resp.Body)
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status code %d from %s", resp.StatusCode, endpoint)
}
topic := &resource.RutrackerAtomTopic{} topic := &resource.RutrackerAtomTopic{}
if err = xml.NewDecoder(resp.Body).Decode(topic); err != nil { if err = xml.NewDecoder(resp.Body).Decode(topic); err != nil {
slog.Error("couldn't decode feed", "endpoint", endpoint, "err", err.Error())
return nil, err return nil, err
} }
return topic, nil return topic, nil
} }
// topicId resolves the rutracker topic id preferring the page link query (?t=...),
// falling back to the entry id tag (tag:rto.feed,...:/t/5702203).
func topicId(e resource.RutrackerAtomEntry) int {
if link, ok := e.PageLink(); ok {
if u, err := url.Parse(link.Href); err == nil {
if id, err := strconv.Atoi(u.Query().Get("t")); err == nil {
return id
}
}
}
id, err := e.TopicId()
if err != nil {
slog.Error("couldn't resolve topic id", "entry_id", e.ID, "err", err.Error())
return 0
}
return id
}
+56 -30
View File
@@ -1,35 +1,61 @@
package resource package resource
import "encoding/xml" import (
"encoding/xml"
"fmt"
"strconv"
"strings"
)
// RutrackerAtomTopic represents the atom feed of a rutracker forum subsection.
type RutrackerAtomTopic struct { type RutrackerAtomTopic struct {
XMLName xml.Name `xml:"feed"` XMLName xml.Name `xml:"feed"`
Text string `xml:",chardata"` Xmlns string `xml:"xmlns,attr"`
Xmlns string `xml:"xmlns,attr"` ID string `xml:"id"`
ID string `xml:"id"` Link []AtomLink `xml:"link"`
Link struct { Updated string `xml:"updated"`
Text string `xml:",chardata"` Title string `xml:"title"`
Href string `xml:"href,attr"` Entry []RutrackerAtomEntry `xml:"entry"`
} `xml:"link"` }
Updated string `xml:"updated"`
Title string `xml:"title"` // AtomLink is a generic atom link element. An entry contains two links:
Entry []struct { // a topic page link (no rel) and a magnet link (rel="enclosure").
Text string `xml:",chardata"` type AtomLink struct {
ID string `xml:"id"` Href string `xml:"href,attr"`
Link struct { Rel string `xml:"rel,attr"`
Text string `xml:",chardata"` Type string `xml:"type,attr"`
Href string `xml:"href,attr"` }
} `xml:"link"`
Updated string `xml:"updated"` type RutrackerAtomEntry struct {
Title string `xml:"title"` ID string `xml:"id"`
Author struct { Link []AtomLink `xml:"link"`
Text string `xml:",chardata"` Updated string `xml:"updated"`
Name string `xml:"name"` Title string `xml:"title"`
} `xml:"author"` Author struct {
Category struct { Name string `xml:"name"`
Text string `xml:",chardata"` } `xml:"author"`
Term string `xml:"term,attr"` Category struct {
Label string `xml:"label,attr"` Term string `xml:"term,attr"`
} `xml:"category"` Label string `xml:"label,attr"`
} `xml:"entry"` } `xml:"category"`
}
// PageLink returns the link to the topic page (the one without rel attribute).
func (e RutrackerAtomEntry) PageLink() (AtomLink, bool) {
for _, l := range e.Link {
if l.Rel == "" {
return l, true
}
}
return AtomLink{}, false
}
// TopicId extracts the topic id from the entry id tag: "tag:rto.feed,2026-08-29:/t/5702203".
func (e RutrackerAtomEntry) TopicId() (int, error) {
const marker = ":/t/"
i := strings.LastIndex(e.ID, marker)
if i < 0 {
return 0, fmt.Errorf("unexpected entry id format: %s", e.ID)
}
return strconv.Atoi(e.ID[i+len(marker):])
} }