コード例 #1
0
        /// <summary>
        /// Builds a submission archive containing the submissions of
        /// all students.
        /// </summary>
        public async Task <Stream> BuildSubmissionArchiveAsync(
            Project project,
            IArchive templateContents,
            IList <StudentSubmission> submissions,
            ProjectSubmissionDownloadFormat format)
        {
            var stream = _fileSystem.CreateNewTempFile();

            using (ZipArchive archive = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: true))
            {
                foreach (var result in submissions)
                {
                    await WriteSubmissionToArchiveAsync
                    (
                        archive,
                        project,
                        result.Student,
                        templateContents,
                        result.Contents,
                        format
                    );

                    result.Contents.Dispose();
                }
            }

            stream.Position = 0;
            return(stream);
        }
コード例 #2
0
        /// <summary>
        /// Downloads the submissions for a given checkpoint, according to the
        /// options specified by the user, in the form of a zip archive.
        /// </summary>
        public async Task <Stream> DownloadSubmissionsAsync(
            string classroomName,
            string projectName,
            string checkpointName,
            IList <int> selectedUserIds,
            ProjectSubmissionDownloadFormat format)
        {
            var checkpoint = await LoadCheckpointAsync
                             (
                classroomName,
                projectName,
                checkpointName
                             );

            var allCheckpointSubmissions = GetCheckpointSubmissionsQuery
                                           (
                checkpoint,
                section: null                       // Include all sections
                                           );

            var selectedUserIdsHash = new HashSet <int>(selectedUserIds);

            var userIdsWithSubmissions = new HashSet <int>
                                         (
                await allCheckpointSubmissions
                .Where(submission => selectedUserIdsHash.Contains(submission.Commit.UserId))
                .GroupBy(submission => submission.Commit.User)
                .Select(group => group.Key.Id)
                .ToListAsync()
                                         );

            var sectionMemberships = await LoadSectionMembershipsAsync(classroomName);

            var studentDownloadRequests = sectionMemberships
                                          .Where
                                          (
                sm => selectedUserIdsHash.Contains(sm.ClassroomMembership.UserId)
                                          )
                                          .Select
                                          (
                sm => new StudentDownloadRequest
                (
                    sm.ClassroomMembership,
                    userIdsWithSubmissions.Contains(sm.ClassroomMembership.User.Id)
                )
                                          )
                                          .ToList();

            var templateContents = await _submissionDownloader.DownloadTemplateContentsAsync
                                   (
                checkpoint.Project
                                   );

            var submissionContents = await _submissionDownloader.DownloadSubmissionsAsync
                                     (
                checkpoint,
                studentDownloadRequests
                                     );

            return(await _submissionArchiveBuilder.BuildSubmissionArchiveAsync
                   (
                       checkpoint.Project,
                       templateContents,
                       submissionContents,
                       format
                   ));
        }
コード例 #3
0
        /// <summary>
        /// Writes the contents of a submission to an archive.
        /// </summary>
        private async Task WriteSubmissionToArchiveAsync(
            ZipArchive archive,
            Project project,
            ClassroomMembership student,
            IArchive templateContents,
            IArchive submissionContents,
            ProjectSubmissionDownloadFormat format)
        {
            bool includeEclipseProjects =
                (
                    format == ProjectSubmissionDownloadFormat.Eclipse ||
                    format == ProjectSubmissionDownloadFormat.All
                );
            bool includeFlatFiles =
                (
                    format == ProjectSubmissionDownloadFormat.Flat ||
                    format == ProjectSubmissionDownloadFormat.All
                );

            // Submissions are grouped by section.  If a student is in multiple
            // sections, just grab the first one
            string sectionName = student.SectionMemberships.First().Section.Name;

            var studentFolder = $"EclipseProjects\\{sectionName}\\{student.GitHubTeam}";

            // The project will contain all non-immutable submission files,
            // plus all immutable and private files from the template project.

            var projectContents = submissionContents.Files
                                  .Where
                                  (
                entry => project.GetFileType(entry) == FileType.Public
                                  )
                                  .Concat
                                  (
                templateContents.Files.Where
                (
                    entry => project.GetFileType(entry) != FileType.Public
                )
                                  )
                                  .ToList();

            foreach (var entry in projectContents)
            {
                if (ExcludeEntry(project, entry))
                {
                    continue;
                }

                var contents        = _transformer.GetFileContents(project, student, entry);
                var archiveFilePath = entry.FullPath;
                var fileName        = archiveFilePath.Substring(archiveFilePath.LastIndexOf("/") + 1);

                if (includeEclipseProjects)
                {
                    var archiveFileFolder = archiveFilePath.Contains("/")
                                                ? archiveFilePath.Substring(0, archiveFilePath.LastIndexOf("/"))
                                                : archiveFilePath;

                    var localFileFolder = $"{studentFolder}\\{archiveFileFolder}";
                    var localFilePath   = $"{localFileFolder}\\{fileName}";

                    // Add the file to the student project folder.
                    var projectFolderEntry = archive.CreateEntry(localFilePath);
                    using (Stream stream = projectFolderEntry.Open())
                    {
                        await stream.WriteAsync(contents, offset : 0, count : contents.Length);
                    }
                }

                // Add the file to the folder containing all files, if applicable.
                if (includeFlatFiles && fileName.EndsWith(".java") && project.GetFileType(entry) == FileType.Public)
                {
                    // Files are grouped by base name, and then by section
                    var baseFileName  = fileName.Substring(0, fileName.LastIndexOf("."));
                    var allFilesEntry = archive.CreateEntry($"AllFiles\\{baseFileName}\\{sectionName}\\{student.GitHubTeam}-{fileName}");
                    using (Stream stream = allFilesEntry.Open())
                    {
                        await stream.WriteAsync(contents, offset : 0, count : contents.Length);
                    }
                }
            }
        }