2018-09-05 23:35:59 +02:00
|
|
|
package sdk
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2019-06-01 01:46:16 +02:00
|
|
|
"fmt"
|
2018-09-05 23:35:59 +02:00
|
|
|
"io/ioutil"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
2019-02-22 19:33:00 +01:00
|
|
|
"regexp"
|
2018-09-05 23:35:59 +02:00
|
|
|
"strconv"
|
2019-02-22 19:33:00 +01:00
|
|
|
"strings"
|
2018-09-05 23:35:59 +02:00
|
|
|
"time"
|
|
|
|
|
2019-10-10 16:50:33 +02:00
|
|
|
"github.com/lbryio/lbry.go/v2/extras/errors"
|
|
|
|
"github.com/lbryio/lbry.go/v2/extras/null"
|
2021-12-30 19:17:11 +01:00
|
|
|
"github.com/lbryio/ytsync/v5/configs"
|
2020-08-08 01:12:55 +02:00
|
|
|
"github.com/lbryio/ytsync/v5/shared"
|
2019-02-27 14:38:43 +01:00
|
|
|
|
2020-06-11 18:45:56 +02:00
|
|
|
"github.com/lbryio/ytsync/v5/util"
|
2019-10-14 17:51:26 +02:00
|
|
|
|
2019-02-27 14:38:43 +01:00
|
|
|
log "github.com/sirupsen/logrus"
|
2018-09-05 23:35:59 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2018-10-11 23:21:05 +02:00
|
|
|
MaxReasonLength = 490
|
2018-09-05 23:35:59 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
type APIConfig struct {
|
2021-11-24 05:54:08 +01:00
|
|
|
ApiURL string
|
|
|
|
ApiToken string
|
|
|
|
HostName string
|
2018-09-05 23:35:59 +02:00
|
|
|
}
|
|
|
|
|
2021-12-30 19:17:11 +01:00
|
|
|
var instance *APIConfig
|
|
|
|
|
|
|
|
func GetAPIsConfigs() *APIConfig {
|
|
|
|
if instance == nil {
|
|
|
|
instance = &APIConfig{
|
|
|
|
ApiURL: configs.Configuration.InternalApisEndpoint,
|
|
|
|
ApiToken: configs.Configuration.InternalApisAuthToken,
|
|
|
|
HostName: configs.Configuration.GetHostname(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return instance
|
|
|
|
}
|
|
|
|
|
2020-08-08 01:12:55 +02:00
|
|
|
func (a *APIConfig) FetchChannels(status string, cliFlags *shared.SyncFlags) ([]shared.YoutubeChannel, error) {
|
2018-09-05 23:35:59 +02:00
|
|
|
type apiJobsResponse struct {
|
2020-08-08 01:12:55 +02:00
|
|
|
Success bool `json:"success"`
|
|
|
|
Error null.String `json:"error"`
|
|
|
|
Data []shared.YoutubeChannel `json:"data"`
|
2018-09-05 23:35:59 +02:00
|
|
|
}
|
|
|
|
endpoint := a.ApiURL + "/yt/jobs"
|
2019-07-12 20:42:44 +02:00
|
|
|
res, err := http.PostForm(endpoint, url.Values{
|
2018-09-05 23:35:59 +02:00
|
|
|
"auth_token": {a.ApiToken},
|
|
|
|
"sync_status": {status},
|
|
|
|
"min_videos": {strconv.Itoa(1)},
|
2020-08-08 01:12:55 +02:00
|
|
|
"after": {strconv.Itoa(int(cliFlags.SyncFrom))},
|
|
|
|
"before": {strconv.Itoa(int(cliFlags.SyncUntil))},
|
2018-09-05 23:35:59 +02:00
|
|
|
"sync_server": {a.HostName},
|
2020-08-08 01:12:55 +02:00
|
|
|
"channel_id": {cliFlags.ChannelID},
|
2018-09-05 23:35:59 +02:00
|
|
|
})
|
2019-07-12 20:42:44 +02:00
|
|
|
if err != nil {
|
2022-05-04 17:13:03 +02:00
|
|
|
util.SendErrorToSlack("error while trying to call %s. Waiting to retry: %s", endpoint, err.Error())
|
|
|
|
time.Sleep(30 * time.Second)
|
|
|
|
return a.FetchChannels(status, cliFlags)
|
2019-07-12 20:42:44 +02:00
|
|
|
}
|
2019-10-16 19:38:45 +02:00
|
|
|
defer res.Body.Close()
|
|
|
|
body, _ := ioutil.ReadAll(res.Body)
|
2019-10-14 17:51:26 +02:00
|
|
|
if res.StatusCode != http.StatusOK {
|
|
|
|
util.SendErrorToSlack("Error %d while trying to call %s. Waiting to retry", res.StatusCode, endpoint)
|
2019-10-25 18:35:09 +02:00
|
|
|
log.Debugln(string(body))
|
2019-10-14 17:51:26 +02:00
|
|
|
time.Sleep(30 * time.Second)
|
2020-08-08 01:12:55 +02:00
|
|
|
return a.FetchChannels(status, cliFlags)
|
2019-10-14 17:51:26 +02:00
|
|
|
}
|
2018-09-05 23:35:59 +02:00
|
|
|
var response apiJobsResponse
|
2019-07-12 20:42:44 +02:00
|
|
|
err = json.Unmarshal(body, &response)
|
2018-09-05 23:35:59 +02:00
|
|
|
if err != nil {
|
2019-08-11 04:50:43 +02:00
|
|
|
return nil, errors.Err(err)
|
2018-09-05 23:35:59 +02:00
|
|
|
}
|
|
|
|
if response.Data == nil {
|
|
|
|
return nil, errors.Err(response.Error)
|
|
|
|
}
|
|
|
|
log.Printf("Fetched channels: %d", len(response.Data))
|
|
|
|
return response.Data, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
type SyncedVideo struct {
|
2019-05-03 05:11:52 +02:00
|
|
|
VideoID string `json:"video_id"`
|
|
|
|
Published bool `json:"published"`
|
|
|
|
FailureReason string `json:"failure_reason"`
|
|
|
|
ClaimName string `json:"claim_name"`
|
|
|
|
ClaimID string `json:"claim_id"`
|
|
|
|
Size int64 `json:"size"`
|
|
|
|
MetadataVersion int8 `json:"metadata_version"`
|
2019-08-21 19:40:35 +02:00
|
|
|
Transferred bool `json:"transferred"`
|
2020-07-21 19:54:28 +02:00
|
|
|
IsLbryFirst bool `json:"is_lbry_first"`
|
2018-09-05 23:35:59 +02:00
|
|
|
}
|
|
|
|
|
2019-02-22 19:33:00 +01:00
|
|
|
func sanitizeFailureReason(s *string) {
|
|
|
|
re := regexp.MustCompile("[[:^ascii:]]")
|
|
|
|
*s = strings.Replace(re.ReplaceAllLiteralString(*s, ""), "\n", " ", -1)
|
|
|
|
|
|
|
|
if len(*s) > MaxReasonLength {
|
|
|
|
*s = (*s)[:MaxReasonLength]
|
|
|
|
}
|
|
|
|
}
|
2019-07-26 05:46:35 +02:00
|
|
|
|
|
|
|
func (a *APIConfig) SetChannelCert(certHex string, channelID string) error {
|
2019-07-31 05:32:02 +02:00
|
|
|
type apiSetChannelCertResponse struct {
|
|
|
|
Success bool `json:"success"`
|
|
|
|
Error null.String `json:"error"`
|
|
|
|
Data string `json:"data"`
|
|
|
|
}
|
|
|
|
|
2019-07-26 05:46:35 +02:00
|
|
|
endpoint := a.ApiURL + "/yt/channel_cert"
|
|
|
|
|
2019-10-12 09:49:49 +02:00
|
|
|
res, err := http.PostForm(endpoint, url.Values{
|
2019-07-31 05:32:02 +02:00
|
|
|
"channel_claim_id": {channelID},
|
|
|
|
"channel_cert": {certHex},
|
|
|
|
"auth_token": {a.ApiToken},
|
2019-07-26 05:46:35 +02:00
|
|
|
})
|
2019-10-12 09:49:49 +02:00
|
|
|
if err != nil {
|
2022-05-04 17:13:03 +02:00
|
|
|
util.SendErrorToSlack("error while trying to call %s. Waiting to retry: %s", endpoint, err.Error())
|
|
|
|
time.Sleep(30 * time.Second)
|
|
|
|
return a.SetChannelCert(certHex, channelID)
|
2019-10-12 09:49:49 +02:00
|
|
|
}
|
2019-10-16 19:38:45 +02:00
|
|
|
defer res.Body.Close()
|
|
|
|
body, _ := ioutil.ReadAll(res.Body)
|
2019-10-14 17:51:26 +02:00
|
|
|
if res.StatusCode != http.StatusOK {
|
|
|
|
util.SendErrorToSlack("Error %d while trying to call %s. Waiting to retry", res.StatusCode, endpoint)
|
2020-05-08 16:33:29 +02:00
|
|
|
log.Debugln(string(body))
|
2019-10-14 17:51:26 +02:00
|
|
|
time.Sleep(30 * time.Second)
|
|
|
|
return a.SetChannelCert(certHex, channelID)
|
|
|
|
}
|
2019-07-31 05:32:02 +02:00
|
|
|
var response apiSetChannelCertResponse
|
2019-10-14 17:51:26 +02:00
|
|
|
err = json.Unmarshal(body, &response)
|
2019-07-26 05:46:35 +02:00
|
|
|
if err != nil {
|
|
|
|
return errors.Err(err)
|
|
|
|
}
|
2019-07-31 05:32:02 +02:00
|
|
|
if !response.Error.IsNull() {
|
|
|
|
return errors.Err(response.Error.String)
|
2019-07-26 05:46:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2019-08-21 19:40:35 +02:00
|
|
|
func (a *APIConfig) SetChannelStatus(channelID string, status string, failureReason string, transferState *int) (map[string]SyncedVideo, map[string]bool, error) {
|
2018-09-05 23:35:59 +02:00
|
|
|
type apiChannelStatusResponse struct {
|
|
|
|
Success bool `json:"success"`
|
|
|
|
Error null.String `json:"error"`
|
|
|
|
Data []SyncedVideo `json:"data"`
|
|
|
|
}
|
|
|
|
endpoint := a.ApiURL + "/yt/channel_status"
|
2019-02-22 19:33:00 +01:00
|
|
|
|
|
|
|
sanitizeFailureReason(&failureReason)
|
2019-08-21 19:40:35 +02:00
|
|
|
params := url.Values{
|
2018-09-05 23:35:59 +02:00
|
|
|
"channel_id": {channelID},
|
|
|
|
"sync_server": {a.HostName},
|
|
|
|
"auth_token": {a.ApiToken},
|
|
|
|
"sync_status": {status},
|
|
|
|
"failure_reason": {failureReason},
|
2019-08-21 19:40:35 +02:00
|
|
|
}
|
|
|
|
if transferState != nil {
|
2019-08-22 06:09:33 +02:00
|
|
|
params.Add("transfer_state", strconv.Itoa(*transferState))
|
2019-08-21 19:40:35 +02:00
|
|
|
}
|
2019-10-14 17:51:26 +02:00
|
|
|
res, err := http.PostForm(endpoint, params)
|
|
|
|
if err != nil {
|
2022-05-04 17:13:03 +02:00
|
|
|
util.SendErrorToSlack("error while trying to call %s. Waiting to retry: %s", endpoint, err.Error())
|
|
|
|
time.Sleep(30 * time.Second)
|
|
|
|
return a.SetChannelStatus(channelID, status, failureReason, transferState)
|
2019-10-14 17:51:26 +02:00
|
|
|
}
|
2019-10-16 19:38:45 +02:00
|
|
|
defer res.Body.Close()
|
|
|
|
body, _ := ioutil.ReadAll(res.Body)
|
2019-10-25 18:35:09 +02:00
|
|
|
if res.StatusCode >= http.StatusInternalServerError {
|
2019-10-14 17:51:26 +02:00
|
|
|
util.SendErrorToSlack("Error %d while trying to call %s. Waiting to retry", res.StatusCode, endpoint)
|
2019-10-25 18:35:09 +02:00
|
|
|
log.Debugln(string(body))
|
2019-10-14 17:51:26 +02:00
|
|
|
time.Sleep(30 * time.Second)
|
|
|
|
return a.SetChannelStatus(channelID, status, failureReason, transferState)
|
|
|
|
}
|
2018-09-05 23:35:59 +02:00
|
|
|
var response apiChannelStatusResponse
|
2019-10-14 17:51:26 +02:00
|
|
|
err = json.Unmarshal(body, &response)
|
2018-09-05 23:35:59 +02:00
|
|
|
if err != nil {
|
2019-08-11 04:50:43 +02:00
|
|
|
return nil, nil, errors.Err(err)
|
2018-09-05 23:35:59 +02:00
|
|
|
}
|
|
|
|
if !response.Error.IsNull() {
|
|
|
|
return nil, nil, errors.Err(response.Error.String)
|
|
|
|
}
|
|
|
|
if response.Data != nil {
|
|
|
|
svs := make(map[string]SyncedVideo)
|
|
|
|
claimNames := make(map[string]bool)
|
|
|
|
for _, v := range response.Data {
|
|
|
|
svs[v.VideoID] = v
|
2019-05-03 05:11:52 +02:00
|
|
|
if v.ClaimName != "" {
|
|
|
|
claimNames[v.ClaimName] = v.Published
|
|
|
|
}
|
2018-09-05 23:35:59 +02:00
|
|
|
}
|
|
|
|
return svs, claimNames, nil
|
|
|
|
}
|
|
|
|
return nil, nil, errors.Err("invalid API response. Status code: %d", res.StatusCode)
|
|
|
|
}
|
|
|
|
|
2018-12-25 01:23:40 +01:00
|
|
|
func (a *APIConfig) SetChannelClaimID(channelID string, channelClaimID string) error {
|
|
|
|
type apiChannelStatusResponse struct {
|
|
|
|
Success bool `json:"success"`
|
|
|
|
Error null.String `json:"error"`
|
|
|
|
Data string `json:"data"`
|
|
|
|
}
|
|
|
|
endpoint := a.ApiURL + "/yt/set_channel_claim_id"
|
2019-10-14 17:51:26 +02:00
|
|
|
res, err := http.PostForm(endpoint, url.Values{
|
2018-12-25 01:23:40 +01:00
|
|
|
"channel_id": {channelID},
|
|
|
|
"auth_token": {a.ApiToken},
|
|
|
|
"channel_claim_id": {channelClaimID},
|
|
|
|
})
|
2019-10-14 17:51:26 +02:00
|
|
|
if err != nil {
|
2022-05-04 17:13:03 +02:00
|
|
|
util.SendErrorToSlack("error while trying to call %s. Waiting to retry: %s", endpoint, err.Error())
|
|
|
|
time.Sleep(30 * time.Second)
|
|
|
|
return a.SetChannelClaimID(channelID, channelClaimID)
|
2019-10-14 17:51:26 +02:00
|
|
|
}
|
2019-10-16 19:38:45 +02:00
|
|
|
defer res.Body.Close()
|
|
|
|
body, _ := ioutil.ReadAll(res.Body)
|
2019-10-14 17:51:26 +02:00
|
|
|
if res.StatusCode != http.StatusOK {
|
|
|
|
util.SendErrorToSlack("Error %d while trying to call %s. Waiting to retry", res.StatusCode, endpoint)
|
2019-10-25 18:35:09 +02:00
|
|
|
log.Debugln(string(body))
|
2019-10-14 17:51:26 +02:00
|
|
|
time.Sleep(30 * time.Second)
|
|
|
|
return a.SetChannelClaimID(channelID, channelClaimID)
|
|
|
|
}
|
2018-12-25 01:23:40 +01:00
|
|
|
var response apiChannelStatusResponse
|
2019-10-14 17:51:26 +02:00
|
|
|
err = json.Unmarshal(body, &response)
|
2018-12-25 01:23:40 +01:00
|
|
|
if err != nil {
|
2019-01-03 17:01:00 +01:00
|
|
|
return errors.Err(err)
|
2018-12-25 01:23:40 +01:00
|
|
|
}
|
|
|
|
if !response.Error.IsNull() {
|
|
|
|
return errors.Err(response.Error.String)
|
|
|
|
}
|
|
|
|
if response.Data != "ok" {
|
|
|
|
return errors.Err("Unexpected API response")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-09-05 23:35:59 +02:00
|
|
|
const (
|
2019-06-12 03:35:21 +02:00
|
|
|
VideoStatusPublished = "published"
|
|
|
|
VideoStatusUpgradeFailed = "upgradefailed"
|
|
|
|
VideoStatusFailed = "failed"
|
2018-09-05 23:35:59 +02:00
|
|
|
)
|
|
|
|
|
2019-06-04 22:21:40 +02:00
|
|
|
func (a *APIConfig) DeleteVideos(videos []string) error {
|
2019-06-06 16:31:35 +02:00
|
|
|
endpoint := a.ApiURL + "/yt/video_delete"
|
2019-06-04 22:21:40 +02:00
|
|
|
videoIDs := strings.Join(videos, ",")
|
|
|
|
vals := url.Values{
|
2019-06-06 16:31:35 +02:00
|
|
|
"video_ids": {videoIDs},
|
2019-06-04 22:21:40 +02:00
|
|
|
"auth_token": {a.ApiToken},
|
|
|
|
}
|
2019-10-14 17:51:26 +02:00
|
|
|
res, err := http.PostForm(endpoint, vals)
|
|
|
|
if err != nil {
|
2022-05-04 17:13:03 +02:00
|
|
|
util.SendErrorToSlack("error while trying to call %s. Waiting to retry: %s", endpoint, err.Error())
|
|
|
|
time.Sleep(30 * time.Second)
|
|
|
|
return a.DeleteVideos(videos)
|
2019-10-14 17:51:26 +02:00
|
|
|
}
|
2019-10-16 19:38:45 +02:00
|
|
|
defer res.Body.Close()
|
|
|
|
body, _ := ioutil.ReadAll(res.Body)
|
2019-10-14 17:51:26 +02:00
|
|
|
if res.StatusCode != http.StatusOK {
|
|
|
|
util.SendErrorToSlack("Error %d while trying to call %s. Waiting to retry", res.StatusCode, endpoint)
|
2019-10-25 18:35:09 +02:00
|
|
|
log.Debugln(string(body))
|
2019-10-14 17:51:26 +02:00
|
|
|
time.Sleep(30 * time.Second)
|
|
|
|
return a.DeleteVideos(videos)
|
|
|
|
}
|
2019-06-06 16:31:35 +02:00
|
|
|
var response struct {
|
|
|
|
Success bool `json:"success"`
|
|
|
|
Error null.String `json:"error"`
|
|
|
|
Data null.String `json:"data"`
|
|
|
|
}
|
2019-10-14 17:51:26 +02:00
|
|
|
err = json.Unmarshal(body, &response)
|
2019-06-04 22:21:40 +02:00
|
|
|
if err != nil {
|
|
|
|
return errors.Err(err)
|
|
|
|
}
|
2019-06-06 16:31:35 +02:00
|
|
|
if !response.Error.IsNull() {
|
|
|
|
return errors.Err(response.Error.String)
|
2019-06-04 22:21:40 +02:00
|
|
|
}
|
2019-06-06 16:31:35 +02:00
|
|
|
|
|
|
|
if !response.Data.IsNull() && response.Data.String == "ok" {
|
|
|
|
return nil
|
2019-06-04 22:21:40 +02:00
|
|
|
}
|
2019-06-06 16:31:35 +02:00
|
|
|
return errors.Err("invalid API response. Status code: %d", res.StatusCode)
|
2019-06-04 22:21:40 +02:00
|
|
|
}
|
|
|
|
|
2020-08-08 01:12:55 +02:00
|
|
|
func (a *APIConfig) MarkVideoStatus(status shared.VideoStatus) error {
|
2018-09-05 23:35:59 +02:00
|
|
|
endpoint := a.ApiURL + "/yt/video_status"
|
2019-02-22 19:33:00 +01:00
|
|
|
|
2019-08-20 07:06:51 +02:00
|
|
|
sanitizeFailureReason(&status.FailureReason)
|
2018-09-05 23:35:59 +02:00
|
|
|
vals := url.Values{
|
2019-08-20 07:06:51 +02:00
|
|
|
"youtube_channel_id": {status.ChannelID},
|
|
|
|
"video_id": {status.VideoID},
|
|
|
|
"status": {status.Status},
|
2018-09-05 23:35:59 +02:00
|
|
|
"auth_token": {a.ApiToken},
|
|
|
|
}
|
2019-08-20 07:06:51 +02:00
|
|
|
if status.Status == VideoStatusPublished || status.Status == VideoStatusUpgradeFailed {
|
|
|
|
if status.ClaimID == "" || status.ClaimName == "" {
|
|
|
|
return errors.Err("claimID (%s) or claimName (%s) missing", status.ClaimID, status.ClaimName)
|
2018-09-05 23:35:59 +02:00
|
|
|
}
|
|
|
|
vals.Add("published_at", strconv.FormatInt(time.Now().Unix(), 10))
|
2019-08-20 07:06:51 +02:00
|
|
|
vals.Add("claim_id", status.ClaimID)
|
|
|
|
vals.Add("claim_name", status.ClaimName)
|
|
|
|
if status.MetaDataVersion > 0 {
|
|
|
|
vals.Add("metadata_version", fmt.Sprintf("%d", status.MetaDataVersion))
|
2019-06-06 23:25:31 +02:00
|
|
|
}
|
2019-08-20 07:06:51 +02:00
|
|
|
if status.Size != nil {
|
|
|
|
vals.Add("size", strconv.FormatInt(*status.Size, 10))
|
2018-09-05 23:35:59 +02:00
|
|
|
}
|
|
|
|
}
|
2019-08-20 07:06:51 +02:00
|
|
|
if status.FailureReason != "" {
|
|
|
|
vals.Add("failure_reason", status.FailureReason)
|
|
|
|
}
|
|
|
|
if status.IsTransferred != nil {
|
|
|
|
vals.Add("transferred", strconv.FormatBool(*status.IsTransferred))
|
2018-09-05 23:35:59 +02:00
|
|
|
}
|
2019-10-14 17:51:26 +02:00
|
|
|
res, err := http.PostForm(endpoint, vals)
|
|
|
|
if err != nil {
|
2022-05-04 17:13:03 +02:00
|
|
|
util.SendErrorToSlack("error while trying to call %s. Waiting to retry: %s", endpoint, err.Error())
|
|
|
|
time.Sleep(30 * time.Second)
|
|
|
|
return a.MarkVideoStatus(status)
|
2019-10-14 17:51:26 +02:00
|
|
|
}
|
2019-10-16 19:38:45 +02:00
|
|
|
defer res.Body.Close()
|
|
|
|
body, _ := ioutil.ReadAll(res.Body)
|
2019-10-14 17:51:26 +02:00
|
|
|
if res.StatusCode != http.StatusOK {
|
|
|
|
util.SendErrorToSlack("Error %d while trying to call %s. Waiting to retry", res.StatusCode, endpoint)
|
2019-10-25 18:35:09 +02:00
|
|
|
log.Debugln(string(body))
|
2019-10-14 17:51:26 +02:00
|
|
|
time.Sleep(30 * time.Second)
|
|
|
|
return a.MarkVideoStatus(status)
|
|
|
|
}
|
2018-09-05 23:35:59 +02:00
|
|
|
var response struct {
|
|
|
|
Success bool `json:"success"`
|
|
|
|
Error null.String `json:"error"`
|
|
|
|
Data null.String `json:"data"`
|
|
|
|
}
|
2019-10-14 17:51:26 +02:00
|
|
|
err = json.Unmarshal(body, &response)
|
2018-09-05 23:35:59 +02:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if !response.Error.IsNull() {
|
|
|
|
return errors.Err(response.Error.String)
|
|
|
|
}
|
|
|
|
if !response.Data.IsNull() && response.Data.String == "ok" {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return errors.Err("invalid API response. Status code: %d", res.StatusCode)
|
|
|
|
}
|
2020-07-29 06:12:23 +02:00
|
|
|
|
|
|
|
func (a *APIConfig) VideoState(videoID string) (string, error) {
|
|
|
|
endpoint := a.ApiURL + "/yt/video_state"
|
|
|
|
vals := url.Values{
|
|
|
|
"video_id": {videoID},
|
|
|
|
"auth_token": {a.ApiToken},
|
|
|
|
}
|
|
|
|
|
|
|
|
res, err := http.PostForm(endpoint, vals)
|
|
|
|
if err != nil {
|
2022-05-04 17:13:03 +02:00
|
|
|
util.SendErrorToSlack("error while trying to call %s. Waiting to retry: %s", endpoint, err.Error())
|
|
|
|
time.Sleep(30 * time.Second)
|
|
|
|
return a.VideoState(videoID)
|
2020-07-29 06:12:23 +02:00
|
|
|
}
|
|
|
|
defer res.Body.Close()
|
|
|
|
body, _ := ioutil.ReadAll(res.Body)
|
|
|
|
if res.StatusCode == http.StatusNotFound {
|
|
|
|
return "not_found", nil
|
|
|
|
}
|
|
|
|
if res.StatusCode != http.StatusOK {
|
|
|
|
util.SendErrorToSlack("Error %d while trying to call %s. Waiting to retry", res.StatusCode, endpoint)
|
|
|
|
log.Debugln(string(body))
|
|
|
|
time.Sleep(30 * time.Second)
|
|
|
|
return a.VideoState(videoID)
|
|
|
|
}
|
|
|
|
var response struct {
|
|
|
|
Success bool `json:"success"`
|
|
|
|
Error null.String `json:"error"`
|
|
|
|
Data null.String `json:"data"`
|
|
|
|
}
|
|
|
|
err = json.Unmarshal(body, &response)
|
|
|
|
if err != nil {
|
|
|
|
return "", errors.Err(err)
|
|
|
|
}
|
|
|
|
if !response.Error.IsNull() {
|
|
|
|
return "", errors.Err(response.Error.String)
|
|
|
|
}
|
|
|
|
if !response.Data.IsNull() {
|
|
|
|
return response.Data.String, nil
|
|
|
|
}
|
|
|
|
return "", errors.Err("invalid API response. Status code: %d", res.StatusCode)
|
|
|
|
}
|
2020-07-30 17:13:19 +02:00
|
|
|
|
|
|
|
type VideoRelease struct {
|
|
|
|
ID uint64 `json:"id"`
|
|
|
|
YoutubeDataID uint64 `json:"youtube_data_id"`
|
|
|
|
VideoID string `json:"video_id"`
|
2020-08-06 02:12:05 +02:00
|
|
|
ReleaseTime string `json:"release_time"`
|
2020-07-30 17:13:19 +02:00
|
|
|
CreatedAt string `json:"created_at"`
|
|
|
|
UpdatedAt string `json:"updated_at"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *APIConfig) GetReleasedDate(videoID string) (*VideoRelease, error) {
|
|
|
|
endpoint := a.ApiURL + "/yt/released"
|
|
|
|
vals := url.Values{
|
|
|
|
"video_id": {videoID},
|
|
|
|
"auth_token": {a.ApiToken},
|
|
|
|
}
|
|
|
|
|
|
|
|
res, err := http.PostForm(endpoint, vals)
|
|
|
|
if err != nil {
|
2022-05-04 17:13:03 +02:00
|
|
|
util.SendErrorToSlack("error while trying to call %s. Waiting to retry: %s", endpoint, err.Error())
|
|
|
|
time.Sleep(30 * time.Second)
|
|
|
|
return a.GetReleasedDate(videoID)
|
2020-07-30 17:13:19 +02:00
|
|
|
}
|
|
|
|
defer res.Body.Close()
|
|
|
|
body, _ := ioutil.ReadAll(res.Body)
|
|
|
|
if res.StatusCode == http.StatusNotFound {
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
if res.StatusCode != http.StatusOK {
|
|
|
|
util.SendErrorToSlack("Error %d while trying to call %s. Waiting to retry", res.StatusCode, endpoint)
|
|
|
|
log.Debugln(string(body))
|
|
|
|
time.Sleep(30 * time.Second)
|
|
|
|
return a.GetReleasedDate(videoID)
|
|
|
|
}
|
|
|
|
var response struct {
|
|
|
|
Success bool `json:"success"`
|
|
|
|
Error null.String `json:"error"`
|
|
|
|
Data VideoRelease `json:"data"`
|
|
|
|
}
|
|
|
|
err = json.Unmarshal(body, &response)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Err(err)
|
|
|
|
}
|
|
|
|
if !response.Error.IsNull() {
|
|
|
|
return nil, errors.Err(response.Error.String)
|
|
|
|
}
|
|
|
|
if response.Data.ReleaseTime != "" {
|
|
|
|
return &response.Data, nil
|
|
|
|
}
|
|
|
|
return nil, errors.Err("invalid API response. Status code: %d", res.StatusCode)
|
|
|
|
}
|