Feature #39: added --user-agent flag

This commit is contained in:
STAM 2023-10-13 01:46:09 +03:00
parent 4f59498482
commit b96d87ca33
Signed by: stam
GPG Key ID: 4F57E51F9C45F8CD
5 changed files with 29 additions and 10 deletions

View File

@ -58,9 +58,14 @@ Options:
--custom-feed <custom-feed> Override URIs to import []
--action <Download|ListURLs|ListVersions|ShowRawJson> Action to perform [default: Download]
--about Show credits banner [default: False]
--product-version <product-version> Override target version to download some product. Advice: Use it with "customFeed". []
--product-version <product-version> Override target version to download some product. Advice: Use
it with "customFeed". []
--skip-file-check Skip compare of file sizes if a local file already exists.
Existing file will be skipped to check and redownload. [default: False]
Existing file will be skipped to check and redownload.
[default: False]
--user-agent <user-agent> Set custom user agent via this feature flag. [default:
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:101.0)
Gecko/20100101 Firefox/101.0]
--version Show version information
-?, -h, --help Show help and usage information
```

View File

@ -16,18 +16,17 @@ using System.Threading.Tasks;
internal class DownloaderService : IHostedService
{
private readonly string UserAgentString = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:101.0) Gecko/20100101 Firefox/101.0";
private readonly ILogger<DownloaderService> logger;
private readonly DownloaderOptions options;
private readonly HttpClient client;
private readonly IHostApplicationLifetime hostApplicationLifetime;
public DownloaderService(IHostApplicationLifetime hostApplicationLifetime, ILogger<DownloaderService> logger, HttpClient client, DownloaderOptions options)
{
this.logger = logger;
this.client = client;
client.DefaultRequestHeaders.Add("User-Agent", this.UserAgentString);
client.DefaultRequestHeaders.Add("User-Agent", options.UserAgent);
this.options = options;
this.hostApplicationLifetime = hostApplicationLifetime;
}
@ -92,7 +91,7 @@ internal class DownloaderService : IHostedService
{
var atlassianJson = await this.client.GetStringAsync(feedUrl, cancellationToken).ConfigureAwait(false);
var json = atlassianJson.Trim()["downloads(".Length..^1];
this.logger.LogTrace("Downloaded json: {0}", json);
this.logger.LogTrace($"Downloaded json: {0}", json);
var parsed = JsonSerializer.Deserialize<ResponseItem[]>(json, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
@ -160,7 +159,7 @@ internal class DownloaderService : IHostedService
try
{
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("User-Agent", this.UserAgentString);
httpClient.DefaultRequestHeaders.Add("User-Agent", options.UserAgent);
var response = await httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, file.ZipUrl));
if (response.IsSuccessStatusCode)
{
@ -238,7 +237,9 @@ internal class DownloaderService : IHostedService
this.logger.LogInformation($"File \"{file.ZipUrl}\" successfully downloaded to \"{outputFile}\".");
}
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
public async Task StopAsync(CancellationToken cancellationToken) { }
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
}

12
src/GlobalSuppressions.cs Normal file
View File

@ -0,0 +1,12 @@
// This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given
// a specific target and scoped to a namespace, type, member, etc.
using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("Usage", "CA2254:Template should be a static expression", Justification = "<Pending>", Scope = "member", Target = "~M:EpicMorg.Atlassian.Downloader.Core.DownloaderService.GetJson(System.String,System.String,System.Threading.CancellationToken)~System.Threading.Tasks.Task{System.ValueTuple{System.String,System.Collections.Generic.IDictionary{System.String,EpicMorg.Atlassian.Downloader.ResponseItem[]}}}")]
[assembly: SuppressMessage("Performance", "CA1869:Cache and reuse 'JsonSerializerOptions' instances", Justification = "<Pending>", Scope = "member", Target = "~M:EpicMorg.Atlassian.Downloader.Core.DownloaderService.GetJson(System.String,System.String,System.Threading.CancellationToken)~System.Threading.Tasks.Task{System.ValueTuple{System.String,System.Collections.Generic.IDictionary{System.String,EpicMorg.Atlassian.Downloader.ResponseItem[]}}}")]
[assembly: SuppressMessage("Usage", "CA2254:Template should be a static expression", Justification = "<Pending>", Scope = "member", Target = "~M:EpicMorg.Atlassian.Downloader.Core.DownloaderService.DownloadFilesFromFeed(System.String,System.Collections.Generic.IDictionary{System.String,EpicMorg.Atlassian.Downloader.ResponseItem[]},System.Threading.CancellationToken)~System.Threading.Tasks.Task")]
[assembly: SuppressMessage("Reliability", "CA2016:Forward the 'CancellationToken' parameter to methods", Justification = "<Pending>", Scope = "member", Target = "~M:EpicMorg.Atlassian.Downloader.Core.DownloaderService.DownloadFilesFromFeed(System.String,System.Collections.Generic.IDictionary{System.String,EpicMorg.Atlassian.Downloader.ResponseItem[]},System.Threading.CancellationToken)~System.Threading.Tasks.Task")]
[assembly: SuppressMessage("Usage", "CA2254:Template should be a static expression", Justification = "<Pending>", Scope = "member", Target = "~M:EpicMorg.Atlassian.Downloader.Core.DownloaderService.DownloadFile(EpicMorg.Atlassian.Downloader.ResponseItem,System.String,System.Threading.CancellationToken)~System.Threading.Tasks.Task")]

View File

@ -1,4 +1,4 @@
namespace EpicMorg.Atlassian.Downloader;
using System;
public record DownloaderOptions(string OutputDir, Uri[] CustomFeed, DownloadAction Action, bool Version, string ProductVersion, bool SkipFileCheck) { }
public record DownloaderOptions(string OutputDir, Uri[] CustomFeed, DownloadAction Action, bool Version, string ProductVersion, bool SkipFileCheck, string UserAgent) { }

View File

@ -23,7 +23,8 @@ public class Program
/// <param name="about">Show credits banner</param>
/// <param name="productVersion">Override target version to download some product. Advice: Use it with "customFeed".</param>
/// <param name="skipFileCheck">Skip compare of file sizes if a local file already exists. Existing file will be skipped to check and redownload.</param>
static async Task Main(string outputDir, Uri[] customFeed = null, DownloadAction action = DownloadAction.Download, bool about = false, string productVersion = null, bool skipFileCheck = false) => await
/// <param name="userAgent">Set custom user agent via this feature flag.</param>
static async Task Main(string outputDir, Uri[] customFeed = null, DownloadAction action = DownloadAction.Download, bool about = false, string productVersion = null, bool skipFileCheck = false, string userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:101.0) Gecko/20100101 Firefox/101.0") => await
Host
.CreateDefaultBuilder()
.ConfigureHostConfiguration(configHost => configHost.AddEnvironmentVariables())
@ -45,7 +46,7 @@ public class Program
.AddSerilog(dispose: true);
})
.AddHostedService<DownloaderService>()
.AddSingleton(new DownloaderOptions(outputDir, customFeed, action, about, productVersion, skipFileCheck))
.AddSingleton(new DownloaderOptions(outputDir, customFeed, action, about, productVersion, skipFileCheck, userAgent))
.AddHttpClient())
.RunConsoleAsync()
.ConfigureAwait(false);