Немного desktop чудес и async

This commit is contained in:
Alex Tri
2019-03-14 12:20:01 +03:00
parent 1c2cee082e
commit 0b93b88118
5 changed files with 145 additions and 124 deletions
+1 -2
View File
@@ -22,10 +22,9 @@ namespace JiraTimeBotForm.JiraIntegration
public string GetTaskName(string branch) public string GetTaskName(string branch)
{ {
Issue issue = null;
try try
{ {
issue = _jira.Issues.Queryable.FirstOrDefault(f => f.Key == branch); var issue = _jira.Issues.Queryable.FirstOrDefault(f => f.Key == branch);
return issue?.Summary; return issue?.Summary;
} }
catch (Exception) catch (Exception)
@@ -1,11 +1,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading;
using JiraTimeBotForm.Configuration; using JiraTimeBotForm.Configuration;
namespace JiraTimeBotForm.TaskTime namespace JiraTimeBotForm.TaskTime
{ {
public interface ITaskTimeDiscoverer public interface ITaskTimeDiscoverer
{ {
List<TaskTimeItem> GetTaskTimes(Settings settings, DateTime? date = null); List<TaskTimeItem> GetTaskTimes(Settings settings, DateTime? date = null, CancellationToken cancellationToken = default(CancellationToken));
} }
} }
+23 -14
View File
@@ -2,7 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Windows.Forms; using System.Threading;
using JiraTimeBotForm.Configuration; using JiraTimeBotForm.Configuration;
using Mercurial; using Mercurial;
@@ -17,28 +17,37 @@ namespace JiraTimeBotForm.TaskTime
_log = log; _log = log;
} }
public List<TaskTimeItem> GetTaskTimes(Settings settings, DateTime? date = null) public List<TaskTimeItem> GetTaskTimes(Settings settings, DateTime? date = null, CancellationToken cancellationToken = default(CancellationToken))
{ {
if (date == null) var workTimeItems = new List<TaskTimeItem>();
{
date = DateTime.Now.Date; date = date.GetValueOrDefault(DateTime.Now.Date);
}
date = date.Value.Date; var workTasks = new List<string>();
List<string> workTasks = new List<string>();
foreach (var repoDirectory in Directory.GetDirectories(settings.RepositoryPath)) foreach (var repoDirectory in Directory.GetDirectories(settings.RepositoryPath))
{ {
cancellationToken.ThrowIfCancellationRequested();
//var project = new DirectoryInfo(repoDirectory).Name; //var project = new DirectoryInfo(repoDirectory).Name;
if (!Directory.Exists(Path.Combine(repoDirectory, ".hg"))) if (!Directory.Exists(Path.Combine(repoDirectory, ".hg")))
{ {
continue; continue;
} }
Application.DoEvents();
var repo = new Repository(repoDirectory); var repo = new Repository(repoDirectory);
var log = repo.Log(new LogCommand {Date = date, Users = { settings.MercurialAuthorEmail } }); var logCommand = new LogCommand
{
Date = date,
Users = { settings.MercurialAuthorEmail }
};
var log = repo.Log(logCommand);
foreach (var changeset in log) foreach (var changeset in log)
{ {
cancellationToken.ThrowIfCancellationRequested();
if (!changeset.Branch.Contains("-")) if (!changeset.Branch.Contains("-"))
{ {
continue; continue;
@@ -51,23 +60,23 @@ namespace JiraTimeBotForm.TaskTime
workTasks.Add(changeset.Branch); workTasks.Add(changeset.Branch);
_log?.Trace($" - Найден changeset: {changeset.Timestamp} - {changeset.Branch} - {changeset.AuthorEmailAddress}"); _log?.Trace($" - Найден changeset: {changeset.Timestamp} - {changeset.Branch} - {changeset.AuthorEmailAddress}");
Application.DoEvents();
} }
} }
//Нам нужно раскидать 480 минут в день. //Нам нужно раскидать 480 минут в день.
var workTimeItems = new List<TaskTimeItem>();
foreach (var taskGroup in workTasks.GroupBy(f => f)) foreach (var taskGroup in workTasks.GroupBy(f => f))
{ {
var minutesPerTime = settings.MinuterPerWorkDay / workTasks.Count; var minutesPerTime = settings.MinuterPerWorkDay / workTasks.Count;
var minutesForCurrentTaskGroup = minutesPerTime * taskGroup.Count(); var minutesForCurrentTaskGroup = minutesPerTime * taskGroup.Count();
workTimeItems.Add(new TaskTimeItem var taskTimeItem = new TaskTimeItem
{ {
Branch = taskGroup.Key, Branch = taskGroup.Key,
Time = TimeSpan.FromMinutes(minutesForCurrentTaskGroup), Time = TimeSpan.FromMinutes(minutesForCurrentTaskGroup),
Commits = taskGroup.Count(), Commits = taskGroup.Count(),
}); };
workTimeItems.Add(taskTimeItem);
} }
return workTimeItems; return workTimeItems;
+18 -3
View File
@@ -47,6 +47,7 @@
this.tmrStart = new System.Windows.Forms.Timer(this.components); this.tmrStart = new System.Windows.Forms.Timer(this.components);
this.txtDummyMode = new System.Windows.Forms.CheckBox(); this.txtDummyMode = new System.Windows.Forms.CheckBox();
this.btnMeeting = new System.Windows.Forms.Button(); this.btnMeeting = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.SuspendLayout(); this.SuspendLayout();
// //
// actTime // actTime
@@ -147,13 +148,14 @@
this.txtLog.Location = new System.Drawing.Point(218, 16); this.txtLog.Location = new System.Drawing.Point(218, 16);
this.txtLog.Multiline = true; this.txtLog.Multiline = true;
this.txtLog.Name = "txtLog"; this.txtLog.Name = "txtLog";
this.txtLog.ReadOnly = true;
this.txtLog.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; this.txtLog.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this.txtLog.Size = new System.Drawing.Size(510, 264); this.txtLog.Size = new System.Drawing.Size(510, 264);
this.txtLog.TabIndex = 11; this.txtLog.TabIndex = 11;
// //
// btnStart // btnStart
// //
this.btnStart.Location = new System.Drawing.Point(34, 257); this.btnStart.Location = new System.Drawing.Point(34, 224);
this.btnStart.Name = "btnStart"; this.btnStart.Name = "btnStart";
this.btnStart.Size = new System.Drawing.Size(103, 23); this.btnStart.Size = new System.Drawing.Size(103, 23);
this.btnStart.TabIndex = 12; this.btnStart.TabIndex = 12;
@@ -175,7 +177,7 @@
// txtDummyMode // txtDummyMode
// //
this.txtDummyMode.AutoSize = true; this.txtDummyMode.AutoSize = true;
this.txtDummyMode.Location = new System.Drawing.Point(31, 234); this.txtDummyMode.Location = new System.Drawing.Point(31, 201);
this.txtDummyMode.Name = "txtDummyMode"; this.txtDummyMode.Name = "txtDummyMode";
this.txtDummyMode.Size = new System.Drawing.Size(114, 17); this.txtDummyMode.Size = new System.Drawing.Size(114, 17);
this.txtDummyMode.TabIndex = 13; this.txtDummyMode.TabIndex = 13;
@@ -184,7 +186,7 @@
// //
// btnMeeting // btnMeeting
// //
this.btnMeeting.Location = new System.Drawing.Point(160, 257); this.btnMeeting.Location = new System.Drawing.Point(160, 224);
this.btnMeeting.Name = "btnMeeting"; this.btnMeeting.Name = "btnMeeting";
this.btnMeeting.Size = new System.Drawing.Size(52, 23); this.btnMeeting.Size = new System.Drawing.Size(52, 23);
this.btnMeeting.TabIndex = 14; this.btnMeeting.TabIndex = 14;
@@ -192,11 +194,23 @@
this.btnMeeting.UseVisualStyleBackColor = true; this.btnMeeting.UseVisualStyleBackColor = true;
this.btnMeeting.Click += new System.EventHandler(this.btnMeeting_Click); this.btnMeeting.Click += new System.EventHandler(this.btnMeeting_Click);
// //
// btnCancel
//
this.btnCancel.Enabled = false;
this.btnCancel.Location = new System.Drawing.Point(34, 256);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(178, 23);
this.btnCancel.TabIndex = 15;
this.btnCancel.Text = "Cancel operation";
this.btnCancel.UseVisualStyleBackColor = true;
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// frmMain // frmMain
// //
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(740, 292); this.ClientSize = new System.Drawing.Size(740, 292);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.btnMeeting); this.Controls.Add(this.btnMeeting);
this.Controls.Add(this.txtDummyMode); this.Controls.Add(this.txtDummyMode);
this.Controls.Add(this.btnStart); this.Controls.Add(this.btnStart);
@@ -243,6 +257,7 @@
private System.Windows.Forms.Timer tmrStart; private System.Windows.Forms.Timer tmrStart;
private System.Windows.Forms.CheckBox txtDummyMode; private System.Windows.Forms.CheckBox txtDummyMode;
private System.Windows.Forms.Button btnMeeting; private System.Windows.Forms.Button btnMeeting;
private System.Windows.Forms.Button btnCancel;
} }
} }
+99 -102
View File
@@ -1,10 +1,15 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using JiraTimeBotForm.Configuration; using JiraTimeBotForm.Configuration;
using JiraTimeBotForm.JiraIntegration; using JiraTimeBotForm.JiraIntegration;
using JiraTimeBotForm.Passwords; using JiraTimeBotForm.Passwords;
using JiraTimeBotForm.TasksProcessors;
using JiraTimeBotForm.TaskTime; using JiraTimeBotForm.TaskTime;
using Newtonsoft.Json; using Newtonsoft.Json;
@@ -19,6 +24,21 @@ namespace JiraTimeBotForm
private readonly ILog _log; private readonly ILog _log;
private readonly NotifyIcon trayIcon; private readonly NotifyIcon trayIcon;
private readonly ContextMenu trayMenu; private readonly ContextMenu trayMenu;
private Job _job;
private readonly IReadOnlyList<Control> _controls;
private CancellationTokenSource _tokenSource;
private CancellationTokenSource GetTokenSource()
{
var tokenSource = new CancellationTokenSource();
tokenSource.Token.Register(() =>
{
_log.Info("Îïåðàöèÿ îòìåíåíà...");
LockUnlock(true);
});
return tokenSource;
}
public frmMain() public frmMain()
{ {
@@ -37,6 +57,10 @@ namespace JiraTimeBotForm
trayIcon.Click += btnTray_Click; trayIcon.Click += btnTray_Click;
trayIcon.DoubleClick += btnTray_Click; trayIcon.DoubleClick += btnTray_Click;
trayIcon.Visible = false; trayIcon.Visible = false;
_job = new Job(_log);
_controls = new Control[] { txtJiraLogin, txtJiraPassword, txtMercurialEmail, actTime, txtRepoPath, txtDummyMode, btnSave, btnStart, btnMeeting };
} }
private void frmMain_FormClosing(object sender, FormClosingEventArgs e) private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
@@ -57,7 +81,7 @@ namespace JiraTimeBotForm
Extensions.Extensions.Restore(this); Extensions.Extensions.Restore(this);
} }
private void btnSave_Click(object sender, EventArgs e) public Settings ReadSettingsAndLock()
{ {
var settings = new Settings var settings = new Settings
{ {
@@ -65,10 +89,31 @@ namespace JiraTimeBotForm
JiraPassword = txtJiraPassword.Text, JiraPassword = txtJiraPassword.Text,
MercurialAuthorEmail = txtMercurialEmail.Text, MercurialAuthorEmail = txtMercurialEmail.Text,
ActivationTime = TimeSpan.Parse(actTime.Text), ActivationTime = TimeSpan.Parse(actTime.Text),
RepositoryPath = txtRepoPath.Text RepositoryPath = txtRepoPath.Text,
DummyMode = txtDummyMode.Checked
}; };
LockUnlock(false);
return settings;
}
public void LockUnlock(bool enabled)
{
foreach (var control in _controls)
{
control.Enabled = enabled;
}
btnCancel.Enabled = !enabled;
tmrStart.Enabled = enabled;
}
private void btnSave_Click(object sender, EventArgs e)
{
var settings = ReadSettingsAndLock();
LockUnlock(true);
var password = new EncryptionClass().Encrypt(settings.JiraUserName, settings.JiraPassword, settings.JiraUrl); var password = new EncryptionClass().Encrypt(settings.JiraUserName, settings.JiraPassword, settings.JiraUrl);
settings.JiraPassword = password; settings.JiraPassword = password;
@@ -99,11 +144,25 @@ namespace JiraTimeBotForm
txtMercurialEmail.Text = settings.MercurialAuthorEmail; txtMercurialEmail.Text = settings.MercurialAuthorEmail;
txtRepoPath.Text = settings.RepositoryPath; txtRepoPath.Text = settings.RepositoryPath;
actTime.Text = settings.ActivationTime.ToString("hh\\:mm\\:ss"); actTime.Text = settings.ActivationTime.ToString("hh\\:mm\\:ss");
txtDummyMode.Checked = settings.DummyMode;
} }
private void btnStart_Click(object sender, EventArgs e) private async void btnStart_Click(object sender, EventArgs e)
{ {
DoTheJob(); var settings = ReadSettingsAndLock();
if (!Directory.Exists(settings.RepositoryPath))
{
MessageBox.Show("Ïàïêà ñ ðåïî íå ñóøåñòâóåò.", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
using (_tokenSource = GetTokenSource())
{
await _job.DoTheJob(settings, new WorkLogTasksProcessor(_log), _tokenSource.Token);
}
LockUnlock(true);
} }
private void frmMain_Resize(object sender, EventArgs e) private void frmMain_Resize(object sender, EventArgs e)
@@ -120,127 +179,65 @@ namespace JiraTimeBotForm
} }
} }
private void tmrStart_Tick(object sender, EventArgs e) private async void tmrStart_Tick(object sender, EventArgs e)
{ {
var runTime = TimeSpan.Parse(actTime.Text); var runTime = TimeSpan.Parse(actTime.Text);
if (Math.Abs((DateTime.Now.TimeOfDay - runTime).TotalSeconds) < 1) if (Math.Abs((DateTime.Now.TimeOfDay - runTime).TotalSeconds) < 1)
{ {
if (DateTime.Now.DayOfWeek == DayOfWeek.Saturday || DateTime.Now.DayOfWeek == DayOfWeek.Sunday) if (DateTime.Now.DayOfWeek == DayOfWeek.Saturday || DateTime.Now.DayOfWeek == DayOfWeek.Sunday)
{ {
_log.Error("сегодня суббота или воскресенье. Работать нельзя =)"); _log.Error("Ñåãîäíÿ ñóááîòà èëè âîñêðåñåíüå. Ðàáîòàòü íåëüçÿ =)");
return; return;
} }
txtDummyMode.Checked = false; _log.Info("Àâòîìàòè÷åñêîå âíåñåíèå âðåìåíè.");
DoTheJob();
var settings = ReadSettingsAndLock();
await Task.Delay(2000);
if (settings.DummyMode)
{
settings.DummyMode = false;
_log.Info("Âûêëþ÷àåì ðåæèì Òåñòîâîãî ïðîãîíà");
}
using (var tokenSource = GetTokenSource())
{
await _job.DoTheJob(settings, new WorkLogTasksProcessor(_log), tokenSource.Token);
}
LockUnlock(true);
} }
} }
private void DoTheJob() private async void btnMeeting_Click(object sender, EventArgs e)
{ {
if (!Directory.Exists(txtRepoPath.Text)) var settings = ReadSettingsAndLock();
if (!Directory.Exists(settings.RepositoryPath))
{ {
MessageBox.Show("Папка с репо не сушествует.", "", MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBox.Show("Ïàïêà ñ ðåïî íå ñóøåñòâóåò.", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
return; return;
} }
txtLog.Text = ""; using (_tokenSource = GetTokenSource())
var settings = new Settings
{ {
JiraUserName = txtJiraLogin.Text, await _job.DoTheJob(settings, new MeetingProcessor(_log), _tokenSource.Token);
JiraPassword = txtJiraPassword.Text,
MercurialAuthorEmail = txtMercurialEmail.Text,
ActivationTime = TimeSpan.Parse(actTime.Text),
RepositoryPath = txtRepoPath.Text
};
var jira = new JiraApi(settings, _log);
var taskDiscoverer = new TaskTimeDiscoverer(_log);
int daysDiff = 0;
while (true)
{
var date = DateTime.Now.Date.AddDays(daysDiff);
var taskTimes = taskDiscoverer.GetTaskTimes(settings, date);
if (!taskTimes.Any())
{
_log.Warn($"{date:dd.MM.yyyy} вы не сделали ничего полезного =) Использую предыдущий день.");
daysDiff--;
if (daysDiff < -7)
{
_log.Error("Не нашли ни одного коммита за предыдущие 7 дней. Возможно вы в отпуске? Выхожу.");
return;
}
continue;
}
_log.Trace($"На реальную дату {date:dd.MM.yyyy} распределение по задачам:");
foreach (var taskTime in taskTimes)
{
_log.Trace($"- {taskTime.Branch} (коммитов {taskTime.Commits}): {taskTime.Time}");
}
jira.SetTodayWorklog(taskTimes, dummy: txtDummyMode.Checked);
_log.Info("Готово.");
return;
}
}
private void btnMeeting_Click(object sender, EventArgs e)
{
if (!Directory.Exists(txtRepoPath.Text))
{
MessageBox.Show("Папка с репо не сушествует.", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
txtLog.Text = "";
var settings = new Settings
{
JiraUserName = txtJiraLogin.Text,
JiraPassword = txtJiraPassword.Text,
MercurialAuthorEmail = txtMercurialEmail.Text,
ActivationTime = TimeSpan.Parse(actTime.Text),
RepositoryPath = txtRepoPath.Text
};
var jira = new JiraApi(settings, _log);
var taskDiscoverer = new TaskTimeDiscoverer();
int daysDiff = -1;
while (true)
{
var date = DateTime.Now.Date.AddDays(daysDiff);
var taskTimes = taskDiscoverer.GetTaskTimes(settings, date);
if (!taskTimes.Any())
{
_log.Warn($"{date:dd.MM.yyyy} вы не сделали ничего полезного =) Использую предыдущий день.");
daysDiff--;
if (daysDiff < -7)
{
_log.Error("Не нашли ни одного коммита за предыдущие 7 дней. Возможно вы в отпуске? Выхожу.");
return;
}
continue;
}
_log.Trace($"На реальную дату {date:dd.MM.yyyy} распределение по задачам:");
foreach (var taskTime in taskTimes.OrderByDescending(f=>f.Time))
{
var taskName = jira.GetTaskName(taskTime.Branch);
_log.Trace($"- {taskTime.Branch}: {taskName} - {taskTime.Time}");
}
break;
} }
LockUnlock(true);
} }
private void label2_Click(object sender, EventArgs e) private void label2_Click(object sender, EventArgs e)
{ {
} }
private void btnCancel_Click(object sender, EventArgs e)
{
_tokenSource.Cancel();
}
} }
} }