Ejemplo n.º 1
0
        public async Task ValidateAsync(Models.Contents.Activity activity, Models.Entities.Lecture lecture, Models.Entities.User user,
                                        Action <bool?, bool, string> doneCallback = null)
        {
            try
            {
                var assign = DatabaseService.Context.LectureUsers.Include(x => x.User).Include(x => x.Lecture).ThenInclude(x => x.Owner).Where(x => x.UserId == user.Id && x.LectureId == lecture.Id).FirstOrDefault();
                if (assign == null)
                {
                    doneCallback(null, false, "The user is not assigned");
                }

                var sandbox = DatabaseService.Context.LectureSandboxes.Where(x => x.Name == activity.Sandbox && x.LectureId == lecture.Id).FirstOrDefault();
                if (sandbox == null)
                {
                    doneCallback(null, false, "Not found sandbox");
                }

                var time = DateTime.Now;
                foreach (var f in activity.GetChildRenderFragments().Select(x => x.Item1))
                {
                    var fileInfo = new FileInfo($"{user.DirectoryPath}/lecture_data/{lecture.Owner.Account}/{lecture.Name}/home/{activity.Directory}/{f.Name}");
                    if (!fileInfo.Directory.Exists)
                    {
                        fileInfo.Directory.Create();
                        Process.Start("chown", $"-R {user.Id + 1000}:{user.Id + 1000} {user.DirectoryPath}/l{lecture.Owner.Account}/ecture_data/{lecture.Name}/home").WaitForExit();
                    }

                    if (activity.GetFileComponents().ContainsKey(f.Name))
                    {
                        Process.Start("rm", $"-R {fileInfo.FullName}").WaitForExit();
                        if (activity.GetFileComponents()[f.Name] is UploadActivityComponent uac)
                        {
                            if (uac.Data != null)
                            {
                                using (var w = new FileStream(fileInfo.FullName, FileMode.Create, FileAccess.Write))
                                {
                                    w.Write(uac.Data, 0, uac.Data.Length);
                                }
                            }
                        }
                        else
                        {
                            using (var w = new StreamWriter(fileInfo.FullName))
                            {
                                w.Write(await activity.GetFileComponents()[f.Name].GetValueAsync());
                            }
                        }

                        if (!fileInfo.Exists)
                        {
                            doneCallback(null, false, "Failure to save. Please retry.");
                            return;
                        }
                        Process.Start("chown", $" {user.Id + 1000}:{user.Id + 1000} {fileInfo.FullName}").WaitForExit();
                        // Process.Start("chown", $"-R {user.Id + 1000}:{user.Id + 1000} {user.DirectoryPath}/lecture_data/{lecture.Owner.Account}/{lecture.Name}/home").WaitForExit();
                        Console.WriteLine($"DEBUG_LOG: SAVE FILE BEFORE VALIDATION {fileInfo.FullName}");
                        if (activity.GetFileComponents()[f.Name] is UploadActivityComponent uac2 && uac2.Data != null)
                        {
                            uac2.SetSavedFileInfo(fileInfo);
                        }
                    }
                }

                assign.RepositoryPair.ClonedRepository.CommitChanges($"[Activity] Name=\"{activity.Name}\" Action=\"Save before Validate\" DateTime=\"{time.ToString("yyyy-MM-ddTHH:mm:sszzz")}\"", user.DisplayName, user.EmailAddress);
                assign.RepositoryPair.ClonedRepository.Push();

                Queue.QueueBackgroundWorkItem(async token =>
                {
                    var accept = await(activity.Validations.Child as ALMS.App.Models.Contents.IValidatable).ValidateAsync(async validation =>
                    {
                        if (string.IsNullOrWhiteSpace(validation.Run))
                        {
                            return(false);
                        }
                        var command = $"cd ~/{activity.Directory}; {validation.Run}";
                        var stdout  = new System.Text.StringBuilder();
                        var stderr  = new System.Text.StringBuilder();
                        await sandbox.DoOnSandboxAsync(user.Account, command,
                                                       data => { stdout.AppendLine(data); }, data => { stderr.AppendLine(data); }, null, activity.Limits);

                        if (validation.Type.ToLower() == "equals")
                        {
                            return(stdout.ToString().Trim() == validation.Answer.Trim());
                        }
                        return(false);
                    });

                    try
                    {
                        assign.RepositoryPair.ClonedRepository.CommitChanges($"[Activity] Name=\"{activity.Name}\" Action=\"Validate\" DateTime=\"{time.ToString("yyyy-MM-ddTHH:mm:sszzz")}\"", user.DisplayName, user.EmailAddress);
                        assign.RepositoryPair.ClonedRepository.Push();

                        DatabaseService.Context.ActivityActionHistories.Add(new Models.Entities.ActivityActionHistory()
                        {
                            User         = user,
                            Lecture      = lecture,
                            ActivityName = activity.Name,
                            Directory    = activity.Directory,
                            ActionType   = accept ? Models.Entities.ActivityActionType.SaveAndValidateAccept : Models.Entities.ActivityActionType.SaveAndValidateReject,
                            DateTime     = time
                        });
                        DatabaseService.Context.SaveChanges();
                        doneCallback(accept, true, "Validate successfully");
                    }
                    catch (Exception e)
                    {
                        doneCallback(null, false, e.Message);
                    }
                }, user.IsTeacher(lecture));
            }
            catch (Exception e)
            {
                doneCallback(null, false, e.Message);
            }
        }
