feat: add support for mastodon media

This commit is contained in:
Oliver Booth 2024-02-23 05:36:31 +00:00
parent 21be5e9622
commit 70f167c9c3
Signed by: oliverbooth
GPG Key ID: E60B570D1B7557B5
8 changed files with 98 additions and 47 deletions

View File

@ -1,22 +0,0 @@
namespace OliverBooth.Data;
public interface IMastodonStatus
{
/// <summary>
/// Gets the content of the status.
/// </summary>
/// <value>The content.</value>
string Content { get; }
/// <summary>
/// Gets the date and time at which this status was posted.
/// </summary>
/// <value>The post timestamp.</value>
DateTimeOffset CreatedAt { get; }
/// <summary>
/// Gets the original URI of the status.
/// </summary>
/// <value>The original URI.</value>
Uri OriginalUri { get; }
}

View File

@ -0,0 +1,10 @@
namespace OliverBooth.Data.Mastodon;
public enum AttachmentType
{
Unknown,
Image,
GifV,
Video,
Audio
}

View File

@ -0,0 +1,34 @@
using System.Text.Json.Serialization;
namespace OliverBooth.Data.Mastodon;
public sealed class MastodonStatus
{
/// <summary>
/// Gets the content of the status.
/// </summary>
/// <value>The content.</value>
[JsonPropertyName("content")]
public string Content { get; set; } = string.Empty;
/// <summary>
/// Gets the date and time at which this status was posted.
/// </summary>
/// <value>The post timestamp.</value>
[JsonPropertyName("created_at")]
public DateTimeOffset CreatedAt { get; set; }
/// <summary>
/// Gets the media attachments for this status.
/// </summary>
/// <value>The media attachments.</value>
[JsonPropertyName("media_attachments")]
public IReadOnlyList<MediaAttachment> MediaAttachments { get; set; } = ArraySegment<MediaAttachment>.Empty;
/// <summary>
/// Gets the original URI of the status.
/// </summary>
/// <value>The original URI.</value>
[JsonPropertyName("url")]
public Uri OriginalUri { get; set; } = null!;
}

View File

@ -0,0 +1,22 @@
namespace OliverBooth.Data.Mastodon;
public sealed class MediaAttachment
{
/// <summary>
/// Gets the preview URL of the attachment.
/// </summary>
/// <value>The preview URL.</value>
public Uri PreviewUrl { get; set; } = null!;
/// <summary>
/// Gets the type of this attachment.
/// </summary>
/// <value>The attachment type.</value>
public AttachmentType Type { get; set; } = AttachmentType.Unknown;
/// <summary>
/// Gets the URL of the attachment.
/// </summary>
/// <value>The URL.</value>
public Uri Url { get; set; } = null!;
}

View File

@ -1,18 +0,0 @@
using System.Text.Json.Serialization;
namespace OliverBooth.Data;
internal sealed class MastodonStatus : IMastodonStatus
{
/// <inheritdoc />
[JsonPropertyName("content")]
public string Content { get; set; } = string.Empty;
/// <inheritdoc />
[JsonPropertyName("created_at")]
public DateTimeOffset CreatedAt { get; set; }
/// <inheritdoc />
[JsonPropertyName("url")]
public Uri OriginalUri { get; set; } = null!;
}

View File

@ -1,18 +1,36 @@
@page @page
@using Humanizer @using Humanizer
@using OliverBooth.Data @using OliverBooth.Data.Mastodon
@using OliverBooth.Services @using OliverBooth.Services
@model Index @model Index
@inject IMastodonService MastodonService @inject IMastodonService MastodonService
@{ @{
ViewData["Title"] = "Blog"; ViewData["Title"] = "Blog";
IMastodonStatus latestStatus = MastodonService.GetLatestStatus(); MastodonStatus latestStatus = MastodonService.GetLatestStatus();
} }
<div class="card text-center mastodon-update-card"> <div class="card text-center mastodon-update-card">
<div class="card-body"> <div class="card-body">
@Html.Raw(latestStatus.Content) @Html.Raw(latestStatus.Content)
@foreach (MediaAttachment attachment in latestStatus.MediaAttachments)
{
switch (attachment.Type)
{
case AttachmentType.Audio:
<p><audio controls="controls" src="@attachment.Url"></audio></p>
break;
case AttachmentType.Video:
<p><video controls="controls" class="figure-img img-fluid" src="@attachment.Url"></video></p>
break;
case AttachmentType.Image:
case AttachmentType.GifV:
<p><img class="figure-img img-fluid" src="@attachment.Url"></p>
break;
}
}
</div> </div>
<div class="card-footer text-muted"> <div class="card-footer text-muted">
<abbr title="@latestStatus.CreatedAt.ToString("F")">@latestStatus.CreatedAt.Humanize()</abbr> <abbr title="@latestStatus.CreatedAt.ToString("F")">@latestStatus.CreatedAt.Humanize()</abbr>

View File

@ -1,4 +1,4 @@
using OliverBooth.Data; using OliverBooth.Data.Mastodon;
namespace OliverBooth.Services; namespace OliverBooth.Services;
@ -8,5 +8,5 @@ public interface IMastodonService
/// Gets the latest status posted to Mastodon. /// Gets the latest status posted to Mastodon.
/// </summary> /// </summary>
/// <returns>The latest status.</returns> /// <returns>The latest status.</returns>
IMastodonStatus GetLatestStatus(); MastodonStatus GetLatestStatus();
} }

View File

@ -1,10 +1,17 @@
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization;
using OliverBooth.Data; using OliverBooth.Data;
using OliverBooth.Data.Mastodon;
namespace OliverBooth.Services; namespace OliverBooth.Services;
internal sealed class MastodonService : IMastodonService internal sealed class MastodonService : IMastodonService
{ {
private static readonly JsonSerializerOptions JsonSerializerOptions = new()
{
Converters = { new JsonStringEnumConverter() },
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower
};
private readonly HttpClient _httpClient; private readonly HttpClient _httpClient;
public MastodonService(HttpClient httpClient) public MastodonService(HttpClient httpClient)
@ -13,7 +20,7 @@ internal sealed class MastodonService : IMastodonService
} }
/// <inheritdoc /> /// <inheritdoc />
public IMastodonStatus GetLatestStatus() public MastodonStatus GetLatestStatus()
{ {
string token = Environment.GetEnvironmentVariable("MASTODON_TOKEN") ?? string.Empty; string token = Environment.GetEnvironmentVariable("MASTODON_TOKEN") ?? string.Empty;
string account = Environment.GetEnvironmentVariable("MASTODON_ACCOUNT") ?? string.Empty; string account = Environment.GetEnvironmentVariable("MASTODON_ACCOUNT") ?? string.Empty;
@ -23,7 +30,7 @@ internal sealed class MastodonService : IMastodonService
using HttpResponseMessage response = _httpClient.Send(request); using HttpResponseMessage response = _httpClient.Send(request);
using var stream = response.Content.ReadAsStream(); using var stream = response.Content.ReadAsStream();
var statuses = JsonSerializer.Deserialize<MastodonStatus[]>(stream) ?? Array.Empty<MastodonStatus>(); var statuses = JsonSerializer.Deserialize<MastodonStatus[]>(stream, JsonSerializerOptions);
return statuses[0]; return statuses?[0]!;
} }
} }