/// <summary> /// Decrypts the selected file. /// </summary> private async Task DecryptFileAsync(string srcFile, string destFile) { if (string.IsNullOrWhiteSpace(srcFile) || !File.Exists(srcFile)) { _loggingService.Log(LogLevel.Warning, $"Invalid source file {srcFile}, skipping..."); return; } await DecryptionHelper.DecryptFileAsync(srcFile, destFile).ConfigureAwait(false); _loggingService.Log(LogLevel.Information, $"Decrypted clip {Path.GetFileName(destFile)}."); }
public async Task StartAsync(int?maxDegreeOfParallelism = null) { int threads = maxDegreeOfParallelism ?? Environment.ProcessorCount; using (var db = new PsvContext(_psvInformation)) { IEnumerable <Course> courses = db.Courses; foreach (var course in courses) { _loggingService.Log(LogLevel.Information, $"Processing course \"{course.Name}\"..."); // Checks string courseSource = Path.Combine(_psvInformation.CoursesPath, course.Name); string courseOutput = Path.Combine(_psvInformation.Output, _stringProcessor.SanitizeTitle(course.Title)); if (!Directory.Exists(courseSource)) { _loggingService.Log(LogLevel.Warning, $"Courses directory for \"{course.Name}\" not found. Skipping..."); continue; } if (!Directory.Exists(courseOutput)) { courseOutput = Directory.CreateDirectory(courseOutput).FullName; } // Course image copy await CopyCourseImageAsync(courseSource, courseOutput).ConfigureAwait(false); // Write course info await WriteCourseInfoAsync(course, courseOutput).ConfigureAwait(false); var modules = await db.Modules.Where(x => x.CourseName == course.Name).ToListAsync() .ConfigureAwait(false); _loggingService.Log(LogLevel.Information, $"Found {modules.Count} modules under course \"{course.Name}\"..."); foreach (var module in modules) { // Preps _loggingService.Log(LogLevel.Information, $"Processing module: {module.Name}..."); string moduleHash = await Task .Run(() => DecryptionHelper.GetModuleHash(module.Name, module.AuthorHandle)) .ConfigureAwait(false); string moduleOutput = Path.Combine(courseOutput, $"{_stringProcessor.TitleToFileIndex(module.ModuleIndex)}. {_stringProcessor.SanitizeTitle(module.Title)}"); string moduleSource = Path.Combine(courseSource, moduleHash); if (!Directory.Exists(moduleOutput)) { moduleOutput = Directory.CreateDirectory(moduleOutput).FullName; } // Write module info await WriteModuleInfoAsync(module, moduleOutput).ConfigureAwait(false); // Process each clip var clips = await db.Clips.Where(x => x.ModuleId == module.Id).ToListAsync() .ConfigureAwait(false); // Bail if no courses are found in database if (clips.Count == 0) { _loggingService.Log(LogLevel.Warning, $"No corresponding clips found for module {module.Name}, skipping..."); continue; } // Write clip info await WriteClipInfoAsync(clips, moduleOutput).ConfigureAwait(false); await clips.ParallelForEachAsync(async clip => { string clipSource = Path.Combine(moduleSource, $"{clip.Name}.psv"); string clipName = $"{_stringProcessor.TitleToFileIndex(clip.ClipIndex)}. {_stringProcessor.SanitizeTitle(clip.Title)}"; string clipFilePath = Path.Combine(moduleOutput, $"{clipName}.mp4"); // Decrypt individual clip await DecryptFileAsync(clipSource, clipFilePath).ConfigureAwait(false); // Create subtitles for each clip if (course.HasTranscript != true) { return; } using (var psvContext = new PsvContext(_psvInformation)) { var transcripts = psvContext.ClipTranscripts.Where(x => x.ClipId == clip.Id); if (!await transcripts.AnyAsync().ConfigureAwait(false)) { return; } await BuildSubtitlesAsync(transcripts, moduleOutput, clipName).ConfigureAwait(false); } }, threads).ConfigureAwait(false); } } } }