Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added animated gifs to API objects, improved link formatter, and more… #457

Merged
merged 2 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 88 additions & 91 deletions src/TagzApp.Blazor.Client/Components/Admin/Blazot.Config.Ui.razor
Original file line number Diff line number Diff line change
@@ -1,127 +1,127 @@
@using System.ComponentModel.DataAnnotations
@using System.Text.Json
@inject ToastService ToastService

<UiProviderConfig ProviderName="Blazot" Health="@Health" ProviderIconCssClass="bi-blazot">

<EditForm Model="Model" OnValidSubmit="SaveConfig">
<AntiforgeryToken />
<ValidationSummary />
<dl>
<dt><label for="ApiKey">Api Key:</label></dt>
<dd>
<InputText name="ApiKey" @bind-Value="Model.ApiKey" placeholder="Api Key" />
<ValidationMessage For="() => Model.ApiKey" class="text-danger" />
</dd>
<dt><label for="SecretAuthKey">Secret Auth Key:</label></dt>
<dd>
<InputText type="password" name="SecretAuthKey" @bind-Value="Model.SecretAuthKey" placeholder="Secret Auth Key" />
<ValidationMessage For="() => Model.SecretAuthKey" class="text-danger" />
</dd>
<dt><label for="BaseAddress">Base Address:</label></dt>
<dd>
<InputText name="BaseAddress" @bind-Value="Model.BaseAddress" placeholder="Base Address of Mastodon Server" />
<ValidationMessage For="() => Model.BaseAddress" class="text-danger" />
</dd>
<dt><label for="Timeout">Timeout:</label></dt>
<dd>
<input name="Timeout" @bind="Model.Timeout" pattern="\d{2}:\d{2}:\d{2}" />
<ValidationMessage For="() => Model.Timeout" class="text-danger" />
</dd>
<dt>Default Headers:</dt>
<dd>
@* Generate a set of textboxes to collect values for the DefaultHeaders dictionary in ViewModel*@
<InputDictionary Value="@Model.DefaultHeaders" KeyCaption="Name" />

</dd>
<dt><label for="UseHttp2">UseHttp2:</label></dt>
<dd>
<InputCheckbox name="UseHttp2" @bind-Value="Model.UseHttp2" />
</dd>
<dt><label for="WindowRequests">Window Requests:</label></dt>
<dd>
<InputNumber name="WindowRequests" @bind-Value="Model.WindowRequests" />
<ValidationMessage For="() => Model.WindowRequests" class="text-danger" />
</dd>
<dt><label for="WindowSeconds">Window Seconds:</label></dt>
<dd>
<InputNumber name="WindowSeconds" @bind-Value="Model.WindowSeconds" />
<ValidationMessage For="() => Model.WindowSeconds" class="text-danger" />
</dd>

<dt><label for="Enabled">Enabled:</label></dt>
<dd>
<InputCheckbox name="Enabled" @bind-Value="Model.Enabled" />
</dd>
</dl>

<button type="submit" class="btn btn-primary">Save</button>

</EditForm>

<UiProviderConfig ProviderName="Blazot" Health="@_Health" ProviderIconCssClass="bi-blazot">
<EditForm Model="_Model" OnValidSubmit="SaveConfigAsync">
<AntiforgeryToken />
<ValidationSummary />
<dl>
<dt><label for="ApiKey">Api Key:</label></dt>
<dd>
<InputText id="ApiKey" name="ApiKey" @bind-Value="_Model.ApiKey" placeholder="Api Key" />
<ValidationMessage For="() => _Model.ApiKey" class="text-danger" />
</dd>
<dt><label for="SecretAuthKey">Secret Auth Key:</label></dt>
<dd>
<InputText id="SecretAuthKey" type="password" name="SecretAuthKey" @bind-Value="_Model.SecretAuthKey" placeholder="Secret Auth Key" />
<ValidationMessage For="() => _Model.SecretAuthKey" class="text-danger" />
</dd>
<dt><label for="BaseAddress">Base Address:</label></dt>
<dd>
<InputText id="BaseAddress" name="BaseAddress" @bind-Value="_Model.BaseAddress" placeholder="Base Address of Mastodon Server" />
<ValidationMessage For="() => _Model.BaseAddress" class="text-danger" />
</dd>
<dt><label for="Timeout">Timeout:</label></dt>
<dd>
<input id="Timeout" name="Timeout" @bind="_Model.Timeout" pattern="\d{2}:\d{2}:\d{2}" />
<ValidationMessage For="() => _Model.Timeout" class="text-danger" />
</dd>
<dt>Default Headers:</dt>
<dd>
@* Generate a set of textboxes to collect values for the DefaultHeaders dictionary in ViewModel*@
<InputDictionary Value="@_Model.DefaultHeaders" KeyCaption="Name" />

</dd>
<dt><label for="UseHttp2">UseHttp2:</label></dt>
<dd>
<InputCheckbox id="UseHttp2" name="UseHttp2" @bind-Value="_Model.UseHttp2" />
</dd>
<dt><label for="WindowRequests">Window Requests:</label></dt>
<dd>
<InputNumber id="WindowRequests" name="WindowRequests" @bind-Value="_Model.WindowRequests" />
<ValidationMessage For="() => _Model.WindowRequests" class="text-danger" />
</dd>
<dt><label for="WindowSeconds">Window Seconds:</label></dt>
<dd>
<InputNumber id="WindowSeconds" name="WindowSeconds" @bind-Value="_Model.WindowSeconds" />
<ValidationMessage For="() => _Model.WindowSeconds" class="text-danger" />
</dd>
<dt><label for="Enabled">Enabled:</label></dt>
<dd>
<InputCheckbox id="Enabled" name="Enabled" @bind-Value="_Model.Enabled" />
</dd>
</dl>

<button type="submit" class="btn btn-primary">Save</button>
</EditForm>
</UiProviderConfig>

@code {

[Parameter, EditorRequired]
public ISocialMediaProvider Provider { get; set; } = null!;

public (SocialMediaStatus Status, string Message) Health { get; set; } = (SocialMediaStatus.Unknown, string.Empty);


public ViewModel Model { get; set; } = new();
[Inject] private ToastService ToastService { get; set; } = null!;
[Parameter, EditorRequired] public ISocialMediaProvider Provider { get; set; } = null!;
private (SocialMediaStatus Status, string Message) _Health = (SocialMediaStatus.Unknown, string.Empty);
private ViewModel _Model = new();

protected override async Task OnParametersSetAsync()
{
var providerConfiguration = await Provider.GetConfiguration(ConfigureTagzAppFactory.Current);

var headers = providerConfiguration.GetConfigurationByKey("DefaultHeaders");
var headerDictionary = string.IsNullOrEmpty(headers) ? new() : JsonSerializer.Deserialize<Dictionary<string, string>>(headers);
var headerDictionary = JsonSerializer.Deserialize<Dictionary<string, string>>(headers) ?? new Dictionary<string, string>();
int.TryParse(providerConfiguration.GetConfigurationByKey(nameof(_Model.WindowRequests)), out var windowRequests);
int.TryParse(providerConfiguration.GetConfigurationByKey(nameof(_Model.WindowSeconds)), out var windowSeconds);

Model = new ViewModel
_Model = new ViewModel
{
BaseAddress = providerConfiguration.GetConfigurationByKey("BaseAddress"),
ApiKey = providerConfiguration.GetConfigurationByKey(nameof(_Model.ApiKey)),
SecretAuthKey = providerConfiguration.GetConfigurationByKey(nameof(_Model.SecretAuthKey)),
WindowRequests = windowRequests,
WindowSeconds = windowSeconds,
BaseAddress = providerConfiguration.GetConfigurationByKey(nameof(_Model.BaseAddress)),
DefaultHeaders = headerDictionary,
Timeout = TimeSpan.Parse(providerConfiguration.GetConfigurationByKey("Timeout")),
UseHttp2 = string.IsNullOrEmpty(providerConfiguration.GetConfigurationByKey("UseHttp2")) ? false : bool.Parse(providerConfiguration.GetConfigurationByKey("UseHttp2")),
Enabled = string.IsNullOrEmpty(providerConfiguration.GetConfigurationByKey("Enabled")) ? false : bool.Parse(providerConfiguration.GetConfigurationByKey("Enabled"))
Timeout = TimeSpan.Parse(providerConfiguration.GetConfigurationByKey(nameof(_Model.Timeout))),
UseHttp2 = !string.IsNullOrWhiteSpace(providerConfiguration.GetConfigurationByKey(nameof(_Model.UseHttp2))) && bool.Parse(providerConfiguration.GetConfigurationByKey(nameof(_Model.UseHttp2))),
Enabled = !string.IsNullOrWhiteSpace(providerConfiguration.GetConfigurationByKey(nameof(_Model.Enabled))) && bool.Parse(providerConfiguration.GetConfigurationByKey(nameof(_Model.Enabled)))
};

Health = await Provider.GetHealth();
_Health = await Provider.GetHealth();
await InvokeAsync(StateHasChanged);

await base.OnParametersSetAsync();
}

private async Task SaveConfig()
private async Task SaveConfigAsync()
{
var providerConfiguration = await Provider.GetConfiguration(ConfigureTagzAppFactory.Current);

Model.DefaultHeaders.Remove(string.Empty);
_Model.DefaultHeaders.Remove(string.Empty);

providerConfiguration.SetConfigurationByKey("BaseAddress", Model.BaseAddress);
providerConfiguration.SetConfigurationByKey("Timeout", Model.Timeout.ToString());
providerConfiguration.SetConfigurationByKey("DefaultHeaders", JsonSerializer.Serialize(Model.DefaultHeaders));
providerConfiguration.SetConfigurationByKey("UseHttp2", Model.UseHttp2.ToString());
providerConfiguration.SetConfigurationByKey("Enabled", Model.Enabled.ToString());
providerConfiguration.SetConfigurationByKey(nameof(_Model.BaseAddress), _Model.BaseAddress);
providerConfiguration.SetConfigurationByKey(nameof(_Model.ApiKey), _Model.ApiKey);
providerConfiguration.SetConfigurationByKey(nameof(_Model.SecretAuthKey), _Model.SecretAuthKey);
providerConfiguration.SetConfigurationByKey(nameof(_Model.WindowRequests), _Model.WindowRequests.ToString());
providerConfiguration.SetConfigurationByKey(nameof(_Model.WindowSeconds), _Model.WindowSeconds.ToString());
providerConfiguration.SetConfigurationByKey(nameof(_Model.Timeout), _Model.Timeout.ToString());
providerConfiguration.SetConfigurationByKey(nameof(_Model.DefaultHeaders), JsonSerializer.Serialize(_Model.DefaultHeaders));
providerConfiguration.SetConfigurationByKey(nameof(_Model.UseHttp2), _Model.UseHttp2.ToString());
providerConfiguration.SetConfigurationByKey(nameof(_Model.Enabled), _Model.Enabled.ToString());

await Provider.SaveConfiguration(ConfigureTagzAppFactory.Current, providerConfiguration);
ToastService.Add($"Saved {providerConfiguration.Name} Configuration", MessageSeverity.Success);
}

public class ViewModel
{

// add properties for each of the fields you want to edit
[Required]
public string ApiKey { get; set; }
[Required]
public string ApiKey { get; set; } = string.Empty;

[Required]
public string BaseAddress { get; set; }
[Required]
public string BaseAddress { get; set; } = string.Empty;

public Dictionary<string, string> DefaultHeaders { get; set; } = new();

[Required]
public string SecretAuthKey { get; set; }
[Required]
public string SecretAuthKey { get; set; } = string.Empty;

[Required]
public TimeSpan Timeout { get; set; }
Expand All @@ -135,8 +135,5 @@
public int WindowRequests { get; set; }

public bool Enabled { get; set; }

}


}
56 changes: 30 additions & 26 deletions src/TagzApp.Providers.Blazot/Configuration/BlazotConfiguration.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using TagzApp.Communication.Configuration;
using TagzApp.Providers.Blazot.Constants;

