mirror of
https://github.com/LukeHagar/plexcsharp.git
synced 2025-12-08 04:20:54 +00:00
ci: regenerated with OpenAPI Doc 0.0.3, Speakeasy CLI 1.129.1
This commit is contained in:
50
PlexAPI/Utils/BigIntSerializer.cs
Normal file
50
PlexAPI/Utils/BigIntSerializer.cs
Normal 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
49
PlexAPI/Utils/DecimalSerializer.cs
Normal file
49
PlexAPI/Utils/DecimalSerializer.cs
Normal 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
67
PlexAPI/Utils/EnumSerializer.cs
Normal file
67
PlexAPI/Utils/EnumSerializer.cs
Normal 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
44
PlexAPI/Utils/FlexibleObjectDeserializer.cs
Normal file
44
PlexAPI/Utils/FlexibleObjectDeserializer.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
129
PlexAPI/Utils/HeaderSerializer.cs
Normal file
129
PlexAPI/Utils/HeaderSerializer.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
41
PlexAPI/Utils/IsoDateTimeSerializer.cs
Normal file
41
PlexAPI/Utils/IsoDateTimeSerializer.cs
Normal 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
502
PlexAPI/Utils/RequestBodySerializer.cs
Normal file
502
PlexAPI/Utils/RequestBodySerializer.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
227
PlexAPI/Utils/SecuritySerializer.cs
Normal file
227
PlexAPI/Utils/SecuritySerializer.cs
Normal 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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
96
PlexAPI/Utils/SpeakeasyHttpClient.cs
Normal file
96
PlexAPI/Utils/SpeakeasyHttpClient.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
243
PlexAPI/Utils/SpeakeasyMetadata.cs
Normal file
243
PlexAPI/Utils/SpeakeasyMetadata.cs
Normal 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
589
PlexAPI/Utils/URLBuilder.cs
Normal 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
241
PlexAPI/Utils/Utilities.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user