jellyfixer/main.go
Marvin Steadfast 2a708c8d1a
All checks were successful
continuous-integration/drone/push Build is passing
cosmetic changes
2021-05-06 10:19:39 +02:00

140 lines
3.3 KiB
Go

// nolint:gomnd,exhaustivestruct
package main
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"time"
"git.xsfx.dev/xsteadfastx/logginghandler"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/spf13/viper"
)
// Logic Jellyfin URL.
type Logic struct {
InternalURL string
ExternalURL string
}
// PublicInfo Chromecast configuration Payload.
type PublicInfo struct {
LocalAddress string `json:"LocalAddress,omitempty"`
ServerName string `json:"ServerName"`
Version string `json:"Version"`
ProductName string `json:"ProductName"`
OperatingSystem string `json:"OperatingSystem"`
ID string `json:"Id"`
StartupWizardCompleted bool `json:"StartupWizardCompleted"`
}
// nolint:funlen
func (l Logic) ServeHTTP(w http.ResponseWriter, r *http.Request) {
logger := logginghandler.Logger(r)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) // nolint:gomnd
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/System/Info/Public", l.InternalURL), nil)
if err != nil {
logger.Error().Msg(err.Error())
http.Error(w, "could not create request jellyfin", http.StatusInternalServerError)
return
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
logger.Error().Msg(err.Error())
http.Error(w, "could not access jellyfin", http.StatusInternalServerError)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
logger.Error().Msg(err.Error())
http.Error(w, "could not read body", http.StatusInternalServerError)
return
}
logger.Debug().Str("body", string(body)).Msg("read body")
var jd PublicInfo
if err := json.Unmarshal(body, &jd); err != nil {
logger.Error().Msg(err.Error())
http.Error(w, "could not unmarshal body", http.StatusInternalServerError)
return
}
var nd PublicInfo
nd.ServerName = jd.ServerName
nd.Version = jd.Version
nd.ProductName = jd.ProductName
nd.OperatingSystem = jd.OperatingSystem
nd.ID = jd.ID
nd.StartupWizardCompleted = jd.StartupWizardCompleted
// When there is no external url defined, it wont include it in the response.
if l.ExternalURL != "" {
nd.LocalAddress = l.ExternalURL
}
bd, err := json.Marshal(nd)
if err != nil {
logger.Error().Msg(err.Error())
http.Error(w, "could not marshal body", http.StatusInternalServerError)
return
}
if _, err := w.Write(bd); err != nil {
logger.Error().Msg(err.Error())
}
}
func main() {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
log.Logger = log.Logger.With().Caller().Logger()
viper.SetEnvPrefix("jellyfixer")
if err := viper.BindEnv("internal_url"); err != nil {
log.Fatal().Msg(err.Error())
}
if err := viper.BindEnv("external_url"); err != nil {
log.Fatal().Msg(err.Error())
}
if len(os.Args) == 2 {
viper.SetConfigFile(os.Args[1])
}
viper.AutomaticEnv()
if viper.GetString("internal_url") == "" {
log.Fatal().Msg("needs key 'internal_url'")
}
l := Logic{
InternalURL: viper.GetString("internal_url"),
ExternalURL: viper.GetString("external_url"),
}
handler := logginghandler.Handler(l)
http.Handle("/", handler)
log.Info().Msg("starting server...")
log.Fatal().Msg(http.ListenAndServe("0.0.0.0:8088", nil).Error())
}