Projektdateien hinzufügen.
This commit is contained in:
34
UmlautAdaptarr/Controllers/CapsController.cs
Normal file
34
UmlautAdaptarr/Controllers/CapsController.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Text;
|
||||
using System.Xml.Linq;
|
||||
using UmlautAdaptarr.Services;
|
||||
using UmlautAdaptarr.Utilities;
|
||||
|
||||
namespace UmlautAdaptarr.Controllers
|
||||
{
|
||||
public class CapsController(ProxyService proxyService) : ControllerBase
|
||||
{
|
||||
private readonly ProxyService _proxyService = proxyService;
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> Caps([FromRoute] string options, [FromRoute] string domain, [FromQuery] string? apikey)
|
||||
{
|
||||
if (!UrlUtilities.IsValidDomain(domain))
|
||||
{
|
||||
return NotFound($"{domain} is not a valid URL.");
|
||||
}
|
||||
|
||||
var requestUrl = UrlUtilities.BuildUrl(domain, "caps", apikey);
|
||||
|
||||
var responseMessage = await _proxyService.ProxyRequestAsync(HttpContext, requestUrl);
|
||||
|
||||
var content = await responseMessage.Content.ReadAsStringAsync();
|
||||
var encoding = responseMessage.Content.Headers.ContentType?.CharSet != null ?
|
||||
Encoding.GetEncoding(responseMessage.Content.Headers.ContentType.CharSet) :
|
||||
Encoding.UTF8;
|
||||
var contentType = responseMessage.Content.Headers.ContentType?.MediaType ?? "application/xml";
|
||||
|
||||
return Content(content, contentType, encoding);
|
||||
}
|
||||
}
|
||||
}
|
||||
93
UmlautAdaptarr/Controllers/SearchController.cs
Normal file
93
UmlautAdaptarr/Controllers/SearchController.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Text;
|
||||
using UmlautAdaptarr.Services;
|
||||
using UmlautAdaptarr.Utilities;
|
||||
|
||||
namespace UmlautAdaptarr.Controllers
|
||||
{
|
||||
public abstract class SearchControllerBase(ProxyService proxyService) : ControllerBase
|
||||
{
|
||||
protected readonly ProxyService _proxyService = proxyService;
|
||||
|
||||
protected async Task<IActionResult> BaseSearch(string options, string domain, IDictionary<string, string> queryParameters)
|
||||
{
|
||||
if (!UrlUtilities.IsValidDomain(domain))
|
||||
{
|
||||
return NotFound($"{domain} is not a valid URL.");
|
||||
}
|
||||
|
||||
var requestUrl = UrlUtilities.BuildUrl(domain, queryParameters);
|
||||
|
||||
var responseMessage = await _proxyService.ProxyRequestAsync(HttpContext, requestUrl);
|
||||
|
||||
var content = await responseMessage.Content.ReadAsStringAsync();
|
||||
var encoding = responseMessage.Content.Headers.ContentType?.CharSet != null ?
|
||||
Encoding.GetEncoding(responseMessage.Content.Headers.ContentType.CharSet) :
|
||||
Encoding.UTF8;
|
||||
var contentType = responseMessage.Content.Headers.ContentType?.MediaType ?? "application/xml";
|
||||
|
||||
return Content(content, contentType, encoding);
|
||||
}
|
||||
}
|
||||
|
||||
public class SearchController(ProxyService proxyService, TitleQueryService titleQueryService) : SearchControllerBase(proxyService)
|
||||
{
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> MovieSearch([FromRoute] string options, [FromRoute] string domain)
|
||||
{
|
||||
var queryParameters = HttpContext.Request.Query.ToDictionary(
|
||||
q => q.Key,
|
||||
q => string.Join(",", q.Value));
|
||||
return await BaseSearch(options, domain, queryParameters);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> GenericSearch([FromRoute] string options, [FromRoute] string domain)
|
||||
{
|
||||
var queryParameters = HttpContext.Request.Query.ToDictionary(
|
||||
q => q.Key,
|
||||
q => string.Join(",", q.Value));
|
||||
return await BaseSearch(options, domain, queryParameters);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> BookSearch([FromRoute] string options, [FromRoute] string domain)
|
||||
{
|
||||
var queryParameters = HttpContext.Request.Query.ToDictionary(
|
||||
q => q.Key,
|
||||
q => string.Join(",", q.Value));
|
||||
return await BaseSearch(options, domain, queryParameters);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> TVSearch([FromRoute] string options, [FromRoute] string domain)
|
||||
{
|
||||
var queryParameters = HttpContext.Request.Query.ToDictionary(
|
||||
q => q.Key,
|
||||
q => string.Join(",", q.Value));
|
||||
|
||||
|
||||
if (queryParameters.TryGetValue("tvdbid", out string tvdbId))
|
||||
{
|
||||
var (HasGermanUmlaut, GermanTitle, ExpectedTitle) = await titleQueryService.QueryShow(tvdbId);
|
||||
|
||||
if (GermanTitle == null && ExpectedTitle == null)
|
||||
{
|
||||
return NotFound($"Show with TVDB ID {tvdbId} not found.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return await BaseSearch(options, domain, queryParameters);
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> MusicSearch([FromRoute] string options, [FromRoute] string domain)
|
||||
{
|
||||
var queryParameters = HttpContext.Request.Query.ToDictionary(
|
||||
q => q.Key,
|
||||
q => string.Join(",", q.Value));
|
||||
return await BaseSearch(options, domain, queryParameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
70
UmlautAdaptarr/Program.cs
Normal file
70
UmlautAdaptarr/Program.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using System.Net;
|
||||
using UmlautAdaptarr.Routing;
|
||||
using UmlautAdaptarr.Services;
|
||||
|
||||
internal class Program
|
||||
{
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add services to the container.
|
||||
builder.Services.AddHttpClient("HttpClient").ConfigurePrimaryHttpMessageHandler(() =>
|
||||
{
|
||||
var handler = new HttpClientHandler
|
||||
{
|
||||
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate | DecompressionMethods.Brotli
|
||||
};
|
||||
|
||||
return handler;
|
||||
});
|
||||
|
||||
builder.Services.AddMemoryCache(options =>
|
||||
{
|
||||
options.SizeLimit = 500;
|
||||
});
|
||||
builder.Services.AddSingleton<ILogger, Logger<TitleQueryService>>();
|
||||
|
||||
builder.Services.AddControllers();
|
||||
builder.Services.AddScoped<TitleQueryService>();
|
||||
builder.Services.AddScoped<ProxyService>();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
app.MapControllerRoute(name: "caps",
|
||||
pattern: "{options}/{*domain}",
|
||||
defaults: new { controller = "Caps", action = "Caps" },
|
||||
constraints: new { t = new TRouteConstraint("caps") });
|
||||
|
||||
app.MapControllerRoute(name: "movie-search",
|
||||
pattern: "{options}/{*domain}",
|
||||
defaults: new { controller = "Search", action = "MovieSearch" },
|
||||
constraints: new { t = new TRouteConstraint("movie") });
|
||||
|
||||
app.MapControllerRoute(name: "tv-search",
|
||||
pattern: "{options}/{*domain}",
|
||||
defaults: new { controller = "Search", action = "TVSearch" },
|
||||
constraints: new { t = new TRouteConstraint("tvsearch") });
|
||||
|
||||
app.MapControllerRoute(name: "music-search",
|
||||
pattern: "{options}/{*domain}",
|
||||
defaults: new { controller = "Search", action = "MusicSearch" },
|
||||
constraints: new { t = new TRouteConstraint("music") });
|
||||
|
||||
app.MapControllerRoute(name: "book-search",
|
||||
pattern: "{options}/{*domain}",
|
||||
defaults: new { controller = "Search", action = "BookSearch" },
|
||||
constraints: new { t = new TRouteConstraint("book") });
|
||||
|
||||
app.MapControllerRoute(name: "generic-search",
|
||||
pattern: "{options}/{*domain}",
|
||||
defaults: new { controller = "Search", action = "GenericSearch" },
|
||||
constraints: new { t = new TRouteConstraint("search") });
|
||||
|
||||
app.Run();
|
||||
}
|
||||
}
|
||||
41
UmlautAdaptarr/Properties/launchSettings.json
Normal file
41
UmlautAdaptarr/Properties/launchSettings.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "optionsTODO/example.com/api?t=movie&apikey=132&imdbid=123&limit=100",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"dotnetRunMessages": true,
|
||||
"applicationUrl": "http://localhost:5182"
|
||||
},
|
||||
"https": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"dotnetRunMessages": true,
|
||||
"applicationUrl": "https://localhost:7068;http://localhost:5182"
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
},
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:49485",
|
||||
"sslPort": 44380
|
||||
}
|
||||
}
|
||||
}
|
||||
23
UmlautAdaptarr/Routing/TRouteConstraint.cs
Normal file
23
UmlautAdaptarr/Routing/TRouteConstraint.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
namespace UmlautAdaptarr.Routing
|
||||
{
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
|
||||
public class TRouteConstraint : IRouteConstraint
|
||||
{
|
||||
private readonly string _methodName;
|
||||
|
||||
public TRouteConstraint(string methodName)
|
||||
{
|
||||
_methodName = methodName;
|
||||
}
|
||||
|
||||
public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
|
||||
{
|
||||
var t = httpContext.Request.Query["t"].ToString();
|
||||
|
||||
return t == _methodName;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
59
UmlautAdaptarr/Services/ProxyService.cs
Normal file
59
UmlautAdaptarr/Services/ProxyService.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
namespace UmlautAdaptarr.Services
|
||||
{
|
||||
public class ProxyService(IHttpClientFactory clientFactory, IConfiguration configuration)
|
||||
{
|
||||
private readonly HttpClient _httpClient = clientFactory.CreateClient("HttpClient") ?? throw new ArgumentNullException();
|
||||
private readonly string _userAgent = configuration["Settings:UserAgent"] ?? throw new ArgumentException("UserAgent must be set in appsettings.json");
|
||||
|
||||
public async Task<HttpResponseMessage> ProxyRequestAsync(HttpContext context, string targetUri)
|
||||
{
|
||||
var requestMessage = new HttpRequestMessage();
|
||||
var requestMethod = context.Request.Method;
|
||||
|
||||
if (!HttpMethods.IsGet(requestMethod))
|
||||
{
|
||||
throw new ArgumentException("Only GET requests are supported", nameof(requestMethod));
|
||||
}
|
||||
|
||||
// Copy the request headers
|
||||
foreach (var header in context.Request.Headers)
|
||||
{
|
||||
if (header.Key == "User-Agent" && _userAgent.Length != 0)
|
||||
{
|
||||
requestMessage.Headers.TryAddWithoutValidation(header.Key, $"{header.Value} + {_userAgent}");
|
||||
}
|
||||
else if (!header.Key.Equals("Host", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
requestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
requestMessage.RequestUri = new Uri(targetUri);
|
||||
requestMessage.Method = HttpMethod.Get;
|
||||
|
||||
//var responseMessage = await _httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead, context.RequestAborted);
|
||||
try
|
||||
{
|
||||
var responseMessage = _httpClient.Send(requestMessage, HttpCompletionOption.ResponseHeadersRead, context.RequestAborted);
|
||||
responseMessage.EnsureSuccessStatusCode();
|
||||
|
||||
// Modify the response content if necessary
|
||||
/*var content = await responseMessage.Content.ReadAsStringAsync();
|
||||
content = ReplaceCharacters(content);
|
||||
responseMessage.Content = new StringContent(content);*/
|
||||
|
||||
return responseMessage;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.ToString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private string ReplaceCharacters(string input)
|
||||
{
|
||||
return input.Replace("Ä", "AE");
|
||||
}
|
||||
}
|
||||
}
|
||||
97
UmlautAdaptarr/Services/TitleQueryService.cs
Normal file
97
UmlautAdaptarr/Services/TitleQueryService.cs
Normal file
@@ -0,0 +1,97 @@
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using UmlautAdaptarr.Utilities;
|
||||
|
||||
namespace UmlautAdaptarr.Services
|
||||
{
|
||||
public class TitleQueryService
|
||||
{
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly IMemoryCache _cache;
|
||||
private readonly ILogger<TitleQueryService> _logger;
|
||||
private readonly string _sonarrHost;
|
||||
private readonly string _sonarrApiKey;
|
||||
|
||||
public TitleQueryService(HttpClient httpClient, IMemoryCache memoryCache, ILogger<TitleQueryService> logger)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
_cache = memoryCache;
|
||||
_logger = logger;
|
||||
|
||||
_sonarrHost = Environment.GetEnvironmentVariable("SONARR_HOST");
|
||||
_sonarrApiKey = Environment.GetEnvironmentVariable("SONARR_API_KEY");
|
||||
}
|
||||
|
||||
public async Task<(bool hasGermanUmlaut, string? GermanTitle, string ExpectedTitle)> QueryShow(string tvdbId)
|
||||
{
|
||||
var cacheKey = $"show_{tvdbId}";
|
||||
if (_cache.TryGetValue(cacheKey, out (bool hasGermanUmlaut, string? GermanTitle, string ExpectedTitle) cachedResult))
|
||||
{
|
||||
return cachedResult;
|
||||
}
|
||||
|
||||
var sonarrUrl = $"{_sonarrHost}/api/v3/series?tvdbId={tvdbId}&includeSeasonImages=false&apikey={_sonarrApiKey}";
|
||||
var response = await _httpClient.GetStringAsync(sonarrUrl);
|
||||
var shows = JsonConvert.DeserializeObject<dynamic>(response);
|
||||
|
||||
if (shows == null)
|
||||
{
|
||||
_logger.LogError($"Parsing Sonarr API response for TVDB ID {tvdbId} resulted in null");
|
||||
return (false, null, string.Empty);
|
||||
} else if (shows.Count == 0)
|
||||
{
|
||||
_logger.LogWarning($"No results found for TVDB ID {tvdbId}");
|
||||
return (false, null, string.Empty);
|
||||
}
|
||||
|
||||
var expectedTitle = shows[0].title as string;
|
||||
if (expectedTitle == null)
|
||||
{
|
||||
_logger.LogError($"Sonarr Title for TVDB ID {tvdbId} is null");
|
||||
return (false, null, string.Empty);
|
||||
}
|
||||
|
||||
string? germanTitle = null;
|
||||
var hasGermanTitle = false;
|
||||
|
||||
if ((string)shows[0].originalLanguage.name != "German")
|
||||
{
|
||||
var thetvdbUrl = $"https://umlautadaptarr.pcjones.de/get_german_title.php?tvdbid={tvdbId}";
|
||||
var tvdbResponse = await _httpClient.GetStringAsync(thetvdbUrl);
|
||||
var tvdbData = JsonConvert.DeserializeObject<dynamic>(tvdbResponse);
|
||||
|
||||
if (tvdbData == null)
|
||||
{
|
||||
_logger.LogError($"Parsing UmlautAdaptarr TitleQuery API response for TVDB ID {tvdbId} resulted in null");
|
||||
return (false, null, string.Empty);
|
||||
}
|
||||
|
||||
if (tvdbData.status == "success")
|
||||
{
|
||||
germanTitle = tvdbData.germanTitle;
|
||||
hasGermanTitle = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
germanTitle = expectedTitle;
|
||||
hasGermanTitle = true;
|
||||
}
|
||||
|
||||
var hasGermanUmlaut = germanTitle?.HasGermanUmlauts() ?? false;
|
||||
|
||||
var result = (hasGermanUmlaut, germanTitle, expectedTitle);
|
||||
_cache.Set(cacheKey, result, new MemoryCacheEntryOptions
|
||||
{
|
||||
SlidingExpiration = hasGermanTitle ? TimeSpan.FromDays(30) : TimeSpan.FromDays(7)
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
19
UmlautAdaptarr/UmlautAdaptarr.csproj
Normal file
19
UmlautAdaptarr/UmlautAdaptarr.csproj
Normal file
@@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<InvariantGlobalization>true</InvariantGlobalization>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Models\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
53
UmlautAdaptarr/Utilities/Extensions.cs
Normal file
53
UmlautAdaptarr/Utilities/Extensions.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
|
||||
namespace UmlautAdaptarr.Utilities
|
||||
{
|
||||
public static class Extensions
|
||||
{
|
||||
public static string GetQuery(this HttpContext context, string key)
|
||||
{
|
||||
return context.Request.Query[key].FirstOrDefault() ?? string.Empty;
|
||||
}
|
||||
|
||||
public static string RemoveAccentButKeepGermanUmlauts(this string text)
|
||||
{
|
||||
// TODO: evaluate if this is needed (here)
|
||||
var stringWithoutSz = text.Replace("ß", "ss");
|
||||
|
||||
var normalizedString = stringWithoutSz.Normalize(NormalizationForm.FormD);
|
||||
var stringBuilder = new StringBuilder();
|
||||
|
||||
foreach (var c in normalizedString)
|
||||
{
|
||||
var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
|
||||
|
||||
if (unicodeCategory != UnicodeCategory.NonSpacingMark || c == '\u0308')
|
||||
{
|
||||
stringBuilder.Append(c);
|
||||
}
|
||||
}
|
||||
|
||||
return stringBuilder.ToString().Normalize(NormalizationForm.FormC);
|
||||
}
|
||||
|
||||
public static string ReplaceGermanUmlautsWithLatinEquivalents(this string text)
|
||||
{
|
||||
return text
|
||||
.Replace("Ö", "Oe")
|
||||
.Replace("Ä", "Ae")
|
||||
.Replace("Ü", "Ue")
|
||||
.Replace("ö", "oe")
|
||||
.Replace("ä", "ae")
|
||||
.Replace("ü", "ue")
|
||||
.Replace("ß", "ss");
|
||||
}
|
||||
|
||||
public static bool HasGermanUmlauts(this string text)
|
||||
{
|
||||
if (text == null) return false;
|
||||
var umlauts = new[] { 'ö', 'ä', 'ü', 'Ä', 'Ü', 'Ö', 'ß' };
|
||||
return umlauts.Any(text.Contains);
|
||||
}
|
||||
}
|
||||
}
|
||||
44
UmlautAdaptarr/Utilities/UrlUtilities.cs
Normal file
44
UmlautAdaptarr/Utilities/UrlUtilities.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
|
||||
namespace UmlautAdaptarr.Utilities
|
||||
{
|
||||
public partial class UrlUtilities
|
||||
{
|
||||
[GeneratedRegex(@"^(?!http:\/\/)([a-zA-Z0-9]+(\.[a-zA-Z0-9]+)+.*)$")]
|
||||
private static partial Regex UrlMatchingRegex();
|
||||
public static bool IsValidDomain(string domain)
|
||||
{
|
||||
// RegEx für eine einfache URL-Validierung ohne http:// und ohne abschließenden Schrägstrich
|
||||
// Erlaubt optionale Subdomains, Domainnamen und TLDs, aber keine Pfade oder Protokolle
|
||||
var regex = UrlMatchingRegex();
|
||||
return regex.IsMatch(domain) && !domain.EndsWith("/");
|
||||
}
|
||||
|
||||
public static string BuildUrl(string domain, IDictionary<string, string> queryParameters)
|
||||
{
|
||||
var uriBuilder = new UriBuilder("https", domain);
|
||||
|
||||
var query = HttpUtility.ParseQueryString(string.Empty);
|
||||
foreach (var param in queryParameters)
|
||||
{
|
||||
query[param.Key] = param.Value;
|
||||
}
|
||||
|
||||
uriBuilder.Query = query.ToString();
|
||||
return uriBuilder.ToString();
|
||||
}
|
||||
|
||||
public static string BuildUrl(string domain, string tParameter, string? apiKey = null)
|
||||
{
|
||||
var queryParameters = new Dictionary<string, string>() { { "t", tParameter } };
|
||||
|
||||
if (!string.IsNullOrEmpty(apiKey))
|
||||
{
|
||||
queryParameters["apiKey"] = apiKey;
|
||||
}
|
||||
|
||||
return BuildUrl(domain, queryParameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
8
UmlautAdaptarr/appsettings.Development.json
Normal file
8
UmlautAdaptarr/appsettings.Development.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
20
UmlautAdaptarr/appsettings.json
Normal file
20
UmlautAdaptarr/appsettings.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"Kestrel": {
|
||||
"Endpoints": {
|
||||
"Http": {
|
||||
"Url": "http://localhost:5005"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Settings": {
|
||||
"UserAgent": "UmlautAdaptarr/1.0",
|
||||
"TitleQueryHost": "https://umlautadaptarr.pcjones.de"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user