otiai10/opengraph

View on GitHub
meta.go

Summary

Maintainability
A
1 hr
Test Coverage
package opengraph

import (
    "strconv"
    "strings"

    "golang.org/x/net/html"
)

// Meta represents any "<meta ...>" HTML tag.
type Meta struct {
    Name     string
    Property string
    Content  string
}

// MetaTag constructs MetaTag.
func MetaTag(node *html.Node) *Meta {
    meta := new(Meta)
    for _, attr := range node.Attr {
        switch attr.Key {
        case "property":
            meta.Property = attr.Val
        case "content":
            meta.Content = attr.Val
        case "name":
            meta.Name = attr.Val
        }
    }
    return meta
}

// Contribute ...
func (meta *Meta) Contribute(og *OpenGraph) (err error) {
    switch {
    case meta.IsTitle():
        og.Title = meta.Content
    case meta.IsOGDescription():
        og.Description = meta.Content
    case meta.IsDescription() && !og.Intent.Strict && og.Description == "":
        og.Description = meta.Content
    case meta.IsSiteName():
        og.SiteName = meta.Content
    case meta.IsImage():
        if len(og.Image) == 0 || og.Image[len(og.Image)-1].URL != meta.Content {
            og.Image = append(og.Image, Image{URL: meta.Content})
        }
    case meta.IsPropertyOf("og:image"):
        if len(og.Image) == 0 {
            return nil
        }
        switch meta.Property {
        case "og:image:width":
            og.Image[len(og.Image)-1].Width, err = strconv.Atoi(meta.Content)
        case "og:image:height":
            og.Image[len(og.Image)-1].Height, err = strconv.Atoi(meta.Content)
        }
    case meta.IsAudio():
        if len(og.Audio) == 0 || og.Audio[len(og.Audio)-1].URL != meta.Content {
            og.Audio = append(og.Audio, Audio{URL: meta.Content})
        }
    case meta.IsVideo():
        if len(og.Video) == 0 || og.Video[len(og.Video)-1].URL != meta.Content {
            og.Video = append(og.Video, Video{URL: meta.Content})
        }
    case meta.IsPropertyOf("og:video"):
        if len(og.Video) == 0 {
            return nil
        }
        switch meta.Property {
        case "og:video:type":
            og.Video[len(og.Video)-1].Type = meta.Content
        case "og:video:secure_url":
            og.Video[len(og.Video)-1].SecureURL = meta.Content
        case "og:video:width":
            og.Video[len(og.Video)-1].Width, err = strconv.Atoi(meta.Content)
        case "og:video:height":
            og.Video[len(og.Video)-1].Height, err = strconv.Atoi(meta.Content)
        case "og:video:duration":
            og.Video[len(og.Video)-1].Duration, err = strconv.Atoi(meta.Content)
        }
    case meta.IsType():
        og.Type = meta.Content
    case meta.IsURL():
        og.URL = meta.Content
    }
    return err
}

// IsTitle returns if it can be "title" of OGP
func (meta *Meta) IsTitle() bool {
    return meta.Property == "og:title" && meta.Content != ""
}

// IsOGDescription returns if it can be "description" of OGP
func (meta *Meta) IsOGDescription() bool {
    return meta.Property == "og:description" && meta.Content != ""
}

// IsDescription returns if it can be "description" of OGP.
// CAUTION: This property SHOULD NOT be used when Intent.Strict == true.
func (meta *Meta) IsDescription() bool {
    return meta.Name == "description" && meta.Content != ""
}

// IsImage returns if it can be a root of "og:image"
func (meta *Meta) IsImage() bool {
    return meta.Property == "og:image" || meta.Property == "og:image:url"
}

// IsPropertyOf returns if it can be a property of specified struct
func (meta *Meta) IsPropertyOf(name string) bool {
    return strings.HasPrefix(meta.Property, name+":")
}

// IsAudio reeturns if it can be a root of "og:audio"
func (meta *Meta) IsAudio() bool {
    return meta.Property == "og:audio" || meta.Property == "og:audio:url"
}

// IsVideo returns if it can be a root of "og:video"
func (meta *Meta) IsVideo() bool {
    return meta.Property == "og:video" || meta.Property == "og:video:url"
}

// IsType returns if it can be "og:type"
func (meta *Meta) IsType() bool {
    return meta.Property == "og:type"
}

// IsSiteName returns if it can be "og:site_name"
func (meta *Meta) IsSiteName() bool {
    return meta.Property == "og:site_name"
}

// IsURL returns if it can be "og:url"
func (meta *Meta) IsURL() bool {
    return meta.Property == "og:url"
}