Click here to Skip to main content
15,897,273 members
Articles / Desktop Programming / WPF

Use LINQ to Create Music Playlists – Revisited

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
27 Apr 2009CPOL4 min read 23.9K   421   12  
A re-write of a previous article. Still using LINQ, but incorporating much more in this iteration 2 version.
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;

namespace PlaylistCreatorFP
{
    public delegate void ErrorEventHandler(object sender, PlaylistCreatorErrorEventArgs e);
    public delegate void MessageEventHandler(object sender, PlaylistCreatorMessageEventArgs e);

    public class PCEngine
    {
        #region Members and Properties

        private DataSetDiskFiles _dsDiskFiles;
        public DataSetDiskFiles DsDiskFiles
        {
            get
            {
                if (_dsDiskFiles == null)
                    _dsDiskFiles = new DataSetDiskFiles();
                return _dsDiskFiles;
            }
        }

        private List<string> _curPlayList;
        private string[] _includeExts;

        #endregion

        #region Events

        public event ErrorEventHandler ErrorOccured;
        protected virtual void OnError(PlaylistCreatorErrorEventArgs e)
        {
            if (ErrorOccured != null)
                ErrorOccured(this, e);
        }

        public event MessageEventHandler SendMessage;
        protected virtual void OnMessage(PlaylistCreatorMessageEventArgs e)
        {
            if (SendMessage != null)
                SendMessage(this, e);
        }

        #endregion

        /// <summary>
        /// Main routine for gathering files information and dumping into an in-memory DataSet
        /// </summary>
        /// <param name="inPath">The folder path at the top of the branch to process</param>
        /// <param name="removeExisting">Option to remove preexisting play list files.  Works with the removeExt patameter</param>
        /// <param name="removeExt">Play list extension to look for to remove.  Works with the removeExisting parameter</param>
        /// <param name="searchPattern">A comma delimited list of file extensions to include in playlist creation</param>
        public void SearchDisk(string inPath, string searchPattern, bool removeExisting, string removeExt)
        {
            if (_includeExts == null)
            {
                _includeExts = searchPattern.Split(new char[] { ',' });
                for (int i = 0; i < _includeExts.Length; i++)
                {
                    _includeExts[i] = _includeExts[i].Trim().Replace(".", "");
                }
            }

            // Insert the root folder node and any files at the root level
            SearchDiskFiles(inPath, removeExisting, removeExt, AddFolderRecord(inPath, true));

            // Traverse tree, adding found files as we go
            string[] dirs = Directory.GetDirectories(inPath, PCConstants.ALLFILES_SEARCH_PATTERN, SearchOption.AllDirectories);

            SendMessage(this, new PlaylistCreatorMessageEventArgs()
            {
                MessageText = string.Format(PCConstants.FORMATTED_MESSAGE_NUM_FILES_FOUND, dirs.Count())
            });

            foreach (string dir in dirs.OrderBy(x => x))
            {
                SearchDiskFiles(dir, removeExisting, removeExt, AddFolderRecord(dir, false));
            }
        }