namespace TagzApp.Providers.Blazot.Configuration;

Expand All @@ -7,9 +8,9 @@ public class BlazotConfiguration : HttpClientOptions, IProviderConfiguration
/// <summary>
/// Declare the section name used.
/// </summary>
public const string AppSettingsSection = "providers:blazot";
public const string AppSettingsSection = BlazotConstants.ProviderId;

public bool Enabled { get; set; } = false;
public bool Enabled { get; set; }

/// <summary>
/// Blazot issued API Key.
Expand All @@ -24,38 +25,40 @@ public class BlazotConfiguration : HttpClientOptions, IProviderConfiguration
/// <summary>
/// The number of seconds in the rate limit window.
/// </summary>
public int WindowSeconds { get; set; } = 60;
public int WindowSeconds { get; set; } = 300;

/// <summary>
/// The number of requests the account allows within the window.
/// </summary>
public int WindowRequests { get; set; }
public int WindowRequests { get; set; } = 5;

/// <summary>
/// Provider Description
/// </summary>
public string Description => "Interact with the Blazot social media service";
public string Name => "Blazot";
public string Description => BlazotConstants.Description;

public string[] Keys => ["ApiKey", "SecretAuthKey", "WindowSeconds", "WindowRequests", "BaseAddress", "Timeout", "DefaultHeaders", "UseHttp2"];
public string Name => BlazotConstants.DisplayName;

