using ICSharpCode.SharpZipLib.Zip; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using MP.AppAuth; using MP.Land.Data; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Threading.Tasks; namespace MP.Land.Pages { public partial class UpdateManager : IDisposable { #region Public Methods public void Dispose() { ListRecords = null; GC.Collect(); } #endregion Public Methods #region Protected Fields protected int numDone = 0; protected int numTot = 0; protected int totalCount = 0; protected long TotalMb = 0; protected UpdateMan updateManAuth = new UpdateMan("SWDownloader", "viaD@nte16"); #endregion Protected Fields #region Protected Properties [Inject] protected MessageService AppMService { get; set; } [Inject] protected IConfiguration Configuration { get; set; } [Inject] protected AppAuthService DataService { get; set; } [Inject] protected LicenseService LicServ { get; set; } = null!; protected string outMessages { get; set; } = ""; protected int percLoading { get; set; } = 0; protected bool showProgress { get; set; } = false; protected bool showUpdate { get; set; } = false; #endregion Protected Properties #region Protected Methods /// /// Restituisce size calcolata /// /// /// protected string CalcSize(long origSize) { return MeasureUtils.SizeSuffix(origSize, 1); } protected void CloseProgUpdate() { showUpdate = false; } /// /// Cicla su tutti i record ed effettua il download /// protected async Task DownloadAll() { // init progress... showProgress = true; showUpdate = true; outMessages = $"Iniziato download per {numTot} packages"; await InvokeAsync(StateHasChanged); percLoading = 0; TotalMb = 0; numDone = 0; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); // ciclo su tutti quelli con licenza valida... List rawList = ListRecords .Where(x => !string.IsNullOrEmpty(x.LicenseKey)).ToList(); List authList = new List(); // ciclo SOLO tra quelli davvero autorizzati... foreach (var item in rawList) { if (LicServ.checkLicenseActive(item.LicenseKey)) { authList.Add(item); } } numTot = authList.Count; foreach (var item in authList) { ScaricaSingolo(item); await InvokeAsync(StateHasChanged); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; outMessages = $"Effettuato download di {numDone} update | {CalcSize(TotalMb)} in {ts.TotalSeconds:N2} s"; await InvokeAsync(StateHasChanged); await Task.Delay(1000); showProgress = false; await InvokeAsync(StateHasChanged); } protected string localPath(string localRepo) { return @$"{Configuration["ServerConf:downloadPath"]}\{localRepo}\{Configuration["appVers"]}"; ; } protected override async Task OnInitializedAsync() { ListRecords = null; await Task.Delay(1); AppMService.ShowSearch = false; AppMService.PageName = "Update Manager"; AppMService.PageIcon = "fas fa-download pe-2"; await ReloadData(); } protected async Task ReloadData() { // importante altrimenti NON mostra update UI await Task.Delay(1); ListRecords = await DataService.UpdManList(); totalCount = ListRecords.Count(); await Task.Delay(1); } /// /// Cicla su tutti i record applicativi, crea ZIP cifrato + upload su LiMan /// protected async Task UploadBackupConfig() { // init progress... showProgress = true; showUpdate = true; outMessages = $"Inizio preparazione per upload configurazioni di {numTot} packages"; await InvokeAsync(StateHasChanged); percLoading = 0; TotalMb = 0; numDone = 0; int numIOB = 0; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); // ciclo su tutti quelli con licenza valida... List rawList = ListRecords .Where(x => !string.IsNullOrEmpty(x.LicenseKey)).ToList(); List authList = new List(); // ciclo SOLO tra quelli davvero autorizzati... foreach (var item in rawList) { if (LicServ.checkLicenseActive(item.LicenseKey)) { authList.Add(item); } } // numero app + IOB + ZIP numTot = authList.Count + 2; // recupero conf files foreach (var item in authList) { // cerco i file di conf e li copio RecuperaConf(item); await Task.Delay(10); await InvokeAsync(StateHasChanged); } // recupero i file IOB RecuperaIobConf(); // ora creo il file zip await PrepareZip(); // effettuo upload await UploadZip(); // concludo! stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; outMessages = $"Effettuato Upload backup configurazioni per {numDone} app + {numIOB} IOB | {CalcSize(TotalMb)} | {ts.TotalSeconds:N2} s"; await InvokeAsync(StateHasChanged); await Task.Delay(1000); showProgress = false; await InvokeAsync(StateHasChanged); } #endregion Protected Methods #region Private Fields private List ListRecords; #endregion Private Fields #region Private Properties #if DEBUG private DirectoryInfo AppDir => new DirectoryInfo(Path.Combine("\\\\iis01.egalware.com", "c$\\inetpub\\wwwroot\\MP\\LAND")); #else private DirectoryInfo AppDir => new DirectoryInfo(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)); #endif #endregion Private Properties #region Private Methods /// /// Preparazione ZIP con password = AuthKey /// private async Task PrepareZip() { string srcPath = Path.Combine(AppDir.FullName, "temp", "orig"); string destPath = Path.Combine(AppDir.FullName, "temp", "zip"); if(!Directory.Exists(destPath)) { Directory.CreateDirectory(destPath); } string zFile = Path.Combine(AppDir.FullName, "temp", "zip", "MAPO.zip"); #if false ZipDirectory(folderName, zFile, 9); await Task.Delay(1); #endif using (ZipFile zipFile = ZipFile.Create(zFile)) { zipFile.BeginUpdate(); addFolderToZip(zipFile, srcPath, srcPath); zipFile.CommitUpdate(); zipFile.Close(); } } public void addFolderToZip(ZipFile f, string root, string folder) { string relative = folder.Substring(root.Length); if (relative.Length > 0) { f.AddDirectory(relative); } foreach (string file in Directory.GetFiles(folder)) { relative = file.Substring(root.Length); f.Add(file, relative); } foreach (string subFolder in Directory.GetDirectories(folder)) { this.addFolderToZip(f, root, subFolder); } } /// /// Method that compress all the files inside a folder (non-recursive) into a zip file. /// /// /// /// private void ZipDirectory(string DirectoryPath, string OutputFilePath, int CompressionLevel = 9) { try { // Depending on the directory this could be very large and would require more attention // in a commercial package. string[] filenames = Directory.GetFiles(DirectoryPath); // 'using' statements guarantee the stream is closed properly which is a big source // of problems otherwise. Its exception safe as well which is great. using (ZipOutputStream OutputStream = new ZipOutputStream(File.Create(OutputFilePath))) { // Define the compression level // 0 - store only to 9 - means best compression OutputStream.SetLevel(CompressionLevel); byte[] buffer = new byte[4096]; foreach (string file in filenames) { // Using GetFileName makes the result compatible with XP // as the resulting path is not absolute. ZipEntry entry = new ZipEntry(Path.GetFileName(file)); // Setup the entry data as required. // Crc and size are handled by the library for seakable streams // so no need to do them here. // Could also use the last write time or similar for the file. entry.DateTime = DateTime.Now; OutputStream.PutNextEntry(entry); using (FileStream fs = File.OpenRead(file)) { // Using a fixed size buffer here makes no noticeable difference for output // but keeps a lid on memory usage. int sourceBytes; do { sourceBytes = fs.Read(buffer, 0, buffer.Length); OutputStream.Write(buffer, 0, sourceBytes); } while (sourceBytes > 0); } } // Finish/Close arent needed strictly as the using statement does this automatically // Finish is important to ensure trailing information for a Zip file is appended. Without this // the created file would be invalid. OutputStream.Finish(); // Close is important to wrap things up and unlock the file. OutputStream.Close(); Console.WriteLine("Files successfully compressed"); } } catch (Exception ex) { // No need to rethrow the exception as for our purposes its handled. Console.WriteLine("Exception during processing {0}", ex); } } /// /// Recupera fdile di conf da app indicata /// /// private void RecuperaConf(AppAuth.Models.UpdMan item) { long size = 0; if (item.IsAuth) { string dstDir = Path.Combine(AppDir.FullName, "temp", "orig", item.PackName); if (!Directory.Exists(dstDir)) { Directory.CreateDirectory(dstDir); } string srcDir = Path.Combine(AppDir.Parent.FullName, item.PackName); // recupero elenco files tipo appsettings*.json if (Directory.Exists(srcDir)) { var dirInfo = new DirectoryInfo(srcDir); // recupero files CORE List fileList = dirInfo.GetFiles("appsettings*.json").ToList(); // recupero files Framework List fileListFram = dirInfo.GetFiles("web*.config").ToList(); // merge... foreach (var fileFrm in fileListFram) { fileList.Add(fileFrm); } // procedo! foreach (var file in fileList) { string fileDestPath = Path.Combine(dstDir, file.Name); file.CopyTo(fileDestPath, true); size += file.Length; } numDone++; percLoading = 100 * numDone / numTot; TotalMb += size; outMessages = $"Configurazioni preparate: {numDone}/{numTot} | {CalcSize(TotalMb)}"; } } } /// /// recupera tutte le conf IOB trasferite all'MP-IO dai vari IOB-WIN /// private void RecuperaIobConf() { long size = 0; string dstDir = Path.Combine(AppDir.FullName, "temp", "orig", "IOB"); if (!Directory.Exists(dstDir)) { Directory.CreateDirectory(dstDir); } string srcIobDir = Path.Combine(AppDir.Parent.FullName, "IO", "fileUpload"); // recupero elenco files tipo appsettings*.json if (Directory.Exists(srcIobDir)) { var dirInfo = new DirectoryInfo(srcIobDir); // recupero files CORE List fileList = dirInfo.GetFiles().ToList(); // procedo! foreach (var file in fileList) { string fileDestPath = Path.Combine(dstDir, file.Name); file.CopyTo(fileDestPath, true); size += file.Length; } numDone++; percLoading = 100 * numDone / numTot; TotalMb += size; outMessages = $"Configurazioni preparate: {numDone}/{numTot} | {CalcSize(TotalMb)}"; } } /// /// Effettua download di una singola app /// /// private void ScaricaSingolo(AppAuth.Models.UpdMan item) { long size = 0; if (item.IsAuth) { size = updateManAuth.downloadLatest(item.ManifestUrl, localPath(item.LocalRepo), item.PackName); } else { size = UpdateMan.obj.downloadLatest(item.ManifestUrl, localPath(item.LocalRepo), item.PackName); } numDone++; percLoading = 100 * numDone / numTot; TotalMb += size; outMessages = $"Scaricati {numDone}/{numTot} packages | {CalcSize(TotalMb)}"; } /// /// Invio zip al server LiMan remoto /// /// /// private async Task UploadZip() { await Task.Delay(200); } #endregion Private Methods } }