private void Dispose_Resources(bool disposing) { if (disposing) { if (frmLog != null) { frmLog.Close(); } if (_frmConsult != null) { _frmConsult.Close(); } if (_consult != null) { _consult.Disconnect(); } if (_emulator != null) { _emulator.Dispose(); } if (_bin != null) { _bin.Clear(); } if (_cfg != null) { _cfg.Save(); } if (_log != null) { _log.Close(); } } }
private void InitializeSettings() { //Логи _log = Log.Instance; _log.CatchExceptions = true; _log.LogLevel = debugFlag ? EventEntryType.Debug : EventEntryType.Event; _log.LogFileEnabled = true; //делегат перехвата событий Click на ToolStripMenuItems _EHmainMenu = new EventHandler(menu_Click); //Инициализация класса настроек приложения _cfg = new Settings(); //Если настройки дефолтовые, то возможно обновили версию. //вытащим настройки из предыдущей версии и сменим флаг if (_cfg.NeedUpgrade) { _cfg.Upgrade(); _cfg.NeedUpgrade = false; } //Проверим на валидность последние пути диалогов if (_cfg.cfgdlgADRPath == null || _cfg.cfgdlgADRPath.Length == 0 || !new DirectoryInfo(_cfg.cfgdlgADRPath).Exists ) { _cfg.cfgdlgADRPath = Environment.CurrentDirectory; } if (_cfg.cfgdlgROMPath == null || _cfg.cfgdlgROMPath.Length == 0 || !new DirectoryInfo(_cfg.cfgdlgROMPath).Exists ) { _cfg.cfgdlgROMPath = Environment.CurrentDirectory; } //список доступных интерфейсов диагностики (устройств) _consltDataList = new ListIndexString <IConsultData>() { new ConsultData(new DataEngine()), new ConsultData(new DataAT()), new ConsultData(new DataHICAS()), new ConsultData(new DataAirCon()), }; mnuConsultMode.DropDownItems.Clear(); //Добавляем список режимов диагностики в меню foreach (IConsultData i in _consltDataList) { string name = i.ToString(); ToolStripMenuItem mnu = new ToolStripMenuItem(); //mnu.Click -= new EventHandler(menu_Click); //mnu.Click += new EventHandler(mnuConsultMode_Click); mnu.Name = mnu.Text = name; mnuConsultMode.DropDownItems.Add(mnu); } //Выбираем первый пункт меню по умолчанию mnuConsultMode_Click( mnuConsultMode.DropDownItems[_consltDataList[0].ToString()], new EventArgs()); //класс работы через интерфейс consult _consult = new ConsultProvider(_consltDataList[0]); //Расчитаем коэффициент скорости если размеры шин заданы if (_cfg.cfgTyreOrigin != null && _cfg.cfgTyreCurrent != null) { ConversionFunctions.SpeedCorrectCoefficient = TyreParams.CalcK(_cfg.cfgTyreOrigin, _cfg.cfgTyreCurrent); } //Если стоит настройка на автоподключение - подключимся к консульту if (_cfg.cfgConsultConnectAtStartup) { menu_Click(mnuConsultConnect); } //создаем класс работы с ROM/ADR Файлами _bin = new From(); //подписываем функцию обновления интерфейса на событие смены источника данных класса _bin.DataSourceChanged += new From.FromEventHandler(InitFRomInterface); //InitInterface(_bin, null); //Откроем предыдущие файлы конфигурации если необходимо if (_cfg.cfgOpenLastConfig) { if (_cfg.cfgRecentAdrFiles.Count > 0 && File.Exists(_cfg.cfgRecentAdrFiles[0])) { try { _bin.OpenAddressFile(_cfg.cfgRecentAdrFiles[0]); } catch { } } if (_cfg.cfgRecentBinFiles.Count > 0 && File.Exists(_cfg.cfgRecentBinFiles[0])) { try { _bin.OpenROMFile(_cfg.cfgRecentBinFiles[0]); } catch { _bin.Clear(); } } } }
protected async Task GenerateTextContentExtractUsersAndUpdateSubject() { if (ctx == null || !ctx.HasValue) { return; } var nonNullContext = ctx.Value; try { var textContent = new StringBuilder(); if (Messagetype == MessageType.RichText_Html) { HtmlContent = Internal_Content; } else if (Messagetype == MessageType.ThreadActivity_AddMember || (Messagetype == MessageType.ThreadActivity_MemberJoined && Internal_Content.StartsWith("<addmember>")) // there seem to be (old?) addmember messages that come with the wrong message type of ThreadActivity_MemberJoined... handle this here ) { XmlDocument doc = new XmlDocument(); // need to force single XML values into array type since we know it also can be an array doc.LoadXml($"<root xmlns:json='http://james.newtonking.com/projects/json'>{Internal_Content.Replace("<target", "<target json:Array='true'").Replace("<detailedtargetinfo", "<detailedtargetinfo json:Array='true'") ?? ""}</root>"); var json = JsonConvert.SerializeXmlNode(doc); var data = JsonUtils.DeserializeObject <ThreadActivityAddMemberWrapper>(logger, json); await Task.WhenAll(data.root.addmember.detailedtargetinfo?.Select(targetInfo => teamsUserRegistry.RegisterDisplayNameForUserIdAsync(nonNullContext, (TeamsParticipant)targetInfo.id, targetInfo.friendlyName, OriginalArrivalTime)) ?? new List <Task>()); if (!string.IsNullOrWhiteSpace(data.root.addmember.initiator)) { await teamsUserRegistry.RegisterDisplayNameForUserIdAsync(nonNullContext, (TeamsParticipant)data.root.addmember.initiator, data.root.addmember.detailedinitiatorinfo?.friendlyName, OriginalArrivalTime); } // TODO: process alternate user display name var memberNames = await Task.WhenAll(data.root.addmember.target.Select(t => teamsUserRegistry.GetDisplayNameForUserIdAsync(nonNullContext, (TeamsParticipant)t))); MessageSubject = $"✈️ {await teamsUserRegistry.GetDisplayNameForUserIdAsync(nonNullContext, (TeamsParticipant)data.root.addmember.initiator)} added: " + string.Join(", ", memberNames); textContent.Append(MessageSubject); } else if (Messagetype == MessageType.ThreadActivity_DeleteMember) { XmlDocument doc = new XmlDocument(); doc.LoadXml($"<root xmlns:json='http://james.newtonking.com/projects/json'>{Internal_Content.Replace("<target", "<target json:Array='true'").Replace("<detailedtargetinfo", "<detailedtargetinfo json:Array='true'")}</root>"); var json = JsonConvert.SerializeXmlNode(doc); var data = JsonUtils.DeserializeObject <ThreadActivityDeleteMemberWrapper>(logger, json); await Task.WhenAll(data.root.deletemember.detailedtargetinfo?.Select(targetInfo => teamsUserRegistry.RegisterDisplayNameForUserIdAsync(nonNullContext, (TeamsParticipant)targetInfo.id, targetInfo.friendlyName, OriginalArrivalTime)) ?? new List <Task>()); if (!string.IsNullOrWhiteSpace(data.root.deletemember.initiator)) { await teamsUserRegistry.RegisterDisplayNameForUserIdAsync(nonNullContext, (TeamsParticipant)data.root.deletemember.initiator, data.root.deletemember.detailedinitiatorinfo?.friendlyName, OriginalArrivalTime); } var memberNames = await Task.WhenAll(data.root.deletemember.target.Select(t => teamsUserRegistry.GetDisplayNameForUserIdAsync(nonNullContext, (TeamsParticipant)t))); MessageSubject = $"✈️ {await teamsUserRegistry.GetDisplayNameForUserIdAsync(nonNullContext, new TeamsParticipant(data.root.deletemember?.initiator))} removed: " + string.Join(", ", memberNames); textContent.Append(MessageSubject); } else if (Messagetype == MessageType.Event_Call) { XmlDocument doc = new XmlDocument(); // prepare XML to JSON conversion; force "part" being a list which cannot be infered from XML if there is only one element doc.LoadXml($"<root xmlns:json='http://james.newtonking.com/projects/json'>{Internal_Content.Replace("<part ", "<part json:Array='true' ")}</root>"); var json = JsonConvert.SerializeXmlNode(doc); var data = JsonUtils.DeserializeObject <EventCallWrapper>(logger, json); await Task.WhenAll(data.root.partlist?.part?.Select(member => teamsUserRegistry.RegisterDisplayNameForUserIdAsync(nonNullContext, (TeamsParticipant)member.identity, member.displayName, OriginalArrivalTime)) ?? new List <Task>()); // sometimes p.name contains the user id and p.identity is empty var memberNames = await Task.WhenAll(data.root.partlist?.part?.Select(p => teamsUserRegistry.GetDisplayNameForUserIdAsync(nonNullContext, TeamsParticipant.FromFirstValid(p.identity, p.name))) ?? new List <Task <string> >()); var callEnded = Internal_Content.Contains("<ended/>"); if (callEnded) { MessageSubject = "☎️ Call ended for: " + string.Join(", ", memberNames); } else { var from = (TeamsParticipant)Internal_FromContactUrl; var displayName = await teamsUserRegistry.GetDisplayNameForUserIdAsync(nonNullContext, from); MessageSubject = $"☎️ Call started by {displayName}"; } textContent.Append(MessageSubject); } else if (Messagetype == MessageType.ThreadActivity_MemberJoined) { var data = JsonUtils.DeserializeObject <ThreadEventMemberJoined>(logger, Internal_Content); await Task.WhenAll(data.members.Select(member => teamsUserRegistry.RegisterDisplayNameForUserIdAsync(nonNullContext, (TeamsParticipant)member.id, member.friendlyname, OriginalArrivalTime))); var memberNames = (await Task.WhenAll(data.members.Select(member => teamsUserRegistry.GetDisplayNameForUserIdAsync(nonNullContext, (TeamsParticipant)member.id)))); MessageSubject = "✈️ Member(s) joined: " + string.Join(", ", memberNames); // note: friendlyname is sometimes empty; second note: für ehemalige Mitarbeiter kann ein ID-Lookup fehlschlagen, aber der friendlyName dennoch gesetzt sein textContent.Append(MessageSubject); } else if (Messagetype == MessageType.ThreadActivity_MemberLeft) { var data = JsonUtils.DeserializeObject <ThreadEventMemberLeft>(logger, Internal_Content); await Task.WhenAll(data.members.Select(member => teamsUserRegistry.RegisterDisplayNameForUserIdAsync(nonNullContext, (TeamsParticipant)member.id, member.friendlyname, OriginalArrivalTime))); var memberNames = await Task.WhenAll(data.members.Select(member => teamsUserRegistry.GetDisplayNameForUserIdAsync(nonNullContext, (TeamsParticipant)member.id))); MessageSubject = "✈️ Member(s) left: " + string.Join(", ", memberNames); textContent.Append(MessageSubject); } else if (Messagetype == MessageType.RichText_Media_CallRecording) { XmlDocument doc = new XmlDocument(); // prepare XML to JSON conversion; force "part" being a list which cannot be infered from XML if there is only one element doc.LoadXml($"<root xmlns:json='http://james.newtonking.com/projects/json'>{Internal_Content.Replace("<Identifiers>", "<Identifiers json:Array='true'>").Replace("<RecordingContent ", "<RecordingContent json:Array='true' ").Replace("<RequestedExports ", "<RequestedExports json:Array='true' ")}</root>"); var json = JsonConvert.SerializeXmlNode(doc); var data = JsonUtils.DeserializeObject <RichTextMedia_CallRecordingWrapper>(logger, json); MessageSubject = $"✍️ Recording started by {await teamsUserRegistry.GetDisplayNameForUserIdAsync(nonNullContext, new TeamsParticipant(data.root?.URIObject?.RecordingInitiatorId?.value))}"; textContent.Append(MessageSubject); } else if (Messagetype == MessageType.Text) { HtmlContent = Internal_Content; } else if (Messagetype == MessageType.ThreadActivity_TopicUpdate) { XmlDocument doc = new XmlDocument(); // <topicupdate><eventtime>0000000000000</eventtime><initiator>8:orgid:00000000-0000-beef-0000-000000000000</initiator><value>New topic</value></topicupdate> doc.LoadXml($"<root xmlns:json='http://james.newtonking.com/projects/json'>{Internal_Content}</root>"); var json = JsonConvert.SerializeXmlNode(doc); var data = JsonUtils.DeserializeObject <ThreadActivityTopicUpdateWrapper>(logger, json); var user = await teamsUserRegistry.GetUserByIdAsync(nonNullContext, (TeamsParticipant)data.root.topicupdate.initiator, false); if (user != null && user.HasDisplayName) { if (From.Count == 1 && (From[0].UserId.Kind == ParticipantKind.TeamsChat || From[0].UserId.Kind == ParticipantKind.Unknown)) { From.Clear(); From.Add(user); } } MessageSubject = $"®️ Topic set to '{data.root.topicupdate.value}' by {await teamsUserRegistry.GetDisplayNameForUserIdAsync(nonNullContext, new TeamsParticipant(data.root.topicupdate.initiator))}"; textContent.Append(MessageSubject); } else { textContent.Append("Unknown message type, don't know how to render: " + Messagetype); } if (string.IsNullOrWhiteSpace(HtmlContent)) { HtmlContent = MessageSubject; } TextContent = textContent.ToString(); } catch (Exception e) { // exceptions here will cancel the whole chat from being parsed; log the message content to analyze it later logger.Error(e, "[{TenantName}] Exception while processing message content in method {MethodName}; Original message content: {MessageContent}", nonNullContext.Tenant.TenantName, nameof(GenerateTextContentExtractUsersAndUpdateSubject), SerializeOriginalMessageAsJson()); // don't just skip a failed message, but cancel chat retrieval and fix the underlying issue, then try again throw; } }