public int CreateWorkItem(Dictionary <string, string> values, MessageAttachmentCollection attachments) { if (ThrowOnCreateBug != null) { throw ThrowOnCreateBug; } Logger.InfoFormat("Creating bug:"); // Generate a random ID int id; do { id = _rand.Next(1, int.MaxValue); } while (Bugs.ContainsKey(id)); // Apply defaults ApplyDefault(values, "ID", id.ToString()); ApplyDefault(values, "Title", $"WorkItem {id}"); ApplyDefault(values, "Assigned To", "Owner"); ApplyDefault(values, "State", "New"); Bugs[id] = new Dictionary <string, string>(values); CacheWorkItem(id); return(id); }
/// <summary> /// Take attachments from the current mail message and put them in a work item /// </summary> /// <param name="message"></param> private static MessageAttachmentCollection SaveAttachments(IIncomingEmailMessage message) { var result = new MessageAttachmentCollection(); foreach (var attachment in message.Attachments) { var filename = attachment.SaveAttachmentToFile(); if (filename != null) { result.Add(filename, attachment.ContentId); Logger.InfoFormat("Attachment saved to file {0}", filename); } } return(result); }
/// <param name="values">The list of fields and their desired values to apply to the work item</param> /// <param name="attachments"></param> /// <returns>Work item ID of the newly created work item</returns> public int CreateWorkItem(Dictionary <string, string> values, MessageAttachmentCollection attachments) { if (values == null) { throw new ArgumentNullException(nameof(values), "Must supply field values when creating new work item"); } //create a work item var workItemType = _tfsProject.WorkItemTypes[_config.TfsServerConfig.WorkItemTemplate]; var workItem = new WorkItem(workItemType); workItem.Open(); foreach (var key in values.Keys) { string value = values[key]; // Resolve current iteration if (_teamSettings != null && key == IterationPathFieldKey && value == CurrentIterationSpecialValue) { value = _teamSettings.CurrentIterationPath; } TryApplyFieldValue(workItem, key, value); } // Workaround for TFS issue - if you change the "Assigned To" field, and then you change the "Activated by" field, the "Assigned To" field reverts // to its original setting. To prevent that, we reapply the "Assigned To" field in case it's in the list of values to change. if (values.ContainsKey(AssignedToFieldKey)) { TryApplyFieldValue(workItem, AssignedToFieldKey, values[AssignedToFieldKey]); } foreach (var attachmentPath in attachments.LocalFilePaths) { workItem.Attachments.Add(new Attachment(attachmentPath)); } ValidateAndSaveWorkItem(workItem); CacheWorkItem(workItem); return(workItem.Id); }
public void ModifyWorkItem(int workItemId, string comment, bool commentIsHtml, Dictionary <string, string> values, MessageAttachmentCollection attachments) { if (ThrowOnModifyBug != null) { throw ThrowOnModifyBug; } if (!Bugs.ContainsKey(workItemId)) { Logger.WarnFormat("Trying to modify non-existing bug {0}. Initializing with no field values", workItemId); Bugs[workItemId] = new Dictionary <string, string>(); } var bugEntry = Bugs[workItemId]; foreach (var key in values.Keys) { bugEntry[key] = values[key]; } if (!bugEntry.ContainsKey(HistoryField)) { bugEntry[HistoryField] = ""; } bugEntry[HistoryField] += comment; }
private void InitWorkItemFields(IIncomingEmailMessage message, Dictionary <string, string> workItemUpdates, MessageAttachmentCollection attachments) { var resolver = new SpecialValueResolver(message, _workItemManager.GetNameResolver()); workItemUpdates["Title"] = resolver.Subject; var rawConversationIndex = message.ConversationId; workItemUpdates[_config.WorkItemSettings.ConversationIndexFieldName] = rawConversationIndex.Substring(0, Math.Min(rawConversationIndex.Length, TfsTextFieldMaxLength)); bool enableImgUpdating = _config.WorkItemSettings.EnableExperimentalHtmlFeatures; foreach (var defaultFieldValue in _config.WorkItemSettings.DefaultFieldValues) { var result = resolver.Resolve(defaultFieldValue.Value); if (enableImgUpdating && message.IsHtmlBody && defaultFieldValue.Value == SpecialValueResolver.RawMessageBodyKeyword) { result = EmailBodyProcessingUtils.UpdateEmbeddedImageLinks(result, attachments.Attachments); } workItemUpdates[defaultFieldValue.Field] = result; } }
/// <param name="workItemId">The ID of the work item to modify </param> /// <param name="comment">Comment to add to description</param> /// <param name="commentIsHtml"></param> /// <param name="values">List of fields to change</param> /// <param name="attachments"></param> public void ModifyWorkItem(int workItemId, string comment, bool commentIsHtml, Dictionary <string, string> values, MessageAttachmentCollection attachments) { if (workItemId <= 0) { return; } var workItem = _tfsStore.GetWorkItem(workItemId); workItem.Open(); if (commentIsHtml) { workItem.History = EmailBodyProcessingUtils.UpdateEmbeddedImageLinks(comment, attachments.Attachments); } else { workItem.History = comment.Replace("\n", "<br>"); } foreach (var key in values.Keys) { TryApplyFieldValue(workItem, key, values[key]); } if (attachments != null) { string GetAttachmentKey(string fileName, long length) { return($"{fileName}|{length}"); } var existingAttachments = new HashSet <string>(workItem.Attachments .OfType <Attachment>() .Select(attachment => GetAttachmentKey(attachment.Name, attachment.Length))); foreach (var attachment in attachments.Attachments) { var localFileInfo = new FileInfo(attachment.FilePath); string key = GetAttachmentKey(localFileInfo.Name, localFileInfo.Length); // If there's already an attachment with the same file name and size, don't bother re-uploading it // TODO: this may break embedded images for html replies since we update the img tag above to point to a local path we don't upload // However, we haven't confirmed this breaks and replying with an identical image is unlikely, so we ignore this for now if (!existingAttachments.Contains(key)) { workItem.Attachments.Add(new Attachment(attachment.FilePath)); } } } ValidateAndSaveWorkItem(workItem); workItem.Save(); }