2021-01-14 19:33:14 +03:00
|
|
|
|
using Microsoft.Extensions.Configuration;
|
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
|
using Microsoft.Extensions.Hosting;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using Serilog;
|
|
|
|
|
using System;
|
2021-01-13 15:24:10 +03:00
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Net.Http;
|
|
|
|
|
using System.Text.Json;
|
2021-01-14 19:33:14 +03:00
|
|
|
|
using System.Threading;
|
2021-01-14 18:05:38 +03:00
|
|
|
|
using System.Threading.Tasks;
|
2021-01-13 15:24:10 +03:00
|
|
|
|
|
2021-01-14 18:05:38 +03:00
|
|
|
|
namespace EpicMorg.Atlassian.Downloader {
|
2021-01-14 19:33:14 +03:00
|
|
|
|
class Program : IHostedService {
|
|
|
|
|
|
|
|
|
|
private readonly ILogger<Program> logger;
|
|
|
|
|
private readonly Arguments arguments;
|
|
|
|
|
|
|
|
|
|
public Program(ILogger<Program> logger,Arguments arguments) {
|
|
|
|
|
this.logger = logger;
|
|
|
|
|
this.arguments = arguments;
|
|
|
|
|
}
|
2021-01-14 18:46:07 +03:00
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
2021-01-16 13:25:29 +03:00
|
|
|
|
/// <param name="OutputDir">Override output directory to download.</param>
|
|
|
|
|
/// <param name="ListURL">Show all download links from feed(s) without downloading.</param>
|
|
|
|
|
/// <param name="ListVersions">Show all versions from feed(s) without downloading.</param>
|
|
|
|
|
/// <param name="ShowRawJson">Show raw json content from feed(s) downloading.</param>
|
2021-01-14 18:46:07 +03:00
|
|
|
|
/// <param name="customFeed">Override URIs to import.</param>
|
|
|
|
|
/// <returns></returns>
|
2021-01-16 13:25:29 +03:00
|
|
|
|
static async Task Main(string OutputDir = "atlassian", bool ListURL = false, bool ListVersions = false, Uri[] customFeed = null, bool ShowRawJson = false) => await
|
2021-01-14 19:33:14 +03:00
|
|
|
|
Host
|
|
|
|
|
.CreateDefaultBuilder()
|
|
|
|
|
.ConfigureHostConfiguration(configHost => configHost.AddEnvironmentVariables())
|
|
|
|
|
.ConfigureAppConfiguration((ctx, configuration) => {
|
|
|
|
|
configuration
|
|
|
|
|
.SetBasePath(Environment.CurrentDirectory)
|
|
|
|
|
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
|
|
|
|
|
.AddJsonFile($"appsettings.{ctx.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true)
|
|
|
|
|
.AddEnvironmentVariables();
|
|
|
|
|
})
|
|
|
|
|
.ConfigureServices((ctx, services) => {
|
2021-01-14 20:00:27 +03:00
|
|
|
|
|
2021-01-14 19:33:14 +03:00
|
|
|
|
services
|
|
|
|
|
.AddOptions()
|
|
|
|
|
.AddLogging(builder => {
|
2021-01-14 20:00:27 +03:00
|
|
|
|
builder.ClearProviders();
|
2021-01-14 19:33:14 +03:00
|
|
|
|
Log.Logger = new LoggerConfiguration()
|
|
|
|
|
.ReadFrom.Configuration(ctx.Configuration)
|
|
|
|
|
.CreateLogger();
|
|
|
|
|
builder.AddSerilog(dispose: true);
|
|
|
|
|
});
|
|
|
|
|
services.AddHostedService<Program>();
|
2021-01-16 13:25:29 +03:00
|
|
|
|
services.AddSingleton(new Arguments(OutputDir, ListURL, ListVersions, customFeed, ShowRawJson));
|
2021-01-14 19:33:14 +03:00
|
|
|
|
})
|
|
|
|
|
.RunConsoleAsync();
|
|
|
|
|
|
2021-01-16 13:25:29 +03:00
|
|
|
|
public record Arguments(string OutputDir = "atlassian", bool ListURL = false, bool ListVersions = false, Uri[] CustomFeed = null, bool ShowRawJson = false);
|
2021-01-14 19:33:14 +03:00
|
|
|
|
|
|
|
|
|
public async Task StartAsync(CancellationToken cancellationToken) {
|
|
|
|
|
|
2021-01-14 18:05:38 +03:00
|
|
|
|
var appTitle = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
|
|
|
|
|
var appVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
|
|
|
|
|
var appStartupDate = DateTime.Now;
|
|
|
|
|
var appBuildType = "[Release]";
|
2021-01-13 16:28:36 +03:00
|
|
|
|
#if DEBUG
|
2021-01-14 18:05:38 +03:00
|
|
|
|
appBuildType = "[Debug]";
|
2021-01-13 16:28:36 +03:00
|
|
|
|
#endif
|
2021-01-14 19:33:14 +03:00
|
|
|
|
|
2021-01-16 13:25:29 +03:00
|
|
|
|
var feedUrls = arguments.CustomFeed != null
|
|
|
|
|
? arguments.CustomFeed.Select(a => a.ToString()).ToArray()
|
2021-01-14 18:46:07 +03:00
|
|
|
|
: new[] {
|
2021-01-13 15:27:33 +03:00
|
|
|
|
"https://my.atlassian.com/download/feeds/archived/bamboo.json",
|
2021-01-15 00:47:53 +03:00
|
|
|
|
"https://my.atlassian.com/download/feeds/archived/clover.json",
|
2021-01-13 15:27:33 +03:00
|
|
|
|
"https://my.atlassian.com/download/feeds/archived/confluence.json",
|
|
|
|
|
"https://my.atlassian.com/download/feeds/archived/crowd.json",
|
|
|
|
|
"https://my.atlassian.com/download/feeds/archived/crucible.json",
|
|
|
|
|
"https://my.atlassian.com/download/feeds/archived/fisheye.json",
|
|
|
|
|
"https://my.atlassian.com/download/feeds/archived/jira-core.json",
|
|
|
|
|
"https://my.atlassian.com/download/feeds/archived/jira-servicedesk.json",
|
|
|
|
|
"https://my.atlassian.com/download/feeds/archived/jira-software.json",
|
|
|
|
|
"https://my.atlassian.com/download/feeds/archived/jira.json",
|
|
|
|
|
"https://my.atlassian.com/download/feeds/archived/stash.json",
|
|
|
|
|
|
|
|
|
|
"https://my.atlassian.com/download/feeds/current/bamboo.json",
|
2021-01-15 00:47:53 +03:00
|
|
|
|
"https://my.atlassian.com/download/feeds/current/clover.json",
|
2021-01-13 15:27:33 +03:00
|
|
|
|
"https://my.atlassian.com/download/feeds/current/confluence.json",
|
|
|
|
|
"https://my.atlassian.com/download/feeds/current/crowd.json",
|
|
|
|
|
"https://my.atlassian.com/download/feeds/current/crucible.json",
|
|
|
|
|
"https://my.atlassian.com/download/feeds/current/fisheye.json",
|
|
|
|
|
"https://my.atlassian.com/download/feeds/current/jira-core.json",
|
|
|
|
|
"https://my.atlassian.com/download/feeds/current/jira-servicedesk.json",
|
|
|
|
|
"https://my.atlassian.com/download/feeds/current/jira-software.json",
|
2021-01-14 16:21:25 +03:00
|
|
|
|
"https://my.atlassian.com/download/feeds/current/stash.json",
|
2021-01-13 15:27:33 +03:00
|
|
|
|
|
2021-01-14 18:05:38 +03:00
|
|
|
|
"https://my.atlassian.com/download/feeds/eap/bamboo.json",
|
|
|
|
|
"https://my.atlassian.com/download/feeds/eap/confluence.json",
|
|
|
|
|
"https://my.atlassian.com/download/feeds/eap/jira.json",
|
2021-01-15 00:47:53 +03:00
|
|
|
|
"https://my.atlassian.com/download/feeds/eap/jira-servicedesk.json",
|
|
|
|
|
"https://my.atlassian.com/download/feeds/eap/stash.json"
|
2021-01-14 18:05:38 +03:00
|
|
|
|
};
|
2021-01-13 15:24:10 +03:00
|
|
|
|
|
2021-01-14 18:05:38 +03:00
|
|
|
|
Console.Title = $"{appTitle} {appVersion} {appBuildType}";
|
2021-01-14 20:00:27 +03:00
|
|
|
|
logger.LogTrace($"Task started at {appStartupDate}.");
|
2021-01-13 15:27:33 +03:00
|
|
|
|
|
2021-01-14 18:05:38 +03:00
|
|
|
|
var client = new HttpClient();
|
2021-01-14 18:46:07 +03:00
|
|
|
|
|
2021-01-14 18:05:38 +03:00
|
|
|
|
foreach (var feedUrl in feedUrls) {
|
2021-01-16 13:25:29 +03:00
|
|
|
|
var feedDir = Path.Combine(arguments.OutputDir, feedUrl[(feedUrl.LastIndexOf('/') + 1)..(feedUrl.LastIndexOf('.'))]);
|
2021-01-14 18:05:38 +03:00
|
|
|
|
var atlassianJson = await client.GetStringAsync(feedUrl);
|
|
|
|
|
var callString = "downloads(";
|
|
|
|
|
var json = atlassianJson[callString.Length..^1];
|
|
|
|
|
var parsed = JsonSerializer.Deserialize<ResponseArray[]>(json, new JsonSerializerOptions {
|
|
|
|
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
|
|
|
|
});
|
2021-01-14 18:46:07 +03:00
|
|
|
|
var versionsProg = parsed.GroupBy(a => a.Version).ToDictionary(a => a.Key, a => a.ToArray());
|
2021-01-16 13:25:29 +03:00
|
|
|
|
if (arguments.ShowRawJson)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Not released yet.");
|
|
|
|
|
return;
|
|
|
|
|
//foreach (var versionProg in versionsProg)
|
|
|
|
|
//{
|
|
|
|
|
// foreach (var file in versionProg.Value)
|
|
|
|
|
// {
|
|
|
|
|
//
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
}
|
|
|
|
|
else if (arguments.ListVersions)
|
|
|
|
|
{
|
|
|
|
|
foreach (var versionProg in versionsProg)
|
|
|
|
|
{
|
|
|
|
|
foreach (var file in versionProg.Value)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine(file.Version);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (arguments.ListURL) {
|
2021-01-14 18:46:07 +03:00
|
|
|
|
foreach (var versionProg in versionsProg) {
|
|
|
|
|
foreach (var file in versionProg.Value) {
|
|
|
|
|
Console.WriteLine(file.ZipUrl);
|
|
|
|
|
}
|
2021-01-14 18:05:38 +03:00
|
|
|
|
}
|
2021-01-14 18:46:07 +03:00
|
|
|
|
} else {
|
2021-01-14 19:33:14 +03:00
|
|
|
|
logger.LogInformation($"Download from JSON \"{feedUrl}\" started at {appStartupDate}.");
|
2021-01-14 18:46:07 +03:00
|
|
|
|
foreach (var versionProg in versionsProg) {
|
|
|
|
|
var directory = Path.Combine(feedDir, versionProg.Key);
|
|
|
|
|
if (!Directory.Exists(directory)) {
|
|
|
|
|
Directory.CreateDirectory(directory);
|
|
|
|
|
}
|
|
|
|
|
foreach (var file in versionProg.Value) {
|
|
|
|
|
if (file.ZipUrl == null) { continue; }
|
|
|
|
|
var serverPath = file.ZipUrl.PathAndQuery;
|
|
|
|
|
var outputFile = Path.Combine(directory, serverPath[(serverPath.LastIndexOf("/") + 1)..]);
|
|
|
|
|
if (!File.Exists(outputFile)) {
|
|
|
|
|
if (!string.IsNullOrEmpty(file.Md5)) {
|
|
|
|
|
File.WriteAllText(outputFile + ".md5", file.Md5);
|
|
|
|
|
}
|
|
|
|
|
using var outputStream = File.OpenWrite(outputFile);
|
|
|
|
|
using var request = await client.GetStreamAsync(file.ZipUrl).ConfigureAwait(false);
|
|
|
|
|
await request.CopyToAsync(outputStream).ConfigureAwait(false);
|
2021-01-14 19:33:14 +03:00
|
|
|
|
//Console.ForegroundColor = ConsoleColor.Green;
|
|
|
|
|
logger.LogInformation($"File \"{file.ZipUrl}\" successfully downloaded to \"{outputFile}\".");
|
|
|
|
|
// Console.ResetColor();
|
2021-01-14 18:46:07 +03:00
|
|
|
|
} else {
|
2021-01-14 19:33:14 +03:00
|
|
|
|
// Console.ForegroundColor = ConsoleColor.Yellow;
|
|
|
|
|
logger.LogWarning($"File \"{outputFile}\" already exists. Download from \"{file.ZipUrl}\" skipped.");
|
|
|
|
|
// Console.ResetColor();
|
2021-01-14 18:05:38 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-14 20:00:27 +03:00
|
|
|
|
logger.LogTrace($"All files from \"{feedUrl}\" successfully downloaded.");
|
2021-01-13 15:27:33 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-14 18:46:07 +03:00
|
|
|
|
|
2021-01-14 20:00:27 +03:00
|
|
|
|
logger.LogTrace($"Download complete at {appStartupDate}.");
|
2021-01-14 19:33:14 +03:00
|
|
|
|
}
|
|
|
|
|
|
2021-01-14 18:46:07 +03:00
|
|
|
|
|
2021-01-14 19:33:14 +03:00
|
|
|
|
public Task StopAsync(CancellationToken cancellationToken) {
|
|
|
|
|
throw new NotImplementedException();
|
2021-01-13 15:24:10 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-14 18:05:38 +03:00
|
|
|
|
public partial class ResponseArray {
|
|
|
|
|
public string Description { get; set; }
|
|
|
|
|
public string Edition { get; set; }
|
|
|
|
|
public Uri ZipUrl { get; set; }
|
|
|
|
|
public object TarUrl { get; set; }
|
|
|
|
|
public string Md5 { get; set; }
|
|
|
|
|
public string Size { get; set; }
|
|
|
|
|
public string Released { get; set; }
|
|
|
|
|
public string Type { get; set; }
|
|
|
|
|
public string Platform { get; set; }
|
|
|
|
|
public string Version { get; set; }
|
|
|
|
|
public Uri ReleaseNotes { get; set; }
|
|
|
|
|
public Uri UpgradeNotes { get; set; }
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-13 15:24:10 +03:00
|
|
|
|
}
|