Cleanup and prepare for instanced link handler (allowing the use of twitter, imgur, etc)
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Tyler 2019-10-03 21:25:57 -04:00
parent 3053714678
commit a1530dc7fa
6 changed files with 65 additions and 31 deletions

View File

@ -19,7 +19,7 @@ const (
maxBodySizeBytes = 20971520
)
func defaultLinkHandler(link string) (*LinkInfo, error) {
func (api *LinkInfoApi) DefaultLinkHandler(link string) (*LinkInfo, error) {
redirects := make([]string, 0)
u, err := url.Parse(link)
@ -31,7 +31,7 @@ func defaultLinkHandler(link string) (*LinkInfo, error) {
var res *http.Response
for i := 0; i < 10; i++ {
res, err = Client.Head(link)
res, err = api.Client.Head(link)
if err != nil {
return nil, err
@ -52,7 +52,7 @@ func defaultLinkHandler(link string) (*LinkInfo, error) {
contentType := res.Header.Get("Content-Type")
if contentType == "" {
contentType = detectContentType(link, "application/octet-stream")
contentType = api.detectContentType(link, "application/octet-stream")
}
if idx := strings.Index(contentType, ";"); idx != -1 {
@ -73,7 +73,7 @@ func defaultLinkHandler(link string) (*LinkInfo, error) {
switch contentType {
case contentTypeHtml:
if contentLength > 0 && contentLength < maxBodySizeBytes {
err = retrieveHtmlLinkTitle(ret, link)
err = api.retrieveHtmlLinkTitle(ret, link)
break
}
fallthrough
@ -84,7 +84,7 @@ func defaultLinkHandler(link string) (*LinkInfo, error) {
return ret, err
}
func detectContentType(link, defaultType string) string {
func (api *LinkInfoApi) detectContentType(link, defaultType string) string {
req, err := http.NewRequest("GET", link, nil)
if err != nil {
@ -93,7 +93,7 @@ func detectContentType(link, defaultType string) string {
req.Header.Set("Range", "bytes=0-512")
res, err := Client.Do(req)
res, err := api.Client.Do(req)
if err != nil {
return defaultType
@ -120,8 +120,8 @@ var (
attrKeys = []string{"property", "name", "itemprop"}
)
func retrieveHtmlLinkTitle(i *LinkInfo, link string) error {
res, err := Client.Get(link)
func (api *LinkInfoApi) retrieveHtmlLinkTitle(i *LinkInfo, link string) error {
res, err := api.Client.Get(link)
if err != nil {
return err

View File

@ -5,8 +5,10 @@ import (
"testing"
)
func Test_detectContentType(t *testing.T) {
contentType := detectContentType("http://example.com", "")
func Test_LinkInfoApi_detectContentType(t *testing.T) {
api := &LinkInfoApi{}
contentType := api.detectContentType("http://example.com", "")
if contentType == "" {
t.Fatal("Unable to test example.com, returned empty type")
@ -21,7 +23,7 @@ func Test_detectContentType(t *testing.T) {
}
}
func Test_defaultLinkHandler(t *testing.T) {
func Test_LinkInfoApi_defaultLinkHandler(t *testing.T) {
type expectedData struct {
Link string
Title string
@ -33,8 +35,10 @@ func Test_defaultLinkHandler(t *testing.T) {
{"http://techslides.com/demos/sample-videos/small.mp4", "", "video/mp4"},
}
api := &LinkInfoApi{}
for _, link := range testLinks {
l, err := defaultLinkHandler(link.Link)
l, err := api.DefaultLinkHandler(link.Link)
if err != nil {
t.Fatal("Unable to retrieve link info:", err)
@ -50,10 +54,12 @@ func Test_defaultLinkHandler(t *testing.T) {
}
}
func Test_retrieveHtmlLinkTitle(t *testing.T) {
func Test_LinkInfoApi_retrieveHtmlLinkTitle(t *testing.T) {
ret := &LinkInfo{}
if err := retrieveHtmlLinkTitle(ret, "http://example.com"); err != nil {
api := &LinkInfoApi{}
if err := api.retrieveHtmlLinkTitle(ret, "http://example.com"); err != nil {
t.Fatal("Unable to retrieve html link title:", err)
}

9
imgur.go Normal file
View File

@ -0,0 +1,9 @@
package linkinfo
var (
imgurHosts = []string{"imgur.com", "i.imgur.com"}
)
func (i *LinkInfoApi) ImgurLinkHandler(link string) (*LinkInfo, error) {
return nil, nil
}

View File

@ -5,14 +5,14 @@ import (
"net/url"
)
type linkHandler struct {
hosts []string
handler func(link string) (*LinkInfo, error)
type LinkHandler struct {
Hosts []string
Handler func(link string) (*LinkInfo, error)
}
type LinkInfoApi struct {
client *http.Client
ImgurId string
Client *http.Client
linkHandlers []*LinkHandler
}
type LinkInfo struct {
@ -24,14 +24,20 @@ type LinkInfo struct {
Redirects []string `json:"redirects,omitempty"`
}
var (
linkHandlers = []*linkHandler{
{hosts: []string{"youtube.com", "youtu.be"}, handler: youtubeLinkHandler},
}
)
func New() *LinkInfoApi {
return &LinkInfoApi{}
api := &LinkInfoApi{}
api.registerDefaultHandlers()
return api
}
func (i *LinkInfoApi) registerDefaultHandlers() {
i.linkHandlers = []*LinkHandler{
{Hosts: youtubeHosts, Handler: i.YoutubeLinkHandler},
{Hosts: imgurHosts, Handler: i.ImgurLinkHandler},
{Hosts: twitterHosts, Handler: i.TwitterLinkHandler},
}
}
func (i *LinkInfoApi) Retrieve(link string) (*LinkInfo, error) {
@ -41,13 +47,13 @@ func (i *LinkInfoApi) Retrieve(link string) (*LinkInfo, error) {
return nil, err
}
for _, handler := range linkHandlers {
for _, host := range handler.hosts {
for _, handler := range i.linkHandlers {
for _, host := range handler.Hosts {
if host == u.Hostname() {
return handler.handler(link)
return handler.Handler(link)
}
}
}
return defaultLinkHandler(link)
return i.DefaultLinkHandler(link)
}

9
twitter.go Normal file
View File

@ -0,0 +1,9 @@
package linkinfo
var (
twitterHosts = []string{"twitter.com"}
)
func (i *LinkInfoApi) TwitterLinkHandler(link string) (*LinkInfo, error) {
return nil, nil
}

View File

@ -1,5 +1,9 @@
package linkinfo
func youtubeLinkHandler(link string) (*LinkInfo, error) {
var (
youtubeHosts = []string{"youtube.com", "youtu.be"}
)
func (i *LinkInfoApi) YoutubeLinkHandler(link string) (*LinkInfo, error) {
return nil, nil
}