Пример #1
0
        public async Task <OfflineSongInfo?> GetSongByFilePathAsync(string path)
        {
            OfflineSongInfo?output = null;

            //TODO: If text cannot be read, the problem is here vvv
            using (StreamReader sr = new StreamReader(infoFilePath, false))
            {
                LUint totalLines;
                if (!TryGetTotalLines(sr, out totalLines))
                {
                    return(null);
                }
                for (LUint i = 0; i < totalLines; i++)
                {
                    string songLine = await sr.ReadLineAsync();

                    if (SongCollectionFormatter.GetFilePath(songLine) == path)
                    {
                        output = new OfflineSongInfo(SongCollectionFormatter.DeserializeString(songLine).Value, i);
                        break;
                    }
                    else if (i == totalLines - 1)
                    {
                        //Last index
                        output = null;
                    }
                }
            }
            return(output);
        }
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="input"></param>
        /// <returns>Song.Null if cannot find a song</returns>
        public async Task <OfflineSongInfo?> GetSongByTitleAsync(string inputTitle)
        {
            OfflineSongInfo?off;

            //TODO: If text cannot be read, the problem is here vvv
            using (StreamReader sr = new StreamReader(infoFilePath, false))
            {
                LUint totalLines;
                if (!TryGetTotalLines(sr, out totalLines))
                {
                    return(null);
                }
#if !TRAINING
                string minDistanceObjStr = null;
                LUint  minDistance       = LUint.MaxValue;
                LUint  objTimesPlayed    = 0;
                LUint  lineNum           = 0;
                for (LUint i = 0; i < totalLines; i++)
                {
                    string songLine = await sr.ReadLineAsync();

                    string songTitle = SongCollectionFormatter.GetSongTitle(songLine);
                    LUint  distance  = diffService.DifferenceScore(inputTitle, songTitle);
                    if (distance < minDistance)
                    {
                        minDistanceObjStr = songLine;
                        objTimesPlayed    = SongCollectionFormatter.GetTimesPlayed(songLine);
                        lineNum           = i;
                        if (distance == 0)
                        {
                            break;
                        }
                    }
                    else if (distance == minDistance)
                    {
                        LUint songTimesPlayed = SongCollectionFormatter.GetTimesPlayed(songLine);
                        if (songTimesPlayed > objTimesPlayed)
                        {
                            minDistanceObjStr = songLine;
                            objTimesPlayed    = songTimesPlayed;
                            lineNum           = i;
                        }
                    }
                }
                if (minDistanceObjStr is null)
                {
                    off = null;
                }
                else
                {
                    off = new OfflineSongInfo(SongCollectionFormatter.DeserializeString(minDistanceObjStr).Value, lineNum);
                }
#endif
            }
            return(off);
        }
Пример #3
0
        public async Task <bool> TryReplaceSongAsync(OfflineSong oldSong, OfflineSong newSong)
        {
            bool replaced = false;

            using (StreamReader sr = File.OpenText(infoFilePath))
                using (StreamWriter sw = File.CreateText(infoFilePath + "temp"))
                {
                    //Get total lines
                    LUint totalLines;
                    //Read and assign to totalLines
                    if (!TryGetTotalLines(sr, out totalLines))
                    {
                        sr.Close();
                        await sw.FlushAsync();

                        File.Delete(infoFilePath + "temp");
                        return(false);
                    }
                    //Write totalLines on new one
                    await sw.WriteLineAsync(totalLines.ToString());

                    string findingString = SongCollectionFormatter.SongFormatter(oldSong);
                    for (LUint i = 0; i < totalLines; i++)
                    {
                        //Read new line
                        string songLine = await sr.ReadLineAsync();

                        if (songLine == findingString)
                        {
                            //Write new song if found
                            await sw.WriteLineAsync(SongCollectionFormatter.SongFormatter(newSong));

                            replaced = true;
                        }
                        else
                        {
                            //Write the line that was read if not found
                            await sw.WriteLineAsync(songLine);
                        }
                    }
                }
            if (replaced)
            {
                File.Delete(infoFilePath);
                File.Move(infoFilePath + "temp", infoFilePath);
                return(true);
            }
            else
            {
                File.Delete(infoFilePath + "temp");
                return(false);
            }
        }
Пример #4
0
        public async Task <OfflineSongInfo?> GetSongByURLAsync(string url)
        {
#if DEBUG
            LogHelper.Logln("Initializing GetSongByURLAsync(url) in Song Collection", LogType.Debug);
#endif
            OfflineSongInfo?output = null;
            //TODO: If text cannot be read, the problem is here vvv
            using (StreamReader sr = new StreamReader(infoFilePath, false))
            {
                LUint totalLines;
                if (!TryGetTotalLines(sr, out totalLines))
                {
                    return(null);
                }
#if DEBUG
                LogHelper.Logln($"There are a total of {totalLines} of songs.", LogType.Debug);
#endif
                for (LUint i = 0; i < totalLines; i++)
                {
                    string songLine = await sr.ReadLineAsync();

                    string oldUrl = SongCollectionFormatter.GetUrl(songLine);
#if DEBUG
                    LogHelper.Logln($"oldUrl = {oldUrl}", LogType.Debug);
#endif
                    if (oldUrl == url)
                    {
                        output = new OfflineSongInfo(SongCollectionFormatter.DeserializeString(songLine).Value, i);
                        break;
                    }
                    else if (i == totalLines - 1)
                    {
                        //Last index
                        output = null;
                    }
                }
            }
            return(output);
        }
Пример #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="lineNo"></param>
        /// <param name="newTimesPlayed"></param>
        /// <returns>Whether the program actually changed times played</returns>
        public async Task <bool> TryChangeTimesPlayed(LUint lineNo, LUint newTimesPlayed)
        {
            using (StreamWriter sw = File.CreateText(infoFilePath + "temp"))
                using (StreamReader sr = File.OpenText(infoFilePath))
                {
                    LUint  totalLines;
                    string line = await sr.ReadLineAsync();

                    if (!LUint.TryParse(line, out totalLines))
                    {
                        LogHelper.Logln($"{infoFilePath} is not encoded as expected.", LogType.Error);
                        sr.Close();
                        await sw.FlushAsync();

                        File.Delete(infoFilePath + "temp");
                        return(false);
                    }
                    if (totalLines == 0)
                    {
                        LogHelper.Logln($"Trying to change {infoFilePath}, which has 0 line of song in it!", LogType.Error);
                        sr.Close();
                        await sw.FlushAsync();

                        File.Delete(infoFilePath + "temp");
                        return(false);
                    }
                    if (totalLines < lineNo)
                    {
                        LogHelper.Logln($"Trying to change line {lineNo} out of {totalLines} in {infoFilePath}!.", LogType.Error);
                        sr.Close();
                        await sw.FlushAsync();

                        File.Delete(infoFilePath + "temp");
                        return(false);
                    }
                    try
                    {
                        await sw.WriteLineAsync(totalLines.ToString());

                        for (int i = 0; i < lineNo; i++)
                        {
                            await sw.WriteLineAsync(await sr.ReadLineAsync());
                        }
                        //Write the changing value
                        string changingString = await sr.ReadLineAsync();

                        await sw.WriteLineAsync(
                            SongCollectionFormatter.ChangeTimesPlayed(
                                changingString, newTimesPlayed));

                        for (; lineNo < totalLines; lineNo++)
                        {
                            await sw.WriteLineAsync(await sr.ReadLineAsync());
                        }
                    }
                    catch (Exception e)
                    {
                        LogHelper.Logln($"Error occured while reading {infoFilePath} and writing {infoFilePath + "temp"}. {e.Message}", LogType.Error);
                        sr.Close();
                        await sw.FlushAsync();

                        File.Delete(infoFilePath + "temp");
                        return(false);
                    }
                }
            try
            {
                File.Delete(infoFilePath);
                File.Move(infoFilePath + "temp", infoFilePath);
            }
            catch (Exception e)
            {
                LogHelper.Logln($"Error while deleting ${infoFilePath} and replacing {infoFilePath} with {infoFilePath + "temp"}. {e.Message}", LogType.Error);
            }
            LogHelper.Logln($"Successfully rewrite times played and flushed all underlying streams.", LogType.Success);
            return(true);
        }
