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 AzureQueue provider to collect and relay messages created on a website #280

Merged
merged 5 commits into from
Nov 7, 2023
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
2 changes: 2 additions & 0 deletions src/TagzApp.Common/ISocialMediaProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public interface ISocialMediaProvider
/// </summary>
string DisplayName { get; }

virtual string DllName => DisplayName;

/// <summary>
/// Provider description
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion src/TagzApp.Common/Models/Creator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class Creator
/// <summary>
/// Uri to the profile of the creator
/// </summary>
public required Uri ProfileUri { get; set; }
public required Uri ProfileUri { get; set; } = new Uri("/img/user.jpg", UriKind.Relative);

/// <summary>
/// Uri to the profile image of the creator
Expand Down
11 changes: 11 additions & 0 deletions src/TagzApp.Providers.AzureQueue/AzureQueueConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace TagzApp.Providers.AzureQueue;

public class AzureQueueConfiguration
{

public string QueueConnectionString { get; set; } = string.Empty;

public bool Activated { get; set; }

}

77 changes: 77 additions & 0 deletions src/TagzApp.Providers.AzureQueue/AzureQueueProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using Azure.Storage.Queues;
using System.Text.Json;

namespace TagzApp.Providers.AzureQueue;

public class AzureQueueProvider : ISocialMediaProvider
{
private const string QueueName = "tagzapp-content";
private readonly AzureQueueConfiguration _Configuration;
private QueueClient _Client;
private SocialMediaStatus _Status = SocialMediaStatus.Unhealthy;
private string _StatusMessage = "Not started";

public string Id => "WEBSITE";
public string DisplayName => "Website";
public string DllName { get { return "AzureQueue"; } }
public string Description => "Q+A submitted through a website form";
public TimeSpan NewContentRetrievalFrequency => TimeSpan.FromSeconds(5);

public AzureQueueProvider(AzureQueueConfiguration configuration)

Check warning on line 20 in src/TagzApp.Providers.AzureQueue/AzureQueueProvider.cs

View workflow job for this annotation

GitHub Actions / Playwright Tests

Non-nullable field '_Client' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.

Check warning on line 20 in src/TagzApp.Providers.AzureQueue/AzureQueueProvider.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field '_Client' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.
{
_Configuration = configuration;
}


public async Task<IEnumerable<Content>> GetContentForHashtag(Hashtag tag, DateTimeOffset since)
{

var messageResponse = await _Client.ReceiveMessagesAsync(maxMessages: 10);
if (!messageResponse.Value.Any()) return Enumerable.Empty<Content>();

var outList = new List<Content>();

foreach (var msg in messageResponse.Value)
{

var content = JsonSerializer.Deserialize<Content>(msg.Body.ToStream());
if (content is not null)
{
content.HashtagSought = tag.Text.ToLowerInvariant();
outList.Add(content);
await _Client.DeleteMessageAsync(msg.MessageId, msg.PopReceipt);
}

}

return outList;


}

public Task<(SocialMediaStatus Status, string Message)> GetHealth()
{
return Task.FromResult((_Status, _StatusMessage));
}

public async Task StartAsync()
{

_Client = new QueueClient(_Configuration.QueueConnectionString, QueueName);

try
{
await _Client.CreateIfNotExistsAsync();
}
catch (Exception ex)
{
_Status = SocialMediaStatus.Unhealthy;
_StatusMessage = $"Unable to start a connection to the Azure Queue: {ex.Message}";
return;
}

_Status = SocialMediaStatus.Healthy;
_StatusMessage = "Connected";

}
}
40 changes: 40 additions & 0 deletions src/TagzApp.Providers.AzureQueue/StartAzureQueue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using Microsoft.Extensions.DependencyInjection;
using TagzApp.Communication;

namespace TagzApp.Providers.AzureQueue;

