From 5df80c93c3e27e0135d59b78de0277bba2d5e87f Mon Sep 17 00:00:00 2001 From: Raymond Krehn Date: Thu, 2 May 2024 16:57:44 -0600 Subject: [PATCH] 1.6 (#4) * - Re-added timer to check on mp3 file conversions and implemented levenshtein to validate it's a file that needs to be converted - Added right-click menu on datagrid to clear it out - Added right-click menu item to restart failed downloads/conversion - Added right-click menu item to open data file directory - Set default state to "paused" so user can make adjustments/fixes before starting process --- Form1.Designer.cs | 2 +- Form1.cs | 218 +++++++++++++++++++++++++++++++++------------- YTPD.csproj | 2 +- 3 files changed, 160 insertions(+), 62 deletions(-) diff --git a/Form1.Designer.cs b/Form1.Designer.cs index ae7c9ee..6696d92 100644 --- a/Form1.Designer.cs +++ b/Form1.Designer.cs @@ -254,7 +254,7 @@ private void InitializeComponent() // contextMenuStrip1.Items.AddRange(new ToolStripItem[] { menu_cleardata, openDataFileToolStripMenuItem, RestartBadItems }); contextMenuStrip1.Name = "contextMenuStrip1"; - contextMenuStrip1.Size = new Size(213, 70); + contextMenuStrip1.Size = new Size(213, 92); // // menu_cleardata // diff --git a/Form1.cs b/Form1.cs index 7e4e976..de5faf7 100644 --- a/Form1.cs +++ b/Form1.cs @@ -9,6 +9,8 @@ using System.Diagnostics; using Microsoft.VisualBasic; using Fastenshtein; +using File = System.IO.File; +using static System.Windows.Forms.LinkLabel; namespace YTPD { @@ -112,11 +114,6 @@ private async void timer1_Tick(object sender, EventArgs e) continue; } - if (row.Cells[0].Value.ToString().ToLower().Contains("romeo")) - { - song = ""; - } - Int16 dlpercent = Convert.ToInt16(row.Cells["DL"].Value); if (dlpercent > 0 && dlpercent < 100) return; @@ -190,7 +187,7 @@ private async void timer1_Tick(object sender, EventArgs e) { isConverting = true; await ConvertFile(fullpath, fullpath.Substring(fullpath.LastIndexOf('.'))); - Console.WriteLine(fullpath); + AppendToFile(fullpath); isConverting = false; } } @@ -209,6 +206,7 @@ static async Task ConvertFile(string inputFilePath, string fileExt) { string outputFilePath = inputFilePath.Replace(fileExt, ".mp3"); string ffmpegcom = $"-n -i \"{inputFilePath}\" \"{outputFilePath}\""; + int exitCode = 1; // Setup parameters ProcessStartInfo psi = new ProcessStartInfo() @@ -216,7 +214,9 @@ static async Task ConvertFile(string inputFilePath, string fileExt) FileName = "ffmpeg", Arguments = ffmpegcom, CreateNoWindow = true, - UseShellExecute = false + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true }; // Start the process @@ -224,36 +224,86 @@ static async Task ConvertFile(string inputFilePath, string fileExt) { process.Start(); + // Read the output and error streams + string error = process.StandardError.ReadToEnd(); + // Wait for the process to exit - await Task.Run(() => process.WaitForExit()); + await Task.Run(() => process.WaitForExit(1200000)); + + // Display the errors + AppendToFile("FFmpeg Errors:"); + AppendToFile(error); // Check the exit code - int exitCode = process.ExitCode; + exitCode = process.ExitCode; - // Handle the result based on the exit code - if (exitCode == 0) + // process errors that can skip to exit + if (error.Contains("No such file") || error.Contains("Invalid data") || error.Contains("already exists") || error.Contains("not in a correct format")) exitCode = 0; + + // file existence errors that can be skipped + if (!System.IO.File.Exists(outputFilePath) || !System.IO.File.Exists(inputFilePath)) exitCode = 0; + + while (process.HasExited == true || exitCode == 0) { - Console.WriteLine("Conversion completed successfully."); - await Task.Run(() => System.IO.File.Delete(inputFilePath)); + if (process.HasExited == true) + { + break; + } else + { + await Task.Delay(1000); + AppendToFile("Waiting for process..."); + + } } - else + } + + + // wait to delete file + Int16 waitcounter = 0; + while (true) + { + waitcounter += 1; + try + { + using (FileStream fileStream = File.OpenWrite(inputFilePath)) + { + break; + } + } + catch (IOException) { - Console.WriteLine($"Error: {exitCode}"); + if (waitcounter > 5) + { + AppendToFile("I can't close the file. Giving up."); + return; + } + + // File is still locked or in use by another process + AppendToFile("File is locked. Waiting for it to become available..."); + Thread.Sleep(60000); // Wait for 1 minute before retrying } } + + // Notify file deletion + AppendToFile("Exit code received, deleting original file."); + await Task.Run(() => System.IO.File.Delete(inputFilePath)); } private void timer_tag_Tick(object sender, EventArgs e) { - string[] artist; - string album = ""; - string songnum = ""; - string song = ""; - string duration = ""; - string link = ""; foreach (DataGridViewRow row in dgv_downloads.Rows) { + // setup variables + bool FoundFile = false; + string[] artist = new[] { "" }; + string album = ""; + string songnum = ""; + string song = ""; + string duration = ""; + string link = ""; + string fullpath = ""; + if (row.Cells[0].Value == null || row.Cells[0].Value == "") return; Int16 dlpercent = Convert.ToInt16(row.Cells["DL"].Value); @@ -267,52 +317,61 @@ private void timer_tag_Tick(object sender, EventArgs e) link = row.Cells["Link"].Value.ToString(); // actual stream - string fullpath = Path.Combine(txt_Dir.Text + "\\" + GetValidFilename(row.Cells["Artist"].Value.ToString()) + "\\" + GetValidFilename(album), songnum + " - " + GetValidFilename(song) + ".mp3"); + fullpath = Path.Combine(txt_Dir.Text + "\\" + GetValidFilename(row.Cells["Artist"].Value.ToString()) + "\\" + GetValidFilename(album), songnum + " - " + GetValidFilename(song) + ".mp3"); // does the file exist? If not, marked it tagged as the user probably moved it already if (!System.IO.File.Exists(fullpath)) { continue; + } else { + FoundFile = true; } - // check if file is in use - bool fileInUse = true; - while (fileInUse) - { - try - { - // Attempt to open the file with FileShare.None to check if it's in use - using (var fileStream = new FileStream(fullpath, FileMode.Open, FileAccess.Read, FileShare.None)) - { - // if the file can be opened, then let's write the mp3 tags - fileInUse = false; - } - } - catch (IOException) - { - // File is still in use, wait for a short duration before trying again - continue; - } - } - - var tagfile = TagLib.File.Create(fullpath); - - tagfile.Tag.AlbumArtists = artist; - tagfile.Tag.Artists = artist; - tagfile.Tag.Album = album; - tagfile.Tag.Title = song; - tagfile.Tag.Comment = link; - tagfile.Tag.Track = Convert.ToUInt16(songnum); - tagfile.Save(); - + TagFile(fullpath, artist, album, song, link, songnum); row.Cells["Tagged"].Value = "1"; row.Cells["Converted"].Value = "Yes"; } else if (dlpercent == 100 && row.Cells["Tagged"].Value.ToString() == "1") { row.Cells["Converted"].Value = "Yes"; + } + } + } + + private void TagFile(string fullpath, string[] artist, string album, string song, string link, string songnum) + { + // check if file is in use + bool fileInUse = true; + while (fileInUse) + { + try + { + // Attempt to open the file with FileShare.None to check if it's in use + using (var fileStream = new FileStream(fullpath, FileMode.Open, FileAccess.Read, FileShare.None)) + { + // if the file can be opened, then let's write the mp3 tags + fileInUse = false; + } + } + catch (IOException) + { + // File is still in use, wait for a short duration before trying again + AppendToFile(fullpath + " in use. Waiting to tag..."); + continue; } } + + var tagfile = TagLib.File.Create(fullpath); + + tagfile.Tag.AlbumArtists = artist; + tagfile.Tag.Artists = artist; + tagfile.Tag.Album = album; + tagfile.Tag.Title = song; + tagfile.Tag.Comment = link; + tagfile.Tag.Track = Convert.ToUInt16(songnum); + tagfile.Save(); + + AppendToFile(fullpath + " successfully tagged with ID3. " + artist.ToString() + " > " + album + " > " + songnum + " > " + song); } private void SaveDataGridViewToCSV() @@ -348,11 +407,11 @@ private void SaveDataGridViewToCSV() } } - Console.WriteLine($"Data saved to {filePath}"); + AppendToFile($"Data saved to {filePath}"); } catch (Exception ex) { - Console.WriteLine($"Error saving data: {ex.Message}"); + AppendToFile($"Error saving data: {ex.Message}"); } finally { @@ -392,11 +451,11 @@ private void LoadCSVIntoDataGridView() } dgv_downloads.Refresh(); - Console.WriteLine($"Data loaded from {filePath}"); + AppendToFile($"Data loaded from {filePath}"); } catch (Exception ex) { - Console.WriteLine($"Error loading data: {ex.Message}"); + AppendToFile($"Error loading data: {ex.Message}"); } } @@ -435,7 +494,7 @@ private void button2_Click(object sender, EventArgs e) else { // Handle the case where the user canceled the dialog - Console.WriteLine("Folder selection canceled by the user."); + AppendToFile("Folder selection canceled by the user."); } } @@ -457,14 +516,18 @@ private async void timer_convert_Tick(object sender, EventArgs e) .Where(file => !file.EndsWith(".mp3", StringComparison.OrdinalIgnoreCase)) .ToArray(); - Console.WriteLine("\nNon-mp3 files files:" + nonMp3Files.Length); + if(nonMp3Files.Length == 0) return; + AppendToFile("\nNon-mp3 files files:" + nonMp3Files.Length); // converts non-mp3 to mp3 foreach (string nonMp3File in nonMp3Files) { + bool SongFound = false; + foreach (DataGridViewRow row in dgv_downloads.Rows) { if (row.Cells[0].Value == null || row.Cells[0].Value.ToString().Length == 0) continue; + // review levenshtein distance for mp3 file and song name so we only convert the mp3 string foundsong = nonMp3File.Substring(nonMp3File.LastIndexOf('\\') + 2); foundsong = foundsong.Substring(foundsong.IndexOf('-') + 2, foundsong.LastIndexOf('.') - 4); @@ -472,12 +535,20 @@ private async void timer_convert_Tick(object sender, EventArgs e) int lev = Levenshtein.Distance(foundsong, cellsong); // if threshold is met, then convert non-mp3 to mp3 - if (lev > 70) + if (lev < 5) { + AppendToFile("Levenshtein threshold passed [" + lev + "] - " + nonMp3File); await ConvertFile(nonMp3File, nonMp3File.Substring(nonMp3File.LastIndexOf('.'))); - Console.WriteLine(nonMp3File); + SongFound = true; + break; } } + + if(SongFound == false) + { + AppendToFile("Unable to find [" + nonMp3File + "'] in your downloaded songs. Attempting convert anyways..."); + await ConvertFile(nonMp3File, nonMp3File.Substring(nonMp3File.LastIndexOf('.'))); + } } } @@ -632,5 +703,32 @@ private void RestartBadItems_Click(object sender, EventArgs e) } } } + + public static void AppendToFile(string content) + { + string filePath = Application.StartupPath + "\\error.log"; + if(!System.IO.File.Exists(filePath)) + System.IO.File.Create(filePath); + + // Get the current date and time + string dateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); + + // Create the log entry with the date, time, and content + string logEntry = $"{dateTime} - {content}{Environment.NewLine}"; + + try + { + // Append the log entry to the file using StreamWriter + using (StreamWriter writer = File.AppendText(filePath)) + { + writer.Write(logEntry); + Console.WriteLine("Log entry appended to the file successfully."); + } + } + catch (Exception ex) + { + Console.WriteLine($"Error appending to the file: {ex.Message}"); + } + } } } diff --git a/YTPD.csproj b/YTPD.csproj index a27471c..6b28fa6 100644 --- a/YTPD.csproj +++ b/YTPD.csproj @@ -24,7 +24,7 @@ - +