DeleteOldLogFilesAndDeleteEmptyDirectories
Log bug Wafer Counter trigger: - master
This commit is contained in:
parent
b1e63df70b
commit
219fdda4ec
2
.gitignore
vendored
2
.gitignore
vendored
@ -327,3 +327,5 @@ ASALocalRun/
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
.vscode/Helper/**
|
60
.vscode/tasks.json
vendored
60
.vscode/tasks.json
vendored
@ -127,6 +127,66 @@
|
||||
"command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s V Helpers",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "File-Folder-Helper AOT s H MET08ANLYSDIFAAST230",
|
||||
"type": "shell",
|
||||
"command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s H '\\\\messa01ec.ec.local\\apps\\Metrology\\Run Data Repository\\MET08ANLYSDIFAAST230\\Source\\MET08ANLYSDIFAAST230'",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "File-Folder-Helper AOT s H MET08DDUPSFS6420",
|
||||
"type": "shell",
|
||||
"command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s H '\\\\messa01ec.ec.local\\apps\\Metrology\\Run Data Repository\\MET08DDUPSFS6420\\Source\\MET08DDUPSFS6420'",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "File-Folder-Helper AOT s H MET08DDUPSP1TBI",
|
||||
"type": "shell",
|
||||
"command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s H '\\\\messa01ec.ec.local\\apps\\Metrology\\Run Data Repository\\MET08DDUPSP1TBI\\Source\\MET08DDUPSP1TBI'",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "File-Folder-Helper AOT s H MET08RESIHGCV",
|
||||
"type": "shell",
|
||||
"command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s H '\\\\messa01ec.ec.local\\apps\\Metrology\\Run Data Repository\\MET08RESIHGCV\\Source\\MET08RESIHGCV'",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "File-Folder-Helper AOT s H MET08RESIMAPCDE",
|
||||
"type": "shell",
|
||||
"command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s H '\\\\messa01ec.ec.local\\apps\\Metrology\\Run Data Repository\\MET08RESIMAPCDE\\Source\\MET08RESIMAPCDE'",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "File-Folder-Helper AOT s H MET08RESISRP2100",
|
||||
"type": "shell",
|
||||
"command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s H '\\\\messa01ec.ec.local\\apps\\Metrology\\Run Data Repository\\MET08RESISRP2100\\Source\\MET08RESISRP2100'",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "File-Folder-Helper AOT s H MET08THFTIRQS408M",
|
||||
"type": "shell",
|
||||
"command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s H '\\\\messa01ec.ec.local\\apps\\Metrology\\Run Data Repository\\MET08THFTIRQS408M\\Source\\MET08THFTIRQS408M'",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "File-Folder-Helper AOT s H MET08THFTIRSTRATUS",
|
||||
"type": "shell",
|
||||
"command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s H '\\\\messa01ec.ec.local\\apps\\Metrology\\Run Data Repository\\MET08THFTIRSTRATUS\\Source\\MET08THFTIRSTRATUS'",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "File-Folder-Helper AOT s H WaferCounter",
|
||||
"type": "shell",
|
||||
"command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s H '\\\\messa01ec.ec.local\\apps\\WaferCounter\\BackupFiles'",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "File-Folder-Helper AOT s F Staging _Logs",
|
||||
"type": "shell",
|
||||
"command": "& L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net7.0/win-x64/publish/File-Folder-Helper.exe s F '\\\\messv02ecc1.ec.local\\EC_EAFLog\\Staging\\_ Logs'",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Kanbn Console",
|
||||
"type": "npm",
|
||||
|
@ -1,3 +1,4 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
@ -77,7 +78,7 @@ internal static partial class HelperCreateNoteFiles
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void CleanExistingFiles(string directory, long ticks)
|
||||
private static void CleanExistingFiles(ILogger<Worker> logger, string directory, long ticks)
|
||||
{
|
||||
string check;
|
||||
string[] lines;
|
||||
@ -121,7 +122,7 @@ internal static partial class HelperCreateNoteFiles
|
||||
continue;
|
||||
File.Move(file, checkFile);
|
||||
}
|
||||
_ = HelperDeleteEmptyDirectories.DeleteEmptyDirectories(directory);
|
||||
HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, directory);
|
||||
}
|
||||
|
||||
private static void CreateDailyNotes(string argsZero, long ticks)
|
||||
@ -272,11 +273,11 @@ internal static partial class HelperCreateNoteFiles
|
||||
}
|
||||
}
|
||||
|
||||
internal static void CreateNoteFiles(string argsZero)
|
||||
internal static void CreateNoteFiles(ILogger<Worker> logger, string argsZero)
|
||||
{
|
||||
long ticks = DateTime.Now.Ticks;
|
||||
List<string> importFiles = new();
|
||||
CleanExistingFiles(argsZero, ticks);
|
||||
CleanExistingFiles(logger, argsZero, ticks);
|
||||
importFiles.AddRange(Directory.GetFiles(argsZero, "*.csv", SearchOption.TopDirectoryOnly));
|
||||
importFiles.AddRange(Directory.GetFiles(argsZero, "*.tsv", SearchOption.TopDirectoryOnly));
|
||||
if (importFiles.Count == 0)
|
||||
|
@ -1,43 +1,86 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.Helpers;
|
||||
|
||||
internal static class HelperDeleteEmptyDirectories
|
||||
{
|
||||
|
||||
internal static bool DeleteEmptyDirectories(string rootDirectory)
|
||||
private static void DeleteOldLogFilesAndDeleteEmptyDirectories(long? ticks, string? searchPattern, string checkDirectory, List<string> deletedDirectories)
|
||||
{
|
||||
bool result;
|
||||
if (!Directory.Exists(rootDirectory))
|
||||
result = false;
|
||||
else
|
||||
string[] files;
|
||||
FileInfo fileInfo;
|
||||
string[] directories = Directory.GetDirectories(checkDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||
if (ticks is not null && !string.IsNullOrEmpty(searchPattern))
|
||||
{
|
||||
string[] files;
|
||||
string[] directories = Directory.GetDirectories(rootDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||
if (directories.Length > 0)
|
||||
files = Array.Empty<string>();
|
||||
else
|
||||
files = Directory.GetFiles(rootDirectory, "*", SearchOption.AllDirectories);
|
||||
if (directories.Length == 0 && files.Length == 0)
|
||||
files = Directory.GetFiles(checkDirectory, searchPattern, SearchOption.TopDirectoryOnly);
|
||||
foreach (string file in files)
|
||||
{
|
||||
result = true;
|
||||
Directory.Delete(rootDirectory);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
foreach (string directory in directories)
|
||||
{
|
||||
result = DeleteEmptyDirectories(directory);
|
||||
if (result)
|
||||
result = DeleteEmptyDirectories(directory);
|
||||
}
|
||||
if (files is null)
|
||||
{
|
||||
directories = Directory.GetDirectories(rootDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||
result = directories.Length == 0;
|
||||
}
|
||||
fileInfo = new(file);
|
||||
if (fileInfo.LastWriteTime.Ticks > ticks)
|
||||
continue;
|
||||
File.Delete(file);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
if (directories.Length > 0)
|
||||
files = Array.Empty<string>();
|
||||
else
|
||||
files = Directory.GetFiles(checkDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||
if (directories.Length == 0 && files.Length == 0)
|
||||
{
|
||||
try
|
||||
{ Directory.Delete(checkDirectory); }
|
||||
catch (UnauthorizedAccessException)
|
||||
{
|
||||
new DirectoryInfo(checkDirectory).Attributes = FileAttributes.Normal;
|
||||
Directory.Delete(checkDirectory);
|
||||
}
|
||||
deletedDirectories.Add(checkDirectory);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<string> check = new();
|
||||
foreach (string directory in directories)
|
||||
{
|
||||
DeleteOldLogFilesAndDeleteEmptyDirectories(ticks, searchPattern, directory, check);
|
||||
deletedDirectories.AddRange(check);
|
||||
if (check.Count > 0 && Directory.Exists(directory))
|
||||
DeleteOldLogFilesAndDeleteEmptyDirectories(ticks, searchPattern, directory, deletedDirectories);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void DeleteOldLogFilesAndDeleteEmptyDirectories(ILogger<Worker> logger, long? ticks, string? searchPattern, string rootDirectory)
|
||||
{
|
||||
List<string> check = new();
|
||||
List<string> directories = Directory.GetDirectories(rootDirectory, "*", SearchOption.TopDirectoryOnly).ToList();
|
||||
directories.Add(rootDirectory);
|
||||
foreach (string directory in directories)
|
||||
{
|
||||
logger.LogInformation("{directoryName}", Path.GetFileName(directory));
|
||||
for (int i = 1; i < 50; i++)
|
||||
{
|
||||
if (!Directory.Exists(directory))
|
||||
break;
|
||||
check.Clear();
|
||||
DeleteOldLogFilesAndDeleteEmptyDirectories(ticks, searchPattern, directory, check);
|
||||
if (check.Count == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void DeleteEmptyDirectories(ILogger<Worker> logger, string rootDirectory)
|
||||
{
|
||||
long? ticks = null;
|
||||
string? searchPattern = null;
|
||||
DeleteOldLogFilesAndDeleteEmptyDirectories(logger, ticks, searchPattern, rootDirectory);
|
||||
}
|
||||
|
||||
internal static void DeleteOldLogFilesAndDeleteEmptyDirectories(ILogger<Worker> logger, string rootDirectory)
|
||||
{
|
||||
long ticks = DateTime.Now.AddHours(-120).Ticks;
|
||||
DeleteOldLogFilesAndDeleteEmptyDirectories(logger, ticks, "*.log", rootDirectory);
|
||||
DeleteOldLogFilesAndDeleteEmptyDirectories(logger, ticks, "*.log.*", rootDirectory);
|
||||
}
|
||||
|
||||
}
|
@ -37,6 +37,8 @@ internal static class HelperHardcodedFileSearchAndSort
|
||||
"SP101",
|
||||
"SPV01",
|
||||
"SRP",
|
||||
"WC6Inch",
|
||||
"WC8Inch",
|
||||
"Bio-Rad"
|
||||
};
|
||||
string[] files = Directory.GetFiles(sourceDirectory, "*", searchOption);
|
||||
|
@ -1137,11 +1137,17 @@ internal static partial class HelperMarkdown
|
||||
{
|
||||
if (string.IsNullOrEmpty(input.StartAt) || string.IsNullOrEmpty(input.Destination))
|
||||
throw new NotSupportedException();
|
||||
ReadOnlyDictionary<string, List<Card>> columnsToCards = GetColumnsToCards(input, relativeToCollection);
|
||||
if (columnsToCards.Count > 0)
|
||||
ReadOnlyDictionary<string, List<Card>> columnsToCards;
|
||||
string jsonFile = Path.Combine(input.Destination, $"{nameof(columnsToCards)}.json");
|
||||
if (File.Exists(jsonFile))
|
||||
File.Delete(jsonFile);
|
||||
columnsToCards = GetColumnsToCards(input, relativeToCollection);
|
||||
if (columnsToCards.Count == 0)
|
||||
File.WriteAllText(jsonFile, "{}");
|
||||
else
|
||||
{
|
||||
string json = JsonSerializer.Serialize(columnsToCards, ColumnsAndCardsSourceGenerationContext.Default.ReadOnlyDictionaryStringListCard);
|
||||
File.WriteAllText(Path.Combine(input.Destination, $"{nameof(columnsToCards)}.json"), json);
|
||||
File.WriteAllText(jsonFile, json);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace File_Folder_Helper.Helpers;
|
||||
|
||||
internal static class HelperTooLong
|
||||
@ -88,7 +90,7 @@ internal static class HelperTooLong
|
||||
}
|
||||
}
|
||||
|
||||
internal static void UpdateDateVerifyAndGetTicksDirectories(Models.AppSettings appSettings, string directory)
|
||||
internal static void UpdateDateVerifyAndGetTicksDirectories(ILogger<Worker> logger, Models.AppSettings appSettings, string directory)
|
||||
{
|
||||
string ticksDirectoryName;
|
||||
DirectoryInfo directoryInfo;
|
||||
@ -107,8 +109,7 @@ internal static class HelperTooLong
|
||||
Directory.SetLastWriteTime(ticksDirectory, new DateTime(directoryTicks));
|
||||
}
|
||||
MaybeMoveFiles(appSettings, ticksDirectories);
|
||||
for (int i = 1; i < 10; i++)
|
||||
_ = HelperDeleteEmptyDirectories.DeleteEmptyDirectories(directory);
|
||||
HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, directory);
|
||||
}
|
||||
|
||||
}
|
@ -11,7 +11,7 @@ internal static partial class HelperZipFilesByDate
|
||||
[GeneratedRegex("[a-zA-Z0-9]{1,}")]
|
||||
private static partial Regex LowerAlphaAlphaAndNumber();
|
||||
|
||||
private static bool SetDateFromZipEntry(ILogger log, string[] zipFiles, string keyFile, string keyFileB, string keyFileC)
|
||||
private static bool SetDateFromZipEntry(ILogger<Worker> logger, string[] zipFiles, string keyFile, string keyFileB, string keyFileC)
|
||||
{
|
||||
bool result = false;
|
||||
string[] files;
|
||||
@ -81,7 +81,7 @@ internal static partial class HelperZipFilesByDate
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
log.LogInformation("<{zipFile}> is invalid!", zipFile);
|
||||
logger.LogInformation("<{zipFile}> is invalid!", zipFile);
|
||||
checkFile = string.Concat(zipFile, ".err");
|
||||
for (int e = 0; e < short.MaxValue; e++)
|
||||
{
|
||||
@ -91,12 +91,12 @@ internal static partial class HelperZipFilesByDate
|
||||
}
|
||||
try
|
||||
{ File.Move(zipFile, checkFile); }
|
||||
catch (Exception) { log.LogInformation("<{zipFile}> couldn't be moved!", zipFile); }
|
||||
catch (Exception) { logger.LogInformation("<{zipFile}> couldn't be moved!", zipFile); }
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static bool ZipFilesByDate(ILogger log, string sourceDirectory, SearchOption searchOption = SearchOption.TopDirectoryOnly, string dayFormat = "")
|
||||
internal static bool ZipFilesByDate(ILogger<Worker> logger, string sourceDirectory, SearchOption searchOption = SearchOption.TopDirectoryOnly, string dayFormat = "")
|
||||
{
|
||||
bool result = false;
|
||||
string key;
|
||||
@ -230,17 +230,17 @@ internal static partial class HelperZipFilesByDate
|
||||
}
|
||||
if (topDirectory != sourceDirectory)
|
||||
try
|
||||
{ _ = HelperDeleteEmptyDirectories.DeleteEmptyDirectories(topDirectory); }
|
||||
{ HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, topDirectory); }
|
||||
catch (Exception) { }
|
||||
log.LogInformation("{topDirectory}", topDirectory);
|
||||
logger.LogInformation("{topDirectory}", topDirectory);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static bool SetDateFromZipEntryForNuspec(ILogger log, string[] files) =>
|
||||
SetDateFromZipEntry(log, files, ".nuspec", "icon", "readme");
|
||||
internal static bool SetDateFromZipEntryForNuspec(ILogger<Worker> logger, string[] files) =>
|
||||
SetDateFromZipEntry(logger, files, ".nuspec", "icon", "readme");
|
||||
|
||||
internal static bool SetDateFromZipEntry(ILogger log, string sourceDirectory, SearchOption searchOption = SearchOption.AllDirectories)
|
||||
internal static bool SetDateFromZipEntry(ILogger<Worker> logger, string sourceDirectory, SearchOption searchOption = SearchOption.AllDirectories)
|
||||
{
|
||||
bool result = false;
|
||||
bool loop;
|
||||
@ -260,7 +260,7 @@ internal static partial class HelperZipFilesByDate
|
||||
_ => throw new NotSupportedException()
|
||||
};
|
||||
zipFiles = Directory.GetFiles(sourceDirectory, searchPattern, searchOption);
|
||||
loop = SetDateFromZipEntry(log, zipFiles, keyFile, keyFileB, keyFileC);
|
||||
loop = SetDateFromZipEntry(logger, zipFiles, keyFile, keyFileB, keyFileC);
|
||||
if (loop && !result)
|
||||
result = true;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ internal class Program
|
||||
_ = builder.Services.AddHostedService<Worker>();
|
||||
using IHost host = builder.Build();
|
||||
ILogger<Program> logger = host.Services.GetRequiredService<ILogger<Program>>();
|
||||
logger.LogCritical("appSettings.Company", appSettings.Company);
|
||||
logger.LogCritical("{appSettings.Company}", appSettings.Company);
|
||||
host.Run();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
trigger:
|
||||
- Development
|
||||
- master
|
||||
jobs:
|
||||
- job: apc_trend
|
||||
displayName: Copy common .gitconfig
|
||||
|
18
Worker.cs
18
Worker.cs
@ -30,7 +30,6 @@ public class Worker : BackgroundService
|
||||
ConsoleKey.B,
|
||||
ConsoleKey.C,
|
||||
ConsoleKey.D,
|
||||
ConsoleKey.E,
|
||||
ConsoleKey.F,
|
||||
ConsoleKey.G,
|
||||
ConsoleKey.H,
|
||||
@ -96,8 +95,8 @@ public class Worker : BackgroundService
|
||||
_Logger.LogInformation("C) Clipboard (Top Directory Only),");
|
||||
_Logger.LogInformation("D) Clipboard (All Directories),");
|
||||
// E
|
||||
// F
|
||||
_Logger.LogInformation("G) Genealogical Data Communication");
|
||||
_Logger.LogInformation("F) Find and delete all *.log.* files then empty directories,");
|
||||
_Logger.LogInformation("G) Genealogical Data Communication,");
|
||||
_Logger.LogInformation("H) Hardcoded file search and sort,");
|
||||
_Logger.LogInformation("I) Ignore case and rename files to lowercase,");
|
||||
_Logger.LogInformation("J) Set Date from Json Entry,");
|
||||
@ -129,6 +128,9 @@ public class Worker : BackgroundService
|
||||
case ConsoleKey.D:
|
||||
Helpers.HelperSaveOrCopyContents.SaveOrCopyContents(_Logger, _Args[0], consoleKey);
|
||||
break;
|
||||
case ConsoleKey.F:
|
||||
Helpers.HelperDeleteEmptyDirectories.DeleteOldLogFilesAndDeleteEmptyDirectories(_Logger, _Args[0]);
|
||||
break;
|
||||
case ConsoleKey.G:
|
||||
Helpers.HelperGenealogicalDataCommunication.FileSystemToGenealogicalDataCommunication(_AppSettings, _Logger, _Args);
|
||||
break;
|
||||
@ -148,7 +150,7 @@ public class Worker : BackgroundService
|
||||
Helpers.HelperLogMerge.LogMerge(_Args[0]);
|
||||
break;
|
||||
case ConsoleKey.N:
|
||||
Helpers.HelperCreateNoteFiles.CreateNoteFiles(_Args[0]);
|
||||
Helpers.HelperCreateNoteFiles.CreateNoteFiles(_Logger, _Args[0]);
|
||||
break;
|
||||
case ConsoleKey.M:
|
||||
if (_Args[0].EndsWith(".kanbn") && Directory.Exists(_Args[0]))
|
||||
@ -169,7 +171,7 @@ public class Worker : BackgroundService
|
||||
_ = Helpers.HelperZipFilesByDate.SetDateFromZipEntry(_Logger, _Args[0]);
|
||||
break;
|
||||
case ConsoleKey.T:
|
||||
Helpers.HelperTooLong.UpdateDateVerifyAndGetTicksDirectories(_AppSettings, _Args[0]);
|
||||
Helpers.HelperTooLong.UpdateDateVerifyAndGetTicksDirectories(_Logger, _AppSettings, _Args[0]);
|
||||
// Helpers.HelperTooLong.TooLong(_Args[0], delete: false);
|
||||
// Helpers.HelperTooLong.TooLong(_Args[0], delete: true);
|
||||
break;
|
||||
@ -189,11 +191,7 @@ public class Worker : BackgroundService
|
||||
switch (consoleKey)
|
||||
{
|
||||
case ConsoleKey.Delete:
|
||||
for (int j = 1; j < 6; j++)
|
||||
{
|
||||
if (!Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(_Args[0]))
|
||||
break;
|
||||
}
|
||||
Helpers.HelperDeleteEmptyDirectories.DeleteEmptyDirectories(_Logger, _Args[0]);
|
||||
break;
|
||||
default:
|
||||
throw new Exception();
|
||||
|
Loading…
x
Reference in New Issue
Block a user