Refactoring and cleanup
This commit is contained in:
+281
-292
@@ -19,193 +19,192 @@ using Icarus.Controllers.Utilities;
|
||||
|
||||
namespace Icarus.Controllers.Managers
|
||||
{
|
||||
public class SongManager
|
||||
{
|
||||
#region Fields
|
||||
public class SongManager
|
||||
{
|
||||
#region Fields
|
||||
private MySqlConnection _conn;
|
||||
private MySqlCommand _cmd;
|
||||
private MySqlDataAdapter _dataDump;
|
||||
private DataTable _results;
|
||||
private List<Song> _songs;
|
||||
private Song _song;
|
||||
private IConfiguration _config;
|
||||
private string _connectionString;
|
||||
private string _tempDirectoryRoot;
|
||||
private string _archiveDirectoryRoot;
|
||||
private string _compressedSongFilename;
|
||||
#endregion
|
||||
private List<Song> _songs;
|
||||
private Song _song;
|
||||
private IConfiguration _config;
|
||||
private string _connectionString;
|
||||
private string _tempDirectoryRoot;
|
||||
private string _archiveDirectoryRoot;
|
||||
private string _compressedSongFilename;
|
||||
#endregion
|
||||
|
||||
|
||||
#region Properties
|
||||
public Song SongDetails
|
||||
{
|
||||
get => _song;
|
||||
set => _song = value;
|
||||
}
|
||||
#region Properties
|
||||
public Song SongDetails
|
||||
{
|
||||
get => _song;
|
||||
set => _song = value;
|
||||
}
|
||||
|
||||
public string ArchiveDirectoryRoot
|
||||
{
|
||||
get => _archiveDirectoryRoot;
|
||||
set => _archiveDirectoryRoot = value;
|
||||
}
|
||||
public string CompressedSongFilename
|
||||
{
|
||||
get => _compressedSongFilename;
|
||||
set => _compressedSongFilename = value;
|
||||
}
|
||||
#endregion
|
||||
public string ArchiveDirectoryRoot
|
||||
{
|
||||
get => _archiveDirectoryRoot;
|
||||
set => _archiveDirectoryRoot = value;
|
||||
}
|
||||
public string CompressedSongFilename
|
||||
{
|
||||
get => _compressedSongFilename;
|
||||
set => _compressedSongFilename = value;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Constructors
|
||||
public SongManager()
|
||||
{
|
||||
Initialize();
|
||||
#region Constructors
|
||||
public SongManager()
|
||||
{
|
||||
Initialize();
|
||||
InitializeConnection();
|
||||
}
|
||||
}
|
||||
|
||||
public SongManager(Song song)
|
||||
{
|
||||
Initialize();
|
||||
public SongManager(Song song)
|
||||
{
|
||||
Initialize();
|
||||
InitializeConnection();
|
||||
_song = song;
|
||||
}
|
||||
public SongManager(IConfiguration config)
|
||||
{
|
||||
_config = config;
|
||||
Initialize();
|
||||
}
|
||||
public SongManager(IConfiguration config)
|
||||
{
|
||||
_config = config;
|
||||
Initialize();
|
||||
InitializeConnection();
|
||||
}
|
||||
public SongManager(IConfiguration config, string tempDirectoryRoot)
|
||||
{
|
||||
_config = config;
|
||||
_tempDirectoryRoot = tempDirectoryRoot;
|
||||
Initialize();
|
||||
}
|
||||
public SongManager(IConfiguration config, string tempDirectoryRoot)
|
||||
{
|
||||
_config = config;
|
||||
_tempDirectoryRoot = tempDirectoryRoot;
|
||||
Initialize();
|
||||
InitializeConnection();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Methods
|
||||
public void SaveSongDetails()
|
||||
#region Methods
|
||||
public void SaveSongDetails()
|
||||
{
|
||||
try
|
||||
{
|
||||
using (MySqlConnection conn = new MySqlConnection(_connectionString))
|
||||
{
|
||||
try
|
||||
{
|
||||
using (MySqlConnection conn = new MySqlConnection(_connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
string query = "INSERT INTO Songs(Title, Album, Artist, Year, Genre, Duration, " +
|
||||
"Filename, SongPath) VALUES(@Title, @Album, @Artist, @Year, @Genre, " +
|
||||
"@Duration, @Filename, @SongPath)";
|
||||
using (MySqlCommand cmd = new MySqlCommand(query, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@Title", _song.Title);
|
||||
cmd.Parameters.AddWithValue("@Album", _song.Album);
|
||||
cmd.Parameters.AddWithValue("@Artist", _song.Artist);
|
||||
cmd.Parameters.AddWithValue("@Year", _song.Year);
|
||||
cmd.Parameters.AddWithValue("@Genre", _song.Genre);
|
||||
cmd.Parameters.AddWithValue("@Duration", _song.Duration);
|
||||
cmd.Parameters.AddWithValue("@Filename", _song.Filename);
|
||||
cmd.Parameters.AddWithValue("@SongPath", _song.SongPath);
|
||||
conn.Open();
|
||||
string query = "INSERT INTO Songs(Title, Album, Artist, Year, Genre, Duration, " +
|
||||
"Filename, SongPath) VALUES(@Title, @Album, @Artist, @Year, @Genre, " +
|
||||
"@Duration, @Filename, @SongPath)";
|
||||
using (MySqlCommand cmd = new MySqlCommand(query, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@Title", _song.Title);
|
||||
cmd.Parameters.AddWithValue("@Album", _song.Album);
|
||||
cmd.Parameters.AddWithValue("@Artist", _song.Artist);
|
||||
cmd.Parameters.AddWithValue("@Year", _song.Year);
|
||||
cmd.Parameters.AddWithValue("@Genre", _song.Genre);
|
||||
cmd.Parameters.AddWithValue("@Duration", _song.Duration);
|
||||
cmd.Parameters.AddWithValue("@Filename", _song.Filename);
|
||||
cmd.Parameters.AddWithValue("@SongPath", _song.SongPath);
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var exMsg = ex.Message;
|
||||
Console.WriteLine($"An Error Occurred: {exMsg}");
|
||||
}
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
public void SaveSongDetails(Song song)
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var exMsg = ex.Message;
|
||||
Console.WriteLine($"An Error Occurred: {exMsg}");
|
||||
}
|
||||
}
|
||||
public void SaveSongDetails(Song song)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (MySqlConnection conn = new MySqlConnection(_connectionString))
|
||||
{
|
||||
try
|
||||
{
|
||||
using (MySqlConnection conn = new MySqlConnection(_connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
string query = "INSERT INTO Songs(Title, Album, Artist, Year, Genre, Duration, " +
|
||||
", Filename, SongPath) VALUES(@Title, @Album, @Artist, @Year, @Genre, " +
|
||||
"@Duration, @Filename, @SongPath)";
|
||||
using (MySqlCommand cmd = new MySqlCommand(query, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@Title", song.Title);
|
||||
cmd.Parameters.AddWithValue("@Album", song.Album);
|
||||
cmd.Parameters.AddWithValue("@Artist", song.Artist);
|
||||
cmd.Parameters.AddWithValue("@Year", song.Year);
|
||||
cmd.Parameters.AddWithValue("@Genre", song.Genre);
|
||||
cmd.Parameters.AddWithValue("@Duration", song.Duration);
|
||||
cmd.Parameters.AddWithValue("@Filename", song.Filename);
|
||||
cmd.Parameters.AddWithValue("@SongPath", song.SongPath);
|
||||
conn.Open();
|
||||
string query = "INSERT INTO Songs(Title, Album, Artist, Year, Genre, Duration, " +
|
||||
", Filename, SongPath) VALUES(@Title, @Album, @Artist, @Year, @Genre, " +
|
||||
"@Duration, @Filename, @SongPath)";
|
||||
using (MySqlCommand cmd = new MySqlCommand(query, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@Title", song.Title);
|
||||
cmd.Parameters.AddWithValue("@Album", song.Album);
|
||||
cmd.Parameters.AddWithValue("@Artist", song.Artist);
|
||||
cmd.Parameters.AddWithValue("@Year", song.Year);
|
||||
cmd.Parameters.AddWithValue("@Genre", song.Genre);
|
||||
cmd.Parameters.AddWithValue("@Duration", song.Duration);
|
||||
cmd.Parameters.AddWithValue("@Filename", song.Filename);
|
||||
cmd.Parameters.AddWithValue("@SongPath", song.SongPath);
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var exMsg = ex.Message;
|
||||
Console.WriteLine($"An Error Occurred: {exMsg}");
|
||||
}
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
public async Task SaveSong(SongData songData)
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var exMsg = ex.Message;
|
||||
Console.WriteLine($"An Error Occurred: {exMsg}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task SaveSong(SongData songData)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (MySqlConnection conn = new MySqlConnection(_connectionString))
|
||||
{
|
||||
try
|
||||
{
|
||||
using (MySqlConnection conn = new MySqlConnection(_connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
string query = "INSERT INTO SongData(Data) VALUES(@Data)";
|
||||
using (MySqlCommand cmd = new MySqlCommand(query, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@Data", songData.Data);
|
||||
conn.Open();
|
||||
string query = "INSERT INTO SongData(Data) VALUES(@Data)";
|
||||
using (MySqlCommand cmd = new MySqlCommand(query, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@Data", songData.Data);
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
var exMsg = ex.Message;
|
||||
Console.WriteLine($"An error occurred: {exMsg}");
|
||||
}
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
public async Task SaveSongToFileSystem(IFormFile song)
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
var exMsg = ex.Message;
|
||||
Console.WriteLine($"An error occurred: {exMsg}");
|
||||
}
|
||||
}
|
||||
public async Task SaveSongToFileSystem(IFormFile song)
|
||||
{
|
||||
try
|
||||
{
|
||||
var filePath = Path.Combine(_tempDirectoryRoot, song.FileName);
|
||||
await SaveSongToFileSystemTemp(song, filePath);
|
||||
System.IO.File.Delete(filePath);
|
||||
|
||||
|
||||
DirectoryManager dirMgr = new DirectoryManager(_config, _song);
|
||||
dirMgr.CreateDirectory();
|
||||
filePath = dirMgr.SongDirectory;
|
||||
if (!song.FileName.EndsWith(".mp3"))
|
||||
filePath += $"{song.FileName}.mp3";
|
||||
else
|
||||
filePath += $"{song.FileName}";
|
||||
|
||||
Console.WriteLine($"Full path {filePath}");
|
||||
|
||||
using (var fileStream = new FileStream(filePath, FileMode.Create))
|
||||
{
|
||||
try
|
||||
{
|
||||
var filePath = Path.Combine(_tempDirectoryRoot, song.FileName);
|
||||
await SaveSongToFileSystemTemp(song, filePath);
|
||||
System.IO.File.Delete(filePath);
|
||||
await song.CopyToAsync(fileStream);
|
||||
_song.SongPath = filePath;
|
||||
|
||||
|
||||
DirectoryManager dirMgr = new DirectoryManager(_config, _song);
|
||||
dirMgr.CreateDirectory();
|
||||
filePath = dirMgr.SongDirectory;
|
||||
if (!song.FileName.EndsWith(".mp3"))
|
||||
filePath += $"{song.FileName}.mp3";
|
||||
else
|
||||
filePath += $"{song.FileName}";
|
||||
|
||||
Console.WriteLine($"Full path {filePath}");
|
||||
|
||||
using (var fileStream = new FileStream(filePath, FileMode.Create))
|
||||
{
|
||||
await song.CopyToAsync(fileStream);
|
||||
_song.SongPath = filePath;
|
||||
SaveSongDetails();
|
||||
|
||||
|
||||
Console.WriteLine($"Writing song to the directory: {filePath}");
|
||||
Console.WriteLine("Song successfully saved");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var exMsg = ex.Message;
|
||||
Console.WriteLine($"An error occurred: {exMsg}");
|
||||
}
|
||||
Console.WriteLine($"Writing song to the directory: {filePath}");
|
||||
Console.WriteLine("Song successfully saved");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var exMsg = ex.Message;
|
||||
Console.WriteLine($"An error occurred: {exMsg}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<Song>> RetrieveAllSongDetails()
|
||||
{
|
||||
@@ -237,160 +236,150 @@ namespace Icarus.Controllers.Managers
|
||||
|
||||
return _songs;
|
||||
}
|
||||
public async Task<Song> RetrieveSongDetails(int id)
|
||||
public async Task<Song> RetrieveSongDetails(int id)
|
||||
{
|
||||
DataTable results = new DataTable();
|
||||
|
||||
try
|
||||
{
|
||||
using (MySqlConnection conn = new MySqlConnection(_connectionString))
|
||||
{
|
||||
DataTable results = new DataTable();
|
||||
conn.Open();
|
||||
string query = "SELECT * FROM Songs WHERE Id=@Id";
|
||||
using (MySqlCommand cmd = new MySqlCommand(query, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@Id", id);
|
||||
|
||||
cmd.ExecuteNonQuery();
|
||||
|
||||
try
|
||||
using (MySqlDataAdapter dataDump = new MySqlDataAdapter(cmd))
|
||||
{
|
||||
using (MySqlConnection conn = new MySqlConnection(_connectionString))
|
||||
{
|
||||
conn.Open();
|
||||
string query = "SELECT * FROM Songs WHERE Id=@Id";
|
||||
using (MySqlCommand cmd = new MySqlCommand(query, conn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@Id", id);
|
||||
cmd.ExecuteNonQuery();
|
||||
|
||||
using (MySqlDataAdapter dataDump = new MySqlDataAdapter(cmd))
|
||||
{
|
||||
dataDump.Fill(results);
|
||||
}
|
||||
}
|
||||
}
|
||||
dataDump.Fill(results);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var exMsg = ex.Message;
|
||||
Console.WriteLine($"An error occurred");
|
||||
}
|
||||
DataRow row = results.Rows[0];
|
||||
|
||||
return new Song
|
||||
{
|
||||
Id = Int32.Parse(row["Id"].ToString()),
|
||||
Filename = row["Filename"].ToString(),
|
||||
SongPath = row["SongPath"].ToString()
|
||||
};
|
||||
}
|
||||
}
|
||||
public async Task<SongData> RetrieveSong(int id)
|
||||
{
|
||||
SongData song = new SongData();
|
||||
try
|
||||
{
|
||||
_song = await RetrieveSongDetails(id);
|
||||
song = RetrieveSongFromFileSystem(_song);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var exMsg = ex.Message;
|
||||
Console.WriteLine($"An error occurred: {exMsg}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var exMsg = ex.Message;
|
||||
Console.WriteLine($"An error occurred");
|
||||
}
|
||||
|
||||
DataRow row = results.Rows[0];
|
||||
|
||||
return song;
|
||||
}
|
||||
public async Task<SongData> RetrieveCompressedSong(int id)
|
||||
{
|
||||
SongData song = new SongData();
|
||||
try
|
||||
{
|
||||
_song = await RetrieveSongDetails(id);
|
||||
Console.WriteLine("Retrieved details of song");
|
||||
return new Song
|
||||
{
|
||||
Id = Int32.Parse(row["Id"].ToString()),
|
||||
Filename = row["Filename"].ToString(),
|
||||
SongPath = row["SongPath"].ToString()
|
||||
};
|
||||
}
|
||||
public async Task<SongData> RetrieveSong(int id)
|
||||
{
|
||||
SongData song = new SongData();
|
||||
try
|
||||
{
|
||||
_song = await RetrieveSongDetails(id);
|
||||
song = await RetrieveSongFromFileSystem(_song);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var exMsg = ex.Message;
|
||||
Console.WriteLine($"An error occurred: {exMsg}");
|
||||
}
|
||||
|
||||
song = RetrieveSongFromFileSystem(_song);
|
||||
Console.WriteLine("Retrieved song from filesystem");
|
||||
return song;
|
||||
}
|
||||
public async Task<SongData> RetrieveSong(Song songMetaData)
|
||||
{
|
||||
SongData song = new SongData();
|
||||
try
|
||||
{
|
||||
Console.WriteLine("Fetching song from filesystem");
|
||||
song = await RetrieveSongFromFileSystem(songMetaData);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var exMsg = ex.Message;
|
||||
Console.WriteLine($"An error occurred: {exMsg}");
|
||||
}
|
||||
|
||||
SongCompression compressed = new SongCompression(_archiveDirectoryRoot);
|
||||
Console.WriteLine("SongCompression Initialized");
|
||||
|
||||
var compressedPath = compressed.RetrieveCompressesSongPath(_song);
|
||||
Console.WriteLine($"Path of compressed song: {compressedPath}");
|
||||
|
||||
song.Data = System.IO.File.ReadAllBytes(compressedPath);
|
||||
|
||||
_compressedSongFilename = compressed.CompressedSongFilename;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var exMsg = ex.Message;
|
||||
Console.WriteLine($"An error occurred: {exMsg}");
|
||||
}
|
||||
return song;
|
||||
}
|
||||
return song;
|
||||
}
|
||||
|
||||
|
||||
Song RetrieveMetaData(string filePath)
|
||||
{
|
||||
string title, artist, album, genre;
|
||||
int year, duration;
|
||||
Song RetrieveMetaData(string filePath)
|
||||
{
|
||||
string title, artist, album, genre;
|
||||
int year, duration;
|
||||
|
||||
TagLib.File tfile = TagLib.File.Create(filePath);
|
||||
duration = (int)tfile.Properties.Duration.TotalSeconds;
|
||||
TagLib.File tfile = TagLib.File.Create(filePath);
|
||||
duration = (int)tfile.Properties.Duration.TotalSeconds;
|
||||
|
||||
|
||||
using (var mp3 = new Mp3(filePath))
|
||||
{
|
||||
Id3Tag tag = mp3.GetTag(Id3TagFamily.Version2X);
|
||||
title = tag.Title;
|
||||
artist = tag.Artists;
|
||||
album = tag.Album;
|
||||
genre = "Not Implemented";
|
||||
year = (int)tag.Year;
|
||||
Console.WriteLine("Title: {0}", title);
|
||||
Console.WriteLine("Artist: {0}", artist);
|
||||
Console.WriteLine("Album: {0}", album);
|
||||
Console.WriteLine("Genre: {0}", genre);
|
||||
Console.WriteLine("Year: {0}", year);
|
||||
Console.WriteLine("Duration: {0}", duration);
|
||||
}
|
||||
using (var mp3 = new Mp3(filePath))
|
||||
{
|
||||
Id3Tag tag = mp3.GetTag(Id3TagFamily.Version2X);
|
||||
title = tag.Title;
|
||||
artist = tag.Artists;
|
||||
album = tag.Album;
|
||||
genre = "Not Implemented";
|
||||
year = (int)tag.Year;
|
||||
Console.WriteLine("Title: {0}", title);
|
||||
Console.WriteLine("Artist: {0}", artist);
|
||||
Console.WriteLine("Album: {0}", album);
|
||||
Console.WriteLine("Genre: {0}", genre);
|
||||
Console.WriteLine("Year: {0}", year);
|
||||
Console.WriteLine("Duration: {0}", duration);
|
||||
}
|
||||
|
||||
_song = new Song
|
||||
{
|
||||
Title = title,
|
||||
Artist = artist,
|
||||
Album = album,
|
||||
Year = year,
|
||||
Genre = genre,
|
||||
Duration = duration,
|
||||
SongPath = filePath
|
||||
};
|
||||
_song = new Song
|
||||
{
|
||||
Title = title,
|
||||
Artist = artist,
|
||||
Album = album,
|
||||
Year = year,
|
||||
Genre = genre,
|
||||
Duration = duration,
|
||||
SongPath = filePath
|
||||
};
|
||||
|
||||
return _song;
|
||||
}
|
||||
return _song;
|
||||
}
|
||||
|
||||
SongData RetrieveSongFromFileSystem(Song details)
|
||||
{
|
||||
async Task<SongData> RetrieveSongFromFileSystem(Song details)
|
||||
{
|
||||
byte[] uncompressedSong = System.IO.File.ReadAllBytes(details.SongPath);
|
||||
|
||||
return new SongData
|
||||
{
|
||||
Data = uncompressedSong
|
||||
};
|
||||
}
|
||||
return new SongData
|
||||
{
|
||||
Data = uncompressedSong
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
async Task SaveSongToFileSystemTemp(IFormFile song, string filePath)
|
||||
{
|
||||
using (var fileStream = new FileStream(filePath, FileMode.Create))
|
||||
{
|
||||
await song.CopyToAsync(fileStream);
|
||||
_song = RetrieveMetaData(filePath);
|
||||
_song.Filename = song.FileName;
|
||||
}
|
||||
}
|
||||
async Task SaveSongToFileSystemTemp(IFormFile song, string filePath)
|
||||
{
|
||||
using (var fileStream = new FileStream(filePath, FileMode.Create))
|
||||
{
|
||||
await song.CopyToAsync(fileStream);
|
||||
_song = RetrieveMetaData(filePath);
|
||||
_song.Filename = song.FileName;
|
||||
}
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
try
|
||||
{
|
||||
_connectionString = _config.GetConnectionString("IcarusDev");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error Occurred: {ex.Message}");
|
||||
}
|
||||
void Initialize()
|
||||
{
|
||||
try
|
||||
{
|
||||
_connectionString = _config.GetConnectionString("IcarusDev");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error Occurred: {ex.Message}");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
void InitializeConnection()
|
||||
{
|
||||
_conn = new MySqlConnection(_connectionString);
|
||||
@@ -441,6 +430,6 @@ namespace Icarus.Controllers.Managers
|
||||
_songs.Add(song);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user