linkinfo/linkinfo.go

111 lines
2.1 KiB
Go

package linkinfo
import (
"net/http"
"net/url"
"time"
)
type LinkHandler struct {
Hosts []string
Handler func(link string) (*LinkInfo, error)
}
type LinkInfoApi struct {
Client *http.Client
UserAgent string
Imgur *ImgurInfoApi
Youtube *YoutubeInfoApi
Twitter *TwitterInfoApi
linkHandlers []*LinkHandler
}
type LinkInfo struct {
Title string `json:"title"`
Description string `json:"description"`
ContentType string `json:"type"`
ContentLength int64 `json:"contentLength"`
Duration string `json:"duration,omitempty"`
Redirects []string `json:"redirects,omitempty"`
}
type HttpOptions struct {
Option
UserAgent string
}
func New(opts ...Option) *LinkInfoApi {
api := &LinkInfoApi{
Client: &http.Client{
Timeout: 15 * time.Second,
},
}
for _, opt := range opts {
switch o := opt.(type) {
case *ImgurOptions:
api.Imgur = &ImgurInfoApi{api, o}
case *YoutubeOptions:
api.Youtube = &YoutubeInfoApi{api, o}
case *TwitterOptions:
api.Twitter = &TwitterInfoApi{opts: o}
api.Twitter.Init()
case *HttpOptions:
api.UserAgent = o.UserAgent
}
}
api.registerDefaultHandlers()
return api
}
func (i *LinkInfoApi) registerDefaultHandlers() {
i.linkHandlers = make([]*LinkHandler, 0)
if i.Imgur != nil {
i.linkHandlers = append(i.linkHandlers, &LinkHandler{
Hosts: imgurHosts,
Handler: i.Imgur.Handler,
})
}
if i.Youtube != nil {
i.linkHandlers = append(i.linkHandlers, &LinkHandler{
Hosts: youtubeHosts,
Handler: i.Youtube.Handler,
})
}
if i.Twitter != nil {
i.linkHandlers = append(i.linkHandlers, &LinkHandler{
Hosts: twitterHosts,
Handler: i.Twitter.Handler,
})
}
}
func (i *LinkInfoApi) AddHandler(handler *LinkHandler) {
i.linkHandlers = append(i.linkHandlers, handler)
}
func (i *LinkInfoApi) Retrieve(link string) (*LinkInfo, error) {
u, err := url.Parse(link)
if err != nil {
return nil, err
}
for _, handler := range i.linkHandlers {
for _, host := range handler.Hosts {
if host == u.Hostname() {
return handler.Handler(link)
}
}
}
return i.DefaultLinkHandler(link)
}