Merge branch 'main' of https://github.com/govdbot/govd
All checks were successful
Build and deploy / build-and-push-image (push) Successful in 8m20s
All checks were successful
Build and deploy / build-and-push-image (push) Successful in 8m20s
This commit is contained in:
commit
933467788e
8 changed files with 65 additions and 71 deletions
|
@ -58,8 +58,6 @@ func ParseGQLMedia(
|
||||||
ctx *models.DownloadContext,
|
ctx *models.DownloadContext,
|
||||||
data *Media,
|
data *Media,
|
||||||
) ([]*models.Media, error) {
|
) ([]*models.Media, error) {
|
||||||
var mediaList []*models.Media
|
|
||||||
|
|
||||||
var caption string
|
var caption string
|
||||||
if data.EdgeMediaToCaption != nil && len(data.EdgeMediaToCaption.Edges) > 0 {
|
if data.EdgeMediaToCaption != nil && len(data.EdgeMediaToCaption.Edges) > 0 {
|
||||||
caption = data.EdgeMediaToCaption.Edges[0].Node.Text
|
caption = data.EdgeMediaToCaption.Edges[0].Node.Text
|
||||||
|
@ -84,8 +82,7 @@ func ParseGQLMedia(
|
||||||
Height: int64(data.Dimensions.Height),
|
Height: int64(data.Dimensions.Height),
|
||||||
})
|
})
|
||||||
|
|
||||||
mediaList = append(mediaList, media)
|
return []*models.Media{media}, nil
|
||||||
|
|
||||||
case "GraphImage", "XDTGraphImage":
|
case "GraphImage", "XDTGraphImage":
|
||||||
media := ctx.Extractor.NewMedia(contentID, contentURL)
|
media := ctx.Extractor.NewMedia(contentID, contentURL)
|
||||||
media.SetCaption(caption)
|
media.SetCaption(caption)
|
||||||
|
@ -96,12 +93,14 @@ func ParseGQLMedia(
|
||||||
URL: []string{data.DisplayURL},
|
URL: []string{data.DisplayURL},
|
||||||
})
|
})
|
||||||
|
|
||||||
mediaList = append(mediaList, media)
|
return []*models.Media{media}, nil
|
||||||
|
|
||||||
case "GraphSidecar", "XDTGraphSidecar":
|
case "GraphSidecar", "XDTGraphSidecar":
|
||||||
if data.EdgeSidecarToChildren != nil && len(data.EdgeSidecarToChildren.Edges) > 0 {
|
if data.EdgeSidecarToChildren != nil && len(data.EdgeSidecarToChildren.Edges) > 0 {
|
||||||
for _, edge := range data.EdgeSidecarToChildren.Edges {
|
edges := data.EdgeSidecarToChildren.Edges
|
||||||
node := edge.Node
|
mediaList := make([]*models.Media, 0, len(edges))
|
||||||
|
|
||||||
|
for i := range edges {
|
||||||
|
node := edges[i].Node
|
||||||
media := ctx.Extractor.NewMedia(contentID, contentURL)
|
media := ctx.Extractor.NewMedia(contentID, contentURL)
|
||||||
media.SetCaption(caption)
|
media.SetCaption(caption)
|
||||||
|
|
||||||
|
@ -128,10 +127,11 @@ func ParseGQLMedia(
|
||||||
|
|
||||||
mediaList = append(mediaList, media)
|
mediaList = append(mediaList, media)
|
||||||
}
|
}
|
||||||
|
return mediaList, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return mediaList, nil
|
return nil, fmt.Errorf("unknown media type: %s", data.Typename)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseEmbedGQL(
|
func ParseEmbedGQL(
|
||||||
|
|
|
@ -42,8 +42,6 @@ var Extractor = &models.Extractor{
|
||||||
}
|
}
|
||||||
|
|
||||||
func MediaListFromAPI(ctx *models.DownloadContext) ([]*models.Media, error) {
|
func MediaListFromAPI(ctx *models.DownloadContext) ([]*models.Media, error) {
|
||||||
var mediaList []*models.Media
|
|
||||||
|
|
||||||
contentID := ctx.MatchedContentID
|
contentID := ctx.MatchedContentID
|
||||||
contentURL := ctx.MatchedContentURL
|
contentURL := ctx.MatchedContentURL
|
||||||
|
|
||||||
|
@ -84,12 +82,12 @@ func MediaListFromAPI(ctx *models.DownloadContext) ([]*models.Media, error) {
|
||||||
media.AddFormat(format)
|
media.AddFormat(format)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(media.Formats) > 0 {
|
if len(media.Formats) > 0 {
|
||||||
mediaList = append(mediaList, media)
|
return []*models.Media{media}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return mediaList, nil
|
// no media found
|
||||||
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetPostData(postID string) (*Post, error) {
|
func GetPostData(postID string) (*Post, error) {
|
||||||
|
|
|
@ -87,9 +87,9 @@ var Extractor = &models.Extractor{
|
||||||
func ExtractPinMedia(ctx *models.DownloadContext) ([]*models.Media, error) {
|
func ExtractPinMedia(ctx *models.DownloadContext) ([]*models.Media, error) {
|
||||||
pinID := ctx.MatchedContentID
|
pinID := ctx.MatchedContentID
|
||||||
contentURL := ctx.MatchedContentURL
|
contentURL := ctx.MatchedContentURL
|
||||||
client := util.GetHTTPClient(ctx.Extractor.CodeName)
|
session := util.GetHTTPClient(ctx.Extractor.CodeName)
|
||||||
|
|
||||||
pinData, err := GetPinData(client, pinID)
|
pinData, err := GetPinData(session, pinID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,7 @@ func ExtractPinMedia(ctx *models.DownloadContext) ([]*models.Media, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetPinData(
|
func GetPinData(
|
||||||
client models.HTTPClient,
|
session models.HTTPClient,
|
||||||
pinID string,
|
pinID string,
|
||||||
) (*PinData, error) {
|
) (*PinData, error) {
|
||||||
params := BuildPinRequestParams(pinID)
|
params := BuildPinRequestParams(pinID)
|
||||||
|
@ -179,7 +179,7 @@ func GetPinData(
|
||||||
// fix 403 error
|
// fix 403 error
|
||||||
req.Header.Set("X-Pinterest-PWS-Handler", "www/[username].js")
|
req.Header.Set("X-Pinterest-PWS-Handler", "www/[username].js")
|
||||||
|
|
||||||
resp, err := client.Do(req)
|
resp, err := session.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to send request: %w", err)
|
return nil, fmt.Errorf("failed to send request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ var Extractor = &models.Extractor{
|
||||||
}
|
}
|
||||||
|
|
||||||
func MediaListFromAPI(ctx *models.DownloadContext) ([]*models.Media, error) {
|
func MediaListFromAPI(ctx *models.DownloadContext) ([]*models.Media, error) {
|
||||||
client := util.GetHTTPClient(ctx.Extractor.CodeName)
|
session := util.GetHTTPClient(ctx.Extractor.CodeName)
|
||||||
|
|
||||||
host := ctx.MatchedGroups["host"]
|
host := ctx.MatchedGroups["host"]
|
||||||
slug := ctx.MatchedGroups["slug"]
|
slug := ctx.MatchedGroups["slug"]
|
||||||
|
@ -89,7 +89,7 @@ func MediaListFromAPI(ctx *models.DownloadContext) ([]*models.Media, error) {
|
||||||
contentID := ctx.MatchedContentID
|
contentID := ctx.MatchedContentID
|
||||||
contentURL := ctx.MatchedContentURL
|
contentURL := ctx.MatchedContentURL
|
||||||
|
|
||||||
manifest, err := GetRedditData(client, host, slug, false)
|
manifest, err := GetRedditData(session, host, slug, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -102,16 +102,12 @@ func MediaListFromAPI(ctx *models.DownloadContext) ([]*models.Media, error) {
|
||||||
title := data.Title
|
title := data.Title
|
||||||
isNsfw := data.Over18
|
isNsfw := data.Over18
|
||||||
|
|
||||||
var mediaList []*models.Media
|
|
||||||
|
|
||||||
if !data.IsVideo {
|
if !data.IsVideo {
|
||||||
// check for single photo
|
// check for single photo
|
||||||
if data.Preview != nil && len(data.Preview.Images) > 0 {
|
if data.Preview != nil && len(data.Preview.Images) > 0 {
|
||||||
media := ctx.Extractor.NewMedia(contentID, contentURL)
|
media := ctx.Extractor.NewMedia(contentID, contentURL)
|
||||||
media.SetCaption(title)
|
media.SetCaption(title)
|
||||||
if isNsfw {
|
media.NSFW = isNsfw
|
||||||
media.NSFW = true
|
|
||||||
}
|
|
||||||
|
|
||||||
image := data.Preview.Images[0]
|
image := data.Preview.Images[0]
|
||||||
|
|
||||||
|
@ -130,8 +126,7 @@ func MediaListFromAPI(ctx *models.DownloadContext) ([]*models.Media, error) {
|
||||||
media.AddFormat(format)
|
media.AddFormat(format)
|
||||||
}
|
}
|
||||||
|
|
||||||
mediaList = append(mediaList, media)
|
return []*models.Media{media}, nil
|
||||||
return mediaList, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for MP4 variant (animated GIF)
|
// check for MP4 variant (animated GIF)
|
||||||
|
@ -145,8 +140,7 @@ func MediaListFromAPI(ctx *models.DownloadContext) ([]*models.Media, error) {
|
||||||
Thumbnail: []string{util.FixURL(image.Source.URL)},
|
Thumbnail: []string{util.FixURL(image.Source.URL)},
|
||||||
})
|
})
|
||||||
|
|
||||||
mediaList = append(mediaList, media)
|
return []*models.Media{media}, nil
|
||||||
return mediaList, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// regular photo
|
// regular photo
|
||||||
|
@ -156,39 +150,45 @@ func MediaListFromAPI(ctx *models.DownloadContext) ([]*models.Media, error) {
|
||||||
URL: []string{util.FixURL(image.Source.URL)},
|
URL: []string{util.FixURL(image.Source.URL)},
|
||||||
})
|
})
|
||||||
|
|
||||||
mediaList = append(mediaList, media)
|
return []*models.Media{media}, nil
|
||||||
return mediaList, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for gallery/collection
|
// check for gallery/collection
|
||||||
if len(data.MediaMetadata) > 0 {
|
if len(data.MediaMetadata) > 0 {
|
||||||
for key, obj := range data.MediaMetadata {
|
// known issue: collection is unordered
|
||||||
if obj.E == "Image" {
|
collection := data.MediaMetadata
|
||||||
media := ctx.Extractor.NewMedia(key, contentURL)
|
mediaList := make([]*models.Media, 0, len(collection))
|
||||||
media.SetCaption(title)
|
|
||||||
if isNsfw {
|
|
||||||
media.NSFW = true
|
|
||||||
}
|
|
||||||
|
|
||||||
|
for _, obj := range collection {
|
||||||
|
media := ctx.Extractor.NewMedia(contentID, contentURL)
|
||||||
|
media.SetCaption(title)
|
||||||
|
media.NSFW = isNsfw
|
||||||
|
|
||||||
|
switch obj.Type {
|
||||||
|
case "Image":
|
||||||
media.AddFormat(&models.MediaFormat{
|
media.AddFormat(&models.MediaFormat{
|
||||||
FormatID: "photo",
|
FormatID: "photo",
|
||||||
Type: enums.MediaTypePhoto,
|
Type: enums.MediaTypePhoto,
|
||||||
URL: []string{util.FixURL(obj.S.U)},
|
URL: []string{util.FixURL(obj.Media.URL)},
|
||||||
})
|
})
|
||||||
|
case "AnimatedImage":
|
||||||
|
media.AddFormat(&models.MediaFormat{
|
||||||
|
FormatID: "video",
|
||||||
|
Type: enums.MediaTypeVideo,
|
||||||
|
VideoCodec: enums.MediaCodecAVC,
|
||||||
|
AudioCodec: enums.MediaCodecAAC,
|
||||||
|
URL: []string{util.FixURL(obj.Media.MP4)},
|
||||||
|
})
|
||||||
|
}
|
||||||
mediaList = append(mediaList, media)
|
mediaList = append(mediaList, media)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return mediaList, nil
|
return mediaList, nil
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// video
|
// video
|
||||||
media := ctx.Extractor.NewMedia(contentID, contentURL)
|
media := ctx.Extractor.NewMedia(contentID, contentURL)
|
||||||
media.SetCaption(title)
|
media.SetCaption(title)
|
||||||
if isNsfw {
|
media.NSFW = isNsfw
|
||||||
media.NSFW = true
|
|
||||||
}
|
|
||||||
|
|
||||||
var redditVideo *Video
|
var redditVideo *Video
|
||||||
|
|
||||||
|
@ -218,16 +218,16 @@ func MediaListFromAPI(ctx *models.DownloadContext) ([]*models.Media, error) {
|
||||||
media.AddFormat(format)
|
media.AddFormat(format)
|
||||||
}
|
}
|
||||||
|
|
||||||
mediaList = append(mediaList, media)
|
return []*models.Media{media}, nil
|
||||||
return mediaList, nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return mediaList, nil
|
// no media found
|
||||||
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetRedditData(
|
func GetRedditData(
|
||||||
client models.HTTPClient,
|
session models.HTTPClient,
|
||||||
host string,
|
host string,
|
||||||
slug string,
|
slug string,
|
||||||
raise bool,
|
raise bool,
|
||||||
|
@ -248,7 +248,7 @@ func GetRedditData(
|
||||||
req.AddCookie(cookie)
|
req.AddCookie(cookie)
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := client.Do(req)
|
res, err := session.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to send request: %w", err)
|
return nil, fmt.Errorf("failed to send request: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -264,7 +264,7 @@ func GetRedditData(
|
||||||
altHost = "www.reddit.com"
|
altHost = "www.reddit.com"
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetRedditData(client, altHost, slug, true)
|
return GetRedditData(session, altHost, slug, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
var response Response
|
var response Response
|
||||||
|
|
|
@ -71,10 +71,11 @@ type VideoPreview struct {
|
||||||
|
|
||||||
type MediaMetadata struct {
|
type MediaMetadata struct {
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
E string `json:"e"`
|
Type string `json:"e"`
|
||||||
S struct {
|
Media struct {
|
||||||
U string `json:"u"`
|
MP4 string `json:"mp4"`
|
||||||
X int64 `json:"x"`
|
URL string `json:"u"`
|
||||||
Y int64 `json:"y"`
|
Width int64 `json:"x"`
|
||||||
|
Height int64 `json:"y"`
|
||||||
} `json:"s"`
|
} `json:"s"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,6 @@ var Extractor = &models.Extractor{
|
||||||
}
|
}
|
||||||
|
|
||||||
func MediaListFromAPI(ctx *models.DownloadContext) ([]*models.Media, error) {
|
func MediaListFromAPI(ctx *models.DownloadContext) ([]*models.Media, error) {
|
||||||
var mediaList []*models.Media
|
|
||||||
client := util.GetHTTPClient(ctx.Extractor.CodeName)
|
client := util.GetHTTPClient(ctx.Extractor.CodeName)
|
||||||
|
|
||||||
response, err := GetVideo(
|
response, err := GetVideo(
|
||||||
|
@ -109,11 +108,7 @@ func MediaListFromAPI(ctx *models.DownloadContext) ([]*models.Media, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(media.Formats) > 0 {
|
return []*models.Media{media}, nil
|
||||||
mediaList = append(mediaList, media)
|
|
||||||
}
|
|
||||||
|
|
||||||
return mediaList, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetVideo(
|
func GetVideo(
|
||||||
|
|
|
@ -12,22 +12,22 @@ import (
|
||||||
|
|
||||||
var accessToken *Token
|
var accessToken *Token
|
||||||
|
|
||||||
func GetAccessToken(client models.HTTPClient) (*Token, error) {
|
func GetAccessToken(session models.HTTPClient) (*Token, error) {
|
||||||
if accessToken == nil || time.Now().Unix() >= accessToken.ExpiresIn {
|
if accessToken == nil || time.Now().Unix() >= accessToken.ExpiresIn {
|
||||||
if err := RefreshAccessToken(client); err != nil {
|
if err := RefreshAccessToken(session); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return accessToken, nil
|
return accessToken, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func RefreshAccessToken(client models.HTTPClient) error {
|
func RefreshAccessToken(session models.HTTPClient) error {
|
||||||
req, err := http.NewRequest(http.MethodGet, tokenEndpoint, nil)
|
req, err := http.NewRequest(http.MethodGet, tokenEndpoint, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create request: %w", err)
|
return fmt.Errorf("failed to create request: %w", err)
|
||||||
}
|
}
|
||||||
req.Header.Set("User-Agent", util.ChromeUA)
|
req.Header.Set("User-Agent", util.ChromeUA)
|
||||||
res, err := client.Do(req)
|
res, err := session.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to send request: %w", err)
|
return fmt.Errorf("failed to send request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,8 +78,6 @@ var Extractor = &models.Extractor{
|
||||||
|
|
||||||
func MediaListFromAPI(ctx *models.DownloadContext) ([]*models.Media, error) {
|
func MediaListFromAPI(ctx *models.DownloadContext) ([]*models.Media, error) {
|
||||||
client := util.GetHTTPClient(ctx.Extractor.CodeName)
|
client := util.GetHTTPClient(ctx.Extractor.CodeName)
|
||||||
var mediaList []*models.Media
|
|
||||||
|
|
||||||
details, err := GetVideoAPI(
|
details, err := GetVideoAPI(
|
||||||
client, ctx.MatchedContentID)
|
client, ctx.MatchedContentID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -119,10 +117,12 @@ func MediaListFromAPI(ctx *models.DownloadContext) ([]*models.Media, error) {
|
||||||
}
|
}
|
||||||
media.AddFormat(format)
|
media.AddFormat(format)
|
||||||
}
|
}
|
||||||
mediaList = append(mediaList, media)
|
return []*models.Media{media}, nil
|
||||||
} else {
|
} else {
|
||||||
images := details.ImagePostInfo.Images
|
images := details.ImagePostInfo.Images
|
||||||
for _, image := range images {
|
mediaList := make([]*models.Media, 0, len(images))
|
||||||
|
for i := range images {
|
||||||
|
image := images[i]
|
||||||
media := ctx.Extractor.NewMedia(
|
media := ctx.Extractor.NewMedia(
|
||||||
ctx.MatchedContentID,
|
ctx.MatchedContentID,
|
||||||
ctx.MatchedContentURL,
|
ctx.MatchedContentURL,
|
||||||
|
@ -135,8 +135,8 @@ func MediaListFromAPI(ctx *models.DownloadContext) ([]*models.Media, error) {
|
||||||
})
|
})
|
||||||
mediaList = append(mediaList, media)
|
mediaList = append(mediaList, media)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return mediaList, nil
|
return mediaList, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetVideoAPI(
|
func GetVideoAPI(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue