Iceshrimp.NET/Iceshrimp.Backend/Controllers/Federation/NodeInfoController.cs
2024-09-13 21:44:31 +02:00

126 lines
No EOL
4.5 KiB
C#

using System.Net;
using System.Net.Mime;
using Iceshrimp.Backend.Controllers.Federation.Attributes;
using Iceshrimp.Backend.Controllers.Shared.Attributes;
using Iceshrimp.Backend.Core.Configuration;
using Iceshrimp.Backend.Core.Database;
using Iceshrimp.Backend.Core.Federation.WebFinger;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
namespace Iceshrimp.Backend.Controllers.Federation;
[FederationApiController]
[Route("/nodeinfo")]
[EnableCors("well-known")]
[Produces(MediaTypeNames.Application.Json)]
public class NodeInfoController(
IOptions<Config.InstanceSection> instanceConfig,
IOptions<Config.StorageSection> storageConfig,
DatabaseContext db
) : ControllerBase
{
[HttpGet("2.1")]
[HttpGet("2.0")]
[ProducesResults(HttpStatusCode.OK)]
public async Task<NodeInfoResponse> GetNodeInfo()
{
var cutoffMonth = DateTime.UtcNow - TimeSpan.FromDays(30);
var cutoffHalfYear = DateTime.UtcNow - TimeSpan.FromDays(180);
var instance = instanceConfig.Value;
var totalUsers =
await db.Users.LongCountAsync(p => p.IsLocalUser && !Constants.SystemUsers.Contains(p.UsernameLower));
var activeMonth =
await db.Users.LongCountAsync(p => p.IsLocalUser &&
!Constants.SystemUsers.Contains(p.UsernameLower) &&
p.LastActiveDate > cutoffMonth);
var activeHalfYear =
await db.Users.LongCountAsync(p => p.IsLocalUser &&
!Constants.SystemUsers.Contains(p.UsernameLower) &&
p.LastActiveDate > cutoffHalfYear);
var localPosts = await db.Notes.LongCountAsync(p => p.UserHost == null);
var maxUploadSize = storageConfig.Value.MaxUploadSizeBytes;
return new NodeInfoResponse
{
Version = Request.Path.Value?.EndsWith("2.1") ?? false ? "2.1" : "2.0",
Software = new NodeInfoResponse.NodeInfoSoftware
{
Name = "Iceshrimp.NET",
Version = instance.Version,
Codename = instance.Codename,
Edition = instance.Edition,
Homepage = new Uri(Constants.ProjectHomepageUrl),
Repository = Request.Path.Value?.EndsWith("2.1") ?? false
? new Uri(Constants.RepositoryUrl)
: null
},
Protocols = ["activitypub"],
Services = new NodeInfoResponse.NodeInfoServices { Inbound = [], Outbound = ["atom1.0", "rss2.0"] },
Usage = new NodeInfoResponse.NodeInfoUsage
{
//FIXME Implement members
Users = new NodeInfoResponse.NodeInfoUsers
{
Total = totalUsers,
ActiveMonth = activeMonth,
ActiveHalfYear = activeHalfYear
},
LocalComments = 0,
LocalPosts = localPosts
},
Metadata = new NodeInfoResponse.NodeInfoMetadata
{
//FIXME Implement members
NodeName = "Iceshrimp.NET",
NodeDescription = "An Iceshrimp.NET instance",
Maintainer = new NodeInfoResponse.Maintainer { Name = "todo", Email = "todo" },
Languages = [],
TosUrl = "todo",
RepositoryUrl = new Uri(Constants.RepositoryUrl),
FeedbackUrl = new Uri(Constants.IssueTrackerUrl),
ThemeColor = "#000000",
DisableRegistration = true,
DisableLocalTimeline = false,
DisableRecommendedTimeline = false,
DisableGlobalTimeline = false,
EmailRequiredForSignup = false,
PostEditing = false,
PostImports = false,
EnableHCaptcha = false,
EnableRecaptcha = false,
MaxNoteTextLength = 0,
MaxCaptionTextLength = 0,
EnableGithubIntegration = false,
EnableDiscordIntegration = false,
EnableEmail = false,
PublicTimelineVisibility = new NodeInfoResponse.PleromaPublicTimelineVisibility
{
Bubble = false,
Federated = false,
Local = false
},
// @formatter:off
UploadLimits = new NodeInfoResponse.PleromaUploadLimits
{
General = maxUploadSize,
Avatar = maxUploadSize,
Background = maxUploadSize,
Banner = maxUploadSize
},
// @formatter:on
Suggestions = new NodeInfoResponse.PleromaSuggestions { Enabled = false },
Federation = new NodeInfoResponse.PleromaFederation { Enabled = true }
},
OpenRegistrations = false
};
}
[HttpGet("2.0.json")]
public IActionResult GetNodeInfoAkkoma()
{
return Redirect("/nodeinfo/2.0");
}
}