Files
plex-prometheus-exporter/plex_client.go

152 lines
4.9 KiB
Go

package main
import (
"bytes"
"crypto/tls"
"encoding/json"
"fmt"
"io"
"net/http"
)
type CurrentlyPlayingDetails struct {
CurrentPlayingTitle string `json:"currentPlayingTitle"`
IpAddress string `json:"ipAddress"`
Platform string `json:"platform"`
Product string `json:"product"`
Title string `json:"title"`
State string `json:"state"`
}
type plexStats struct {
CurrentSessions float64 `json:"currentSessions"`
NumMovies float64 `json:"numMovies"`
NumTV float64 `json:"numTV"`
NumTranscodes float64 `json:"numTranscodes"`
NumAllSessions float64 `json:"numAllSessions"`
CurrentlyPlayingDetails CurrentlyPlayingDetails `json:"currentlyPlayingDetails"`
}
type PlexClient struct {
baseUrl string
client *http.Client
plexToken string
}
func setupClient(settings *serverSettings) PlexClient {
transCfg := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
return PlexClient{
baseUrl: settings.plexAddr,
client: &http.Client{Transport: transCfg},
plexToken: settings.plexToken,
}
}
// sendRequest sends a request and resturns response (always assuming a get request)
func (pc *PlexClient) sendRequest(url string, body []byte) (result []byte) {
fullUrl := pc.baseUrl + url
req, err := http.NewRequest("GET", fullUrl, bytes.NewBuffer(body))
if err != nil {
fmt.Println("Error creating new request", err)
return
}
req.Header.Add("Accept", "application/json")
q := req.URL.Query()
q.Add("X-Plex-Token", pc.plexToken)
req.URL.RawQuery = q.Encode()
res, err := pc.client.Do(req)
if err != nil {
fmt.Println("Error sending request", err)
return
}
defer res.Body.Close()
resBody, err := io.ReadAll(res.Body)
if err != nil {
fmt.Println("Unable to read response body: ", err)
return
}
return resBody
}
func (pc *PlexClient) getActiveSessions() *ActiveSessions {
result := pc.sendRequest("/status/sessions", nil)
currentActiveSessions := ActiveSessions{}
err := json.Unmarshal(result, &currentActiveSessions)
if err != nil {
fmt.Println("Error unmarshalling current active sessions: ", err)
}
return &currentActiveSessions
}
func (pc *PlexClient) getNumMovies() *RawPlexModel {
result := pc.sendRequest("/library/sections/3/all", nil) //Hard code library ID for now TODO: Grab from library/sections call
libraryAll := RawPlexModel{}
err := json.Unmarshal(result, &libraryAll)
if err != nil {
fmt.Println("Error unmarshalling num movies: ", err)
}
return &libraryAll
}
func (pc *PlexClient) getNumTV() *ActiveSessions {
result := pc.sendRequest("/library/sections/2/all", nil) //Hard code library ID for now TODO: Grab from library/sections call
libraryAll := ActiveSessions{}
err := json.Unmarshal(result, &libraryAll)
if err != nil {
fmt.Println("Error unmarshalling num tv: ", err)
}
return &libraryAll
}
func (pc *PlexClient) getNumTranscodes() *RawPlexModel {
result := pc.sendRequest("/transcode/sessions", nil)
transcodesAll := RawPlexModel{}
err := json.Unmarshal(result, &transcodesAll)
if err != nil {
fmt.Println("Error unmarshalling num transcodes: ", err)
}
return &transcodesAll
}
// getServerHistory gets the entire history of plays on the plex server
func (pc *PlexClient) getServerHistory() *RawPlexModel {
result := pc.sendRequest("/status/sessions/history/all", nil)
sessionsAll := RawPlexModel{}
err := json.Unmarshal(result, &sessionsAll)
if err != nil {
fmt.Println("Error unmarshalling session server history: ", err)
}
return &sessionsAll
}
func (pc *PlexClient) gatherAllStats() *plexStats {
allStats := plexStats{}
sessionsData := pc.getActiveSessions()
libraryDetails := pc.getNumMovies()
tvshowDetails := pc.getNumTV()
transcodeDetails := pc.getNumTranscodes()
allSessionsData := pc.getServerHistory()
allStats.CurrentSessions = float64(sessionsData.MediaContainer.Size)
allStats.NumMovies = float64(libraryDetails.MediaContainer.Size)
allStats.NumTV = float64(tvshowDetails.MediaContainer.Size)
allStats.NumTranscodes = float64(transcodeDetails.MediaContainer.Size)
allStats.NumAllSessions = float64(allSessionsData.MediaContainer.Size)
if len(sessionsData.MediaContainer.Metadata) > 0 {
allStats.CurrentlyPlayingDetails.CurrentPlayingTitle = sessionsData.MediaContainer.Metadata[0].Title
allStats.CurrentlyPlayingDetails.IpAddress = sessionsData.MediaContainer.Metadata[0].Player.Address
allStats.CurrentlyPlayingDetails.Platform = sessionsData.MediaContainer.Metadata[0].Player.Platform
allStats.CurrentlyPlayingDetails.Product = sessionsData.MediaContainer.Metadata[0].Player.Product
allStats.CurrentlyPlayingDetails.State = sessionsData.MediaContainer.Metadata[0].Player.State
allStats.CurrentlyPlayingDetails.Title = sessionsData.MediaContainer.Metadata[0].Player.Title
}
return &allStats
}