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); }
/// <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); }
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); } }
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); }
/// <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); }
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); }
/// <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); }