Skip to content

Commit

Permalink
Merge pull request #13 from daystram/dev
Browse files Browse the repository at this point in the history
  • Loading branch information
daystram authored Feb 6, 2021
2 parents 87eff54 + dcab76f commit e3329a4
Show file tree
Hide file tree
Showing 22 changed files with 342 additions and 145 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ $ go mod tidy
$ bee run
```

### cast-is
`cast-is` uses [Go Modules](https://blog.golang.org/using-go-modules) module/dependency manager, hence at least Go 1.11 is required. To ease development, [comstrek/air](https://github.com/cosmtrek/air) is used to live-reload the application. Install the tool as documented.

To begin developing, simply enter the sub-directory and run the development server:
```shell
$ cd cast-is
$ go mod tidy
$ air
```

### cast-fe
Populate `.env.development` with the required credentials.

Expand Down
2 changes: 1 addition & 1 deletion cast-be/controller/v1/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type AuthControllerAuth struct {
Handler handlers.Handler
}

// @Title Register user from OID, skip if already exists
// @Title Register user from OID, skip if exists, update if required
// @Param idToken body {datatransfers.UserRegister} true "registration info"
// @Success 200 success
// @router /check [post]
Expand Down
2 changes: 2 additions & 0 deletions cast-be/controller/v1/video.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ func (c *VideoControllerAuth) EditVideo(_ string) datatransfers.Response {
Title: video.Title,
Description: video.Description,
Tags: strings.Split(video.Tags, ","),
Unlisted: video.Unlisted,
}, c.Controller, c.userID)
if err != nil {
fmt.Printf("[VideoControllerAuth::EditVideo] failed editing video. %+v\n", err)
Expand Down Expand Up @@ -190,6 +191,7 @@ func (c *VideoControllerAuth) UploadVideo(_ string) datatransfers.Response {
Title: upload.Title,
Description: upload.Description,
Tags: strings.Split(upload.Tags, ","),
Unlisted: upload.Unlisted,
}, c.Controller, c.userID)
if err != nil {
fmt.Printf("[VideoControllerAuth::UploadVideo] failed creating video. %+v\n", err)
Expand Down
9 changes: 7 additions & 2 deletions cast-be/datatransfers/video.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type Video struct {
Views int `json:"views" bson:"views"`
Duration int64 `json:"duration,omitempty" bson:"duration"` // only for VODs
IsLive bool `json:"is_live" bson:"is_live"` // only for Live
Unlisted bool `json:"unlisted" bson:"unlisted"`
Pending bool `json:"pending" bson:"pending"`
Resolutions int `json:"resolutions" bson:"resolutions"` // 0:None, 1:180p, 2:360p, 3:480p, 4:720p, 5:1080p, only for VODs
Likes int `json:"likes" bson:"likes"`
Expand All @@ -35,8 +36,8 @@ type VideoInsert struct {
Description string `bson:"description"`
Tags []string `bson:"tags"`
Views int `json:"views" bson:"views"`
Duration int64 `bson:"duration"` // only for VODs
IsLive bool `bson:"is_live"` // only for Live
IsLive bool `bson:"is_live"` // only for Live, always set to true for VODs
Unlisted bool `bson:"unlisted"`
Resolutions int `bson:"resolutions"` // 0:None, 1:180p, 2:360p, 3:480p, 4:720p, 5:1080p, only for VODs
CreatedAt time.Time `bson:"created_at"`
}
Expand All @@ -45,26 +46,30 @@ type VideoUploadForm struct {
Title string `form:"title"`
Description string `form:"description"`
Tags string `form:"tags"`
Unlisted bool `form:"unlisted"`
}

type VideoUpload struct {
Title string
Description string
Tags []string
Unlisted bool
}

type VideoEditForm struct {
Hash string `form:"hash"`
Title string `form:"title"`
Description string `form:"description"`
Tags string `form:"tags"`
Unlisted bool `form:"unlisted"`
}

type VideoEdit struct {
Hash string
Title string
Description string
Tags []string
Unlisted bool
}

type Comment struct {
Expand Down
61 changes: 35 additions & 26 deletions cast-be/handlers/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,36 +20,45 @@ func (m *module) Register(idToken datatransfers.UserRegister) (err error) {
fmt.Printf("[Register] Failed parsing id_token. %+v\n", err)
return
}
exists := false
if err = m.db.userOrm.CheckUnique("_id", user.ID); err != nil {
return nil // user exists
exists = true
}
if err = m.db.userOrm.CheckUnique("username", user.Username); err != nil {
return nil // user exists
if err = m.db.userOrm.CheckUnique("username", user.Username); err != nil { // double check
exists = true
}
if err = m.db.userOrm.InsertUser(user); err != nil {
fmt.Printf("[Register] Failed adding %s user entry. %+v\n", user.Username, err)
return
}
if _, err = m.db.videoOrm.InsertVideo(datatransfers.VideoInsert{
ID: primitive.NewObjectID(),
Hash: user.Username,
Type: constants.VideoTypeLive,
Author: user.ID,
Title: fmt.Sprintf("%s's Livestream", user.Username),
Tags: []string{"live", "first"},
Description: "Welcome to my stream!",
Resolutions: -1,
IsLive: false,
}); err != nil {
_ = m.db.userOrm.DeleteOneByID(user.ID)
fmt.Printf("[Register] Failed adding %s live video entry. %+v\n", user.Username, err)
return
if exists {
if err = m.db.userOrm.UpdateUser(user); err != nil {
fmt.Printf("[Register] Failed updating user entry. %+v\n", err)
return
}
} else {
if err = m.db.userOrm.InsertUser(user); err != nil {
fmt.Printf("[Register] Failed adding %s user entry. %+v\n", user.Username, err)
return
}
if _, err = m.db.videoOrm.InsertVideo(datatransfers.VideoInsert{
ID: primitive.NewObjectID(),
Hash: user.Username,
Type: constants.VideoTypeLive,
Author: user.ID,
Title: fmt.Sprintf("%s's Livestream", user.Username),
Tags: []string{"live", "first"},
Description: "Welcome to my stream!",
Resolutions: -1,
IsLive: false,
Unlisted: false,
}); err != nil {
_ = m.db.userOrm.DeleteOneByID(user.ID)
fmt.Printf("[Register] Failed adding %s live video entry. %+v\n", user.Username, err)
return
}
_, _ = m.s3.CopyObject(&s3.CopyObjectInput{
Bucket: aws.String(config.AppConfig.S3Bucket),
CopySource: aws.String(fmt.Sprintf("%s/%s.jpg", config.AppConfig.S3Bucket, constants.ThumbnailDefault)),
Key: aws.String(fmt.Sprintf("%s/%s.jpg", constants.ThumbnailRootDir, user.Username)),
})
}
_, _ = m.s3.CopyObject(&s3.CopyObjectInput{
Bucket: aws.String(config.AppConfig.S3Bucket),
CopySource: aws.String(fmt.Sprintf("%s/%s.jpg", config.AppConfig.S3Bucket, constants.ThumbnailDefault)),
Key: aws.String(fmt.Sprintf("%s/%s.jpg", constants.ThumbnailRootDir, user.Username)),
})
return
}

Expand Down
16 changes: 9 additions & 7 deletions cast-be/handlers/rtmp.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,15 @@ func (m *module) CreateRTMPUpLink() {
return
}
fmt.Printf("[RTMPUpLink] UpLink for %s connected\n", username)
m.BroadcastNotificationSubscriber(video.Author.ID, datatransfers.NotificationOutgoing{
Message: fmt.Sprintf("%s just went live! Watch now!", video.Author.Name),
Name: video.Author.Name,
Username: video.Author.Username,
Hash: video.Hash,
CreatedAt: time.Now(),
})
if !video.Unlisted {
m.BroadcastNotificationSubscriber(video.Author.ID, datatransfers.NotificationOutgoing{
Message: fmt.Sprintf("%s just went live! Watch now!", video.Author.Name),
Name: video.Author.Name,
Username: video.Author.Username,
Hash: video.Hash,
CreatedAt: time.Now(),
})
}
m.live.mutex.Unlock()
} else {
fmt.Printf("[RTMPUpLink] UpLink for %s already exists\n", username)
Expand Down
2 changes: 1 addition & 1 deletion cast-be/handlers/transcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (m *module) TranscodeListenerWorker() {
CreatedAt: time.Now(),
})
}
if resolution == 1 {
if !video.Unlisted && resolution == 1 {
m.BroadcastNotificationSubscriber(video.Author.ID, datatransfers.NotificationOutgoing{
Message: fmt.Sprintf("%s just uploaded %s! Watch now!", video.Author.Name, video.Title),
Name: video.Author.Name,
Expand Down
7 changes: 4 additions & 3 deletions cast-be/handlers/video.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@ func (m *module) CreateVOD(upload data.VideoUpload, controller beego.Controller,
Author: userID,
Description: upload.Description,
Tags: upload.Tags,
IsLive: true, // must be set to true for VODs
Unlisted: upload.Unlisted,
Views: 0,
Duration: 0,
IsLive: true,
Resolutions: 0,
CreatedAt: time.Now(),
}); err != nil {
Expand Down Expand Up @@ -179,12 +179,13 @@ func (m *module) UpdateVideo(video data.VideoEdit, controller beego.Controller,
Author: userID,
Description: video.Description,
Tags: video.Tags,
Unlisted: video.Unlisted,
}); err != nil {
return errors.New(fmt.Sprintf("[UpdateVideo] error updating video. %+v", err))
}
// Retrieve thumbnail
var thumbnail multipart.File
if thumbnail, _, err = controller.GetFile("thumbnail"); err!= nil {
if thumbnail, _, err = controller.GetFile("thumbnail"); err != nil {
if err == http.ErrMissingFile {
return nil
} else {
Expand Down
11 changes: 11 additions & 0 deletions cast-be/models/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type UserOrmer interface {
GetOneByUsername(username string) (user datatransfers.User, err error)
CheckUnique(field, value string) (err error)
InsertUser(user datatransfers.User) (err error)
UpdateUser(user datatransfers.User) (err error)
DeleteOneByID(ID string) (err error)
}

Expand Down Expand Up @@ -55,6 +56,16 @@ func (o *userOrm) InsertUser(user datatransfers.User) (err error) {
return
}

func (o *userOrm) UpdateUser(user datatransfers.User) (err error) {
return o.collection.FindOneAndUpdate(context.Background(),
bson.M{"_id": user.ID},
bson.D{{"$set", bson.D{
{"username", user.Username},
{"name", user.Name},
}}},
).Err()
}

func (o *userOrm) DeleteOneByID(ID string) (err error) {
_, err = o.collection.DeleteOne(context.Background(), bson.M{"_id": ID})
return
Expand Down
10 changes: 8 additions & 2 deletions cast-be/models/video.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ func (o *videoOrm) GetRecent(variant string, count int, offset int) (result []da
{{"$match", bson.D{{"type", variant}}}},
{{"$match", bson.D{{"resolutions", bson.D{{"$ne", 0}}}}}},
{{"$match", bson.D{{"is_live", true}}}},
{{"$match", bson.D{{"unlisted", false}}}},
{{"$sort", bson.D{{"created_at", -1}, {"_id", 1}}}},
{{"$skip", offset}},
{{"$limit", count}},
Expand Down Expand Up @@ -75,6 +76,7 @@ func (o *videoOrm) GetLiked(userID string, count int, offset int) (result []data
if query, err = o.collection.Aggregate(context.Background(), mongo.Pipeline{
{{"$match", bson.D{{"resolutions", bson.D{{"$ne", 0}}}}}},
{{"$match", bson.D{{"is_live", true}}}},
{{"$match", bson.D{{"unlisted", false}}}},
{{"$sort", bson.D{{"created_at", -1}, {"_id", 1}}}},
{{"$lookup", bson.D{
{"from", constants.DBCollectionLike},
Expand Down Expand Up @@ -111,6 +113,7 @@ func (o *videoOrm) GetSubscribed(userID string, count int, offset int) (result [
if query, err = o.collection.Aggregate(context.Background(), mongo.Pipeline{
{{"$match", bson.D{{"resolutions", bson.D{{"$ne", 0}}}}}},
{{"$match", bson.D{{"is_live", true}}}},
{{"$match", bson.D{{"unlisted", false}}}},
{{"$sort", bson.D{{"created_at", -1}, {"_id", 1}}}},
{{"$lookup", bson.D{
{"from", constants.DBCollectionSubscription},
Expand Down Expand Up @@ -147,6 +150,7 @@ func (o *videoOrm) GetTrending(count int, offset int) (result []datatransfers.Vi
if query, err = o.collection.Aggregate(context.Background(), mongo.Pipeline{
{{"$match", bson.D{{"resolutions", bson.D{{"$ne", 0}}}}}},
{{"$match", bson.D{{"is_live", true}}}},
{{"$match", bson.D{{"unlisted", false}}}},
{{"$lookup", bson.D{
{"from", constants.DBCollectionLike},
{"localField", "hash"},
Expand Down Expand Up @@ -185,7 +189,7 @@ func (o *videoOrm) GetTrending(count int, offset int) (result []datatransfers.Vi

func (o *videoOrm) GetAllVODByAuthor(author string) (videos []datatransfers.Video, err error) {
query := &mongo.Cursor{}
if query, err = o.collection.Aggregate(context.Background(), mongo.Pipeline{
if query, err = o.collection.Aggregate(context.Background(), mongo.Pipeline{ // unlisted VODs included
{{"$match", bson.D{{"author", author}}}},
{{"$match", bson.D{{"type", constants.VideoTypeVOD}}}},
{{"$sort", bson.D{{"created_at", -1}, {"_id", 1}}}},
Expand All @@ -210,7 +214,7 @@ func (o *videoOrm) GetAllVODByAuthor(author string) (videos []datatransfers.Vide

func (o *videoOrm) GetAllVODByAuthorPaginated(author string, count int, offset int) (videos []datatransfers.Video, err error) {
query := &mongo.Cursor{}
if query, err = o.collection.Aggregate(context.Background(), mongo.Pipeline{
if query, err = o.collection.Aggregate(context.Background(), mongo.Pipeline{ // unlisted VODs included
{{"$match", bson.D{{"author", author}}}},
{{"$match", bson.D{{"type", constants.VideoTypeVOD}}}},
{{"$sort", bson.D{{"created_at", -1}, {"_id", 1}}}},
Expand Down Expand Up @@ -251,6 +255,7 @@ func (o *videoOrm) Search(queryString string, count int, offset int) (result []d
{{"$match", bson.D{{"$text", bson.D{{"$search", queryString}}}}}},
{{"$match", bson.D{{"resolutions", bson.D{{"$ne", 0}}}}}},
{{"$match", bson.D{{"is_live", true}}}},
{{"$match", bson.D{{"unlisted", false}}}},
{{"$sort", bson.D{{"views", -1}, {"created_at", -1}, {"_id", 1}}}},
{{"$skip", offset}},
{{"$limit", count}},
Expand Down Expand Up @@ -397,6 +402,7 @@ func (o *videoOrm) EditVideo(video datatransfers.VideoInsert) (err error) {
{"title", video.Title},
{"description", video.Description},
{"tags", video.Tags},
{"unlisted", video.Unlisted},
}}},
).Err()
}
Expand Down
6 changes: 1 addition & 5 deletions cast-fe/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
"bs-custom-file-input": "^1.3.4",
"dashjs": "^3.0.3",
"flv.js": "^1.5.0",
"js-cookie": "^2.2.1",
"query-string": "^6.12.1",
"react": "^16.13.0",
"react-bootstrap": "^1.0.0-beta.17",
Expand All @@ -22,17 +21,14 @@
"react-responsive": "^8.0.3",
"react-router-dom": "^5.1.2",
"react-scripts": "3.4.0",
"react-scroll": "^1.7.16",
"react-tag-input": "^6.4.2",
"react-timeago": "^4.4.0",
"react-toastify": "^6.0.4",
"react-truncate": "^2.4.0",
"video.js": "^7.6.6",
"videojs-contrib-dash": "^2.11.0",
"videojs-contrib-quality-levels": "^2.0.9",
"videojs-flvjs-es6": "^1.0.1",
"videojs-http-source-selector": "^1.1.6",
"zxcvbn": "^4.4.2"
"videojs-http-source-selector": "^1.1.6"
},
"scripts": {
"start": "react-scripts start",
Expand Down
4 changes: 4 additions & 0 deletions cast-fe/src/components/Cast.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,15 @@ let style = {
fontSize: 18,
fontWeight: 600,
margin: 0,
overflow: "hidden",
textOverflow: "ellipsis",
},
cast_author: {
fontSize: 16,
fontWeight: 400,
margin: 0,
overflow: "hidden",
textOverflow: "ellipsis",
},
cast_duration: {
fontSize: 16,
Expand Down
Loading

0 comments on commit e3329a4

Please sign in to comment.