using FluentFTP; using System; using System.Collections.Generic; using System.Data.SqlClient; using System.IO; using System.IO.Compression; using System.Linq; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Threading; using System.Threading.Tasks; using Tango.Core; using Tango.Core.IO; using Tango.PMR.Synchronization; using Tango.Settings; using Tango.SQLExaminer; using Tango.Transport.Web; namespace Tango.PPC.Common.MachineSetup { public class MachineSetupManager : ExtendedObject, IMachineSetupManager { public event EventHandler ProgressLog; public event EventHandler ProgressStep; private MachineSetupSteps _currentStep; public MachineSetupSteps CurrentStep { get { return _currentStep; } set { if (_currentStep != value) { _currentStep = value; RaisePropertyChangedAuto(); ProgressStep?.Invoke(this, _currentStep); } } } private double _downloadProgress; public double DownloadingPackagesProgress { get { return _downloadProgress; } private set { _downloadProgress = value; RaisePropertyChangedAuto(); } } private String _updatingPackagesStatus; public String DownloadingPackagesStatus { get { return _updatingPackagesStatus; } set { _updatingPackagesStatus = value; RaisePropertyChangedAuto(); } } public Task Setup(string serialNumber, string machineServiceAddress) { return Task.Factory.StartNew(() => { //Connect to machine service and get matching packages for this machine. CurrentStep = MachineSetupSteps.DownloadingPackage; DownloadingPackagesProgress = 0; DownloadingPackagesStatus = "Connecting to machine service..."; MachineSetupRequest request = new MachineSetupRequest(); request.SerialNumber = serialNumber; MachineSetupResponse setup_response = null; using (var http = new ProtoWebClient()) { setup_response = http.Post(machineServiceAddress + "/api/Synchronization/MachineSetup", request).Result; } //Create temporary folders for packages. var _newPackageTempFolder = TemporaryManager.CreateFolder(); _newPackageTempFolder.Persist = true; //Download software package. var tempFile = TemporaryManager.CreateFile(".zip"); DownloadingPackagesStatus = "Downloading software package..."; int fileSize = 0; DownloadingPackagesProgress = 0; using (FileStreamWrapper fs = new FileStreamWrapper(tempFile.Path, FileMode.Create, (current) => { InvokeUINow(() => { Thread.Sleep(10); DownloadingPackagesProgress = ((double)current / (double)fileSize) * 100d; }); })) { using (FtpClient ftp = new FtpClient(setup_response.FtpAddress, setup_response.UserName, setup_response.Password)) { LogManager.Log("Connecting to FTP site: " + setup_response.FtpAddress); ftp.ConnectAsync().Wait(); LogManager.Log("Retrieving download size..."); fileSize = (int)ftp.GetFileSize(setup_response.FilePath); LogManager.Log("Download size: " + fileSize + " bytes."); LogManager.Log("Starting download..."); ftp.DownloadAsync(fs, setup_response.FilePath).Wait(); } } //Extract software package. ZipFile.ExtractToDirectory(tempFile, _newPackageTempFolder); //Synchronize database CurrentStep = MachineSetupSteps.SynchronizingSchema; String db_name = "Tango"; String localAddress = SettingsManager.Default.GetOrCreate().DataBaseSource; String remote_address = setup_response.DbAddress; DbManager db = new DbManager(new SqlConnection(String.Format("Server={0};Integrated security=SSPI", localAddress))); if (!db.Exists(db_name)) { throw new InvalidProgramException("Database tango does not exists."); } db.ClearDb(db_name); //TODO: This is not working! ExaminerSequenceConfigurationRunner runner = new ExaminerSequenceConfigurationRunner( Path.Combine(_newPackageTempFolder, "Synchronization Scripts", "config.xml"), Path.Combine(_newPackageTempFolder, "Synchronization Scripts"), new ExaminerSequenceDataSource() { Address = remote_address, DataBaseName = db_name, IntegratedSecurity = true, }, new ExaminerSequenceDataSource() { Address = localAddress, DataBaseName = db_name, IntegratedSecurity = true, }, serialNumber); runner.Log += (x, msg) => { ProgressLog.Invoke(this, msg); }; runner.ScriptExecuting += (x, item) => { if (item.Type == ExaminerSequenceItemType.Data && item.RequiresSerialNumber) { CurrentStep = MachineSetupSteps.SynchronizingMachineConfiguration; } else if (item.Type == ExaminerSequenceItemType.Data) { CurrentStep = MachineSetupSteps.SynchronizingData; } }; runner.Run().Wait(); }); } } }