예제 #1
0
파일: lab.go 프로젝트: tokams/autograder
// ApproveLabHandler is a http handler used by teachers to approve a lab.
func ApproveLabHandler(w http.ResponseWriter, r *http.Request) {
	// Checks if the user is signed in and a teacher.
	member, err := checkTeacherApproval(w, r, true)
	if err != nil {
		log.Println(err)
		return
	}

	course := r.FormValue("Course")
	username := r.FormValue("User")
	approve := r.FormValue("Approve")
	labnum, err := strconv.Atoi(r.FormValue("Labnum"))
	if err != nil {
		log.Println(err)
		http.Error(w, err.Error(), 404)
		return
	}

	if approve != "true" {
		log.Println("Missing approval")
		http.Error(w, "Not approved", 404)
		return
	}

	if !git.HasOrganization(course) || username == "" {
		log.Println("Missing username or uncorrect course")
		http.Error(w, "Unknown Organization", 404)
		return
	}

	org, err := git.NewOrganization(course, true)
	if err != nil {
		log.Println(err)
		http.Error(w, err.Error(), 404)
		return
	}

	if !org.IsTeacher(member) {
		log.Println(member.Name + " is not a teacher of " + org.Name)
		http.Error(w, "Not a teacher of this course.", 404)
		return
	}

	var isgroup bool
	if git.HasMember(username) {
		isgroup = false
	} else {
		isgroup = strings.Contains(username, "group")
		if !isgroup {
			log.Println("No user found")
			http.Error(w, "Unknown User", 404)
			return
		}
	}

	var latestbuild int
	var res *ci.BuildResult
	if isgroup {
		gnum, err := strconv.Atoi(username[len("group"):])
		if err != nil {
			log.Println(err)
			http.Error(w, err.Error(), 404)
			return
		}
		group, err := git.NewGroup(course, gnum, false)
		if err != nil {
			log.Println(err)
			http.Error(w, err.Error(), 404)
			return
		}

		defer func() {
			if err := group.Save(); err != nil {
				group.Unlock()
				log.Println(err)
			}
		}()

		latestbuild = group.GetLastBuildID(labnum)
		if latestbuild < 0 {
			http.Error(w, "No build registered on lab.", 500)
			return
		}

		res, err = ci.GetBuildResult(latestbuild)
		if err != nil {
			log.Println(err)
			http.Error(w, err.Error(), 500)
			return
		}

		group.SetApprovedBuild(res.Labnum, res.ID, res.PushTime)

		if org.Slipdays {
			for username := range group.Members {
				user, err := git.NewMemberFromUsername(username, false)
				if err != nil {
					log.Println(err)
					continue
				}

				copt := user.Courses[org.Name]
				err = copt.RecalculateSlipDays()
				if err != nil {
					log.Println(err)
				}
				user.Courses[org.Name] = copt
			}
		}
	} else {
		user, err := git.NewMemberFromUsername(username, false)
		if err != nil {
			log.Println(err.Error())
			http.Error(w, err.Error(), 500)
			return
		}

		defer func() {
			if err := user.Save(); err != nil {
				user.Unlock()
				log.Println(err)
			}
		}()

		latestbuild = user.GetLastBuildID(course, labnum)
		if latestbuild < 0 {
			http.Error(w, "No build registered on lab.", 500)
			return
		}

		res, err = ci.GetBuildResult(latestbuild)
		if err != nil {
			log.Println(err)
			http.Error(w, err.Error(), 500)
			return
		}

		user.SetApprovedBuild(org.Name, res.Labnum, res.ID, res.PushTime)

		if org.Slipdays {
			copt := user.Courses[org.Name]
			err = copt.RecalculateSlipDays()
			if err != nil {
				log.Println(err)
			}
			user.Courses[org.Name] = copt
		}
	}

	res.Status = "Approved"

	if err := res.Save(); err != nil {
		log.Println(err)
		http.Error(w, err.Error(), 500)
		return
	}
}
예제 #2
0
파일: ci.go 프로젝트: tokams/autograder
// CIResultSummaryHandler is a http handler used to get a build summary
// of the build for a user or group. This handler writes back the summary
// as JSON data.
func CIResultSummaryHandler(w http.ResponseWriter, r *http.Request) {
	// Checks if the user is signed in and a teacher.
	teacher, err := checkTeacherApproval(w, r, false)
	if err != nil {
		http.Error(w, err.Error(), 404)
		log.Println(err)
		return
	}

	orgname := r.FormValue("Course")
	username := r.FormValue("Username")

	if orgname == "" || username == "" {
		http.Error(w, "Empty request.", 404)
		return
	}

	org, err := git.NewOrganization(orgname, true)
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}

	if !org.IsTeacher(teacher) {
		http.Error(w, "Not a teacher for this course.", 404)
		return
	}

	res := make(map[string]*ci.BuildResult)
	notes := make(map[string]string)
	//credit := make(map[string]score.Score)
	//if group ...
	if strings.HasPrefix(username, git.GroupRepoPrefix) {
		groupid, err := strconv.Atoi(username[len(git.GroupRepoPrefix):])
		if err != nil {
			log.Println(err)
			http.Error(w, err.Error(), 500)
			return
		}

		group, err := git.NewGroup(orgname, groupid, true)
		if err != nil {
			log.Println(err)
			http.Error(w, err.Error(), 500)
			return
		}

		for labnum, lab := range group.Assignments {
			labname := org.GroupLabFolders[labnum]
			buildid := group.GetLastBuildID(labnum)
			if buildid < 0 {
				continue
			}

			build, err := ci.GetBuildResult(buildid)
			if err != nil {
				log.Println(err)
				continue
			}
			res[labname] = build
			notes[labname] = lab.Notes
			//credit[labname] = lab.ExtraCredit
		}
	} else {
		user, err := git.NewMemberFromUsername(username, true)
		if err != nil {
			log.Println(err)
			http.Error(w, err.Error(), 500)
			return
		}

		courseopt, ok := user.Courses[orgname]
		if ok {
			for labnum, lab := range courseopt.Assignments {
				labname := org.IndividualLabFolders[labnum]
				buildid := user.GetLastBuildID(orgname, labnum)
				if buildid < 0 {
					continue
				}

				build, err := ci.GetBuildResult(buildid)
				if err != nil {
					log.Println(err)
					continue
				}
				res[labname] = build
				notes[labname] = lab.Notes
				//credit[labname] = lab.ExtraCredit
			}
		}
	}

	view := SummaryView{
		Course:  orgname,
		User:    username,
		Summary: res,
		Notes:   notes,
		//ExtraCredit: credit,
	}

	enc := json.NewEncoder(w)

	err = enc.Encode(view)
	if err != nil {
		http.Error(w, err.Error(), 404)
	}
}
예제 #3
0
파일: ci.go 프로젝트: tokams/autograder
// CIResultListHandler returns a list of a given number of build results for a
// group or user.
// Required input:
// - Course string
// - Username string //or
// - Group int       // if Group value is higher than 0 it defaults to group selection.
// - Labnum int
// - Length int      // number of results to find, defoult 10
// - Offset int      // default 0
func CIResultListHandler(w http.ResponseWriter, r *http.Request) {
	// Checks if the user is signed in and a teacher.
	teacher, err := checkTeacherApproval(w, r, false)
	if err != nil {
		http.Error(w, err.Error(), 404)
		log.Println(err)
		return
	}

	course := r.FormValue("Course")
	username := r.FormValue("Username")
	groupid, _ := strconv.Atoi(r.FormValue("Group"))
	labnum, err := strconv.Atoi(r.FormValue("Labnum"))
	if err != nil {
		log.Println(err)
		http.Error(w, err.Error(), 404)
		return
	}
	length, err := strconv.Atoi(r.FormValue("Length"))
	if err != nil {
		length = 10
	}
	offset, _ := strconv.Atoi(r.FormValue("Offset"))

	org, err := git.NewOrganization(course, true)
	if err != nil {
		log.Println(err)
		http.Error(w, err.Error(), 500)
		return
	}

	if !org.IsTeacher(teacher) {
		log.Println(err)
		http.Error(w, "Not a teacher of this course", 404)
		return
	}

	view := CIResultListview{
		Course:   course,
		Username: username,
		Group:    groupid,
		Labnum:   labnum,
		Length:   length,
		Offset:   offset,
		Builds:   make([]*ci.BuildResult, 0),
	}

	if groupid > 0 {
		group, err := git.NewGroup(org.Name, groupid, true)
		if err != nil {
			log.Println(err)
			http.Error(w, err.Error(), 500)
			return
		}

		if group.Course != org.Name {
			log.Println(err)
			http.Error(w, "Not a group in this course", 404)
			return
		}

		if lab, ok := group.Assignments[labnum]; ok {
			buildlength := len(lab.Builds) - offset
			for i := buildlength; i > buildlength && i >= 0; i-- {
				build, err := ci.GetBuildResult(lab.Builds[i])
				if err != nil {
					log.Println(err)
					continue
				}

				view.Builds = append(view.Builds, build)
			}
		}

	} else {
		user, err := git.NewMemberFromUsername(username, true)
		if err != nil {
			log.Println(err)
			http.Error(w, err.Error(), 500)
			return
		}

		if !org.IsMember(user) {
			log.Println(err)
			http.Error(w, "Not a member of this course", 404)
			return
		}

		if courseopt, ok := user.Courses[org.Name]; ok {
			if lab, ok := courseopt.Assignments[labnum]; ok {
				buildlength := len(lab.Builds) - offset
				for i := buildlength; i > buildlength && i >= 0; i-- {
					build, err := ci.GetBuildResult(lab.Builds[i])
					if err != nil {
						log.Println(err)
						continue
					}

					view.Builds = append(view.Builds, build)
				}
			}
		}
	}

	enc := json.NewEncoder(w)
	err = enc.Encode(view)
	if err != nil {
		http.Error(w, err.Error(), 404)
	}
}
예제 #4
0
파일: ci.go 프로젝트: tokams/autograder
// CIResultHandler is a http handeler for getting results from
// a build. This handler writes back the results as JSON data.
func CIResultHandler(w http.ResponseWriter, r *http.Request) {
	// Checks if the user is signed in and a teacher.
	member, err := checkMemberApproval(w, r, false)
	if err != nil {
		http.Error(w, err.Error(), 404)
		log.Println(err)
		return
	}

	// TODO: add more security
	orgname := r.FormValue("Course")
	username := r.FormValue("Username")
	labname := r.FormValue("Labname")

	org, err := git.NewOrganization(orgname, true)
	if err != nil {
		http.Error(w, err.Error(), 500)
		return
	}

	if !org.IsMember(member) {
		http.Error(w, "Not a member for this course.", 404)
		return
	}

	var res *ci.BuildResult

	if strings.HasPrefix(username, git.GroupRepoPrefix) {
		labnum := -1
		for i, name := range org.GroupLabFolders {
			if name == labname {
				labnum = i
				break
			}
		}

		if labnum < 0 {
			http.Error(w, "No lab with that name found.", 404)
			return
		}

		groupid, err := strconv.Atoi(username[len(git.GroupRepoPrefix):])
		if err != nil {
			http.Error(w, "Could not convert the group ID.", 404)
			return
		}

		group, err := git.NewGroup(orgname, groupid, true)
		if err != nil {
			log.Println(err)
			http.Error(w, err.Error(), 404)
			return
		}

		buildid := group.GetLastBuildID(labnum)
		if buildid < 0 {
			http.Error(w, "Could not find the build.", 404)
			return
		}

		res, err = ci.GetBuildResult(buildid)
		if err != nil {
			log.Println(err)
			http.Error(w, err.Error(), 404)
			return
		}
	} else {
		labnum := -1
		for i, name := range org.IndividualLabFolders {
			if name == labname {
				labnum = i
				break
			}
		}

		if labnum < 0 {
			http.Error(w, "No lab with that name found.", 404)
			return
		}

		user, err := git.NewMemberFromUsername(username, true)
		if err != nil {
			log.Println(err)
			http.Error(w, err.Error(), 404)
			return
		}

		buildid := user.GetLastBuildID(orgname, labnum)
		if buildid < 0 {
			http.Error(w, "Could not find the build.", 404)
			return
		}

		res, err = ci.GetBuildResult(buildid)
		if err != nil {
			log.Println(err)
			http.Error(w, err.Error(), 404)
			return
		}
	}

	enc := json.NewEncoder(w)

	err = enc.Encode(res)
	if err != nil {
		http.Error(w, err.Error(), 404)
	}

}