Пример #6
0
        public async Task <bool> TryChangeTimesPlayed(LUint lineNo, OfflineSong offlineSong)
        {
            using (StreamWriter sw = File.CreateText(infoFilePath + "temp"))
                using (StreamReader sr = File.OpenText(infoFilePath))
                {
                    LUint  totalLines;
                    string line = await sr.ReadLineAsync();

                    #region Precautions
                    if (!LUint.TryParse(line, out totalLines))
                    {
                        LogHelper.Logln($"{infoFilePath} is not encoded as expected.", LogType.Error);
                        sr.Close();
                        await sw.FlushAsync();

                        File.Delete(infoFilePath + "temp");
                        return(false);
                    }
                    if (totalLines == 0)
                    {
                        LogHelper.Logln($"Trying to change {infoFilePath}, which has 0 line of song in it!", LogType.Error);
                        sr.Close();
                        await sw.FlushAsync();

                        File.Delete(infoFilePath + "temp");
                        return(false);
                    }
                    if (totalLines < lineNo)
                    {
                        LogHelper.Logln($"Trying to change line {lineNo} out of {totalLines} in {infoFilePath}!.", LogType.Error);
                        sr.Close();
                        await sw.FlushAsync();

                        File.Delete(infoFilePath + "temp");
                        return(false);
                    }
                    #endregion
                    //totalLines is now assigned
                    try
                    {
                        await sw.WriteLineAsync(totalLines.ToString());

                        bool songRearranged = false;
                        for (int i = 0; i < lineNo; i++)
                        {
                            string songLine = await sr.ReadLineAsync();

                            if (!songRearranged)
                            {
                                if (SongCollectionFormatter.GetTimesPlayed(songLine) == offlineSong.timesPlayed)
                                {
                                    int min = Math.Min(SongCollectionFormatter.GetSongTitle(songLine).Length
                                                       , offlineSong.song.Title.Length);
                                    for (int j = 0; j < min; j++)
                                    {
                                        if (offlineSong.song.Title[j] < SongCollectionFormatter.GetSongTitle(songLine)[j] || j == min - 1)
                                        {
                                            songRearranged = true;
                                            await sw.WriteLineAsync(SongCollectionFormatter.SongFormatter(offlineSong));

                                            break;
                                        }
                                        else if (offlineSong.song.Title[j] > SongCollectionFormatter.GetSongTitle(songLine)[j])
                                        {
                                            break;
                                        }
                                    }
                                }
                                else if (SongCollectionFormatter.GetTimesPlayed(songLine) < offlineSong.timesPlayed)
                                {
                                    //We might want to re-arrange it if the song being changed the times played has
                                    //a promotion of rank
                                    songRearranged = true;
                                    await sw.WriteLineAsync(SongCollectionFormatter.SongFormatter(offlineSong));
                                }
                            }
                            await sw.WriteLineAsync(songLine);
                        }
                        await sr.ReadLineAsync(); //Move to next line on the reader since we don't need to use it

                        if (!songRearranged)      //If ranking does not change
                        {
                            await sw.WriteLineAsync(SongCollectionFormatter.SongFormatter(offlineSong));
                        }
                        for (; lineNo < totalLines; lineNo++) //DEBUNK THIS
                        {
                            await sw.WriteLineAsync(await sr.ReadLineAsync());
                        }
                    }
                    catch (Exception e)
                    {
                        LogHelper.Logln($"Error occured while reading {infoFilePath} and writing {infoFilePath + "temp"}. {e.Message}", LogType.Error);
                        sr.Close();
                        await sw.FlushAsync();

                        File.Delete(infoFilePath + "temp");
                        return(false);
                    }
                }
            #region Clean-up
            try
            {
                File.Delete(infoFilePath);
                File.Move(infoFilePath + "temp", infoFilePath);
            }
            catch (Exception e)
            {
                LogHelper.Logln($"Error while deleting ${infoFilePath} and replacing {infoFilePath} with {infoFilePath + "temp"}. {e.Message}", LogType.Error);
            }
            LogHelper.Logln($"Successfully rewrite times played and flushed all underlying streams.", LogType.Success);
            #endregion
            return(true);
        }
