mirror of https://github.com/fluffle/goirc
Add a listener for YouTube and URLs, and spit out the Video Name or Title back to the sourc.
This commit is contained in:
parent
ed85f957b5
commit
18a149335b
|
@ -26,6 +26,9 @@ func main() {
|
|||
c.HandleFunc(irc.DISCONNECTED,
|
||||
func(conn *irc.Conn, line *irc.Line) { quit <- true })
|
||||
|
||||
c.HandleFunc(irc.PRIVMSG, YouTubeFunc)
|
||||
c.HandleFunc(irc.PRIVMSG, UrlFunc)
|
||||
|
||||
// set up a goroutine to read commands from stdin
|
||||
in := make(chan string, 4)
|
||||
reallyquit := false
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type youTubeVideo struct {
|
||||
Entry struct {
|
||||
Info struct {
|
||||
Title struct {
|
||||
Text string `json:"$t"`
|
||||
} `json:"media$title"`
|
||||
Description struct {
|
||||
Text string `json:"$t"`
|
||||
} `json:"media$description"`
|
||||
} `json:"media$group"`
|
||||
Rating struct {
|
||||
Likes string `json:"numLikes"`
|
||||
Dislikes string `json:"numDislikes"`
|
||||
} `json:"yt$rating"`
|
||||
Statistics struct {
|
||||
Views string `json:"viewCount"`
|
||||
} `json:"yt$statistics"`
|
||||
} `json:entry`
|
||||
}
|
||||
|
||||
func UrlFunc(conn *Conn, line *Line) {
|
||||
text := line.Message()
|
||||
if regex, err := regexp.Compile(`(\s|^)(http://|https://)(.*?)(\s|$)`); err == nil {
|
||||
url := strings.TrimSpace(regex.FindString(text))
|
||||
if url != "" {
|
||||
if resp, err := http.Get(url); err == nil {
|
||||
if strings.HasPrefix(resp.Header.Get("Content-Type"), "text/html") {
|
||||
defer resp.Body.Close()
|
||||
if content, err := ioutil.ReadAll(resp.Body); err == nil {
|
||||
if regex, err := regexp.Compile(`<title>(.*?)</title>`); err == nil {
|
||||
if regex.Match([]byte(content)) {
|
||||
conn.Privmsg(line.Target(), strings.TrimSpace(regex.FindStringSubmatch(string(content))[1]))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func YouTubeFunc(conn *Conn, line *Line) {
|
||||
text := line.Message()
|
||||
if regex, err := regexp.Compile(`(\s|^)(http://|https://)?(www.)?(youtube.com/watch\?v=|youtu.be/)(.*?)(\s|$|\&|#)`); err == nil {
|
||||
if regex.Match([]byte(text)) {
|
||||
matches := regex.FindStringSubmatch(text)
|
||||
id := matches[len(matches)-2]
|
||||
url := fmt.Sprintf("https://gdata.youtube.com/feeds/api/videos/%s?v=2&alt=json", id)
|
||||
if resp, err := http.Get(url); err == nil {
|
||||
defer resp.Body.Close()
|
||||
if contents, err := ioutil.ReadAll(resp.Body); err == nil {
|
||||
var data youTubeVideo
|
||||
if err := json.Unmarshal(contents, &data); err == nil {
|
||||
conn.Privmsg(line.Target(), fmt.Sprintf("%s - %s views (%s likes, %s dislikes)", data.Entry.Info.Title.Text, data.Entry.Statistics.Views, data.Entry.Rating.Likes, data.Entry.Rating.Dislikes))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -88,3 +88,26 @@ func parseLine(s string) *Line {
|
|||
}
|
||||
return line
|
||||
}
|
||||
|
||||
// Return the contents of the message portion of a line.
|
||||
// This only really makes sense for messages with a :message portion, but there
|
||||
// are a lot of them.
|
||||
func (line *Line) Message() string {
|
||||
if len(line.Args) > 0 {
|
||||
return line.Args[len(line.Args)-1]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Return the target of the line. This only really makes sense for PRIVMSG.
|
||||
// If the line was broadcast from a channel, the target will be that channel.
|
||||
// If the line was broadcast by a user, the target will be that user.
|
||||
func (line *Line) Target() string {
|
||||
if line.Cmd == PRIVMSG {
|
||||
if !strings.HasPrefix(line.Args[0], "#") {
|
||||
return line.Nick
|
||||
}
|
||||
return line.Args[0]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue