file-folder-helper/Helpers/HelperZipFilesByDate.cs
Mike Phares 219fdda4ec DeleteOldLogFilesAndDeleteEmptyDirectories
Log bug
Wafer Counter
trigger:  - master
2023-10-01 11:07:36 -07:00

270 lines
12 KiB
C#

using Microsoft.Extensions.Logging;
using System.Globalization;
using System.IO.Compression;
using System.Text.RegularExpressions;
namespace File_Folder_Helper.Helpers;
internal static partial class HelperZipFilesByDate
{
[GeneratedRegex("[a-zA-Z0-9]{1,}")]
private static partial Regex LowerAlphaAlphaAndNumber();
private static bool SetDateFromZipEntry(ILogger<Worker> logger, string[] zipFiles, string keyFile, string keyFileB, string keyFileC)
{
bool result = false;
string[] files;
string checkFile;
FileInfo fileInfo;
string? zipDirectory;
DateTimeOffset? dateTimeOffset;
foreach (string zipFile in zipFiles)
try
{
dateTimeOffset = null;
fileInfo = new(zipFile);
using ZipArchive zip = ZipFile.Open(zipFile, ZipArchiveMode.Read);
foreach (ZipArchiveEntry zipArchiveEntry in zip.Entries)
{
if (!zipArchiveEntry.Name.EndsWith(keyFile))
continue;
dateTimeOffset = zipArchiveEntry.LastWriteTime;
break;
}
zipDirectory = Path.GetDirectoryName(zipFile);
if (dateTimeOffset is null || zipDirectory is null)
continue;
if (fileInfo.LastWriteTime != dateTimeOffset.Value.LocalDateTime)
{
File.SetLastWriteTime(fileInfo.FullName, dateTimeOffset.Value.LocalDateTime);
if (!result)
result = true;
}
files = Directory.GetFiles(zipDirectory, $"*{keyFile}", SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
fileInfo = new(file);
if (fileInfo.LastWriteTime != dateTimeOffset.Value.LocalDateTime)
{
File.SetLastWriteTime(fileInfo.FullName, dateTimeOffset.Value.LocalDateTime);
if (!result)
result = true;
}
}
if (string.IsNullOrEmpty(keyFileB))
continue;
files = Directory.GetFiles(zipDirectory, keyFileB, SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
fileInfo = new(file);
if (fileInfo.LastWriteTime != dateTimeOffset.Value.LocalDateTime)
{
File.SetLastWriteTime(fileInfo.FullName, dateTimeOffset.Value.LocalDateTime);
if (!result)
result = true;
}
}
if (string.IsNullOrEmpty(keyFileC))
continue;
files = Directory.GetFiles(zipDirectory, keyFileC, SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
fileInfo = new(file);
if (fileInfo.LastWriteTime != dateTimeOffset.Value.LocalDateTime)
{
File.SetLastWriteTime(fileInfo.FullName, dateTimeOffset.Value.LocalDateTime);
if (!result)
result = true;
}
}
}
catch (Exception)
{
logger.LogInformation("<{zipFile}> is invalid!", zipFile);
checkFile = string.Concat(zipFile, ".err");
for (int e = 0; e < short.MaxValue; e++)
{
if (!File.Exists(checkFile))
break;
checkFile = string.Concat(checkFile, e);
}
try
{ File.Move(zipFile, checkFile); }
catch (Exception) { logger.LogInformation("<{zipFile}> couldn't be moved!", zipFile); }
}
return result;
}
internal static bool ZipFilesByDate(ILogger<Worker> logger, string sourceDirectory, SearchOption searchOption = SearchOption.TopDirectoryOnly, string dayFormat = "")
{
bool result = false;
string key;
bool addFile;
string fileName;
string? zipPath;
FileInfo fileInfo;
string weekOfYear;
string[] segments;
string[] subFiles;
string zipDirectory;
DateTime creationTime;
string? directoryName;
DateTime lastWriteTime;
DateTime nowDateTime = DateTime.Now;
DateTime dateTime = DateTime.MinValue;
DateTime firstEmail = new(2019, 3, 8);
CultureInfo cultureInfo = new("en-US");
Calendar calendar = cultureInfo.Calendar;
Regex regex = LowerAlphaAlphaAndNumber();
Dictionary<string, DateTime> weeks = new();
int ticksLength = nowDateTime.AddDays(-6).Ticks.ToString().Length;
for (int i = 0; i < int.MaxValue; i++)
{
dateTime = firstEmail.AddDays(i);
if (dateTime > nowDateTime)
break;
weekOfYear = calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00");
key = string.Concat(dateTime.ToString("yyyy"), "_Week_", weekOfYear);
if (!weeks.ContainsKey(key))
weeks.Add(key, dateTime);
}
weekOfYear = calendar.GetWeekOfYear(nowDateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00");
string skipKey = string.Concat(nowDateTime.ToString("yyyy"), "_Week_", weekOfYear);
Dictionary<string, List<string>> keyValuePairs = new();
string[] topDirectories = Directory.GetDirectories(sourceDirectory, "*", SearchOption.TopDirectoryOnly);
if (topDirectories.Length == 0)
topDirectories = new string[] { sourceDirectory };
foreach (string topDirectory in topDirectories)
{
keyValuePairs.Clear();
directoryName = Path.GetDirectoryName(topDirectory);
subFiles = Directory.GetFiles(topDirectory, "*", searchOption);
zipPath = string.IsNullOrEmpty(directoryName) ? null : Path.Combine(directoryName, "ZipPath");
zipDirectory = zipPath is not null && Directory.Exists(zipPath) ? zipPath : topDirectory;
foreach (string subFile in subFiles)
{
addFile = false;
if (subFile.EndsWith(".zip"))
continue;
fileName = Path.GetFileName(subFile);
fileInfo = new FileInfo(subFile);
creationTime = fileInfo.CreationTime;
if (creationTime > dateTime)
continue;
lastWriteTime = fileInfo.LastWriteTime;
if (fileName.Contains(lastWriteTime.ToString("yyyyMMdd")) || fileName.Contains(lastWriteTime.ToString("yyyy-MM-dd")) ||
fileName.Contains(creationTime.ToString("yyyyMMdd")) || fileName.Contains(creationTime.ToString("yyyy-MM-dd")) ||
fileName.Contains(lastWriteTime.ToString("yyMMdd")) || fileName.Contains(lastWriteTime.ToString("yy-MM-dd")) ||
fileName.Contains(creationTime.ToString("yyMMdd")) || fileName.Contains(creationTime.ToString("yy-MM-dd")) ||
fileName.Contains(lastWriteTime.AddDays(-1).ToString("yyyyMMdd")) || fileName.Contains(lastWriteTime.AddDays(-1).ToString("yyyy-MM-dd")) ||
fileName.Contains(creationTime.AddDays(-1).ToString("yyyyMMdd")) || fileName.Contains(creationTime.AddDays(-1).ToString("yyyy-MM-dd")) ||
fileName.Contains(lastWriteTime.AddDays(-1).ToString("yyMMdd")) || fileName.Contains(lastWriteTime.AddDays(-1).ToString("yy-MM-dd")) ||
fileName.Contains(creationTime.AddDays(-1).ToString("yyMMdd")) || fileName.Contains(creationTime.AddDays(-1).ToString("yy-MM-dd")))
addFile = true;
if (!addFile && fileName.Length > ticksLength)
{
MatchCollection matches = regex.Matches(fileName);
foreach (Match match in matches.Cast<Match>())
{
if (match.Value.Length != ticksLength)
continue;
if (!long.TryParse(match.Value, out long ticks))
continue;
addFile = true;
break;
}
if (addFile)
break;
}
if (addFile)
{
weekOfYear = calendar.GetWeekOfYear(lastWriteTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00");
if (string.IsNullOrEmpty(dayFormat))
key = string.Concat(lastWriteTime.ToString("yyyy"), "_Week_", weekOfYear);
else
key = string.Concat(lastWriteTime.ToString("yyyy"), "_Week_", weekOfYear, "_", lastWriteTime.ToString(dayFormat));
if (key == skipKey)
continue;
if (!keyValuePairs.ContainsKey(key))
keyValuePairs.Add(key, new List<string>());
keyValuePairs[key].Add(subFile);
}
}
foreach (KeyValuePair<string, List<string>> element in keyValuePairs)
{
key = Path.Combine(zipDirectory, $"{element.Key}.zip");
if (File.Exists(key))
for (short i = 101; i < short.MaxValue; i++)
{
key = Path.Combine(zipDirectory, $"{element.Key}_{i}.zip");
if (!File.Exists(key))
break;
}
using ZipArchive zip = ZipFile.Open(key, ZipArchiveMode.Create);
foreach (string file in element.Value)
{
_ = zip.CreateEntryFromFile(file, Path.GetFileName(file));
File.Delete(file);
}
if (zipPath is not null && Directory.Exists(zipPath) && !string.IsNullOrEmpty(directoryName))
try
{ Directory.SetLastWriteTime(directoryName, DateTime.Now); }
catch (Exception) { }
}
subFiles = Directory.GetFiles(zipDirectory, "*.zip", SearchOption.TopDirectoryOnly);
foreach (string subFile in subFiles)
{
fileName = Path.GetFileNameWithoutExtension(subFile);
segments = fileName.Split('_');
if (segments.Length > 2)
fileName = string.Concat(segments[0], '_', segments[1], '_', segments[2]);
if (weeks.TryGetValue(fileName, out DateTime value))
try
{
if (!result)
result = true;
File.SetLastWriteTime(subFile, value);
}
catch (Exception) { }
}
if (topDirectory != sourceDirectory)
try
{ HelperDeleteEmptyDirectories.DeleteEmptyDirectories(logger, topDirectory); }
catch (Exception) { }
logger.LogInformation("{topDirectory}", topDirectory);
}
return result;
}
internal static bool SetDateFromZipEntryForNuspec(ILogger<Worker> logger, string[] files) =>
SetDateFromZipEntry(logger, files, ".nuspec", "icon", "readme");
internal static bool SetDateFromZipEntry(ILogger<Worker> logger, string sourceDirectory, SearchOption searchOption = SearchOption.AllDirectories)
{
bool result = false;
bool loop;
string keyFile;
string keyFileB;
string keyFileC;
string[] zipFiles;
string searchPattern;
if (!Directory.Exists(sourceDirectory))
_ = Directory.CreateDirectory(sourceDirectory);
for (int i = 1; i < 3; i++)
{
(searchPattern, keyFile, keyFileB, keyFileC) = i switch
{
1 => ("*.nupkg", ".nuspec", "icon", "readme"),
2 => ("*.vsix", ".vsixmanifest", string.Empty, string.Empty),
_ => throw new NotSupportedException()
};
zipFiles = Directory.GetFiles(sourceDirectory, searchPattern, searchOption);
loop = SetDateFromZipEntry(logger, zipFiles, keyFile, keyFileB, keyFileC);
if (loop && !result)
result = true;
}
return result;
}
}