140 lines
3.5 KiB
Go
140 lines
3.5 KiB
Go
package mpchc
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
neturl "net/url"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/rs/zerolog"
|
|
)
|
|
|
|
type MpcHc struct {
|
|
Host string
|
|
Port int
|
|
Path string
|
|
Logger *zerolog.Logger
|
|
}
|
|
|
|
func (api *MpcHc) url() string {
|
|
return fmt.Sprintf("http://%s:%d", api.Host, api.Port)
|
|
}
|
|
|
|
// Execute sends a command to MPC and returns the response.
|
|
func (api *MpcHc) Execute(command int, data map[string]interface{}) (string, error) {
|
|
url := fmt.Sprintf("%s/command.html?wm_command=%d", api.url(), command)
|
|
|
|
if data != nil {
|
|
queryParams := neturl.Values{}
|
|
for key, value := range data {
|
|
queryParams.Add(key, fmt.Sprintf("%v", value))
|
|
}
|
|
url += "&" + queryParams.Encode()
|
|
}
|
|
|
|
response, err := http.Get(url)
|
|
if err != nil {
|
|
api.Logger.Error().Err(err).Msg("mpc hc: Failed to execute command")
|
|
return "", err
|
|
}
|
|
defer response.Body.Close()
|
|
|
|
// Check HTTP status code and errors
|
|
statusCode := response.StatusCode
|
|
if !((statusCode >= 200) && (statusCode <= 299)) {
|
|
err = fmt.Errorf("http error code: %d\n", statusCode)
|
|
return "", err
|
|
}
|
|
|
|
// Get byte response and http status code
|
|
byteArr, readErr := io.ReadAll(response.Body)
|
|
if readErr != nil {
|
|
err = fmt.Errorf("error reading response: %s\n", readErr)
|
|
return "", err
|
|
}
|
|
|
|
// Write response
|
|
res := string(byteArr)
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func escapeInput(input string) string {
|
|
if strings.HasPrefix(input, "http") {
|
|
return neturl.QueryEscape(input)
|
|
} else {
|
|
input = filepath.FromSlash(input)
|
|
return strings.ReplaceAll(neturl.QueryEscape(input), "+", "%20")
|
|
}
|
|
}
|
|
|
|
// OpenAndPlay opens a video file in MPC.
|
|
func (api *MpcHc) OpenAndPlay(filePath string) (string, error) {
|
|
url := fmt.Sprintf("%s/browser.html?path=%s", api.url(), escapeInput(filePath))
|
|
api.Logger.Trace().Str("url", url).Msg("mpc hc: Opening and playing")
|
|
|
|
response, err := http.Get(url)
|
|
if err != nil {
|
|
api.Logger.Error().Err(err).Msg("mpc hc: Failed to connect to MPC")
|
|
return "", err
|
|
}
|
|
defer response.Body.Close()
|
|
|
|
// Check HTTP status code and errors
|
|
statusCode := response.StatusCode
|
|
if !((statusCode >= 200) && (statusCode <= 299)) {
|
|
err = fmt.Errorf("http error code: %d\n", statusCode)
|
|
api.Logger.Error().Err(err).Msg("mpc hc: Failed to open and play")
|
|
return "", err
|
|
}
|
|
|
|
// Get byte response and http status code
|
|
byteArr, readErr := io.ReadAll(response.Body)
|
|
if readErr != nil {
|
|
err = fmt.Errorf("error reading response: %s\n", readErr)
|
|
api.Logger.Error().Err(err).Msg("mpc hc: Failed to open and play")
|
|
return "", err
|
|
}
|
|
|
|
// Write response
|
|
res := string(byteArr)
|
|
|
|
return res, nil
|
|
}
|
|
|
|
// GetVariables retrieves player variables from MPC.
|
|
func (api *MpcHc) GetVariables() (*Variables, error) {
|
|
url := fmt.Sprintf("%s/variables.html", api.url())
|
|
|
|
response, err := http.Get(url)
|
|
if err != nil {
|
|
api.Logger.Error().Err(err).Msg("mpc hc: Failed to get variables")
|
|
return &Variables{}, err
|
|
}
|
|
defer response.Body.Close()
|
|
|
|
// Check HTTP status code and errors
|
|
statusCode := response.StatusCode
|
|
if !((statusCode >= 200) && (statusCode <= 299)) {
|
|
err = fmt.Errorf("http error code: %d\n", statusCode)
|
|
api.Logger.Error().Err(err).Msg("mpc hc: Failed to get variables")
|
|
return &Variables{}, err
|
|
}
|
|
|
|
// Get byte response and http status code
|
|
byteArr, readErr := io.ReadAll(response.Body)
|
|
if readErr != nil {
|
|
err = fmt.Errorf("error reading response: %s\n", readErr)
|
|
api.Logger.Error().Err(err).Msg("mpc hc: Failed to get variables")
|
|
return &Variables{}, err
|
|
}
|
|
|
|
// Write response
|
|
res := string(byteArr)
|
|
vars := parseVariables(res)
|
|
|
|
return vars, nil
|
|
}
|