private List <ReviewTeam> ParseReviewTeams() { List <ReviewTeam> reviewTeams = new List <ReviewTeam>(); string[] reviewTeamKeys = Request.Form.AllKeys.Where(k => k.Contains("reviewTeam_")).ToArray(); foreach (string reviewTeamKey in reviewTeamKeys) { int reviewerId = 0; Int32.TryParse(reviewTeamKey.Split('_')[1], out reviewerId); //skip bad apples if (reviewerId == 0) { continue; } //Loop through each review item. Review items are contained within the form value separated //by underscores (_) string reviewItems = Request.Form[reviewTeamKey]; string[] itemPieces = reviewItems.Split('_'); foreach (string item in itemPieces) { int authorId = 0; Int32.TryParse(item, out authorId); if (authorId > 0) { ReviewTeam activeTeam = new ReviewTeam(); activeTeam.ReviewTeamID = reviewerId; activeTeam.AuthorTeamID = authorId; reviewTeams.Add(activeTeam); } } } return(reviewTeams); }
public ActionResult Grade(int assignmentID, int authorTeamID, bool resubmission = false) { WebClient client = new WebClient(); Assignment assignment = db.Assignments.Find(assignmentID); AssignmentTeam at = GetAssignmentTeam(assignment, ActiveCourseUser); ReviewTeam reviewTeam = null; if (at != null) { reviewTeam = (from rt in assignment.ReviewTeams where rt.ReviewTeamID == at.TeamID && rt.AuthorTeamID == authorTeamID select rt).FirstOrDefault(); } //Send off to Annotate if we have exactly one deliverable and that deliverable is a PDF document if (assignment.Deliverables.Count == 1 && assignment.Deliverables[0].DeliverableType == DeliverableType.PDF) { AnnotateApi api = new AnnotateApi(ConfigurationManager.AppSettings["AnnotateUserName"], ConfigurationManager.AppSettings["AnnotateApiKey"]); AnnotateResult uploadResult = api.UploadDocument((int)assignment.ID, authorTeamID, resubmission); if (uploadResult.Result == ResultCode.OK) { AnnotateResult createResult = api.CreateAccount(CurrentUser); if (createResult.Result == ResultCode.OK) { //instructors get to see everyone, regardless of CR settings CriticalReviewSettings settings = new CriticalReviewSettings(); settings.AnonymizeComments = false; api.SetDocumentAnonymity(CurrentUser, uploadResult.DocumentCode, uploadResult.DocumentDate, settings); api.GiveAccessToDocument(CurrentUser, uploadResult.DocumentCode, uploadResult.DocumentDate); //log the user in to annotate string loginString = api.GetAnnotateLoginUrl(CurrentUser, uploadResult.DocumentCode, uploadResult.DocumentDate); //load the annotate url for the view ViewBag.AnnotateUrl = loginString; } } } else { return(RedirectToRoute(new { controller = "Home", action = "Index", area = "" })); } return(View("Review")); }
/// <summary> /// Used in annotate to build a unique string for each document in OSBLE /// </summary> /// <param name="assignmentID">The assignment on which the submission took place (NOT THE CRITICAL REVIEW)</param> /// <param name="authorTeamID">The team that submitted the document</param> /// <returns></returns> public static string GetAnnotateDocumentName(int assignmentID, int authorTeamID) { using (OSBLEContext db = new OSBLEContext()) { Assignment assignment = db.Assignments.Find(assignmentID); AssignmentTeam assignmentTeam = new AssignmentTeam(); ReviewTeam reviewTeam = new ReviewTeam(); //needed for anchored discussion string fileName; if (assignment.Type == AssignmentTypes.AnchoredDiscussion) { reviewTeam = (from rt in db.ReviewTeams where rt.AssignmentID == assignment.ID && rt.AuthorTeamID == authorTeamID select rt ).FirstOrDefault(); fileName = string.Format( "{0}-{1}-{2}-{3}", assignment.CourseID, assignment.ID, reviewTeam.ReviewTeamID, assignment.Deliverables[0].ToString() ); } else { assignmentTeam = (from at in db.AssignmentTeams where at.AssignmentID == assignment.ID && at.TeamID == authorTeamID select at ).FirstOrDefault(); fileName = string.Format( "{0}-{1}-{2}-{3}", assignment.CourseID, assignment.ID, assignmentTeam.TeamID, assignment.Deliverables[0].ToString() ); } return(fileName); } }
/// <summary> /// Loads a PDF for critical review /// </summary> /// <param name="assignmentID"></param> /// <param name="authorTeamID"></param> /// <returns></returns> public ActionResult Review(int assignmentID, int authorTeamID) { WebClient client = new WebClient(); Assignment CRassignment = db.Assignments.Find(assignmentID); AssignmentTeam at = GetAssignmentTeam(CRassignment, ActiveCourseUser); ReviewTeam reviewTeam = null; if (at != null) { reviewTeam = (from rt in CRassignment.ReviewTeams where rt.ReviewTeamID == at.TeamID && rt.AuthorTeamID == authorTeamID select rt).FirstOrDefault(); } bool canAccessReview = false; //Determine whether or not the current user can access the document if (CRassignment.Type == AssignmentTypes.CriticalReview) { //is the user a reviewer? if (reviewTeam != null) { canAccessReview = true; } //or, is the user an instructor? else if (ActiveCourseUser.AbstractRole.CanGrade) { canAccessReview = true; } //or, has the review been published and the current user is the author of the docment? else if (CRassignment.IsCriticalReviewPublished == true) { reviewTeam = (from rt in CRassignment.ReviewTeams where rt.AuthorTeamID == authorTeamID select rt ).FirstOrDefault(); if (reviewTeam != null) { TeamMember tm = reviewTeam.AuthorTeam.TeamMembers.Where(t => t.CourseUserID == ActiveCourseUser.ID).FirstOrDefault(); if (tm != null) { canAccessReview = true; } } } } if (canAccessReview) { //Send off to Annotate if we have exactly one deliverable and that deliverable is a PDF document if (CRassignment.PreceedingAssignment.Deliverables.Count == 1 && CRassignment.PreceedingAssignment.Deliverables[0].DeliverableType == DeliverableType.PDF) { AnnotateApi api = new AnnotateApi(ConfigurationManager.AppSettings["AnnotateUserName"], ConfigurationManager.AppSettings["AnnotateApiKey"]); AnnotateResult uploadResult = api.UploadDocument((int)CRassignment.PrecededingAssignmentID, authorTeamID); if (uploadResult.Result == ResultCode.OK) { AnnotateResult createResult = api.CreateAccount(CurrentUser); if (createResult.Result == ResultCode.OK) { //instructors get to see everyone, regardless of CR settings CriticalReviewSettings settings = CRassignment.CriticalReviewSettings; if (ActiveCourseUser.AbstractRoleID == (int)CourseRole.CourseRoles.Instructor) { settings.AnonymizeComments = false; } api.SetDocumentAnonymity(CurrentUser, uploadResult.DocumentCode, uploadResult.DocumentDate, settings); api.GiveAccessToDocument(CurrentUser, uploadResult.DocumentCode, uploadResult.DocumentDate); //log the user in to annotate string loginString = api.GetAnnotateLoginUrl(CurrentUser, uploadResult.DocumentCode, uploadResult.DocumentDate); //load the annotate url for the view ViewBag.AnnotateUrl = loginString; } } } else { return(RedirectToRoute(new { controller = "Home", action = "Index", area = "" })); } } return(View()); }
public ActionResult Create(int?id, IEnumerable <HttpPostedFileBase> files, int?authorTeamID = null) { if (id != null) { Assignment assignment = db.Assignments.Find(id); //submit event to the eventlog try { if (assignment != null) { var sub = new SubmitEvent { AssignmentId = id.Value, SenderId = CurrentUser.ID, SolutionName = assignment.AssignmentName, CourseId = assignment.CourseID, }; int eventLogId = Posts.SaveEvent(sub); DBHelper.AddToSubmitEventProperties(eventLogId); if (eventLogId == -1) { throw new Exception("Failed to log submit event to the eventlog table -- Posts.SaveEvent returned -1"); } else { if (DBHelper.InterventionEnabledForCourse(assignment.CourseID ?? -1)) { //process suggestions if interventions are enabled for this course. using (EventCollectionController ecc = new EventCollectionController()) { ecc.ProcessLogForInterventionSync((ActivityEvent)sub); string authKey = Request.Cookies["AuthKey"].Value.Split('=').Last(); ecc.NotifyNewSuggestion(CurrentUser.ID, assignment.CourseID ?? 0, authKey); } } } } else { var sub = new SubmitEvent { AssignmentId = id.Value, SenderId = CurrentUser.ID, SolutionName = "NULL ASSIGNMENT", }; int eventLogId = Posts.SaveEvent(sub); if (eventLogId == -1) { throw new Exception("Failed to log submit event to the eventlog table -- Posts.SaveEvent returned -1 -- Assignment is null"); } } } catch (Exception e) { throw new Exception("Failed to log submit event to the eventlog table: ", e); } if (assignment != null && (assignment.HasDeliverables == true || assignment.Type == AssignmentTypes.CriticalReview || assignment.Type == AssignmentTypes.AnchoredDiscussion)) { List <Deliverable> deliverables; if (assignment.Type == AssignmentTypes.CriticalReview) { deliverables = new List <Deliverable>((assignment.PreceedingAssignment).Deliverables); } else if (assignment.Type == AssignmentTypes.AnchoredDiscussion) { //TODO: need to keep deliverables if no changes have been made. //need to remove old deliverables assignment.Deliverables.Clear(); db.SaveChanges(); deliverables = new List <Deliverable>((assignment).Deliverables); List <string> deliverableNames = new List <string>(); foreach (var file in files) { deliverables.Add(new Deliverable { Assignment = assignment, AssignmentID = assignment.ID, DeliverableType = DeliverableType.PDF, Name = Path.GetFileNameWithoutExtension(file.FileName), }); } foreach (Deliverable d in deliverables) { assignment.Deliverables.Add(d); } db.Entry(assignment).State = System.Data.EntityState.Modified; db.SaveChanges(); } else { deliverables = new List <Deliverable>((assignment).Deliverables); } if (assignment.CourseID == ActiveCourseUser.AbstractCourseID && (ActiveCourseUser.AbstractRole.CanSubmit == true || ActiveCourseUser.AbstractRole.CanUploadFiles == true)) { AssignmentTeam assignmentTeam = GetAssignmentTeam(assignment, ActiveCourseUser); int i = 0; //the files variable is null when submitting an in-browser text submission if (files != null) { int anchoredDiscussionDocumentCount = 0; foreach (var file in files) { anchoredDiscussionDocumentCount++; if (file != null && file.ContentLength > 0) { DeliverableType type = (DeliverableType)deliverables[i].Type; //jump over all DeliverableType.InBrowserText as they will be handled separately while (type == DeliverableType.InBrowserText) { i++; type = (DeliverableType)deliverables[i].Type; } string fileName = Path.GetFileName(file.FileName); string extension = Path.GetExtension(file.FileName).ToLower(); string deliverableName = string.Format("{0}{1}", deliverables[i].Name, extension); string[] allowFileExtensions = GetFileExtensions(type); if (allowFileExtensions.Contains(extension)) { if (assignment.Type == AssignmentTypes.CriticalReview || assignment.Type == AssignmentTypes.AnchoredDiscussion) { //TODO: clean this up AssignmentTeam authorTeam = new AssignmentTeam(); ReviewTeam reviewTeam = new ReviewTeam(); if (assignment.Type == AssignmentTypes.AnchoredDiscussion) { authorTeam = new AssignmentTeam { Assignment = assignment, AssignmentID = assignment.ID, Team = null, TeamID = anchoredDiscussionDocumentCount, }; reviewTeam = new ReviewTeam { Assignment = assignment, AssignmentID = assignment.ID, //AuthorTeam = null, AuthorTeamID = anchoredDiscussionDocumentCount, //ReviewingTeam = null, ReviewTeamID = ActiveCourseUser.AbstractCourse.ID, }; assignment.ReviewTeams.Add(reviewTeam); //db.Entry(assignment).State = System.Data.EntityState.Modified; db.SaveChanges(); } else { authorTeam = (from at in db.AssignmentTeams where at.TeamID == authorTeamID && at.AssignmentID == assignment.PrecededingAssignmentID select at).FirstOrDefault(); reviewTeam = (from tm in db.TeamMembers join t in db.Teams on tm.TeamID equals t.ID join rt in db.ReviewTeams on t.ID equals rt.ReviewTeamID where tm.CourseUserID == ActiveCourseUser.ID && rt.AssignmentID == assignment.ID select rt).FirstOrDefault(); } //MG&MK: file system for critical review assignments is laid out a bit differently, so //critical review assignments must use different file system functions //remove all prior files OSBLE.Models.FileSystem.AssignmentFilePath fs = Models.FileSystem.Directories.GetAssignment( ActiveCourseUser.AbstractCourseID, assignment.ID); fs.Review(authorTeam.TeamID, reviewTeam.ReviewTeamID) .File(deliverableName) .Delete(); if (assignment.Type != AssignmentTypes.AnchoredDiscussion) // handle assignments that are not anchored discussion { //We need to remove the zipfile corresponding to the authorTeamId being sent in as well as the regularly cached zip. AssignmentTeam precedingAuthorAssignmentTeam = (from at in assignment.PreceedingAssignment.AssignmentTeams where at.TeamID == authorTeamID select at).FirstOrDefault(); FileSystem.RemoveZipFile(ActiveCourseUser.AbstractCourse as Course, assignment, precedingAuthorAssignmentTeam); FileSystem.RemoveZipFile(ActiveCourseUser.AbstractCourse as Course, assignment, assignmentTeam); } else //anchored discussion type TODO: this does nothing right now, fix! { //We need to remove the zipfile corresponding to the authorTeamId being sent in as well as the regularly cached zip. AssignmentTeam precedingAuthorAssignmentTeam = (from at in assignment.AssignmentTeams where at.TeamID == authorTeamID select at).FirstOrDefault(); FileSystem.RemoveZipFile(ActiveCourseUser.AbstractCourse as Course, assignment, precedingAuthorAssignmentTeam); FileSystem.RemoveZipFile(ActiveCourseUser.AbstractCourse as Course, assignment, assignmentTeam); } //add in the new file //authorTeamID is the deliverable file counter, and reviewTeamID is the courseID fs.Review(authorTeam.TeamID, reviewTeam.ReviewTeamID) .AddFile(deliverableName, file.InputStream); //unzip and rezip xps files because some XPS generators don't do it right if (extension.ToLower().CompareTo(".xps") == 0) { //XPS documents require the actual file path, so get that. OSBLE.Models.FileSystem.FileCollection fileCollection = OSBLE.Models.FileSystem.Directories.GetAssignment( ActiveCourseUser.AbstractCourseID, assignment.ID) .Review(authorTeam.TeamID, reviewTeam.ReviewTeamID) .File(deliverables[i].Name); string path = fileCollection.FirstOrDefault(); string extractPath = Path.Combine(FileSystem.GetTeamUserSubmissionFolderForAuthorID(true, ActiveCourseUser.AbstractCourse as Course, (int)id, assignmentTeam, authorTeam.Team), "extract"); using (ZipFile oldZip = ZipFile.Read(path)) { oldZip.ExtractAll(extractPath, ExtractExistingFileAction.OverwriteSilently); } using (ZipFile newZip = new ZipFile()) { newZip.AddDirectory(extractPath); newZip.Save(path); } } } else { //If a submission of any extension exists delete it. This is needed because they could submit a .c file and then a .cs file and the teacher would not know which one is the real one. string submission = FileSystem.GetDeliverable(ActiveCourseUser.AbstractCourse as Course, assignment.ID, assignmentTeam, deliverables[i].Name, allowFileExtensions); if (submission != null) { FileInfo oldSubmission = new FileInfo(submission); if (oldSubmission.Exists) { oldSubmission.Delete(); } } FileSystem.RemoveZipFile(ActiveCourseUser.AbstractCourse as Course, assignment, assignmentTeam); string path = Path.Combine(FileSystem.GetTeamUserSubmissionFolder(true, ActiveCourseUser.AbstractCourse as Course, (int)id, assignmentTeam), deliverables[i].Name + extension); file.SaveAs(path); //unzip and rezip xps files because some XPS generators don't do it right if (extension.ToLower().CompareTo(".xps") == 0) { string extractPath = Path.Combine(FileSystem.GetTeamUserSubmissionFolder(true, ActiveCourseUser.AbstractCourse as Course, (int)id, assignmentTeam), "extract"); using (ZipFile oldZip = ZipFile.Read(path)) { oldZip.ExtractAll(extractPath, ExtractExistingFileAction.OverwriteSilently); } using (ZipFile newZip = new ZipFile()) { newZip.AddDirectory(extractPath); newZip.Save(path); } } } DateTime?dueDate = assignment.DueDate; if (dueDate != null) { //TODO: add case for anchored discussion assignment (new NotificationController()).SendFilesSubmittedNotification(assignment, assignmentTeam, deliverables[i].Name); } } else { //The submission view handles incorrect extension types, so this area of code is unlikely to be reached. In the case that it does a occur, //we will ineloquently redirect them to assignment index without feedback. Cache["SubmissionReceived"] = false; return(RedirectToAction("Index", "Assignment")); } } i++; } } // Creates the text files from text boxes int j = 0; string delName; do { if (Request != null) { //delName = Request.Params["desiredName[" + j + "]"]; delName = Request.Unvalidated.Form["desiredName[" + j + "]"]; } else //TODO: change this to releveant string { delName = null; } if (delName != null) { string inbrowser; if (Request != null) { //inbrowser = Request.Params["inBrowserText[" + j + "]"]; inbrowser = Request.Unvalidated.Form["inBrowserText[" + j + "]"]; if (inbrowser.Length > 0) { var path = Path.Combine(FileSystem.GetTeamUserSubmissionFolder(true, ActiveCourseUser.AbstractCourse as Course, (int)id, assignmentTeam), CurrentUser.LastName + "_" + CurrentUser.FirstName + "_" + delName + ".txt"); System.IO.File.WriteAllText(path, inbrowser); } } } j++; } while (delName != null); Cache["SubmissionReceived"] = true; Cache["SubmissionReceivedAssignmentID"] = assignment.ID; if (authorTeamID != null) { Cache["SubmissionForAuthorTeamID"] = authorTeamID; } if (assignment.Type == AssignmentTypes.AnchoredDiscussion) { return(RedirectToAction("Index", "AnchoredDiscussionController")); } else { return(Redirect(Request.UrlReferrer.ToString())); } } } } return(Create(id)); }
public override DynamicDictionary BuildHeader(Assignment assignment) { dynamic header = Builder.BuildHeader(assignment); header.Assignment = assignment; header.CRdownload = new DynamicDictionary(); header.CRdownload.hasPublished = assignment.IsCriticalReviewPublished; header.CRdownload.publishedDate = assignment.CriticalReviewPublishDate; header.CRdownload.hasRubricToView = false; //get student's team AssignmentTeam assignmentTeam = null; assignmentTeam = OSBLEController.GetAssignmentTeam(assignment.PreceedingAssignment, Student); header.CRdownload.teamID = assignmentTeam.TeamID; header.CRdownload.hasRecievedReview = false; //PDF reviews don't get sent to the file system (they get sent to annotate) //so we can't check the file system for review items. //yc: but we can check to see if the file has been submitted into annotate //dbo.annotatedocumentreferences has a field osbledocumentcode, and we have the date it was "uploaded" //it follows the format:#-#-#-filename.PDF == courseID-PreviousAssignmentid-teamthatisreviewingreviewing-filename.PDF //we also have dbo.reviewteams that show if some one has reviewed your assignment Assignment previousAssignment = assignment.PreceedingAssignment; //yc: locate all reivew teams ReviewTeam reviewers = null; bool foundAnnotateEntry = false; using (OSBLEContext db = new OSBLEContext()) { if (assignmentTeam != null) { reviewers = (from rte in db.ReviewTeams where rte.AuthorTeamID == assignmentTeam.TeamID select rte).FirstOrDefault(); } if (reviewers != null) { //if a review team exists, determin if the annoation exisits string lookup = assignment.CourseID.ToString() + "-" + previousAssignment.ID.ToString() + "-" + assignmentTeam.TeamID.ToString() + "-"; AnnotateDocumentReference d = (from adr in db.AnnotateDocumentReferences where adr.OsbleDocumentCode.Contains(lookup) select adr).FirstOrDefault(); if (d != null && (assignment.DueDate < DateTime.Now || assignment.IsCriticalReviewPublished)) { foundAnnotateEntry = true; } } } if (foundAnnotateEntry)//( //previousAssignment.HasDeliverables //&& previousAssignment.Deliverables[0].DeliverableType == DeliverableType.PDF //&& previousAssignment.Deliverables.Count == 1 //) { header.CRdownload.hasRecievedReview = true; } else { if (assignmentTeam != null) { //get list of all teams reviewing student List <AssignmentTeam> reviewersOfStudent = (from rt in assignment.ReviewTeams join at in assignment.AssignmentTeams on rt.ReviewTeamID equals at.TeamID where rt.AuthorTeamID == assignmentTeam.TeamID select at).ToList(); //check each team for a submission foreach (AssignmentTeam at in reviewersOfStudent) { //if(at.GetSubmissionTime() != null) if (FileSystem.GetSubmissionTime(at, assignmentTeam.Team) != null) { header.CRdownload.hasRecievedReview = true; break; } } } //check if there is at one student rubric that has been filled out for the current user if (assignment.HasStudentRubric) { using (OSBLEContext db = new OSBLEContext()) { header.CRdownload.hasRubricToView = (from e in db.RubricEvaluations where e.AssignmentID == assignment.ID && e.RecipientID == assignmentTeam.TeamID && e.Evaluator.AbstractRoleID == (int)CourseRole.CourseRoles.Student && e.DatePublished != null select e.ID).Count() > 0; } } } header.CRdownload.student = Student; header.CRdownload.assignmentID = assignment.ID; return(header); }