Skip to content

Commit

Permalink
Merge branch 'dev' into enh/video-section-component
Browse files Browse the repository at this point in the history
# Conflicts:
#	web/assets/css/home.css
#	web/template/watch.gohtml
#	web/ts/video/watchers.ts
  • Loading branch information
MatthiasReumann committed Aug 17, 2023
2 parents fe6de03 + a85cc21 commit be53a16
Show file tree
Hide file tree
Showing 86 changed files with 4,018 additions and 2,867 deletions.
1 change: 0 additions & 1 deletion .idea/runConfigurations/run_production.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ RUN rm -rf web/assets/ts-dist &&\
WORKDIR /app/web
RUN npm i --no-dev

FROM golang:1.20-alpine3.17 as build-env
FROM golang:1.21-alpine3.18 as build-env

RUN mkdir /gostuff
WORKDIR /gostuff
Expand Down
33 changes: 21 additions & 12 deletions api/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ var allowedReactions = map[string]struct{}{
"eyes": {},
}

const (
POLL_START_MSG = "start_poll"
POLL_CLOSE_MSG = "close_active_poll"
POLL_PARTICIPATION_MSG = "submit_poll_option_vote"
)

var routes chatRoutes

func RegisterRealtimeChatChannel() {
Expand Down Expand Up @@ -130,6 +136,7 @@ func (r chatRoutes) handleSubmitPollOptionVote(ctx tools.TUMLiveContext, msg []b
voteCount, _ := r.ChatDao.GetPollOptionVoteCount(req.PollOptionId)

voteUpdateMap := gin.H{
"type": POLL_PARTICIPATION_MSG,
"pollOptionId": req.PollOptionId,
"votes": voteCount,
}
Expand Down Expand Up @@ -191,10 +198,11 @@ func (r chatRoutes) handleStartPoll(ctx tools.TUMLiveContext, msg []byte) {
}

pollMap := gin.H{
"active": true,
"question": poll.Question,
"pollOptions": pollOptionsJson,
"submitted": 0,
"type": POLL_START_MSG,
"active": true,
"question": poll.Question,
"options": pollOptionsJson,
"submitted": 0,
}
if pollJson, err := json.Marshal(pollMap); err == nil {
broadcastStream(ctx.Stream.ID, pollJson)
Expand Down Expand Up @@ -222,8 +230,9 @@ func (r chatRoutes) handleCloseActivePoll(ctx tools.TUMLiveContext) {
}

statsMap := gin.H{
"question": poll.Question,
"pollOptionResults": pollOptions,
"type": POLL_CLOSE_MSG,
"question": poll.Question,
"options": pollOptions,
}

if statsJson, err := json.Marshal(statsMap); err == nil {
Expand Down Expand Up @@ -397,10 +406,10 @@ func (r chatRoutes) handleRetract(ctx tools.TUMLiveContext, msg []byte) {
func (r chatRoutes) handleMessage(ctx tools.TUMLiveContext, context *realtime.Context, msg []byte) {
var chat chatReq
if err := json.Unmarshal(msg, &chat); err != nil {
log.WithError(err).Error("error unmarshaling chat message")
log.WithError(err).Error("error unmarshalling chat message")
return
}
if !ctx.Course.ChatEnabled {
if !ctx.Course.ChatEnabled && !ctx.Stream.ChatEnabled {
return
}
uname := ctx.User.GetPreferredName()
Expand Down Expand Up @@ -577,10 +586,10 @@ func (r chatRoutes) getActivePoll(c *gin.Context) {
}

c.JSON(http.StatusOK, gin.H{
"active": true,
"question": poll.Question,
"pollOptions": pollOptions,
"submitted": submitted,
"active": true,
"question": poll.Question,
"options": pollOptions,
"submitted": submitted,
})
}

Expand Down
8 changes: 4 additions & 4 deletions api/chat_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,10 @@ func TestActivePoll(t *testing.T) {
}

res := gin.H{
"active": true,
"question": testutils.PollStreamFPVLive.Question,
"pollOptions": pollOptions,
"submitted": submitted,
"active": true,
"question": testutils.PollStreamFPVLive.Question,
"options": pollOptions,
"submitted": submitted,
}

gomino.TestCases{
Expand Down
57 changes: 42 additions & 15 deletions api/courses.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,18 +266,6 @@ func (r coursesRoutes) getUsers(c *gin.Context) {
func (r coursesRoutes) getPinned(c *gin.Context) {
tumLiveContext := c.MustGet("TUMLiveContext").(tools.TUMLiveContext)

year, term := tum.GetCurrentSemester()
year, err := strconv.Atoi(c.DefaultQuery("year", strconv.Itoa(year)))
if err != nil {
_ = c.Error(tools.RequestError{
Status: http.StatusBadRequest,
CustomMessage: "invalid year",
Err: err,
})
return
}
term = c.DefaultQuery("term", term)

var pinnedCourses []model.Course
if tumLiveContext.User != nil {
pinnedCourses = tumLiveContext.User.PinnedCourses
Expand All @@ -288,7 +276,7 @@ func (r coursesRoutes) getPinned(c *gin.Context) {
pinnedCourses = commons.Unique(pinnedCourses, func(c model.Course) uint { return c.ID })
resp := make([]model.CourseDTO, 0, len(pinnedCourses))
for _, course := range pinnedCourses {
if !course.IsHidden() && course.Year == year && course.TeachingTerm == term {
if !course.IsHidden() {
resp = append(resp, course.ToDTO())
}
}
Expand All @@ -303,13 +291,16 @@ func sortCourses(courses []model.Course) {
}

func (r coursesRoutes) getCourseBySlug(c *gin.Context) {
tumLiveContext := c.MustGet("TUMLiveContext").(tools.TUMLiveContext)

type URI struct {
Slug string `uri:"slug" binding:"required"`
}

type Query struct {
Year int `form:"year"`
Term string `form:"term"`
Year int `form:"year"`
Term string `form:"term"`
UserID uint `form:"userId"`
}

var uri URI
Expand Down Expand Up @@ -359,14 +350,38 @@ func (r coursesRoutes) getCourseBySlug(c *gin.Context) {
return
}

if (course.IsLoggedIn() && tumLiveContext.User == nil) || (course.IsEnrolled() && !tumLiveContext.User.IsEligibleToWatchCourse(course)) {
c.AbortWithStatus(http.StatusUnauthorized)
}

streams := course.Streams
streamsDTO := make([]model.StreamDTO, len(streams))
for i, s := range streams {
err := tools.SetSignedPlaylists(&s, &model.User{
Model: gorm.Model{ID: query.UserID},
}, course.DownloadsEnabled)
if err != nil {
_ = c.Error(tools.RequestError{
Err: err,
Status: http.StatusInternalServerError,
CustomMessage: "can't sign stream",
})
return
}
streamsDTO[i] = s.ToDTO()
}

isAdmin := course.UserID == query.UserID
for _, user := range course.Admins {
if user.ID == query.UserID {
isAdmin = true
break
}
}

courseDTO := course.ToDTO()
courseDTO.Streams = streamsDTO
courseDTO.IsAdmin = isAdmin

c.JSON(http.StatusOK, courseDTO)
}
Expand Down Expand Up @@ -1527,6 +1542,11 @@ func (r coursesRoutes) copyCourse(c *gin.Context) {
course := tlctx.Course
streams := course.Streams

admins, err := r.DaoWrapper.CoursesDao.GetCourseAdmins(course.ID)
if err != nil {
log.WithError(err).Error("Error getting course admins")
admins = []model.User{}
}
course.Model = gorm.Model{}
course.Streams = nil
yearInt, err := strconv.Atoi(request.Year)
Expand Down Expand Up @@ -1561,6 +1581,13 @@ func (r coursesRoutes) copyCourse(c *gin.Context) {
numErrors++
}
}
for _, admin := range admins {
err := r.CoursesDao.AddAdminToCourse(admin.ID, course.ID)
if err != nil {
log.WithError(err).Error("Can't add admin to course")
numErrors++
}
}
c.JSON(http.StatusOK, gin.H{"numErrs": numErrors, "newCourse": course.ID})
}

Expand Down
48 changes: 39 additions & 9 deletions api/courses_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,12 +319,6 @@ func TestCoursesCRUD(t *testing.T) {
url := "/api/courses/users/pinned"

gomino.TestCases{
"invalid year": {
Router: CourseRouterWrapper,
Url: fmt.Sprintf("%s?year=XX&term=S", url),
Middlewares: testutils.GetMiddlewares(tools.ErrorHandler, testutils.TUMLiveContext(testutils.TUMLiveContextStudent)),
ExpectedCode: http.StatusBadRequest,
},
"not logged-in": {
Router: CourseRouterWrapper,
Middlewares: testutils.GetMiddlewares(tools.ErrorHandler, testutils.TUMLiveContext(testutils.TUMLiveContextUserNil)),
Expand All @@ -339,7 +333,7 @@ func TestCoursesCRUD(t *testing.T) {
},
}.
Method(http.MethodGet).
Url(fmt.Sprintf("%s?year=2022&term=W", url)).
Url(url).
Run(t, testutils.Equal)
})

Expand Down Expand Up @@ -415,7 +409,7 @@ func TestCoursesCRUD(t *testing.T) {
}
configGinCourseRouter(r, wrapper)
},
Middlewares: testutils.GetMiddlewares(tools.ErrorHandler, testutils.TUMLiveContext(testutils.TUMLiveContextStudent)),
Middlewares: testutils.GetMiddlewares(tools.ErrorHandler, testutils.TUMLiveContext(testutils.TUMLiveContextAdmin)),
ExpectedCode: http.StatusOK,
ExpectedResponse: response,
},
Expand Down Expand Up @@ -791,6 +785,15 @@ func TestCoursesCRUD(t *testing.T) {
CreateCourse(gomock.Any(), gomock.Any(), true).
Return(errors.New("")).
AnyTimes()
coursesMock.
EXPECT().GetCourseAdmins(testutils.CourseFPV.ID).
Return([]model.User{testutils.Admin}, nil).
MinTimes(1).MaxTimes(1)
coursesMock.
EXPECT().
AddAdminToCourse(gomock.Any(), gomock.Any()).
Return(nil).
AnyTimes()
return coursesMock
}(),
}
Expand All @@ -803,7 +806,34 @@ func TestCoursesCRUD(t *testing.T) {
"success": {
Router: func(r *gin.Engine) {
wrapper := dao.DaoWrapper{
CoursesDao: testutils.GetCoursesMock(t),
CoursesDao: func() dao.CoursesDao {
coursesMock := mock_dao.NewMockCoursesDao(gomock.NewController(t))
coursesMock.
EXPECT().
GetCourseById(gomock.Any(), testutils.CourseFPV.ID).
Return(testutils.CourseFPV, nil).
AnyTimes()
coursesMock.
EXPECT().
GetCourseBySlugYearAndTerm(gomock.Any(), testutils.CourseFPV.Slug, testutils.CourseFPV.TeachingTerm, testutils.CourseFPV.Year).
Return(testutils.CourseFPV, nil).
AnyTimes()
coursesMock.
EXPECT().
CreateCourse(gomock.Any(), gomock.Any(), true).
Return(nil).
AnyTimes()
coursesMock.
EXPECT().GetCourseAdmins(testutils.CourseFPV.ID).
Return([]model.User{testutils.Admin}, nil).
MinTimes(1).MaxTimes(1)
coursesMock.
EXPECT().
AddAdminToCourse(gomock.Any(), gomock.Any()).
Return(nil).
AnyTimes()
return coursesMock
}(),
StreamsDao: testutils.GetStreamMock(t),
}
configGinCourseRouter(r, wrapper)
Expand Down
Binary file added branding/thumb-fallback.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion dao/courses.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ func (d coursesDao) GetCourseBySlugYearAndTerm(ctx context.Context, slug string,
return db.Order("unit_start desc")
}).Preload("Streams", func(db *gorm.DB) *gorm.DB {
return db.Order("start desc")
}).Where("teaching_term = ? AND slug = ? AND year = ?", term, slug, year).First(&course).Error
}).Preload("Admins").Where("teaching_term = ? AND slug = ? AND year = ?", term, slug, year).First(&course).Error
if err == nil {
Cache.SetWithTTL(fmt.Sprintf("courseBySlugYearAndTerm%v%v%v", slug, term, year), course, 1, time.Minute)
}
Expand Down
Loading

0 comments on commit be53a16

Please sign in to comment.