Skip to content

Commit

Permalink
Add search paths. (#4)
Browse files Browse the repository at this point in the history
* rename webroot to urlbase. update starr
* lidar updates
* change paths, add search
* move things around
  • Loading branch information
davidnewhall authored Dec 24, 2020
1 parent f9eb81b commit 7f26c51
Show file tree
Hide file tree
Showing 16 changed files with 446 additions and 303 deletions.
2 changes: 2 additions & 0 deletions bindata/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
The files in this folder are auto generated from the files/ folder.
Currently bindata is used to store the favicon.ico file. That is all.
247 changes: 247 additions & 0 deletions bindata/bindata.go

Large diffs are not rendered by default.

Binary file added bindata/files/favicon.ico
Binary file not shown.
3 changes: 3 additions & 0 deletions bindata/generate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package bindata

//go:generate go-bindata -pkg bindata -modtime 1587356420 -o bindata.go files/
3 changes: 1 addition & 2 deletions dnclient/appmeta.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
//nolint:dupl
package dnclient

import (
Expand Down Expand Up @@ -70,7 +69,7 @@ func (c *Client) handleAPIpath(app App, api string, next apiHandle, method ...st
}

// disccordnotifier uses 1-indexes.
c.router.Handle(path.Join("/", c.Config.URLBase, "api", string(app), api),
c.router.Handle(path.Join("/", c.Config.URLBase, "api", string(app), "{id:[0-9]+}", api),
c.checkAPIKey(c.responseWrapper(func(r *http.Request) (int, interface{}) {
switch id, _ := strconv.Atoi(mux.Vars(r)["id"]); {
default: // unknown app, just run the handler.
Expand Down
249 changes: 0 additions & 249 deletions dnclient/bindata.go

This file was deleted.

2 changes: 1 addition & 1 deletion dnclient/init.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//nolint:dupl
//nolint:dupl,golint
package dnclient

/*
Expand Down
10 changes: 5 additions & 5 deletions dnclient/lidarr.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ mbid - music brainz is the source for lidarr (todo)

// lidarrHandlers is called once on startup to register the web API paths.
func (c *Client) lidarrHandlers() {
c.handleAPIpath(Lidarr, "/add/{id:[0-9]+}", c.lidarrAddAlbum, "POST")
c.handleAPIpath(Lidarr, "/check/{id:[0-9]+}/{albumid:[-a-z]+}", c.lidarrCheckAlbum, "GET")
c.handleAPIpath(Lidarr, "/qualityProfiles/{id:[0-9]+}", c.lidarrProfiles, "GET")
c.handleAPIpath(Lidarr, "/qualityDefinitions/{id:[0-9]+}", c.lidarrQualityDefs, "GET")
c.handleAPIpath(Lidarr, "/rootFolder/{id:[0-9]+}", c.lidarrRootFolders, "GET")
c.handleAPIpath(Lidarr, "/add", c.lidarrAddAlbum, "POST")
c.handleAPIpath(Lidarr, "/check/{albumid:[-a-z]+}", c.lidarrCheckAlbum, "GET")
c.handleAPIpath(Lidarr, "/qualityProfiles", c.lidarrProfiles, "GET")
c.handleAPIpath(Lidarr, "/qualityDefinitions", c.lidarrQualityDefs, "GET")
c.handleAPIpath(Lidarr, "/rootFolder", c.lidarrRootFolders, "GET")
}

func (c *Client) lidarrRootFolders(r *http.Request) (int, interface{}) {
Expand Down
54 changes: 50 additions & 4 deletions dnclient/radarr.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@ import (
"fmt"
"net/http"
"strconv"
"strings"

"github.com/gorilla/mux"
"golift.io/starr/radarr"
)

// radarrHandlers is called once on startup to register the web API paths.
func (c *Client) radarrHandlers() {
c.handleAPIpath(Radarr, "/add/{id:[0-9]+}", c.radarrAddMovie, "POST")
c.handleAPIpath(Radarr, "/check/{id:[0-9]+}/{tmdbid:[0-9]+}", c.radarrCheckMovie, "GET")
c.handleAPIpath(Radarr, "/qualityProfiles/{id:[0-9]+}", c.radarrProfiles, "GET")
c.handleAPIpath(Radarr, "/rootFolder/{id:[0-9]+}", c.radarrRootFolders, "GET")
c.handleAPIpath(Radarr, "/add", c.radarrAddMovie, "POST")
c.handleAPIpath(Radarr, "/search/{query}", c.radarrSearchMovie, "GET")
c.handleAPIpath(Radarr, "/check/{tmdbid:[0-9]+}", c.radarrCheckMovie, "GET")
c.handleAPIpath(Radarr, "/qualityProfiles", c.radarrProfiles, "GET")
c.handleAPIpath(Radarr, "/rootFolder", c.radarrRootFolders, "GET")
}

func (c *Client) radarrRootFolders(r *http.Request) (int, interface{}) {
Expand Down Expand Up @@ -62,6 +64,50 @@ func (c *Client) radarrCheckMovie(r *http.Request) (int, interface{}) {
return http.StatusOK, http.StatusText(http.StatusNotFound)
}

func (c *Client) radarrSearchMovie(r *http.Request) (int, interface{}) {
// Get all movies
movies, err := getRadarr(r).GetMovie(0)
if err != nil {
return http.StatusServiceUnavailable, fmt.Errorf("getting movies: %w", err)
}

query := strings.TrimSpace(strings.ToLower(mux.Vars(r)["query"])) // in
returnMovies := make([]map[string]interface{}, 0) // out

for _, movie := range movies {
if movieSearch(query, []string{movie.Title, movie.OriginalTitle}, movie.AlternateTitles) {
returnMovies = append(returnMovies, map[string]interface{}{
"id": movie.ID,
"title": movie.Title,
"cinemas": movie.InCinemas,
"status": movie.Status,
"exists": movie.HasFile,
"added": movie.Added,
"year": movie.Year,
"path": movie.Path,
})
}
}

return http.StatusOK, returnMovies
}

func movieSearch(query string, titles []string, alts []*radarr.AlternativeTitle) bool {
for _, t := range titles {
if t != "" && strings.Contains(strings.ToLower(t), query) {
return true
}
}

for _, t := range alts {
if strings.Contains(strings.ToLower(t.Title), query) {
return true
}
}

return false
}

func (c *Client) radarrAddMovie(r *http.Request) (int, interface{}) {
payload := &radarr.AddMovieInput{}
// Extract payload and check for TMDB ID.
Expand Down
62 changes: 57 additions & 5 deletions dnclient/readarr.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,20 @@ import (
"fmt"
"net/http"
"strconv"
"strings"

"github.com/gorilla/mux"
"golift.io/starr/readarr"
)

// readarrHandlers is called once on startup to register the web API paths.
func (c *Client) readarrHandlers() {
c.handleAPIpath(Readarr, "/add/{id:[0-9]+}", c.readarrAddBook, "POST")
c.handleAPIpath(Readarr, "/check/{id:[0-9]+}/{grid:[0-9]+}", c.readarrCheckBook, "GET")
c.handleAPIpath(Readarr, "/metadataProfiles/{id:[0-9]+}", c.readarrMetaProfiles, "GET")
c.handleAPIpath(Readarr, "/qualityProfiles/{id:[0-9]+}", c.readarrProfiles, "GET")
c.handleAPIpath(Readarr, "/rootFolder/{id:[0-9]+}", c.readarrRootFolders, "GET")
c.handleAPIpath(Readarr, "/add", c.readarrAddBook, "POST")
c.handleAPIpath(Readarr, "/search/{query}", c.readarrSearchBook, "GET")
c.handleAPIpath(Readarr, "/check/{grid:[0-9]+}", c.readarrCheckBook, "GET")
c.handleAPIpath(Readarr, "/metadataProfiles", c.readarrMetaProfiles, "GET")
c.handleAPIpath(Readarr, "/qualityProfiles", c.readarrProfiles, "GET")
c.handleAPIpath(Readarr, "/rootFolder", c.readarrRootFolders, "GET")
}

func (c *Client) readarrRootFolders(r *http.Request) (int, interface{}) {
Expand Down Expand Up @@ -80,6 +82,56 @@ func (c *Client) readarrCheckBook(r *http.Request) (int, interface{}) {
return http.StatusOK, http.StatusText(http.StatusNotFound)
}

func (c *Client) readarrSearchBook(r *http.Request) (int, interface{}) {
books, err := getReadarr(r).GetBook(0)
if err != nil {
return http.StatusServiceUnavailable, fmt.Errorf("getting books: %w", err)
}

query := strings.TrimSpace(strings.ToLower(mux.Vars(r)["query"])) // in
returnBooks := make([]map[string]interface{}, 0) // out

for _, book := range books {
if bookSearch(query, book.Title, book.Editions) {
b := map[string]interface{}{
"id": book.ID,
"title": book.Title,
"release": book.ReleaseDate,
"author": book.Author.AuthorName,
"authorId": book.Author.Ended,
"overview": book.Overview,
"ratings": book.Ratings.Value,
"pages": book.PageCount,
"exists": false,
"files": 0,
}

if book.Statistics != nil {
b["files"] = book.Statistics.BookFileCount
b["exists"] = book.Statistics.SizeOnDisk > 0
}

returnBooks = append(returnBooks, b)
}
}

return http.StatusOK, returnBooks
}

func bookSearch(query, title string, editions []*readarr.Edition) bool {
if strings.Contains(strings.ToLower(title), query) {
return true
}

for _, t := range editions {
if strings.Contains(strings.ToLower(t.Title), query) {
return true
}
}

return false
}

func (c *Client) readarrAddBook(r *http.Request) (int, interface{}) {
payload := &readarr.AddBookInput{}
// Extract payload and check for TMDB ID.
Expand Down
61 changes: 56 additions & 5 deletions dnclient/sonarr.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,20 @@ import (
"fmt"
"net/http"
"strconv"
"strings"

"github.com/gorilla/mux"
"golift.io/starr/sonarr"
)

// sonarrHandlers is called once on startup to register the web API paths.
func (c *Client) sonarrHandlers() {
c.handleAPIpath(Sonarr, "/add/{id:[0-9]+}", c.sonarrAddSeries, "POST")
c.handleAPIpath(Sonarr, "/check/{id:[0-9]+}/{tvdbid:[0-9]+}", c.sonarrCheckSeries, "GET")
c.handleAPIpath(Sonarr, "/qualityProfiles/{id:[0-9]+}", c.sonarrProfiles, "GET")
c.handleAPIpath(Sonarr, "/languageProfiles/{id:[0-9]+}", c.sonarrLangProfiles, "GET")
c.handleAPIpath(Sonarr, "/rootFolder/{id:[0-9]+}", c.sonarrRootFolders, "GET")
c.handleAPIpath(Sonarr, "/add", c.sonarrAddSeries, "POST")
c.handleAPIpath(Sonarr, "/check/{tvdbid:[0-9]+}", c.sonarrCheckSeries, "GET")
c.handleAPIpath(Sonarr, "/search/{query}", c.sonarrSearchSeries, "GET")
c.handleAPIpath(Sonarr, "/qualityProfiles", c.sonarrProfiles, "GET")
c.handleAPIpath(Sonarr, "/languageProfiles", c.sonarrLangProfiles, "GET")
c.handleAPIpath(Sonarr, "/rootFolder", c.sonarrRootFolders, "GET")
}

func (c *Client) sonarrRootFolders(r *http.Request) (int, interface{}) {
Expand Down Expand Up @@ -80,6 +82,55 @@ func (c *Client) sonarrCheckSeries(r *http.Request) (int, interface{}) {
return http.StatusOK, http.StatusText(http.StatusNotFound)
}

func (c *Client) sonarrSearchSeries(r *http.Request) (int, interface{}) {
// Get all movies
series, err := getSonarr(r).GetAllSeries()
if err != nil {
return http.StatusServiceUnavailable, fmt.Errorf("getting series: %w", err)
}

query := strings.TrimSpace(strings.ToLower(mux.Vars(r)["query"])) // in
returnSeries := make([]map[string]interface{}, 0) // out

for _, s := range series {
if seriesSearch(query, s.Title, s.AlternateTitles) {
b := map[string]interface{}{
"id": s.ID,
"title": s.Title,
"first": s.FirstAired,
"next": s.NextAiring,
"prev": s.PreviousAiring,
"added": s.Added,
"status": s.Status,
"exists": false,
"path": s.Path,
}

if s.Statistics != nil {
b["exists"] = s.Statistics.SizeOnDisk > 0
}

returnSeries = append(returnSeries, b)
}
}

return http.StatusOK, returnSeries
}

func seriesSearch(query, title string, alts []*sonarr.AlternateTitle) bool {
if strings.Contains(strings.ToLower(title), query) {
return true
}

for _, t := range alts {
if strings.Contains(strings.ToLower(t.Title), query) {
return true
}
}

return false
}

func (c *Client) sonarrAddSeries(r *http.Request) (int, interface{}) {
payload := &sonarr.AddSeriesInput{}
// Extract payload and check for TMDB ID.
Expand Down
44 changes: 21 additions & 23 deletions dnclient/webserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import (
"os"
"path"
"strconv"
"strings"
"time"

"github.com/Go-Lift-TV/discordnotifier-client/bindata"
"github.com/gorilla/mux"
"golift.io/version"
)
Expand Down Expand Up @@ -85,7 +87,7 @@ func (c *Client) checkAPIKey(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("X-API-Key") != c.Config.APIKey {
c.Printf("HTTP [%s] %s %s: %d: Unauthorized: bad API key",
r.RemoteAddr, r.Method, r.RequestURI, http.StatusUnauthorized)
strings.Split(r.RemoteAddr, ":")[0], r.Method, r.RequestURI, http.StatusUnauthorized)
w.WriteHeader(http.StatusUnauthorized)
} else {
next.ServeHTTP(w, r)
Expand All @@ -110,9 +112,10 @@ func (c *Client) responseWrapper(next apiHandle) http.Handler {
}

if s, ok := msg.(string); ok {
c.Printf("HTTP [%s] %s %s: %s: %s", r.RemoteAddr, r.Method, r.RequestURI, statusTxt, s)
c.Printf("HTTP [%s] %s %s: %s: %s",
strings.Split(r.RemoteAddr, ":")[0], r.Method, r.RequestURI, statusTxt, strings.TrimSpace(s))
} else {
c.Printf("HTTP [%s] %s %s: %s", r.RemoteAddr, r.Method, r.RequestURI, statusTxt)
c.Printf("HTTP [%s] %s %s: %s", strings.Split(r.RemoteAddr, ":")[0], r.Method, r.RequestURI, statusTxt)
}

w.Header().Set("Content-Type", "application/json")
Expand All @@ -131,22 +134,14 @@ func (c *Client) statusResponse(r *http.Request) (int, interface{}) {

// versionResponse returns application run and build time data.
func (c *Client) versionResponse(r *http.Request) (int, interface{}) {
return http.StatusOK, struct {
V string `json:"version"`
U string `json:"uptime"`
S float64 `json:"uptime_seconds"`
D string `json:"build_date"`
B string `json:"branch"`
G string `json:"go_version"`
R string `json:"revision"`
}{
version.Version,
time.Since(version.Started).Round(time.Second).String(),
time.Since(version.Started).Round(time.Second).Seconds(),
version.BuildDate,
version.Branch,
version.GoVersion,
version.Revision,
return http.StatusOK, map[string]interface{}{
"version": version.Version,
"uptime": time.Since(version.Started).Round(time.Second).String(),
"uptime_seconds": time.Since(version.Started).Round(time.Second).Seconds(),
"build_date": version.BuildDate,
"branch": version.Branch,
"go_version": version.GoVersion,
"revision": version.Revision,
}
}

Expand All @@ -158,16 +153,19 @@ func (c *Client) notFound(r *http.Request) (int, interface{}) {
// slash is the handler for /.
func (c *Client) slash(w http.ResponseWriter, r *http.Request) {
msg := "<p>" + c.Flags.Name() + ": <strong>working</strong></p>\n"
c.Printf("HTTP [%s] %s %s: OK: %s", r.RemoteAddr, r.Method, r.RequestURI, msg)
c.Printf("HTTP [%s] %s %s: OK: %s",
strings.Split(r.RemoteAddr, ":")[0], r.Method, r.RequestURI, strings.TrimSpace(msg))

_, _ = w.Write([]byte(msg))
}

func (c *Client) favIcon(w http.ResponseWriter, r *http.Request) {
if b, err := Asset("init/windows/application.ico"); err != nil {
c.Printf("HTTP [%s] %s %s: 500: Internal Server Error: %v", r.RemoteAddr, r.Method, r.RequestURI, err)
if b, err := bindata.Asset("files/favicon.ico"); err != nil {
c.Printf("HTTP [%s] %s %s: 500: Internal Server Error: %v",
strings.Split(r.RemoteAddr, ":")[0], r.Method, r.RequestURI, err)
w.WriteHeader(http.StatusInternalServerError)
} else {
c.Printf("HTTP [%s] %s %s: 200 OK", r.RemoteAddr, r.Method, r.RequestURI)
c.Printf("HTTP [%s] %s %s: 200 OK", strings.Split(r.RemoteAddr, ":")[0], r.Method, strings.TrimSpace(r.RequestURI))
http.ServeContent(w, r, r.URL.Path, time.Now(), bytes.NewReader(b))
}
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ require (
github.com/spf13/pflag v1.0.6-0.20201009195203-85dd5c8bc61c
golift.io/cnfg v0.0.7
golift.io/rotatorr v0.0.0-20201213130124-94efc0b9aff1
golift.io/starr v0.9.5-0.20201222022736-eaadaabe9989
golift.io/starr v0.9.5-0.20201223211915-58a134784642
golift.io/version v0.0.2
)
8 changes: 2 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,8 @@ golift.io/cnfg v0.0.7 h1:qkNpP5Bq+5Gtoc6HcI8kapMD5zFOVan6qguxqBQF3OY=
golift.io/cnfg v0.0.7/go.mod h1:AsB0DJe7nv0bizKaoy3e3MjjOF7upTpMOMvsfv4CNNk=
golift.io/rotatorr v0.0.0-20201213130124-94efc0b9aff1 h1:8SDkFT5QpXyN24BCPw5Yux7SiMExnbL8o2hK1yfW3pk=
golift.io/rotatorr v0.0.0-20201213130124-94efc0b9aff1/go.mod h1:EZevRvIGRh8jDMwuYL0/tlPns0KynquPZzb0SerIC1s=
golift.io/starr v0.9.4 h1:lKs33b22mLOTwebqv1+Z5Vkv6BJ1oth8g16jlAZxHyk=
golift.io/starr v0.9.4/go.mod h1:vc04EcdpqkBG7jCySmehqtlQEJ1nrEYeqZmDV1Xpj3k=
golift.io/starr v0.9.5-0.20201221214402-b08bed538e3a h1://hGYlq5/vSfMAzyDS/fOsSoBku1++tAKBisHSm/uuQ=
golift.io/starr v0.9.5-0.20201221214402-b08bed538e3a/go.mod h1:EE8B7OlqZlE/EGmBP1bLsK1OHEgWwbNpyjDXX0B2f0Y=
golift.io/starr v0.9.5-0.20201222022736-eaadaabe9989 h1:tsjSnwtW1gxWmY3e50LqQacAE6uWNPmuLN8EZXD7h+c=
golift.io/starr v0.9.5-0.20201222022736-eaadaabe9989/go.mod h1:EE8B7OlqZlE/EGmBP1bLsK1OHEgWwbNpyjDXX0B2f0Y=
golift.io/starr v0.9.5-0.20201223211915-58a134784642 h1:ibv7D2vjklWJ9TKcBqV321ZRRALuKZIxhwvfhYczliQ=
golift.io/starr v0.9.5-0.20201223211915-58a134784642/go.mod h1:EE8B7OlqZlE/EGmBP1bLsK1OHEgWwbNpyjDXX0B2f0Y=
golift.io/version v0.0.2 h1:i0gXRuSDHKs4O0sVDUg4+vNIuOxYoXhaxspftu2FRTE=
golift.io/version v0.0.2/go.mod h1:76aHNz8/Pm7CbuxIsDi97jABL5Zui3f2uZxDm4vB6hU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
Binary file modified init/windows/application.ico
Binary file not shown.
Loading

0 comments on commit 7f26c51

Please sign in to comment.