all repos — fixyoutube-go @ 913b5e94318ac196a2c6111e459ffe2ba801cd36

A better way to embed YouTube videos everywhere (inspired by FixTweet).

change invidious instance if one fails
Marco Andronaco andronacomarco@gmail.com
Thu, 11 Jan 2024 15:34:44 +0100
commit

913b5e94318ac196a2c6111e459ffe2ba801cd36

parent

f4aee526df2825f57da964fff12ea902c5979782

1 files changed, 42 insertions(+), 4 deletions(-)

jump to
M invidious/invidious.goinvidious/invidious.go

@@ -14,6 +14,7 @@

"github.com/sirupsen/logrus" ) +const timeoutDuration = 10 * time.Minute const maxSizeMB = 50 const instancesEndpoint = "https://api.invidious.io/instances.json?sort_by=api,type" const videosEndpoint = "https://%s/api/v1/videos/%s?fields=videoId,title,description,author,lengthSeconds,size,formatStreams"

@@ -21,8 +22,14 @@

var expireRegex = regexp.MustCompile(`(?i)expire=(\d+)`) var logger = logrus.New() +type Timeout struct { + Instance string + Timestamp time.Time +} + type Client struct { http *http.Client + timeouts []Timeout Instance string }

@@ -137,7 +144,25 @@ CacheVideoDB(*video)

return video, nil } +func (c *Client) isNotTimedOut(instance string) bool { + for i := range c.timeouts { + cur := c.timeouts[i] + if instance == cur.Instance { + return false + } + } + return true +} + func (c *Client) NewInstance() error { + now := time.Now() + + timeoutsTest := func(t Timeout) bool { return now.Sub(t.Timestamp) < timeoutDuration } + c.timeouts = filter(c.timeouts, timeoutsTest) + + timeout := Timeout{c.Instance, now} + c.timeouts = append(c.timeouts, timeout) + resp, err := c.http.Get(instancesEndpoint) if err != nil { return err

@@ -159,9 +184,18 @@ if err != nil {

return err } - c.Instance = jsonArray[0][0].(string) - logger.Info("Using new instance:", c.Instance) - return nil + for i := range jsonArray { + instance := jsonArray[i][0].(string) + instanceTest := func(t Timeout) bool { return t.Instance == instance } + result := filter(c.timeouts, instanceTest) + if len(result) == 0 { + c.Instance = instance + logger.Info("Using new instance: ", c.Instance) + return nil + } + } + logger.Error("Cannot find a valid instance.") + return err } func (c *Client) ProxyVideo(w http.ResponseWriter, videoId string, formatIndex int) error {

@@ -215,5 +249,9 @@ }

func NewClient(httpClient *http.Client) *Client { InitDB() - return &Client{httpClient, ""} + return &Client{ + http: httpClient, + timeouts: []Timeout{}, + Instance: "", + } }