Skip to content

Commit

Permalink
Merge #3877 Support multiple download URLs per module
Browse files Browse the repository at this point in the history
  • Loading branch information
HebaruSan committed Aug 9, 2023
2 parents 1d88407 + 985292b commit ffcc534
Show file tree
Hide file tree
Showing 57 changed files with 2,011 additions and 435 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.

## v1.33.3

### Features

- [Multiple] Support multiple download URLs per module (#3877 by: HebaruSan; reviewed: techman83)

### Bugfixes

- [GUI] Updated Chinese translation to reduce misunderstandings (#3864 by: Fierce-Cat; reviewed: HebaruSan)
Expand Down
16 changes: 14 additions & 2 deletions CKAN.schema
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,20 @@
},
"download" : {
"description" : "URL where mod can be downloaded by tools",
"type" : "string",
"format" : "uri"
"oneOf" : [
{
"type" : "string",
"format" : "uri"
},
{
"type" : "array",
"items" : {
"type" : "string",
"format" : "uri"
},
"uniqueItems" : true
}
]
},
"download_size" : {
"description" : "The size of the download in bytes",
Expand Down
2 changes: 1 addition & 1 deletion Cmdline/Action/Show.cs
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ private int ShowMod(CkanModule module, ShowOptions opts)
if (!opts.without_files && !module.IsDLC)
{
// Compute the CKAN filename.
string file_uri_hash = NetFileCache.CreateURLHash(module.download);
string file_uri_hash = NetFileCache.CreateURLHash(module.download[0]);
string file_name = CkanModule.StandardName(module.identifier, module.version);

user.RaiseMessage("");
Expand Down
17 changes: 11 additions & 6 deletions ConsoleUI/ModInfoScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -512,11 +512,16 @@ private void addVersionBox(int l, int t, int r, int b, Func<string> title, Func<

private string HostedOn()
{
string dl = mod.download?.ToString() ?? "";
foreach (var kvp in hostDomains) {
if (dl.IndexOf(kvp.Key, StringComparison.CurrentCultureIgnoreCase) >= 0) {
return string.Format(Properties.Resources.ModInfoHostedOn, kvp.Value);
}
if (mod.download != null && mod.download.Count > 0)
{
var downloadHosts = mod.download
.Select(dlUri => dlUri.Host)
.Select(host =>
hostDomains.TryGetValue(host, out string name)
? name
: host);
return string.Format(Properties.Resources.ModInfoHostedOn,
string.Join(", ", downloadHosts));
}
if (mod.resources != null) {
if (mod.resources.bugtracker != null) {
Expand Down Expand Up @@ -550,7 +555,7 @@ private string HostedOn()
: Properties.Resources.ModInfoBuyFromKSPStoreOrSteamStore;
}
}
return mod.download?.Host ?? "";
return "";
}

private void Download(ConsoleTheme theme)
Expand Down
7 changes: 7 additions & 0 deletions Core/Configuration/IConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,12 @@ public interface IConfiguration
/// Paths that should be excluded from all installations
/// </summary>
string[] GlobalInstallFilters { get; set; }

/// <summary>
/// List of hosts in order of priority when there are multiple URLs to choose from.
/// The first null value represents where all other hosts should go.
/// </summary>
/// <value></value>
string[] PreferredHosts { get; set; }
}
}
34 changes: 26 additions & 8 deletions Core/Configuration/JsonConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;

using Newtonsoft.Json;

using CKAN.Games;

namespace CKAN.Configuration
Expand All @@ -23,20 +25,16 @@ private class Config
public IList<GameInstanceEntry> GameInstances { get; set; } = new List<GameInstanceEntry>();
public IDictionary<string, string> AuthTokens { get; set; } = new Dictionary<string, string>();
public string[] GlobalInstallFilters { get; set; } = new string[] { };
public string[] PreferredHosts { get; set; } = new string[] { };
}

public class ConfigConverter : JsonPropertyNamesChangedConverter
{
protected override Dictionary<string, string> mapping
{
get
=> new Dictionary<string, string>
{
return new Dictionary<string, string>
{
{ "KspInstances", "GameInstances" }
};
}
}
{ "KspInstances", "GameInstances" }
};
}

private class GameInstanceEntry
Expand Down Expand Up @@ -326,6 +324,26 @@ public string[] GlobalInstallFilters
}
}

public string[] PreferredHosts
{
get
{
lock (_lock)
{
return config.PreferredHosts;
}
}

set
{
lock (_lock)
{
config.PreferredHosts = value;
SaveConfig();
}
}
}

// <summary>
// Save the JSON configuration file.
// </summary>
Expand Down
5 changes: 5 additions & 0 deletions Core/Configuration/Win32RegistryConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,11 @@ public void SetAuthToken(string host, string token)
/// </summary>
public string[] GlobalInstallFilters { get; set; }

/// <summary>
/// Not implemented because the Windows registry is deprecated
/// </summary>
public string[] PreferredHosts { get; set; }

public static bool DoesRegistryConfigurationExist()
{
RegistryKey key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(CKAN_KEY_NO_PREFIX);
Expand Down
5 changes: 3 additions & 2 deletions Core/Converters/JsonSingleOrArrayConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
return token.ToObject<T>() == null ? null : new List<T> { token.ToObject<T>() };
}

public override bool CanWrite => false;
public override bool CanWrite => true;

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
var list = value as List<T>;
serializer.Serialize(writer, list?.Count == 1 ? list[0] : value);
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion Core/Exporters/DelimeterSeparatedValueExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public void Export(IRegistryQuerier registry, Stream stream)
QuoteIfNecessary(mod.Module.description),
QuoteIfNecessary(string.Join(";", mod.Module.author)),
QuoteIfNecessary(mod.Module.kind),
WriteUri(mod.Module.download),
WriteUri(mod.Module.download[0]),
mod.Module.download_size,
mod.Module.ksp_version,
mod.Module.ksp_version_min,
Expand Down
1 change: 0 additions & 1 deletion Core/GameInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,6 @@ public bool Scan()

return dllChanged || dlcChanged;
}
return false;
}

#endregion
Expand Down
1 change: 1 addition & 0 deletions Core/HelpURLs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public static class HelpURLs

public const string CloneFakeInstances = "https://github.com/KSP-CKAN/CKAN/pull/2627";
public const string DeleteDirectories = "https://github.com/KSP-CKAN/CKAN/pull/2962";
public const string PreferredHosts = "https://github.com/KSP-CKAN/CKAN/pull/3877";
public const string Filters = "https://github.com/KSP-CKAN/CKAN/pull/3458";
public const string Labels = "https://github.com/KSP-CKAN/CKAN/pull/2936";
public const string PlayTime = "https://github.com/KSP-CKAN/CKAN/pull/3543";
Expand Down
21 changes: 16 additions & 5 deletions Core/ModuleInstaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,11 @@ public static string Download(CkanModule module, string filename, NetModuleCache
{
log.Info("Downloading " + filename);

string tmp_file = Net.Download(module.download);
string tmp_file = Net.Download(module.download
.OrderBy(u => u,
new PreferredHostUriComparer(
ServiceLocator.Container.Resolve<IConfiguration>().PreferredHosts))
.First());

return cache.Store(module, tmp_file, new Progress<long>(bytes => {}), filename, true);
}
Expand Down Expand Up @@ -1051,14 +1055,14 @@ public void Upgrade(IEnumerable<CkanModule> modules, IDownloader netAsyncDownloa
{
User.RaiseMessage(Properties.Resources.ModuleInstallerUpgradeInstallingResuming,
module.name, module.version,
module.download.Host,
string.Join(", ", PrioritizedHosts(module.download)),
CkanModule.FmtSize(module.download_size - inProgressFile.Length));
}
else
{
User.RaiseMessage(Properties.Resources.ModuleInstallerUpgradeInstallingUncached,
module.name, module.version,
module.download.Host,
string.Join(", ", PrioritizedHosts(module.download)),
CkanModule.FmtSize(module.download_size));
}
}
Expand Down Expand Up @@ -1093,13 +1097,15 @@ public void Upgrade(IEnumerable<CkanModule> modules, IDownloader netAsyncDownloa
{
User.RaiseMessage(Properties.Resources.ModuleInstallerUpgradeUpgradingResuming,
module.name, installed.version, module.version,
module.download.Host, CkanModule.FmtSize(module.download_size - inProgressFile.Length));
string.Join(", ", PrioritizedHosts(module.download)),
CkanModule.FmtSize(module.download_size - inProgressFile.Length));
}
else
{
User.RaiseMessage(Properties.Resources.ModuleInstallerUpgradeUpgradingUncached,
module.name, installed.version, module.version,
module.download.Host, CkanModule.FmtSize(module.download_size));
string.Join(", ", PrioritizedHosts(module.download)),
CkanModule.FmtSize(module.download_size));
}
}
else
Expand Down Expand Up @@ -1227,6 +1233,11 @@ public void Replace(IEnumerable<ModuleReplacement> replacements, RelationshipRes

#endregion

public static IEnumerable<string> PrioritizedHosts(IEnumerable<Uri> urls)
=> urls.OrderBy(u => u, new PreferredHostUriComparer(ServiceLocator.Container.Resolve<IConfiguration>().PreferredHosts))
.Select(dl => dl.Host)
.Distinct();

/// <summary>
/// Makes sure all the specified mods are downloaded.
/// </summary>
Expand Down
7 changes: 3 additions & 4 deletions Core/Net/AutoUpdate.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Diagnostics;
using System.Net;
Expand Down Expand Up @@ -151,13 +152,11 @@ public void StartUpdateProcess(bool launchCKANAfterUpdate, IUser user = null)
new[]
{
new Net.DownloadTarget(
latestUpdate.UpdaterDownload,
null,
new List<Uri> { latestUpdate.UpdaterDownload },
updaterFilename,
latestUpdate.UpdaterSize),
new Net.DownloadTarget(
latestUpdate.ReleaseDownload,
null,
new List<Uri> { latestUpdate.ReleaseDownload },
ckanFilename,
latestUpdate.ReleaseSize),
},
Expand Down
18 changes: 8 additions & 10 deletions Core/Net/Net.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,18 +146,16 @@ public static string Download(string url, out string etag, string filename = nul

public class DownloadTarget
{
public Uri url { get; private set; }
public Uri fallbackUrl { get; private set; }
public string filename { get; private set; }
public long size { get; private set; }
public string mimeType { get; private set; }
public List<Uri> urls { get; private set; }
public string filename { get; private set; }
public long size { get; private set; }
public string mimeType { get; private set; }

public DownloadTarget(Uri url, Uri fallback = null, string filename = null, long size = 0, string mimeType = "")
public DownloadTarget(List<Uri> urls, string filename = null, long size = 0, string mimeType = "")
{
TxFileManager FileTransaction = new TxFileManager();

this.url = url;
this.fallbackUrl = fallback;
this.urls = urls;
this.filename = string.IsNullOrEmpty(filename)
? FileTransaction.GetTempFileName()
: filename;
Expand All @@ -174,7 +172,7 @@ public static string DownloadWithProgress(string url, string filename = null, IU
public static string DownloadWithProgress(Uri url, string filename = null, IUser user = null)
{
var targets = new[] {
new DownloadTarget(url, null, filename)
new DownloadTarget(new List<Uri> { url }, filename)
};
DownloadWithProgress(targets, user);
return targets.First().filename;
Expand All @@ -191,7 +189,7 @@ public static void DownloadWithProgress(ICollection<DownloadTarget> downloadTarg
}
else
{
File.Move(filename, downloadTargets.First(p => p.url == url).filename);
File.Move(filename, downloadTargets.First(p => p.urls.Contains(url)).filename);
}
};
downloader.DownloadAndWait(downloadTargets);
Expand Down
Loading

0 comments on commit ffcc534

Please sign in to comment.