public class StartAzureQueue : BaseConfigurationProvider, IConfigureProvider
{

private AzureQueueConfiguration _azureQueueConfiguration;

public StartAzureQueue(IProviderConfigurationRepository providerConfigurationRepository) : base(providerConfigurationRepository)

Check warning on line 11 in src/TagzApp.Providers.AzureQueue/StartAzureQueue.cs

View workflow job for this annotation

GitHub Actions / Playwright Tests

Non-nullable field '_azureQueueConfiguration' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.

Check warning on line 11 in src/TagzApp.Providers.AzureQueue/StartAzureQueue.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field '_azureQueueConfiguration' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.
{
}

public async Task<IServiceCollection> RegisterServices(IServiceCollection services, CancellationToken cancellationToken = default)
{
await LoadConfigurationValuesAsync("WEBSITE", cancellationToken);

services.AddSingleton(_azureQueueConfiguration ?? new());
services.AddTransient<ISocialMediaProvider, AzureQueueProvider>();
return services;
}

protected override void MapConfigurationValues(ProviderConfiguration providerConfiguration)
{

var config = providerConfiguration.ConfigurationSettings;

if (config != null)
{
_azureQueueConfiguration = new()
{
Activated = providerConfiguration.Activated,
QueueConnectionString = config["QueueConnectionString"] ?? string.Empty
};
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Azure.Storage.Queues" Version="12.16.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\TagzApp.Common\TagzApp.Common.csproj" />
<ProjectReference Include="..\TagzApp.Communication\TagzApp.Communication.csproj" />
</ItemGroup>

</Project>
4 changes: 2 additions & 2 deletions src/TagzApp.Web/Areas/Admin/Pages/Providers.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<h2>Provider Management</h2>

<article class="mt-3">
@foreach (var provider in Model.Providers)
@foreach (var provider in Model.Providers.OrderBy(p => p.DisplayName))
{
var health = await provider.GetHealth();

Expand Down Expand Up @@ -41,7 +41,7 @@
<p class="ps-3 pt-3 mb-0 fst-italic">Please fill in the configuration values below:</p>
<form method="post" class="p-3" id="@($"{provider.Id}-form")">
<input type="hidden" id="Name" name="Name" value="@provider.DisplayName" />
@foreach (var property in vmUtilities.LoadViewModel(provider.DisplayName) ?? new System.Reflection.PropertyInfo[0])
@foreach (var property in vmUtilities.LoadViewModel(provider.DllName) ?? new System.Reflection.PropertyInfo[0])
{
var displayName = vmUtilities.GetDisplayName(property);
displayName = string.IsNullOrWhiteSpace(displayName) ? property.Name : displayName;
Expand Down
2 changes: 1 addition & 1 deletion src/TagzApp.Web/Pages/Overlay.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@

overlayDisplay.className = "begin";
overlayDisplay.innerHTML = `
<img class="ProfilePicture" src="${content.authorProfileImageUri}" alt="${content.authorDisplayName}" />
<img class="ProfilePicture" src="${content.authorProfileImageUri}" alt="${content.authorDisplayName}" onerror="this.src='/img/user.jpg';" />
<div class="byline">
<div class="author">${content.authorDisplayName}</div>
<div class="authorUserName">${content.authorUserName}</div>
Expand Down
2 changes: 1 addition & 1 deletion src/TagzApp.Web/Pages/PortraitOverlay.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@

overlayDisplay.className = "begin";
overlayDisplay.innerHTML = `
<img class="ProfilePicture" src="${content.authorProfileImageUri}" alt="${content.authorDisplayName}" />
<img class="ProfilePicture" src="${content.authorProfileImageUri}" alt="${content.authorDisplayName}" onerror="this.src='/img/user.jpg';" />
<div class="byline">
<div class="author">${content.authorDisplayName}</div>
<div class="authorUserName">${content.authorUserName}</div>
Expand Down
2 changes: 1 addition & 1 deletion src/TagzApp.Web/Pages/Waterfall.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

<div class="modal-front modal-content">
<div class="modal-header">
<img class="ProfilePicture" src="" alt="" />
<img class="ProfilePicture" src="" alt="" onerror="this.src='/img/user.jpg';" />
<div class="author"></div>
<div class="authorUserName" title=""></div>
<i class="provider bi"></i>
Expand Down
1 change: 1 addition & 0 deletions src/TagzApp.Web/TagzApp.Web.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<ItemGroup>
<ProjectReference Include="..\TagzApp.Common\TagzApp.Common.csproj" />
<ProjectReference Include="..\TagzApp.Communication\TagzApp.Communication.csproj" />
<ProjectReference Include="..\TagzApp.Providers.AzureQueue\TagzApp.Providers.AzureQueue.csproj" />
<ProjectReference Include="..\TagzApp.Providers.Mastodon\TagzApp.Providers.Mastodon.csproj" />
<ProjectReference Include="..\TagzApp.Providers.TwitchChat\TagzApp.Providers.TwitchChat.csproj" />
<ProjectReference Include="..\TagzApp.Providers.Twitter\TagzApp.Providers.Twitter.csproj" />
Expand Down
25 changes: 14 additions & 11 deletions src/TagzApp.Web/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,20 @@
"WindowRequests": 5,
"Activated": false,
"Description": "Blazot is an all new social networking platform and your launchpad to the social universe!"
}
},
"HttpPolicies": {
"HttpCircuitBreaker": {
"DurationOfBreak": "00:01:00",
"ExceptionsAllowedBeforeBreaking": 20
},
"HttpRetry": {
"BackoffPower": 2,
"Count": 3
"website": {
"Activated": true,
}
},
"AllowedHosts": "*"
},
"HttpPolicies": {
"HttpCircuitBreaker": {
"DurationOfBreak": "00:01:00",
"ExceptionsAllowedBeforeBreaking": 20
},
"HttpRetry": {
"BackoffPower": 2,
"Count": 3
}
},
"AllowedHosts": "*"
}
Binary file added src/TagzApp.Web/wwwroot/img/user.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion src/TagzApp.Web/wwwroot/js/site.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@
newMessage.innerHTML = `
<img class="ProfilePicture" src="${content.authorProfileImageUri}" alt="${
content.authorDisplayName
}" />
}" onerror="this.src='/img/user.jpg';" />
<div class="byline">
<div class="author">${content.authorDisplayName} <i class="autoMod"></i></div>
<div class="authorUserName" title="${content.authorUserName}">${
Expand Down Expand Up @@ -322,6 +322,9 @@
case 'twitter':
cssClass = 'twitter-x';
break;
case 'website':
cssClass = 'globe2';
break;
case 'youtube-chat':
cssClass = 'youtube';
break;
Expand Down
7 changes: 7 additions & 0 deletions src/TagzApp.sln
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TagzApp.Storage.Postgres.Se
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TagzApp.Providers.YouTubeChat", "TagzApp.Providers.YouTubeChat\TagzApp.Providers.YouTubeChat.csproj", "{3562DD07-36C6-4729-A0B7-5DD119AEC7CD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TagzApp.Providers.AzureQueue", "TagzApp.Providers.AzureQueue\TagzApp.Providers.AzureQueue.csproj", "{F1503058-9A18-4EB2-A009-9311655707DF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -103,6 +105,10 @@ Global
{3562DD07-36C6-4729-A0B7-5DD119AEC7CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3562DD07-36C6-4729-A0B7-5DD119AEC7CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3562DD07-36C6-4729-A0B7-5DD119AEC7CD}.Release|Any CPU.Build.0 = Release|Any CPU
{F1503058-9A18-4EB2-A009-9311655707DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F1503058-9A18-4EB2-A009-9311655707DF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F1503058-9A18-4EB2-A009-9311655707DF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F1503058-9A18-4EB2-A009-9311655707DF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -121,6 +127,7 @@ Global
{95D763E5-52F5-4155-A888-C66A686BA6EB} = {370455D5-6EA6-44C1-B315-B621F7B6A954}
{F0F32FC9-C435-4B1D-BB21-61B93633E307} = {370455D5-6EA6-44C1-B315-B621F7B6A954}
{3562DD07-36C6-4729-A0B7-5DD119AEC7CD} = {99E0BB3F-9591-4C7A-A8EE-C54B0C3DE7A5}
{F1503058-9A18-4EB2-A009-9311655707DF} = {99E0BB3F-9591-4C7A-A8EE-C54B0C3DE7A5}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F2AD77A5-5B2D-41FC-AD37-8EF8A4E54410}
Expand Down
Loading