private void runExtractor() { string[] fileArray; try { fileArray = Directory.GetFiles(textBox_folder.Text, "*.mp3", Properties.Settings.Default.importFromSubfolders ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly); } catch (System.IO.DirectoryNotFoundException) { MessageBox.Show("Input directory does not exist!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } Console.WriteLine($"Found {fileArray.Length} mp3 files"); toolStripStatusLabel1.Text = $"Found {fileArray.Length} mp3 files"; statusStrip1.Update(); //------------------------------------------------------------------------------ toolStripStatusLabel1.Text = $"Finding extractors..."; statusStrip1.Update(); List <TokenExtractor> teList = new List <TokenExtractor>(); string[] tokenExtractorFileArray = Directory.GetFiles("extractors/", "*.json", SearchOption.AllDirectories); TokenExtractorConverter teConverter = new TokenExtractorConverter(); foreach (string s in tokenExtractorFileArray) { if (Properties.Settings.Default.disabledExtractors != null) { if (Properties.Settings.Default.disabledExtractors.Contains(Path.GetFileName(s))) { Console.WriteLine($"Ommitting json file {Path.GetFileName(s)}"); continue; } } using (StreamReader r = new StreamReader(s)) { string json = r.ReadToEnd(); teList.Add(JsonConvert.DeserializeObject <TokenExtractor>(json, teConverter)); Console.WriteLine($"Found json file {Path.GetFileName(s)}"); } } // time to order the TokenExtractors teList.Sort(delegate(TokenExtractor x, TokenExtractor y) { if (x.delimiters.Length == y.delimiters.Length) { if (x.indexMap.Count == y.indexMap.Count) { return(0); } else if (x.indexMap.Count > y.indexMap.Count) { return(1); } else if (x.indexMap.Count < y.indexMap.Count) { return(-1); } return(0); } else if (x.delimiters.Length > y.delimiters.Length) { return(1); } else if (x.delimiters.Length < y.delimiters.Length) { return(-1); } else { return(0); } }); teList.Reverse(); Console.WriteLine("Sorted List:"); foreach (TokenExtractor t in teList) { Console.WriteLine($" {t.name}"); } MusicDiscoverer md = new MusicDiscoverer(); //string[] fileArray = Directory.GetFiles(textBox_folder.Text, "*.mp3", SearchOption.AllDirectories); Console.WriteLine($"Found {fileArray.Length} mp3 files"); Dictionary <string, TrackProperties> inputFiles = new Dictionary <string, TrackProperties>(); foreach (string s in fileArray) { inputFiles[s] = new TrackProperties(s, new Track()); inputFiles[s].shortFilename = Path.GetFileNameWithoutExtension(s); } toolStripStatusLabel1.Text = $"Extracting/searching for tags..."; statusStrip1.Update(); bool noInternet = false; foreach (KeyValuePair <string, TrackProperties> inputFile in inputFiles) { foreach (TokenExtractor te in teList) { if (inputFile.Value.addTrackIfNotNull(te.extractProperties(inputFile.Value.shortFilename))) { inputFile.Value.track.track = Regex.Replace(inputFile.Value.track.track, "feat.", "ft.", RegexOptions.IgnoreCase); inputFile.Value.track.dataFrom = "Extracted"; break; } } inputFile.Value.checkMapStatus(); if (inputFile.Value.mappedStatus == TrackProperties.PARTIALLY_MAPPED || inputFile.Value.mappedStatus == TrackProperties.NOT_MAPPED) { //Console.WriteLine($"Need to find missing information for {inputFile.Value.shortFilename}"); List <string> keywords = new List <string>(); string title; if (!inputFile.Value.isNullOrEmpty(inputFile.Value.track.track)) { title = inputFile.Value.track.track; } else { title = Regex.Replace(inputFile.Value.shortFilename, "feat.", "ft.", RegexOptions.IgnoreCase); } title = RemoveBetween(title, '[', ']'); title = RemoveBetween(title, '(', ')'); // it should always be ft. now int index = title.IndexOf("ft."); if (index > 0) { title = title.Substring(0, index); } title = title.Trim(); keywords.AddRange(title.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries)); if (!inputFile.Value.isNullOrEmpty(inputFile.Value.track.artist)) { keywords.Add(inputFile.Value.track.artist); } if (!inputFile.Value.isNullOrEmpty(inputFile.Value.track.album)) { keywords.Add(inputFile.Value.track.album); } Track[] suggestedTracks = md.getSuggestedSongs(keywords.ToArray(), 5); // number is PER API if (suggestedTracks == null) { noInternet = true; continue; } if (suggestedTracks.Length > 0) // make sure we have at least one suggested track { foreach (Track t in suggestedTracks) { t.trackLevDistance = CalcLevenshteinDistance(t.track, inputFile.Value.track.track); t.artistLevDistance = CalcLevenshteinDistance(t.artist, inputFile.Value.track.artist); } // now we sort the suggested tracks in order of artistLevDistance, then trackLevDistance Array.Sort(suggestedTracks, delegate(Track x, Track y) { if (x.artistLevDistance == y.artistLevDistance) { if (x.trackLevDistance == y.trackLevDistance) { return(0); } else if (x.trackLevDistance > y.trackLevDistance) { return(1); } else if (x.trackLevDistance < y.trackLevDistance) { return(-1); } } else if (x.artistLevDistance > y.artistLevDistance) { return(1); } else if (x.artistLevDistance < y.artistLevDistance) { return(-1); } return(0); }); // grab the top 5? and store them inputFile.Value.suggestedTracks = new List <Track>(); for (int i = 0; i < Math.Min(suggestedTracks.Length, 5); i++) { inputFile.Value.suggestedTracks.Add(suggestedTracks[i]); } // if we have a GOOD match, copy the content if (inputFile.Value.suggestedTracks[0].artistLevDistance + inputFile.Value.suggestedTracks[0].trackLevDistance < 10) { inputFile.Value.track = inputFile.Value.suggestedTracks[0]; //Console.WriteLine($"Found match for {inputFile.Value.shortFilename}, copying content"); } } inputFile.Value.checkMapStatus(); // make sure to update the status - we'll be using this in the UI stuff! // if we're STILL missing stuff, let's try and get it from other songs by the same artist // If I think of other stuff to add here, use if (inputFile.Value.mappedStatus == TrackProperties.PARTIALLY_MAPPED || inputFile.Value.mappedStatus == TrackProperties.NOT_MAPPED) again to check for missing if (inputFile.Value.track != null && inputFile.Value.isNullOrEmpty(inputFile.Value.track.genre)) { //Console.WriteLine($"Genre missing for ({inputFile.Value.shortFilename})"); if (inputFile.Value.track.artist != "") { // if we have an artist, let's look at their other songs // could try adding album here, but it is likely that the album is not there if have got to this stage Track[] otherTracksByArtist = md.getSuggestedSongs(new[] { inputFile.Value.track.artist }, 10); if (otherTracksByArtist.Length > 0) { Console.WriteLine($"Found a bunch of other songs({otherTracksByArtist.Length}) by the same artist"); // let's find the most popular genre Dictionary <string, int> possibleGenres = new Dictionary <string, int>(); foreach (Track t in otherTracksByArtist) { if (possibleGenres.ContainsKey(t.genre)) { possibleGenres[t.genre]++; } else { possibleGenres[t.genre] = 1; } } List <KeyValuePair <string, int> > possibleGenresList = possibleGenres.ToList(); possibleGenresList.Sort(delegate(KeyValuePair <string, int> pair1, KeyValuePair <string, int> pair2) { return(pair1.Value.CompareTo(pair2.Value)); }); Console.WriteLine($"Best genre match: {possibleGenresList[0].Key}"); inputFile.Value.track.genre = possibleGenresList[0].Key; inputFile.Value.track.genreFrom = "API"; } } } } } if (noInternet) { MessageBox.Show("Cannot connect to the internet!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } // -------------------------------------------------------------------- // let's move featured stuff into the track name if it's in the artist foreach (KeyValuePair <string, TrackProperties> inputFile in inputFiles) { if (!isNullOrEmpty(inputFile.Value.track.artist)) { if (inputFile.Value.track.artist.Contains("(ft.", StringComparison.OrdinalIgnoreCase)) { Regex regex = new Regex(string.Format(@"\(ft\..*\)")); string featuredArtist = getBetween(inputFile.Value.track.artist, "(ft. ", ")").Trim(); Console.WriteLine("Found featured artist: " + featuredArtist); inputFile.Value.track.artist = regex.Replace(inputFile.Value.track.artist, string.Empty).Trim(); // now add the feat. to trackname inputFile.Value.track.track += " (ft. " + featuredArtist + ")"; } else if (inputFile.Value.track.artist.Contains("ft.", StringComparison.OrdinalIgnoreCase)) { /*Regex regex = new Regex(string.Format(@"ft\..*")); * string featuredArtist = inputFile.Value.track.artist.Substring(inputFile.Value.track.artist.IndexOf(("ft.") + 3)); * Console.WriteLine("LOLOL: Found featured artist: " + featuredArtist); * inputFile.Value.track.artist = regex.Replace(inputFile.Value.track.artist, string.Empty).Trim();*/ // TODO: then add ft. to trackname or whatever } if (inputFile.Value.track.artist.Contains("(feat.", StringComparison.OrdinalIgnoreCase)) { Regex regex = new Regex(string.Format(@"\(feat\..*\)")); string featuredArtist = getBetween(inputFile.Value.track.artist, "(feat. ", ")").Trim(); Console.WriteLine("Found featured artist: " + featuredArtist); inputFile.Value.track.artist = regex.Replace(inputFile.Value.track.artist, string.Empty).Trim(); // now add the feat. to trackname inputFile.Value.track.track += " (ft. " + featuredArtist + ")"; } else if (inputFile.Value.track.artist.Contains("feat.", StringComparison.OrdinalIgnoreCase)) { /*Regex regex = new Regex(string.Format(@"\(feat\..*")); * inputFile.Value.track.artist = regex.Replace(inputFile.Value.track.artist, string.Empty).Trim();*/ // TODO: then add ft. to trackname or whatever } } } toolStripStatusLabel1.Text = $"Updating table..."; statusStrip1.Update(); dataGridView1.Rows.Clear(); foreach (KeyValuePair <string, TrackProperties> inputFile in inputFiles) { dataGridView1.Rows.Add(new[] { inputFile.Value.shortFilename, "", inputFile.Value.track.track, inputFile.Value.track.artist, inputFile.Value.track.album, inputFile.Value.track.genre, inputFile.Value.track.dataFrom, "", inputFile.Value.longFilename }); if (inputFile.Value.track.genreFrom == "API") { dataGridView1[5, dataGridView1.Rows.GetLastRow(DataGridViewElementStates.None)].Style.BackColor = System.Drawing.Color.CadetBlue; } if (inputFile.Value.mappedStatus == TrackProperties.NOT_MAPPED) { dataGridView1.Rows[dataGridView1.Rows.GetLastRow(DataGridViewElementStates.None)].DefaultCellStyle.BackColor = System.Drawing.Color.IndianRed; dataGridView1[7, dataGridView1.Rows.GetLastRow(DataGridViewElementStates.None)].Value = "Empty"; } if (inputFile.Value.mappedStatus == TrackProperties.PARTIALLY_MAPPED) { dataGridView1.Rows[dataGridView1.Rows.GetLastRow(DataGridViewElementStates.None)].DefaultCellStyle.BackColor = System.Drawing.Color.Gold; dataGridView1[7, dataGridView1.Rows.GetLastRow(DataGridViewElementStates.None)].Value = "Partial"; } if (inputFile.Value.mappedStatus == TrackProperties.FULLY_MAPPED) { dataGridView1.Rows[dataGridView1.Rows.GetLastRow(DataGridViewElementStates.None)].DefaultCellStyle.BackColor = System.Drawing.Color.ForestGreen; dataGridView1[7, dataGridView1.Rows.GetLastRow(DataGridViewElementStates.None)].Value = "Full"; } } toolStripStatusLabel1.Text = $"Finished"; statusStrip1.Update(); }
private void button_export_Click(object sender, EventArgs e) { if (!Directory.Exists(textBox_outputFolder.Text)) { MessageBox.Show("Output folder does not exist", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (dataGridView1.RowCount == 0) { MessageBox.Show("No files to operate on", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } int outputFilenamesStatus = checkOutputFilenames(); if (outputFilenamesStatus == 1) { MessageBox.Show("One or more bad filenames!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (outputFilenamesStatus == 2) { MessageBox.Show("One or more duplicate filenames!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } foreach (DataGridViewRow r in dataGridView1.Rows) { TrackProperties tp = new TrackProperties((string)r.Cells["Longfilename"].Value, new Track()); tp.track.artist = (string)r.Cells["Artist"].Value; tp.track.track = (string)r.Cells["Track"].Value; tp.track.genre = (string)r.Cells["Genre"].Value; tp.track.album = (string)r.Cells["Album"].Value; tp.shortFilename = (string)r.Cells["Output Filename"].Value; string pathTofile; try { if (Properties.Settings.Default.exportToFolders) { if (tp.isNullOrEmpty(tp.track.artist)) { MessageBox.Show("Artist is missing on a track! (Trying to export to Artist/(Album/)Outputfilename", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } if (Properties.Settings.Default.exportToAlbumFolders) { if (tp.isNullOrEmpty(tp.track.album)) { MessageBox.Show("Album is missing on a track! (Trying to export to Artist/Album/Outputfilename", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } Directory.CreateDirectory(textBox_outputFolder.Text + "/" + tp.track.artist); Directory.CreateDirectory(textBox_outputFolder.Text + "/" + tp.track.artist + "/" + tp.track.album); pathTofile = textBox_outputFolder.Text + "/" + tp.track.artist + "/" + tp.track.album + "/" + tp.shortFilename + ".mp3"; System.IO.File.Copy(tp.longFilename, pathTofile); } else if (Properties.Settings.Default.exportToFolders) { Directory.CreateDirectory(textBox_outputFolder.Text + "/" + tp.track.artist); pathTofile = textBox_outputFolder.Text + "/" + tp.track.artist + "/" + tp.shortFilename + ".mp3"; System.IO.File.Copy(tp.longFilename, pathTofile); } else { pathTofile = textBox_outputFolder.Text + "/" + tp.shortFilename + ".mp3"; System.IO.File.Copy(tp.longFilename, pathTofile); } } catch (IOException err) { MessageBox.Show("Attempted to overwrite a file! Make sure the output directory is clear.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); Console.WriteLine("Attempted to overwrite a file! Make sure the output directory is clear."); Console.WriteLine(err.ToString()); return; } // now tag stuff TagLib.File file = TagLib.File.Create(pathTofile); Tag tagv1 = file.GetTag(TagTypes.Id3v1); if (!tp.isNullOrEmpty(tp.track.track)) { file.Tag.Title = tp.track.track; tagv1.Title = tp.track.track; } if (!tp.isNullOrEmpty(tp.track.album)) { file.Tag.Album = tp.track.album; tagv1.Album = tp.track.album; } if (!tp.isNullOrEmpty(tp.track.genre)) { file.Tag.Genres = new[] { tp.track.genre }; tagv1.Genres = new[] { tp.track.genre }; } if (!tp.isNullOrEmpty(tp.track.artist)) { string[] artists = tp.track.artist.Split('&'); foreach (string artist in artists) { artist.Trim(); } file.Tag.AlbumArtists = artists; file.Tag.Artists = artists; tagv1.AlbumArtists = artists; tagv1.Artists = artists; } file.Save(); file.Dispose(); } MessageBox.Show("Sucessfully outputted all files", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information); }