forked from n0madic/twitter-scraper
-
Notifications
You must be signed in to change notification settings - Fork 0
/
unified_card.go
97 lines (82 loc) · 2.21 KB
/
unified_card.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package twitterscraper
import (
"encoding/json"
"fmt"
"strings"
)
// unified card JSON object
type unifiedCard struct {
Type string `json:"type"`
Components []string `json:"components"`
ComponentObjects map[string]struct {
Type string `json:"type"`
Data map[string]interface{} `json:"data"`
} `json:"component_objects"`
DestinationObjects map[string]struct {
Type string `json:"type"`
Data struct {
UrlData struct {
URL string `json:"url"`
Vanity string `json:"vanity"`
} `json:"url_data"`
} `json:"data"`
} `json:"destination_objects"`
MediaEntities map[string]struct {
IDStr string `json:"id_str"`
MediaURLHttps string `json:"media_url_https"`
Type string `json:"type"`
URL string `json:"url"`
} `json:"media_entities"`
}
// unified card's details JSON object
type details struct {
Title struct {
Content string `json:"content"`
} `json:"title"`
Subtitle struct {
Content string `json:"content"`
} `json:"subtitle"`
Destination string `json:"destination"`
}
func (uc *unifiedCard) parseCard() *Card {
// regardless multiple keys holding structures,
// there is only on browser link, detail and media
// for both image & video cards
knownTypes := []string{"image_website", "video_website"}
if !stringInSlice(uc.Type, knownTypes) {
return nil
}
c := &Card{}
for _, component := range uc.ComponentObjects {
if component.Type == "details" {
var d details
jsondetails, err := json.Marshal(component.Data)
if err != nil {
continue
}
if err := json.Unmarshal(jsondetails, &d); err != nil {
continue
}
c.Text = fmt.Sprintf("%s\n%s", d.Subtitle.Content, d.Title.Content)
c.HTML = c.Text
}
}
for _, dest := range uc.DestinationObjects {
switch dest.Type {
case "browser", "browser_with_docked_media":
c.URLs = append(c.URLs, dest.Data.UrlData.URL)
}
}
for _, media := range uc.MediaEntities {
switch media.Type {
case "photo", "video":
c.Photos = append(c.Photos, media.MediaURLHttps)
}
}
if len(c.URLs) > 0 && len(c.Photos) > 0 {
c.HTML = fmt.Sprintf(
`<a href="%s"><img src="%s"><br>%s</a>`,
c.URLs[0], c.Photos[0], strings.Replace(c.Text, "\n", "<br>", 1))
}
return c
}