ci: regenerated with OpenAPI Doc 0.0.3, Speakeasy CLI 1.129.1

This commit is contained in:
speakeasybot
2024-01-01 14:37:30 +00:00
parent 4d1564b0b7
commit d69f35d589
621 changed files with 22413 additions and 3 deletions

View File

@@ -0,0 +1,50 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace PlexAPI.Utils
{
using System;
using System.Globalization;
using System.Numerics;
using Newtonsoft.Json;
internal class BigIntSerializer : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(BigInteger);
public override bool CanRead => true;
public override object? ReadJson(
JsonReader reader,
Type objectType,
object? existingValue,
JsonSerializer serializer
)
{
if (reader.Value == null)
{
return null;
}
return BigInteger.Parse(reader.Value.ToString()!);
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteValue("null");
return;
}
writer.WriteValue(((BigInteger)value).ToString(CultureInfo.InvariantCulture));
}
}
}

View File

@@ -0,0 +1,49 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace PlexAPI.Utils
{
using System;
using System.Globalization;
using Newtonsoft.Json;
internal class DecimalSerializer : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(Decimal);
public override bool CanRead => true;
public override object? ReadJson(
JsonReader reader,
Type objectType,
object? existingValue,
JsonSerializer serializer
)
{
if (reader.Value == null)
{
return null;
}
return Decimal.Parse(reader.Value.ToString()!);
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteValue("null");
return;
}
writer.WriteValue(((Decimal)value).ToString(CultureInfo.InvariantCulture));
}
}
}

View File

@@ -0,0 +1,67 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
using System;
using Newtonsoft.Json;
namespace PlexAPI.Utils
{
internal class EnumSerializer : JsonConverter
{
public override bool CanConvert(System.Type objectType) => objectType.IsEnum;
public override bool CanRead => true;
public override object? ReadJson(
JsonReader reader,
System.Type objectType,
object? existingValue,
JsonSerializer serializer
)
{
if (reader.Value == null)
{
throw new ArgumentNullException(nameof(reader.Value));
}
var extensionType = System.Type.GetType(objectType.FullName + "Extension");
if (extensionType == null)
{
return Enum.ToObject(objectType, reader.Value);
}
var method = extensionType.GetMethod("ToEnum");
if (method == null)
{
throw new Exception($"Unable to find ToEnum method on {extensionType.FullName}");
}
return method.Invoke(null, new[] { (string)reader.Value });
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteValue("null");
return;
}
var extensionType = System.Type.GetType(value.GetType().FullName + "Extension");
if (extensionType == null)
{
writer.WriteValue(value);
return;
}
writer.WriteValue(Utilities.ToString(value));
}
}
}

View File

@@ -0,0 +1,44 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace PlexAPI.Utils
{
using System;
using System.Linq;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
internal class FlexibleObjectDeserializer: JsonConverter
{
public override bool CanConvert(Type objectType) =>
objectType == typeof(object);
public override bool CanWrite => false;
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
var token = JToken.ReadFrom(reader);
if (token is JArray)
{
return new List<object>(token.Select(t =>
{
return t.ToString();
}));
}
return token.ToObject(objectType);
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) =>
throw new NotImplementedException();
}
}

View File

@@ -0,0 +1,129 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace PlexAPI.Utils
{
using System.Collections;
using System.Collections.Generic;
using System.Net.Http;
using System.Reflection;
internal static class HeaderSerializer
{
public static void PopulateHeaders(ref HttpRequestMessage httpRequest, object? request)
{
if (request == null)
{
return;
}
var props = request.GetType().GetProperties();
foreach (var prop in props)
{
var val = prop.GetValue(request);
if (val == null)
{
continue;
}
var metadata = prop.GetCustomAttribute<SpeakeasyMetadata>()?.GetHeaderMetadata();
if (metadata == null || metadata.Name == "")
{
continue;
}
var headerValue = SerializeHeader(val, metadata.Explode);
if (headerValue != "")
{
httpRequest.Headers.Add(metadata.Name, headerValue);
}
}
}
private static string SerializeHeader(object value, bool explode)
{
if (Utilities.IsClass(value))
{
var items = new List<string>();
var props = value.GetType().GetProperties();
foreach (var prop in props)
{
var val = prop.GetValue(value);
if (val == null)
{
continue;
}
var metadata = prop.GetCustomAttribute<SpeakeasyMetadata>()?.GetHeaderMetadata();
if (metadata == null || metadata.Name == null)
{
continue;
}
if (explode)
{
items.Add($"{metadata.Name}={Utilities.ValueToString(val)}");
}
else
{
items.Add(metadata.Name);
items.Add(Utilities.ValueToString(val));
}
}
return string.Join(",", items);
}
else if (Utilities.IsDictionary(value))
{
var items = new List<string>();
foreach (DictionaryEntry entry in (IDictionary)value)
{
var key = entry.Key?.ToString();
if (key == null)
{
continue;
}
if (explode)
{
items.Add($"{key}={Utilities.ValueToString(entry.Value)}");
}
else
{
items.Add(key);
items.Add(Utilities.ValueToString(entry.Value));
}
}
return string.Join(",", items);
}
else if (Utilities.IsList(value))
{
var items = new List<string>();
foreach (var item in (IList)value)
{
items.Add(Utilities.ValueToString(item));
}
return string.Join(",", items);
}
else
{
return Utilities.ValueToString(value);
}
}
}
}

View File

@@ -0,0 +1,41 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace PlexAPI.Utils
{
using System;
using System.Globalization;
using Newtonsoft.Json;
internal class IsoDateTimeSerializer: JsonConverter
{
public override bool CanConvert(Type objectType) =>
objectType == typeof(DateTime);
public override bool CanRead => false;
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) =>
throw new NotImplementedException();
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteValue("null");
return;
}
DateTime time = (DateTime)value;
// The built-in Iso converter coerces to local time;
// This standardizes to UTC.
writer.WriteValue(time.ToUniversalTime().ToString("o", CultureInfo.InvariantCulture));
}
}
}

View File

@@ -0,0 +1,502 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace PlexAPI.Utils
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net.Http;
using System.Reflection;
using System.Text;
internal class RequestBodySerializer
{
public static HttpContent? Serialize(
object? request,
string requestFieldName,
string serializationMethod
)
{
if (request == null)
{
return null;
}
if (Utilities.IsClass(request))
{
var prop = GetPropertyInfo(request, requestFieldName);
if (prop != null)
{
var metadata = prop.GetCustomAttribute<SpeakeasyMetadata>()?.GetRequestMetadata();
if (metadata != null)
{
var fieldValue = prop.GetValue(request);
if (fieldValue == null)
{
return null;
}
return TrySerialize(
fieldValue,
requestFieldName,
serializationMethod,
metadata.MediaType ?? ""
);
}
}
}
// Not an object or flattened request
return TrySerialize(request, requestFieldName, serializationMethod);
}
private static HttpContent? TrySerialize(
object request,
string requestFieldName,
string serializationMethod,
string mediaType = ""
)
{
if (mediaType == "")
{
mediaType = new Dictionary<string, string>()
{
{ "json", "application/json" },
{ "form", "application/x-www-form-urlencoded" },
{ "multipart", "multipart/form-data" },
{ "raw", "application/octet-stream" },
{ "string", "text/plain" },
}[serializationMethod];
}
switch (serializationMethod)
{
case "json":
return SerializeJson(request, mediaType);
case "form":
return SerializeForm(request, requestFieldName, mediaType);
case "multipart":
return SerializeMultipart(request, mediaType);
default:
// if request is a byte array, use it directly otherwise encode
if (request.GetType() == typeof(byte[]))
{
return SerializeRaw((byte[])request, mediaType);
}
else if (request.GetType() == typeof(string))
{
return SerializeString((string)request, mediaType);
}
else
{
throw new Exception(
"Cannot serialize request body of type "
+ request.GetType().Name
+ " with serialization method "
+ serializationMethod
+ ""
);
}
}
}
private static HttpContent SerializeJson(object request, string mediaType)
{
return new StringContent(Utilities.SerializeJSON(request), Encoding.UTF8, mediaType);
}
private static HttpContent SerializeForm(
object request,
string requestFieldName,
string mediaType
)
{
Dictionary<string, List<string>> form = new Dictionary<string, List<string>>();
if (Utilities.IsClass(request))
{
var props = request.GetType().GetProperties();
foreach (var prop in props)
{
var val = prop.GetValue(request);
if (val == null)
{
continue;
}
var metadata = prop.GetCustomAttribute<SpeakeasyMetadata>()?.GetFormMetadata();
if (metadata == null)
{
continue;
}
if (metadata.Json)
{
var key = metadata.Name ?? prop.Name;
if (key == "")
{
continue;
}
if (!form.ContainsKey(key))
{
form.Add(key, new List<string>());
}
form[key].Add(Utilities.SerializeJSON(val));
}
else
{
switch (metadata.Style)
{
case "form":
SerializeFormValue(
metadata.Name ?? prop.Name,
metadata.Explode,
val,
ref form
);
break;
default:
throw new Exception("Unsupported form style " + metadata.Style);
}
}
}
}
else if (Utilities.IsDictionary(request))
{
foreach (var k in ((IDictionary)request).Keys)
{
var key = k?.ToString();
if (key == null)
{
continue;
}
if (!form.ContainsKey(key))
{
form.Add(key, new List<string>());
}
form[key].Add(Utilities.ValueToString(((IDictionary)request)[key]));
}
}
else if (Utilities.IsList(request))
{
foreach (var item in (IList)request)
{
if (!form.ContainsKey(requestFieldName))
{
form.Add(requestFieldName, new List<string>());
}
form[requestFieldName].Add(Utilities.ValueToString(item));
}
}
else
{
throw new Exception(
"Cannot serialize form data from type " + request.GetType().Name
);
}
var formData = new List<KeyValuePair<string?, string?>>();
foreach (var key in form.Keys)
{
foreach (var val in form[key])
{
formData.Add(
new KeyValuePair<string?, string?>(
key + (form[key].Count > 1 ? "[]" : ""),
val
)
);
}
}
return new FormUrlEncodedContent(formData);
}
private static HttpContent SerializeMultipart(object request, string mediaType)
{
var formData = new MultipartFormDataContent();
var properties = request.GetType().GetProperties();
foreach (var prop in properties)
{
var value = prop.GetValue(request);
if (value == null)
{
continue;
}
var metadata = prop.GetCustomAttribute<SpeakeasyMetadata>()?.GetMultipartFormMetadata();
if (metadata == null)
{
continue;
}
if (metadata.File)
{
if (!Utilities.IsClass(value))
{
throw new Exception(
"Cannot serialize multipart file from type " + value.GetType().Name
);
}
var fileProps = value.GetType().GetProperties();
byte[]? content = null;
string fileName = "";
string fieldName = "";
foreach (var fileProp in fileProps)
{
var fileMetadata = fileProp
.GetCustomAttribute<SpeakeasyMetadata>()
?.GetMultipartFormMetadata();
if (
fileMetadata == null
|| (!fileMetadata.Content && fileMetadata.Name == "")
)
{
continue;
}
if (fileMetadata.Content)
{
content = (byte[]?)fileProp.GetValue(value);
}
else
{
fieldName = fileMetadata.Name ?? fileProp.Name;
fileName = fileProp.GetValue(value)?.ToString() ?? "";
}
}
if (fieldName == "" || fileName == "" || content == null)
{
throw new Exception("Invalid multipart/form-data file");
}
formData.Add(new ByteArrayContent(content), fieldName, fileName);
}
else if (metadata.Json)
{
formData.Add(
new StringContent(Utilities.SerializeJSON(value)),
metadata.Name ?? prop.Name
);
}
else if (Utilities.IsList(value))
{
var values = new List<string>();
foreach (var item in (IList)value)
{
values.Add(Utilities.ValueToString(item));
}
foreach (var val in values)
{
formData.Add(new StringContent(val), metadata.Name ?? prop.Name);
}
}
else
{
formData.Add(
new StringContent(Utilities.ValueToString(value)),
metadata.Name ?? prop.Name
);
}
}
return formData;
}
private static HttpContent SerializeRaw(byte[] request, string mediaType)
{
var content = new ByteArrayContent(request);
content.Headers.Add("Content-Type", mediaType);
return content;
}
private static HttpContent SerializeString(string request, string mediaType)
{
return new StringContent(request, Encoding.UTF8, mediaType);
}
private static void SerializeFormValue(
string fieldName,
bool explode,
object value,
ref Dictionary<string, List<string>> form
)
{
if (Utilities.IsClass(value))
{
if (Utilities.IsDate(value))
{
if (!form.ContainsKey(fieldName))
{
form[fieldName] = new List<string>();
}
form[fieldName].Add(Utilities.ValueToString(value));
}
else
{
var props = value.GetType().GetProperties();
var items = new List<string>();
foreach (var prop in props)
{
var val = prop.GetValue(value);
if (val == null)
{
continue;
}
var metadata = prop.GetCustomAttribute<SpeakeasyMetadata>()?.GetFormMetadata();
if (metadata == null || metadata.Name == null)
{
continue;
}
if (explode)
{
if (!form.ContainsKey(metadata.Name))
{
form[metadata.Name] = new List<string>();
}
form[metadata.Name].Add(Utilities.ValueToString(val));
}
else
{
items.Add($"{metadata.Name},{Utilities.ValueToString(val)}");
}
}
if (items.Count > 0)
{
if (!form.ContainsKey(fieldName))
{
form[fieldName] = new List<string>();
}
form[fieldName].Add(string.Join(",", items));
}
}
}
else if (Utilities.IsDictionary(value))
{
var items = new List<string>();
foreach (var k in ((IDictionary)value).Keys)
{
var key = k?.ToString();
if (key == null)
{
continue;
}
if (explode)
{
if (!form.ContainsKey(key))
{
form[key] = new List<string>();
}
form[key].Add(
Utilities.ValueToString(((IDictionary)value)[key])
);
}
else
{
items.Add($"{key},{Utilities.ValueToString(((IDictionary)value)[key])}");
}
}
if (items.Count > 0)
{
if (!form.ContainsKey(fieldName))
{
form[fieldName] = new List<string>();
}
form[fieldName].Add(string.Join(",", items));
}
}
else if (Utilities.IsList(value))
{
var values = new List<string>();
var items = new List<string>();
foreach (var item in (IList)value)
{
if (explode)
{
values.Add(Utilities.ValueToString(item));
}
else
{
items.Add(Utilities.ValueToString(item));
}
}
if (items.Count > 0)
{
values.Add(string.Join(",", items));
}
foreach (var val in values)
{
if (!form.ContainsKey(fieldName))
{
form[fieldName] = new List<string>();
}
form[fieldName].Add(val);
}
}
else
{
if (!form.ContainsKey(fieldName))
{
form[fieldName] = new List<string>();
}
form[fieldName].Add(Utilities.ValueToString(value));
}
}
private static PropertyInfo? GetPropertyInfo(object value, string propertyName)
{
try
{
return value.GetType().GetProperty(propertyName);
}
catch (Exception)
{
return null;
}
}
}
}

View File

@@ -0,0 +1,227 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace PlexAPI.Utils
{
using System;
using System.Reflection;
using System.Text;
internal static class SecuritySerializer
{
public static ISpeakeasyHttpClient Apply(ISpeakeasyHttpClient client, object security)
{
if (security == null)
{
return client;
}
client = new SpeakeasyHttpClient(client);
var props = security.GetType().GetProperties();
foreach (var prop in props)
{
var value = prop.GetValue(security, null);
if (value == null)
{
continue;
}
var metadata = prop.GetCustomAttribute<SpeakeasyMetadata>()?.GetSecurityMetadata();
if (metadata == null)
{
continue;
}
if (metadata.Option)
{
ApplyOption(ref client, value);
}
else if (metadata.Scheme)
{
if (metadata.SubType == "basic" && !Utilities.IsClass(value))
{
ApplyScheme(ref client, metadata, security);
return client;
}
else
{
ApplyScheme(ref client, metadata, value);
}
}
}
return client;
}
private static void ApplyOption(ref ISpeakeasyHttpClient client, object option)
{
var props = option.GetType().GetProperties();
foreach (var prop in props)
{
var value = prop.GetValue(option, null);
if (value == null)
{
continue;
}
var metadata = prop.GetCustomAttribute<SpeakeasyMetadata>()?.GetSecurityMetadata();
if (metadata == null || !metadata.Scheme)
{
continue;
}
ApplyScheme(ref client, metadata, value);
}
}
private static void ApplyScheme(
ref ISpeakeasyHttpClient client,
SpeakeasyMetadata.SecurityMetadata schemeMetadata,
object scheme
)
{
if (Utilities.IsClass(scheme))
{
if (schemeMetadata.Type == "http" && schemeMetadata.SubType == "basic")
{
ApplyBasicAuthScheme(ref client, scheme);
return;
}
var props = scheme.GetType().GetProperties();
foreach (var prop in props)
{
var value = prop.GetValue(scheme, null);
if (value == null)
{
continue;
}
var metadata = prop.GetCustomAttribute<SpeakeasyMetadata>()?.GetSecurityMetadata();
if (metadata == null || metadata.Name == "")
{
continue;
}
ApplySchemeValue(ref client, schemeMetadata, metadata, value);
}
}
else
{
ApplySchemeValue(ref client, schemeMetadata, schemeMetadata, scheme);
}
}
private static void ApplySchemeValue(
ref ISpeakeasyHttpClient client,
SpeakeasyMetadata.SecurityMetadata schemeMetadata,
SpeakeasyMetadata.SecurityMetadata valueMetadata,
object value
)
{
if (valueMetadata.Name == "")
{
return;
}
switch (schemeMetadata.Type)
{
case "apiKey":
switch (schemeMetadata.SubType)
{
case "header":
client.AddHeader(valueMetadata.Name, Utilities.ValueToString(value));
break;
case "query":
client.AddQueryParam(
valueMetadata.Name,
Utilities.ValueToString(value)
);
break;
case "cookie":
client.AddHeader(
"cookie",
$"{valueMetadata.Name}={Utilities.ValueToString(value)}"
);
break;
default:
throw new Exception(
$"Unknown apiKey subType: {schemeMetadata.SubType}"
);
}
break;
case "openIdConnect":
client.AddHeader(valueMetadata.Name, Utilities.ValueToString(value));
break;
case "oauth2":
client.AddHeader(valueMetadata.Name, Utilities.ValueToString(value));
break;
case "http":
switch (schemeMetadata.SubType)
{
case "bearer":
client.AddHeader(
valueMetadata.Name,
Utilities.PrefixBearer(Utilities.ValueToString(value))
);
break;
default:
throw new Exception($"Unknown http subType: {schemeMetadata.SubType}");
}
break;
default:
throw new Exception($"Unknown security type: {schemeMetadata.Type}");
}
}
private static void ApplyBasicAuthScheme(ref ISpeakeasyHttpClient client, object scheme)
{
var props = scheme.GetType().GetProperties();
string username = "";
string password = "";
foreach (var prop in props)
{
var value = prop.GetValue(scheme, null);
if (value == null)
{
continue;
}
var metadata = prop.GetCustomAttribute<SpeakeasyMetadata>()?.GetSecurityMetadata();
if (metadata == null || metadata.Name == "")
{
continue;
}
if (metadata.Name == "username")
{
username = Utilities.ValueToString(value);
}
else if (metadata.Name == "password")
{
password = Utilities.ValueToString(value);
}
}
var auth = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{username}:{password}"));
client.AddHeader("Authorization", $"Basic {auth}");
}
}
}

View File

@@ -0,0 +1,96 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace PlexAPI.Utils
{
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
public interface ISpeakeasyHttpClient
{
void AddHeader(string key, string value);
void AddQueryParam(string key, string value);
Task<HttpResponseMessage> SendAsync(HttpRequestMessage message);
}
public class SpeakeasyHttpClient : ISpeakeasyHttpClient
{
private ISpeakeasyHttpClient? client;
private Dictionary<string, List<string>> headers { get; } =
new Dictionary<string, List<string>>();
private Dictionary<string, List<string>> queryParams { get; } =
new Dictionary<string, List<string>>();
internal SpeakeasyHttpClient(ISpeakeasyHttpClient? client = null)
{
this.client = client;
}
public void AddHeader(string key, string value)
{
if (headers.ContainsKey(key))
{
headers[key].Add(value);
}
else
{
headers.Add(key, new List<string> { value });
}
}
public void AddQueryParam(string key, string value)
{
if (queryParams.ContainsKey(key))
{
queryParams[key].Add(value);
}
else
{
queryParams.Add(key, new List<string> { value });
}
}
public async Task<HttpResponseMessage> SendAsync(HttpRequestMessage message)
{
foreach(var hh in headers)
{
foreach(var hv in hh.Value)
{
message.Headers.Add(hh.Key, hv);
}
}
/*var qp = URLBuilder.SerializeQueryParams(queryParams);
if (qp != "")
{
if (message.uri.Query == "")
{
message.url += "?" + qp;
}
else
{
message.url += "&" + qp;
}
}*/
if (client != null)
{
return await client.SendAsync(message);
}
return await new HttpClient().SendAsync(message);
}
}
}

