Add context to the soapcalls API

This commit is contained in:
Alex Ballas
2023-05-23 19:44:51 +03:00
parent d8eec476da
commit 4e5131149e
10 changed files with 40 additions and 26 deletions

View File

@@ -147,7 +147,7 @@ func run() error {
scr := &dummyScreen{ctxCancel: cancel}
tvdata, err := soapcalls.NewTVPayload(soapcalls.Options{
tvdata, err := soapcalls.NewTVPayload(&soapcalls.Options{
DMR: flagRes.dmrURL,
Media: absMediaFile,
Subs: absSubtitlesFile,

View File

@@ -147,7 +147,7 @@ func run() error {
return err
}
tvdata, err := soapcalls.NewTVPayload(soapcalls.Options{
tvdata, err := soapcalls.NewTVPayload(&soapcalls.Options{
DMR: flagRes.dmrURL,
Media: absMediaFile,
Subs: absSubtitlesFile,

View File

@@ -1,6 +1,7 @@
package devices
import (
"context"
"fmt"
"sort"
@@ -30,7 +31,7 @@ func LoadSSDPservices(delay int) (map[string]string, error) {
// (stop,play,pause). If we need support other functionalities
// like volume control we need to use the RenderingControl service.
if srv.Type == "urn:schemas-upnp-org:service:AVTransport:1" {
friendlyName, err := soapcalls.GetFriendlyName(srv.Location)
friendlyName, err := soapcalls.GetFriendlyName(context.Background(), srv.Location)
if err != nil {
continue
}

View File

@@ -4,6 +4,7 @@
package gui
import (
"context"
"errors"
"log"
"math"
@@ -382,7 +383,7 @@ func mainWindow(s *NewScreen) fyne.CanvasObject {
// Widgets actions
list.OnSelected = func(id widget.ListItemID) {
playpause.Enable()
t, err := soapcalls.DMRextractor(data[id].addr)
t, err := soapcalls.DMRextractor(context.Background(), data[id].addr)
check(s, err)
if err == nil {
s.selectedDevice = data[id]

View File

@@ -1,15 +1,16 @@
package soapcalls
import (
"context"
"encoding/xml"
"fmt"
"net/http"
)
// GetFriendlyName returns the friendly name value for a the specific DMR url.
func GetFriendlyName(dmr string) (string, error) {
func GetFriendlyName(ctx context.Context, dmr string) (string, error) {
client := &http.Client{}
req, err := http.NewRequest(http.MethodGet, dmr, nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, dmr, nil)
if err != nil {
return "", fmt.Errorf("failed to create NewRequest for GetFriendlyName: %w", err)
}

View File

@@ -1,6 +1,7 @@
package soapcalls
import (
"context"
"encoding/xml"
"net/http"
"net/http/httptest"
@@ -31,7 +32,7 @@ func TestGetFriendlyName(t *testing.T) {
defer testServer.Close()
friendly, err := GetFriendlyName(testServer.URL)
friendly, err := GetFriendlyName(context.Background(), testServer.URL)
if err != nil {
t.Fatalf("%s: Failed to call GetFriendlyName due to %s", testName, err.Error())
}

View File

@@ -2,6 +2,7 @@ package soapcalls
import (
"bytes"
"context"
"encoding/json"
"encoding/xml"
"fmt"
@@ -37,6 +38,7 @@ type TVPayload struct {
initLogOnce sync.Once
mu sync.RWMutex
Logging io.Writer
ctx context.Context
MediaRenderersStates map[string]*States
CurrentTimers map[string]*time.Timer
InitialMediaRenderersStates map[string]bool
@@ -179,7 +181,7 @@ func (p *TVPayload) setAVTransportSoapCall() error {
retryClient.Logger = nil
client := retryClient.StandardClient()
req, err := http.NewRequest("POST", parsedURLtransport.String(), bytes.NewReader(xml))
req, err := http.NewRequestWithContext(p.ctx, "POST", parsedURLtransport.String(), bytes.NewReader(xml))
if err != nil {
p.Log().Error().Str("Method", "setAVTransportSoapCall").Str("Action", "Prepare POST").Err(err).Msg("")
return fmt.Errorf("setAVTransportSoapCall POST error: %w", err)
@@ -245,7 +247,7 @@ func (p *TVPayload) setNextAVTransportSoapCall(clear bool) error {
client := &http.Client{}
req, err := http.NewRequest("POST", parsedURLtransport.String(), bytes.NewReader(xml))
req, err := http.NewRequestWithContext(p.ctx, "POST", parsedURLtransport.String(), bytes.NewReader(xml))
if err != nil {
p.Log().Error().Str("Method", "setNextAVTransportSoapCall").Str("Action", "Prepare POST").Err(err).Msg("")
return fmt.Errorf("setNextAVTransportSoapCall POST error: %w", err)
@@ -330,7 +332,7 @@ func (p *TVPayload) PlayPauseStopSoapCall(action string) error {
client = retryClient.StandardClient()
}
req, err := http.NewRequest("POST", parsedURLtransport.String(), bytes.NewReader(xml))
req, err := http.NewRequestWithContext(p.ctx, "POST", parsedURLtransport.String(), bytes.NewReader(xml))
if err != nil {
p.Log().Error().Str("Method", "AVTransportActionSoapCall").Str("Action", "Prepare POST").Err(err).Msg("")
return fmt.Errorf("AVTransportActionSoapCall POST error: %w", err)
@@ -407,7 +409,7 @@ func (p *TVPayload) SeekSoapCall(reltime string) error {
client = retryClient.StandardClient()
}
req, err := http.NewRequest("POST", parsedURLtransport.String(), bytes.NewReader(xml))
req, err := http.NewRequestWithContext(p.ctx, "POST", parsedURLtransport.String(), bytes.NewReader(xml))
if err != nil {
p.Log().Error().Str("Method", "SeekSoapCall").Str("Action", "Prepare POST").Err(err).Msg("")
return fmt.Errorf("SeekSoapCall POST error: %w", err)
@@ -481,7 +483,7 @@ func (p *TVPayload) SubscribeSoapCall(uuidInput string) error {
client := retryClient.StandardClient()
req, err := http.NewRequest("SUBSCRIBE", parsedURLcontrol.String(), nil)
req, err := http.NewRequestWithContext(p.ctx, "SUBSCRIBE", parsedURLcontrol.String(), nil)
if err != nil {
p.Log().Error().Str("Method", "SubscribeSoapCall").Str("Action", "Prepare SUBSCRIBE").Err(err).Msg("")
return fmt.Errorf("SubscribeSoapCall SUBSCRIBE error: %w", err)
@@ -592,7 +594,7 @@ func (p *TVPayload) UnsubscribeSoapCall(uuid string) error {
client := &http.Client{}
req, err := http.NewRequest("UNSUBSCRIBE", parsedURLcontrol.String(), nil)
req, err := http.NewRequestWithContext(p.ctx, "UNSUBSCRIBE", parsedURLcontrol.String(), nil)
if err != nil {
return fmt.Errorf("UnsubscribeSoapCall UNSUBSCRIBE error: %w", err)
}
@@ -654,7 +656,7 @@ func (p *TVPayload) GetMuteSoapCall() (string, error) {
}
client := &http.Client{}
req, err := http.NewRequest("POST", parsedRenderingControlURL.String(), bytes.NewReader(xmlbuilder))
req, err := http.NewRequestWithContext(p.ctx, "POST", parsedRenderingControlURL.String(), bytes.NewReader(xmlbuilder))
if err != nil {
p.Log().Error().Str("Method", "GetMuteSoapCall").Str("Action", "Prepare POST").Err(err).Msg("")
return "", fmt.Errorf("GetMuteSoapCall POST error: %w", err)
@@ -731,7 +733,7 @@ func (p *TVPayload) SetMuteSoapCall(number string) error {
}
client := &http.Client{}
req, err := http.NewRequest("POST", parsedRenderingControlURL.String(), bytes.NewReader(xmlbuilder))
req, err := http.NewRequestWithContext(p.ctx, "POST", parsedRenderingControlURL.String(), bytes.NewReader(xmlbuilder))
if err != nil {
p.Log().Error().Str("Method", "SetMuteSoapCall").Str("Action", "Prepare POST").Err(err).Msg("")
return fmt.Errorf("SetMuteSoapCall POST error: %w", err)
@@ -798,7 +800,7 @@ func (p *TVPayload) GetVolumeSoapCall() (int, error) {
}
client := &http.Client{}
req, err := http.NewRequest("POST", parsedRenderingControlURL.String(), bytes.NewReader(xmlbuilder))
req, err := http.NewRequestWithContext(p.ctx, "POST", parsedRenderingControlURL.String(), bytes.NewReader(xmlbuilder))
if err != nil {
p.Log().Error().Str("Method", "GetVolumeSoapCall").Str("Action", "Prepare POST").Err(err).Msg("")
return 0, fmt.Errorf("GetVolumeSoapCall POST error: %w", err)
@@ -886,7 +888,7 @@ func (p *TVPayload) SetVolumeSoapCall(v string) error {
}
client := &http.Client{}
req, err := http.NewRequest("POST", parsedRenderingControlURL.String(), bytes.NewReader(xmlbuilder))
req, err := http.NewRequestWithContext(p.ctx, "POST", parsedRenderingControlURL.String(), bytes.NewReader(xmlbuilder))
if err != nil {
p.Log().Error().Str("Method", "SetVolumeSoapCall").Str("Action", "Prepare POST").Err(err).Msg("")
return fmt.Errorf("SetVolumeSoapCall POST error: %w", err)
@@ -953,7 +955,7 @@ func (p *TVPayload) GetProtocolInfo() error {
}
client := &http.Client{}
req, err := http.NewRequest("POST", parsedConnectionManagerURL.String(), bytes.NewReader(xmlbuilder))
req, err := http.NewRequestWithContext(p.ctx, "POST", parsedConnectionManagerURL.String(), bytes.NewReader(xmlbuilder))
if err != nil {
p.Log().Error().Str("Method", "GetProtocolInfo").Str("Action", "Prepare POST").Err(err).Msg("")
return fmt.Errorf("GetProtocolInfo POST error: %w", err)
@@ -1027,7 +1029,7 @@ func (p *TVPayload) Gapless() (string, error) {
}
client := &http.Client{}
req, err := http.NewRequest("POST", parsedURLtransport.String(), bytes.NewReader(xmlbuilder))
req, err := http.NewRequestWithContext(p.ctx, "POST", parsedURLtransport.String(), bytes.NewReader(xmlbuilder))
if err != nil {
p.Log().Error().Str("Method", "Gapless").Str("Action", "Prepare POST").Err(err).Msg("")
return "", fmt.Errorf("Gapless POST error: %w", err)
@@ -1106,7 +1108,7 @@ func (p *TVPayload) GetTransportInfo() ([]string, error) {
}
client := &http.Client{}
req, err := http.NewRequest("POST", parsedURLtransport.String(), bytes.NewReader(xmlbuilder))
req, err := http.NewRequestWithContext(p.ctx, "POST", parsedURLtransport.String(), bytes.NewReader(xmlbuilder))
if err != nil {
p.Log().Error().Str("Method", "GetTransportInfo").Str("Action", "Prepare POST").Err(err).Msg("")
return nil, fmt.Errorf("GetTransportInfo POST error: %w", err)
@@ -1188,7 +1190,7 @@ func (p *TVPayload) GetPositionInfo() ([]string, error) {
}
client := &http.Client{}
req, err := http.NewRequest("POST", parsedURLtransport.String(), bytes.NewReader(xmlbuilder))
req, err := http.NewRequestWithContext(p.ctx, "POST", parsedURLtransport.String(), bytes.NewReader(xmlbuilder))
if err != nil {
p.Log().Error().Str("Method", "GetPositionInfo").Str("Action", "Prepare POST").Err(err).Msg("")
return nil, fmt.Errorf("GetPositionInfo POST error: %w", err)

View File

@@ -1,6 +1,7 @@
package soapcalls
import (
"context"
"io"
"net/url"
"time"
@@ -10,6 +11,7 @@ import (
type Options struct {
Logging io.Writer
ctx context.Context
DMR string
Media string
Subs string
@@ -19,8 +21,12 @@ type Options struct {
Seek bool
}
func NewTVPayload(o Options) (*TVPayload, error) {
upnpServicesURLs, err := DMRextractor(o.DMR)
func NewTVPayload(o *Options) (*TVPayload, error) {
if o.ctx == nil {
o.ctx = context.Background()
}
upnpServicesURLs, err := DMRextractor(o.ctx, o.DMR)
if err != nil {
return nil, err
}

View File

@@ -1,6 +1,7 @@
package soapcalls
import (
"context"
"encoding/xml"
"fmt"
"io"
@@ -55,7 +56,7 @@ type DMRextracted struct {
}
// DMRextractor extracts the services URLs from the main DMR xml.
func DMRextractor(dmrurl string) (*DMRextracted, error) {
func DMRextractor(ctx context.Context, dmrurl string) (*DMRextracted, error) {
var root rootNode
ex := &DMRextracted{}
@@ -65,7 +66,7 @@ func DMRextractor(dmrurl string) (*DMRextracted, error) {
}
client := &http.Client{}
req, err := http.NewRequest("GET", dmrurl, nil)
req, err := http.NewRequestWithContext(ctx, "GET", dmrurl, nil)
if err != nil {
return nil, fmt.Errorf("DMRextractor GET error: %w", err)
}

View File

@@ -1,6 +1,7 @@
package soapcalls
import (
"context"
"net/http"
"net/http/httptest"
"testing"
@@ -42,7 +43,7 @@ func TestDMRextractor(t *testing.T) {
defer testServer.Close()
_, err := DMRextractor(testServer.URL)
_, err := DMRextractor(context.Background(), testServer.URL)
if err != nil {
t.Fatalf("Failed to call DMRextractor due to %s", err.Error())
}