static public void UpdateDiscussionEvent(DiscussionSetting ds, Event dEvent, int ActiveCourseUserId, ContextBase db) { //Link to assignment details. Note, since this is hardcoded to osble.org, it will not work locally. UrlHelper u = new UrlHelper(System.Web.HttpContext.Current.Request.RequestContext); dEvent.Description = "[url:Assignment Page|" + u.Action("Index", "Home", new { assignmentId = ds.AssignmentID, area = "AssignmentDetails" }, System.Web.HttpContext.Current.Request.Url.Scheme) + "]"; //dEvent.Description = "[url:Assignment Page|plus.osble.org/AssignmentDetails/" + ds.AssignmentID + "]"; dEvent.EndDate = null; dEvent.StartDate = ds.InitialPostDueDate; dEvent.StartTime = ds.InitialPostDueDueTime; dEvent.PosterID = ActiveCourseUserId; dEvent.Title = ds.Assignment.AssignmentName + " Initial Post(s) Due"; dEvent.Approved = true; if (dEvent.ID == 0) { db.Events.Add(dEvent); db.SaveChanges(); } ds.AssociatedEventID = dEvent.ID; db.Entry(ds).State = System.Data.EntityState.Modified; db.Entry(dEvent).State = System.Data.EntityState.Modified; db.SaveChanges(); }
/// <summary> /// Returns a boolean indicating if an Reviewer's name should be anonymized. /// </summary> /// <param name="CRAssignment">Critical Review Assignment</param> /// <param name="authorTeam">The Team of reviewers</param> /// <param name="discussionSettings">Critical Review Discussion's discussion settings. (if applicable)</param> /// <returns></returns> private bool AnonymizeReviewer(Assignment CRAssignment, Team reviewTeam, DiscussionSetting discussionSettings = null) { //MG: reviewers are to be anonymous if any of the criteria are met: //From DiscsussionSettings: //ActiveCurrentUser is a Moderator and Students are anonymous to Moderators. (Could occur when a moderator is downloading files from a CRD) //ActiveCurrentUser is a Student and Students are anonymous to Students. //From CriticalReviewSettings: //AnonymizeCommentsCommentsAfterPublish && Critical Review Assignment is published && AcitveCourseUser is not on Review Team //Anonymizecomments && Critical REview Assignment is not published && AcitveCourseUser is not on Review Team bool anonymize = false; //Instructors and TAs should never have anonymous reviewers. if (ActiveCourseUser.AbstractRoleID == (int)CourseRole.CourseRoles.Instructor || ActiveCourseUser.AbstractRoleID == (int)CourseRole.CourseRoles.TA) { return(false); } //Discussion Settings check if (discussionSettings != null) { if (ActiveCourseUser.AbstractRoleID == (int)CourseRole.CourseRoles.Student && discussionSettings.HasAnonymousStudentsToStudents) { anonymize = true; } else if (ActiveCourseUser.AbstractRoleID == (int)CourseRole.CourseRoles.Moderator && discussionSettings.HasAnonymousStudentsToModerators) { anonymize = true; } } //Critical Review settings check if (CRAssignment.CriticalReviewSettings != null) { bool onTeam = reviewTeam.TeamMembers.Where(tm => tm.CourseUserID == ActiveCourseUser.ID).Count() > 0; //comments are made by reviewers, so anonymize comments translates to anonymizing reviewers. //Only considering anonymization if user is not on the review team. if (onTeam == false && CRAssignment.CriticalReviewSettings.AnonymizeCommentsAfterPublish && CRAssignment.IsCriticalReviewPublished == true) { anonymize = true; } else if (onTeam == false && CRAssignment.CriticalReviewSettings.AnonymizeComments && CRAssignment.IsCriticalReviewPublished == false) { anonymize = true; } } return(anonymize); }
/// <summary> /// Returns a boolean indicating if an Author's name should be anonymized. /// </summary> /// <param name="CRAssignment">Critical Review Assignment</param> /// <param name="authorTeam">The Team of authors</param> /// <param name="discussionSettings">Critical Review Discussion's discussion settings. (if applicable)</param> /// <returns></returns> private bool AnonymizeAuthor(Assignment CRAssignment, Team authorTeam, DiscussionSetting discussionSettings = null) { //MG:authors are to be anonymous if any of the criteria are met: //From DiscsussionSettings: //ActiveCurrentUser is a Moderator and Students are anonymous to Moderators. (Could occur when a moderator is downloading files from a CRD) //ActiveCurrentUser is a Student and Students are anonymous to Students. //From CriticalReviewSettings: //AnonymizeAuthor && ActiveCourseUser is not on Author team bool anonymize = false; //Instructors and TAs should never have anonymous authors. if (ActiveCourseUser.AbstractRoleID == (int)CourseRole.CourseRoles.Instructor || ActiveCourseUser.AbstractRoleID == (int)CourseRole.CourseRoles.TA) { return(false); } //Discussion Settings check if (discussionSettings != null) { if (ActiveCourseUser.AbstractRoleID == (int)CourseRole.CourseRoles.Student && discussionSettings.HasAnonymousStudentsToStudents) { anonymize = true; } else if (ActiveCourseUser.AbstractRoleID == (int)CourseRole.CourseRoles.Moderator && discussionSettings.HasAnonymousStudentsToModerators) { anonymize = true; } } //Critical Review settings check if (CRAssignment.CriticalReviewSettings != null && CRAssignment.CriticalReviewSettings.AnonymizeAuthor) { //Check if ActiveCourseUser is part of AuthorTeam. If not, anonymize. bool onTeam = authorTeam.TeamMembers.Where(tm => tm.CourseUserID == ActiveCourseUser.ID).Count() > 0; if (onTeam == false) { anonymize = true; } } return(anonymize); }
public ActionResult Index(DiscussionSetting model) { Assignment = db.Assignments.Find(model.AssignmentID); if (ModelState.IsValid) { //delete preexisting settings to prevent an FK relation issue DiscussionSetting setting = db.DiscussionSettings.Find(model.AssignmentID); Event eventToUpdate = null; if (setting != null) { eventToUpdate = setting.AssociatedEvent; db.DiscussionSettings.Remove(setting); } db.SaveChanges(); //...and then re-add it. Assignment.DiscussionSettings = model; db.SaveChanges(); //account for local client time, reset to UTC CourseController cc = new CourseController(); var course = ActiveCourseUser.AbstractCourse as Course; if (course != null) { //get the timezone of the course int utcOffset = course.TimeZoneOffset; TimeZoneInfo tz = cc.getTimeZone(utcOffset); Assignment.DiscussionSettings.InitialPostDueDate = TimeZoneInfo.ConvertTimeToUtc(Assignment.DiscussionSettings.InitialPostDueDate, tz); db.SaveChanges(); WasUpdateSuccessful = true; } else { WasUpdateSuccessful = false; } if (Assignment.IsDraft == false) { //If the assignment is published, that means there was an associted event, but was deleted when DiscussionSettings was removed //Re-adding event EventController.UpdateDiscussionEvent(Assignment.DiscussionSettings, eventToUpdate, ActiveCourseUser.ID, db); } //If TAs are allowed to post to all discussion, //remove them from any discussion teams they may have already been assigned to if (model.TAsCanPostToAllDiscussions == true) { foreach (DiscussionTeam dt in Assignment.DiscussionTeams) { List <TeamMember> tmsToRemove = new List <TeamMember>(); foreach (TeamMember tm in dt.Team.TeamMembers.Where(tm => tm.CourseUser.AbstractRoleID == (int)CourseRole.CourseRoles.TA)) { tmsToRemove.Add(tm); } foreach (TeamMember tm in tmsToRemove) { dt.Team.TeamMembers.Remove(tm); } } } } else { WasUpdateSuccessful = false; } return(base.PostBack(Assignment.DiscussionSettings)); }
/// <summary> /// Gets all the reviewed documents that belong to AuthorTeam. This function is used by other FileHandler function /// </summary> /// <param name="CRAssignment">The critical review assignment to fetch documents from</param> /// <param name="authorTeam">The Team that was reviewed</param> /// <param name="zipFileName">The Team that was reviewed</param> /// <param name="discussionSetting"></param> /// <returns></returns> private ActionResult GetAllReviewedDocuments(Assignment CRAssignment, Team authorTeam, string zipFileName, DiscussionSetting discussionSetting = null) { Assignment basicAssignment = CRAssignment.PreceedingAssignment; //If the BasicAssignment was a PDF, then use annotate to view discussion items if (basicAssignment.HasDeliverables && basicAssignment.Deliverables[0].DeliverableType == DeliverableType.PDF) { return(RedirectToRoute(new { controller = "PdfCriticalReview", action = "Review", assignmentID = CRAssignment.ID, authorTeamID = authorTeam.ID })); } //Gathering list of all TeamIDs who reviewed this Author List <int> reviewingTeamIds = (from rt in CRAssignment.ReviewTeams where rt.AuthorTeamID == authorTeam.ID select rt.ReviewTeamID).ToList(); //Gathering all the assignment teams who reviewed DiscussionTeam's Author List <AssignmentTeam> reviewingTeams = (from at in CRAssignment.AssignmentTeams where reviewingTeamIds.Contains(at.TeamID) select at).ToList(); //Streams used for ".cpml" Merging. MemoryStream parentStream = new MemoryStream(); MemoryStream outputStream = new MemoryStream(); bool FirstTime = true; //Bool used to determine if original file was added to stream //ZipFile for all Reviews ZipFile zipFile = new ZipFile(); //Determining displayname for the author team. string authorDisplayName = authorTeam.Name; if (AnonymizeAuthor(CRAssignment, authorTeam, discussionSetting) || ActiveCourseUser.AbstractRoleID == (int)CourseRole.CourseRoles.Observer) { authorDisplayName = "Anonymous " + authorTeam.ID; } //Potentially multiple review teams are merged onto 1 team for the Critical Review Discussion //so each Review Teams documents must be within the Critical Review Discussion Documents. foreach (AssignmentTeam reviewTeam in reviewingTeams) { //Get Reviews for AutuhorTeam from ReviewTeam. string reviewTeamSubmissionPath = Models.FileSystem.Directories.GetAssignment( ActiveCourseUser.AbstractCourseID, CRAssignment.ID) .Review(authorTeam.ID, reviewTeam.TeamID) .GetPath(); //Directory might not exist, check to avoid runtime error. if (new DirectoryInfo(reviewTeamSubmissionPath).Exists) { //Checking anonmous settings to determine name of folder string reviewerDisplayName = reviewTeam.Team.Name; if (AnonymizeReviewer(CRAssignment, reviewTeam.Team, discussionSetting) || ActiveCourseUser.AbstractRoleID == (int)CourseRole.CourseRoles.Observer) { //Change displayName if Reviewer is to be anonymized reviewerDisplayName = "Anonymous " + reviewTeam.Team.ID; } string folderName = "Review from " + reviewerDisplayName; zipFile.AddDirectory(reviewTeamSubmissionPath, folderName); //Check each file to see it s a .cpml. If it is, handle merging them into one .cpml foreach (string filename in Directory.EnumerateFiles(reviewTeamSubmissionPath)) { if (Path.GetExtension(filename) == ".cpml") { //Only want to add the original file to the stream once. if (FirstTime == true) { string originalFile = OSBLE.Models.FileSystem.Directories.GetAssignment( ActiveCourseUser.AbstractCourseID, basicAssignment.ID) .Submission(authorTeam) .GetPath(); FileStream filestream = System.IO.File.OpenRead(originalFile + "\\" + basicAssignment.Deliverables[0].Name + ".cpml"); filestream.CopyTo(parentStream); FirstTime = false; } //Merge the FileStream from filename + parentStream into outputStream. ChemProV.Core.CommentMerger.Merge(parentStream, authorDisplayName, System.IO.File.OpenRead(filename), reviewerDisplayName, outputStream); //close old parent stream before writing over it parentStream.Close(); //Copy outputStream to parentStream, creating new outputStream parentStream = new MemoryStream(); outputStream.Seek(0, SeekOrigin.Begin); outputStream.CopyTo(parentStream); outputStream = new MemoryStream(); } } } } //Adding merged document to Zip if there was every a .cpml if (FirstTime == false) { parentStream.Seek(0, SeekOrigin.Begin); zipFile.AddEntry("MergedReview.cpml", parentStream); } //Saving zip to a stream MemoryStream returnValue = new MemoryStream(); zipFile.Save(returnValue); returnValue.Position = 0; //Returning zip return(new FileStreamResult(returnValue, "application/octet-stream") { FileDownloadName = zipFileName }); }
/// <summary> /// yc: with a given list of assignments, copy them from one course to another. /// </summary> /// <param name="courseDestination"></param> /// <param name="courseSource"></param> /// <param name="previousAssignments"></param> /// <returns></returns> public bool CopyAssignments(Course courseDestination, Course courseSource, List <Assignment> previousAssignments) { try { //calculate # of weeks since start date double difference = courseDestination.StartDate.Subtract(courseSource.StartDate).TotalDays; //for linking purposes, key == previous id, value == the clone course that is teh same Dictionary <int, int> linkHolder = new Dictionary <int, int>(); foreach (Assignment p in previousAssignments) { //disabling assignments that are not finished being handled yet if (p.Type == AssignmentTypes.AnchoredDiscussion || p.Type == AssignmentTypes.CommitteeDiscussion || p.Type == AssignmentTypes.ReviewOfStudentWork) { continue; } int prid = -1, paid = p.ID; //for insert sake of cloned assigntment we must temprarly hold the list of assignments //whos id links to this assignment for temporary holding List <Assignment> previouslyLinked = (from pl in db.Assignments where pl.PrecededingAssignmentID == paid select pl).ToList(); //remove the links for now foreach (Assignment link in previouslyLinked) { link.PrecededingAssignmentID = null; db.Entry(link).State = EntityState.Modified; db.SaveChanges(); } //tmp holders if (p.RubricID != null) { prid = (int)p.RubricID; } //we are now ready for copying Assignment na = new Assignment(p); //na = p; na.CourseID = courseDestination.ID; //rewrite course id na.IsDraft = true; na.AssociatedEvent = null; na.AssociatedEventID = null; na.PrecededingAssignmentID = null; na.AssignmentTeams = new List <AssignmentTeam>(); na.DiscussionTeams = new List <DiscussionTeam>(); na.ReviewTeams = new List <ReviewTeam>(); na.Deliverables = new List <Deliverable>(); SetUpClonedAssignmentTeams(p, na); //recalcualte new offsets for due dates on assignment if (p.CriticalReviewPublishDate != null) { na.CriticalReviewPublishDate = ((DateTime)(p.CriticalReviewPublishDate)).Add(new TimeSpan(Convert.ToInt32(difference), 0, 0, 0)); } //CourseController cc = new CourseController(); // to retain the time incase of in differt daylightsavings .. shifts //DateTime dd = cc.convertFromUtc(courseSource.TimeZoneOffset, na.DueDate); //DateTime dt = cc.convertFromUtc(courseSource.TimeZoneOffset, na.DueTime); //DateTime rd = cc.convertFromUtc(courseSource.TimeZoneOffset, na.ReleaseDate); //DateTime rt = cc.convertFromUtc(courseSource.TimeZoneOffset, na.ReleaseTime); DateTime dd = na.DueDate.UTCToCourse(courseSource.ID); DateTime dt = na.DueTime.UTCToCourse(courseSource.ID); DateTime rd = na.ReleaseDate.UTCToCourse(courseSource.ID); DateTime rt = na.ReleaseTime.UTCToCourse(courseSource.ID); dd = dd.Add(new TimeSpan(Convert.ToInt32(difference), 0, 0, 0)); dt = dt.Add(new TimeSpan(Convert.ToInt32(difference), 0, 0, 0)); rd = rd.Add(new TimeSpan(Convert.ToInt32(difference), 0, 0, 0)); rt = rt.Add(new TimeSpan(Convert.ToInt32(difference), 0, 0, 0)); //convert back to utc //na.DueDate = cc.convertToUtc(courseDestination.TimeZoneOffset, dd); //na.DueTime = cc.convertToUtc(courseDestination.TimeZoneOffset, dt); //na.ReleaseDate = cc.convertToUtc(courseDestination.TimeZoneOffset, rd); //na.ReleaseTime = cc.convertToUtc(courseDestination.TimeZoneOffset, rt); na.DueDate = dd.CourseToUTC(courseDestination.ID); na.DueTime = dt.CourseToUTC(courseDestination.ID); na.ReleaseDate = rd.CourseToUTC(courseDestination.ID); na.ReleaseTime = rt.CourseToUTC(courseDestination.ID); //we now have a base to save db.Assignments.Add(na); db.SaveChanges(); //fix the link now foreach (Assignment link in previouslyLinked) { link.PrecededingAssignmentID = paid; db.Entry(link).State = EntityState.Modified; db.SaveChanges(); } linkHolder.Add(paid, na.ID); //for future assignment links if (p.PrecededingAssignmentID != null) { na.PrecededingAssignmentID = linkHolder[(int)p.PrecededingAssignmentID]; na.PreceedingAssignment = db.Assignments.Find(linkHolder[(int)p.PrecededingAssignmentID]); db.Entry(na).State = EntityState.Modified; db.SaveChanges(); } //copy assignmenttypes if (p.Type == AssignmentTypes.DiscussionAssignment || p.Type == AssignmentTypes.CriticalReviewDiscussion) { DiscussionSetting pds = (from ds in db.DiscussionSettings where ds.AssignmentID == paid select ds).FirstOrDefault(); DiscussionSetting nds = new DiscussionSetting(); nds.InitialPostDueDate = pds.InitialPostDueDate.Add(new TimeSpan(Convert.ToInt32(difference), 0, 0, 0)); nds.InitialPostDueDueTime = pds.InitialPostDueDueTime.Add(new TimeSpan(Convert.ToInt32(difference), 0, 0, 0)); nds.AssociatedEventID = null; nds.MaximumFirstPostLength = pds.MaximumFirstPostLength; nds.MinimumFirstPostLength = pds.MinimumFirstPostLength; nds.AnonymitySettings = pds.AnonymitySettings; na.DiscussionSettings = nds; db.Entry(na).State = EntityState.Modified; db.SaveChanges(); } //copy critical review settings if (p.Type == AssignmentTypes.CriticalReview) { CriticalReviewSettings pcs = (from ds in db.CriticalReviewSettings where ds.AssignmentID == paid select ds).FirstOrDefault(); if (pcs != null) { CriticalReviewSettings ncs = new CriticalReviewSettings(); ncs.ReviewSettings = pcs.ReviewSettings; na.CriticalReviewSettings = ncs; db.Entry(na).State = EntityState.Modified; db.SaveChanges(); } } //team eval if (p.Type == AssignmentTypes.TeamEvaluation) { TeamEvaluationSettings ptes = (from tes in db.TeamEvaluationSettings where tes.AssignmentID == paid select tes).FirstOrDefault(); if (ptes != null) { TeamEvaluationSettings ntes = new TeamEvaluationSettings(); ntes.DiscrepancyCheckSize = ptes.DiscrepancyCheckSize; ntes.RequiredCommentLength = ptes.RequiredCommentLength; ntes.MaximumMultiplier = ptes.MaximumMultiplier; ntes.AssignmentID = na.ID; na.TeamEvaluationSettings = ntes; db.Entry(na).State = EntityState.Modified; db.SaveChanges(); } } //components //rubrics if (p.RubricID != null) { CopyRubric(p, na); } ///deliverables List <Deliverable> pads = (from d in db.Deliverables where d.AssignmentID == paid select d).ToList(); foreach (Deliverable pad in pads) { Deliverable nad = new Deliverable(); nad.AssignmentID = na.ID; nad.DeliverableType = pad.DeliverableType; nad.Assignment = na; nad.Name = pad.Name; db.Deliverables.Add(nad); db.SaveChanges(); na.Deliverables.Add(nad); db.Entry(na).State = EntityState.Modified; db.SaveChanges(); } //abet stuff should prolly go here } return(true); } catch (Exception ex) { return(false); } }
/// <summary> /// Returns true if the posters name should be Anonymized for a discussion assignment /// </summary> /// <param name="currentUser">The current users</param> /// <param name="poster">The posters courseuser</param> /// <param name="discussionSetting">The assignments discussion settings</param> /// <returns></returns> public static bool AnonymizeNameForDiscussion(CourseUser poster, CourseUser currentUser, DiscussionSetting discussionSettings) { bool Anonymous = false; //Don't want to set anonymous permissions if the poster is the current user //Additionally, we do not want to anonmize for TA or Instructors if (poster.ID != currentUser.ID && currentUser.AbstractRoleID != (int)CourseRole.CourseRoles.Instructor && currentUser.AbstractRoleID != (int)CourseRole.CourseRoles.TA) { //Checking role of currentUser bool currentUserIsStudent = currentUser.AbstractRoleID == (int)CourseRole.CourseRoles.Student; bool currentUserIsModerator = currentUser.AbstractRoleID == (int)CourseRole.CourseRoles.Moderator; bool currentUserIsObserver = currentUser.AbstractRoleID == (int)CourseRole.CourseRoles.Observer; //Checking role of poster. Note: If the poster is a TA, we treat them like a moderator or instructor depending on the value //of TAsCanPostToAllDiscussions bool posterIsStudent = poster.AbstractRoleID == (int)CourseRole.CourseRoles.Student; bool posterIsModerator = poster.AbstractRoleID == (int)CourseRole.CourseRoles.Moderator || (!discussionSettings.TAsCanPostToAllDiscussions && poster.AbstractRoleID == (int)CourseRole.CourseRoles.TA); bool posterIsInstructor = poster.AbstractRoleID == (int)CourseRole.CourseRoles.Instructor || (discussionSettings.TAsCanPostToAllDiscussions && poster.AbstractRoleID == (int)CourseRole.CourseRoles.TA); //if current user is a student, poster is a student, and student is anonymized to student if (discussionSettings.HasAnonymousStudentsToStudents && currentUserIsStudent && posterIsStudent) { Anonymous = true; } //if current user is a student, poster is an instructor, and instructor is anonymized to student else if (discussionSettings.HasAnonymousInstructorsToStudents && currentUserIsStudent && posterIsInstructor) { Anonymous = true; } //if current user is a student, poster is an moderator, and moderator is anonymized to student else if (discussionSettings.HasAnonymousModeratorsToStudents && currentUserIsStudent && posterIsModerator) { Anonymous = true; } //if current user is a moderator, poster is a student, and student is anonymized to moderator else if (discussionSettings.HasAnonymousStudentsToModerators && currentUserIsModerator && posterIsStudent) { Anonymous = true; } else if (currentUserIsObserver) { Anonymous = true; } } return(Anonymous); }