View File

@@ -0,0 +1,243 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace PlexAPI.Utils
{
using System;
using System.Collections.Generic;
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
internal class SpeakeasyMetadata : Attribute
{
internal class RequestMetadata
{
public string? MediaType { get; set; } = null;
}
internal class FormMetadata
{
public string Style { get; set; } = "form";
public bool Explode { get; set; } = true;
public bool Json { get; set; } = false;
public string Name { get; set; } = "";
}
internal class MultipartFormMetadata
{
public bool File { get; set; } = false;
public bool Content { get; set; } = false;
public bool Json { get; set; } = false;
public string Name { get; set; } = "";
}
internal class PathParamMetadata
{
public string Style { get; set; } = "simple";
public bool Explode { get; set; } = false;
public string Name { get; set; } = "";
public string? Serialization { get; set; } = null;
}
internal class QueryParamMetadata
{
public string Style { get; set; } = "form";
public bool Explode { get; set; } = true;
public string Name { get; set; } = "";
public string? Serialization { get; set; } = null;
}
internal class HeaderMetadata
{
public string Style { get; set; } = "simple";
public bool Explode { get; set; } = false;
public string Name { get; set; } = "";
}
internal class SecurityMetadata
{
public string? Type { get; set; } = null;
public string? SubType { get; set; } = null;
public bool Option { get; set; } = false;
public bool Scheme { get; set; } = false;
public string Name { get; set; } = "";
}
public string Value { get; set; }
private Dictionary<string, string>? metadata;
public SpeakeasyMetadata(string value)
{
Value = value;
}
public RequestMetadata? GetRequestMetadata()
{
if (GetMetadata().TryGetValue("request", out var value))
{
var metadata = new RequestMetadata();
ParseMetadata(value, ref metadata);
return metadata;
}
return null;
}
public FormMetadata? GetFormMetadata()
{
if (GetMetadata().TryGetValue("form", out var value))
{
var metadata = new FormMetadata();
ParseMetadata(value, ref metadata);
return metadata;
}
return null;
}
public MultipartFormMetadata? GetMultipartFormMetadata()
{
if (GetMetadata().TryGetValue("multipartForm", out var value))
{
var metadata = new MultipartFormMetadata();
ParseMetadata(value, ref metadata);
return metadata;
}
return null;
}
public PathParamMetadata? GetPathParamMetadata()
{
if (GetMetadata().TryGetValue("pathParam", out var value))
{
var metadata = new PathParamMetadata();
ParseMetadata(value, ref metadata);
return metadata;
}
return null;
}
public QueryParamMetadata? GetQueryParamMetadata()
{
if (GetMetadata().TryGetValue("queryParam", out var value))
{
var metadata = new QueryParamMetadata();
ParseMetadata(value, ref metadata);
return metadata;
}
return null;
}
public HeaderMetadata? GetHeaderMetadata()
{
if (GetMetadata().TryGetValue("header", out var value))
{
var metadata = new HeaderMetadata();
ParseMetadata(value, ref metadata);
return metadata;
}
return null;
}
public SecurityMetadata? GetSecurityMetadata()
{
if (GetMetadata().TryGetValue("security", out var value))
{
var metadata = new SecurityMetadata();
ParseMetadata(value, ref metadata);
return metadata;
}
return null;
}
private Dictionary<string, string> GetMetadata()
{
if (metadata != null)
{
return metadata;
}
metadata = new Dictionary<string, string>();
var groups = Value.Split(" ");
foreach (var group in groups)
{
var parts = group.Split(":");
if (parts.Length != 2)
{
continue;
}
metadata.Add(parts[0], parts[1]);
}
return metadata;
}
private void ParseMetadata<T>(string raw, ref T metadata)
{
Dictionary<string, string> values = new Dictionary<string, string>();
var groups = raw.Split(",");
foreach (var group in groups)
{
var parts = group.Split("=");
var val = "";
if (parts.Length == 2)
{
val = parts[1];
}
values.Add(parts[0], val);
}
var props = typeof(T).GetProperties();
foreach (var prop in props)
{
if (
values.TryGetValue(
char.ToLower(prop.Name[0]) + prop.Name.Substring(1),
out var value
)
)
{
if (prop.PropertyType == typeof(bool) || prop.PropertyType == typeof(Boolean))
{
prop.SetValue(metadata, value == "true" || value == "");
}
else
{
prop.SetValue(metadata, value);
}
}
}
}
}
}

589
PlexAPI/Utils/URLBuilder.cs Normal file
View File

