4
0
mirror of https://github.com/cwinfo/matterbridge.git synced 2025-07-17 13:08:54 +00:00

Update mattermost library (#2152)

* Update mattermost library

* Fix linting
This commit is contained in:
Wim
2024-05-24 23:08:09 +02:00
committed by GitHub
parent 65d78e38af
commit d16645c952
1003 changed files with 89451 additions and 114025 deletions

View File

@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015 Vitaly Dyatlov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -8,81 +8,37 @@ import (
"golang.org/x/net/html"
"golang.org/x/net/html/atom"
"github.com/dyatlov/go-opengraph/opengraph/types/actor"
"github.com/dyatlov/go-opengraph/opengraph/types/article"
"github.com/dyatlov/go-opengraph/opengraph/types/audio"
"github.com/dyatlov/go-opengraph/opengraph/types/book"
"github.com/dyatlov/go-opengraph/opengraph/types/image"
"github.com/dyatlov/go-opengraph/opengraph/types/music"
"github.com/dyatlov/go-opengraph/opengraph/types/profile"
"github.com/dyatlov/go-opengraph/opengraph/types/video"
)
// Image defines Open Graph Image type
type Image struct {
URL string `json:"url"`
SecureURL string `json:"secure_url"`
Type string `json:"type"`
Width uint64 `json:"width"`
Height uint64 `json:"height"`
draft bool `json:"-"`
}
// Video defines Open Graph Video type
type Video struct {
URL string `json:"url"`
SecureURL string `json:"secure_url"`
Type string `json:"type"`
Width uint64 `json:"width"`
Height uint64 `json:"height"`
draft bool `json:"-"`
}
// Audio defines Open Graph Audio Type
type Audio struct {
URL string `json:"url"`
SecureURL string `json:"secure_url"`
Type string `json:"type"`
draft bool `json:"-"`
}
// Article contain Open Graph Article structure
type Article struct {
PublishedTime *time.Time `json:"published_time"`
ModifiedTime *time.Time `json:"modified_time"`
ExpirationTime *time.Time `json:"expiration_time"`
Section string `json:"section"`
Tags []string `json:"tags"`
Authors []*Profile `json:"authors"`
}
// Profile contains Open Graph Profile structure
type Profile struct {
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Username string `json:"username"`
Gender string `json:"gender"`
}
// Book contains Open Graph Book structure
type Book struct {
ISBN string `json:"isbn"`
ReleaseDate *time.Time `json:"release_date"`
Tags []string `json:"tags"`
Authors []*Profile `json:"authors"`
}
// OpenGraph contains facebook og data
type OpenGraph struct {
isArticle bool
isBook bool
isProfile bool
Type string `json:"type"`
URL string `json:"url"`
Title string `json:"title"`
Description string `json:"description"`
Determiner string `json:"determiner"`
SiteName string `json:"site_name"`
Locale string `json:"locale"`
LocalesAlternate []string `json:"locales_alternate"`
Images []*Image `json:"images"`
Audios []*Audio `json:"audios"`
Videos []*Video `json:"videos"`
Article *Article `json:"article,omitempty"`
Book *Book `json:"book,omitempty"`
Profile *Profile `json:"profile,omitempty"`
Type string `json:"type"`
URL string `json:"url"`
Title string `json:"title"`
Description string `json:"description"`
Determiner string `json:"determiner"`
SiteName string `json:"site_name"`
Locale string `json:"locale"`
LocalesAlternate []string `json:"locales_alternate"`
Images []*image.Image `json:"images"`
Audios []*audio.Audio `json:"audios"`
Videos []*video.Video `json:"videos"`
Article *article.Article `json:"article,omitempty"`
Book *book.Book `json:"book,omitempty"`
Profile *profile.Profile `json:"profile,omitempty"`
Music *music.Music `json:"music,omitempty"`
}
// NewOpenGraph returns new instance of Open Graph structure
@ -137,21 +93,13 @@ func (og *OpenGraph) ensureHasVideo() {
if len(og.Videos) > 0 {
return
}
og.Videos = append(og.Videos, &Video{draft: true})
og.Videos = append(og.Videos, video.NewVideo())
}
func (og *OpenGraph) ensureHasImage() {
if len(og.Images) > 0 {
return
func (og *OpenGraph) ensureHasMusic() {
if og.Music == nil {
og.Music = music.NewMusic()
}
og.Images = append(og.Images, &Image{draft: true})
}
func (og *OpenGraph) ensureHasAudio() {
if len(og.Audios) > 0 {
return
}
og.Audios = append(og.Audios, &Audio{draft: true})
}
// ProcessMeta processes meta attributes and adds them to Open Graph structure if they are suitable for that
@ -182,73 +130,110 @@ func (og *OpenGraph) ProcessMeta(metaAttrs map[string]string) {
case "og:locale:alternate":
og.LocalesAlternate = append(og.LocalesAlternate, metaAttrs["content"])
case "og:audio":
if len(og.Audios)>0 && og.Audios[len(og.Audios)-1].draft {
og.Audios[len(og.Audios)-1].URL = metaAttrs["content"]
og.Audios[len(og.Audios)-1].draft = false
} else {
og.Audios = append(og.Audios, &Audio{URL: metaAttrs["content"]})
}
og.Audios = audio.AddUrl(og.Audios, metaAttrs["content"])
case "og:audio:secure_url":
og.ensureHasAudio()
og.Audios[len(og.Audios)-1].SecureURL = metaAttrs["content"]
og.Audios = audio.AddSecureUrl(og.Audios, metaAttrs["content"])
case "og:audio:type":
og.ensureHasAudio()
og.Audios[len(og.Audios)-1].Type = metaAttrs["content"]
og.Audios = audio.AddType(og.Audios, metaAttrs["content"])
case "og:image":
if len(og.Images)>0 && og.Images[len(og.Images)-1].draft {
og.Images[len(og.Images)-1].URL = metaAttrs["content"]
og.Images[len(og.Images)-1].draft = false
} else {
og.Images = append(og.Images, &Image{URL: metaAttrs["content"]})
}
og.Images = image.AddURL(og.Images, metaAttrs["content"])
case "og:image:url":
og.ensureHasImage()
og.Images[len(og.Images)-1].URL = metaAttrs["content"]
og.Images = image.AddURL(og.Images, metaAttrs["content"])
case "og:image:secure_url":
og.ensureHasImage()
og.Images[len(og.Images)-1].SecureURL = metaAttrs["content"]
og.Images = image.AddSecureURL(og.Images, metaAttrs["content"])
case "og:image:type":
og.ensureHasImage()
og.Images[len(og.Images)-1].Type = metaAttrs["content"]
og.Images = image.AddType(og.Images, metaAttrs["content"])
case "og:image:width":
w, err := strconv.ParseUint(metaAttrs["content"], 10, 64)
if err == nil {
og.ensureHasImage()
og.Images[len(og.Images)-1].Width = w
og.Images = image.AddWidth(og.Images, w)
}
case "og:image:height":
h, err := strconv.ParseUint(metaAttrs["content"], 10, 64)
if err == nil {
og.ensureHasImage()
og.Images[len(og.Images)-1].Height = h
og.Images = image.AddHeight(og.Images, h)
}
case "og:video":
if len(og.Videos)>0 && og.Videos[len(og.Videos)-1].draft {
og.Videos[len(og.Videos)-1].URL = metaAttrs["content"]
og.Videos[len(og.Videos)-1].draft = false
} else {
og.Videos = append(og.Videos, &Video{URL: metaAttrs["content"]})
og.Videos = video.AddURL(og.Videos, metaAttrs["content"])
case "og:video:tag":
og.Videos = video.AddTag(og.Videos, metaAttrs["content"])
case "og:video:duration":
if i, err := strconv.ParseUint(metaAttrs["content"], 10, 64); err == nil {
og.Videos = video.AddDuration(og.Videos, i)
}
case "og:video:release_date":
if t, err := time.Parse(time.RFC3339, metaAttrs["content"]); err == nil {
og.Videos = video.AddReleaseDate(og.Videos, &t)
}
case "og:video:url":
og.ensureHasVideo()
og.Videos[len(og.Videos)-1].URL = metaAttrs["content"]
og.Videos = video.AddURL(og.Videos, metaAttrs["content"])
case "og:video:secure_url":
og.ensureHasVideo()
og.Videos[len(og.Videos)-1].SecureURL = metaAttrs["content"]
og.Videos = video.AddSecureURL(og.Videos, metaAttrs["content"])
case "og:video:type":
og.ensureHasVideo()
og.Videos[len(og.Videos)-1].Type = metaAttrs["content"]
og.Videos = video.AddTag(og.Videos, metaAttrs["content"])
case "og:video:width":
w, err := strconv.ParseUint(metaAttrs["content"], 10, 64)
if err == nil {
og.ensureHasVideo()
og.Videos[len(og.Videos)-1].Width = w
og.Videos = video.AddWidth(og.Videos, w)
}
case "og:video:height":
h, err := strconv.ParseUint(metaAttrs["content"], 10, 64)
if err == nil {
og.ensureHasVideo()
og.Videos[len(og.Videos)-1].Height = h
og.Videos = video.AddHeight(og.Videos, h)
}
case "og:video:actor":
og.ensureHasVideo()
og.Videos[len(og.Videos)-1].Actors = actor.AddProfile(og.Videos[len(og.Videos)-1].Actors, metaAttrs["content"])
case "og:video:actor:role":
og.ensureHasVideo()
og.Videos[len(og.Videos)-1].Actors = actor.AddRole(og.Videos[len(og.Videos)-1].Actors, metaAttrs["content"])
case "og:video:director":
og.ensureHasVideo()
og.Videos[len(og.Videos)-1].Directors = append(og.Videos[len(og.Videos)-1].Directors, metaAttrs["content"])
case "og:video:writer":
og.ensureHasVideo()
og.Videos[len(og.Videos)-1].Writers = append(og.Videos[len(og.Videos)-1].Writers, metaAttrs["content"])
case "og:music:duration":
og.ensureHasMusic()
if i, err := strconv.ParseUint(metaAttrs["content"], 10, 64); err == nil {
og.Music.Duration = i
}
case "og:music:release_date":
og.ensureHasMusic()
if t, err := time.Parse(time.RFC3339, metaAttrs["content"]); err == nil {
og.Music.ReleaseDate = &t
}
case "og:music:album":
og.ensureHasMusic()
og.Music.Album.URL = metaAttrs["content"]
case "og:music:album:disc":
og.ensureHasMusic()
if i, err := strconv.ParseUint(metaAttrs["content"], 10, 64); err == nil {
og.Music.Album.Disc = i
}
case "og:music:album:track":
og.ensureHasMusic()
if i, err := strconv.ParseUint(metaAttrs["content"], 10, 64); err == nil {
og.Music.Album.Track = i
}
case "og:music:musician":
og.ensureHasMusic()
og.Music.Musicians = append(og.Music.Musicians, metaAttrs["content"])
case "og:music:creator":
og.ensureHasMusic()
og.Music.Creators = append(og.Music.Creators, metaAttrs["content"])
case "og:music:song":
og.ensureHasMusic()
og.Music.AddSongUrl(metaAttrs["content"])
case "og:music:disc":
og.ensureHasMusic()
if i, err := strconv.ParseUint(metaAttrs["content"], 10, 64); err == nil {
og.Music.AddSongDisc(i)
}
case "og:music:track":
og.ensureHasMusic()
if i, err := strconv.ParseUint(metaAttrs["content"], 10, 64); err == nil {
og.Music.AddSongTrack(i)
}
default:
if og.isArticle {
@ -263,100 +248,64 @@ func (og *OpenGraph) ProcessMeta(metaAttrs map[string]string) {
func (og *OpenGraph) processArticleMeta(metaAttrs map[string]string) {
if og.Article == nil {
og.Article = &Article{}
og.Article = &article.Article{}
}
switch metaAttrs["property"] {
case "article:published_time":
case "og:article:published_time":
t, err := time.Parse(time.RFC3339, metaAttrs["content"])
if err == nil {
og.Article.PublishedTime = &t
}
case "article:modified_time":
case "og:article:modified_time":
t, err := time.Parse(time.RFC3339, metaAttrs["content"])
if err == nil {
og.Article.ModifiedTime = &t
}
case "article:expiration_time":
case "og:article:expiration_time":
t, err := time.Parse(time.RFC3339, metaAttrs["content"])
if err == nil {
og.Article.ExpirationTime = &t
}
case "article:section":
case "og:article:section":
og.Article.Section = metaAttrs["content"]
case "article:tag":
case "og:article:tag":
og.Article.Tags = append(og.Article.Tags, metaAttrs["content"])
case "article:author:first_name":
if len(og.Article.Authors) == 0 {
og.Article.Authors = append(og.Article.Authors, &Profile{})
}
og.Article.Authors[len(og.Article.Authors)-1].FirstName = metaAttrs["content"]
case "article:author:last_name":
if len(og.Article.Authors) == 0 {
og.Article.Authors = append(og.Article.Authors, &Profile{})
}
og.Article.Authors[len(og.Article.Authors)-1].LastName = metaAttrs["content"]
case "article:author:username":
if len(og.Article.Authors) == 0 {
og.Article.Authors = append(og.Article.Authors, &Profile{})
}
og.Article.Authors[len(og.Article.Authors)-1].Username = metaAttrs["content"]
case "article:author:gender":
if len(og.Article.Authors) == 0 {
og.Article.Authors = append(og.Article.Authors, &Profile{})
}
og.Article.Authors[len(og.Article.Authors)-1].Gender = metaAttrs["content"]
case "og:article:author":
og.Article.Authors = append(og.Article.Authors, metaAttrs["content"])
}
}
func (og *OpenGraph) processBookMeta(metaAttrs map[string]string) {
if og.Book == nil {
og.Book = &Book{}
og.Book = &book.Book{}
}
switch metaAttrs["property"] {
case "book:release_date":
case "og:book:release_date":
t, err := time.Parse(time.RFC3339, metaAttrs["content"])
if err == nil {
og.Book.ReleaseDate = &t
}
case "book:isbn":
case "og:book:isbn":
og.Book.ISBN = metaAttrs["content"]
case "book:tag":
case "og:book:tag":
og.Book.Tags = append(og.Book.Tags, metaAttrs["content"])
case "book:author:first_name":
if len(og.Book.Authors) == 0 {
og.Book.Authors = append(og.Book.Authors, &Profile{})
}
og.Book.Authors[len(og.Book.Authors)-1].FirstName = metaAttrs["content"]
case "book:author:last_name":
if len(og.Book.Authors) == 0 {
og.Book.Authors = append(og.Book.Authors, &Profile{})
}
og.Book.Authors[len(og.Book.Authors)-1].LastName = metaAttrs["content"]
case "book:author:username":
if len(og.Book.Authors) == 0 {
og.Book.Authors = append(og.Book.Authors, &Profile{})
}
og.Book.Authors[len(og.Book.Authors)-1].Username = metaAttrs["content"]
case "book:author:gender":
if len(og.Book.Authors) == 0 {
og.Book.Authors = append(og.Book.Authors, &Profile{})
}
og.Book.Authors[len(og.Book.Authors)-1].Gender = metaAttrs["content"]
case "og:book:author":
og.Book.Authors = append(og.Book.Authors, metaAttrs["content"])
}
}
func (og *OpenGraph) processProfileMeta(metaAttrs map[string]string) {
if og.Profile == nil {
og.Profile = &Profile{}
og.Profile = &profile.Profile{}
}
switch metaAttrs["property"] {
case "profile:first_name":
case "og:profile:first_name":
og.Profile.FirstName = metaAttrs["content"]
case "profile:last_name":
case "og:profile:last_name":
og.Profile.LastName = metaAttrs["content"]
case "profile:username":
case "og:profile:username":
og.Profile.Username = metaAttrs["content"]
case "profile:gender":
case "og:profile:gender":
og.Profile.Gender = metaAttrs["content"]
}
}

View File

@ -0,0 +1,27 @@
package actor
// Actor contain Open Graph Actor structure
type Actor struct {
Profile string `json:"profile"`
Role string `json:"role"`
}
func NewActor() *Actor {
return &Actor{}
}
func AddProfile(actors []*Actor, v string) []*Actor {
if len(actors) == 0 || actors[len(actors)-1].Profile != "" {
actors = append(actors, &Actor{})
}
actors[len(actors)-1].Profile = v
return actors
}
func AddRole(actors []*Actor, v string) []*Actor {
if len(actors) == 0 || actors[len(actors)-1].Role != "" {
actors = append(actors, &Actor{})
}
actors[len(actors)-1].Role = v
return actors
}

View File

@ -0,0 +1,15 @@
package article
import (
"time"
)
// Article contain Open Graph Article structure
type Article struct {
PublishedTime *time.Time `json:"published_time"`
ModifiedTime *time.Time `json:"modified_time"`
ExpirationTime *time.Time `json:"expiration_time"`
Section string `json:"section"`
Tags []string `json:"tags"`
Authors []string `json:"authors"`
}

View File

@ -0,0 +1,36 @@
package audio
// Audio defines Open Graph Audio Type
type Audio struct {
URL string `json:"url"`
SecureURL string `json:"secure_url"`
Type string `json:"type"`
}
func NewAudio() *Audio {
return &Audio{}
}
func AddUrl(audios []*Audio, v string) []*Audio {
if len(audios) == 0 || audios[len(audios)-1].URL != "" {
audios = append(audios, &Audio{})
}
audios[len(audios)-1].URL = v
return audios
}
func AddSecureUrl(audios []*Audio, v string) []*Audio {
if len(audios) == 0 || audios[len(audios)-1].SecureURL != "" {
audios = append(audios, &Audio{})
}
audios[len(audios)-1].SecureURL = v
return audios
}
func AddType(audios []*Audio, v string) []*Audio {
if len(audios) == 0 || audios[len(audios)-1].Type != "" {
audios = append(audios, &Audio{})
}
audios[len(audios)-1].Type = v
return audios
}

View File

@ -0,0 +1,13 @@
package book
import (
"time"
)
// Book contains Open Graph Book structure
type Book struct {
ISBN string `json:"isbn"`
ReleaseDate *time.Time `json:"release_date"`
Tags []string `json:"tags"`
Authors []string `json:"authors"`
}

View File

@ -0,0 +1,53 @@
package image
// Image defines Open Graph Image type
type Image struct {
URL string `json:"url"`
SecureURL string `json:"secure_url"`
Type string `json:"type"`
Width uint64 `json:"width"`
Height uint64 `json:"height"`
}
func NewImage() *Image {
return &Image{}
}
func ensureHasImage(images []*Image) []*Image {
if len(images) == 0 {
images = append(images, NewImage())
}
return images
}
func AddURL(images []*Image, v string) []*Image {
if len(images) == 0 || (images[len(images)-1].URL != "" && images[len(images)-1].URL != v) {
images = append(images, NewImage())
}
images[len(images)-1].URL = v
return images
}
func AddSecureURL(images []*Image, v string) []*Image {
images = ensureHasImage(images)
images[len(images)-1].SecureURL = v
return images
}
func AddType(images []*Image, v string) []*Image {
images = ensureHasImage(images)
images[len(images)-1].Type = v
return images
}
func AddWidth(images []*Image, v uint64) []*Image {
images = ensureHasImage(images)
images[len(images)-1].Width = v
return images
}
func AddHeight(images []*Image, v uint64) []*Image {
images = ensureHasImage(images)
images[len(images)-1].Height = v
return images
}

View File

@ -0,0 +1,52 @@
package music
import (
"time"
)
// Music defines Open Graph Music type
type Music struct {
Musicians []string `json:"musicians,omitempty"`
Creators []string `json:"creators,omitempty"`
Duration uint64 `json:"duration,omitempty"`
ReleaseDate *time.Time `json:"release_date,omitempty"`
Album *Album `json:"album"`
Songs []*Song `json:"songs"`
}
type Album struct {
URL string `json:"url,omitempty"`
Disc uint64 `json:"disc,omitempty"`
Track uint64 `json:"track,omitempty"`
}
type Song struct {
URL string `json:"url,omitempty"`
Disc uint64 `json:"disc,omitempty"`
Track uint64 `json:"track,omitempty"`
}
func NewMusic() *Music {
return &Music{Album: &Album{}}
}
func (m *Music) AddSongUrl(v string) {
if len(m.Songs) == 0 || m.Songs[len(m.Songs)-1].URL != "" {
m.Songs = append(m.Songs, &Song{})
}
m.Songs[len(m.Songs)-1].URL = v
}
func (m *Music) AddSongDisc(v uint64) {
if len(m.Songs) == 0 {
m.Songs = append(m.Songs, &Song{})
}
m.Songs[len(m.Songs)-1].Disc = v
}
func (m *Music) AddSongTrack(v uint64) {
if len(m.Songs) == 0 {
m.Songs = append(m.Songs, &Song{})
}
m.Songs[len(m.Songs)-1].Track = v
}

View File

@ -0,0 +1,59 @@
package profile
import "strings"
// Profile contain Open Graph Profile structure
type Profile struct {
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Username string `json:"username"`
Gender string `json:"gender"`
}
func NewProfile() *Profile {
return &Profile{}
}
func AddBasicProfile(profiles []*Profile, v string) []*Profile {
parts := strings.SplitN(v, " ", 2)
if len(profiles) == 0 || profiles[len(profiles)-1].FirstName != "" {
profiles = append(profiles, &Profile{})
}
profiles[len(profiles)-1].FirstName = parts[0]
if len(parts) > 1 {
profiles[len(profiles)-1].LastName = parts[1]
}
return profiles
}
func AddFirstName(profiles []*Profile, v string) []*Profile {
if len(profiles) == 0 || profiles[len(profiles)-1].FirstName != "" {
profiles = append(profiles, &Profile{})
}
profiles[len(profiles)-1].FirstName = v
return profiles
}
func AddLastName(profiles []*Profile, v string) []*Profile {
if len(profiles) == 0 || profiles[len(profiles)-1].LastName != "" {
profiles = append(profiles, &Profile{})
}
profiles[len(profiles)-1].LastName = v
return profiles
}
func AddUsername(profiles []*Profile, v string) []*Profile {
if len(profiles) == 0 || profiles[len(profiles)-1].Username != "" {
profiles = append(profiles, &Profile{})
}
profiles[len(profiles)-1].Username = v
return profiles
}
func AddGender(profiles []*Profile, v string) []*Profile {
if len(profiles) == 0 || profiles[len(profiles)-1].Gender != "" {
profiles = append(profiles, &Profile{})
}
profiles[len(profiles)-1].Gender = v
return profiles
}

View File

@ -0,0 +1,83 @@
package video
import (
"time"
"github.com/dyatlov/go-opengraph/opengraph/types/actor"
)
// Video defines Open Graph Video type
type Video struct {
URL string `json:"url"`
SecureURL string `json:"secure_url"`
Type string `json:"type"`
Width uint64 `json:"width"`
Height uint64 `json:"height"`
Actors []*actor.Actor `json:"actors,omitempty"`
Directors []string `json:"directors,omitempty"`
Writers []string `json:"writers,omitempty"`
Duration uint64 `json:"duration,omitempty"`
ReleaseDate *time.Time `json:"release_date,omitempty"`
Tags []string `json:"tags,omitempty"`
}
func NewVideo() *Video {
return &Video{}
}
func ensureHasVideo(videos []*Video) []*Video {
if len(videos) == 0 {
videos = append(videos, NewVideo())
}
return videos
}
func AddURL(videos []*Video, v string) []*Video {
if len(videos) == 0 || (videos[len(videos)-1].URL != "" && videos[len(videos)-1].URL != v) {
videos = append(videos, NewVideo())
}
videos[len(videos)-1].URL = v
return videos
}
func AddTag(videos []*Video, v string) []*Video {
videos = ensureHasVideo(videos)
videos[len(videos)-1].Tags = append(videos[len(videos)-1].Tags, v)
return videos
}
func AddDuration(videos []*Video, v uint64) []*Video {
videos = ensureHasVideo(videos)
videos[len(videos)-1].Duration = v
return videos
}
func AddReleaseDate(videos []*Video, v *time.Time) []*Video {
videos = ensureHasVideo(videos)
videos[len(videos)-1].ReleaseDate = v
return videos
}
func AddSecureURL(videos []*Video, v string) []*Video {
videos = ensureHasVideo(videos)
videos[len(videos)-1].SecureURL = v
return videos
}
func AddType(videos []*Video, v string) []*Video {
videos = ensureHasVideo(videos)
videos[len(videos)-1].Type = v
return videos
}
func AddWidth(videos []*Video, v uint64) []*Video {
videos = ensureHasVideo(videos)
videos[len(videos)-1].Width = v
return videos
}
func AddHeight(videos []*Video, v uint64) []*Video {
videos = ensureHasVideo(videos)
videos[len(videos)-1].Height = v
return videos
}