        /// <summary>
        /// Generates playlist files from collected disc information
        /// </summary>
        /// <param name="playlistFilename"></param>
        public void CreatePlayLists(string playlistFilename)
        {
            if (_curPlayList == null)
                _curPlayList = new List<string>();

            string curPath = "";

            foreach (DataSetDiskFiles.PCFoldersRow foldersRow in DsDiskFiles.PCFolders)
            {
                // Populate list from current branch
                _curPlayList.Clear();
                GetBranch(foldersRow.FolderId);

                // Prep list before writing to disk
                curPath = foldersRow.FolderPath;
                if (!curPath.EndsWith(@"\"))
                    curPath += @"\";
                for (int i = 0; i < _curPlayList.Count; i++)
                {
                    _curPlayList[i] = _curPlayList[i].Replace(curPath, "");
                }

                SendMessage(this, new PlaylistCreatorMessageEventArgs() 
                { 
                    MessageText = string.Format(PCConstants.FORMATTED_MESSAGE_PLAYLIST_CREATED, Path.Combine(curPath, playlistFilename)) 
                });
                WritePlaylist(Path.Combine(curPath, playlistFilename));
            }
        }

        private void SearchDiskFiles(string inPath, bool removePlaylist, string removePlaylistExt, int folderId)
        {
            DirectoryInfo di = new DirectoryInfo(inPath);
            string curFileExt;
            foreach (FileInfo file in di.GetFiles(PCConstants.ALLFILES_SEARCH_PATTERN, SearchOption.TopDirectoryOnly))
            {
                curFileExt = file.Extension.Replace(".", "");
                if (_includeExts.Contains(curFileExt))
                {
                    AddFileRecord(file.FullName, folderId);
                }
                if (removePlaylist && curFileExt == removePlaylistExt.Replace(".", ""))
                {
                    try
                    {
                        File.Delete(file.FullName);
                    }
                    catch (Exception ex)
                    {
                        ErrorOccured(this, new PlaylistCreatorErrorEventArgs() { ErrorMessage = ex.Message });
                    }
                }
            }
        }
        int AddFolderRecord(string inPath, bool rootNode)
        {
            var res = from f in DsDiskFiles.PCFolders
                      where f.FolderPath == inPath
                      select f;
            if (res.Count() > 0)
                return res.FirstOrDefault().FolderId;

            DataSetDiskFiles.PCFoldersRow fr = DsDiskFiles.PCFolders.NewPCFoldersRow();

            if (rootNode)
            {
                fr.ParentId = 0;
            }
            else
            {
                DirectoryInfo di = new DirectoryInfo(inPath);
                fr.ParentId =
                    (from f in DsDiskFiles.PCFolders
                     where f.FolderPath == di.Parent.FullName
                     select f.FolderId).FirstOrDefault();
            }

            if (string.IsNullOrEmpty(inPath) || inPath.Trim() == "")
                fr.SetFolderPathNull();
            else
                fr.FolderPath = inPath;

            try
            {
                DsDiskFiles.PCFolders.AddPCFoldersRow(fr);
                return fr.FolderId;
            }
            catch (Exception ex)
            {
                ErrorOccured(this, new PlaylistCreatorErrorEventArgs() { ErrorMessage = ex.Message });
                return -1;
            }
        }
        void AddFileRecord(string inPath, int folderId)
        {
            DataSetDiskFiles.PCFilesRow flr = DsDiskFiles.PCFiles.NewPCFilesRow();

            flr.FolderId = folderId;

            if (string.IsNullOrEmpty(inPath) || inPath.Trim() == "")
            {
                flr.SetFilenameNull();
            }
            else
            {
                FileInfo fi = new FileInfo(inPath);
                flr.Filename = fi.Name;
            }

            try
            {
                DsDiskFiles.PCFiles.AddPCFilesRow(flr);
            }
            catch (Exception ex)
            {
                ErrorOccured(this, new PlaylistCreatorErrorEventArgs() { ErrorMessage = ex.Message });
            }
        }

        void GetBranch(int folderId)
        {
            DataSetDiskFiles.PCFoldersRow folderRow = DsDiskFiles.PCFolders.FindByFolderId(folderId);
            if (folderRow == null)
                return;

            DataRelation selfJoin = DsDiskFiles.PCFolders.ChildRelations[1];

            GetNodeFiles(folderRow.FolderId);

            DataSetDiskFiles.PCFoldersRow[] fRows = (DataSetDiskFiles.PCFoldersRow[])folderRow.GetChildRows(selfJoin);
            foreach (DataSetDiskFiles.PCFoldersRow fRow in fRows)
            {
                GetBranch(fRow.FolderId);
            }
        }
        void GetNodeFiles(int folderId)
        {
            var res = from flds in DsDiskFiles.PCFolders
                      join fls in DsDiskFiles.PCFiles on flds.FolderId equals fls.FolderId
                      where flds.FolderId == folderId
                      select new { FullPath = Path.Combine(flds.FolderPath, fls.Filename) };
            foreach (var fp in res)
            {
                _curPlayList.Add(fp.FullPath);
            }
        }

        void WritePlaylist(string inPath)
        {
            try
            {
                using (TextWriter tw = new StreamWriter(inPath, false))
                {
                    foreach (string file in _curPlayList)
                    {
                        tw.WriteLine(file);
                    }
                }
            }
            catch (Exception ex)
            {
                ErrorOccured(this, new PlaylistCreatorErrorEventArgs() { ErrorMessage = ex.Message });
            }
        }

    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
United States United States
Dave has been working in the software industry for a few years now. Having graduated with his BS in Computer Science & Engineering from the University of Toledo in 2002, Dave enjoys learning about new technologies and likes to apply new programming methods to solve age-old challenges. In his spare time he is addicted to movies (sci-fi, horror, anything good!) and spending time with family and friends. Dave also harbors a secret desire to make it big in the film/music industry—here’s lookin’ at you, kid! ;o)

Comments and Discussions