From 2a98e13a2635e869f440c1db16470b6dfd8f3f95 Mon Sep 17 00:00:00 2001 From: stam Date: Wed, 13 Jan 2021 15:27:33 +0300 Subject: [PATCH] v1.0.0.1 --- src/AtlassianDownloader.csproj | 1 + src/AtlassianDownloader.sln | 25 ++++++++++ src/Program.cs | 87 +++++++++++++++++++++++---------- src/favicon.ico | Bin 0 -> 15086 bytes src/favicon.png | Bin 0 -> 1238 bytes 5 files changed, 86 insertions(+), 27 deletions(-) create mode 100644 src/AtlassianDownloader.sln create mode 100644 src/favicon.ico create mode 100644 src/favicon.png 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 0000000000000000000000000000000000000000..cb7476e4e77515a1d113a7a24d388401ef1597a3 GIT binary patch literal 15086 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 s@>!mIj?R literal 0 HcmV?d00001 diff --git a/src/favicon.png b/src/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..eab24e91432ac3dbf2398917ff34db74524c3f8e GIT binary patch literal 1238 zcmZ{kdsGs36vux&WGZP}D*`h>L$J~UaWWbC04#{qGCgxj<^xSjrPP^bB*)V77Vl~KpVV~+mZAG_z=`?>di&-c%Jt9Qrj@NoBX z2LO0*IqWzm$sf}d;jCXnKb&>~ejqYB5`eZ^q&>~WIpZ@panS%ABLW~k1%TDL5>Es0 zt<(5A6#%*vfVGDkI`=S~0wSHagYBd`DeOC!QXHRjxnY}Wy%Owd28R;aXaF_yNz#A@$S>NM2+v5i= zyzcRQyjL%Yxay8fK$jp&uE&=7p(>!kW(`6I`Aei}?PF%c%3iIvjkxCf1Z($dMJ&zA zkKGAv-b2#wm8n4AG48?$V?Jp_F}+lum!$S-dIL_urOkF|H$y3XS)(ifc}iNQ5oW@-=Y(TpyZP zjtQj&x^boNez<$rbNQ{T1%$7Kiz`qCkXib1dXOSBj%7F>5lraT&oUp?2zg-j^>awA z9J8@i!Vm@j+boVW5tMJ96{@N}3tq1Pa)DHAq zTbj#iFnKyvT_-hmh|JwrRO}i`i0(`hy?$paF8(TD1>9ttZ|4}=bqdPyzx$HivzbO2 zK~G9ZM!PD*EP~C9#?h2LRh&P9G%#N6VxS5 zBU6nvgV9S2WdmVKVZynpz@j*5YJTGkm^}STfnOVVqPZ7ijhKo zh3EpPHWl`a%;90868G&ST{ALQMp#s}V$_2~VX#@6V~zgt8~ksT7Tm6snLyGgf#FkLh;Y1}kczTDqdT^IQ>KyMz&GWWPM zw&#Y|dcX{j@fYy%>Yvc4W!NtjGl>Oh-678V_bZA@EE1#@WzsVWGMxZHW@Kjf!EnGE*!51!+SXo&W#< literal 0 HcmV?d00001