Skip to content

Commit

Permalink
allow copying videos to other courses
Browse files Browse the repository at this point in the history
  • Loading branch information
joschahenningsen committed Jul 12, 2023
1 parent ede41ef commit f71e783
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 1 deletion.
50 changes: 50 additions & 0 deletions api/courses.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ func configGinCourseRouter(router *gin.Engine, daoWrapper dao.DaoWrapper) {
{
stream.Use(tools.InitStream(daoWrapper))
stream.GET("/transcodingProgress", routes.getTranscodingProgress)
stream.POST("/copy", routes.copyStream)
}

stats := courses.Group("/stats")
Expand Down Expand Up @@ -1516,6 +1517,55 @@ type copyCourseRequest struct {
YearW string
}

func (r coursesRoutes) copyStream(c *gin.Context) {
type req struct {
TargetCourse uint `json:"targetCourse"`
}
var request req
err := c.BindJSON(&request)
if err != nil {
_ = c.Error(tools.RequestError{Status: http.StatusBadRequest, CustomMessage: "Bad request", Err: err})
return
}
tlctx := c.MustGet("TUMLiveContext").(tools.TUMLiveContext)

targetCourseAdmins, err := r.DaoWrapper.CoursesDao.GetCourseAdmins(request.TargetCourse)
if err != nil {
log.WithError(err).Error("Error getting course admins")
_ = c.Error(tools.RequestError{
Status: http.StatusInternalServerError,
CustomMessage: "can't determine admins of target course",
Err: err,
})
}
isAdmin := false
for _, admin := range targetCourseAdmins {
if admin.ID == tlctx.User.ID {
isAdmin = true
break
}
}
if !isAdmin {
_ = c.Error(tools.RequestError{
Status: http.StatusForbidden,
CustomMessage: "you are not admin of the target course",
})
return
}

stream := tlctx.Stream
stream.Model = gorm.Model{}
stream.CourseID = request.TargetCourse
err = r.StreamsDao.CreateStream(stream)
if err != nil {
_ = c.Error(tools.RequestError{
Status: http.StatusInternalServerError,
CustomMessage: "Can't save stream",
Err: err,
})
}
}

func (r coursesRoutes) copyCourse(c *gin.Context) {
var request copyCourseRequest
err := c.BindJSON(&request)
Expand Down
1 change: 1 addition & 0 deletions model/stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ func (s Stream) getJson(lhs []LectureHall, course Course) gin.H {
"courseSlug": course.Slug,
"private": s.Private,
"downloadableVods": s.GetVodFiles(),
"isCopying": false,
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,10 @@
:class="lecture.private?'text-gray-400 dark:hover:text-gray-500 hover:text-gray-300':'text-red-400 dark:hover:text-red-500 hover:text-red-300'">
Make private
</button>
<button class="block w-full px-4 py-2 text-left text-sm text-gray-400 dark:hover:text-gray-500 hover:text-gray-300"
@click="lecture.isCopying = true; closeMoreDropdown()">
Move/Copy to other course
</button>
</div>
<template x-if="lecture.seriesIdentifier.length > 0">
<div class="border-t border-black">
Expand All @@ -217,7 +221,7 @@
</div>
</div>

<button x-show="lecture.uiEditMode == 0"
<button x-show="lecture.uiEditMode == 0 && !lecture.isCopying"
@click="lecture.startSingleEdit(); closeMoreDropdown();"
class="bg-gray-100 dark:bg-gray-900 w-full py-2 mt-2 rounded-b">
<span class="text-gray-700 dark:text-gray-300">Edit Lecture</span>
Expand Down Expand Up @@ -451,5 +455,53 @@
</div>
</div>
</div>

<template x-if="lecture.isCopying">
<form class="p-4" x-data="{move: false, selected: -1, success: undefined}"
@submit.prevent="fetch(`/api/course/${lecture.courseId}/stream/${lecture.lectureId}/copy`,
{method: 'POST', body: JSON.stringify({targetCourse: selected})}).then(r=>{success=r.ok})">
<div x-show="success===undefined">
<div class="w-full grid grid-cols-2">
<button @click="move=false" class="w-full py-2 mt-2 rounded" :class="!move && 'bg-indigo-500/70'" type="button">
<span class="text-gray-700 dark:text-gray-300">Copy</span>
</button>
<button @click="move=true" class="w-full py-2 mt-2 rounded" :class="move && 'bg-indigo-500/70'" type="button">
<span class="text-gray-700 dark:text-gray-300">Move</span>
</button>
</div>
<span class="text-3 mt-3">Select target course:</span>
<div class="flex flex-col m-2 mb-4">
{{range $c := $user.AdministeredCourses}}
{{if ne $c.ID $course.ID}}
<label class="w-full">
<input name="targetcourse" type="radio" @click="selected={{$c.ID}}">
<span>
{{$c.Name}}
<span class="font-semibold">{{$c.Year}} | {{$c.TeachingTerm}}</span>
</span>
</label>
{{end}}
{{end}}
</div>
<button @click="lecture.isCopying = false"
type="button"
class="px-8 py-3 text-2 text-white rounded bg-indigo-500/70 hover:bg-indigo-500/90 dark:bg-indigo-500/10 disabled:opacity-20 dark:hover:bg-indigo-500/20 mr-4">
Cancel
</button>

<button type="submit"
class="px-8 py-3 text-2 text-white rounded bg-indigo-500/70 hover:bg-indigo-500/90 dark:bg-indigo-500/10 disabled:opacity-20 dark:hover:bg-indigo-500/20 mr-4"
:disabled="selected === -1">
Done
</button>
</div>
<div x-show="success===true">
<span class="text-success font-semibold">Lecture copied successfully.</span>
</div>
<div x-show="success===false">
<span class="text-red-500 font-semibold">Lecture could not be copied!</span>
</div>
</form>
</template>
</li>
{{end}}

0 comments on commit f71e783

Please sign in to comment.