aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Server
diff options
context:
space:
mode:
Diffstat (limited to 'Jellyfin.Server')
-rw-r--r--Jellyfin.Server/Filters/AdditionalModelFilter.cs105
1 files changed, 72 insertions, 33 deletions
diff --git a/Jellyfin.Server/Filters/AdditionalModelFilter.cs b/Jellyfin.Server/Filters/AdditionalModelFilter.cs
index 4cd0fc231..421eeecda 100644
--- a/Jellyfin.Server/Filters/AdditionalModelFilter.cs
+++ b/Jellyfin.Server/Filters/AdditionalModelFilter.cs
@@ -92,17 +92,51 @@ namespace Jellyfin.Server.Filters
continue;
}
- // Additional discriminator needed for GroupUpdate models...
- if (messageType == SessionMessageType.SyncPlayGroupUpdate && type != typeof(SyncPlayGroupUpdateCommandMessage))
- {
- continue;
- }
-
var schema = context.SchemaGenerator.GenerateSchema(type, context.SchemaRepository);
outboundWebSocketSchemas.Add(schema);
outboundWebSocketDiscriminators.Add(messageType.ToString()!, schema.Reference.ReferenceV3);
}
+ // Add custom "SyncPlayGroupUpdateMessage" schema because Swashbuckle cannot generate it for us
+ var syncPlayGroupUpdateMessageSchema = new OpenApiSchema
+ {
+ Type = "object",
+ Description = "Untyped sync play command.",
+ Properties = new Dictionary<string, OpenApiSchema>
+ {
+ {
+ "Data", new OpenApiSchema
+ {
+ AllOf =
+ [
+ new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = nameof(GroupUpdate<object>) } }
+ ],
+ Description = "Group update data",
+ Nullable = false,
+ }
+ },
+ { "MessageId", new OpenApiSchema { Type = "string", Format = "uuid", Description = "Gets or sets the message id." } },
+ {
+ "MessageType", new OpenApiSchema
+ {
+ Enum = Enum.GetValues<SessionMessageType>().Select(type => new OpenApiString(type.ToString())).ToList<IOpenApiAny>(),
+ AllOf =
+ [
+ new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = nameof(SessionMessageType) } }
+ ],
+ Description = "The different kinds of messages that are used in the WebSocket api.",
+ Default = new OpenApiString(nameof(SessionMessageType.SyncPlayGroupUpdate)),
+ ReadOnly = true
+ }
+ },
+ },
+ AdditionalPropertiesAllowed = false,
+ Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "SyncPlayGroupUpdateMessage" }
+ };
+ context.SchemaRepository.AddDefinition("SyncPlayGroupUpdateMessage", syncPlayGroupUpdateMessageSchema);
+ outboundWebSocketSchemas.Add(syncPlayGroupUpdateMessageSchema);
+ outboundWebSocketDiscriminators[nameof(SessionMessageType.SyncPlayGroupUpdate)] = syncPlayGroupUpdateMessageSchema.Reference.ReferenceV3;
+
var outboundWebSocketMessageSchema = new OpenApiSchema
{
Type = "object",
@@ -140,41 +174,46 @@ namespace Jellyfin.Server.Filters
});
// Manually generate sync play GroupUpdate messages.
- if (!context.SchemaRepository.Schemas.TryGetValue(nameof(GroupUpdate), out var groupUpdateSchema))
- {
- groupUpdateSchema = context.SchemaGenerator.GenerateSchema(typeof(GroupUpdate), context.SchemaRepository);
- }
-
- var groupUpdateOfGroupInfoSchema = context.SchemaGenerator.GenerateSchema(typeof(GroupUpdate<GroupInfoDto>), context.SchemaRepository);
- var groupUpdateOfGroupStateSchema = context.SchemaGenerator.GenerateSchema(typeof(GroupUpdate<GroupStateUpdate>), context.SchemaRepository);
- var groupUpdateOfStringSchema = context.SchemaGenerator.GenerateSchema(typeof(GroupUpdate<string>), context.SchemaRepository);
- var groupUpdateOfPlayQueueSchema = context.SchemaGenerator.GenerateSchema(typeof(GroupUpdate<PlayQueueUpdate>), context.SchemaRepository);
+ var groupUpdateTypes = typeof(GroupUpdate<>).Assembly.GetTypes()
+ .Where(t => t.BaseType != null
+ && t.BaseType.IsGenericType
+ && t.BaseType.GetGenericTypeDefinition() == typeof(GroupUpdate<>))
+ .ToList();
- groupUpdateSchema.OneOf = new List<OpenApiSchema>
+ var groupUpdateSchemas = new List<OpenApiSchema>();
+ var groupUpdateDiscriminators = new Dictionary<string, string>();
+ foreach (var type in groupUpdateTypes)
{
- groupUpdateOfGroupInfoSchema,
- groupUpdateOfGroupStateSchema,
- groupUpdateOfStringSchema,
- groupUpdateOfPlayQueueSchema
- };
+ var groupUpdateType = (GroupUpdateType?)type.GetProperty(nameof(GroupUpdate<object>.Type))?.GetCustomAttribute<DefaultValueAttribute>()?.Value;
+ if (groupUpdateType is null)
+ {
+ continue;
+ }
+
+ var schema = context.SchemaGenerator.GenerateSchema(type, context.SchemaRepository);
+ groupUpdateSchemas.Add(schema);
+ groupUpdateDiscriminators[groupUpdateType.ToString()!] = schema.Reference.ReferenceV3;
+ }
- groupUpdateSchema.Discriminator = new OpenApiDiscriminator
+ var groupUpdateSchema = new OpenApiSchema
{
- PropertyName = nameof(GroupUpdate.Type),
- Mapping = new Dictionary<string, string>
+ Type = "object",
+ Description = "Represents the list of possible group update types",
+ Reference = new OpenApiReference
+ {
+ Id = nameof(GroupUpdate<object>),
+ Type = ReferenceType.Schema
+ },
+ OneOf = groupUpdateSchemas,
+ Discriminator = new OpenApiDiscriminator
{
- { GroupUpdateType.UserJoined.ToString(), groupUpdateOfStringSchema.Reference.ReferenceV3 },
- { GroupUpdateType.UserLeft.ToString(), groupUpdateOfStringSchema.Reference.ReferenceV3 },
- { GroupUpdateType.GroupJoined.ToString(), groupUpdateOfGroupInfoSchema.Reference.ReferenceV3 },
- { GroupUpdateType.GroupLeft.ToString(), groupUpdateOfStringSchema.Reference.ReferenceV3 },
- { GroupUpdateType.StateUpdate.ToString(), groupUpdateOfGroupStateSchema.Reference.ReferenceV3 },
- { GroupUpdateType.PlayQueue.ToString(), groupUpdateOfPlayQueueSchema.Reference.ReferenceV3 },
- { GroupUpdateType.NotInGroup.ToString(), groupUpdateOfStringSchema.Reference.ReferenceV3 },
- { GroupUpdateType.GroupDoesNotExist.ToString(), groupUpdateOfStringSchema.Reference.ReferenceV3 },
- { GroupUpdateType.LibraryAccessDenied.ToString(), groupUpdateOfStringSchema.Reference.ReferenceV3 }
+ PropertyName = nameof(GroupUpdate<object>.Type),
+ Mapping = groupUpdateDiscriminators
}
};
+ context.SchemaRepository.Schemas[nameof(GroupUpdate<object>)] = groupUpdateSchema;
+
context.SchemaGenerator.GenerateSchema(typeof(ServerDiscoveryInfo), context.SchemaRepository);
foreach (var configuration in _serverConfigurationManager.GetConfigurationStores())