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) }