Ejemplo n.º 2
0
        public async Task SubmitAsync(Models.Contents.Activity activity, Models.Entities.Lecture lecture, Models.Entities.User user,
                                      Action <int?, bool, string> doneCallback = null)
        {
            try
            {
                var assign = DatabaseService.Context.LectureUsers.Include(x => x.User).Include(x => x.Lecture).ThenInclude(x => x.Owner).Where(x => x.UserId == user.Id && x.LectureId == lecture.Id).FirstOrDefault();
                if (assign == null)
                {
                    doneCallback(null, false, "The user is not assigned"); return;
                }
                var time = DateTime.Now;

                foreach (var f in activity.GetChildRenderFragments().Select(x => x.Item1))
                {
                    var fileInfo = new FileInfo($"{user.DirectoryPath}/lecture_data/{lecture.Owner.Account}/{lecture.Name}/home/{activity.Directory}/{f.Name}");
                    if (!fileInfo.Directory.Exists)
                    {
                        fileInfo.Directory.Create();
                        Process.Start("chown", $"-R {user.Id + 1000}:{user.Id + 1000} {user.DirectoryPath}/lecture_data/{lecture.Owner.Account}/{lecture.Name}/home").WaitForExit();
                    }

                    if (activity.GetFileComponents().ContainsKey(f.Name))
                    {
                        Process.Start("rm", $"-R {fileInfo.FullName}").WaitForExit();
                        if (activity.GetFileComponents()[f.Name] is UploadActivityComponent uac)
                        {
                            if (uac.Data != null)
                            {
                                using (var w = new FileStream(fileInfo.FullName, FileMode.Create, FileAccess.Write))
                                {
                                    w.Write(uac.Data, 0, uac.Data.Length);
                                }
                            }
                        }
                        else
                        {
                            using (var w = new StreamWriter(fileInfo.FullName))
                            {
                                w.Write(await activity.GetFileComponents()[f.Name].GetValueAsync());
                            }
                        }
                        if (!fileInfo.Exists)
                        {
                            doneCallback(null, false, "Failure to submit. Please retry.");
                            return;
                        }
                        Process.Start("chown", $" {user.Id + 1000}:{user.Id + 1000} {fileInfo.FullName}").WaitForExit();
                        // Process.Start("chown", $"-R {user.Id + 1000}:{user.Id + 1000} {user.DirectoryPath}/lecture_data/{lecture.Owner.Account}/{lecture.Name}/home").WaitForExit();
                        Console.WriteLine($"DEBUG_LOG: SAVE FILE BEFORE SUBMIT {fileInfo.FullName}");
                        if (activity.GetFileComponents()[f.Name] is UploadActivityComponent uac2 && uac2.Data != null)
                        {
                            uac2.SetSavedFileInfo(fileInfo);
                        }
                    }
                }

                // Check certainly saved
                //foreach (var f in activity.GetChildRenderFragments().Select(x => x.Item1))
                //{
                //    var fileInfo = new FileInfo($"{user.DirectoryPath}/lecture_data/{lecture.Owner.Account}/{lecture.Name}/home/{activity.Directory}/{f.Name}");
                //    if (!fileInfo.Exists)
                //    {
                //        doneCallback(null, false, "Failure to save. Please retry.");
                //        return;
                //    }
                //}

                assign.RepositoryPair.ClonedRepository.CommitChanges($"[Activity] Name=\"{activity.Name}\" Action=\"Save before Submit\" DateTime=\"{time.ToString("yyyy-MM-ddTHH:mm:sszzz")}\"", user.DisplayName, user.EmailAddress);
                assign.RepositoryPair.ClonedRepository.Push();


                var submit_file = new FileInfo($"{user.DirectoryPath}/lecture_data/{lecture.Owner.Account}/{lecture.Name}/home/{activity.Directory}/SUBMIT");
                var command     = $"cd ~/{activity.Directory}; {activity.Submit}";
                Queue.QueueBackgroundWorkItem(async token =>
                {
                    try
                    {
                        if (!string.IsNullOrWhiteSpace(activity.Submit))
                        {
                            var sandbox = DatabaseService.Context.LectureSandboxes.Where(x => x.Name == activity.Sandbox && x.LectureId == lecture.Id).FirstOrDefault();
                            if (sandbox == null)
                            {
                                doneCallback(null, false, "Not found sandbox"); return;
                            }

                            var sb = new System.Text.StringBuilder();
                            await sandbox.DoOnSandboxWithCmdAsync(user, command, (stdout) => { sb.AppendLine(stdout); }, null, null, (code) =>
                            {
                                using (var w = new StreamWriter(submit_file.FullName))
                                {
                                    w.Write(sb.ToString());
                                }
                            });
                            if (!submit_file.Exists)
                            {
                                doneCallback(null, false, "Failure to submit. Please retry.");
                                return;
                            }

                            assign.RepositoryPair.ClonedRepository.CommitChanges($"[Activity] Name=\"{activity.Name}\" Action=\"Save Submit Summary\" DateTime=\"{time.ToString("yyyy-MM-ddTHH:mm:sszzz")}\"", user.DisplayName, user.EmailAddress);
                            assign.RepositoryPair.ClonedRepository.Push();
                        }


                        foreach (var f in activity.GetChildRenderFragments().Select(x => x.Item1))
                        {
                            var fileInfo = new FileInfo($"{lecture.DirectoryPath}/submissions/{user.Account}/{activity.Name}/{f.Name}");
                            if (!fileInfo.Directory.Exists)
                            {
                                fileInfo.Directory.Create();
                            }

                            if (activity.GetFileComponents().ContainsKey(f.Name))
                            {
                                if (activity.GetFileComponents()[f.Name] is UploadActivityComponent uac)
                                {
                                    if (uac.Data != null)
                                    {
                                        using (var w = new FileStream(fileInfo.FullName, FileMode.Create, FileAccess.Write))
                                        {
                                            w.Write(uac.Data, 0, uac.Data.Length);
                                        }
                                    }
                                }
                                else
                                {
                                    using (var w = new StreamWriter(fileInfo.FullName))
                                    {
                                        w.Write(await activity.GetFileComponents()[f.Name].GetValueAsync());
                                    }
                                }
                            }
                            Console.WriteLine($"DEBUG_LOG: SAVE FILE OF SUBMISSION {fileInfo.FullName}");
                            if (!fileInfo.Exists)
                            {
                                doneCallback(null, false, "Failure to submit. Please retry.");
                                return;
                            }
                            if (activity.GetFileComponents()[f.Name] is UploadActivityComponent uac2 && uac2.Data != null)
                            {
                                uac2.SetSubmittedFileInfo(fileInfo);
                            }
                        }


                        if (!string.IsNullOrWhiteSpace(activity.Submit))
                        {
                            var source = new FileInfo($"{user.DirectoryPath}/lecture_data/{lecture.Owner.Account}/{lecture.Name}/home/{activity.Directory}/SUBMIT");
                            var target = new FileInfo($"{lecture.DirectoryPath}/submissions/{user.Account}/{activity.Name}/SUBMIT");
                            File.Copy(source.FullName, target.FullName, true);
                            if (!target.Exists)
                            {
                                doneCallback(null, false, "Failure to submit. Please retry.");
                                return;
                            }
                        }

                        lecture.LectureSubmissionsRepositoryPair.ClonedRepository.CommitChanges($"[Activity] Name=\"{activity.Name}\" Action=\"Submit\" DateTime=\"{time.ToString("yyyy-MM-ddTHH:mm:sszzz")}\"", user.DisplayName, user.EmailAddress);
                        lecture.LectureSubmissionsRepositoryPair.ClonedRepository.Push();

                        DatabaseService.Context.ActivityActionHistories.Add(new Models.Entities.ActivityActionHistory()
                        {
                            User         = user,
                            Lecture      = lecture,
                            ActivityName = activity.Name,
                            Directory    = activity.Directory,
                            ActionType   = Models.Entities.ActivityActionType.SaveAndSubmit,
                            DateTime     = time
                        });
                        DatabaseService.Context.SaveChanges();
                        doneCallback(null, true, "Files were submitted successfully");
                    }
                    catch
                    {
                        doneCallback(null, false, "Failure to submit. Please retry.");
                        return;
                    }
                }, user.IsTeacher(lecture));
            }
            catch (Exception e)
            {
                doneCallback(null, false, e.Message);
            }
        }