diff --git a/src/AtlassianDownloader.csproj b/src/AtlassianDownloader.csproj index 2082704..b657bdb 100644 --- a/src/AtlassianDownloader.csproj +++ b/src/AtlassianDownloader.csproj @@ -3,6 +3,7 @@ Exe net5.0 + favicon.ico diff --git a/src/AtlassianDownloader.sln b/src/AtlassianDownloader.sln new file mode 100644 index 0000000..da0bb6a --- /dev/null +++ b/src/AtlassianDownloader.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30803.129 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtlassianDownloader", "AtlassianDownloader.csproj", "{9C7EA014-5883-4FCD-BF1D-DC561F8958DD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9C7EA014-5883-4FCD-BF1D-DC561F8958DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9C7EA014-5883-4FCD-BF1D-DC561F8958DD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9C7EA014-5883-4FCD-BF1D-DC561F8958DD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9C7EA014-5883-4FCD-BF1D-DC561F8958DD}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {6DE5A36D-883D-4DA1-9962-38FDD1EAD190} + EndGlobalSection +EndGlobal diff --git a/src/Program.cs b/src/Program.cs index 9b78609..dd5b590 100644 --- a/src/Program.cs +++ b/src/Program.cs @@ -4,43 +4,76 @@ using System.Linq; using System.Net.Http; using System.Text.Json; -var output = "output"; -var feedUrl = "https://my.atlassian.com/download/feeds/archived/jira.json"; - //https://my.atlassian.com/download/feeds/current/jira-software.json +var outputDir = "output"; +var feedUrls = + new[] { + "https://my.atlassian.com/download/feeds/archived/bamboo.json", + "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", + "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", + "https://my.atlassian.com/download/feeds/current/stash.json" + }; + + var client = new HttpClient(); -var atlassianJson = await client.GetStringAsync(feedUrl); -var callString = "downloads("; -var json = atlassianJson[callString.Length..^1]; -var parsed = JsonSerializer.Deserialize(json, new JsonSerializerOptions +foreach (var feedUrl in feedUrls) { - PropertyNamingPolicy = JsonNamingPolicy.CamelCase, -}); -var versions = parsed.GroupBy(a => a.Version).ToDictionary(a => a.Key, a => a.Select(b => b.ZipUrl).ToArray()); + var feedDir = Path.Combine(outputDir, feedUrl[(feedUrl.LastIndexOf('/') + 1)..(feedUrl.LastIndexOf('.'))]); + var atlassianJson = await client.GetStringAsync(feedUrl); + var callString = "downloads("; + var json = atlassianJson[callString.Length..^1]; + var parsed = JsonSerializer.Deserialize(json, new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + }); + var versions = parsed.GroupBy(a => a.Version).ToDictionary(a => a.Key, a => a.ToArray()); -foreach (var version in versions) -{ - var directory = Path.Combine(output, version.Key); - if (!Directory.Exists(directory)) + foreach (var version in versions) { - Directory.CreateDirectory(directory); - } - foreach (var link in version.Value) - { - var q = link.PathAndQuery; - var outputFile = Path.Combine(directory, q[(q.LastIndexOf("/") + 1)..]); - if (!File.Exists(outputFile)) + var directory = Path.Combine(feedDir, version.Key); + if (!Directory.Exists(directory)) { - using var file = File.OpenWrite(outputFile); - using var request = await client.GetStreamAsync(link).ConfigureAwait(false); - await request.CopyToAsync(file).ConfigureAwait(false); - Console.WriteLine($"Downloaded {link}"); + Directory.CreateDirectory(directory); } - else + foreach (var file in version.Value) { - Console.WriteLine($"File for {link} already exists"); + 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); + Console.WriteLine($"Downloaded {outputFile}"); + } + else + { + Console.WriteLine($"File for {file.ZipUrl} already exists"); + } } } + Console.WriteLine($"Downloaded all files from " + + $"{feedUrl}"); } Console.WriteLine("Download complete"); diff --git a/src/favicon.ico b/src/favicon.ico new file mode 100644 index 0000000..cb7476e Binary files /dev/null and b/src/favicon.ico differ diff --git a/src/favicon.png b/src/favicon.png new file mode 100644 index 0000000..eab24e9 Binary files /dev/null and b/src/favicon.png differ