Пример #7
0
        /// <summary>
        /// Please make sure the infoFilePath exists
        /// </summary>
        /// <param name="song"></param>
        /// <returns></returns>
        public async Task <bool> TryAddSongAsync(OfflineSong song)
        {
            bool songAdded;

            using (StreamReader sr = File.OpenText(infoFilePath))
                using (StreamWriter sw = File.CreateText(infoFilePath + "temp"))
                {
                    LUint  totalLines;
                    string line = await sr.ReadLineAsync();

                    if (!LUint.TryParse(line, out totalLines))
                    {
                        LogHelper.Logln($"{infoFilePath} is not encoded as expected.", LogType.Error);
                        sr.Close();
                        await sw.FlushAsync();

                        sw.Close();
                        File.Delete(infoFilePath + "temp");
                        return(false);
                    }
                    if (totalLines == 0)
                    {
                        await sw.WriteLineAsync('1');

                        await sw.WriteLineAsync(SongCollectionFormatter.SongFormatter(song));

                        sr.Close();
                        await sw.FlushAsync();

                        sw.Close();
                        File.Delete(infoFilePath);
                        File.Move(infoFilePath + "temp", infoFilePath);
                        return(true);
                    }
#if DEBUG
                    LogHelper.Logln($"Total lines = {totalLines}", LogType.Warning);
#endif
                    await sw.WriteLineAsync((totalLines + 1).ToString());

                    //We are now done with getting and writing the number of totalLines of the new file
                    songAdded = false;
                    for (int i = 0; i < totalLines; i++)
                    {
                        string songLine = await sr.ReadLineAsync();

                        if (!songAdded)
                        {
#if DEBUG
                            LogHelper.Logln("!songAdded; i = " + i);
#endif
                            LUint songLineTimesPlayed = SongCollectionFormatter.GetTimesPlayed(songLine);
                            if (songLineTimesPlayed == song.timesPlayed)
                            {
                                //2»aaaaaaa...
                                //1»abcde»... //songLine
                                //1»bcdefeee»... //song.song
                                string songTitle = SongCollectionFormatter.GetSongTitle(songLine);
                                int    minLength = Math.Min(song.song.Title.Length, songTitle.Length); //5, 8 => 5
                                for (int j = 0; j < minLength; j++)
                                {
                                    if (song.song.Title[j] < songTitle[j])
                                    //if the adding song is less than the existed one alphabetically
                                    {
                                        await sw.WriteLineAsync(SongCollectionFormatter.SongFormatter(song));

                                        songAdded = true;
                                        break;
                                    }
                                    else if (j == minLength - 1)
                                    //If the adding song is a modification of the existed one
                                    {
                                        if (song.song.Title.Length != songTitle.Length) //the original or the new one might be a remix
                                        {
                                            //It does not matter anymore if the new title is an inserted of an old one
                                            await sw.WriteLineAsync(SongCollectionFormatter.SongFormatter(song));

                                            songAdded = true;
                                            break;
                                        }
                                        else //same title, exit
                                        {
                                            string songDuration = SongCollectionFormatter.GetDuration(songLine);
                                            //Check duration of both
                                            if (songDuration == song.song.Duration)
                                            {
                                                //Same song
                                                sr.Close();
                                                await sw.FlushAsync();

                                                sw.Close();
                                                File.Delete(infoFilePath + "temp");
                                                return(true);
                                            }
                                            //The else case is automatically handled
                                        }
                                    }
                                    else if (song.song.Title[j] > songTitle[j])
                                    {
                                        break;
                                    }
                                }
                            }
                            else if (songLineTimesPlayed < song.timesPlayed)
                            {
                                await sw.WriteLineAsync(SongCollectionFormatter.SongFormatter(song));

                                songAdded = true;
                            }
                        }
                        await sw.WriteLineAsync(songLine);
                    }
                    if (!songAdded)
                    {
                        //When you have eliminated the impossible, whatever remains, however improbable, must be the truth.
                        //- Sherlock Holmes/Sir Arthur Conan Doyle
                        await sw.WriteLineAsync(SongCollectionFormatter.SongFormatter(song));

                        songAdded = true;
                    }
                }
            #region Clean-up (works perfectly)
#if DEBUG
            LogHelper.Logln("Flushed sr and sw.", LogType.Success);
#endif
            try
            {
#if DEBUG
                if (songAdded)
                {
                    LogHelper.Logln("Since songAdded, delete old file, replace new file", LogType.Success);
#endif
                File.Delete(infoFilePath);
                File.Move(infoFilePath + "temp", infoFilePath);
#if DEBUG
            }
            else
            {
                LogHelper.Logln("Since !songAdded, delete new file.", LogType.Success);
                File.Delete(infoFilePath + "temp");
            }
#endif
            }
            catch (Exception e)
            {
                LogHelper.Logln($"Error while deleting ${infoFilePath} and replacing {infoFilePath} with {infoFilePath + "temp"}. {e.Message}", LogType.Error);
            }
#if DEBUG
            LogHelper.Logln("TryAddSongAsync algorithm got to the bottom of before returning.", LogType.Success);
#endif
            #endregion
            return(songAdded);
        }