Example #1
0
        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();
        }
Example #2
0
        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);
        }