console

package
v0.0.0-...-4ba9c06 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 26, 2019 License: GPL-3.0 Imports: 23 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var AdminAddCmd = &cobra.Command{
	Use:   "add [userID]",
	Short: "set gives an user global admin permission",
	Long: `Will set the gobal root flag to "true" for a given user
 bypassing all permission tests`,
	Args: cobra.ExactArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		userID := MustInt64Parameter(args[0], "userID")

		_, stores := MustConnectAndStores()

		user, err := stores.User.Get(userID)
		if err != nil {
			log.Fatalf("user with id %v not found\n", userID)
		}

		user.Root = true
		if err := stores.User.Update(user); err != nil {
			panic(err)
		}

		fmt.Printf("The user %s %s (id:%v) has now global admin privileges\n",
			user.FirstName, user.LastName, user.ID)
	},
}
View Source
var AdminCmd = &cobra.Command{
	Use:   "admin",
	Short: "Management of global admins.",
}
View Source
var AdminRemoveCmd = &cobra.Command{
	Use:   "remove [userID]",
	Short: "removes global admin permission from a user",
	Long:  `Will set the gobal root flag to false for a user `,
	Args:  cobra.ExactArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		userID := MustInt64Parameter(args[0], "userID")

		_, stores := MustConnectAndStores()

		user, err := stores.User.Get(userID)
		if err != nil {
			log.Fatalf("user with id %v not found\n", userID)
		}
		user.Root = false
		if err := stores.User.Update(user); err != nil {
			panic(err)
		}

		fmt.Printf("user %s %s (%v) is not an admin anymore\n", user.FirstName, user.LastName, user.ID)

	},
}
View Source
var CourseCmd = &cobra.Command{
	Use:   "course",
	Short: "Management of cours assignment",
}
View Source
var DatabaseBackupCmd = &cobra.Command{
	Use:   "backup [file.sql.gz]",
	Short: "backup database to a file",
	Long:  `Will dump the entire database to a snapshot file`,
	Args:  cobra.ExactArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		file := args[0]

		if helper.FileExists(file) {
			log.Fatalf("The file %s does exists! Will not override!\n", file)
		}

		infoMap := parseConnectionString(viper.GetString("database_connection"))

		shell1 := exec.Command("pg_dump",
			"-h", infoMap["host"],
			"-U", infoMap["user"],
			"-p", infoMap["port"],
			"-d", infoMap["dbname"])
		shell1.Env = os.Environ()
		shell1.Env = append(shell1.Env, fmt.Sprintf("PGPASSWORD=%s", infoMap["password"]))

		shell2 := exec.Command("gzip")

		r, w := io.Pipe()
		shell1.Stdout = w
		shell2.Stdin = r

		var b2 bytes.Buffer
		shell2.Stdout = &b2

		shell1.Start()
		shell2.Start()
		shell1.Wait()
		w.Close()
		err := shell2.Wait()
		if err != nil {
			panic(err)
		}

		destination, err := os.Create(file)
		if err != nil {
			panic(err)
		}
		defer destination.Close()
		_, err = io.Copy(destination, &b2)
		if err != nil {
			log.Fatalf("storing snapshot was not successfull\n %s", err)
		}

	},
}
View Source
var DatabaseCmd = &cobra.Command{
	Use:   "database",
	Short: "Management of database.",
}
View Source
var DatabaseRestoreCmd = &cobra.Command{
	Use:   "restore [file.sql.gz]",
	Short: "restore database from a file",
	Long:  `Will clean entire database and load a snapshot`,
	Args:  cobra.ExactArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		file := args[0]

		if !helper.FileExists(file) {
			log.Fatalf("The file %s does not exists!\n", file)
		}

		infoMap := parseConnectionString(viper.GetString("database_connection"))

		shell := exec.Command("dropdb",
			"-h", infoMap["host"],
			"-U", infoMap["user"],
			"-p", infoMap["port"],
			infoMap["dbname"])
		shell.Env = os.Environ()
		shell.Env = append(shell.Env, fmt.Sprintf("PGPASSWORD=%s", infoMap["password"]))
		out, err := shell.CombinedOutput()
		fmt.Printf("%s", out)
		if err != nil {
			log.Fatal("dropping db was not successfull")
		}

		shell = exec.Command("createdb",
			"-h", infoMap["host"],
			"-U", infoMap["user"],
			"-p", infoMap["port"],
			"--owner", infoMap["user"],
			infoMap["dbname"])
		shell.Env = os.Environ()
		shell.Env = append(shell.Env, fmt.Sprintf("PGPASSWORD=%s", infoMap["password"]))
		out, err = shell.CombinedOutput()
		fmt.Printf("%s", out)
		if err != nil {
			log.Fatal("creating db was not successfull")
		}

		shell1 := exec.Command("gunzip",
			"-c", file)
		shell2 := exec.Command("psql",
			"-h", infoMap["host"],
			"-U", infoMap["user"],
			"-p", infoMap["port"],
			infoMap["dbname"])
		shell2.Env = os.Environ()
		shell2.Env = append(shell2.Env, fmt.Sprintf("PGPASSWORD=%s", infoMap["password"]))

		r, w := io.Pipe()
		shell1.Stdout = w
		shell2.Stdin = r

		var b2 bytes.Buffer
		shell2.Stdout = &b2

		shell1.Start()
		shell2.Start()
		shell1.Wait()
		w.Close()
		err = shell2.Wait()

		if err != nil {
			log.Fatalf("load db from was not successfull\n %s", err)
		}
	},
}
View Source
var DatabaseRunCmd = &cobra.Command{
	Use:   "run [sql]",
	Short: "run a sql command",
	Long:  `run a SQl statement. This statement will persistently changes entries!`,
	Args:  cobra.ExactArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		sql := args[0]

		infoMap := parseConnectionString(viper.GetString("database_connection"))

		shell := exec.Command("psql",
			"-h", infoMap["host"],
			"-U", infoMap["user"],
			"-p", infoMap["port"],
			"-d", infoMap["dbname"],
			"-c", sql)
		shell.Env = os.Environ()
		shell.Env = append(shell.Env, fmt.Sprintf("PGPASSWORD=%s", infoMap["password"]))
		out, err := shell.CombinedOutput()
		fmt.Printf("%s", out)
		if err != nil {
			log.Fatal("executing SQL-statement was not successfull")
		}

	},
}
View Source
var GroupCmd = &cobra.Command{
	Use:   "group",
	Short: "Management of groups",
}
View Source
var GroupEnroll = &cobra.Command{
	Use:   "enroll [groupID] [userID]",
	Short: "enroll a student to a group",
	Long: `enroll a student to a group or update enrollment if student is
already enrolled in another group`,
	Args: cobra.ExactArgs(2),
	Run: func(cmd *cobra.Command, args []string) {
		groupID := MustInt64Parameter(args[0], "groupID")
		userID := MustInt64Parameter(args[1], "userID")

		_, stores := MustConnectAndStores()

		user, err := stores.User.Get(userID)
		failWhenSmallestWhiff(err)

		course, err := stores.Group.IdentifyCourseOfGroup(groupID)
		failWhenSmallestWhiff(err)

		enrollment, err := stores.Group.GetGroupEnrollmentOfUserInCourse(userID, course.ID)

		if err != nil {

			enrollment := &model.GroupEnrollment{
				UserID:  userID,
				GroupID: groupID,
			}

			_, err := stores.Group.CreateGroupEnrollmentOfUserInCourse(enrollment)
			failWhenSmallestWhiff(err)

		} else {
			group, err := stores.Group.Get(enrollment.GroupID)
			failWhenSmallestWhiff(err)

			fmt.Printf("user %s %s (id: %v) was    enrolled in group (%v) %s\n",
				user.FirstName,
				user.LastName,
				user.ID,
				group.ID, group.Description)

			enrollment.GroupID = groupID
			err = stores.Group.ChangeGroupEnrollmentOfUserInCourse(enrollment)
			failWhenSmallestWhiff(err)

		}

		group, err := stores.Group.Get(groupID)
		failWhenSmallestWhiff(err)

		fmt.Printf("user %s %s (id: %v) is now enrolled in group (%v) %s\n",
			user.FirstName,
			user.LastName,
			user.ID,
			group.ID, group.Description)

	},
}
View Source
var GroupList = &cobra.Command{
	Use:   "list [courseID]",
	Short: "list all groups from a specific course",
	Long: `shows information about exercise groups with their description and
number of assigned students`,
	Args: cobra.ExactArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		courseID := MustInt64Parameter(args[0], "courseID")

		db, _ := MustConnectAndStores()

		groupSummaries := []groupSummary{}

		err := db.Select(&groupSummaries, `
SELECT
  count(*), ug.group_id, g.description
FROM
  user_group ug
INNER JOIN groups g ON g.id = ug.group_id
WHERE
  g.course_id = $1
GROUP BY
  ug.group_id, g.description
ORDER BY g.description
    `, courseID)
		failWhenSmallestWhiff(err)

		fmt.Printf("count   groupID    description\n")
		for k, v := range groupSummaries {
			fmt.Printf("%5d  %7d   %s\n", v.Count, v.GroupID, v.Description)
			if k%5 == 0 {
				fmt.Println("")
			}
		}
	},
}
View Source
var GroupLocate = &cobra.Command{
	Use:   "locate [courseID] [userID]",
	Short: "locate a student in a group",
	Long:  `show the exercise group for a given student`,
	Args:  cobra.ExactArgs(2),
	Run: func(cmd *cobra.Command, args []string) {
		courseID := MustInt64Parameter(args[0], "courseID")
		userID := MustInt64Parameter(args[1], "userID")

		_, stores := MustConnectAndStores()

		user, err := stores.User.Get(userID)
		if err != nil {
			log.Fatalf("user with id %v not found\n", userID)
		}

		course, err := stores.Course.Get(courseID)
		if err != nil {
			log.Fatalf("course with id %v not found\n", courseID)
		}

		groups, err := stores.Group.GetInCourseWithUser(user.ID, course.ID)
		failWhenSmallestWhiff(err)

		if len(groups) == 0 {
			log.Fatalf("user %s %s (%d) is not enrolled as a student in course %s (%d)",
				user.FirstName, user.LastName, user.ID, course.Name, course.ID)
		}

		group := groups[0]

		fmt.Printf("found\n")
		fmt.Printf(" - Group (%d):   %s\n", group.ID, group.Description)
		fmt.Printf(" - Tutor (%d):   %s %s\n", group.TutorID, group.TutorFirstName, group.TutorLastName)
		fmt.Printf(" - Student (%d): %s %s \n", user.ID, user.FirstName, user.LastName)

	},
}
View Source
var GroupParseBidsSolution = &cobra.Command{

	Use:   "import-assignments [courseID] [file]",
	Short: "parse solution and assign students to groups",
	Long:  `for assignment`,
	Args:  cobra.ExactArgs(2),
	Run: func(cmd *cobra.Command, args []string) {

		type Assignment struct {
			GroupID int64
			UserID  int64
		}

		courseID := MustInt64Parameter(args[0], "courseID")

		db, stores := MustConnectAndStores()

		course, err := stores.Course.Get(courseID)
		if err != nil {
			log.Fatalf("course with id %v not found\n", course.ID)
		}
		fmt.Println("work on course", course.ID)

		file, err := os.Open(args[1])
		failWhenSmallestWhiff(err)
		defer file.Close()

		reader := bufio.NewReader(file)
		uids := []int64{}
		assignments := []Assignment{}
		for {
			line, _, err := reader.ReadLine()
			if err == io.EOF {
				break
			}

			string := fmt.Sprintf("%s", line)
			if strings.HasPrefix(string, "assign[") {
				parts := strings.Split(string, "[")
				parts = strings.Split(parts[1], "]")
				parts = strings.Split(parts[0], ",")

				v, err := strconv.Atoi(parts[0][1:])
				failWhenSmallestWhiff(err)
				w, err := strconv.Atoi(parts[1][1:])
				failWhenSmallestWhiff(err)

				assignments = append(assignments, Assignment{GroupID: int64(w), UserID: int64(v)})
				uids = append(uids, int64(v))
			}

		}

		tx, err := db.Begin()
		failWhenSmallestWhiff(err)

		_, err = tx.Exec(`
DELETE FROM
  user_group ug
USING
  groups g
WHERE
  ug.group_id = g.id
AND
  g.course_id = $1
AND
  ug.user_id = ANY($2)`, course.ID, pq.Array(uids))
		if err != nil {
			fmt.Println(err)
			tx.Rollback()
			failWhenSmallestWhiff(err)
		}

		for _, assignment := range assignments {
			fmt.Printf("%v %v\n", assignment.UserID, assignment.GroupID)

			_, err = tx.Exec("INSERT INTO user_group (id,user_id,group_id) VALUES (DEFAULT,$1,$2);", assignment.UserID, assignment.GroupID)
			if err != nil {
				tx.Rollback()
				failWhenSmallestWhiff(err)
			}
		}

		err = tx.Commit()
		if err != nil {
			tx.Rollback()
			failWhenSmallestWhiff(err)
		}

		fmt.Println("Done")

	},
}
View Source
var GroupReadBids = &cobra.Command{
	Use:   "dump-bids [courseID] [file]  [min_per_group] [max_per_group]",
	Short: "export group-bids of all users in a course",
	Long:  `for assignment`,
	Args:  cobra.ExactArgs(4),
	Run: func(cmd *cobra.Command, args []string) {

		courseID := MustInt64Parameter(args[0], "courseID")
		minPerGroup := MustIntParameter(args[2], "minPerGroup")
		maxPerGroup := MustIntParameter(args[3], "maxPerGroup")

		if minPerGroup > maxPerGroup {
			log.Fatalf("minPerGroup %d > maxPerGroup %d is infeasible",
				minPerGroup, maxPerGroup)
		}

		fmt.Printf("bound Group Capacitiy >= %v\n", minPerGroup)
		fmt.Printf("bound Group Capacitiy <= %v\n", maxPerGroup)

		f, err := os.Create(fmt.Sprintf("%s.dat", args[1]))
		failWhenSmallestWhiff(err)
		defer f.Close()

		db, stores := MustConnectAndStores()

		course, err := stores.Course.Get(courseID)
		if err != nil {
			log.Fatalf("course with id %v not found\n", course.ID)
		}

		groups, err := stores.Group.GroupsOfCourse(course.ID)
		failWhenSmallestWhiff(err)

		fmt.Printf("found %v groups\n", len(groups))

		groupIDArray := []int64{}
		for _, group := range groups {
			groupIDArray = append(groupIDArray, group.ID)
		}

		gids := strings.Trim(strings.Replace(fmt.Sprint(groupIDArray), " ", " g", -1), "[]")

		students, err := stores.Course.EnrolledUsers(course.ID,
			[]string{"0"},
			"%%",
			"%%",
			"%%",
			"%%",
			"%%",
		)
		failWhenSmallestWhiff(err)

		fmt.Printf("found %v students\n", len(students))
		fmt.Printf("\n")
		fmt.Printf("\n")

		uids := ""
		for _, student := range students {
			g := strconv.FormatInt(student.ID, 10)
			uids = uids + " u" + g
		}

		f.WriteString(fmt.Sprintf("set group := g%s;\n", gids))
		f.WriteString(fmt.Sprintf("set student := %s;\n", uids))
		f.WriteString(fmt.Sprintf("\n"))
		f.WriteString(fmt.Sprintf("param pref:\n"))
		f.WriteString(fmt.Sprintf("     g%s:=\n", gids))

		for _, student := range students {
			uid := strconv.FormatInt(student.ID, 10)
			bids := []model.GroupBid{}

			err := db.Select(&bids, `
SELECT
  *
FROM
  group_bids
WHERE
  user_id = $1
AND
  group_id = ANY($2)
ORDER BY
  group_id ASC`, student.ID, pq.Array(groupIDArray))
			if err != nil {
				panic(err)
			}

			f.WriteString(fmt.Sprintf("u%s", uid))

			for _, group := range groups {
				bidValue := 10
				for _, bid := range bids {
					if bid.GroupID == group.ID {
						bidValue = bid.Bid
						break
					}
				}
				f.WriteString(fmt.Sprintf(" %v", bidValue))
			}
			f.WriteString(fmt.Sprintf("\n"))
		}

		f.WriteString(fmt.Sprintf(";\n"))
		f.WriteString(fmt.Sprintf("\n"))
		f.WriteString(fmt.Sprintf("end;\n"))

		fmod, err := os.Create(fmt.Sprintf("%s.mod", args[1]))
		failWhenSmallestWhiff(err)
		defer fmod.Close()

		fmod.WriteString(fmt.Sprintf("set student;\n"))
		fmod.WriteString(fmt.Sprintf("set group;\n"))
		fmod.WriteString(fmt.Sprintf("\n"))
		fmod.WriteString(fmt.Sprintf("var assign{i in student, j in group} binary;\n"))
		fmod.WriteString(fmt.Sprintf("param pref{i in student, j in group};\n"))
		fmod.WriteString(fmt.Sprintf("\n"))
		fmod.WriteString(fmt.Sprintf("maximize totalPref:\n"))
		fmod.WriteString(fmt.Sprintf("    sum{i in student, j in group} pref[i,j]*assign[i,j];\n"))
		fmod.WriteString(fmt.Sprintf("\n"))
		fmod.WriteString(fmt.Sprintf("subject to exactly_one_group {i in student}:\n"))
		fmod.WriteString(fmt.Sprintf("    sum {j in group} assign[i,j] =1;\n"))
		fmod.WriteString(fmt.Sprintf("\n"))
		fmod.WriteString(fmt.Sprintf("subject to min3{j in group}:\n"))
		fmod.WriteString(fmt.Sprintf("    sum{i in student} assign[i,j]>=%v;\n", minPerGroup))
		fmod.WriteString(fmt.Sprintf("\n"))
		fmod.WriteString(fmt.Sprintf("subject to max4{j in group}:\n"))
		fmod.WriteString(fmt.Sprintf("    sum{i in student} assign[i,j]<=%v;\n", maxPerGroup))
		fmod.WriteString(fmt.Sprintf("\n"))
		fmod.WriteString(fmt.Sprintf("end;\n"))
		fmod.WriteString(fmt.Sprintf("\n"))
		fmod.WriteString(fmt.Sprintf("\n"))

		fmt.Println("run the command")
		fmt.Println("")
		fmt.Println("")
		fmt.Printf("sudo docker run -v \"$PWD\":/data -it patwie/symphony  /var/symphony/bin/symphony -F %s.mod -D /data/%s.dat -f /data/%s.par\n", args[1], args[1], args[1])
		fmt.Println("")

		fpar, err := os.Create(fmt.Sprintf("%s.par", args[1]))
		failWhenSmallestWhiff(err)
		fpar.WriteString(fmt.Sprintf("time_limit 50\n"))
		fpar.WriteString(fmt.Sprintf("\n"))
		defer fpar.Close()

	},
}
View Source
var GroupUserBids = &cobra.Command{
	Use:   "bids [courseID] [userID]",
	Short: "list all bids of a user",
	Args:  cobra.ExactArgs(2),
	Run: func(cmd *cobra.Command, args []string) {
		courseID := MustInt64Parameter(args[0], "courseID")
		userID := MustInt64Parameter(args[1], "userID")

		db, stores := MustConnectAndStores()

		user, err := stores.User.Get(userID)
		if err != nil {
			log.Fatalf("user with id %v not found\n", userID)
		}

		course, err := stores.Course.Get(courseID)
		if err != nil {
			log.Fatalf("course with id %v not found\n", courseID)
		}

		userBidSummaries := []userBidSummary{}

		err = db.Select(&userBidSummaries, `
SELECT
  bid, group_id, description
FROM
  group_bids gb
INNER JOIN groups g ON gb.group_id = g.id
WHERE
  gb.user_id = $1
AND
  g.course_id = $2
    `, user.ID, course.ID)
		failWhenSmallestWhiff(err)

		fmt.Printf("  bid   groupID    description\n")
		for k, v := range userBidSummaries {
			fmt.Printf("%5d  %7d   %s\n", v.Bid, v.GroupID, v.Description)
			if k%5 == 0 && k > 0 {
				fmt.Println("")
			}
		}

	},
}
View Source
var SubmissionCmd = &cobra.Command{
	Use:   "submission",
	Short: "Management of submission",
}
View Source
var SubmissionRunCmd = &cobra.Command{
	Use:   "run [submissionID]",
	Short: "run tests for a submission without writing to db",
	Long:  `will enqueue a submission again into the testing queue`,
	Args:  cobra.ExactArgs(1),
	Run: func(cmd *cobra.Command, args []string) {

		submissionID := MustInt64Parameter(args[0], "submissionID")

		_, stores := MustConnectAndStores()

		submission, err := stores.Submission.Get(submissionID)
		failWhenSmallestWhiff(err)

		task, err := stores.Task.Get(submission.TaskID)
		failWhenSmallestWhiff(err)

		log.Println("try starting docker...")

		ds := service.NewDockerService()
		defer ds.Client.Close()

		var exit int64
		var stdout string

		submissionHnd := helper.NewSubmissionFileHandle(submission.ID)
		if !submissionHnd.Exists() {
			log.Fatalf("submission file %s for id %v is missing", submissionHnd.Path(), submission.ID)
		}

		if task.PublicDockerImage.Valid {
			frameworkHnd := helper.NewPublicTestFileHandle(task.ID)
			if frameworkHnd.Exists() {

				log.Printf("use docker image \"%v\"\n", task.PublicDockerImage.String)
				log.Printf("use framework file \"%v\"\n", frameworkHnd.Path())
				stdout, exit, err = ds.Run(
					task.PublicDockerImage.String,
					submissionHnd.Path(),
					frameworkHnd.Path(),
					viper.GetInt64("worker_docker_memory_bytes"),
				)
				if err != nil {
					log.Fatal(err)
				}

				fmt.Println(" --- STDOUT -- BEGIN ---")
				fmt.Println(stdout)
				fmt.Println(" --- STDOUT -- END   ---")
				fmt.Printf("exit-code: %v\n", exit)
			} else {
				fmt.Println("skip public test, there is no framework file")

			}

		} else {
			fmt.Println("skip public test, there is no docker file")
		}

		if task.PrivateDockerImage.Valid {
			frameworkHnd := helper.NewPrivateTestFileHandle(task.ID)
			if frameworkHnd.Exists() {

				log.Printf("use docker image \"%v\"\n", task.PrivateDockerImage.String)
				log.Printf("use framework file \"%v\"\n", frameworkHnd.Path())
				stdout, exit, err = ds.Run(
					task.PrivateDockerImage.String,
					submissionHnd.Path(),
					frameworkHnd.Path(),
					viper.GetInt64("worker_docker_memory_bytes"),
				)
				if err != nil {
					log.Fatal(err)
				}

				fmt.Println(" --- STDOUT -- BEGIN ---")
				fmt.Println(stdout)
				fmt.Println(" --- STDOUT -- END   ---")
				fmt.Printf("exit-code: %v\n", exit)
			} else {
				fmt.Println("skip private test, there is no framework file")

			}

		} else {
			fmt.Println("skip private test, there is no docker file")
		}

	},
}
View Source
var SubmissionTriggerAllCmd = &cobra.Command{
	Use:   "trigger_all [taskID] [kind]",
	Short: "trigger_all tests all submissions for a given task",
	Long: `Will enqueue all submissions for a given task again into the testing queue
This triggers all [kind]-tests again (private, public).
`,
	Args: cobra.ExactArgs(2),
	Run: func(cmd *cobra.Command, args []string) {

		taskID := MustInt64Parameter(args[0], "taskID")

		switch args[1] {
		case "public", "private":
		default:
			log.Fatalf("kind '%s' must be one of 'public', 'private'\n", args[2])
		}

		db, stores := MustConnectAndStores()

		task, err := stores.Task.Get(taskID)
		failWhenSmallestWhiff(err)

		sheet, err := stores.Task.IdentifySheetOfTask(task.ID)
		failWhenSmallestWhiff(err)

		course, err := stores.Sheet.IdentifyCourseOfSheet(sheet.ID)
		failWhenSmallestWhiff(err)

		log.Println("starting producer...")

		cfg := &service.Config{
			Connection:   viper.GetString("rabbitmq_connection"),
			Exchange:     "infomark-worker-exchange",
			ExchangeType: "direct",
			Queue:        "infomark-worker-submissions",
			Key:          viper.GetString("rabbitmq_key"),
			Tag:          "SimpleSubmission",
		}

		submissions := []SubmissionWithGradeID{}
		err = db.Select(&submissions, `
SELECT
  s.*, g.id grade_id
FROM
  submissions s
INNER JOIN grades g ON s.id = g.submission_ID
WHERE task_id = $1
    `, task.ID)
		failWhenSmallestWhiff(err)

		producer, _ := service.NewProducer(cfg)
		logger := logrus.New()
		logger.SetFormatter(&logrus.TextFormatter{
			DisableColors: false,
			FullTimestamp: true,
		})
		logger.Out = os.Stdout

		for _, submissionWithGrade := range submissions {
			sublog := logger.WithFields(logrus.Fields{"submissionID": submissionWithGrade.ID})

			sublog.Info("Try to enqueue")

			submissionHnd := helper.NewSubmissionFileHandle(submissionWithGrade.ID)
			if !submissionHnd.Exists() {
				sublog.Warn("uploaded file does not exists --> skip")
			}

			sha256, err := helper.NewSubmissionFileHandle(submissionWithGrade.ID).Sha256()
			if err != nil {
				sublog.Warn("Skip as sha cannot be computed")
			}

			tokenManager, err := authenticate.NewTokenAuth()
			failWhenSmallestWhiff(err)
			accessToken, err := tokenManager.CreateAccessJWT(
				authenticate.NewAccessClaims(1, true))
			failWhenSmallestWhiff(err)

			var (
				body []byte
				merr error
			)

			if args[1] == "public" {
				body, merr = json.Marshal(shared.NewSubmissionAMQPWorkerRequest(
					course.ID, taskID, submissionWithGrade.ID, submissionWithGrade.GradeID,
					accessToken, viper.GetString("url"), task.PublicDockerImage.String, sha256, "public"))

			} else {
				body, merr = json.Marshal(shared.NewSubmissionAMQPWorkerRequest(
					course.ID, taskID, submissionWithGrade.ID, submissionWithGrade.GradeID,
					accessToken, viper.GetString("url"), task.PrivateDockerImage.String, sha256, "private"))
			}
			if merr != nil {
				log.Fatalf("json.Marshal: %s", merr)
			}

			producer.Publish(body)

		}

	},
}
View Source
var SubmissionTriggerCmd = &cobra.Command{
	Use:   "trigger [submissionID]",
	Short: "put submission into testing queue",
	Long:  `will enqueue a submission again into the testing queue`,
	Args:  cobra.ExactArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		submissionID := MustInt64Parameter(args[0], "submissionID")

		_, stores := MustConnectAndStores()

		submission, err := stores.Submission.Get(submissionID)
		failWhenSmallestWhiff(err)

		task, err := stores.Task.Get(submission.TaskID)
		failWhenSmallestWhiff(err)

		sheet, err := stores.Task.IdentifySheetOfTask(submission.TaskID)
		failWhenSmallestWhiff(err)

		course, err := stores.Sheet.IdentifyCourseOfSheet(sheet.ID)
		failWhenSmallestWhiff(err)

		grade, err := stores.Grade.GetForSubmission(submission.ID)
		failWhenSmallestWhiff(err)

		log.Println("starting producer...")

		cfg := &service.Config{
			Connection:   viper.GetString("rabbitmq_connection"),
			Exchange:     "infomark-worker-exchange",
			ExchangeType: "direct",
			Queue:        "infomark-worker-submissions",
			Key:          viper.GetString("rabbitmq_key"),
			Tag:          "SimpleSubmission",
		}

		sha256, err := helper.NewSubmissionFileHandle(submission.ID).Sha256()
		failWhenSmallestWhiff(err)

		tokenManager, err := authenticate.NewTokenAuth()
		failWhenSmallestWhiff(err)
		accessToken, err := tokenManager.CreateAccessJWT(
			authenticate.NewAccessClaims(1, true))
		failWhenSmallestWhiff(err)

		bodyPublic, err := json.Marshal(shared.NewSubmissionAMQPWorkerRequest(
			course.ID, task.ID, submission.ID, grade.ID,
			accessToken, viper.GetString("url"), task.PublicDockerImage.String, sha256, "public"))
		if err != nil {
			log.Fatalf("json.Marshal: %s", err)
		}

		bodyPrivate, err := json.Marshal(shared.NewSubmissionAMQPWorkerRequest(
			course.ID, task.ID, submission.ID, grade.ID,
			accessToken, viper.GetString("url"), task.PrivateDockerImage.String, sha256, "private"))
		if err != nil {
			log.Fatalf("json.Marshal: %s", err)
		}

		producer, _ := service.NewProducer(cfg)
		producer.Publish(bodyPublic)
		producer.Publish(bodyPrivate)

	},
}
View Source
var UserCmd = &cobra.Command{
	Use:   "user",
	Short: "Management of users",
}
View Source
var UserConfirmCmd = &cobra.Command{
	Use:   "confirm [email]",
	Short: "confirms the email address manually",
	Long:  `Will run confirmation procedure for an user `,
	Args:  cobra.ExactArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		_, stores := MustConnectAndStores()

		email := args[0]
		if err := is.Email.Validate(email); err != nil {
			log.Fatalf("email '%s' is not a valid email\n", email)
		}

		user, err := stores.User.FindByEmail(email)
		if err != nil {
			log.Fatalf("user with email %v not found\n", email)
		}

		user.ConfirmEmailToken = null.String{}
		if err := stores.User.Update(user); err != nil {
			panic(err)
		}

		fmt.Printf("email %s of user %s %s has been confirmed\n",
			email, user.FirstName, user.LastName)
	},
}
View Source
var UserEnrollInCourse = &cobra.Command{
	Use:   "enroll [courseID] [userID] [role]",
	Short: "will enroll a user into course",
	Args:  cobra.ExactArgs(3),
	Run: func(cmd *cobra.Command, args []string) {
		var err error

		courseID := MustInt64Parameter(args[0], "courseID")
		userID := MustInt64Parameter(args[1], "userID")

		role := int64(0)
		switch args[2] {
		case "admin":
			role = int64(2)
		case "tutor":
			role = int64(1)
		case "student":
			role = int64(0)
		default:
			log.Fatalf("role '%s' must be one of 'student', 'tutor', 'admin'\n", args[2])
		}

		_, stores := MustConnectAndStores()

		user, err := stores.User.Get(userID)
		if err != nil {
			log.Fatalf("user with id %v not found\n", userID)
		}

		course, err := stores.Course.Get(courseID)
		if err != nil {
			log.Fatalf("user with id %v not found\n", userID)
		}

		if err := stores.Course.Enroll(course.ID, user.ID, role); err != nil {
			panic(err)
		}

		fmt.Printf("user %s %s is now enrolled in course %v with role %v\n",
			user.FirstName, user.LastName, course.ID, role)
	},
}
View Source
var UserFindCmd = &cobra.Command{
	Use:   "find [query]",
	Short: "find user by first_name, last_name or email",
	Long:  `List all users matching the query`,
	Args:  cobra.ExactArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		db, _ := MustConnectAndStores()

		query := fmt.Sprintf("%%%s%%", args[0])

		users := []model.User{}
		err := db.Select(&users, `
SELECT
  *
FROM
  users
WHERE
 last_name LIKE $1
OR
 first_name LIKE $1
OR
 email LIKE $1`, query)
		failWhenSmallestWhiff(err)

		fmt.Printf("found %v users matching %s\n", len(users), query)
		for k, user := range users {
			fmt.Printf("%4d %20s %20s %50s\n",
				user.ID, user.FirstName, user.LastName, user.Email)
			if k%10 == 0 && k != 0 {
				fmt.Println("")
			}
		}

		fmt.Printf("found %v users matching %s\n", len(users), query)
	},
}
View Source
var UserSetEmailCmd = &cobra.Command{
	Use:   "set-email [userID] [email]",
	Short: "will alter the email address",
	Long:  `Will change email address of an user without confirmation procedure`,
	Args:  cobra.ExactArgs(2),
	Run: func(cmd *cobra.Command, args []string) {
		userID := MustInt64Parameter(args[0], "userID")
		email := args[1]
		if err := is.Email.Validate(email); err != nil {
			log.Fatalf("email '%s' is not a valid email\n", email)
		}

		_, stores := MustConnectAndStores()

		user, err := stores.User.Get(userID)
		if err != nil {
			fmt.Printf("user with id %v not found\n", userID)
			return
		}

		user.Email = email
		if err := stores.User.Update(user); err != nil {
			panic(err)
		}

		fmt.Printf("email of user %s %s is now %s\n",
			user.FirstName, user.LastName, user.Email)
	},
}

Functions

func ConnectAndStores

func ConnectAndStores() (*sqlx.DB, *app.Stores, error)

func MustConnectAndStores

func MustConnectAndStores() (*sqlx.DB, *app.Stores)

func MustInt64Parameter

func MustInt64Parameter(argStr string, name string) int64

func MustIntParameter

func MustIntParameter(argStr string, name string) int

Types

type SubmissionWithGradeID

type SubmissionWithGradeID struct {
	*model.Submission
	GradeID int64 `db:"grade_id"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL