-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Determine release time via YouTube API
- Loading branch information
1 parent
2ba960a
commit eb30fa4
Showing
4 changed files
with
194 additions
and
95 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package local | ||
|
||
import ( | ||
"time" | ||
|
||
log "github.com/sirupsen/logrus" | ||
|
||
"github.com/lbryio/lbry.go/v2/extras/util" | ||
) | ||
|
||
type YouTubeVideoEnricher interface { | ||
EnrichMissing(source *SourceVideo) error | ||
} | ||
|
||
type YouTubeAPIVideoEnricher struct { | ||
api *YouTubeAPI | ||
} | ||
|
||
func NewYouTubeAPIVideoEnricher(apiKey string) (*YouTubeAPIVideoEnricher) { | ||
enricher := YouTubeAPIVideoEnricher{ | ||
api: NewYouTubeAPI(apiKey), | ||
} | ||
return &enricher | ||
} | ||
|
||
func (e *YouTubeAPIVideoEnricher) EnrichMissing(source *SourceVideo) error { | ||
if source.ReleaseTime != nil { | ||
log.Debugf("Video %s does not need enrichment. YouTubeAPIVideoEnricher is skipping.", source.ID) | ||
return nil | ||
} | ||
|
||
snippet, err := e.api.GetVideoSnippet(source.ID) | ||
if err != nil { | ||
log.Errorf("Error snippet data for video %s: %v", err) | ||
return err | ||
} | ||
|
||
publishedAt, err := time.Parse(time.RFC3339, snippet.PublishedAt) | ||
if err != nil { | ||
log.Errorf("Error converting publishedAt to timestamp: %v", err) | ||
} else { | ||
source.ReleaseTime = util.PtrToInt64(publishedAt.Unix()) | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package local | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
"net/http" | ||
"time" | ||
|
||
log "github.com/sirupsen/logrus" | ||
) | ||
|
||
type YouTubeAPI struct { | ||
apiKey string | ||
client *http.Client | ||
} | ||
|
||
func NewYouTubeAPI(apiKey string) (*YouTubeAPI) { | ||
client := &http.Client { | ||
Transport: &http.Transport{ | ||
MaxIdleConns: 10, | ||
IdleConnTimeout: 30 * time.Second, | ||
DisableCompression: true, | ||
}, | ||
} | ||
|
||
api := YouTubeAPI { | ||
apiKey: apiKey, | ||
client: client, | ||
} | ||
|
||
return &api | ||
} | ||
|
||
func (a *YouTubeAPI) GetVideoSnippet(videoID string) (*VideoSnippet, error) { | ||
req, err := http.NewRequest("GET", "https://youtube.googleapis.com/youtube/v3/videos", nil) | ||
if err != nil { | ||
log.Errorf("Error creating http client for YouTube API: %v", err) | ||
return nil, err | ||
} | ||
|
||
query := req.URL.Query() | ||
query.Add("part", "snippet") | ||
query.Add("id", videoID) | ||
query.Add("key", a.apiKey) | ||
req.URL.RawQuery = query.Encode() | ||
|
||
req.Header.Add("Accept", "application/json") | ||
|
||
resp, err := a.client.Do(req) | ||
defer resp.Body.Close() | ||
if err != nil { | ||
log.Errorf("Error from YouTube API: %v", err) | ||
return nil, err | ||
} | ||
|
||
body, err := io.ReadAll(resp.Body) | ||
log.Tracef("Response from YouTube API: %s", string(body[:])) | ||
|
||
var result videoListResponse | ||
err = json.Unmarshal(body, &result) | ||
if err != nil { | ||
log.Errorf("Error deserializing video list response from YouTube API: %v", err) | ||
return nil, err | ||
} | ||
|
||
if len(result.Items) != 1 { | ||
err = fmt.Errorf("YouTube API responded with incorrect number of snippets (%d) while attempting to get snippet data for video %s", len(result.Items), videoID) | ||
return nil, err | ||
} | ||
|
||
return &result.Items[0].Snippet, nil | ||
} | ||
|
||
type videoListResponse struct { | ||
Items []struct { | ||
Snippet VideoSnippet `json:"snippet"` | ||
} `json:"items"` | ||
} | ||
|
||
type VideoSnippet struct { | ||
PublishedAt string `json:"publishedAt"` | ||
} |
Oops, something went wrong.