/
video.go
138 lines (128 loc) · 3.99 KB
/
video.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package models
import (
"fmt"
db "github.com/confur-me/confur-api/db"
"time"
)
type Video struct {
ID uint `gorm:"primary_key" json:"id"`
Title *string `sql:"not null,type:text" binding:"required" json:"title"`
Url string `json:"url"`
Length *uint `json:"length,omitempty"`
Description string `sql:"type:text" json:"description"`
ConferenceSlug *string `sql:"not null,index" binding:"required" json:"conference_slug"`
Conference *Conference `json:"conference,omitempty" gorm:"foreignkey:conference_slug"`
Scope *string `sql:"not null,index" json:"scope"`
TagResources *[]Tag `gorm:"many2many:videos_tags;associationforeignkey:tag_slug" json:"-"`
Tags []string `sql:"-" json:"tags"`
Speakers *[]Speaker `gorm:"many2many:videos_speakers" json:"speakers,omitempty"`
EventID *uint `sql:"index" json:"event_id"`
Event *Event `json:"event,omitempty" gorm:"foreignkey:event_id"`
LikesCount uint `json:"likes_count"`
DislikesCount uint `json:"likes_count"`
Rating float64 `json:"rating"`
Thumbnail string `sql:"type:text" json:"thumbnail"`
Language *string `sql:"type:varchar(2)" json:"language"`
DeletedAt *time.Time `json:"deleted_at,omitempty"`
}
type videoService struct {
Service
}
func NewVideoService(params map[string]interface{}) *videoService {
s := new(videoService)
s.params = params
return s
}
// TODO: inject likes count
func (this *videoService) Videos() (*[]Video, int, int, int, error) {
var (
err error
count int
offset int
collection []Video = make([]Video, 0)
limit int = 20
)
if conn, ok := db.Connection(); ok {
query := &conn
if v, ok := this.params["conference"]; ok {
query = query.Where("conference_slug = ?", v)
}
if v, ok := this.params["event"]; ok {
query = query.Where("event_id = ?", v)
}
if v, ok := this.params["query"]; ok {
// FIXME: CHECK sql injection possibility
query = query.
Where("title ILIKE ?", fmt.Sprintf("%%%v%%", v))
}
if _, ok := this.params["shuffle"]; ok {
query = query.Where("random() < 0.01")
}
if v, ok := this.params["limit"]; ok {
if v.(int) > 0 && v.(int) <= 50 {
limit = v.(int)
}
}
if v, ok := this.params["offset"]; ok {
offset = v.(int)
}
if v, ok := this.params["tag"]; ok {
query = query.Joins("INNER JOIN videos_tags ON videos_tags.video_id = videos.id").Where("videos_tags.tag_slug = ?", v)
}
err = query.
Preload("Conference").
Preload("Event").
Scopes(GetRange(limit, offset)).
Find(&collection).
Scopes(Unpaginate).
Count(&count).
Error
if err == nil {
tags := make(map[uint][]string)
videoIds := make([]uint, 0)
for _, video := range collection {
videoIds = append(videoIds, video.ID)
}
if len(videoIds) > 0 {
if rows, err1 := conn.Table("videos_tags").Select("video_id, tag_slug").Where("video_id IN (?)", videoIds).Rows(); err1 == nil {
var (
videoId uint
tag string
)
for rows.Next() {
rows.Scan(&videoId, &tag)
tags[videoId] = append(tags[videoId], tag)
}
for i, video := range collection {
video.Tags = tags[video.ID]
collection[i] = video
}
}
}
}
}
return &collection, count, limit, offset, err
}
func (this *videoService) Video() (*Video, error) {
var (
resource Video
err error
)
if conn, ok := db.Connection(); ok {
if v, ok := this.params["video"]; ok {
err = conn.Where("id = ?", v).Preload("Conference").Preload("Event").First(&resource).Error
if err == nil {
var tagResources []Tag
speakers := make([]Speaker, 0)
tags := make([]string, 0)
conn.Model(&resource).Related(&tagResources, "TagResources").Related(&speakers, "Speakers")
for _, v := range tagResources {
tags = append(tags, v.Slug)
}
resource.Tags = tags
resource.Speakers = &speakers
}
}
}
return &resource, err
}