Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Installation message usability improvements #3989

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
41 changes: 22 additions & 19 deletions Cmdline/ConsoleUser.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Linq;
using System.Text.RegularExpressions;
using log4net;

namespace CKAN.CmdLine
Expand Down Expand Up @@ -255,27 +254,31 @@ public void RaiseError(string message, params object[] args)
/// <param name="percent">Progress in percent</param>
public void RaiseProgress(string message, int percent)
{
if (Regex.IsMatch(message, Properties.Resources.UserProgressDownloadSubstring, RegexOptions.IgnoreCase))
{
// In headless mode, only print a new message if the percent has changed,
// to reduce clutter in Jenkins for large downloads
if (!Headless || percent != previousPercent)
{
// The \r at the front here causes download messages to *overwrite* each other.
Console.Write("\r{0} - {1}% ", message, percent);
previousPercent = percent;
}
}
else
// The percent looks weird on non-download messages.
// The leading newline makes sure we don't end up with a mess from previous
// download messages.
GoToStartOfLine();
Console.Write("{0}", message);

// This message leaves the cursor at the end of a line of text
atStartOfLine = false;
}

public void RaiseProgress(int percent, long bytesPerSecond, long bytesLeft)
{
if (!Headless || percent != previousPercent)
{
// The percent looks weird on non-download messages.
// The leading newline makes sure we don't end up with a mess from previous
// download messages.
GoToStartOfLine();
Console.Write("{0}", message);
var fullMsg = string.Format(CKAN.Properties.Resources.NetAsyncDownloaderProgress,
CkanModule.FmtSize(bytesPerSecond),
CkanModule.FmtSize(bytesLeft));
// The \r at the front here causes download messages to *overwrite* each other.
Console.Write("\r{0} - {1}% ", fullMsg, percent);
previousPercent = percent;

// This message leaves the cursor at the end of a line of text
atStartOfLine = false;
}
// These messages leave the cursor at the end of a line of text
atStartOfLine = false;
}

/// <summary>
Expand Down
15 changes: 15 additions & 0 deletions ConsoleUI/Toolkit/ConsoleScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,21 @@ public void RaiseProgress(string message, int percent)
Draw(userTheme);
}

/// <summary>
/// Update a user visible progress bar
/// </summary>
/// <param name="percent">Value 0-100 representing the progress</param>
/// <param name="bytesPerSecond">Current download rate</param>
/// <param name="bytesLeft">Bytes remaining in the downloads</param>
public void RaiseProgress(int percent, long bytesPerSecond, long bytesLeft)
{
var fullMsg = string.Format(CKAN.Properties.Resources.NetAsyncDownloaderProgress,
CkanModule.FmtSize(bytesPerSecond),
CkanModule.FmtSize(bytesLeft));
Progress(fullMsg, percent);
Draw(userTheme);
}

/// <summary>
/// Forward a RaiseProgress request to child classes
/// </summary>
Expand Down
10 changes: 6 additions & 4 deletions Core/ModuleInstaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -700,10 +700,12 @@ internal static string CopyZipEntry(ZipFile zipfile, ZipEntry entry, string full
foreach (string mod in goners)
{
int percent_complete = (step++ * 100) / goners.Count;
User.RaiseProgress(
string.Format(Properties.Resources.ModuleInstallerRemovingMod, mod),
percent_complete);
Uninstall(mod, ref possibleConfigOnlyDirs, registry_manager.registry);
var registry = registry_manager.registry;
User.RaiseProgress(string.Format(Properties.Resources.ModuleInstallerRemovingMod,
registry.InstalledModule(mod)?.Module.ToString()
?? mod),
percent_complete);
Uninstall(mod, ref possibleConfigOnlyDirs, registry);
}

// Enforce consistency if we're not installing anything,
Expand Down
12 changes: 5 additions & 7 deletions Core/Net/NetAsyncDownloader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -346,10 +346,12 @@ private void DownloadModule(NetAsyncDownloaderDownloadPart dl)
/// true to queue, false to start immediately
/// </returns>
private bool shouldQueue(Uri url)
=> !url.IsFile
=> !url.IsFile && url.IsAbsoluteUri
// Ignore inactive downloads
&& downloads.Except(queuedDownloads)
.Any(dl => (!dl.CurrentUri.IsAbsoluteUri || dl.CurrentUri.Host == url.Host)
.Any(dl => dl.CurrentUri != url
// Look for active downloads from the same host
&& (dl.CurrentUri.IsAbsoluteUri && dl.CurrentUri.Host == url.Host)
// Consider done if no bytes left
&& dl.bytesLeft > 0
// Consider done if already tried and failed
Expand Down Expand Up @@ -422,11 +424,7 @@ private void FileProgressReport(int index, long bytesDownloaded, long bytesToDow
}

int totalPercentage = (int)(((totalSize - totalBytesLeft) * 100) / (totalSize));
User.RaiseProgress(
string.Format(Properties.Resources.NetAsyncDownloaderProgress,
CkanModule.FmtSize(totalBytesPerSecond),
CkanModule.FmtSize(totalBytesLeft)),
totalPercentage);
User.RaiseProgress(totalPercentage, totalBytesPerSecond, totalBytesLeft);
}

private void PopFromQueue(string host)
Expand Down
5 changes: 3 additions & 2 deletions Core/Net/NetAsyncModulesDownloader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,9 @@ private void ModuleDownloadComplete(Uri url, string filename, Exception error, s
CkanModule module = null;
try
{
module = modules.First(m => m.download?.Any(dlUri => dlUri == url)
?? false);
module = modules.First(m => (m.download?.Any(dlUri => dlUri == url)
?? false)
|| m.InternetArchiveDownload == url);
User.RaiseMessage(Properties.Resources.NetAsyncDownloaderValidating, module);
cache.Store(module, filename,
new Progress<long>(percent => StoreProgress?.Invoke(module, 100 - percent, 100)),
Expand Down
8 changes: 4 additions & 4 deletions Core/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@
<data name="NetDownloading" xml:space="preserve"><value>Downloading {0}</value></data>
<data name="NetMissingCertFailed" xml:space="preserve"><value>Failed downloading {0}</value></data>
<data name="NetInvalidLocation" xml:space="preserve"><value>Invalid URL in Location header: {0}</value></data>
<data name="NetAsyncDownloaderDownloading" xml:space="preserve"><value>Downloading "{0}"</value></data>
<data name="NetAsyncDownloaderDownloading" xml:space="preserve"><value>Downloading {0} ...</value></data>
<data name="NetAsyncDownloaderCancelled" xml:space="preserve"><value>Download cancelled by user</value></data>
<data name="NetAsyncDownloaderProgress" xml:space="preserve"><value>{0}/sec - downloading - {1} left</value><comment>Should contain UserProgressDownloadSubstring from CmdLine</comment></data>
<data name="NetAsyncDownloaderProgress" xml:space="preserve"><value>{0}/sec - downloading - {1} left</value></data>
<data name="NetAsyncDownloaderTryingFallback" xml:space="preserve"><value>Failed to download "{0}", trying fallback "{1}"</value></data>
<data name="NetAsyncDownloaderValidating" xml:space="preserve"><value>Finished downloading {0}, validating and storing to cache...</value></data>
<data name="NetFileCacheCannotFind" xml:space="preserve"><value>Cannot find cache directory: {0}</value></data>
Expand Down Expand Up @@ -209,11 +209,11 @@ Install the `mono-complete` package or equivalent for your operating system.</va
<data name="GameInstanceNoValidName" xml:space="preserve"><value>Could not return a valid name for the new instance</value></data>
<data name="GameInstanceByPathName" xml:space="preserve"><value>custom</value></data>
<data name="GameInstancePathNotFound" xml:space="preserve"><value>{0} does not exist</value></data>
<data name="ModuleInstallerDownloading" xml:space="preserve"><value>Downloading "{0}"</value></data>
<data name="ModuleInstallerDownloading" xml:space="preserve"><value>Downloading {0} ...</value></data>
<data name="ModuleInstallerNothingToInstall" xml:space="preserve"><value>Nothing to install</value></data>
<data name="ModuleInstallerAboutToInstall" xml:space="preserve"><value>About to install:</value></data>
<data name="ModuleInstallerUserDeclined" xml:space="preserve"><value>User declined install list</value></data>
<data name="ModuleInstallerInstallingMod" xml:space="preserve"><value>Installing mod "{0}"</value></data>
<data name="ModuleInstallerInstallingMod" xml:space="preserve"><value>Installing {0}...</value></data>
<data name="ModuleInstallerUpdatingRegistry" xml:space="preserve"><value>Updating registry</value></data>
<data name="ModuleInstallerCommitting" xml:space="preserve"><value>Committing filesystem changes</value></data>
<data name="ModuleInstallerRescanning" xml:space="preserve"><value>Rescanning {0}</value></data>
Expand Down
7 changes: 4 additions & 3 deletions Core/Registry/Registry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1305,10 +1305,11 @@ public IEnumerable<string> GetAllHosts()
=> repoDataMgr.GetAllAvailableModules(repositories.Values)
// Pick all latest modules where download is not null
// Merge all the URLs into one sequence
.SelectMany(availMod => availMod?.Latest()?.download
?? Enumerable.Empty<Uri>())
.SelectMany(availMod => (availMod?.Latest()?.download
?? Enumerable.Empty<Uri>())
.Append(availMod?.Latest()?.InternetArchiveDownload))
// Skip relative URLs because they don't have hosts
.Where(dlUri => dlUri.IsAbsoluteUri)
.Where(dlUri => dlUri?.IsAbsoluteUri ?? false)
// Group the URLs by host
.GroupBy(dlUri => dlUri.Host)
// Put most commonly used hosts first
Expand Down
1 change: 0 additions & 1 deletion Core/Repositories/RepositoryDataManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ public enum UpdateResult
targets.Select(t => new FileInfo(t.filename).Length));
foreach ((Repository repo, Net.DownloadTarget target) in toUpdate.Zip(targets))
{
user.RaiseMessage(Properties.Resources.NetRepoLoadingModulesFromRepo, repo.name);
var file = target.filename;
msg = string.Format(Properties.Resources.NetRepoLoadingModulesFromRepo,
repo.name);
Expand Down
5 changes: 5 additions & 0 deletions Core/User.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public interface IUser
void RaiseError(string message, params object[] args);

void RaiseProgress(string message, int percent);
void RaiseProgress(int percent, long bytesPerSecond, long bytesLeft);
void RaiseMessage(string message, params object[] args);
}

Expand Down Expand Up @@ -59,6 +60,10 @@ public void RaiseProgress(string message, int percent)
{
}

public void RaiseProgress(int percent, long bytesPerSecond, long bytesLeft)
{
}

public void RaiseMessage(string message, params object[] args)
{
}
Expand Down
4 changes: 3 additions & 1 deletion GUI/Controls/EditModSearch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ public void ExpandCollapse()
/// </summary>
public event Action SurrenderFocus;

public event Action<string> ShowError;

public ModSearch Search
{
get => currentSearch;
Expand Down Expand Up @@ -141,7 +143,7 @@ private void ImmediateHandler(object sender, EventArgs e)
}
catch (Kraken k)
{
Main.Instance?.AddStatusMessage(k.Message);
ShowError?.Invoke(k.Message);
}
}

Expand Down
2 changes: 2 additions & 0 deletions GUI/Controls/EditModSearches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public EditModSearches()

public event Action SurrenderFocus;
public event Action<List<ModSearch>> ApplySearches;
public event Action<string> ShowError;

public void Clear()
{
Expand Down Expand Up @@ -113,6 +114,7 @@ private EditModSearch AddSearch()
};
ctl.ApplySearch += EditModSearch_ApplySearch;
ctl.SurrenderFocus += EditModSearch_SurrenderFocus;
ctl.ShowError += error => ShowError?.Invoke(error);

editors.Add(ctl);
Controls.Add(ctl);
Expand Down
1 change: 1 addition & 0 deletions GUI/Controls/ManageMods.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.