// Copyright (c) 2017 Informatikbüro Daniel Schick // using bsmd.database; using bsmd.email; using log4net; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.ServiceProcess; using System.Timers; namespace bsmd.ExcelReadService { public partial class ExcelReadService : ServiceBase { private Timer _timer; private object _timerlock = new object(); private bool processRunning = false; private ILog _log = LogManager.GetLogger(typeof(ExcelReadService)); public ExcelReadService() { Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory); InitializeComponent(); } protected override void OnStart(string[] args) { this.EventLog.Source = this.ServiceName; this.EventLog.Log = "Application"; this.Init(args); this.EventLog.WriteEntry("NSW Excel Read Service started.", EventLogEntryType.Information); System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly(); FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location); string version = fvi.FileVersion; _log.InfoFormat("Starting NSW Excel Read Service. v.{0} -------------- ", version); //Confirmation.InitDictionaries(); this.DoOnce(); } private void Init(string[] args) { this._timer = new Timer(); this._timer.Interval = Properties.Settings.Default.SleepSeconds * 1000; this._timer.Elapsed += _timer_Elapsed; this._timer.Enabled = true; } private void _timer_Elapsed(object sender, ElapsedEventArgs e) { lock (this._timerlock) { if (this.processRunning) return; else this.processRunning = true; } if (DBManager.Instance.Connect(Properties.Settings.Default.ConnectionString)) { try { string messageId = ""; string attachmentLocalPath = null; string mailSender = ""; string receiptSubject = "NSW Sheet Service Status INFO"; string mailSubject = ""; Dictionary reportingPartyDict = DBManager.Instance.GetReportingPartyDict(); using (BSMDPopClient bsmdPopClient = new BSMDPopClient()) { if(bsmdPopClient.IsConnected) { // --- BEGIN ------------ TEST /* ExcelReader er = new ExcelReader(@"E:\work\bsmd\nsw\Source\bsmd.ExcelReadService\2016_01_08_BMSD - EUNoAD Tool Rev 3.0_mit Testdaten.xls"); string amsg; MessageCore aCore; bool aReadResult = Util.ProcessSheet(er, out amsg, out aCore); er.Dispose(); */ // --- END --------------- TEST // check and download next e-Mail, saving attachment while (bsmdPopClient.ReceiveSingleMail(out attachmentLocalPath, out messageId, out mailSender, out mailSubject)) { bool readResult = false; string readMessage = ""; string receiptText = ""; MessageCore messageCore = null; if (attachmentLocalPath == null) { receiptText = "incoming E-Mail did not contain an Excel attachment!"; _log.WarnFormat(receiptText); } else { // only a valid sender gets a reply bool isValidSender = false; foreach (string aValidSender in Properties.Settings.Default.ValidSender) { if (mailSender.Equals(aValidSender, StringComparison.OrdinalIgnoreCase)) { isValidSender = true; break; } } if (!isValidSender) { receiptText = string.Format("ignored e - mail from illegal sender: {0}", mailSender); _log.Warn(receiptText); } else { // try to read/import attachment using (ExcelReader reader = new ExcelReader(attachmentLocalPath)) { try { ImportHeader importHeader = new ImportHeader(); importHeader.ImportDate = DateTime.Now; readResult = Util.ProcessSheet(reader, out readMessage, out messageCore); if(readResult) { // Saving plaintext data (ImportHeader + ImportValues) for each reading importHeader.MessageCoreId = messageCore.Id.Value; importHeader.Filename = Path.GetFileName(attachmentLocalPath); importHeader.SenderEmail = mailSender; bool foundReportingParty = false; foreach (Guid rpKey in reportingPartyDict.Keys) { if (reportingPartyDict[rpKey].UserEMail.IsNullOrEmpty()) continue; if (reportingPartyDict[rpKey].UserEMail.Equals(mailSender, StringComparison.OrdinalIgnoreCase)) { importHeader.ReportingPartyId = rpKey; foundReportingParty = true; break; } } if(!foundReportingParty) { _log.WarnFormat("Sender {0} is an unknown reporting party", mailSender); } DBManager.Instance.Save(importHeader); List valueList = importHeader.CreateUpdateList(reader.ImportValues); // Bulk save recommended here.. ImportValue.BulkSave(valueList); } } catch (Exception ex) { _log.Error(ex.ToString()); readMessage = string.Format("{0} Unerwartete Fehlersitutation:Bitte Info an Christin od. Daniel", ex.Message); } if (!readResult) { receiptText = string.Format("Incoming sheet could not be read: {0}", readMessage); _log.Error(receiptText); } if (readResult) { // Quittung / set messagecore to createreport and let reportGenerator create a reply? if (Properties.Settings.Default.SendConfirmationSheet) { List localConfirmationSheets = reader.SaveConfirmationSheets(attachmentLocalPath); // get the ship's name string shipname = DBManager.Instance.GetShipNameFromCore(messageCore); if (shipname.IsNullOrEmpty()) shipname = messageCore.IMO; if (mailSubject.IsNullOrEmpty()) mailSubject = string.Format("{0}: {1}", Properties.Settings.Default.SendEMailSubject, shipname); // send reply sheet back to sender BSMDMail.SendNSWReportWithAttachments(mailSubject, localConfirmationSheets, mailSender); } } } } // remove attachment _log.InfoFormat("removing local file {0}", attachmentLocalPath); if (!Properties.Settings.Default.TestMode) File.Delete(attachmentLocalPath); attachmentLocalPath = null; } if (receiptText.Length > 0) { _log.Debug("sending system info email"); BSMDMail.SendSystemInfo(receiptSubject, receiptText, mailSender); } // remove e-Mail _log.InfoFormat("deleting mail with messageId {0}", messageId); _log.InfoFormat("mail delete {0}", bsmdPopClient.DeleteMessageByMessageId(messageId) ? "successful" : "failed"); } } } #region Phase II - Excel Sheets auf Anforderung erzeugen List excelMessageCoreList = DBManager.Instance.GetMessageCoresForExcelCreate(); if(excelMessageCoreList.Count > 0) _log.InfoFormat("{0} excel sheets to create from database", excelMessageCoreList.Count); foreach(MessageCore excelCore in excelMessageCoreList) { // load messages List messages = DBManager.Instance.GetMessagesForCore(excelCore, DBManager.MessageLoad.ALL); // template } #endregion DBManager.Instance.Disconnect(); } catch (Exception ex) { _log.ErrorFormat("Exception occurred: {0}", ex.ToString()); } } else { _log.Error("DB Connection failure"); } // close any excel processes still running Process[] process = Process.GetProcessesByName("Excel"); foreach (Process p in process) { if (!string.IsNullOrEmpty(p.ProcessName)) { try { _log.InfoFormat("Killing process {0} {1}", p.ProcessName, p.Id); p.Kill(); } catch (Exception ex) { _log.WarnFormat("Error killing process {0} {1}: {2}", p.ProcessName, p.Id, ex.Message); } } } lock (this._timerlock) { this.processRunning = false; } } protected override void OnStop() { this._log.Info("Stopping NSW Excel Read Service."); } internal void DoOnce() { this._timer_Elapsed(null, null); } } }