using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using GestoreTrimestrale.Logic; using System.Configuration; using SmartFTP.Logic; using DataAccessLayer; using System.Data; using System.Windows.Threading; using System.Text.RegularExpressions; using System.IO; namespace GestoreTrimestrale { /// /// Interaction logic for MainWindow.xaml /// enum MessageType { Information, Error, Warning } public partial class MainWindow : Window { private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); configModel model; Thread gestoreThread; Thread getLogsThread; Thread updateCountersThread; Thread processObservation; bool initialize; private ZipManagerProcess myZipManager = null; private DateTime logsDate; private CounterStorage counterStorage; private bool statisticsPrepared = false; private string currentConfigFile = null; private string defaultConfigFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; public MainWindow() { initialize = true; InitializeComponent(); this.t_saveToDisk.Items.Add(0); this.t_saveToDisk.Items.Add(1); this.t_saveToDisk.Items.Add(2); counterStorage = new CounterStorage(); this.t_counters_elab.ItemsSource = counterStorage.ElabCounters; this.t_counters_stato.ItemsSource = counterStorage.StatoReportCounters; SetFieldsUsingConfig(); processObservation = new Thread(() => ObserveProcesses()); processObservation.Start(); setConfigFile(); } private void SetFieldsUsingConfig(string configPath = null) { model = new configModel(configPath); this.t_autoZip.IsChecked = true; this.t_connectionString.Text = model.ConnectionString; this.t_cliPerZip.Text = model.numeroCfPerZip.ToString(); this.t_conProcesses.Text = model.maxGestoreThreads.ToString(); this.t_pdfOutputFolder.Text = model.PDFOutputFolder; this.t_pdfProcessFolder.Text = model.PDFProcessFolder; //this.t_workFolder.Text = model.WorkFolder; this.t_zipBackupFolder.Text = model.ZipBackupFolder; this.t_zipFolder.Text = model.ZipFolder; this.t_logWaitTime.Text = model.loggingInterval.ToString(); this.t_qContratti.Text = model.QueryContratti; this.t_saveToDisk.SelectedValue = model.SavePDFtoDISK; this.t_connectionString_reportManager.Text = model.ConnectionStringReportManager; this.t_zipWaitTime.Text = model.zipInterval.ToString(); this.t_countersWaitTime.Text = model.countersUpdateInterval.ToString(); this.t_ftpPassword.Password = model.FTPPassword; this.t_ftpServer.Text = model.FTPServer; this.t_ftpUser.Text = model.FTPLogin; this.t_sqlCommandTimeout.Text = model.SqlCommandTimeout.ToString(); initialize = false; } private void main_TextChanged(object sender, TextChangedEventArgs e) { try { // UpdateModel(); } catch (Exception ex) { MessageBox.Show(ex.Message + ex.StackTrace); } } private void UpdateModel(object sender = null, string newVal = null) { if (!initialize) { if (sender != null) { if (sender == this.t_connectionString) { model.ConnectionString = this.t_connectionString.Text; } } model.ConnectionStringReportManager = this.t_connectionString_reportManager.Text; int tmp = 0; int.TryParse(this.t_cliPerZip.Text, out tmp); model.numeroCfPerZip = tmp; tmp = 0; int.TryParse(this.t_conProcesses.Text, out tmp); model.maxGestoreThreads = tmp; tmp = 0; int.TryParse(this.t_logWaitTime.Text, out tmp); model.loggingInterval = tmp; tmp = 0; int.TryParse(this.t_countersWaitTime.Text, out tmp); model.countersUpdateInterval = tmp; tmp = 0; int.TryParse(this.t_zipWaitTime.Text, out tmp); model.zipInterval = tmp; tmp = 0; int.TryParse(this.t_sqlCommandTimeout.Text, out tmp); model.SqlCommandTimeout = tmp; model.FTPPassword = this.t_ftpPassword.Password; model.FTPServer = this.t_ftpServer.Text; model.FTPLogin = this.t_ftpUser.Text; model.PDFOutputFolder = this.t_pdfOutputFolder.Text; model.PDFProcessFolder = this.t_pdfProcessFolder.Text; //model.WorkFolder = this.t_workFolder.Text; model.ZipBackupFolder = this.t_zipBackupFolder.Text; model.ZipFolder = this.t_zipFolder.Text; model.QueryContratti = this.t_qContratti.Text; model.SavePDFtoDISK = Int32.Parse(this.t_saveToDisk.SelectedValue.ToString()); //ConfigurationManager.RefreshSection("appConfig"); } } private void t_ftpPassword_PasswordChanged(object sender, RoutedEventArgs e) { UpdateModel(); } private void t_connectionString_TextInput(object sender, TextCompositionEventArgs e) { UpdateModel(); } private void t_connectionString_SelectionChanged(object sender, SelectionChangedEventArgs e) { UpdateModel(); } private void t_saveToDisk_SelectionChanged(object sender, SelectionChangedEventArgs e) { //UpdateModel(); } private void button_Click(object sender, RoutedEventArgs e) { try { if (button.Content.ToString().ToLower() == "start processing") { string message = "Are you sure you want to start the process?"; List differences = FindConfigAndInputDifferences(); if (differences.Count > 0) { message = "There are differences between currently loaded config and data in graphic interface, in following fields:\n\n"; foreach (string s in differences) { message += string.Format("*{0}\n", s); } message += "\n"; message += "Are you sure you want to start the process?"; } if (MessageBox.Show(message, "Please confirm", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes) { InsertMessage("Starting pdf creation process", MessageType.Information); SetPorcessingControls(false); ConfigurationManager.RefreshSection("appConfig"); button.Content = "Stop Processing"; ThreadStart starter = () => { try { PrepareStatistics(); GestorePDF.Logic.ThreadManager m = new GestorePDF.Logic.ThreadManager(); int maxGestoreThreads = int.Parse(ConfigurationManager.AppSettings["maxGestoreThreads"]); m.Main(maxGestoreThreads); } catch (Exception ex) { Application.Current.Dispatcher.Invoke(new Action(() => { MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); })); } }; starter += () => { button.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate () { button.IsEnabled = false; button.Content = "Processing Finished"; })); if (updateCountersThread != null && updateCountersThread.IsAlive) { updateCountersThread.Abort(); } string statisticsResult = GetStatistics(); MessageBox.Show(statisticsResult, "PDF generation process finished"); }; gestoreThread = new Thread(starter) { IsBackground = true }; getLogsThread = new Thread(() => ObtainLogs()); updateCountersThread = new Thread(() => ObtainStatistics()); logsDate = DateTime.Now; gestoreThread.Start(); getLogsThread.Start(); updateCountersThread.Start(); if (t_autoZip.IsChecked == true) { InitializeZipping(); } } } else if (MessageBox.Show("Are you sure you want to abort the process", "Warning", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes) { button.Content = "Start Processing"; if (gestoreThread != null && gestoreThread.IsAlive) gestoreThread.Abort(); if (getLogsThread != null && getLogsThread.IsAlive) getLogsThread.Abort(); if (myZipManager != null) myZipManager.Dispose(); SetPorcessingControls(true); } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); } } private List FindConfigAndInputDifferences() { List results = new List(); if (t_connectionString.Text.ToLower() != ConfigurationManager.ConnectionStrings["SqlServerStampeC6Connection"].ToString().ToLower()) { results.Add("database for processing"); } if (t_connectionString_reportManager.Text.ToLower() != ConfigurationManager.ConnectionStrings["SqlServerConnection"].ToString().ToLower()) { results.Add("database for report manager"); } if (t_qContratti.Text.ToLower() != ConfigurationManager.AppSettings["QueryContratti"].ToString().ToLower()) { results.Add("query contratti"); } if (t_saveToDisk.Text.ToLower() != ConfigurationManager.AppSettings["SavePDFtoDISK"].ToString().ToLower()) { results.Add("save PDF to DISK"); } if (t_pdfProcessFolder.Text.ToLower() != ConfigurationManager.AppSettings["pathFolder"].ToString().ToLower()) { results.Add("PDF process folder"); } if (t_pdfOutputFolder.Text.ToLower() != ConfigurationManager.AppSettings["pathPDFToDB_PERIODICO"].ToString().ToLower()) { results.Add("PDF output folder"); } if (t_zipFolder.Text.ToLower() != ConfigurationManager.AppSettings["path_OUTPUT_ZIP_PERIODICO"].ToString().ToLower()) { results.Add("zip folder"); } if (t_zipBackupFolder.Text.ToLower() != ConfigurationManager.AppSettings["path_ZIP_BACKUP_FOLDER"].ToString().ToLower()) { results.Add("zip backup folder"); } if (t_sqlCommandTimeout.Text.ToLower() != ConfigurationManager.AppSettings["sqlCommandTimeout"].ToString().ToLower()) { results.Add("sql commands timeout"); } if (t_conProcesses.Text.ToLower() != ConfigurationManager.AppSettings["maxGestoreThreads"].ToString().ToLower()) { results.Add("number of concurrent processes"); } if (t_cliPerZip.Text.ToLower() != ConfigurationManager.AppSettings["numeroCfPerZip"].ToString().ToLower()) { results.Add("number of Client's per zip file"); } if (t_logWaitTime.Text.ToLower() != ConfigurationManager.AppSettings["loggingInterval"].ToString().ToLower()) { results.Add("logging interval (minutes)"); } if (t_countersWaitTime.Text.ToLower() != ConfigurationManager.AppSettings["statisticsUpdateInterval"].ToString().ToLower()) { results.Add("counters update interval (minutes)"); } if (t_zipWaitTime.Text.ToLower() != ConfigurationManager.AppSettings["zipInterval"].ToString().ToLower()) { results.Add("zip process \"wait\" interval (minutes)"); } if (t_ftpServer.Text.ToLower() != ConfigurationManager.AppSettings["FTPServer"].ToString().ToLower()) { results.Add("FTP Server location"); } if (t_ftpUser.Text.ToLower() != ConfigurationManager.AppSettings["FTPUser"].ToString().ToLower()) { results.Add("FTP Login"); } if (t_ftpPassword.Password.ToLower() != ConfigurationManager.AppSettings["FTPPassword"].ToString().ToLower()) { results.Add("FTP Password"); } return results; } public void SetPorcessingControls(bool isEnabled) { t_autoZip.IsEnabled = t_cliPerZip.IsEnabled = t_conProcesses.IsEnabled = t_ftpLog.IsEnabled = t_ftpPassword.IsEnabled = t_ftpServer.IsEnabled = t_ftpUser.IsEnabled = t_pdfOutputFolder.IsEnabled = t_pdfProcessFolder.IsEnabled = t_qContratti.IsEnabled = t_saveToDisk.IsEnabled = //t_workFolder.IsEnabled = t_zipBackupFolder.IsEnabled = t_zipFolder.IsEnabled = t_zipWaitTime.IsEnabled = t_logWaitTime.IsEnabled = t_countersWaitTime.IsEnabled = isEnabled; } private void t_autoZip_Click(object sender, RoutedEventArgs e) { button2.IsEnabled = !(t_autoZip.IsChecked == true); } private void button1_Click(object sender, RoutedEventArgs e) { InsertMessage("Starting ftp transfer process", MessageType.Information); string zipFolder = model.ZipFolder; string backupFolder = model.ZipBackupFolder; string ftpServer = model.FTPServer; string ftpUser = model.FTPLogin; string ftpPath = model.FTPPath; string ftpPassword = model.FTPPassword; int res = FTPProcessSeparated.UploadTrimestraleFiles(zipFolder, ftpServer, ftpPath, ftpUser, ftpPassword, backupFolder); } private void t_saveToDisk_SelectionChanged_1(object sender, SelectionChangedEventArgs e) { if (initialize) return; model.SavePDFtoDISK = int.Parse(e.AddedItems[0].ToString()); } private void InitializeZipping() { InsertMessage("Starting zip process", MessageType.Information); int zipInterval = int.Parse(ConfigurationManager.AppSettings["zipInterval"]); myZipManager = new ZipManagerProcess(zipInterval, @"c:\temp\o.txt"); //myZipManager.Start(); } private void button2_Click(object sender, RoutedEventArgs e) { if (button2.Content.ToString() == "Start zipping") { button2.Content = "Stop zipping"; InitializeZipping(); } else { if (myZipManager != null && myZipManager.workingThread != null && myZipManager.workingThread.IsAlive) { myZipManager.workingThread.Abort(); button2.Content = "Start zipping"; } } } private void InsertMessage(string message, MessageType type) { } private void ObtainLogs() { string getLogsProcedure = ConfigurationManager.AppSettings["getLogsProcedure"]; while (gestoreThread?.IsAlive == true) { try { using (DataAccessDE dataAccess = new DataAccessDE(DBProvider.SqlServerStampeC6)) { List parameters = new List(); parameters.Add(new Parametro() { ParameterName = "LogsSince", Value = logsDate }); logsDate = DateTime.Now; DataTable result = dataAccess.ExecuteDataTableStoredProcedure(DBProvider.SqlServerStampeC6, getLogsProcedure, parameters); List tmp = new List(); foreach (DataRow row in result.Rows) { tmp.Add(new LogItem() { ContractType = row["TipoContratto"].ToString(), FiscalCode = row["CodiceFiscale"].ToString(), Message = row["message"].ToString(), Status = row["process_status"].ToString(), ReportType = row["ReportType"].ToString(), Rete = row["Rete"].ToString(), Time = row["logged"].ToString() }); } tmp.Reverse(); t_log.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate () { foreach (LogItem item in tmp) { t_log.Items.Insert(0, item); } })); } } catch (Exception ex) { try { logger.Error(String.Format("Error occured during obtaining logs. Message: {0}", ex.Message)); } catch { } } int sleepMinutes = 1; string value = ConfigurationManager.AppSettings["loggingInterval"]; int.TryParse(value, out sleepMinutes); Thread.Sleep(sleepMinutes * 60 * 1000); } } private void PrepareStatistics() { try { using (DataAccessDE dataAccess = new DataAccessDE(DBProvider.SqlServerStampeC6)) { dataAccess.ExecuteNonQueryStoredProcedure(DBProvider.SqlServerStampeC6, ConfigurationManager.AppSettings["statisticsPrepare"], null); statisticsPrepared = true; } } catch (Exception ex) { try { logger.Error(ex.Message); } catch { } } } private void ObtainStatistics() { Thread.Sleep(15000); while (gestoreThread?.IsAlive == true) { GetStatistics(); int sleepMinutes = 60; string value = ConfigurationManager.AppSettings["statisticsUpdateInterval"]; int.TryParse(value, out sleepMinutes); Thread.Sleep(sleepMinutes * 60 * 1000); } GetStatistics(); } private string GetStatistics() { string result = string.Empty; int done = -1; int total = -1; try { if (statisticsPrepared) { using (DataAccessDE dataAccess = new DataAccessDE(DBProvider.SqlServerStampeC6)) { using (IDataReader reader = dataAccess.ExecuteDataReaderStoredProcedure(DBProvider.SqlServerStampeC6, ConfigurationManager.AppSettings["getStatistics"], null)) { int resultSetCount = 0; do { while (reader.Read()) { if (resultSetCount == 0) { int statoReport = int.Parse(reader.GetValue(0).ToString()); string rete = reader.GetValue(1).ToString(); int counter = int.Parse(reader.GetValue(2).ToString()); Application.Current.Dispatcher.BeginInvoke(new Action(() => { StatoReportCounterItem item = counterStorage.StatoReportCounters.Where(x => x.Rete == rete && x.StatoReport == statoReport).FirstOrDefault(); if (item != null) { item.Count = counter; } else { counterStorage.StatoReportCounters.Add(new StatoReportCounterItem() { StatoReport = statoReport, Rete = rete, Count = counter }); } })); } else { int elab = int.Parse(reader.GetValue(0).ToString()); string rete = reader.GetValue(1).ToString(); int counter = int.Parse(reader.GetValue(2).ToString()); switch (elab) { case 3: case 4: case 10: done += counter; total += counter; break; default: total += counter; break; } Application.Current.Dispatcher.BeginInvoke(new Action(() => { ElabCounterItem item = counterStorage.ElabCounters.Where(x => x.Rete == rete && x.Elab == elab).FirstOrDefault(); if (item != null) { item.Count = counter; } else { counterStorage.ElabCounters.Add(new ElabCounterItem() { Elab = elab, Rete = rete, Count = counter }); } })); } } resultSetCount++; } while (reader.NextResult()); } } if (done != -1 && total != -1) { statisticsProgressBar.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate () { statisticsProgressBar.Value = done; statisticsProgressBar.Maximum = total; })); progressBarPercentage.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate () { progressBarPercentage.Content = String.Format("{0}%", (int)(done * 100 / total)); })); } } } catch (Exception ex) { try { logger.Info(String.Format("Error occured during obtaining statistics. Message: {0}", ex.Message)); } catch { } } return String.Format("Reports generated: {0} / {1}", done, total); } private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { System.Diagnostics.Process.GetCurrentProcess().Kill(); Application.Current.Shutdown(); } private void t_PreviewTextInputInteger(object sender, TextCompositionEventArgs e) { e.Handled = !IsTextAllowed(e.Text); if (e.Handled) { return; } try { UpdateModel(sender, e.Text); } catch (Exception ex) { MessageBox.Show(ex.Message + ex.StackTrace); } } private void t_PreviewTextInputString(object sender, TextCompositionEventArgs e) { try { UpdateModel(); } catch (Exception ex) { MessageBox.Show(ex.Message + ex.StackTrace); } } private void TextBoxPasting(object sender, DataObjectPastingEventArgs e) { if (e.DataObject.GetDataPresent(typeof(String))) { String text = (String)e.DataObject.GetData(typeof(String)); if (!IsTextAllowed(text)) { e.CancelCommand(); } } else { e.CancelCommand(); } } private static bool IsTextAllowed(string text) { Regex regex = new Regex("[^0-9]+"); //regex that matches disallowed text return !regex.IsMatch(text); } private void ObserveProcesses() { while (true) { if (gestoreThread != null && gestoreThread.IsAlive) { SpinningCircle.Dispatcher.Invoke(new Action(() => { SpinningCircle.Visibility = Visibility.Visible; })); } else { SpinningCircle.Dispatcher.Invoke(new Action(() => { SpinningCircle.Visibility = Visibility.Hidden; })); } if (myZipManager != null && myZipManager.workingThread != null && myZipManager.workingThread.IsAlive) { SpinningCircleZip.Dispatcher.Invoke(new Action(() => { SpinningCircleZip.Visibility = Visibility.Visible; })); } else { SpinningCircleZip.Dispatcher.Invoke(new Action(() => { SpinningCircleZip.Visibility = Visibility.Hidden; })); button2.Dispatcher.Invoke(new Action(() => { button2.Content = "Start zipping"; })); } Thread.Sleep(1000); } } private void buttonSaveConfig_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(String.Format("All keys in both '{0}' and '{1}' config files will get overwritten with the data specified in fields in entire application. Are you sure you want to do this?", System.IO.Path.GetFileName(currentConfigFile), System.IO.Path.GetFileName(defaultConfigFile)), "Save config confirmation", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes) { UpdateModel(); model.SaveConfig(currentConfigFile); } } private void buttonLoadConfig_Click(object sender, RoutedEventArgs e) { if (MessageBox.Show(String.Format("Loaded file will additionally replace '{0}' file. Are you sure you want to do this?", System.IO.Path.GetFileName(defaultConfigFile)), "Loading confirmation", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes) { try { var ofd = new Microsoft.Win32.OpenFileDialog() { Filter = "config files (*.config)|*.config" }; var result = ofd.ShowDialog(); if (result == true) { var filePath = ofd.FileName; SetFieldsUsingConfig(filePath); setConfigFile(filePath); } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error while opening config file."); } } } private void setConfigFile(string filePath = null) { if (filePath == null) { currentConfigFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; } else { currentConfigFile = filePath; } ConfigPathLabel.Text = currentConfigFile; } } }