BUG-1811: Improved the Jira destination "sub" icons, by showing the issue types.

This commit is contained in:
Robin 2016-08-18 11:46:38 +02:00
commit f88672b5f6
8 changed files with 423 additions and 54 deletions

View file

@ -22,6 +22,8 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
@ -31,15 +33,21 @@ using Greenshot.IniFile;
using GreenshotPlugin.Core;
namespace GreenshotJiraPlugin {
/// <summary>
/// This encapsulates the JiraApi to make it possible to change as less old Greenshot code as needed
/// </summary>
public class JiraConnector : IDisposable {
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(JiraConnector));
private static readonly JiraConfiguration Config = IniConfig.GetIniSection<JiraConfiguration>();
// Used to remove the wsdl information from the old SOAP Uri
public const string DefaultPostfix = "/rpc/soap/jirasoapservice-v2?wsdl";
private DateTime _loggedInTime = DateTime.Now;
private DateTimeOffset _loggedInTime = DateTimeOffset.MinValue;
private bool _loggedIn;
private readonly int _timeout;
private readonly object _lock = new object();
private string _url;
private JiraApi _jiraApi;
private IssueTypeBitmapCache _issueTypeBitmapCache;
public void Dispose() {
if (_jiraApi != null)
@ -51,7 +59,6 @@ namespace GreenshotJiraPlugin {
public JiraConnector() {
_url = Config.Url.Replace(DefaultPostfix, "");
_timeout = Config.Timeout;
_jiraApi = new JiraApi(new Uri(_url));
}
/// <summary>
@ -60,11 +67,18 @@ namespace GreenshotJiraPlugin {
/// <returns>true if login was done sucessfully</returns>
private async Task<bool> DoLogin(string user, string password)
{
if (_url.EndsWith("wsdl"))
lock (_lock)
{
_url = _url.Replace(DefaultPostfix, "");
// recreate the service with the new url
_jiraApi = new JiraApi(new Uri(_url));
if (_url.EndsWith("wsdl"))
{
_url = _url.Replace(DefaultPostfix, "");
}
if (_jiraApi == null)
{
// recreate the service with the new url
_jiraApi = new JiraApi(new Uri(_url));
_issueTypeBitmapCache = new IssueTypeBitmapCache(_jiraApi);
}
}
LoginInfo loginInfo;
@ -118,14 +132,22 @@ namespace GreenshotJiraPlugin {
}
/// <summary>
/// End the session, if there was one
/// </summary>
public async Task Logout() {
if (_jiraApi != null)
if (_jiraApi != null && _loggedIn)
{
await _jiraApi.EndSessionAsync();
_loggedIn = false;
}
}
/// <summary>
/// check the login credentials, to prevent timeouts of the session, or makes a login
/// Do not use ConfigureAwait to call this, as it will move await from the UI thread.
/// </summary>
/// <returns></returns>
private async Task CheckCredentials() {
if (_loggedIn) {
if (_loggedInTime.AddMinutes(_timeout-1).CompareTo(DateTime.Now) < 0) {
@ -137,32 +159,81 @@ namespace GreenshotJiraPlugin {
}
}
/// <summary>
/// Get the favourite filters
/// </summary>
/// <returns>List with filters</returns>
public async Task<IList<Filter>> GetFavoriteFiltersAsync()
{
await CheckCredentials();
return await _jiraApi.GetFavoriteFiltersAsync().ConfigureAwait(false);
}
/// <summary>
/// Get the issue for a key
/// </summary>
/// <param name="issueKey">Jira issue key</param>
/// <returns>Issue</returns>
public async Task<Issue> GetIssueAsync(string issueKey)
{
await CheckCredentials();
return await _jiraApi.GetIssueAsync(issueKey).ConfigureAwait(false);
}
public async Task<Attachment> AttachAsync<TContent>(string issueKey, TContent content, string filename, string contentType = null, CancellationToken cancellationToken = default(CancellationToken)) where TContent : class
/// <summary>
/// Attach the content to the jira
/// </summary>
/// <param name="issueKey"></param>
/// <param name="content">IBinaryContainer</param>
/// <param name="filename"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task AttachAsync(string issueKey, IBinaryContainer content, CancellationToken cancellationToken = default(CancellationToken))
{
await CheckCredentials().ConfigureAwait(false);
return await _jiraApi.AttachAsync(issueKey, content, filename, contentType, cancellationToken).ConfigureAwait(false);
await CheckCredentials();
using (var memoryStream = new MemoryStream())
{
content.WriteToStream(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
await _jiraApi.AttachAsync(issueKey, memoryStream, content.Filename, content.ContentType, cancellationToken).ConfigureAwait(false);
}
}
/// <summary>
/// Add a comment to the supplied issue
/// </summary>
/// <param name="issueKey">Jira issue key</param>
/// <param name="body">text</param>
/// <param name="visibility">the visibility role</param>
/// <param name="cancellationToken">CancellationToken</param>
public async Task AddCommentAsync(string issueKey, string body, string visibility = null, CancellationToken cancellationToken = default(CancellationToken))
{
await CheckCredentials();
await _jiraApi.AddCommentAsync(issueKey, body, visibility, cancellationToken).ConfigureAwait(false);
}
public async Task<SearchResult> SearchAsync(string jql, int maxResults = 20, IList<string> fields = null, CancellationToken cancellationToken = default(CancellationToken))
/// <summary>
/// Get the search results for the specified filter
/// </summary>
/// <param name="filter">Filter</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task<IList<Issue>> SearchAsync(Filter filter, CancellationToken cancellationToken = default(CancellationToken))
{
await CheckCredentials();
return await _jiraApi.SearchAsync(jql, maxResults, fields, cancellationToken).ConfigureAwait(false);
var searchResult = await _jiraApi.SearchAsync(filter.Jql, 20, new[] { "summary", "reporter", "assignee", "created" }, cancellationToken).ConfigureAwait(false);
return searchResult.Issues;
}
/// <summary>
/// Get the bitmap representing the issue type of an issue, from cache.
/// </summary>
/// <param name="issue">Issue</param>
/// <param name="cancellationToken">CancellationToken</param>
/// <returns>Bitmap</returns>
public async Task<Bitmap> GetIssueTypeBitmapAsync(Issue issue, CancellationToken cancellationToken = default(CancellationToken))
{
return await _issueTypeBitmapCache.GetOrCreateAsync(issue, cancellationToken).ConfigureAwait(false);
}
public Uri JiraBaseUri => _jiraApi.JiraBaseUri;