public ActionResult Search(CoursesViewModel vm) { vm = BuildCoursesViewModel(vm); if (vm.SelectedCourse > 0) { Course toJoin = Db.Courses.Where(c => c.Id == vm.SelectedCourse).FirstOrDefault(); if (toJoin != null) { CourseUserRelationship cur = new CourseUserRelationship() { CourseId = toJoin.Id, UserId = CurrentUser.Id, Role = CourseRole.Student, IsApproved = !toJoin.RequiresApprovalBeforeAdmission, IsActive = true }; Db.CourseUserRelationships.Add(cur); Db.SaveChanges(); if (toJoin.RequiresApprovalBeforeAdmission == true) { vm.ServerMessage = string.Format("A request to join {0} has been sent to the course instructor. Until then, certain features related to the course may be unavailable.", toJoin.Name); } else { vm.ServerMessage = string.Format("You are now enrolled in {0}.", toJoin.Name); } } else { vm.ServerMessage = "There server experienced an error when trying to add you to the selected course. Please try again. If the problem persists, please contact [email protected]."; } } return(View(vm)); }
public ActionResult CreateAssignment(Assignment vm) { //make sure that assignment creation is allowed CourseUserRelationship relationship = Db.CourseUserRelationships .Where(cr => cr.CourseId == vm.CourseId) .Where(cr => cr.UserId == CurrentUser.Id) .FirstOrDefault(); if (relationship != null) { if (relationship.Role == CourseRole.Coordinator) { vm.IsDeleted = false; //Adjust to UTC vm.DueDate = vm.DueDate.AddMinutes(vm.UtcOffsetMinutes); vm.ReleaseDate = vm.ReleaseDate.AddMinutes(vm.UtcOffsetMinutes); //AC note: I'm not using ModelState.IsValid because it's flagging the non-mapped ReleaseTime/DueTime as invalid. //As such, there's potential for the db insert to go bad. Thus, the try/catch. try { Db.Assignments.Add(vm); Db.SaveChanges(); } catch (Exception) { } } } return(RedirectToAction("Details", new { id = vm.CourseId })); }
/// <summary> /// Deletes the supplied file from a course's "CourseDocs" section. /// </summary> /// <param name="id"></param> /// <param name="file"></param> /// <returns></returns> public ActionResult DeleteCourseFile(int id, string file) { Course course = Db.Courses.Where(a => a.Id == id).FirstOrDefault(); if (course == null) { //course not found return(RedirectToAction("MyCourses")); } //can the user delete files? CourseUserRelationship relationship = course.CourseUserRelationships.Where(cu => cu.UserId == CurrentUser.Id).FirstOrDefault(); if (relationship != null) { if (relationship.Role == CourseRole.Coordinator) { //it's okay to delete files FileSystem fs = new FileSystem(); FileCollection collection = fs.Course(course).CourseDocs().File(file); collection.Delete(); } } return(RedirectToAction("Details", new { id = course.Id })); }
/// <summary> /// Deletes the specified from from the specified assignment /// </summary> /// <param name="id">The ID of the assignment that the file is attached to</param> /// <param name="file"></param> /// <returns></returns> public ActionResult DeleteAssignmentFile(int id, string file) { Assignment assignment = Db.Assignments.Where(a => a.Id == id).FirstOrDefault(); if (assignment == null) { //assignment not found return(RedirectToAction("MyCourses")); } //can the user delete files? CourseUserRelationship relationship = assignment.Course.CourseUserRelationships.Where(cu => cu.UserId == CurrentUser.Id).FirstOrDefault(); if (relationship != null) { if (relationship.Role == CourseRole.Coordinator) { //it's okay to delete files FileSystem fs = new FileSystem(); FileCollection collection = fs.Course(assignment.CourseId).Assignment(assignment).Attachments().File(file); collection.Delete(); } } return(RedirectToAction("Details", new { id = assignment.CourseId })); }
/// <summary> /// Takes a full gradebook table and parses the table down to rows that have a leading "#" (indicating they are "global" rows) /// and columns that do not have a leading "!" (indiciating they are not to be shown). Additionally, the row that corrisponds to the current user /// (indicated by identification number in the StudentID column) will be included. /// </summary> /// <param name="gradebookTable"></param> /// <returns></returns> private List <List <string> > ParseStudentTable(CourseUserRelationship courseUser, List <List <string> > gradebookTable) { List <List <string> > studentTable = new List <List <string> >(); List <int> studentGlobalRows = new List <int>(); if (gradebookTable.Count > 0) { int IdColumn = 0; //?? //find which rows should be displayed for (int i = 0; i < gradebookTable.Count; i++) { //If its student's grade row, add it. int studentId = -1; Int32.TryParse(gradebookTable[i][IdColumn], out studentId); if (studentId == courseUser.User.InstitutionId) { studentTable.Add(gradebookTable[i].ToList()); } //Add global rows (denoted by a leading '#'). else if (gradebookTable[i][0].Length > 0 && gradebookTable[i][0][0] == '#') { studentTable.Add(gradebookTable[i].ToList()); studentGlobalRows.Add(studentTable.Count - 1); } } ViewBag.GlobalRows = studentGlobalRows; //Iterating over studentTable to find columns that should not be displayed (denoted by leading '!') List <int> columnsToRemove = new List <int>(); for (int i = 0; i < studentTable.Count; i++) { for (int j = 0; j < studentTable[i].Count; j++) { if (studentTable[i][j].Length > 0 && studentTable[i][j][0] == '!') { columnsToRemove.Add(j); } } } //removing columns that were marked with a '!'. //Removing them in from highest index to lowest index so that indicies are not messed up upon first removal columnsToRemove.Sort(); for (int i = columnsToRemove.Count() - 1; i >= 0; i--) { int currentStudentTableLength = studentTable.Count; for (int j = 0; j < currentStudentTableLength; j++) { studentTable[j].RemoveAt(columnsToRemove[i]); } } } return(studentTable); }
/// <summary> /// Deletes a given assignment from the system /// </summary> /// <param name="id"></param> /// <returns></returns> public ActionResult DeleteAssignment(int id) { Assignment some_assignment = Db.Assignments.Where(a => a.Id == id).FirstOrDefault(); if (some_assignment != null) { //make sure the current user is a course coordinator CourseUserRelationship relationship = some_assignment.Course.CourseUserRelationships.Where(c => c.UserId == CurrentUser.Id).FirstOrDefault(); if (relationship != null) { if (relationship.Role == CourseRole.Coordinator) { some_assignment.IsDeleted = true; Db.SaveChanges(); return(RedirectToAction("Details", new { id = some_assignment.CourseId })); } } } return(RedirectToAction("MyCourses")); }
// // GET: /Courses/ public ActionResult Index() { //try to find default course int courseId = CurrentUser.DefaultCourseId; if (courseId <= 0) { CourseUserRelationship cur = CurrentUser.CourseUserRelationships.FirstOrDefault(); if (cur != null) { courseId = cur.CourseId; return(RedirectToAction("Details", new { id = courseId })); } } else { return(RedirectToAction("Details", new { id = courseId })); } //no course found, redirect return(RedirectToAction("NoCourses")); }
/// <summary> /// Removes a student from a course /// </summary> /// <param name="courseId"></param> /// <param name="vm"></param> private void RemoveUserFromCourse(int courseId, EditProfileViewModel vm) { //set last active pane vm.LastActivePane = 2; CourseUserRelationship toRemove = Db.CourseUserRelationships .Where(c => c.CourseId == courseId) .Where(c => c.UserId == CurrentUser.Id) .FirstOrDefault(); List <CourseUserRelationship> allRelationships = Db.CourseUserRelationships.Where(cur => cur.UserId == CurrentUser.Id).ToList(); //does the current user only have one course? if (allRelationships.Count() <= 1) { vm.RemoveCourseMessage = "You must always be enrolled in at least one course. To remove this course, please first add an additional course."; } else { //ELSE: user has at least two courses if (toRemove != null) { //is the course being removed the current default course? if (CurrentUser.DefaultCourseId == toRemove.CourseId) { //switch default course to another course CourseUserRelationship other = allRelationships.Where(cur => cur.CourseId != toRemove.CourseId).FirstOrDefault(); CurrentUser.DefaultCourseId = other.CourseId; } vm.RemoveCourseMessage = string.Format("You have been removed from {0}.", toRemove.Course.Name); Db.Entry(toRemove).State = System.Data.Entity.EntityState.Deleted; Db.SaveChanges(); } else { vm.RemoveCourseMessage = "An error occurred when I attempted to remove you from the course. Please try again. If the problem persists, please contact support at \"[email protected]\"."; } } }
public ActionResult Index(int courseId = -1, string gradebookName = null) { //default to user's default course if (courseId <= 0) { courseId = CurrentUser.DefaultCourseId; } Course currentCourse = Db.Courses.Where(c => c.Id == courseId).FirstOrDefault(); CourseUserRelationship courseRelationship = Db.CourseUserRelationships .Where(cur => cur.CourseId == currentCourse.Id) .Where(cur => cur.UserId == CurrentUser.Id) .FirstOrDefault(); //Get the GradebookFilePath for current course FileSystem fs = new FileSystem(); GradebookFilePath gfp = fs.Course(courseId).Gradebook(); //get last upload time DirectoryInfo directoryInfo = new DirectoryInfo(gfp.GetPath()); DateTime lastUpload = directoryInfo.LastWriteTime; //Generating list of Gradebook tabs List <string> TabNames = new List <string>(); foreach (string temp in gfp.AllFiles()) { TabNames.Add(Path.GetFileNameWithoutExtension(temp)); } //Selecting which gradebook will be loaded. If gradebookName is null, then select the first tab bool gradeBookExists = true; if (gradebookName == null) { if (TabNames.Count > 0) { gradebookName = TabNames[0]; } else { gradeBookExists = false; } } //If gradebook exists, set up certain viewbags ViewBag.GradeBookExists = gradeBookExists; if (gradeBookExists) { try { SetUpViewBagForGradebook(courseRelationship, gradebookName); ViewBag.SelectedTab = gradebookName; ViewBag.TabNames = TabNames; } catch (Exception) { gradeBookExists = false; ViewBag.TabNames = new List <string>(); ViewBag.SelectedTab = ""; ViewBag.TableData = new List <List <string> >(); ViewBag.GradeBookExists = false; } } //Setup viewbags based on usertype if (courseRelationship.Role == CourseRole.Coordinator) { //Setting instructor/Ta specific viewbags ViewBag.CanUpload = true; //TODO: Implement error messages ////Grabbing error message then wiping it. //if (Cache["UploadErrorMessage"] != null) //{ // ViewBag.UploadErrorMsg = Cache["UploadErrorMessage"]; // Cache["UploadErrorMessage"] = ""; //} } else { //Setting student specific ViewBags ViewBag.CanUpload = false; } if (gradeBookExists) { ViewBag.LastUploadMessage = "Last updated " + lastUpload.ToShortDateString().ToString() + " " + lastUpload.ToShortTimeString().ToString() + "(UTC)"; } else if (courseRelationship.Role == CourseRole.Coordinator) { //If user is an instructor and there is currnetly no gradebook, then change upload message ViewBag.LastUploadMessage = "Upload Gradebook File"; //Generate additional upload fail messages. } ViewBag.CurrentCourseId = courseId; ViewBag.EnrolledCourses = Db.CourseUserRelationships.Where(cur => cur.UserId == CurrentUser.Id).Select(cur => cur.Course).ToList(); return(View()); }
/// <summary> /// Sets up ViewBags for the given gradebookName. The assumption made in this function is that the StudentID number is in /// column 0. /// </summary> /// <param name="gradebookName"></param> private void SetUpViewBagForGradebook(CourseUserRelationship courseUser, string gradebookName) { //Get the GradebookFilePath for current course, then the FileCollection for the given gradebookName FileSystem fs = new FileSystem(); GradebookFilePath gfp = fs.Course(courseUser.CourseId).Gradebook(); FileCollection gradebook = gfp.File(gradebookName + ".csv");; //Getting the filePath, which is the filename in the file collction string filePath = gradebook.FirstOrDefault(); //Open the file as a FileStream. For this, we want to wrap it in a try/catch block, as others might be attempting to use this stream //at the same time. We'll allow it attempt to open the stream for up to maxTime. FileStream stream = null; TimeSpan interval = new TimeSpan(0, 0, 0, 0, 50); TimeSpan totalTime = new TimeSpan(); TimeSpan maxTime = new TimeSpan(0, 0, 0, 4, 0); //4second max wait before giving up while (stream == null) { try { //Get the stream related to the current file stream = new FileStream(filePath, FileMode.Open); } catch (IOException ex) { Thread.Sleep(interval); totalTime += interval; //if we've waited longer than maxTime, throw the original exception if (totalTime > maxTime) { throw ex; } } } //reading the file into a List of List of strings using CSVReader. List <List <string> > table = new List <List <string> >(); CsvReader csvReader = new CsvReader(stream); table = csvReader.Parse(); stream.Close(); //close the stream to allow others to access it. //If the user is NOT an instructor or TA, then only display them rows that match their UserProfileID. if (courseUser.Role == CourseRole.Student) { table = ParseStudentTable(courseUser, table); } else { List <int> globalRows = new List <int>(); List <int> hiddenColumns = new List <int>(); //find which rows should be displayed as "globals" for (int i = 0; i < table.Count; i++) { //Add global rows (denoted by a leading '#'). if (table[i][0].Length > 0 && table[i][0][0] == '#') { globalRows.Add(i); for (int j = 0; j < table[i].Count; j++) //go through each cell in global row and check for hidden column values { if (table[i][j].Length > 2 && table[i][j][0] == '!' && table[i][j][1] == '!') { hiddenColumns.Add(j); } } } } ViewBag.Instructor_ColumnsToHide = hiddenColumns; ViewBag.NameColumnIndex = 1; //AC: ?? ViewBag.GlobalRows = globalRows; } ViewBag.TableData = table; }
public ActionResult UploadGradebook(HttpPostedFileBase file, int courseId = -1) { //default to user's default course if (courseId <= 0) { courseId = CurrentUser.DefaultCourseId; } Course currentCourse = Db.Courses.Where(c => c.Id == courseId).FirstOrDefault(); CourseUserRelationship courseRelationship = Db.CourseUserRelationships .Where(cur => cur.CourseId == currentCourse.Id) .Where(cur => cur.UserId == CurrentUser.Id) .FirstOrDefault(); //Get the GradebookFilePath for current course FileSystem fs = new FileSystem(); GradebookFilePath gfp = fs.Course(courseId).Gradebook(); //delete old items in gradebook int filesInGradebookFolder = gfp.AllFiles().Count; int filesDeleted = 0; TimeSpan interval = new TimeSpan(0, 0, 0, 0, 50); TimeSpan totalTime = new TimeSpan(); TimeSpan maxTime = new TimeSpan(0, 0, 0, 6, 0); //4second max wait before giving up while (filesInGradebookFolder != filesDeleted) { filesDeleted += gfp.AllFiles().Delete(); if (filesInGradebookFolder != filesDeleted) { Thread.Sleep(interval); totalTime += interval; } if (totalTime > maxTime) { throw new Exception("Failed to delete all gradebook files, try again later");; } } int filesFailedToLoadCount = 0; //integer used for error message //Add new item(s) based on file extension. if (file == null) { //No file. Meaning 1 file failed to load. filesFailedToLoadCount++; } else if (Path.GetExtension(file.FileName) == ".zip") { using (MemoryStream zipStream = new MemoryStream()) { file.InputStream.CopyTo(zipStream); zipStream.Position = 0; filesFailedToLoadCount += UploadGradebookZip(zipStream.ToArray(), gfp); } } else if (Path.GetExtension(file.FileName) == ".csv") { //we have a .csv. Simply add it into the Gradebook directory gfp.AddFile(Path.GetFileName(file.FileName), file.InputStream); } else { //file wasnt csv or zip. Meaning 1 file failed to load. filesFailedToLoadCount++; } //Generate error message. if (filesFailedToLoadCount > 0) { if (filesFailedToLoadCount == 1) { UserCache["UploadErrorMessage"] = filesFailedToLoadCount.ToString() + " file during upload was not of .csv file type, upload may have failed."; } else if (filesFailedToLoadCount > 1) { UserCache["UploadErrorMessage"] = filesFailedToLoadCount.ToString() + " files during upload were not of .csv file type, upload may have failed."; } } return(RedirectToAction("Index")); }