Skip to content

Commit

Permalink
added tvmaze id support; added method to get tracker capabilities; up…
Browse files Browse the repository at this point in the history
…dated categories
  • Loading branch information
Michael Robinson committed Apr 8, 2019
1 parent 23ae922 commit 25844e9
Show file tree
Hide file tree
Showing 5 changed files with 2,557 additions and 2 deletions.
17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
[![MIT license](http://img.shields.io/badge/license-MIT-brightgreen.svg)](http://opensource.org/licenses/MIT)


> newznab XML API client for Go (golang)
> newznab/torznab XML API client for Go (golang)
## Documentation
[GoDoc](https://godoc.org/github.com/mrobinsn/go-newznab/newznab)
Expand All @@ -32,6 +32,12 @@ client := newznab.New("http://my-usenet-indexer", "my-api-key", 1234, false)
```
Note the missing `/api` part of the URL. Depending on the called method either `/api` or `/rss` will be appended to the given base URL. A valid user ID is only required for RSS methods.

### Get the capabilities of your tracker
```
caps, _ := client.Capabilities()
```
You will want to check the result of this to determine if your tracker supports searching by tvrage, imdb, tvmaze, etc.

### Search using a tvrage id:
```
categories := []int{
Expand All @@ -50,6 +56,15 @@ categories := []int{
results, _ := client.SearchWithIMDB(categories, "0364569")
```

### Search using a tvmaze id:
```
categories := []int{
newznab.CategoryTVHD,
newznab.CategoryTVSD,
}
results, _ := client.SearchWithTVMaze(categories, 80, 3, 1)
```

### Search using a name and set of categories:
```
results, _ := client.SearchWithQueries(categories, "Oldboy", "movie")
Expand Down
41 changes: 40 additions & 1 deletion newznab/newznab.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import (
"strings"
"time"

log "github.com/Sirupsen/logrus"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
)

// Various constants for categories
Expand All @@ -25,6 +25,8 @@ const (
CategoryTVSD = 5030
// CategoryTVHD is for high-definition shows
CategoryTVHD = 5040
// CategoryTVUHD is for UHD shows
CategoryTVUHD = 5045
// CategoryTVOther is for other shows
CategoryTVOther = 5050
// CategoryTVSport is for sports shows
Expand All @@ -41,6 +43,8 @@ const (
CategoryMovieSD = 2030
// CategoryMovieHD is for high-definition movies
CategoryMovieHD = 2040
// CategoryMovieUHD is for UHD movies
CategoryMovieUHD = 2045
// CategoryMovieBluRay is for blu-ray movies
CategoryMovieBluRay = 2050
// CategoryMovie3D is for 3-D movies
Expand Down Expand Up @@ -95,6 +99,17 @@ func (c Client) SearchWithTVDB(categories []int, tvDBID int, season int, episode
})
}

// SearchWithTVMaze returns NZBs for the given parameters
func (c Client) SearchWithTVMaze(categories []int, tvMazeID int, season int, episode int) ([]NZB, error) {
return c.search(url.Values{
"tvmazeid": []string{strconv.Itoa(tvMazeID)},
"cat": c.splitCats(categories),
"season": []string{strconv.Itoa(season)},
"episode": []string{strconv.Itoa(episode)},
"t": []string{"tvsearch"},
})
}

// SearchWithIMDB returns NZBs for the given parameters
func (c Client) SearchWithIMDB(categories []int, imdbID string) ([]NZB, error) {
return c.search(url.Values{
Expand Down Expand Up @@ -122,6 +137,13 @@ func (c Client) LoadRSSFeed(categories []int, num int) ([]NZB, error) {
})
}

// Capabilities returns the capabilities of this tracker
func (c Client) Capabilities() (Capabilities, error) {
return c.caps(url.Values{
"t": []string{"caps"},
})
}

// LoadRSSFeedUntilNZBID fetches NZBs until a given NZB id is reached.
func (c Client) LoadRSSFeedUntilNZBID(categories []int, num int, id string, maxRequests int) ([]NZB, error) {
count := 0
Expand Down Expand Up @@ -170,6 +192,19 @@ func (c Client) search(vals url.Values) ([]NZB, error) {
return c.process(vals, apiPath)
}

func (c Client) caps(vals url.Values) (Capabilities, error) {
vals.Set("apikey", c.apikey)
resp, err := c.getURL(c.buildURL(vals, apiPath))
if err != nil {
return Capabilities{}, errors.Wrap(err, "failed to get capabilities")
}
var cResp Capabilities
if err = xml.Unmarshal(resp, &cResp); err != nil {
return cResp, errors.Wrap(err, "failed to unmarshal xml")
}
return cResp, nil
}

func (c Client) process(vals url.Values, path string) ([]NZB, error) {
var nzbs []NZB
resp, err := c.getURL(c.buildURL(vals, path))
Expand Down Expand Up @@ -231,6 +266,8 @@ func (c Client) process(vals url.Values, path string) ([]NZB, error) {
nzb.TVDBID = attr.Value
case "rageid":
nzb.TVRageID = attr.Value
case "tvmazeid":
nzb.TVMazeID = attr.Value
case "info":
nzb.Info = attr.Value
case "season":
Expand Down Expand Up @@ -260,6 +297,8 @@ func (c Client) process(vals url.Values, path string) ([]NZB, error) {
} else {
nzb.UsenetDate = parsedUsetnetDate
}
case "resolution":
nzb.Resolution = attr.Value
default:
log.WithFields(log.Fields{
"name": attr.Name,
Expand Down
6 changes: 6 additions & 0 deletions newznab/newznab_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ func TestUsenetCrawlerClient(t *testing.T) {
require.NotEmpty(t, results, "expected results")
})

t.Run("valid category and TVMaze id", func(t *testing.T) {
results, err := client.SearchWithTVMaze(categories, 65, 10, 1)
require.NoError(t, err)
require.NotEmpty(t, results, "expected results")
})

t.Run("valid category and tvrage id", func(t *testing.T) {
results, err := client.SearchWithTVRage(categories, 2870, 10, 1)
require.NoError(t, err)
Expand Down
33 changes: 33 additions & 0 deletions newznab/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@ type NZB struct {
Info string `json:"info,omitempty"`
Genre string `json:"genre,omitempty"`

Resolution string `json:"resolution,omitempty"`

// TV Specific stuff
TVDBID string `json:"tvdbid,omitempty"`
TVRageID string `json:"tvrageid,omitempty"`
TVMazeID string `json:"tvmazeid,omitempty"`
Season string `json:"season,omitempty"`
Episode string `json:"episode,omitempty"`
TVTitle string `json:"tvtitle,omitempty"`
Expand Down Expand Up @@ -178,3 +181,33 @@ func (t *Time) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
return nil

}

type Capabilities struct {
Server struct {
Title string `xml:"title,attr" json:"title,omitempty"`
} `xml:"server" json:"server,omitempty"`
Searching struct {
Search struct {
Available string `xml:"available,attr" json:"available,omitempty"`
SupportedParams string `xml:"supportedParams,attr" json:"supported_params,omitempty"`
} `xml:"search" json:"search,omitempty"`
TvSearch struct {
Available string `xml:"available,attr" json:"available,omitempty"`
SupportedParams string `xml:"supportedParams,attr" json:"supported_params,omitempty"`
} `xml:"tv-search" json:"tv_search,omitempty"`
MovieSearch struct {
Available string `xml:"available,attr" json:"available,omitempty"`
SupportedParams string `xml:"supportedParams,attr" json:"supported_params,omitempty"`
} `xml:"movie-search" json:"movie_search,omitempty"`
} `xml:"searching" json:"searching,omitempty"`
Categories struct {
Category []struct {
ID string `xml:"id,attr" json:"id,omitempty"`
Name string `xml:"name,attr" json:"name,omitempty"`
Subcat []struct {
ID string `xml:"id,attr" json:"id,omitempty"`
Name string `xml:"name,attr" json:"name,omitempty"`
} `xml:"subcat" json:"subcat,omitempty"`
} `xml:"category" json:"category,omitempty"`
} `xml:"categories" json:"categories,omitempty"`
}
Loading

0 comments on commit 25844e9

Please sign in to comment.