-
Notifications
You must be signed in to change notification settings - Fork 0
/
youtube.go
93 lines (84 loc) · 2.83 KB
/
youtube.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
package extensions
import (
"encoding/json"
"fmt"
"github.com/pawelszydlo/papa-bot"
"github.com/pawelszydlo/papa-bot/events"
"github.com/pawelszydlo/papa-bot/utils"
"net/url"
"regexp"
"strconv"
"text/template"
"time"
)
// ExtensionYoutube - extension for getting basic video information.
type ExtensionYoutube struct {
youTubeRe *regexp.Regexp
bot *papaBot.Bot
Texts *ExtensionYoutubeTexts
}
type ExtensionYoutubeTexts struct {
TempNotice *template.Template
}
// Init inits the extension.
func (ext *ExtensionYoutube) Init(bot *papaBot.Bot) error {
ext.youTubeRe = regexp.MustCompile(`(?i)youtu(?:be\.com/watch\?v=|\.be/)([\w\-_]*)(&(amp;)?[\w?=]*)?`)
ext.bot = bot
// Load texts.
texts := new(ExtensionYoutubeTexts)
if err := bot.LoadTexts("youtube", texts); err != nil {
return err
}
ext.Texts = texts
bot.EventDispatcher.RegisterListener(events.EventURLFound, ext.UrlListener)
return nil
}
// UrlListener will try to get more info on GitHub links.
func (ext *ExtensionYoutube) UrlListener(message events.EventMessage) {
match := ext.youTubeRe.FindStringSubmatch(message.Message)
if len(match) < 2 {
return
}
go func() {
video_no := match[1]
// Get response
err, _, body := ext.bot.GetPageBody(fmt.Sprintf("https://youtube.com/get_video_info?video_id=%s", video_no), nil)
if err != nil {
ext.bot.Log.Warningf("Error getting response from YouTube: %s", err)
return
}
// Extract data from www-from-urlencoded.
params, err := url.ParseQuery(string(body))
if err != nil {
ext.bot.Log.Error(err)
return
}
// Intersting stuff is only in the "player_response" -> "videoDetails".
response, ok := params["player_response"]
if !ok {
ext.bot.Log.Error("Player response not found.")
}
// Convert from JSON
var raw_data interface{}
if err := json.Unmarshal([]byte(response[0]), &raw_data); err != nil {
ext.bot.Log.Warningf("Error parsing JSON from YouTube get info: %s", err)
return
}
data := raw_data.(map[string]interface{})["videoDetails"].(map[string]interface{})
// Map that the user will be able to use for formatting.
duration, err := time.ParseDuration(fmt.Sprintf("%ss", data["lengthSeconds"]))
views, _ := strconv.Atoi(data["viewCount"].(string))
values := map[string]string{
"title": fmt.Sprintf("%s", data["title"]),
"length": ext.bot.Humanizer.SecondsToTimeString(int64(duration.Seconds())),
"description": fmt.Sprintf("%s", data["shortDescription"]),
"rating": fmt.Sprintf("%.2f", data["averageRating"]),
"views": ext.bot.Humanizer.HumanizeNumber(float64(views), 0),
"author": fmt.Sprintf("%s", data["author"]),
}
// Add "more".
ext.bot.AddMoreInfo(message.TransportName, message.Channel, values["description"])
// Send the notice.
ext.bot.SendNotice(&message, utils.Format(ext.Texts.TempNotice, values))
}()
}