public string[] Keys => [nameof(Enabled), nameof(ApiKey), nameof(SecretAuthKey), nameof(WindowSeconds), nameof(WindowRequests), nameof(BaseAddress), nameof(Timeout), nameof(DefaultHeaders), nameof(UseHttp2)];

public BlazotConfiguration()
{
BaseAddress = new Uri("https://api.blazot.com");
BaseAddress = new Uri(BlazotConstants.BaseAddress);
}

public string GetConfigurationByKey(string key)
{
return key switch
{
"ApiKey" => ApiKey,
"SecretAuthKey" => SecretAuthKey,
"WindowSeconds" => WindowSeconds.ToString(),
"WindowRequests" => WindowRequests.ToString(),
"BaseAddress" => BaseAddress?.ToString() ?? string.Empty,
"Timeout" => Timeout.ToString(),
"DefaultHeaders" => DefaultHeaders?.Serialize() ?? string.Empty,
"UseHttp2" => UseHttp2.ToString(),
nameof(ApiKey) => ApiKey,
nameof(SecretAuthKey) => SecretAuthKey,
nameof(WindowSeconds) => WindowSeconds.ToString(),
nameof(WindowRequests) => WindowRequests.ToString(),
nameof(BaseAddress) => BaseAddress?.ToString() ?? string.Empty,
nameof(Timeout) => Timeout.ToString(),
nameof(DefaultHeaders) => DefaultHeaders?.Serialize() ?? string.Empty,
nameof(UseHttp2) => UseHttp2.ToString(),
nameof(Enabled) => Enabled.ToString(),
_ => string.Empty
};
}
Expand All @@ -66,32 +69,33 @@ public void SetConfigurationByKey(string key, string value)
// Set the property with the same name as the key submitted and don't use reflection
switch (key)
{
case "ApiKey":
case nameof(ApiKey):
ApiKey = value;
break;
case "SecretAuthKey":
case nameof(SecretAuthKey):
SecretAuthKey = value;
break;
case "WindowSeconds":
case nameof(WindowSeconds):
WindowSeconds = int.Parse(value);
break;
case "WindowRequests":
case nameof(WindowRequests):
WindowRequests = int.Parse(value);
break;
case "BaseAddress":
case nameof(BaseAddress):
BaseAddress = new Uri(value);
break;
case "Timeout":
case nameof(Timeout):
Timeout = TimeSpan.Parse(value);
break;
case "DefaultHeaders":
case nameof(DefaultHeaders):
DefaultHeaders = DeserializeHeaders(value);
break;
case "UseHttp2":
case nameof(UseHttp2):
UseHttp2 = bool.Parse(value);
break;
case nameof(Enabled):
Enabled = bool.Parse(value);
break;
}


}
}
19 changes: 18 additions & 1 deletion src/TagzApp.Providers.Blazot/Constants/BlazotConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,23 @@ internal static class BlazotConstants
/// </summary>
public const string BaseAppAddress = "https://blazot.com";

public const string ProviderId = "BLAZOT";
/// <summary>
/// The provider id used in the database for provider system configuration.
/// </summary>
public const string ProviderId = "provider-blazot";

/// <summary>
/// The provider name used as an identifier in the database content entries.
/// </summary>
public const string Provider = "BLAZOT";

/// <summary>
/// The display name.
/// </summary>
public const string DisplayName = "Blazot";

/// <summary>
/// The provider description.
/// </summary>
public const string Description = "Interact with the Blazot social media service.";
}
10 changes: 9 additions & 1 deletion src/TagzApp.Providers.Blazot/Converters/ContentConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public IEnumerable<Content> ConvertToContent(List<Transmission>? transmissions,

var content = new Content
{
Provider = BlazotConstants.ProviderId,
Provider = BlazotConstants.Provider,
ProviderId = transmission.TransmissionId.ToString(),
Author = new Creator
{
Expand Down Expand Up @@ -102,6 +102,14 @@ public IEnumerable<Content> ConvertToContent(List<Transmission>? transmissions,
};
}

if (!string.IsNullOrWhiteSpace(transmission.AnimatedMedia?.Url))
{
content.PreviewCard = new Card
{
ImageUri = new Uri(transmission.AnimatedMedia.Url)
};
}

return content;
}
catch (Exception ex)
Expand Down
Loading
Loading