|
@@ -3,6 +3,7 @@ package kinds
|
|
|
import (
|
|
|
"net/url"
|
|
|
"strings"
|
|
|
+ "errors"
|
|
|
)
|
|
|
|
|
|
type Link Dict
|
|
@@ -16,8 +17,19 @@ func (l Link) Category() string {
|
|
|
return "link"
|
|
|
}
|
|
|
|
|
|
-func (l Link) MediaType() (string, error) {
|
|
|
- return Get[string](l, "mediaType")
|
|
|
+func (l Link) Supertype() (string, error) {
|
|
|
+ mediaType, err := Get[string](l, "mediaType")
|
|
|
+ return strings.Split(mediaType, "/")[0], err
|
|
|
+}
|
|
|
+
|
|
|
+func (l Link) Subtype() (string, error) {
|
|
|
+ if mediaType, err := Get[string](l, "mediaType"); err != nil {
|
|
|
+ return "", err
|
|
|
+ } else if split := strings.Split(mediaType, "/"); len(split) < 2 {
|
|
|
+ return "", errors.New("Media type " + mediaType + " lacks a subtype")
|
|
|
+ } else {
|
|
|
+ return split[1], nil
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
func (l Link) URL() (*url.URL, error) {
|
|
@@ -33,6 +45,16 @@ func (l Link) Identifier() (*url.URL, error) {
|
|
|
return nil, nil
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+func (l Link) rating() int {
|
|
|
+ height, err := Get[int](l, "height")
|
|
|
+ if err != nil { height = 1 }
|
|
|
+ width, err := Get[int](l, "width")
|
|
|
+ if err != nil { width = 1 }
|
|
|
+ return height * width
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
func (l Link) String() (string, error) {
|
|
|
output := ""
|
|
@@ -43,9 +65,53 @@ func (l Link) String() (string, error) {
|
|
|
output += url.String()
|
|
|
}
|
|
|
|
|
|
- if mediaType, err := l.MediaType(); err == nil {
|
|
|
- output += " (" + mediaType + ")"
|
|
|
+ if Subtype, err := l.Subtype(); err == nil {
|
|
|
+ output += " (" + Subtype + ")"
|
|
|
}
|
|
|
|
|
|
return output, nil
|
|
|
}
|
|
|
+
|
|
|
+func SelectBestLink(links []Link, supertype string) (Link, error) {
|
|
|
+ if len(links) == 0 {
|
|
|
+ return nil, errors.New("Can't select best link of type " + supertype + "/* from an empty list")
|
|
|
+ }
|
|
|
+
|
|
|
+ bestLink := links[0]
|
|
|
+
|
|
|
+ for _, thisLink := range links[1:] {
|
|
|
+ var bestLinkSupertypeMatches bool
|
|
|
+ if bestLinkSupertype, err := bestLink.Supertype(); err != nil {
|
|
|
+ bestLinkSupertypeMatches = false
|
|
|
+ } else {
|
|
|
+ bestLinkSupertypeMatches = bestLinkSupertype == supertype
|
|
|
+ }
|
|
|
+
|
|
|
+ var thisLinkSuperTypeMatches bool
|
|
|
+ if thisLinkSupertype, err := thisLink.Supertype(); err != nil {
|
|
|
+ thisLinkSuperTypeMatches = false
|
|
|
+ } else {
|
|
|
+ thisLinkSuperTypeMatches = thisLinkSupertype == supertype
|
|
|
+ }
|
|
|
+
|
|
|
+ if thisLinkSuperTypeMatches && !bestLinkSupertypeMatches {
|
|
|
+ bestLink = thisLink
|
|
|
+ continue
|
|
|
+ } else if !thisLinkSuperTypeMatches && bestLinkSupertypeMatches {
|
|
|
+ continue
|
|
|
+ } else if thisLink.rating() > bestLink.rating() {
|
|
|
+ bestLink = thisLink
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return bestLink, nil
|
|
|
+}
|
|
|
+
|
|
|
+func SelectFirstLink(links []Link) (Link, error) {
|
|
|
+ if len(links) == 0 {
|
|
|
+ return nil, errors.New("can't select first Link from an empty list of links")
|
|
|
+ } else {
|
|
|
+ return links[0], nil
|
|
|
+ }
|
|
|
+}
|