/// <summary> /// Retrive video infos from the database /// </summary> /// <param name="courseID">course id</param> /// <param name="videoID">video id</param> /// <returns>VideoInfo instance or null</returns> private VideoInfo GetVideoInfoFromDB(string courseID, string videoID) { VideoInfo videoInfo = null; try { SQLiteCommand cmd = DatabaseConnection.CreateCommand(); int? chapterID = null; // Query all required tables and fields from the database cmd.CommandText = @"SELECT Video.ID, Video.ChapterId, Video.CourseId, Video.Title, Filename, Course.Title as CourseTitle, Video.SortIndex, Chapter.Title as ChapterTitle, Chapter.SortIndex as ChapterIndex FROM Video, Course, Chapter WHERE Video.ChapterId = Chapter.ID AND Course.ID = Video.CourseId AND Video.CourseId = @courseId AND Video.ID = @videoId"; cmd.Parameters.Add(new SQLiteParameter("@courseId", courseID)); cmd.Parameters.Add(new SQLiteParameter("@videoId", videoID)); SQLiteDataReader reader = cmd.ExecuteReader(); if (reader.Read()) { videoInfo = new VideoInfo { CourseTitle = reader.GetString(reader.GetOrdinal("CourseTitle")), ChapterTitle = reader.GetString(reader.GetOrdinal("ChapterTitle")), ChapterIndex = reader.GetInt32(reader.GetOrdinal("ChapterIndex")), VideoIndex = reader.GetInt32(reader.GetOrdinal("SortIndex")), VideoTitle = reader.GetString(reader.GetOrdinal("Title")) }; chapterID = reader.GetInt32(reader.GetOrdinal("ChapterId")); if (videoInfo.ChapterTitle.Contains(".")) { videoInfo.ChapterTitle = videoInfo.ChapterTitle.Split('.')[1].Trim(); } videoInfo.ChapterTitle = videoInfo.ChapterIndex > 9 ? $"{videoInfo.ChapterIndex} - {videoInfo.ChapterTitle}" : $"0{videoInfo.ChapterIndex} - {videoInfo.ChapterTitle}"; videoInfo.VideoID = videoID; videoInfo.CourseID = courseID; } //Extra Code to get Correct Serial No. of the Video stored in VideoPrefix int?FirstVideoSortIndex = null; if (chapterID.HasValue) { cmd = DatabaseConnection.CreateCommand(); cmd.CommandText = @"SELECT Video.SortIndex FROM Video WHERE Video.ChapterId = @chapterID ORDER BY Video.SortIndex"; cmd.Parameters.Add(new SQLiteParameter("@chapterID", chapterID)); reader = cmd.ExecuteReader(); if (reader.Read()) { FirstVideoSortIndex = reader.GetInt32(reader.GetOrdinal("SortIndex")); } } if (FirstVideoSortIndex.HasValue) { int SerialNo = videoInfo.VideoIndex - (int)FirstVideoSortIndex + 1; videoInfo.VideoPrefix = SerialNo < 10 ? "0" + SerialNo : SerialNo.ToString(); } else { //Debug.WriteLine("FirstVideoSortIndex = " + FirstVideoSortIndex); videoInfo.VideoPrefix = videoInfo.VideoIndex.ToString(); } //############################################################################### } catch (Exception e) { WriteToConsole($"[ERR] Exception occured during db query ({courseID}/{videoID}): {e.Message}", Color.Yellow); videoInfo = null; } return(videoInfo); }
/// <summary> /// Decrypt all files in a given folder /// </summary> /// <param name="folderPath">path to folder with encrypted .lynda files</param> /// <param name="outputFolder">specify an output folder</param> public async Task DecryptAll(string folderPath, string outputFolder = "") { if (!Directory.Exists(folderPath)) { throw new DirectoryNotFoundException(); } if (string.IsNullOrWhiteSpace(outputFolder)) { outputFolder = Path.Combine(Path.GetDirectoryName(folderPath), "decrypted"); } OutputDirectory = Directory.Exists(outputFolder) ? new DirectoryInfo(outputFolder) : Directory.CreateDirectory(outputFolder); IEnumerable <string> files = Directory.EnumerateFiles(folderPath, "*.lynda", SearchOption.AllDirectories) .Concat(Directory.EnumerateFiles(folderPath, "*.ldcw", SearchOption.AllDirectories)); TotalFiles = files.Count(); foreach (string entry in files) { string newPath = string.Empty; string item = entry; if (Options.UseDatabase) { try { // get metadata with courseID and videoID VideoInfo videoInfo = GetVideoInfoFromDB(new DirectoryInfo(Path.GetDirectoryName(item)).Name, Path.GetFileName(item).Split('_')[0]); if (videoInfo != null) { // create new path and folder string complexTitle, simpleTitle, VideoPrefix; VideoPrefix = videoInfo.ChapterIndex < 10 ? $"0{videoInfo.ChapterIndex}-{videoInfo.VideoPrefix}" : $"{videoInfo.ChapterIndex}-{videoInfo.VideoPrefix}"; complexTitle = $"{VideoPrefix} - {videoInfo.VideoTitle}.mp4"; simpleTitle = $"{VideoPrefix}.mp4"; newPath = Path.Combine(OutputDirectory.FullName, CleanPath(videoInfo.CourseTitle), CleanPath(videoInfo.ChapterTitle), CleanPath(complexTitle)); if (newPath.Length > 240) { newPath = Path.Combine(OutputDirectory.FullName, CleanPath(videoInfo.CourseTitle), CleanPath(videoInfo.ChapterTitle), CleanPath(simpleTitle)); } if (!Directory.Exists(Path.GetDirectoryName(newPath))) { Directory.CreateDirectory(Path.GetDirectoryName(newPath)); } } } catch (Exception e) { WriteToConsole($"[ERR] Could not retrive media information from database! Exception: {e.Message} Falling back to default behaviour!", Color.Yellow); } } if (String.IsNullOrWhiteSpace(newPath)) { newPath = Path.ChangeExtension(item, ".mp4"); } await Semaphore.WaitAsync(); TaskList.Add(Task.Run(() => { ct.ThrowIfCancellationRequested(); Decrypt(item, newPath); if (Options.SubTitle == true) { ConvertSub(item, newPath, Options.RemoveFilesAfterDecryption); } lock (SemaphoreLock) { Semaphore.Release(); } }, ct)); } await Task.WhenAll(TaskList); WriteToConsole("Decryption completed!", Color.Blue); MessageBox.Show("Decryption completed!", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); }