@@ -0,0 +1,589 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace PlexAPI.Utils
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Reflection;
internal static class URLBuilder
{
public static string Build(string baseUrl, string path, object? request)
{
var url = baseUrl;
if (url.EndsWith("/"))
{
url = url.Substring(0, url.Length - 1);
}
url += path;
var parameters = GetPathParameters(request);
url = ReplaceParameters(url, parameters);
var queryParams = SerializeQueryParams(TrySerializeQueryParams(request));
if (queryParams != "")
{
url += $"?{queryParams}";
}
return url;
}
public static string ReplaceParameters(string url, Dictionary<string, string> parameters)
{
foreach (var key in parameters.Keys)
{
url = url.Replace($"{{{key}}}", parameters[key]);
}
return url;
}
public static string SerializeQueryParams(Dictionary<string, List<string>> queryParams) {
var queries = new List<string>();
foreach (var key in queryParams.Keys)
{
foreach (var value in queryParams[key])
{
queries.Add($"{key}={value}");
}
}
return string.Join("&", queries);
}
private static Dictionary<string, string> GetPathParameters(object? request)
{
var parameters = new Dictionary<string, string>();
if (request == null)
{
return parameters;
}
var props = request.GetType().GetProperties();
foreach (var prop in props)
{
var val = prop.GetValue(request);
if (val == null)
{
continue;
}
if (prop.GetCustomAttribute<SpeakeasyMetadata>()?.GetRequestMetadata() != null)
{
continue;
}
var metadata = prop.GetCustomAttribute<SpeakeasyMetadata>()?.GetPathParamMetadata();
if (metadata == null)
{
continue;
}
if (metadata.Serialization != null)
{
switch (metadata.Serialization)
{
case "json":
parameters.Add(
metadata.Name ?? prop.Name,
WebUtility.UrlEncode(Utilities.SerializeJSON(val))
);
break;
default:
throw new Exception(
$"Unknown serialization type: {metadata.Serialization}"
);
}
}
else
{
switch (metadata.Style)
{
case "simple":
var simpleParams = SerializeSimplePathParams(
metadata.Name ?? prop.Name,
val,
metadata.Explode
);
foreach (var key in simpleParams.Keys)
{
parameters.Add(key, simpleParams[key]);
}
break;
default:
throw new Exception($"Unsupported path param style: {metadata.Style}");
}
}
}
return parameters;
}
private static Dictionary<string, List<string>> TrySerializeQueryParams(object? request)
{
var parameters = new Dictionary<string, List<string>>();
if (request == null)
{
return parameters;
}
var props = request.GetType().GetProperties();
foreach (var prop in props)
{
var val = prop.GetValue(request);
if (val == null)
{
continue;
}
if (prop.GetCustomAttribute<SpeakeasyMetadata>()?.GetRequestMetadata() != null)
{
continue;
}
var metadata = prop.GetCustomAttribute<SpeakeasyMetadata>()?.GetQueryParamMetadata();
if (metadata == null)
{
continue;
}
if (metadata.Serialization != null)
{
switch (metadata.Serialization)
{
case "json":
if (!parameters.ContainsKey(metadata.Name ?? prop.Name))
{
parameters.Add(metadata.Name ?? prop.Name, new List<string>());
}
parameters[metadata.Name ?? prop.Name].Add(
Utilities.SerializeJSON(val)
);
break;
default:
throw new Exception(
$"Unknown serialization type: {metadata.Serialization}"
);
}
}
else
{
switch (metadata.Style)
{
case "form":
var formParams = SerializeFormQueryParams(
metadata.Name ?? prop.Name,
val,
metadata.Explode,
","
);
foreach (var key in formParams.Keys)
{
if (!parameters.ContainsKey(key))
{
parameters.Add(key, new List<string>());
}
foreach (var v in formParams[key])
{
parameters[key].Add(v);
}
}
break;
case "deepObject":
var deepObjParams = SerializeDeepObjectQueryParams(
metadata.Name ?? prop.Name,
val
);
foreach (var key in deepObjParams.Keys)
{
if (!parameters.ContainsKey(key))
{
parameters.Add(key, new List<string>());
}
foreach (var v in deepObjParams[key])
{
parameters[key].Add(v);
}
}
break;
case "pipeDelimited":
var pipeParams = SerializeFormQueryParams(
metadata.Name ?? prop.Name,
val,
metadata.Explode,
"|"
);
foreach (var key in pipeParams.Keys)
{
if (!parameters.ContainsKey(key))
{
parameters.Add(key, new List<string>());
}
foreach (var v in pipeParams[key])
{
parameters[key].Add(v);
}
}
break;
default:
throw new Exception($"Unsupported query param style: {metadata.Style}");
}
}
}
return parameters;
}
private static Dictionary<string, string> SerializeSimplePathParams(
string parentName,
object value,
bool explode
)
{
var parameters = new Dictionary<string, string>();
if (Utilities.IsClass(value))
{
var vals = new List<string>();
var props = value.GetType().GetProperties();
foreach (var prop in props)
{
var val = prop.GetValue(value);
if (val == null)
{
continue;
}
var metadata = prop.GetCustomAttribute<SpeakeasyMetadata>()?.GetPathParamMetadata();
if (metadata == null)
{
continue;
}
if (explode)
{
vals.Add($"{metadata.Name}={Utilities.ToString(val)}");
}
else
{
vals.Add($"{metadata.Name},{Utilities.ToString(val)}");
}
}
parameters.Add(parentName, string.Join(",", vals));
}
else if (Utilities.IsDictionary(value))
{
var vals = new List<string>();
foreach (var key in ((IDictionary)value).Keys)
{
if (key == null)
{
continue;
}
var val = ((IDictionary)value)[key];
if (explode)
{
vals.Add($"{key}={Utilities.ToString(val)}");
}
else
{
vals.Add($"{key},{Utilities.ToString(val)}");
}
}
parameters.Add(parentName, string.Join(",", vals));
}
else if (Utilities.IsList(value))
{
var vals = new List<string>();
foreach (var val in (IEnumerable)value)
{
vals.Add(Utilities.ToString(val));
}
parameters.Add(parentName, string.Join(",", vals));
}
else
{
parameters.Add(parentName, Utilities.ToString(value));
}
return parameters;
}
private static Dictionary<string, List<string>> SerializeFormQueryParams(
string parentName,
object value,
bool explode,
string delimiter
)
{
var parameters = new Dictionary<string, List<string>>();
if (Utilities.IsClass(value) && !Utilities.IsDate(value))
{
var props = value.GetType().GetProperties();
var items = new List<string>();
foreach (var prop in props)
{
var val = prop.GetValue(value);
if (val == null)
{
continue;
}
var metadata = prop.GetCustomAttribute<SpeakeasyMetadata>()?.GetQueryParamMetadata();
if (metadata == null || metadata.Name == null)
{
continue;
}
if (explode)
{
if (!parameters.ContainsKey(metadata.Name))
{
parameters.Add(metadata.Name, new List<string>());
}
parameters[metadata.Name].Add(
Utilities.ToString(val)
);
}
else
{
items.Add(
$"{metadata.Name}{delimiter}{Utilities.ValueToString(val)}"
);
}
}
if (items.Count > 0)
{
if (!parameters.ContainsKey(parentName))
{
parameters.Add(parentName, new List<string>());
}
parameters[parentName].Add(string.Join(delimiter, items));
}
}
else if (Utilities.IsDictionary(value))
{
var items = new List<string>();
foreach (var k in ((IDictionary)value).Keys)
{
var key = k?.ToString();
if (key == null)
{
continue;
}
if (explode)
{
if (!parameters.ContainsKey(key))
{
parameters.Add(key, new List<string>());
}
parameters[key].Add(
Utilities.ValueToString(((IDictionary)value)[key])
);
}
else
{
items.Add(
$"{key}{delimiter}{Utilities.ValueToString(((IDictionary)value)[key])}"
);
}
}
if (items.Count > 0)
{
if (!parameters.ContainsKey(parentName))
{
parameters.Add(parentName, new List<string>());
}
parameters[parentName].Add(string.Join(delimiter, items));
}
}
else if (Utilities.IsList(value))
{
var values = new List<string>();
var items = new List<string>();
foreach (var item in (IList)value)
{
if (explode)
{
values.Add(Utilities.ValueToString(item));
}
else
{
items.Add(Utilities.ValueToString(item));
}
}
if (items.Count > 0)
{
values.Add(string.Join(delimiter, items));
}
foreach (var val in values)
{
if (!parameters.ContainsKey(parentName))
{
parameters.Add(parentName, new List<string>());
}
parameters[parentName].Add(val);
}
}
else
{
if (!parameters.ContainsKey(parentName))
{
parameters.Add(parentName, new List<string>());
}
parameters[parentName].Add(Utilities.ValueToString(value));
}
return parameters;
}
private static Dictionary<string, List<string>> SerializeDeepObjectQueryParams(
string parentName,
object value
)
{
var parameters = new Dictionary<string, List<string>>();
if (Utilities.IsClass(value))
{
var props = value.GetType().GetProperties();
foreach (var prop in props)
{
var val = prop.GetValue(value);
if (val == null)
{
continue;
}
var metadata = prop.GetCustomAttribute<SpeakeasyMetadata>()?.GetQueryParamMetadata();
if (metadata == null || metadata.Name == null)
{
continue;
}
var keyName = $"{parentName}[{metadata.Name}]";
if (val != null && Utilities.IsList(val))
{
foreach (var v in (IList)val)
{
if (!parameters.ContainsKey(keyName))
{
parameters.Add(keyName, new List<string>());
}
parameters[keyName].Add(
Utilities.ValueToString(v)
);
}
}
else
{
if (!parameters.ContainsKey(keyName))
{
parameters.Add(keyName, new List<string>());
}
parameters[keyName].Add(Utilities.ValueToString(val));
}
}
}
else if (Utilities.IsDictionary(value))
{
foreach (var key in ((IDictionary)value).Keys)
{
if (key == null)
{
continue;
}
var val = ((IDictionary)value)[key];
var keyName = $"{parentName}[{key}]";
if (val != null && Utilities.IsList(val))
{
foreach (var v in (IList)val)
{
if (!parameters.ContainsKey(keyName))
{
parameters.Add(keyName, new List<string>());
}
parameters[keyName].Add(
Utilities.ValueToString(v)
);
}
}
else
{
if (!parameters.ContainsKey(keyName))
{
parameters.Add(keyName, new List<string>());
}
parameters[keyName].Add(Utilities.ValueToString(val));
}
}
}
return parameters;
}
}
}

241
PlexAPI/Utils/Utilities.cs Normal file
View File

@@ -0,0 +1,241 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT.
//
// Changes to this file may cause incorrect behavior and will be lost when
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
namespace PlexAPI.Utils
{
using System;
using System.Linq;
using System.Net.Http.Headers;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using NodaTime;
using System.Collections;
public class Utilities
{
public static string SerializeJSON(object obj)
{
return JsonConvert.SerializeObject(
obj,
new JsonSerializerSettings()
{
NullValueHandling = NullValueHandling.Ignore,
Converters = new JsonConverter[]
{
new IsoDateTimeSerializer(),
new EnumSerializer()
}
}
);
}
public static bool IsDictionary(object? o)
{
if (o == null)
return false;
return o is IDictionary
&& o.GetType().IsGenericType
&& o.GetType().GetGenericTypeDefinition().IsAssignableFrom(typeof(Dictionary<,>));
}
public static bool IsList(object? o)
{
if (o == null)
return false;
return o is IList
&& o.GetType().IsGenericType
&& o.GetType().GetGenericTypeDefinition().IsAssignableFrom(typeof(List<>));
}
public static bool IsClass(object? o)
{
if (o == null)
return false;
return o.GetType().IsClass && (o.GetType().FullName ?? "").StartsWith("PlexAPI.Models");
}
// TODO: code review polyfilled for IsAssignableTo
public static bool IsSameOrSubclass(Type potentialBase, Type potentialDescendant)
{
return potentialDescendant.IsSubclassOf(potentialBase)
|| potentialDescendant == potentialBase;
}
public static bool IsString(object? obj)
{
if (obj != null)
{
var type = obj.GetType();
return IsSameOrSubclass(type, typeof(string));
}
else
{
return false;
}
}
public static bool IsPrimitive(object obj) => obj != null && obj.GetType().IsPrimitive;
public static bool IsEnum(object obj) => obj != null && obj.GetType().IsEnum;
public static bool IsDate(object obj) =>
obj != null && (obj.GetType() == typeof(DateTime) || obj.GetType() == typeof(LocalDate));
private static string StripSurroundingQuotes(string input)
{
Regex surroundingQuotesRegex = new Regex("^\"(.*)\"$");
var match = surroundingQuotesRegex.Match(input);
if(match.Groups.Values.Count() == 2)
{
return match.Groups.Values.Last().ToString();
}
return input;
}
public static string ValueToString(object? value)
{
if (value == null)
{
return "";
}
if (value.GetType() == typeof(DateTime))
{
return ((DateTime)value)
.ToUniversalTime()
.ToString("o", System.Globalization.CultureInfo.InvariantCulture);
}
else if (value.GetType() == typeof(LocalDate))
{
return ((LocalDate)value)
.ToDateTimeUnspecified()
.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture);
}
else if (value.GetType() == typeof(bool))
{
return (bool)value ? "true" : "false";
}
else if (IsEnum(value))
{
var method = Type.GetType(value.GetType().FullName + "Extension")
?.GetMethod("Value");
if (method == null)
{
return Convert.ChangeType(value, Enum.GetUnderlyingType(value.GetType()))?.ToString() ?? "";
}
return (string)(method.Invoke(null, new[] { value }) ?? "");
}
return value.ToString() ?? "";
}
public static string ToString(object? obj)
{
if (obj == null)
{
return "";
}
if (IsString(obj))
{
return obj.ToString() ?? "";
}
if (IsPrimitive(obj))
{
return JsonConvert.SerializeObject(obj);
}
if (IsEnum(obj))
{
var attributes = obj.GetType().GetMember(obj.ToString() ?? "").First().CustomAttributes;
if (attributes.Count() == 0)
{
return JsonConvert.SerializeObject(obj);
}
var args = attributes.First().ConstructorArguments;
if (args.Count() == 0)
{
return JsonConvert.SerializeObject(obj);
}
return StripSurroundingQuotes(args.First().ToString());
}
if (IsDate(obj))
{
return StripSurroundingQuotes(JsonConvert.SerializeObject(obj, new JsonSerializerSettings(){ NullValueHandling = NullValueHandling.Ignore, Converters = new JsonConverter[] { new IsoDateTimeSerializer(), new EnumSerializer() }}));
}
return JsonConvert.SerializeObject(obj, new JsonSerializerSettings(){ NullValueHandling = NullValueHandling.Ignore, Converters = new JsonConverter[] { new IsoDateTimeSerializer(), new EnumSerializer() }});
}
public static bool IsContentTypeMatch(string expected, string? actual)
{
if (actual == null)
{
return false;
}
if (expected == actual || expected == "*" || expected == "*/*")
{
return true;
}
try
{
var mediaType = MediaTypeHeaderValue.Parse(actual).MediaType ?? "";
if (expected == mediaType)
{
return true;
}
var parts = mediaType.Split('/');
if (parts.Length == 2)
{
if (parts[0] + "/*" == expected || "*/" + parts[1] == expected)
{
return true;
}
}
}
catch (Exception) { }
return false;
}
public static string PrefixBearer(string authHeaderValue)
{
if (authHeaderValue.StartsWith("bearer ", StringComparison.InvariantCultureIgnoreCase))
{
return authHeaderValue;
}
return $"Bearer {authHeaderValue}";
}
public static string RemoveSuffix(string inputString, string suffix)
{
if (!String.IsNullOrEmpty(suffix) && inputString.EndsWith(suffix))
{
return inputString.Remove(inputString.Length - suffix.Length, suffix.Length);
}
return inputString;
}
public static string TemplateUrl(string template, Dictionary<string, string> paramDict)
{
foreach(KeyValuePair<string, string> entry in paramDict)
{
template = template.Replace('{' + entry.Key + '}', entry.Value);
}
return template;
}
}
}