2019-10-04 01:25:57 +00:00
|
|
|
package linkinfo
|
|
|
|
|
2019-10-04 03:31:24 +00:00
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
|
|
|
"path/filepath"
|
|
|
|
"regexp"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
const imgurApiUrl = "https://api.imgur.com/3/%s/%s.json"
|
|
|
|
|
2019-10-04 01:25:57 +00:00
|
|
|
var (
|
|
|
|
imgurHosts = []string{"imgur.com", "i.imgur.com"}
|
2019-10-04 03:31:24 +00:00
|
|
|
|
|
|
|
imgurAlbumRegexp = regexp.MustCompile("^/(a|gallery)/")
|
2019-10-04 01:25:57 +00:00
|
|
|
)
|
|
|
|
|
2019-10-04 03:31:24 +00:00
|
|
|
type ImgurOptions struct {
|
|
|
|
Option
|
|
|
|
|
|
|
|
ClientId string
|
|
|
|
}
|
|
|
|
|
|
|
|
type ImgurInfoApi struct {
|
|
|
|
api *LinkInfoApi
|
|
|
|
opts *ImgurOptions
|
|
|
|
}
|
|
|
|
|
|
|
|
type imgurResponse struct {
|
|
|
|
Success bool `json:"success"`
|
|
|
|
Data imgurData `json:"data"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type imgurData struct {
|
|
|
|
Type string `json:"type"`
|
|
|
|
Title string `json:"title"`
|
|
|
|
Description string `json:"description"`
|
|
|
|
Width int `json:"width"`
|
|
|
|
Height int `json:"height"`
|
|
|
|
Animated bool `json:"animated"`
|
|
|
|
Nsfw bool `json:"nsfw"`
|
|
|
|
}
|
|
|
|
|
|
|
|
func (i *ImgurInfoApi) Handler(link string) (*LinkInfo, error) {
|
|
|
|
if i.opts.ClientId == "" {
|
|
|
|
return nil, errors.New("invalid client id")
|
|
|
|
}
|
|
|
|
|
|
|
|
u, err := url.Parse(link)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
id := filepath.Base(u.Path)
|
|
|
|
|
|
|
|
extension := filepath.Ext(id)
|
|
|
|
|
|
|
|
if extension != "" {
|
|
|
|
id = id[0 : len(id)-len(extension)]
|
|
|
|
}
|
|
|
|
|
|
|
|
imageType := "image"
|
|
|
|
|
|
|
|
if imgurAlbumRegexp.MatchString(link) {
|
|
|
|
imageType = "album"
|
|
|
|
}
|
|
|
|
|
|
|
|
req, err := http.NewRequest("GET", fmt.Sprintf(imgurApiUrl, imageType, id), nil)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
req.Header.Set("Authorization", "Client-ID "+i.opts.ClientId)
|
|
|
|
|
|
|
|
res, err := i.api.Client.Do(req)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
defer res.Body.Close()
|
|
|
|
|
|
|
|
var response imgurResponse
|
|
|
|
|
|
|
|
if err := json.NewDecoder(res.Body).Decode(&response); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if !response.Success {
|
|
|
|
return nil, errors.New("imgur api returned success=false")
|
|
|
|
}
|
|
|
|
|
|
|
|
var title string
|
|
|
|
|
|
|
|
if response.Data.Title != "" {
|
|
|
|
title = "Imgur - " + response.Data.Title
|
|
|
|
} else {
|
|
|
|
title = "Imgur - " + id
|
|
|
|
|
|
|
|
switch response.Data.Type {
|
|
|
|
case "image/jpeg":
|
|
|
|
title += ".jpg"
|
|
|
|
case "image/png":
|
|
|
|
title += ".png"
|
|
|
|
case "image/gif":
|
|
|
|
title += ".gif"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
attribs := make([]string, 0)
|
|
|
|
|
|
|
|
if imageType == "album" {
|
|
|
|
attribs = append(attribs, "Album")
|
|
|
|
} else {
|
|
|
|
attribs = append(attribs, fmt.Sprintf("%dx%d", response.Data.Width, response.Data.Height))
|
|
|
|
|
|
|
|
if response.Data.Animated {
|
|
|
|
attribs = append(attribs, "Animated")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
title += " (" + strings.Join(attribs, ", ") + ")"
|
|
|
|
|
|
|
|
if response.Data.Nsfw {
|
|
|
|
attribs = append(attribs, "NSFW")
|
|
|
|
}
|
|
|
|
|
|
|
|
info := &LinkInfo{
|
|
|
|
Title: title,
|
|
|
|
Description: response.Data.Description,
|
|
|
|
}
|
|
|
|
|
|
|
|
return info, nil
|
2019-10-04 01:25:57 +00:00
|
|
|
}
|