diff --git a/CloudConvert.API/CloudConvert.API.csproj b/CloudConvert.API/CloudConvert.API.csproj index fde5168..74b45a5 100644 --- a/CloudConvert.API/CloudConvert.API.csproj +++ b/CloudConvert.API/CloudConvert.API.csproj @@ -18,6 +18,8 @@ + + diff --git a/CloudConvert.API/CloudConvertAPI.cs b/CloudConvert.API/CloudConvertAPI.cs index b329c9a..f6287ba 100644 --- a/CloudConvert.API/CloudConvertAPI.cs +++ b/CloudConvert.API/CloudConvertAPI.cs @@ -5,290 +5,295 @@ using System.Net.Http; using System.Security.Cryptography; using System.Text; -using System.Threading.Tasks; using System.Text.Json; +using System.Threading; +using System.Threading.Tasks; +using CloudConvert.API.Models; using CloudConvert.API.Models.JobModels; using CloudConvert.API.Models.TaskModels; -using CloudConvert.API.Models; -using System.Threading; -namespace CloudConvert.API +namespace CloudConvert.API; + +public interface ICloudConvertAPI { - public interface ICloudConvertAPI + #region Jobs + Task> GetAllJobsAsync(JobListFilter jobFilter, CancellationToken cancellationToken = default); + Task> CreateJobAsync(JobCreateRequest request, CancellationToken cancellationToken = default); + Task> GetJobAsync(string id, CancellationToken cancellationToken = default); + Task> WaitJobAsync(string id, CancellationToken cancellationToken = default); + Task DeleteJobAsync(string id, CancellationToken cancellationToken = default); + #endregion + + #region Tasks + Task> GetAllTasksAsync(TaskListFilter jobFilter, CancellationToken cancellationToken = default); + Task> CreateTaskAsync(string operation, T request, CancellationToken cancellationToken = default); + Task> GetTaskAsync(string id, string include = null, CancellationToken cancellationToken = default); + Task> WaitTaskAsync(string id, CancellationToken cancellationToken = default); + Task DeleteTaskAsync(string id, CancellationToken cancellationToken = default); + #endregion + + Task UploadAsync(string url, byte[] file, string fileName, object parameters, CancellationToken cancellationToken = default); + Task UploadAsync(string url, Stream file, string fileName, object parameters, CancellationToken cancellationToken = default); + bool ValidateWebhookSignatures(string payloadString, string signature, string signingSecret); + string CreateSignedUrl(string baseUrl, string signingSecret, JobCreateRequest job, string cacheKey = null); +} + +public class CloudConvertAPI : ICloudConvertAPI +{ + readonly string _apiUrl; + readonly string _apiSyncUrl; + + readonly RestHelper _restHelper; + readonly string _api_key = "Bearer "; + private const string SandboxUrlApi = "https://api.sandbox.cloudconvert.com/v2"; + private const string PublicUrlApi = "https://api.cloudconvert.com/v2"; + private const string SandboxUrlSyncApi = "https://sync.api.sandbox.cloudconvert.com/v2"; + private const string PublicUrlSyncApi = "https://sync.api.cloudconvert.com/v2"; + static readonly char[] base64Padding = { '=' }; + + internal CloudConvertAPI(RestHelper restHelper, string api_key, bool isSandbox = false) { - #region Jobs - Task> GetAllJobsAsync(JobListFilter jobFilter, CancellationToken cancellationToken = default); - Task> CreateJobAsync(JobCreateRequest request, CancellationToken cancellationToken = default); - Task> GetJobAsync(string id, CancellationToken cancellationToken = default); - Task> WaitJobAsync(string id, CancellationToken cancellationToken = default); - Task DeleteJobAsync(string id, CancellationToken cancellationToken = default); - #endregion - - #region Tasks - Task> GetAllTasksAsync(TaskListFilter jobFilter, CancellationToken cancellationToken = default); - Task> CreateTaskAsync(string operation, T request, CancellationToken cancellationToken = default); - Task> GetTaskAsync(string id, string include = null, CancellationToken cancellationToken = default); - Task> WaitTaskAsync(string id, CancellationToken cancellationToken = default); - Task DeleteTaskAsync(string id, CancellationToken cancellationToken = default); - #endregion - - Task UploadAsync(string url, byte[] file, string fileName, object parameters, CancellationToken cancellationToken = default); - Task UploadAsync(string url, Stream file, string fileName, object parameters, CancellationToken cancellationToken = default); - bool ValidateWebhookSignatures(string payloadString, string signature, string signingSecret); - string CreateSignedUrl(string baseUrl, string signingSecret, JobCreateRequest job, string cacheKey = null); + _apiUrl = isSandbox ? SandboxUrlApi : PublicUrlApi; + _apiSyncUrl = isSandbox ? SandboxUrlSyncApi : PublicUrlSyncApi; + _api_key = $"Bearer {api_key}"; + _restHelper = restHelper; } - public class CloudConvertAPI : ICloudConvertAPI + public CloudConvertAPI(string api_key, bool isSandbox = false) + : this(new RestHelper(), api_key, isSandbox) { - readonly string _apiUrl; - readonly string _apiSyncUrl; - - readonly RestHelper _restHelper; - readonly string _api_key = "Bearer "; - const string sandboxUrlApi = "https://api.sandbox.cloudconvert.com/v2"; - const string publicUrlApi = "https://api.cloudconvert.com/v2"; - const string sandboxUrlSyncApi = "https://sync.api.sandbox.cloudconvert.com/v2"; - const string publicUrlSyncApi = "https://sync.api.cloudconvert.com/v2"; - static readonly char[] base64Padding = { '=' }; - - internal CloudConvertAPI(RestHelper restHelper, string api_key, bool isSandbox = false) - { - _apiUrl = isSandbox ? sandboxUrlApi : publicUrlApi; - _apiSyncUrl = isSandbox ? sandboxUrlSyncApi : publicUrlSyncApi; - _api_key += api_key; - _restHelper = restHelper; - } + } - public CloudConvertAPI(string api_key, bool isSandbox = false) - : this(new RestHelper(), api_key, isSandbox) - { - } + public CloudConvertAPI(string url, string api_key) + { + _apiUrl = url; + _api_key = $"Bearer {api_key}"; + _restHelper = new RestHelper(); + } - public CloudConvertAPI(string url, string api_key) - { - _apiUrl = url; - _api_key += api_key; - _restHelper = new RestHelper(); - } + private HttpRequestMessage GetRequest(string endpoint, HttpMethod method, object model = null) + { + var request = new HttpRequestMessage { RequestUri = new Uri(endpoint), Method = method }; - private HttpRequestMessage GetRequest(string endpoint, HttpMethod method, object model = null) + if (model is not null) { - var request = new HttpRequestMessage { RequestUri = new Uri(endpoint), Method = method }; + var content = new StringContent(JsonSerializer.Serialize(model, DefaultJsonSerializerOptions.SerializerOptions), Encoding.UTF8, "application/json"); + request.Content = content; + } - if (model != null) - { - var content = new StringContent(JsonSerializer.Serialize(model, DefaultJsonSerializerOptions.SerializerOptions), Encoding.UTF8, "application/json"); - request.Content = content; - } + request.Headers.Add("Authorization", _api_key); + request.Headers.Add("User-Agent", "cloudconvert-dotnet/v" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString() + " (https://github.com/cloudconvert/cloudconvert-dotnet)"); - request.Headers.Add("Authorization", _api_key); - request.Headers.Add("User-Agent", "cloudconvert-dotnet/v" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString() + " (https://github.com/cloudconvert/cloudconvert-dotnet)"); + return request; + } - return request; - } + private HttpRequestMessage GetMultipartFormDataRequest(string endpoint, HttpMethod method, HttpContent fileContent, string fileName, Dictionary parameters = null) + { + var content = new MultipartFormDataContent(); + var request = new HttpRequestMessage { RequestUri = new Uri(endpoint), Method = method, }; - private HttpRequestMessage GetMultipartFormDataRequest(string endpoint, HttpMethod method, HttpContent fileContent, string fileName, Dictionary parameters = null) + if (parameters is not null) { - var content = new MultipartFormDataContent(); - var request = new HttpRequestMessage { RequestUri = new Uri(endpoint), Method = method, }; - - if (parameters != null) + foreach (var param in parameters) { - foreach (var param in parameters) - { - content.Add(new StringContent(param.Value), param.Key); - } + content.Add(new StringContent(param.Value), param.Key); } + } - fileContent.Headers.Add("Content-Disposition", $"form-data; name=\"file\"; filename=\"{new string(Encoding.UTF8.GetBytes(fileName).Select(b => (char)b).ToArray())}\""); - content.Add(fileContent); + fileContent.Headers.Add("Content-Disposition", $"form-data; name=\"file\"; filename=\"{new string(Encoding.UTF8.GetBytes(fileName).Select(b => (char)b).ToArray())}\""); + content.Add(fileContent); - request.Content = content; + request.Content = content; - return request; - } + return request; + } - #region Jobs - - /// - /// List all jobs. Requires the task.read scope. - /// - /// - /// - /// - /// The list of jobs. You can find details about the job model response in the documentation about the show jobs endpoint. - /// - public Task> GetAllJobsAsync(JobListFilter jobFilter, CancellationToken cancellationToken = default) - => _restHelper.RequestAsync>(GetRequest($"{_apiUrl}/jobs?filter[status]={jobFilter.Status}&filter[tag]={jobFilter.Tag}&include={jobFilter.Include}&per_page={jobFilter.PerPage}&page={jobFilter.Page}", HttpMethod.Get), cancellationToken); - - /// - /// Create a job with one ore more tasks. Requires the task.write scope. - /// - /// - /// - /// - /// The created job. You can find details about the job model response in the documentation about the show jobs endpoint. - /// - public Task> CreateJobAsync(JobCreateRequest model, CancellationToken cancellationToken = default) - => _restHelper.RequestAsync>(GetRequest($"{_apiUrl}/jobs", HttpMethod.Post, model), cancellationToken); - - /// - /// Show a job. Requires the task.read scope. - /// - /// - /// - /// - public Task> GetJobAsync(string id, CancellationToken cancellationToken = default) - => _restHelper.RequestAsync>(GetRequest($"{_apiUrl}/jobs/{id}", HttpMethod.Get), cancellationToken); - - /// - /// Wait until the job status is finished or error. This makes the request block until the job has been completed. Requires the task.read scope. - /// - /// We do not recommend using this for long running jobs (e.g. video encodings). - /// Your system might automatically time out requests if there is not data transferred for a longer time. - /// In general, please avoid to block your application until a CloudConvert job completes. - /// There might be cases in which we need to queue your job which results in longer processing times than usual. - /// Using an asynchronous approach with webhooks is beneficial in such cases. - /// - /// - /// - /// - /// The finished or failed job, including tasks. You can find details about the job model response in the documentation about the show job endpoint. - /// - public Task> WaitJobAsync(string id, CancellationToken cancellationToken = default) - => _restHelper.RequestAsync>(GetRequest($"{_apiSyncUrl}/jobs/{id}", HttpMethod.Get), cancellationToken); - - /// - /// Delete a job, including all tasks and data. Requires the task.write scope. - /// Jobs are deleted automatically 24 hours after they have ended. - /// - /// - /// - /// - /// An empty response with HTTP Code 204. - /// - public Task DeleteJobAsync(string id, CancellationToken cancellationToken = default) - => _restHelper.RequestAsync(GetRequest($"{_apiUrl}/jobs/{id}", HttpMethod.Delete), cancellationToken); - - #endregion - - #region Tasks - - /// - /// List all tasks with their status, payload and result. Requires the task.read scope. - /// - /// - /// - /// - /// The list of tasks. You can find details about the task model response in the documentation about the show tasks endpoint. - /// - public Task> GetAllTasksAsync(TaskListFilter taskFilter, CancellationToken cancellationToken = default) - => _restHelper.RequestAsync>(GetRequest($"{_apiUrl}/tasks?filter[job_id]={taskFilter.JobId}&filter[status]={taskFilter.Status}&filter[operation]={taskFilter.Operation}&include={taskFilter.Include}&per_page={taskFilter.PerPage}&page={taskFilter.Page}", HttpMethod.Get), cancellationToken); - - /// - /// Create task. - /// - /// - /// - /// - /// - /// The created task. You can find details about the task model response in the documentation about the show tasks endpoint. - /// - public Task> CreateTaskAsync(string operation, T model, CancellationToken cancellationToken = default) - => _restHelper.RequestAsync>(GetRequest($"{_apiUrl}/{operation}", HttpMethod.Post, model), cancellationToken); - - /// - /// Show a task. Requires the task.read scope. - /// - /// - /// - /// - /// - public Task> GetTaskAsync(string id, string include = null, CancellationToken cancellationToken = default) - => _restHelper.RequestAsync>(GetRequest($"{_apiUrl}/tasks/{id}?include={include}", HttpMethod.Get), cancellationToken); - - /// - /// Wait until the task status is finished or error. This makes the request block until the task has been completed. Requires the task.read scope. - /// - /// We do not recommend using this for long running jobs (e.g. video encodings). - /// Your system might automatically time out requests if there is not data transferred for a longer time. - /// In general, please avoid to block your application until a CloudConvert job completes. - /// There might be cases in which we need to queue your task which results in longer processing times than usual. - /// Using an asynchronous approach with webhooks is beneficial in such cases. - /// - /// - /// - /// - /// The finished or failed task. You can find details about the task model response in the documentation about the show tasks endpoint. - /// - public Task> WaitTaskAsync(string id, CancellationToken cancellationToken = default) - => _restHelper.RequestAsync>(GetRequest($"{_apiSyncUrl}/tasks/{id}", HttpMethod.Get), cancellationToken); - - /// - /// Delete a task, including all data. Requires the task.write scope. - /// Tasks are deleted automatically 24 hours after they have ended. - /// - /// - /// - /// - /// An empty response with HTTP Code 204. - /// - public Task DeleteTaskAsync(string id, CancellationToken cancellationToken = default) - => _restHelper.RequestAsync(GetRequest($"{_apiUrl}/tasks/{id}", HttpMethod.Delete), cancellationToken); - - #endregion - - public Task UploadAsync(string url, byte[] file, string fileName, object parameters, CancellationToken cancellationToken) - => _restHelper.RequestAsync(GetMultipartFormDataRequest(url, HttpMethod.Post, new ByteArrayContent(file), fileName, GetParameters(parameters)), cancellationToken); - - public Task UploadAsync(string url, Stream stream, string fileName, object parameters, CancellationToken cancellationToken = default) - => _restHelper.RequestAsync(GetMultipartFormDataRequest(url, HttpMethod.Post, new StreamContent(stream), fileName, GetParameters(parameters)), cancellationToken); - - public string CreateSignedUrl(string baseUrl, string signingSecret, JobCreateRequest job, string cacheKey = null) - { - string url = baseUrl; - string jobJson = JsonSerializer.Serialize(job, DefaultJsonSerializerOptions.SerializerOptions); - string base64Job = System.Convert.ToBase64String(Encoding.ASCII.GetBytes(jobJson)).TrimEnd(base64Padding).Replace('+', '-').Replace('/', '_'); + #region Jobs + + /// + /// List all jobs. Requires the task.read scope. + /// + /// + /// + /// + /// The list of jobs. You can find details about the job model response in the documentation about the show jobs endpoint. + /// + public Task> GetAllJobsAsync(JobListFilter jobFilter, CancellationToken cancellationToken = default) + => _restHelper.RequestAsync>(GetRequest($"{_apiUrl}/jobs?filter[status]={jobFilter.Status}&filter[tag]={jobFilter.Tag}&include={jobFilter.Include}&per_page={jobFilter.PerPage}&page={jobFilter.Page}", HttpMethod.Get), cancellationToken); + + /// + /// Create a job with one ore more tasks. Requires the task.write scope. + /// + /// + /// + /// + /// The created job. You can find details about the job model response in the documentation about the show jobs endpoint. + /// + public Task> CreateJobAsync(JobCreateRequest model, CancellationToken cancellationToken = default) + => _restHelper.RequestAsync>(GetRequest($"{_apiUrl}/jobs", HttpMethod.Post, model), cancellationToken); + + /// + /// Show a job. Requires the task.read scope. + /// + /// + /// + /// + public Task> GetJobAsync(string id, CancellationToken cancellationToken = default) + => _restHelper.RequestAsync>(GetRequest($"{_apiUrl}/jobs/{id}", HttpMethod.Get), cancellationToken); + + /// + /// Wait until the job status is finished or error. This makes the request block until the job has been completed. Requires the task.read scope. + /// + /// We do not recommend using this for long running jobs (e.g. video encodings). + /// Your system might automatically time out requests if there is not data transferred for a longer time. + /// In general, please avoid to block your application until a CloudConvert job completes. + /// There might be cases in which we need to queue your job which results in longer processing times than usual. + /// Using an asynchronous approach with webhooks is beneficial in such cases. + /// + /// + /// + /// + /// The finished or failed job, including tasks. You can find details about the job model response in the documentation about the show job endpoint. + /// + public Task> WaitJobAsync(string id, CancellationToken cancellationToken = default) + => _restHelper.RequestAsync>(GetRequest($"{_apiSyncUrl}/jobs/{id}", HttpMethod.Get), cancellationToken); + + /// + /// Delete a job, including all tasks and data. Requires the task.write scope. + /// Jobs are deleted automatically 24 hours after they have ended. + /// + /// + /// + /// + /// An empty response with HTTP Code 204. + /// + public Task DeleteJobAsync(string id, CancellationToken cancellationToken = default) + => _restHelper.RequestAsync(GetRequest($"{_apiUrl}/jobs/{id}", HttpMethod.Delete), cancellationToken); + + #endregion + + #region Tasks + + /// + /// List all tasks with their status, payload and result. Requires the task.read scope. + /// + /// + /// + /// + /// The list of tasks. You can find details about the task model response in the documentation about the show tasks endpoint. + /// + public Task> GetAllTasksAsync(TaskListFilter taskFilter, CancellationToken cancellationToken = default) + => _restHelper.RequestAsync>(GetRequest($"{_apiUrl}/tasks?filter[job_id]={taskFilter.JobId}&filter[status]={taskFilter.Status}&filter[operation]={taskFilter.Operation}&include={taskFilter.Include}&per_page={taskFilter.PerPage}&page={taskFilter.Page}", HttpMethod.Get), cancellationToken); + + /// + /// Create task. + /// + /// + /// + /// + /// + /// The created task. You can find details about the task model response in the documentation about the show tasks endpoint. + /// + public Task> CreateTaskAsync(string operation, T model, CancellationToken cancellationToken = default) + => _restHelper.RequestAsync>(GetRequest($"{_apiUrl}/{operation}", HttpMethod.Post, model), cancellationToken); + + /// + /// Show a task. Requires the task.read scope. + /// + /// + /// + /// + /// + public Task> GetTaskAsync(string id, string include = null, CancellationToken cancellationToken = default) + => _restHelper.RequestAsync>(GetRequest($"{_apiUrl}/tasks/{id}?include={include}", HttpMethod.Get), cancellationToken); + + /// + /// Wait until the task status is finished or error. This makes the request block until the task has been completed. Requires the task.read scope. + /// + /// We do not recommend using this for long running jobs (e.g. video encodings). + /// Your system might automatically time out requests if there is not data transferred for a longer time. + /// In general, please avoid to block your application until a CloudConvert job completes. + /// There might be cases in which we need to queue your task which results in longer processing times than usual. + /// Using an asynchronous approach with webhooks is beneficial in such cases. + /// + /// + /// + /// + /// The finished or failed task. You can find details about the task model response in the documentation about the show tasks endpoint. + /// + public Task> WaitTaskAsync(string id, CancellationToken cancellationToken = default) + => _restHelper.RequestAsync>(GetRequest($"{_apiSyncUrl}/tasks/{id}", HttpMethod.Get), cancellationToken); + + /// + /// Delete a task, including all data. Requires the task.write scope. + /// Tasks are deleted automatically 24 hours after they have ended. + /// + /// + /// + /// + /// An empty response with HTTP Code 204. + /// + public Task DeleteTaskAsync(string id, CancellationToken cancellationToken = default) + => _restHelper.RequestAsync(GetRequest($"{_apiUrl}/tasks/{id}", HttpMethod.Delete), cancellationToken); + + #endregion + + public Task UploadAsync(string url, byte[] file, string fileName, object parameters, CancellationToken cancellationToken) + => _restHelper.RequestAsync(GetMultipartFormDataRequest(url, HttpMethod.Post, new ByteArrayContent(file), fileName, GetParameters(parameters)), cancellationToken); + + public Task UploadAsync(string url, Stream stream, string fileName, object parameters, CancellationToken cancellationToken = default) + => _restHelper.RequestAsync(GetMultipartFormDataRequest(url, HttpMethod.Post, new StreamContent(stream), fileName, GetParameters(parameters)), cancellationToken); + + public string CreateSignedUrl(string baseUrl, string signingSecret, JobCreateRequest job, string cacheKey = null) + { + var jobJson = JsonSerializer.Serialize(job, DefaultJsonSerializerOptions.SerializerOptions); + var base64Job = Convert.ToBase64String(Encoding.ASCII.GetBytes(jobJson)) + .TrimEnd(base64Padding) + .Replace('+', '-') + .Replace('/', '_'); - url += "?job=" + base64Job; + var builder = new StringBuilder(baseUrl) + .Append("?job=") + .Append(base64Job); - if(cacheKey != null) { - url += "&cache_key=" + cacheKey; - } + if (cacheKey is not null) + { + builder.Append("&cache_key=").Append(cacheKey); + } - string signature = HashHMAC(signingSecret, url); + var urlWithoutSignature = builder.ToString(); + var signature = HashHMAC(signingSecret, urlWithoutSignature); - url += "&s=" + signature; + return builder.Append("&s=").Append(signature).ToString(); + } - return url; - } + public bool ValidateWebhookSignatures(string payloadString, string signature, string signingSecret) + { + string hashHMAC = HashHMAC(signingSecret, payloadString); - public bool ValidateWebhookSignatures(string payloadString, string signature, string signingSecret) - { - string hashHMAC = HashHMAC(signingSecret, payloadString); + return hashHMAC == signature; + } - return hashHMAC == signature; - } + private static string HashHMAC(string key, string message) + { + using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key)); + var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(message)); + return BitConverter.ToString(hash).Replace("-", "").ToLower(); + } - private string HashHMAC(string key, string message) - { - byte[] hash = new HMACSHA256(Encoding.UTF8.GetBytes(key)).ComputeHash(new UTF8Encoding().GetBytes(message)); - return BitConverter.ToString(hash).Replace("-", "").ToLower(); - } - private Dictionary GetParameters(object parameters) - { - var dictionaryParameters = new Dictionary(); + private Dictionary GetParameters(object parameters) + { + var dictionaryParameters = new Dictionary(); - if (parameters is JsonElement jsonElement) + if (parameters is JsonElement jsonElement) + { + foreach (JsonProperty prop in jsonElement.EnumerateObject()) { - foreach (JsonProperty prop in jsonElement.EnumerateObject()) - { - dictionaryParameters[prop.Name] = prop.Value.GetString(); - } + dictionaryParameters[prop.Name] = prop.Value.GetString(); } - - return dictionaryParameters; } + + return dictionaryParameters; } } diff --git a/CloudConvert.API/DefaultJsonSerializerOptions.cs b/CloudConvert.API/DefaultJsonSerializerOptions.cs index acd337c..a829d3b 100644 --- a/CloudConvert.API/DefaultJsonSerializerOptions.cs +++ b/CloudConvert.API/DefaultJsonSerializerOptions.cs @@ -1,14 +1,13 @@ -using System.Text.Json.Serialization; using System.Text.Json; +using System.Text.Json.Serialization; + +namespace CloudConvert.API; -namespace CloudConvert.API +public class DefaultJsonSerializerOptions { - public class DefaultJsonSerializerOptions + public static readonly JsonSerializerOptions SerializerOptions = new() { - public static readonly JsonSerializerOptions SerializerOptions = new() - { - Converters = { new JsonStringEnumConverter() }, - DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull - }; - } + Converters = { new JsonStringEnumConverter() }, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull + }; } diff --git a/CloudConvert.API/Extensions/CloudConvertOptions.cs b/CloudConvert.API/Extensions/CloudConvertOptions.cs new file mode 100644 index 0000000..c051f39 --- /dev/null +++ b/CloudConvert.API/Extensions/CloudConvertOptions.cs @@ -0,0 +1,19 @@ +namespace CloudConvert.API.Extensions; + +/// +/// Configuration options for the CloudConvert API client. +/// +public class CloudConvertOptions +{ + /// + /// The CloudConvert API key used to authenticate requests. + /// + public string ApiKey { get; set; } + + /// + /// Whether to use the CloudConvert sandbox environment. + /// Use true during development and testing to avoid consuming real credits. + /// Defaults to false. + /// + public bool IsSandbox { get; set; } = false; +} diff --git a/CloudConvert.API/Extensions/ServiceCollectionExtensions.cs b/CloudConvert.API/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..396c809 --- /dev/null +++ b/CloudConvert.API/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,58 @@ +using System; +using System.Net.Http; +using System.Threading; +using Microsoft.Extensions.DependencyInjection; + +namespace CloudConvert.API.Extensions; + +/// +/// Extension methods for registering CloudConvert API services with the dependency injection container. +/// +public static class ServiceCollectionExtensions +{ + /// + /// Registers the CloudConvert API client and its dependencies with the dependency injection container. + /// + /// The to add the services to. + /// A delegate to configure the . + /// The so that calls can be chained. + /// Thrown when is not provided. + /// + /// Register the CloudConvert API client in your DI container: + /// + /// services.AddCloudConvertAPI(options => + /// { + /// options.ApiKey = "your_api_key"; + /// options.IsSandbox = false; + /// }); + /// + /// + public static IServiceCollection AddCloudConvertAPI( + this IServiceCollection services, + Action configure) + { + var options = new CloudConvertOptions(); + configure(options); + + if (string.IsNullOrWhiteSpace(options.ApiKey)) + { + throw new ArgumentException("ApiKey is required", nameof(configure)); + } + + services.AddHttpClient(client => + { + client.Timeout = Timeout.InfiniteTimeSpan; + }) + .ConfigurePrimaryHttpMessageHandler(() => new WebApiHandler(false)); + + services.AddSingleton(sp => + { + var httpClient = sp.GetRequiredService() + .CreateClient(nameof(CloudConvertAPI)); + + return new CloudConvertAPI(new RestHelper(httpClient), options.ApiKey, options.IsSandbox); + }); + + return services; + } +} diff --git a/CloudConvert.API/Extensions/StringExtensions.cs b/CloudConvert.API/Extensions/StringExtensions.cs index be950bf..670ead4 100644 --- a/CloudConvert.API/Extensions/StringExtensions.cs +++ b/CloudConvert.API/Extensions/StringExtensions.cs @@ -15,7 +15,7 @@ public static string TrimLengthWithEllipsis([NotNull] this string str, int maxLe return str; } - return str.Substring(0, maxLength) + "..."; + return string.Concat(str.AsSpan(0, maxLength), "..."); } public static string GetEnumDescription(this TEnum source) where TEnum : struct, Enum diff --git a/CloudConvert.API/Models/Enums/CaptureWebsiteWaitUntil.cs b/CloudConvert.API/Models/Enums/CaptureWebsiteWaitUntil.cs index 2f04acb..1f7b2ed 100644 --- a/CloudConvert.API/Models/Enums/CaptureWebsiteWaitUntil.cs +++ b/CloudConvert.API/Models/Enums/CaptureWebsiteWaitUntil.cs @@ -1,10 +1,9 @@ -namespace CloudConvert.API.Models.Enums -{ - public enum CaptureWebsiteWaitUntil - { - domcontentloaded, - load, - networkidle0, - networkidle2 - }; -} +namespace CloudConvert.API.Models.Enums; + +public enum CaptureWebsiteWaitUntil +{ + domcontentloaded, + load, + networkidle0, + networkidle2 +}; diff --git a/CloudConvert.API/Models/Enums/ExportS3Acl.cs b/CloudConvert.API/Models/Enums/ExportS3Acl.cs index a92eaca..fcdb9d7 100644 --- a/CloudConvert.API/Models/Enums/ExportS3Acl.cs +++ b/CloudConvert.API/Models/Enums/ExportS3Acl.cs @@ -1,26 +1,24 @@ using System.ComponentModel; -namespace CloudConvert.API.Models.Enums -{ - public enum ExportS3Acl - { - [Description("private")] - Private, +namespace CloudConvert.API.Models.Enums; - [Description("public-read")] - PublicRead, +public enum ExportS3Acl +{ + [Description("private")] + Private, - [Description("public-read-write")] - PublicReadWrite, + [Description("public-read")] + PublicRead, - [Description("authenticated-read")] - AuthenticatedRead, + [Description("public-read-write")] + PublicReadWrite, - [Description("bucket-owner-read")] - BucketOwnerRead, + [Description("authenticated-read")] + AuthenticatedRead, - [Description("bucket-owner-full-control")] - BucketOwnerFullControl - }; + [Description("bucket-owner-read")] + BucketOwnerRead, -} + [Description("bucket-owner-full-control")] + BucketOwnerFullControl +}; diff --git a/CloudConvert.API/Models/Enums/JobStatus.cs b/CloudConvert.API/Models/Enums/JobStatus.cs index 82fa843..dee4e8c 100644 --- a/CloudConvert.API/Models/Enums/JobStatus.cs +++ b/CloudConvert.API/Models/Enums/JobStatus.cs @@ -1,9 +1,8 @@ -namespace CloudConvert.API.Models.Enums +namespace CloudConvert.API.Models.Enums; + +public enum JobStatus { - public enum JobStatus - { - processing, - finished, - error - } + processing, + finished, + error } diff --git a/CloudConvert.API/Models/Enums/MergeOutputFormat.cs b/CloudConvert.API/Models/Enums/MergeOutputFormat.cs index c7a2e61..0b24f56 100644 --- a/CloudConvert.API/Models/Enums/MergeOutputFormat.cs +++ b/CloudConvert.API/Models/Enums/MergeOutputFormat.cs @@ -1,7 +1,6 @@ -namespace CloudConvert.API.Models.Enums -{ - public enum MergeOutputFormat - { - pdf - }; -} +namespace CloudConvert.API.Models.Enums; + +public enum MergeOutputFormat +{ + pdf +}; diff --git a/CloudConvert.API/Models/Enums/OptimizeInputFormat.cs b/CloudConvert.API/Models/Enums/OptimizeInputFormat.cs index 3a5a6f0..3cbbab9 100644 --- a/CloudConvert.API/Models/Enums/OptimizeInputFormat.cs +++ b/CloudConvert.API/Models/Enums/OptimizeInputFormat.cs @@ -1,9 +1,8 @@ -namespace CloudConvert.API.Models.Enums +namespace CloudConvert.API.Models.Enums; + +public enum OptimizeInputFormat { - public enum OptimizeInputFormat - { - jpg, - pdf, - png - }; -} + jpg, + pdf, + png +}; diff --git a/CloudConvert.API/Models/Enums/OptimizeProfile.cs b/CloudConvert.API/Models/Enums/OptimizeProfile.cs index d25a599..86d51c1 100644 --- a/CloudConvert.API/Models/Enums/OptimizeProfile.cs +++ b/CloudConvert.API/Models/Enums/OptimizeProfile.cs @@ -1,11 +1,10 @@ -namespace CloudConvert.API.Models.Enums +namespace CloudConvert.API.Models.Enums; + +public enum OptimizeProfile { - public enum OptimizeProfile - { - archive, - max, - mrc, - print, - web - }; -} + archive, + max, + mrc, + print, + web +}; diff --git a/CloudConvert.API/Models/Enums/TaskStatus.cs b/CloudConvert.API/Models/Enums/TaskStatus.cs index dce5f26..1967398 100644 --- a/CloudConvert.API/Models/Enums/TaskStatus.cs +++ b/CloudConvert.API/Models/Enums/TaskStatus.cs @@ -1,10 +1,9 @@ -namespace CloudConvert.API.Models.Enums -{ - public enum TaskStatus - { - waiting, - processing, - finished, - error - } +namespace CloudConvert.API.Models.Enums; + +public enum TaskStatus + { + waiting, + processing, + finished, + error } diff --git a/CloudConvert.API/Models/Enums/ThumbnailFit.cs b/CloudConvert.API/Models/Enums/ThumbnailFit.cs index 0813119..caceda3 100644 --- a/CloudConvert.API/Models/Enums/ThumbnailFit.cs +++ b/CloudConvert.API/Models/Enums/ThumbnailFit.cs @@ -1,9 +1,8 @@ -namespace CloudConvert.API.Models.Enums -{ - public enum ThumbnailFit - { - max, - crop, - scale - }; -} +namespace CloudConvert.API.Models.Enums; + +public enum ThumbnailFit +{ + max, + crop, + scale +}; diff --git a/CloudConvert.API/Models/Enums/ThumbnailOutputFormat.cs b/CloudConvert.API/Models/Enums/ThumbnailOutputFormat.cs index 782eb64..c92194a 100644 --- a/CloudConvert.API/Models/Enums/ThumbnailOutputFormat.cs +++ b/CloudConvert.API/Models/Enums/ThumbnailOutputFormat.cs @@ -1,8 +1,7 @@ -namespace CloudConvert.API.Models.Enums -{ - public enum ThumbnailOutputFormat - { - jpg, - png - }; -} +namespace CloudConvert.API.Models.Enums; + +public enum ThumbnailOutputFormat +{ + jpg, + png +}; diff --git a/CloudConvert.API/Models/ErrorResponse.cs b/CloudConvert.API/Models/ErrorResponse.cs index a3739b5..bcb3393 100644 --- a/CloudConvert.API/Models/ErrorResponse.cs +++ b/CloudConvert.API/Models/ErrorResponse.cs @@ -1,16 +1,15 @@ using System.Text.Json.Serialization; -namespace CloudConvert.API.Models +namespace CloudConvert.API.Models; + +public partial class ErrorResponse { - public partial class ErrorResponse - { - [JsonPropertyName("message")] - public string Message { get; set; } + [JsonPropertyName("message")] + public string Message { get; set; } - [JsonPropertyName("code")] - public string Code { get; set; } + [JsonPropertyName("code")] + public string Code { get; set; } - [JsonPropertyName("errors")] - public object Errors { get; set; } - } + [JsonPropertyName("errors")] + public object Errors { get; set; } } diff --git a/CloudConvert.API/Models/ExportOperations/ExportAzureBlobCreateRequest.cs b/CloudConvert.API/Models/ExportOperations/ExportAzureBlobCreateRequest.cs index 816e802..e73bbee 100644 --- a/CloudConvert.API/Models/ExportOperations/ExportAzureBlobCreateRequest.cs +++ b/CloudConvert.API/Models/ExportOperations/ExportAzureBlobCreateRequest.cs @@ -1,35 +1,34 @@ using System.Text.Json.Serialization; -namespace CloudConvert.API.Models.ExportOperations +namespace CloudConvert.API.Models.ExportOperations; + +public class ExportAzureBlobCreateRequest { - public class ExportAzureBlobCreateRequest - { - [JsonPropertyName("operation")] - public string Operation { get; } = "export/azure/blob"; + [JsonPropertyName("operation")] + public string Operation { get; } = "export/azure/blob"; - /// - /// The input task name(s) for this task. - /// input: string | string[]; - /// - [JsonPropertyName("input")] - public object Input { get; set; } + /// + /// The input task name(s) for this task. + /// input: string | string[]; + /// + [JsonPropertyName("input")] + public object Input { get; set; } - [JsonPropertyName("storage_account")] - public string Storage_Account { get; set; } + [JsonPropertyName("storage_account")] + public string Storage_Account { get; set; } - [JsonPropertyName("storage_access_key")] - public string Storage_Access_Key { get; set; } + [JsonPropertyName("storage_access_key")] + public string Storage_Access_Key { get; set; } - [JsonPropertyName("sas_token")] - public string Sas_Token { get; set; } + [JsonPropertyName("sas_token")] + public string Sas_Token { get; set; } - [JsonPropertyName("container")] - public string Container { get; set; } + [JsonPropertyName("container")] + public string Container { get; set; } - [JsonPropertyName("blob")] - public string Blob { get; set; } + [JsonPropertyName("blob")] + public string Blob { get; set; } - [JsonPropertyName("blob_prefix")] - public string Blob_Prefix { get; set; } - } + [JsonPropertyName("blob_prefix")] + public string Blob_Prefix { get; set; } } diff --git a/CloudConvert.API/Models/ExportOperations/ExportGoogleCloudStorageCreateRequest.cs b/CloudConvert.API/Models/ExportOperations/ExportGoogleCloudStorageCreateRequest.cs index 04b0796..950e124 100644 --- a/CloudConvert.API/Models/ExportOperations/ExportGoogleCloudStorageCreateRequest.cs +++ b/CloudConvert.API/Models/ExportOperations/ExportGoogleCloudStorageCreateRequest.cs @@ -1,35 +1,34 @@ using System.Text.Json.Serialization; -namespace CloudConvert.API.Models.ExportOperations +namespace CloudConvert.API.Models.ExportOperations; + +public class ExportGoogleCloudStorageCreateRequest { - public class ExportGoogleCloudStorageCreateRequest - { - [JsonPropertyName("operation")] - public string Operation { get; } = "export/google-cloud-storage"; + [JsonPropertyName("operation")] + public string Operation { get; } = "export/google-cloud-storage"; - /// - /// The input task name(s) for this task. - /// input: string | string[]; - /// - [JsonPropertyName("input")] - public object Input { get; set; } + /// + /// The input task name(s) for this task. + /// input: string | string[]; + /// + [JsonPropertyName("input")] + public object Input { get; set; } - [JsonPropertyName("project_id")] - public string ProjectId { get; set; } + [JsonPropertyName("project_id")] + public string ProjectId { get; set; } - [JsonPropertyName("bucket")] - public string Bucket { get; set; } + [JsonPropertyName("bucket")] + public string Bucket { get; set; } - [JsonPropertyName("client_email")] - public string Client_Email { get; set; } + [JsonPropertyName("client_email")] + public string Client_Email { get; set; } - [JsonPropertyName("private_key")] - public string Private_Key { get; set; } + [JsonPropertyName("private_key")] + public string Private_Key { get; set; } - [JsonPropertyName("file")] - public string File { get; set; } + [JsonPropertyName("file")] + public string File { get; set; } - [JsonPropertyName("file_prefix")] - public string File_Prefix { get; set; } - } + [JsonPropertyName("file_prefix")] + public string File_Prefix { get; set; } } diff --git a/CloudConvert.API/Models/ExportOperations/ExportOpenStackCreateRequest.cs b/CloudConvert.API/Models/ExportOperations/ExportOpenStackCreateRequest.cs index a004e44..efd0ce4 100644 --- a/CloudConvert.API/Models/ExportOperations/ExportOpenStackCreateRequest.cs +++ b/CloudConvert.API/Models/ExportOperations/ExportOpenStackCreateRequest.cs @@ -1,38 +1,37 @@ using System.Text.Json.Serialization; -namespace CloudConvert.API.Models.ExportOperations +namespace CloudConvert.API.Models.ExportOperations; + +public class ExportOpenStackCreateRequest { - public class ExportOpenStackCreateRequest - { - [JsonPropertyName("operation")] - public string Operation { get; } = "export/openstack"; + [JsonPropertyName("operation")] + public string Operation { get; } = "export/openstack"; - /// - /// The input task name(s) for this task. - /// input: string | string[]; - /// - [JsonPropertyName("input")] - public object Input { get; set; } + /// + /// The input task name(s) for this task. + /// input: string | string[]; + /// + [JsonPropertyName("input")] + public object Input { get; set; } - [JsonPropertyName("auth_url")] - public string Auth_Url { get; set; } + [JsonPropertyName("auth_url")] + public string Auth_Url { get; set; } - [JsonPropertyName("username")] - public string Username { get; set; } + [JsonPropertyName("username")] + public string Username { get; set; } - [JsonPropertyName("password")] - public string Password { get; set; } + [JsonPropertyName("password")] + public string Password { get; set; } - [JsonPropertyName("region")] - public string Region { get; set; } + [JsonPropertyName("region")] + public string Region { get; set; } - [JsonPropertyName("container")] - public string Container { get; set; } + [JsonPropertyName("container")] + public string Container { get; set; } - [JsonPropertyName("file")] - public string File { get; set; } + [JsonPropertyName("file")] + public string File { get; set; } - [JsonPropertyName("file_prefix")] - public string FilePrefix { get; set; } - } + [JsonPropertyName("file_prefix")] + public string FilePrefix { get; set; } } diff --git a/CloudConvert.API/Models/ExportOperations/ExportS3CreateRequest.cs b/CloudConvert.API/Models/ExportOperations/ExportS3CreateRequest.cs index 63194f1..38d4903 100644 --- a/CloudConvert.API/Models/ExportOperations/ExportS3CreateRequest.cs +++ b/CloudConvert.API/Models/ExportOperations/ExportS3CreateRequest.cs @@ -2,87 +2,86 @@ using System.Text.Json.Serialization; using CloudConvert.API.Models.Enums; -namespace CloudConvert.API.Models.ExportOperations +namespace CloudConvert.API.Models.ExportOperations; + +public class ExportS3CreateRequest { - public class ExportS3CreateRequest - { - [JsonPropertyName("operation")] - public string Operation { get; } = "export/s3"; + [JsonPropertyName("operation")] + public string Operation { get; } = "export/s3"; - /// - /// The input task name(s) for this task. - /// input: string | string[]; - /// - [JsonPropertyName("input")] - public object Input { get; set; } + /// + /// The input task name(s) for this task. + /// input: string | string[]; + /// + [JsonPropertyName("input")] + public object Input { get; set; } - /// - /// The Amazon S3 bucket where to store the file(s). - /// - [JsonPropertyName("bucket")] - public string Bucket { get; set; } + /// + /// The Amazon S3 bucket where to store the file(s). + /// + [JsonPropertyName("bucket")] + public string Bucket { get; set; } - /// - /// Specify the Amazon S3 endpoint, e.g. us-west-2 or eu-west-1. - /// - [JsonPropertyName("region")] - public string Region { get; set; } + /// + /// Specify the Amazon S3 endpoint, e.g. us-west-2 or eu-west-1. + /// + [JsonPropertyName("region")] + public string Region { get; set; } - [JsonPropertyName("endpoint")] - public string Endpoint { get; set; } + [JsonPropertyName("endpoint")] + public string Endpoint { get; set; } - /// - /// S3 key for storing the file (the filename in the bucket, including path). - /// - [JsonPropertyName("key")] - public string Key { get; set; } + /// + /// S3 key for storing the file (the filename in the bucket, including path). + /// + [JsonPropertyName("key")] + public string Key { get; set; } - /// - /// Alternatively to using key, you can specify a key prefix for exporting files. - /// - [JsonPropertyName("key_prefix")] - public string Key_Prefix { get; set; } + /// + /// Alternatively to using key, you can specify a key prefix for exporting files. + /// + [JsonPropertyName("key_prefix")] + public string Key_Prefix { get; set; } - /// - /// The Amazon S3 access key id. - /// - [JsonPropertyName("access_key_id")] - public string Access_Key_Id { get; set; } + /// + /// The Amazon S3 access key id. + /// + [JsonPropertyName("access_key_id")] + public string Access_Key_Id { get; set; } - /// - /// The Amazon S3 secret access key. - /// - [JsonPropertyName("secret_access_key")] - public string Secret_Access_Key { get; set; } + /// + /// The Amazon S3 secret access key. + /// + [JsonPropertyName("secret_access_key")] + public string Secret_Access_Key { get; set; } - /// - /// Auth using temporary credentials. - /// - [JsonPropertyName("session_token")] - public string Session_Token { get; set; } + /// + /// Auth using temporary credentials. + /// + [JsonPropertyName("session_token")] + public string Session_Token { get; set; } - /// - /// S3 ACL for storing the files. - /// - [JsonPropertyName("acl")] - public ExportS3Acl? Acl { get; set; } + /// + /// S3 ACL for storing the files. + /// + [JsonPropertyName("acl")] + public ExportS3Acl? Acl { get; set; } - /// - /// S3 CacheControl header to specify the lifetime of the file. - /// - [JsonPropertyName("cache_control")] - public string Cache_Control { get; set; } + /// + /// S3 CacheControl header to specify the lifetime of the file. + /// + [JsonPropertyName("cache_control")] + public string Cache_Control { get; set; } - /// - /// Object of additional S3 meta data. - /// - [JsonPropertyName("metadata")] - public Dictionary Metadata { get; set; } + /// + /// Object of additional S3 meta data. + /// + [JsonPropertyName("metadata")] + public Dictionary Metadata { get; set; } - /// - /// Enable the Server-side encryption algorithm used when storing this object in S3. - /// - [JsonPropertyName("server_side_encryption")] - public string Server_Side_Encryption { get; set; } - } + /// + /// Enable the Server-side encryption algorithm used when storing this object in S3. + /// + [JsonPropertyName("server_side_encryption")] + public string Server_Side_Encryption { get; set; } } diff --git a/CloudConvert.API/Models/ExportOperations/ExportSFTPCreateRequest.cs b/CloudConvert.API/Models/ExportOperations/ExportSFTPCreateRequest.cs index 0378756..6b2668f 100644 --- a/CloudConvert.API/Models/ExportOperations/ExportSFTPCreateRequest.cs +++ b/CloudConvert.API/Models/ExportOperations/ExportSFTPCreateRequest.cs @@ -1,38 +1,37 @@ using System.Text.Json.Serialization; -namespace CloudConvert.API.Models.ExportOperations +namespace CloudConvert.API.Models.ExportOperations; + +public class ExportSFTPCreateRequest { - public class ExportSFTPCreateRequest - { - [JsonPropertyName("operation")] - public string Operation { get; } = "export/sftp"; + [JsonPropertyName("operation")] + public string Operation { get; } = "export/sftp"; - /// - /// The input task name(s) for this task. - /// input: string | string[]; - /// - [JsonPropertyName("input")] - public object Input { get; set; } + /// + /// The input task name(s) for this task. + /// input: string | string[]; + /// + [JsonPropertyName("input")] + public object Input { get; set; } - [JsonPropertyName("host")] - public string Host { get; set; } + [JsonPropertyName("host")] + public string Host { get; set; } - [JsonPropertyName("port")] - public string Port { get; set; } + [JsonPropertyName("port")] + public string Port { get; set; } - [JsonPropertyName("username")] - public string Username { get; set; } + [JsonPropertyName("username")] + public string Username { get; set; } - [JsonPropertyName("password")] - public string Password { get; set; } + [JsonPropertyName("password")] + public string Password { get; set; } - [JsonPropertyName("private_key")] - public string Private_Key { get; set; } + [JsonPropertyName("private_key")] + public string Private_Key { get; set; } - [JsonPropertyName("file")] - public string File { get; set; } + [JsonPropertyName("file")] + public string File { get; set; } - [JsonPropertyName("path")] - public string Path { get; set; } - } + [JsonPropertyName("path")] + public string Path { get; set; } } diff --git a/CloudConvert.API/Models/ExportOperations/ExportUrlCreateRequest.cs b/CloudConvert.API/Models/ExportOperations/ExportUrlCreateRequest.cs index 79a58d5..e8c3d1e 100644 --- a/CloudConvert.API/Models/ExportOperations/ExportUrlCreateRequest.cs +++ b/CloudConvert.API/Models/ExportOperations/ExportUrlCreateRequest.cs @@ -1,32 +1,31 @@ using System.Text.Json.Serialization; -namespace CloudConvert.API.Models.ExportOperations +namespace CloudConvert.API.Models.ExportOperations; + +public class ExportUrlCreateRequest { - public class ExportUrlCreateRequest - { - [JsonPropertyName("operation")] - public string Operation { get; } = "export/url"; + [JsonPropertyName("operation")] + public string Operation { get; } = "export/url"; - /// - /// The input task name(s) for this task. - /// input: string | string[]; - /// - [JsonPropertyName("input")] - public object Input { get; set; } + /// + /// The input task name(s) for this task. + /// input: string | string[]; + /// + [JsonPropertyName("input")] + public object Input { get; set; } - /// - /// This option makes the export URLs return the Content-Disposition inline header, which tells browser to display the file instead of downloading it. - /// - [JsonPropertyName("inline")] - public bool? Inline { get; set; } + /// + /// This option makes the export URLs return the Content-Disposition inline header, which tells browser to display the file instead of downloading it. + /// + [JsonPropertyName("inline")] + public bool? Inline { get; set; } - [JsonPropertyName("inline_additional")] - public bool? Inline_Additional { get; set; } + [JsonPropertyName("inline_additional")] + public bool? Inline_Additional { get; set; } - /// - /// By default, multiple files will create multiple export URLs. When enabling this option, one export URL with a ZIP file will be created. - /// - [JsonPropertyName("archive_multiple_files")] - public bool? Archive_Multiple_Files { get; set; } - } + /// + /// By default, multiple files will create multiple export URLs. When enabling this option, one export URL with a ZIP file will be created. + /// + [JsonPropertyName("archive_multiple_files")] + public bool? Archive_Multiple_Files { get; set; } } diff --git a/CloudConvert.API/Models/ImportOperations/ImportAzureBlobCreateRequest.cs b/CloudConvert.API/Models/ImportOperations/ImportAzureBlobCreateRequest.cs index 9cbebe2..0202694 100644 --- a/CloudConvert.API/Models/ImportOperations/ImportAzureBlobCreateRequest.cs +++ b/CloudConvert.API/Models/ImportOperations/ImportAzureBlobCreateRequest.cs @@ -1,31 +1,30 @@ using System.Text.Json.Serialization; -namespace CloudConvert.API.Models.ImportOperations +namespace CloudConvert.API.Models.ImportOperations; + +public class ImportAzureBlobCreateRequest { - public class ImportAzureBlobCreateRequest - { - [JsonPropertyName("operation")] - public string Operation { get; } = "import/azure/blob"; + [JsonPropertyName("operation")] + public string Operation { get; } = "import/azure/blob"; - [JsonPropertyName("storage_account")] - public string Storage_Account { get; set; } + [JsonPropertyName("storage_account")] + public string Storage_Account { get; set; } - [JsonPropertyName("storage_access_key")] - public string Storage_Access_Key { get; set; } + [JsonPropertyName("storage_access_key")] + public string Storage_Access_Key { get; set; } - [JsonPropertyName("sas_token")] - public string Sas_Token { get; set; } + [JsonPropertyName("sas_token")] + public string Sas_Token { get; set; } - [JsonPropertyName("container")] - public string Container { get; set; } + [JsonPropertyName("container")] + public string Container { get; set; } - [JsonPropertyName("blob")] - public string Blob { get; set; } + [JsonPropertyName("blob")] + public string Blob { get; set; } - [JsonPropertyName("blob_prefix")] - public string Blob_Prefix { get; set; } + [JsonPropertyName("blob_prefix")] + public string Blob_Prefix { get; set; } - [JsonPropertyName("filename")] - public string Filename { get; set; } - } + [JsonPropertyName("filename")] + public string Filename { get; set; } } diff --git a/CloudConvert.API/Models/ImportOperations/ImportGoogleCloudStorageCreateRequest.cs b/CloudConvert.API/Models/ImportOperations/ImportGoogleCloudStorageCreateRequest.cs index d51867d..cf52498 100644 --- a/CloudConvert.API/Models/ImportOperations/ImportGoogleCloudStorageCreateRequest.cs +++ b/CloudConvert.API/Models/ImportOperations/ImportGoogleCloudStorageCreateRequest.cs @@ -1,31 +1,30 @@ using System.Text.Json.Serialization; -namespace CloudConvert.API.Models.ImportOperations +namespace CloudConvert.API.Models.ImportOperations; + +public class ImportGoogleCloudStorageCreateRequest { - public class ImportGoogleCloudStorageCreateRequest - { - [JsonPropertyName("operation")] - public string Operation { get; } = "import/google-cloud-storage"; + [JsonPropertyName("operation")] + public string Operation { get; } = "import/google-cloud-storage"; - [JsonPropertyName("project_id")] - public string Project_Id { get; set; } + [JsonPropertyName("project_id")] + public string Project_Id { get; set; } - [JsonPropertyName("bucket")] - public string Bucket { get; set; } + [JsonPropertyName("bucket")] + public string Bucket { get; set; } - [JsonPropertyName("client_email")] - public string Client_Email { get; set; } + [JsonPropertyName("client_email")] + public string Client_Email { get; set; } - [JsonPropertyName("private_key")] - public string Private_Key { get; set; } + [JsonPropertyName("private_key")] + public string Private_Key { get; set; } - [JsonPropertyName("file")] - public string File { get; set; } + [JsonPropertyName("file")] + public string File { get; set; } - [JsonPropertyName("file_prefix")] - public string File_Prefix { get; set; } + [JsonPropertyName("file_prefix")] + public string File_Prefix { get; set; } - [JsonPropertyName("filename")] - public string Filename { get; set; } - } + [JsonPropertyName("filename")] + public string Filename { get; set; } } diff --git a/CloudConvert.API/Models/ImportOperations/ImportOpenStackCreateRequest.cs b/CloudConvert.API/Models/ImportOperations/ImportOpenStackCreateRequest.cs index 224b250..b6988ef 100644 --- a/CloudConvert.API/Models/ImportOperations/ImportOpenStackCreateRequest.cs +++ b/CloudConvert.API/Models/ImportOperations/ImportOpenStackCreateRequest.cs @@ -1,34 +1,33 @@ using System.Text.Json.Serialization; -namespace CloudConvert.API.Models.ImportOperations +namespace CloudConvert.API.Models.ImportOperations; + +public class ImportOpenStackCreateRequest { - public class ImportOpenStackCreateRequest - { - [JsonPropertyName("operation")] - public string Operation { get; } = "import/openstack"; + [JsonPropertyName("operation")] + public string Operation { get; } = "import/openstack"; - [JsonPropertyName("auth_url")] - public string Auth_Url { get; set; } + [JsonPropertyName("auth_url")] + public string Auth_Url { get; set; } - [JsonPropertyName("username")] - public string Username { get; set; } + [JsonPropertyName("username")] + public string Username { get; set; } - [JsonPropertyName("password")] - public string Password { get; set; } + [JsonPropertyName("password")] + public string Password { get; set; } - [JsonPropertyName("region")] - public string Region { get; set; } + [JsonPropertyName("region")] + public string Region { get; set; } - [JsonPropertyName("container")] - public string Container { get; set; } + [JsonPropertyName("container")] + public string Container { get; set; } - [JsonPropertyName("file")] - public string File { get; set; } + [JsonPropertyName("file")] + public string File { get; set; } - [JsonPropertyName("file_prefix")] - public string File_Prefix { get; set; } + [JsonPropertyName("file_prefix")] + public string File_Prefix { get; set; } - [JsonPropertyName("filename")] - public string Filename { get; set; } - } + [JsonPropertyName("filename")] + public string Filename { get; set; } } diff --git a/CloudConvert.API/Models/ImportOperations/ImportS3CreateRequest.cs b/CloudConvert.API/Models/ImportOperations/ImportS3CreateRequest.cs index 23b7d43..b20f7a9 100644 --- a/CloudConvert.API/Models/ImportOperations/ImportS3CreateRequest.cs +++ b/CloudConvert.API/Models/ImportOperations/ImportS3CreateRequest.cs @@ -1,58 +1,57 @@ using System.Text.Json.Serialization; -namespace CloudConvert.API.Models.ImportOperations +namespace CloudConvert.API.Models.ImportOperations; + +public class ImportS3CreateRequest { - public class ImportS3CreateRequest - { - [JsonPropertyName("operation")] - public string Operation { get; } = "import/s3"; - - /// - /// The Amazon S3 bucket where to download the file. - /// - [JsonPropertyName("bucket")] - public string Bucket { get; set; } - - /// - /// Specify the Amazon S3 endpoint, e.g. us-west-2 or eu-west-1. - /// - [JsonPropertyName("region")] - public string Region { get; set; } - - [JsonPropertyName("endpoint")] - public string Endpoint { get; set; } - - /// - /// S3 key of the input file (the filename in the bucket, including path). - /// - [JsonPropertyName("key")] - public string Key { get; set; } - - /// - /// Alternatively to using key, you can specify a key prefix for importing multiple files. - /// - [JsonPropertyName("key_prefix")] - public string Key_Prefix { get; set; } - - /// - /// The Amazon S3 access key id. - /// - [JsonPropertyName("access_key_id")] - public string Access_Key_Id { get; set; } - - /// - /// The Amazon S3 secret access key. - /// - [JsonPropertyName("secret_access_key")] - public string Secret_Access_Key { get; set; } - - /// - /// Auth using temporary credentials. - /// - [JsonPropertyName("session_token")] - public string Session_Token { get; set; } - - [JsonPropertyName("filename")] - public string Filename { get; set; } - } + [JsonPropertyName("operation")] + public string Operation { get; } = "import/s3"; + + /// + /// The Amazon S3 bucket where to download the file. + /// + [JsonPropertyName("bucket")] + public string Bucket { get; set; } + + /// + /// Specify the Amazon S3 endpoint, e.g. us-west-2 or eu-west-1. + /// + [JsonPropertyName("region")] + public string Region { get; set; } + + [JsonPropertyName("endpoint")] + public string Endpoint { get; set; } + + /// + /// S3 key of the input file (the filename in the bucket, including path). + /// + [JsonPropertyName("key")] + public string Key { get; set; } + + /// + /// Alternatively to using key, you can specify a key prefix for importing multiple files. + /// + [JsonPropertyName("key_prefix")] + public string Key_Prefix { get; set; } + + /// + /// The Amazon S3 access key id. + /// + [JsonPropertyName("access_key_id")] + public string Access_Key_Id { get; set; } + + /// + /// The Amazon S3 secret access key. + /// + [JsonPropertyName("secret_access_key")] + public string Secret_Access_Key { get; set; } + + /// + /// Auth using temporary credentials. + /// + [JsonPropertyName("session_token")] + public string Session_Token { get; set; } + + [JsonPropertyName("filename")] + public string Filename { get; set; } } diff --git a/CloudConvert.API/Models/ImportOperations/ImportSFTPCreateRequest.cs b/CloudConvert.API/Models/ImportOperations/ImportSFTPCreateRequest.cs index 6facd7e..53de5d5 100644 --- a/CloudConvert.API/Models/ImportOperations/ImportSFTPCreateRequest.cs +++ b/CloudConvert.API/Models/ImportOperations/ImportSFTPCreateRequest.cs @@ -1,34 +1,33 @@ using System.Text.Json.Serialization; -namespace CloudConvert.API.Models.ImportOperations +namespace CloudConvert.API.Models.ImportOperations; + +public class ImportSFTPCreateRequest { - public class ImportSFTPCreateRequest - { - [JsonPropertyName("operation")] - public string Operation { get; } = "import/sftp"; + [JsonPropertyName("operation")] + public string Operation { get; } = "import/sftp"; - [JsonPropertyName("host")] - public string Host { get; set; } + [JsonPropertyName("host")] + public string Host { get; set; } - [JsonPropertyName("port")] - public string Port { get; set; } + [JsonPropertyName("port")] + public string Port { get; set; } - [JsonPropertyName("username")] - public string Username { get; set; } + [JsonPropertyName("username")] + public string Username { get; set; } - [JsonPropertyName("password")] - public string Password { get; set; } + [JsonPropertyName("password")] + public string Password { get; set; } - [JsonPropertyName("private_key")] - public string Private_Key { get; set; } + [JsonPropertyName("private_key")] + public string Private_Key { get; set; } - [JsonPropertyName("file")] - public string File { get; set; } + [JsonPropertyName("file")] + public string File { get; set; } - [JsonPropertyName("path")] - public string Path { get; set; } + [JsonPropertyName("path")] + public string Path { get; set; } - [JsonPropertyName("filename")] - public string Filename { get; set; } - } + [JsonPropertyName("filename")] + public string Filename { get; set; } } diff --git a/CloudConvert.API/Models/ImportOperations/ImportUploadCreateRequest.cs b/CloudConvert.API/Models/ImportOperations/ImportUploadCreateRequest.cs index d9dcfc9..c49e7ba 100644 --- a/CloudConvert.API/Models/ImportOperations/ImportUploadCreateRequest.cs +++ b/CloudConvert.API/Models/ImportOperations/ImportUploadCreateRequest.cs @@ -1,16 +1,15 @@ using System.Text.Json.Serialization; -namespace CloudConvert.API.Models.ImportOperations +namespace CloudConvert.API.Models.ImportOperations; + +public class ImportUploadCreateRequest { - public class ImportUploadCreateRequest - { - [JsonPropertyName("operation")] - public string Operation { get; } = "import/upload"; + [JsonPropertyName("operation")] + public string Operation { get; } = "import/upload"; - /// - /// Redirect user to this URL after upload - /// - [JsonPropertyName("redirect")] - public string Redirect { get; set; } - } + /// + /// Redirect user to this URL after upload + /// + [JsonPropertyName("redirect")] + public string Redirect { get; set; } } diff --git a/CloudConvert.API/Models/ImportOperations/ImportUrlCreateRequest.cs b/CloudConvert.API/Models/ImportOperations/ImportUrlCreateRequest.cs index abae899..32e4c30 100644 --- a/CloudConvert.API/Models/ImportOperations/ImportUrlCreateRequest.cs +++ b/CloudConvert.API/Models/ImportOperations/ImportUrlCreateRequest.cs @@ -1,23 +1,22 @@ using System.Collections.Generic; using System.Text.Json.Serialization; -namespace CloudConvert.API.Models.ImportOperations +namespace CloudConvert.API.Models.ImportOperations; + +public class ImportUrlCreateRequest { - public class ImportUrlCreateRequest - { - [JsonPropertyName("operation")] - public string Operation { get; } = "import/url"; + [JsonPropertyName("operation")] + public string Operation { get; } = "import/url"; - [JsonPropertyName("url")] - public string Url { get; set; } + [JsonPropertyName("url")] + public string Url { get; set; } - /// - /// The filename of the input file, including extension. If none provided we will try to detect the filename from the URL. - /// - [JsonPropertyName("filename")] - public string Filename { get; set; } + /// + /// The filename of the input file, including extension. If none provided we will try to detect the filename from the URL. + /// + [JsonPropertyName("filename")] + public string Filename { get; set; } - [JsonPropertyName("headers")] - public Dictionary Headers { get; set; } - } + [JsonPropertyName("headers")] + public Dictionary Headers { get; set; } } diff --git a/CloudConvert.API/Models/JobModels/JobCreateRequest.cs b/CloudConvert.API/Models/JobModels/JobCreateRequest.cs index 1ae3276..8ecfefe 100644 --- a/CloudConvert.API/Models/JobModels/JobCreateRequest.cs +++ b/CloudConvert.API/Models/JobModels/JobCreateRequest.cs @@ -1,24 +1,23 @@ using System.Text.Json.Serialization; -namespace CloudConvert.API.Models.JobModels +namespace CloudConvert.API.Models.JobModels; + +public partial class JobCreateRequest { - public partial class JobCreateRequest - { - /// - /// The example on the right consists of three tasks: import-my-file, convert-my-file and export-my-file. - /// You can name these tasks however you want, but only alphanumeric characters, - and _ are allowed in the task names. - /// - /// Each task has an operation, which is the endpoint for creating the task (for example: convert, import/s3 or export/s3). - /// The other parameters are the same as for creating the task using their direct endpoint. - /// The input parameter allows it to directly reference the name of another task, created with the same job request. - /// - [JsonPropertyName("tasks")] - public object Tasks { get; set; } + /// + /// The example on the right consists of three tasks: import-my-file, convert-my-file and export-my-file. + /// You can name these tasks however you want, but only alphanumeric characters, - and _ are allowed in the task names. + /// + /// Each task has an operation, which is the endpoint for creating the task (for example: convert, import/s3 or export/s3). + /// The other parameters are the same as for creating the task using their direct endpoint. + /// The input parameter allows it to directly reference the name of another task, created with the same job request. + /// + [JsonPropertyName("tasks")] + public object Tasks { get; set; } - /// - /// An arbitrary string to identify the job. Does not have any effect and can be used to associate the job with an ID in your application. - /// - [JsonPropertyName("tag")] - public string Tag { get; set; } - } + /// + /// An arbitrary string to identify the job. Does not have any effect and can be used to associate the job with an ID in your application. + /// + [JsonPropertyName("tag")] + public string Tag { get; set; } } diff --git a/CloudConvert.API/Models/JobModels/JobListFilter.cs b/CloudConvert.API/Models/JobModels/JobListFilter.cs index 3ee09b4..b453657 100644 --- a/CloudConvert.API/Models/JobModels/JobListFilter.cs +++ b/CloudConvert.API/Models/JobModels/JobListFilter.cs @@ -1,41 +1,40 @@ using CloudConvert.API.Models.Enums; -namespace CloudConvert.API.Models.JobModels +namespace CloudConvert.API.Models.JobModels; + +public class JobListFilter { - public class JobListFilter + public JobListFilter() { - public JobListFilter() - { - Status = null; - Tag = null; - Include = null; - PerPage = null; - Page = null; - } + Status = null; + Tag = null; + Include = null; + PerPage = null; + Page = null; + } - /// - /// The result will be filtered to include only jobs with a specific status (processing, finished or error). - /// - public JobStatus? Status { get; set; } + /// + /// The result will be filtered to include only jobs with a specific status (processing, finished or error). + /// + public JobStatus? Status { get; set; } - /// - /// The result will be filtered to include only jobs with a tag. - /// - public string Tag { get; set; } + /// + /// The result will be filtered to include only jobs with a tag. + /// + public string Tag { get; set; } - /// - /// Include tasks in the result. - /// - public string Include { get; set; } + /// + /// Include tasks in the result. + /// + public string Include { get; set; } - /// - /// Number of tasks per page, defaults to 100. - /// - public int? PerPage { get; set; } + /// + /// Number of tasks per page, defaults to 100. + /// + public int? PerPage { get; set; } - /// - /// The result page to show. - /// - public int? Page { get; set; } - } + /// + /// The result page to show. + /// + public int? Page { get; set; } } diff --git a/CloudConvert.API/Models/JobModels/JobResponse.cs b/CloudConvert.API/Models/JobModels/JobResponse.cs index 471c9fc..ccb2b11 100644 --- a/CloudConvert.API/Models/JobModels/JobResponse.cs +++ b/CloudConvert.API/Models/JobModels/JobResponse.cs @@ -3,53 +3,52 @@ using System.Text.Json.Serialization; using CloudConvert.API.Models.TaskModels; -namespace CloudConvert.API.Models.JobModels +namespace CloudConvert.API.Models.JobModels; + +public partial class JobResponse { - public partial class JobResponse - { - /// - /// The ID of the job. - /// - [JsonPropertyName("id")] - public string Id { get; set; } - - /// - /// Your given tag of the job. - /// - [JsonPropertyName("tag")] - public string Tag { get; set; } - - /// - /// The status of the job. Is one of processing, finished or error. - /// - [JsonPropertyName("status")] - public string Status { get; set; } - - /// - /// ISO8601 timestamp of the creation of the job. - /// - [JsonPropertyName("created_at")] - public DateTimeOffset? Created_At { get; set; } - - /// - /// ISO8601 timestamp when the job started processing. - /// - [JsonPropertyName("started_at")] - public DateTimeOffset? Started_At { get; set; } - - /// - /// ISO8601 timestamp when the job finished or failed. - /// - [JsonPropertyName("ended_at")] - public DateTimeOffset? Ended_At { get; set; } - - /// - /// List of tasks that are part of the job. You can find details about the task model response in the documentation about the show tasks endpoint. - /// - [JsonPropertyName("tasks")] - public List Tasks { get; set; } - - [JsonPropertyName("links")] - public ResponseLinks Links { get; set; } - } + /// + /// The ID of the job. + /// + [JsonPropertyName("id")] + public string Id { get; set; } + + /// + /// Your given tag of the job. + /// + [JsonPropertyName("tag")] + public string Tag { get; set; } + + /// + /// The status of the job. Is one of processing, finished or error. + /// + [JsonPropertyName("status")] + public string Status { get; set; } + + /// + /// ISO8601 timestamp of the creation of the job. + /// + [JsonPropertyName("created_at")] + public DateTimeOffset? Created_At { get; set; } + + /// + /// ISO8601 timestamp when the job started processing. + /// + [JsonPropertyName("started_at")] + public DateTimeOffset? Started_At { get; set; } + + /// + /// ISO8601 timestamp when the job finished or failed. + /// + [JsonPropertyName("ended_at")] + public DateTimeOffset? Ended_At { get; set; } + + /// + /// List of tasks that are part of the job. You can find details about the task model response in the documentation about the show tasks endpoint. + /// + [JsonPropertyName("tasks")] + public List Tasks { get; set; } + + [JsonPropertyName("links")] + public ResponseLinks Links { get; set; } } diff --git a/CloudConvert.API/Models/ListResponse.cs b/CloudConvert.API/Models/ListResponse.cs index 25bcc04..7d6b6d8 100644 --- a/CloudConvert.API/Models/ListResponse.cs +++ b/CloudConvert.API/Models/ListResponse.cs @@ -1,17 +1,16 @@ using System.Collections.Generic; using System.Text.Json.Serialization; -namespace CloudConvert.API.Models +namespace CloudConvert.API.Models; + +public partial class ListResponse { - public partial class ListResponse - { - [JsonPropertyName("data")] - public List Data { get; set; } + [JsonPropertyName("data")] + public List Data { get; set; } - [JsonPropertyName("links")] - public ListResponseLinks Links { get; set; } + [JsonPropertyName("links")] + public ListResponseLinks Links { get; set; } - [JsonPropertyName("meta")] - public ListResponseMeta Meta { get; set; } - } + [JsonPropertyName("meta")] + public ListResponseMeta Meta { get; set; } } diff --git a/CloudConvert.API/Models/ListResponseLinks.cs b/CloudConvert.API/Models/ListResponseLinks.cs index c3a8010..a586d03 100644 --- a/CloudConvert.API/Models/ListResponseLinks.cs +++ b/CloudConvert.API/Models/ListResponseLinks.cs @@ -1,20 +1,19 @@ using System; using System.Text.Json.Serialization; -namespace CloudConvert.API.Models +namespace CloudConvert.API.Models; + +public partial class ListResponseLinks { - public partial class ListResponseLinks - { - [JsonPropertyName("first")] - public Uri First { get; set; } + [JsonPropertyName("first")] + public Uri First { get; set; } - [JsonPropertyName("last")] - public Uri Last { get; set; } + [JsonPropertyName("last")] + public Uri Last { get; set; } - [JsonPropertyName("prev")] - public Uri Prev { get; set; } + [JsonPropertyName("prev")] + public Uri Prev { get; set; } - [JsonPropertyName("next")] - public Uri Next { get; set; } - } + [JsonPropertyName("next")] + public Uri Next { get; set; } } diff --git a/CloudConvert.API/Models/ListResponseMeta.cs b/CloudConvert.API/Models/ListResponseMeta.cs index 6196cb5..a7d84ff 100644 --- a/CloudConvert.API/Models/ListResponseMeta.cs +++ b/CloudConvert.API/Models/ListResponseMeta.cs @@ -1,23 +1,22 @@ using System; using System.Text.Json.Serialization; -namespace CloudConvert.API.Models +namespace CloudConvert.API.Models; + +public partial class ListResponseMeta { - public partial class ListResponseMeta - { - [JsonPropertyName("current_page")] - public int? Current_Page { get; set; } + [JsonPropertyName("current_page")] + public int? Current_Page { get; set; } - [JsonPropertyName("from")] - public int? From { get; set; } + [JsonPropertyName("from")] + public int? From { get; set; } - [JsonPropertyName("path")] - public Uri Path { get; set; } + [JsonPropertyName("path")] + public Uri Path { get; set; } - [JsonPropertyName("per_page")] - public int? Per_Page { get; set; } + [JsonPropertyName("per_page")] + public int? Per_Page { get; set; } - [JsonPropertyName("to")] - public int? To { get; set; } - } + [JsonPropertyName("to")] + public int? To { get; set; } } diff --git a/CloudConvert.API/Models/Response.cs b/CloudConvert.API/Models/Response.cs index ad19d29..77fcbbf 100644 --- a/CloudConvert.API/Models/Response.cs +++ b/CloudConvert.API/Models/Response.cs @@ -1,10 +1,9 @@ using System.Text.Json.Serialization; -namespace CloudConvert.API.Models +namespace CloudConvert.API.Models; + +public partial class Response { - public partial class Response - { - [JsonPropertyName("data")] - public T Data { get; set; } - } + [JsonPropertyName("data")] + public T Data { get; set; } } diff --git a/CloudConvert.API/Models/ResponseLinks.cs b/CloudConvert.API/Models/ResponseLinks.cs index e9a8fd6..d889450 100644 --- a/CloudConvert.API/Models/ResponseLinks.cs +++ b/CloudConvert.API/Models/ResponseLinks.cs @@ -1,11 +1,10 @@ using System; using System.Text.Json.Serialization; -namespace CloudConvert.API.Models +namespace CloudConvert.API.Models; + +public partial class ResponseLinks { - public partial class ResponseLinks - { - [JsonPropertyName("self")] - public Uri Self { get; set; } - } + [JsonPropertyName("self")] + public Uri Self { get; set; } } diff --git a/CloudConvert.API/Models/TaskModels/TaskListFilter.cs b/CloudConvert.API/Models/TaskModels/TaskListFilter.cs index 2ca0a51..7e8874c 100644 --- a/CloudConvert.API/Models/TaskModels/TaskListFilter.cs +++ b/CloudConvert.API/Models/TaskModels/TaskListFilter.cs @@ -1,47 +1,46 @@ using CloudConvert.API.Models.Enums; -namespace CloudConvert.API.Models.TaskModels +namespace CloudConvert.API.Models.TaskModels; + +public class TaskListFilter { - public class TaskListFilter + public TaskListFilter() { - public TaskListFilter() - { - Status = null; - JobId = null; - Operation = null; - Include = null; - PerPage = null; - Page = null; - } - - /// - /// The result will be filtered to include only tasks with a specific status (waiting, processing, finished or error). - /// - public TaskStatus? Status { get; set; } - - /// - /// The result will be filtered to include only tasks for a specific Job ID. - /// - public string JobId { get; set; } - - /// - /// Filter result to only include tasks of with a matching operation (for example convert or import/s3). - /// - public string Operation { get; set; } - - /// - /// Include retries, depends_on_tasks, payload and/or job in the result. Multiple include values are separated by ,. - /// - public string[] Include { get; set; } - - /// - /// Number of tasks per page, defaults to 100. - /// - public int? PerPage { get; set; } - - /// - /// The result page to show. - /// - public int? Page { get; set; } + Status = null; + JobId = null; + Operation = null; + Include = null; + PerPage = null; + Page = null; } + + /// + /// The result will be filtered to include only tasks with a specific status (waiting, processing, finished or error). + /// + public TaskStatus? Status { get; set; } + + /// + /// The result will be filtered to include only tasks for a specific Job ID. + /// + public string JobId { get; set; } + + /// + /// Filter result to only include tasks of with a matching operation (for example convert or import/s3). + /// + public string Operation { get; set; } + + /// + /// Include retries, depends_on_tasks, payload and/or job in the result. Multiple include values are separated by ,. + /// + public string[] Include { get; set; } + + /// + /// Number of tasks per page, defaults to 100. + /// + public int? PerPage { get; set; } + + /// + /// The result page to show. + /// + public int? Page { get; set; } } diff --git a/CloudConvert.API/Models/TaskModels/TaskResponse.cs b/CloudConvert.API/Models/TaskModels/TaskResponse.cs index d21f0cf..b4c3b0d 100644 --- a/CloudConvert.API/Models/TaskModels/TaskResponse.cs +++ b/CloudConvert.API/Models/TaskModels/TaskResponse.cs @@ -3,138 +3,137 @@ using System.Text.Json.Serialization; using CloudConvert.API.Models.Enums; -namespace CloudConvert.API.Models.TaskModels +namespace CloudConvert.API.Models.TaskModels; + +public partial class TaskResponse { - public partial class TaskResponse - { - /// - /// The ID of the task. - /// - [JsonPropertyName("id")] - public string Id { get; set; } - - /// - /// The Job ID the task belongs to. - /// - [JsonPropertyName("job_id")] - public string Job_Id { get; set; } - - [JsonPropertyName("name")] - public string Name { get; set; } - - /// - /// Name of the operation, for example convert or import/s3. - /// - [JsonPropertyName("operation")] - public string Operation { get; set; } - - /// - /// The status of the task. Is one of waiting, processing, finished or error. - /// - [JsonPropertyName("status")] - public TaskStatus Status { get; set; } - - /// - /// The amount of conversion minutes the task consumed. Available when the status is finished. - /// - [JsonPropertyName("credits")] - public int? Credits { get; set; } - - /// - /// The status message. Contains the error message if the task status is error. - /// - [JsonPropertyName("message")] - public object Message { get; set; } - - /// - /// The error code if the task status is error. - /// - [JsonPropertyName("code")] - public string Code { get; set; } - - [JsonPropertyName("percent")] - public int Percent { get; set; } - - /// - /// ISO8601 timestamp of the creation of the task. - /// - [JsonPropertyName("created_at")] - public DateTimeOffset? Created_At { get; set; } - - /// - /// ISO8601 timestamp when the task started processing. - /// - [JsonPropertyName("started_at")] - public DateTimeOffset? Started_At { get; set; } - - /// - /// ISO8601 timestamp when the task finished or failed. - /// - [JsonPropertyName("ended_at")] - public DateTimeOffset? Ended_At { get; set; } - - /// - /// List of tasks that are dependencies for this task. Only available if the include parameter was set to depends_on_tasks. - /// - [JsonPropertyName("depends_on_tasks")] - public object Depends_On_Tasks { get; set; } - - [JsonPropertyName("depends_on_task_ids")] - public List Depends_On_Task_Ids { get; set; } - - /// - /// ID of the original task, if this task is a retry. - /// - [JsonPropertyName("retry_of_task_id")] - public string Retry_Of_Task_Id { get; set; } - - [JsonPropertyName("copy_of_task_id")] - public object Copy_Of_Task_Id { get; set; } - - [JsonPropertyName("user_id")] - public int User_Id { get; set; } - - [JsonPropertyName("priority")] - public long Priority { get; set; } - - [JsonPropertyName("host_name")] - public object Host_Name { get; set; } - - [JsonPropertyName("storage")] - public string Storage { get; set; } - - /// - /// List of tasks that are retries of this task. Only available if the include parameter was set to retries. - /// - [JsonPropertyName("retries")] - public string Retries { get; set; } - - /// - /// Name of the engine. - /// - [JsonPropertyName("engine")] - public string Engine { get; set; } - - /// - /// Version of the engine. - /// - [JsonPropertyName("engine_version")] - public string Engine_Version { get; set; } - - /// - /// Your submitted payload for the tasks. Depends on the operation type. - /// - [JsonPropertyName("payload")] - public object Payload { get; set; } - - /// - /// The result of the task. Depends on the operation type. - /// Finished tasks always do have a files key with the names of the result files of the task (See the example on the right). - /// - [JsonPropertyName("result")] - public TaskResult Result { get; set; } - - [JsonPropertyName("links")] - public ResponseLinks Links { get; set; } - } + /// + /// The ID of the task. + /// + [JsonPropertyName("id")] + public string Id { get; set; } + + /// + /// The Job ID the task belongs to. + /// + [JsonPropertyName("job_id")] + public string Job_Id { get; set; } + + [JsonPropertyName("name")] + public string Name { get; set; } + + /// + /// Name of the operation, for example convert or import/s3. + /// + [JsonPropertyName("operation")] + public string Operation { get; set; } + + /// + /// The status of the task. Is one of waiting, processing, finished or error. + /// + [JsonPropertyName("status")] + public TaskStatus Status { get; set; } + + /// + /// The amount of conversion minutes the task consumed. Available when the status is finished. + /// + [JsonPropertyName("credits")] + public int? Credits { get; set; } + + /// + /// The status message. Contains the error message if the task status is error. + /// + [JsonPropertyName("message")] + public object Message { get; set; } + + /// + /// The error code if the task status is error. + /// + [JsonPropertyName("code")] + public string Code { get; set; } + + [JsonPropertyName("percent")] + public int Percent { get; set; } + + /// + /// ISO8601 timestamp of the creation of the task. + /// + [JsonPropertyName("created_at")] + public DateTimeOffset? Created_At { get; set; } + + /// + /// ISO8601 timestamp when the task started processing. + /// + [JsonPropertyName("started_at")] + public DateTimeOffset? Started_At { get; set; } + + /// + /// ISO8601 timestamp when the task finished or failed. + /// + [JsonPropertyName("ended_at")] + public DateTimeOffset? Ended_At { get; set; } + + /// + /// List of tasks that are dependencies for this task. Only available if the include parameter was set to depends_on_tasks. + /// + [JsonPropertyName("depends_on_tasks")] + public object Depends_On_Tasks { get; set; } + + [JsonPropertyName("depends_on_task_ids")] + public List Depends_On_Task_Ids { get; set; } + + /// + /// ID of the original task, if this task is a retry. + /// + [JsonPropertyName("retry_of_task_id")] + public string Retry_Of_Task_Id { get; set; } + + [JsonPropertyName("copy_of_task_id")] + public object Copy_Of_Task_Id { get; set; } + + [JsonPropertyName("user_id")] + public int User_Id { get; set; } + + [JsonPropertyName("priority")] + public long Priority { get; set; } + + [JsonPropertyName("host_name")] + public object Host_Name { get; set; } + + [JsonPropertyName("storage")] + public string Storage { get; set; } + + /// + /// List of tasks that are retries of this task. Only available if the include parameter was set to retries. + /// + [JsonPropertyName("retries")] + public string Retries { get; set; } + + /// + /// Name of the engine. + /// + [JsonPropertyName("engine")] + public string Engine { get; set; } + + /// + /// Version of the engine. + /// + [JsonPropertyName("engine_version")] + public string Engine_Version { get; set; } + + /// + /// Your submitted payload for the tasks. Depends on the operation type. + /// + [JsonPropertyName("payload")] + public object Payload { get; set; } + + /// + /// The result of the task. Depends on the operation type. + /// Finished tasks always do have a files key with the names of the result files of the task (See the example on the right). + /// + [JsonPropertyName("result")] + public TaskResult Result { get; set; } + + [JsonPropertyName("links")] + public ResponseLinks Links { get; set; } } diff --git a/CloudConvert.API/Models/TaskModels/TaskResult.cs b/CloudConvert.API/Models/TaskModels/TaskResult.cs index c0dd8bb..9f2a530 100644 --- a/CloudConvert.API/Models/TaskModels/TaskResult.cs +++ b/CloudConvert.API/Models/TaskModels/TaskResult.cs @@ -1,17 +1,16 @@ using System.Collections.Generic; using System.Text.Json.Serialization; -namespace CloudConvert.API.Models.TaskModels +namespace CloudConvert.API.Models.TaskModels; + +public partial class TaskResult { - public partial class TaskResult - { - [JsonPropertyName("form")] - public UploadForm Form { get; set; } + [JsonPropertyName("form")] + public UploadForm Form { get; set; } - [JsonPropertyName("files")] - public List Files { get; set; } + [JsonPropertyName("files")] + public List Files { get; set; } - [JsonPropertyName("metadata")] - public Dictionary Metadata { get; set; } - } + [JsonPropertyName("metadata")] + public Dictionary Metadata { get; set; } } diff --git a/CloudConvert.API/Models/TaskModels/TaskResultFile.cs b/CloudConvert.API/Models/TaskModels/TaskResultFile.cs index a288b1f..d576bdd 100644 --- a/CloudConvert.API/Models/TaskModels/TaskResultFile.cs +++ b/CloudConvert.API/Models/TaskModels/TaskResultFile.cs @@ -1,17 +1,16 @@ using System; using System.Text.Json.Serialization; -namespace CloudConvert.API.Models.TaskModels +namespace CloudConvert.API.Models.TaskModels; + +public partial class TaskResultFile { - public partial class TaskResultFile - { - [JsonPropertyName("filename")] - public string Filename { get; set; } + [JsonPropertyName("filename")] + public string Filename { get; set; } - [JsonPropertyName("size")] - public long Size { get; set; } + [JsonPropertyName("size")] + public long Size { get; set; } - [JsonPropertyName("url")] - public Uri Url { get; set; } - } + [JsonPropertyName("url")] + public Uri Url { get; set; } } diff --git a/CloudConvert.API/Models/TaskModels/UploadForm.cs b/CloudConvert.API/Models/TaskModels/UploadForm.cs index 2482278..0a8d8d8 100644 --- a/CloudConvert.API/Models/TaskModels/UploadForm.cs +++ b/CloudConvert.API/Models/TaskModels/UploadForm.cs @@ -1,14 +1,13 @@ using System; using System.Text.Json.Serialization; -namespace CloudConvert.API.Models.TaskModels +namespace CloudConvert.API.Models.TaskModels; + +public partial class UploadForm { - public partial class UploadForm - { - [JsonPropertyName("url")] - public Uri Url { get; set; } + [JsonPropertyName("url")] + public Uri Url { get; set; } - [JsonPropertyName("parameters")] - public object Parameters { get; set; } - } + [JsonPropertyName("parameters")] + public object Parameters { get; set; } } diff --git a/CloudConvert.API/Models/TaskOperations/ArchiveCreateRequest.cs b/CloudConvert.API/Models/TaskOperations/ArchiveCreateRequest.cs index 033a4d8..460ea1f 100644 --- a/CloudConvert.API/Models/TaskOperations/ArchiveCreateRequest.cs +++ b/CloudConvert.API/Models/TaskOperations/ArchiveCreateRequest.cs @@ -1,38 +1,37 @@ using System.Text.Json.Serialization; -namespace CloudConvert.API.Models.TaskOperations +namespace CloudConvert.API.Models.TaskOperations; + +public class ArchiveCreateRequest { - public class ArchiveCreateRequest - { - [JsonPropertyName("operation")] - public string Operation { get; } = "archive"; - - /// - /// The input task name(s) for this task. - /// input: string | string[]; - /// - [JsonPropertyName("input")] - public object Input { get; set; } - - [JsonPropertyName("output_format")] - public string Output_Format { get; set; } - - [JsonPropertyName("engine")] - public string Engine { get; set; } - - [JsonPropertyName("engine_version")] - public string Engine_Version { get; set; } - - /// - /// Choose a filename (including extension) for the output file. - /// - [JsonPropertyName("filename")] - public string Filename { get; set; } - - /// - /// Timeout in seconds after the task will be cancelled. - /// - [JsonPropertyName("timeout")] - public int? Timeout { get; set; } - } + [JsonPropertyName("operation")] + public string Operation { get; } = "archive"; + + /// + /// The input task name(s) for this task. + /// input: string | string[]; + /// + [JsonPropertyName("input")] + public object Input { get; set; } + + [JsonPropertyName("output_format")] + public string Output_Format { get; set; } + + [JsonPropertyName("engine")] + public string Engine { get; set; } + + [JsonPropertyName("engine_version")] + public string Engine_Version { get; set; } + + /// + /// Choose a filename (including extension) for the output file. + /// + [JsonPropertyName("filename")] + public string Filename { get; set; } + + /// + /// Timeout in seconds after the task will be cancelled. + /// + [JsonPropertyName("timeout")] + public int? Timeout { get; set; } } diff --git a/CloudConvert.API/Models/TaskOperations/CaptureCreateRequest.cs b/CloudConvert.API/Models/TaskOperations/CaptureCreateRequest.cs index 4615ae5..ed29af6 100644 --- a/CloudConvert.API/Models/TaskOperations/CaptureCreateRequest.cs +++ b/CloudConvert.API/Models/TaskOperations/CaptureCreateRequest.cs @@ -2,94 +2,93 @@ using System.Text.Json.Serialization; using CloudConvert.API.Models.Enums; -namespace CloudConvert.API.Models.TaskOperations +namespace CloudConvert.API.Models.TaskOperations; + +public class CaptureWebsiteCreateRequest { - public class CaptureWebsiteCreateRequest - { - [JsonPropertyName("operation")] - public string Operation { get; } = "capture-website"; + [JsonPropertyName("operation")] + public string Operation { get; } = "capture-website"; - /// - /// URL of the website - /// - [JsonPropertyName("url")] - public string Url { get; set; } + /// + /// URL of the website + /// + [JsonPropertyName("url")] + public string Url { get; set; } - [JsonPropertyName("output_format")] - public string Output_Format { get; set; } + [JsonPropertyName("output_format")] + public string Output_Format { get; set; } - [JsonPropertyName("engine")] - public string Engine { get; set; } + [JsonPropertyName("engine")] + public string Engine { get; set; } - [JsonPropertyName("engine_version")] - public string Engine_Version { get; set; } + [JsonPropertyName("engine_version")] + public string Engine_Version { get; set; } - /// - /// Choose a filename(including extension) for the output file. - /// - [JsonPropertyName("filename")] - public string Filename { get; set; } + /// + /// Choose a filename(including extension) for the output file. + /// + [JsonPropertyName("filename")] + public string Filename { get; set; } - [JsonPropertyName("pages")] - public string Pages { get; set; } + [JsonPropertyName("pages")] + public string Pages { get; set; } - [JsonPropertyName("zoom")] - public int? Zoom { get; set; } + [JsonPropertyName("zoom")] + public int? Zoom { get; set; } - [JsonPropertyName("page_width")] - public int? Page_Width { get; set; } + [JsonPropertyName("page_width")] + public int? Page_Width { get; set; } - [JsonPropertyName("page_height")] - public int? Page_Height { get; set; } + [JsonPropertyName("page_height")] + public int? Page_Height { get; set; } - [JsonPropertyName("margin_top")] - public int? Margin_Top { get; set; } + [JsonPropertyName("margin_top")] + public int? Margin_Top { get; set; } - [JsonPropertyName("margin_bottom")] - public int? Margin_Bottom { get; set; } + [JsonPropertyName("margin_bottom")] + public int? Margin_Bottom { get; set; } - [JsonPropertyName("margin_left")] - public int? Margin_Left { get; set; } + [JsonPropertyName("margin_left")] + public int? Margin_Left { get; set; } - [JsonPropertyName("margin_right")] - public int? Margin_Right { get; set; } + [JsonPropertyName("margin_right")] + public int? Margin_Right { get; set; } - [JsonPropertyName("print_background")] - public bool? Print_Background { get; set; } + [JsonPropertyName("print_background")] + public bool? Print_Background { get; set; } - [JsonPropertyName("display_header_footer")] - public bool? Display_Header_Footer { get; set; } + [JsonPropertyName("display_header_footer")] + public bool? Display_Header_Footer { get; set; } - [JsonPropertyName("header_template")] - public string Header_Template { get; set; } + [JsonPropertyName("header_template")] + public string Header_Template { get; set; } - [JsonPropertyName("footer_template")] - public string Footer_Template { get; set; } + [JsonPropertyName("footer_template")] + public string Footer_Template { get; set; } - [JsonPropertyName("wait_until")] - public CaptureWebsiteWaitUntil? Wait_Until { get; set; } + [JsonPropertyName("wait_until")] + public CaptureWebsiteWaitUntil? Wait_Until { get; set; } - [JsonPropertyName("wait_for_element")] - public string Wait_For_Element { get; set; } + [JsonPropertyName("wait_for_element")] + public string Wait_For_Element { get; set; } - [JsonPropertyName("wait_time")] - public int? Wait_Time { get; set; } + [JsonPropertyName("wait_time")] + public int? Wait_Time { get; set; } - [JsonPropertyName("headers")] - public Dictionary Headers { get; set; } + [JsonPropertyName("headers")] + public Dictionary Headers { get; set; } - /// - /// Timeout in seconds after the task will be cancelled. - /// - [JsonPropertyName("timeout")] - public int? Timeout { get; set; } + /// + /// Timeout in seconds after the task will be cancelled. + /// + [JsonPropertyName("timeout")] + public int? Timeout { get; set; } - /// - /// Conversion and engine-specific options. Depends on input_format and output_format. - /// Select input and output format above to show additional conversion options. - /// - [JsonExtensionData] - [JsonPropertyName("options")] - public Dictionary Options { get; set; } - } + /// + /// Conversion and engine-specific options. Depends on input_format and output_format. + /// Select input and output format above to show additional conversion options. + /// + [JsonExtensionData] + [JsonPropertyName("options")] + public Dictionary Options { get; set; } } diff --git a/CloudConvert.API/Models/TaskOperations/CommandCreateRequest.cs b/CloudConvert.API/Models/TaskOperations/CommandCreateRequest.cs index a323a21..70059bd 100644 --- a/CloudConvert.API/Models/TaskOperations/CommandCreateRequest.cs +++ b/CloudConvert.API/Models/TaskOperations/CommandCreateRequest.cs @@ -1,41 +1,40 @@ using System.Text.Json.Serialization; -namespace CloudConvert.API.Models.TaskOperations +namespace CloudConvert.API.Models.TaskOperations; + +public class CommandCreateRequest { - public class CommandCreateRequest - { - [JsonPropertyName("operation")] - public string Operation { get; } = "command"; - - /// - /// The input task name(s) for this task. - /// input: string | string[]; - /// - [JsonPropertyName("input")] - public object Input { get; set; } - - [JsonPropertyName("engine")] - public string Engine { get; set; } - - [JsonPropertyName("engine_version")] - public string Engine_Version { get; set; } - - /// - /// Capture the console output of the command and return it in the results object. - /// - [JsonPropertyName("capture_output")] - public bool? Capture_Output { get; set; } - - [JsonPropertyName("command")] - public string Command { get; set; } - - [JsonPropertyName("arguments")] - public string Arguments { get; set; } - - /// - /// Timeout in seconds after the task will be cancelled. - /// - [JsonPropertyName("timeout")] - public int? Timeout { get; set; } - } + [JsonPropertyName("operation")] + public string Operation { get; } = "command"; + + /// + /// The input task name(s) for this task. + /// input: string | string[]; + /// + [JsonPropertyName("input")] + public object Input { get; set; } + + [JsonPropertyName("engine")] + public string Engine { get; set; } + + [JsonPropertyName("engine_version")] + public string Engine_Version { get; set; } + + /// + /// Capture the console output of the command and return it in the results object. + /// + [JsonPropertyName("capture_output")] + public bool? Capture_Output { get; set; } + + [JsonPropertyName("command")] + public string Command { get; set; } + + [JsonPropertyName("arguments")] + public string Arguments { get; set; } + + /// + /// Timeout in seconds after the task will be cancelled. + /// + [JsonPropertyName("timeout")] + public int? Timeout { get; set; } } diff --git a/CloudConvert.API/Models/TaskOperations/ConvertCreateRequest.cs b/CloudConvert.API/Models/TaskOperations/ConvertCreateRequest.cs index ef09b03..37b3216 100644 --- a/CloudConvert.API/Models/TaskOperations/ConvertCreateRequest.cs +++ b/CloudConvert.API/Models/TaskOperations/ConvertCreateRequest.cs @@ -1,53 +1,52 @@ using System.Collections.Generic; using System.Text.Json.Serialization; -namespace CloudConvert.API.Models.TaskOperations +namespace CloudConvert.API.Models.TaskOperations; + +public class ConvertCreateRequest { - public class ConvertCreateRequest - { - [JsonPropertyName("operation")] - public string Operation { get; } = "convert"; - - /// - /// The input task name(s) for this task. - /// input: string | string[]; - /// - [JsonPropertyName("input")] - public object Input { get; set; } - - /// - /// If not set, the extension of the input file is used as input format - /// - [JsonPropertyName("input_format")] - public string Input_Format { get; set; } - - [JsonPropertyName("output_format")] - public string Output_Format { get; set; } - - [JsonPropertyName("engine")] - public string Engine { get; set; } - - [JsonPropertyName("engine_version")] - public string Engine_Version { get; set; } - - /// - /// Choose a filename (including extension) for the output file. - /// - [JsonPropertyName("filename")] - public string Filename { get; set; } - - /// - /// Timeout in seconds after the task will be cancelled. - /// - [JsonPropertyName("timeout")] - public int? Timeout { get; set; } - - /// - /// Conversion and engine specific options. Depends on input_format and output_format. - /// Select input and output format above to show additional conversion options. - /// - [JsonExtensionData] - [JsonPropertyName("options")] - public Dictionary Options { get; set; } - } + [JsonPropertyName("operation")] + public string Operation { get; } = "convert"; + + /// + /// The input task name(s) for this task. + /// input: string | string[]; + /// + [JsonPropertyName("input")] + public object Input { get; set; } + + /// + /// If not set, the extension of the input file is used as input format + /// + [JsonPropertyName("input_format")] + public string Input_Format { get; set; } + + [JsonPropertyName("output_format")] + public string Output_Format { get; set; } + + [JsonPropertyName("engine")] + public string Engine { get; set; } + + [JsonPropertyName("engine_version")] + public string Engine_Version { get; set; } + + /// + /// Choose a filename (including extension) for the output file. + /// + [JsonPropertyName("filename")] + public string Filename { get; set; } + + /// + /// Timeout in seconds after the task will be cancelled. + /// + [JsonPropertyName("timeout")] + public int? Timeout { get; set; } + + /// + /// Conversion and engine specific options. Depends on input_format and output_format. + /// Select input and output format above to show additional conversion options. + /// + [JsonExtensionData] + [JsonPropertyName("options")] + public Dictionary Options { get; set; } } diff --git a/CloudConvert.API/Models/TaskOperations/MergeCreateRequest.cs b/CloudConvert.API/Models/TaskOperations/MergeCreateRequest.cs index f3e3aca..fa25403 100644 --- a/CloudConvert.API/Models/TaskOperations/MergeCreateRequest.cs +++ b/CloudConvert.API/Models/TaskOperations/MergeCreateRequest.cs @@ -1,39 +1,38 @@ using System.Text.Json.Serialization; using CloudConvert.API.Models.Enums; -namespace CloudConvert.API.Models.TaskOperations +namespace CloudConvert.API.Models.TaskOperations; + +public class MergeCreateRequest { - public class MergeCreateRequest - { - [JsonPropertyName("operation")] - public string Operation { get; } = "merge"; - - /// - /// The input task name(s) for this task. - /// input: string | string[]; - /// - [JsonPropertyName("input")] - public object Input { get; set; } - - [JsonPropertyName("output_format")] - public MergeOutputFormat Output_Format { get; set; } - - [JsonPropertyName("engine")] - public string Engine { get; set; } - - [JsonPropertyName("engine_version")] - public string Engine_Version { get; set; } - - /// - /// Choose a filename (including extension) for the output file. - /// - [JsonPropertyName("filename")] - public string Filename { get; set; } - - /// - /// Timeout in seconds after the task will be cancelled. - /// - [JsonPropertyName("timeout")] - public int? Timeout { get; set; } - } + [JsonPropertyName("operation")] + public string Operation { get; } = "merge"; + + /// + /// The input task name(s) for this task. + /// input: string | string[]; + /// + [JsonPropertyName("input")] + public object Input { get; set; } + + [JsonPropertyName("output_format")] + public MergeOutputFormat Output_Format { get; set; } + + [JsonPropertyName("engine")] + public string Engine { get; set; } + + [JsonPropertyName("engine_version")] + public string Engine_Version { get; set; } + + /// + /// Choose a filename (including extension) for the output file. + /// + [JsonPropertyName("filename")] + public string Filename { get; set; } + + /// + /// Timeout in seconds after the task will be cancelled. + /// + [JsonPropertyName("timeout")] + public int? Timeout { get; set; } } diff --git a/CloudConvert.API/Models/TaskOperations/MetadataCreateRequest.cs b/CloudConvert.API/Models/TaskOperations/MetadataCreateRequest.cs index 9eb795d..d2d0761 100644 --- a/CloudConvert.API/Models/TaskOperations/MetadataCreateRequest.cs +++ b/CloudConvert.API/Models/TaskOperations/MetadataCreateRequest.cs @@ -1,40 +1,39 @@ using System.Collections.Generic; using System.Text.Json.Serialization; -namespace CloudConvert.API.Models.TaskOperations +namespace CloudConvert.API.Models.TaskOperations; + +public class MetadataCreateRequest { - public class MetadataCreateRequest - { - [JsonPropertyName("operation")] - public string Operation { get; } = "metadata"; - - /// - /// The input task name(s) for this task. - /// input: string | string[]; - /// - [JsonPropertyName("input")] - public object Input { get; set; } - - /// - /// If not set, the extension of the input file is used as input format - /// - [JsonPropertyName("input_format")] - public string Input_Format { get; set; } - - [JsonPropertyName("engine")] - public string Engine { get; set; } - - [JsonPropertyName("engine_version")] - public string Engine_Version { get; set; } - - [JsonPropertyName("timeout")] - public int? Timeout { get; set; } - - /// - /// Conversion and engine specific options. Depends on input_format and output_format. - /// - [JsonExtensionData] - [JsonPropertyName("options")] - public Dictionary Options { get; set; } - } + [JsonPropertyName("operation")] + public string Operation { get; } = "metadata"; + + /// + /// The input task name(s) for this task. + /// input: string | string[]; + /// + [JsonPropertyName("input")] + public object Input { get; set; } + + /// + /// If not set, the extension of the input file is used as input format + /// + [JsonPropertyName("input_format")] + public string Input_Format { get; set; } + + [JsonPropertyName("engine")] + public string Engine { get; set; } + + [JsonPropertyName("engine_version")] + public string Engine_Version { get; set; } + + [JsonPropertyName("timeout")] + public int? Timeout { get; set; } + + /// + /// Conversion and engine specific options. Depends on input_format and output_format. + /// + [JsonExtensionData] + [JsonPropertyName("options")] + public Dictionary Options { get; set; } } diff --git a/CloudConvert.API/Models/TaskOperations/MetadataWriteCreateRequest.cs b/CloudConvert.API/Models/TaskOperations/MetadataWriteCreateRequest.cs index e6ceb6f..591ee17 100644 --- a/CloudConvert.API/Models/TaskOperations/MetadataWriteCreateRequest.cs +++ b/CloudConvert.API/Models/TaskOperations/MetadataWriteCreateRequest.cs @@ -1,43 +1,42 @@ using System.Collections.Generic; using System.Text.Json.Serialization; -namespace CloudConvert.API.Models.TaskOperations +namespace CloudConvert.API.Models.TaskOperations; + +public class MetadataWriteCreateRequest { - public class MetadataWriteCreateRequest - { - [JsonPropertyName("operation")] - public string Operation { get; } = "metadata/write"; - - /// - /// The input task name(s) for this task. - /// input: string | string[]; - /// - [JsonPropertyName("input")] - public object Input { get; set; } - - /// - /// If not set, the extension of the input file is used as input format - /// - [JsonPropertyName("input_format")] - public string Input_Format { get; set; } - - [JsonPropertyName("engine")] - public string Engine { get; set; } - - [JsonPropertyName("engine_version")] - public string Engine_Version { get; set; } - - [JsonPropertyName("timeout")] - public int? Timeout { get; set; } - - [JsonPropertyName("metadata")] - public Dictionary Metadata { get; set; } - - /// - /// Conversion and engine specific options. Depends on input_format and output_format. - /// - [JsonExtensionData] - [JsonPropertyName("options")] - public Dictionary Options { get; set; } - } + [JsonPropertyName("operation")] + public string Operation { get; } = "metadata/write"; + + /// + /// The input task name(s) for this task. + /// input: string | string[]; + /// + [JsonPropertyName("input")] + public object Input { get; set; } + + /// + /// If not set, the extension of the input file is used as input format + /// + [JsonPropertyName("input_format")] + public string Input_Format { get; set; } + + [JsonPropertyName("engine")] + public string Engine { get; set; } + + [JsonPropertyName("engine_version")] + public string Engine_Version { get; set; } + + [JsonPropertyName("timeout")] + public int? Timeout { get; set; } + + [JsonPropertyName("metadata")] + public Dictionary Metadata { get; set; } + + /// + /// Conversion and engine specific options. Depends on input_format and output_format. + /// + [JsonExtensionData] + [JsonPropertyName("options")] + public Dictionary Options { get; set; } } diff --git a/CloudConvert.API/Models/TaskOperations/OptimizeCreateRequest.cs b/CloudConvert.API/Models/TaskOperations/OptimizeCreateRequest.cs index 5a98f1a..c0373a5 100644 --- a/CloudConvert.API/Models/TaskOperations/OptimizeCreateRequest.cs +++ b/CloudConvert.API/Models/TaskOperations/OptimizeCreateRequest.cs @@ -2,55 +2,54 @@ using System.Text.Json.Serialization; using CloudConvert.API.Models.Enums; -namespace CloudConvert.API.Models.TaskOperations +namespace CloudConvert.API.Models.TaskOperations; + +public class OptimizeCreateRequest { - public class OptimizeCreateRequest - { - [JsonPropertyName("operation")] - public string Operation { get; } = "optimize"; - - /// - /// The input task name(s) for this task. - /// input: string | string[]; - /// - [JsonPropertyName("input")] - public object Input { get; set; } - - /// - /// If not set, the extension of the input file is used as input format - /// - [JsonPropertyName("input_format")] - public OptimizeInputFormat? Input_Format { get; set; } - - [JsonPropertyName("engine")] - public string Engine { get; set; } - - [JsonPropertyName("engine_version")] - public string Engine_Version { get; set; } - - /// - /// Choose a filename (including extension) for the output file. - /// - [JsonPropertyName("filename")] - public string Filename { get; set; } - - [JsonPropertyName("quality")] - public int? Quality { get; set; } - - [JsonPropertyName("profile")] - public OptimizeProfile? Profile { get; set; } - - /// - /// Timeout in seconds after the task will be cancelled. - /// - [JsonPropertyName("timeout")] - public int? Timeout { get; set; } - - /// - /// Conversion and engine specific options. Depends on input_format and output_format. - /// - [JsonExtensionData] - [JsonPropertyName("options")] - public Dictionary Options { get; set; } - } + [JsonPropertyName("operation")] + public string Operation { get; } = "optimize"; + + /// + /// The input task name(s) for this task. + /// input: string | string[]; + /// + [JsonPropertyName("input")] + public object Input { get; set; } + + /// + /// If not set, the extension of the input file is used as input format + /// + [JsonPropertyName("input_format")] + public OptimizeInputFormat? Input_Format { get; set; } + + [JsonPropertyName("engine")] + public string Engine { get; set; } + + [JsonPropertyName("engine_version")] + public string Engine_Version { get; set; } + + /// + /// Choose a filename (including extension) for the output file. + /// + [JsonPropertyName("filename")] + public string Filename { get; set; } + + [JsonPropertyName("quality")] + public int? Quality { get; set; } + + [JsonPropertyName("profile")] + public OptimizeProfile? Profile { get; set; } + + /// + /// Timeout in seconds after the task will be cancelled. + /// + [JsonPropertyName("timeout")] + public int? Timeout { get; set; } + + /// + /// Conversion and engine specific options. Depends on input_format and output_format. + /// + [JsonExtensionData] + [JsonPropertyName("options")] + public Dictionary Options { get; set; } } diff --git a/CloudConvert.API/Models/TaskOperations/ThumbnailCreateRequest.cs b/CloudConvert.API/Models/TaskOperations/ThumbnailCreateRequest.cs index fc19a3b..a83438c 100644 --- a/CloudConvert.API/Models/TaskOperations/ThumbnailCreateRequest.cs +++ b/CloudConvert.API/Models/TaskOperations/ThumbnailCreateRequest.cs @@ -2,77 +2,76 @@ using System.Text.Json.Serialization; using CloudConvert.API.Models.Enums; -namespace CloudConvert.API.Models.TaskOperations +namespace CloudConvert.API.Models.TaskOperations; + +public class ThumbnailCreateRequest { - public class ThumbnailCreateRequest - { - [JsonPropertyName("operation")] - public string Operation { get; } = "thumbnail"; + [JsonPropertyName("operation")] + public string Operation { get; } = "thumbnail"; - /// - /// The input task name(s) for this task. - /// input: string | string[]; - /// - [JsonPropertyName("input")] - public object Input { get; set; } + /// + /// The input task name(s) for this task. + /// input: string | string[]; + /// + [JsonPropertyName("input")] + public object Input { get; set; } - /// - /// If not set, the extension of the input file is used as input format - /// - [JsonPropertyName("input_format")] - public string Input_Format { get; set; } + /// + /// If not set, the extension of the input file is used as input format + /// + [JsonPropertyName("input_format")] + public string Input_Format { get; set; } - [JsonPropertyName("output_format")] - public ThumbnailOutputFormat Output_Format { get; set; } + [JsonPropertyName("output_format")] + public ThumbnailOutputFormat Output_Format { get; set; } - [JsonPropertyName("engine")] - public string Engine { get; set; } + [JsonPropertyName("engine")] + public string Engine { get; set; } - [JsonPropertyName("engine_version")] - public string Engine_Version { get; set; } + [JsonPropertyName("engine_version")] + public string Engine_Version { get; set; } - /// - /// Choose a filename (including extension) for the output file. - /// - [JsonPropertyName("filename")] - public string Filename { get; set; } + /// + /// Choose a filename (including extension) for the output file. + /// + [JsonPropertyName("filename")] + public string Filename { get; set; } - /// - /// Timeout in seconds after the task will be cancelled. - /// - [JsonPropertyName("timeout")] - public int? Timeout { get; set; } + /// + /// Timeout in seconds after the task will be cancelled. + /// + [JsonPropertyName("timeout")] + public int? Timeout { get; set; } - /// - /// Sets the mode of sizing the thumbnail. "Max" resizes the thumbnail to fit within the width and height, but will not increase the size of the image if it is smaller than width or height. "Crop" resizes the thumbnail to fill the width and height dimensions and crops any excess image data. "Scale" enforces the thumbnail width and height by scaling. Defaults to max. - /// - [JsonPropertyName("fit")] - public ThumbnailFit? Fit { get; set; } + /// + /// Sets the mode of sizing the thumbnail. "Max" resizes the thumbnail to fit within the width and height, but will not increase the size of the image if it is smaller than width or height. "Crop" resizes the thumbnail to fill the width and height dimensions and crops any excess image data. "Scale" enforces the thumbnail width and height by scaling. Defaults to max. + /// + [JsonPropertyName("fit")] + public ThumbnailFit? Fit { get; set; } - /// - /// Set thumbnail width in pixels. - /// - [JsonPropertyName("width")] - public int? Width { get; set; } + /// + /// Set thumbnail width in pixels. + /// + [JsonPropertyName("width")] + public int? Width { get; set; } - /// - /// Set thumbnail height in pixels. - /// - [JsonPropertyName("height")] - public int? Height { get; set; } + /// + /// Set thumbnail height in pixels. + /// + [JsonPropertyName("height")] + public int? Height { get; set; } - /// - /// Number of thumbnails to create. Defaults to 1. - /// - [JsonPropertyName("count")] - public int? Count { get; set; } + /// + /// Number of thumbnails to create. Defaults to 1. + /// + [JsonPropertyName("count")] + public int? Count { get; set; } - /// - /// Conversion and engine specific options. Depends on input_format and output_format. - /// Select input and output format above to show additional conversion options. - /// - [JsonExtensionData] - [JsonPropertyName("options")] - public Dictionary Options { get; set; } - } + /// + /// Conversion and engine specific options. Depends on input_format and output_format. + /// Select input and output format above to show additional conversion options. + /// + [JsonExtensionData] + [JsonPropertyName("options")] + public Dictionary Options { get; set; } } diff --git a/CloudConvert.API/Models/TaskOperations/WatermarkCreateRequest.cs b/CloudConvert.API/Models/TaskOperations/WatermarkCreateRequest.cs index 8025c82..d97a515 100644 --- a/CloudConvert.API/Models/TaskOperations/WatermarkCreateRequest.cs +++ b/CloudConvert.API/Models/TaskOperations/WatermarkCreateRequest.cs @@ -1,50 +1,49 @@ using System.Collections.Generic; using System.Text.Json.Serialization; -namespace CloudConvert.API.Models.TaskOperations +namespace CloudConvert.API.Models.TaskOperations; + +public class WatermarkCreateRequest { - public class WatermarkCreateRequest - { - [JsonPropertyName("operation")] - public string Operation { get; } = "watermark"; - - /// - /// The input task name(s) for this task. - /// input: string | string[]; - /// - [JsonPropertyName("input")] - public object Input { get; set; } - - /// - /// If not set, the extension of the input file is used as input format - /// - [JsonPropertyName("input_format")] - public string Input_Format { get; set; } - - [JsonPropertyName("engine")] - public string Engine { get; set; } - - [JsonPropertyName("engine_version")] - public string Engine_Version { get; set; } - - /// - /// Choose a filename (including extension) for the output file. - /// - [JsonPropertyName("filename")] - public string Filename { get; set; } - - /// - /// Timeout in seconds after the task will be cancelled. - /// - [JsonPropertyName("timeout")] - public int? Timeout { get; set; } - - /// - /// Conversion and engine specific options. Depends on input_format and output_format. - /// Select input and output format above to show additional conversion options. - /// - [JsonExtensionData] - [JsonPropertyName("options")] - public Dictionary Options { get; set; } - } + [JsonPropertyName("operation")] + public string Operation { get; } = "watermark"; + + /// + /// The input task name(s) for this task. + /// input: string | string[]; + /// + [JsonPropertyName("input")] + public object Input { get; set; } + + /// + /// If not set, the extension of the input file is used as input format + /// + [JsonPropertyName("input_format")] + public string Input_Format { get; set; } + + [JsonPropertyName("engine")] + public string Engine { get; set; } + + [JsonPropertyName("engine_version")] + public string Engine_Version { get; set; } + + /// + /// Choose a filename (including extension) for the output file. + /// + [JsonPropertyName("filename")] + public string Filename { get; set; } + + /// + /// Timeout in seconds after the task will be cancelled. + /// + [JsonPropertyName("timeout")] + public int? Timeout { get; set; } + + /// + /// Conversion and engine specific options. Depends on input_format and output_format. + /// Select input and output format above to show additional conversion options. + /// + [JsonExtensionData] + [JsonPropertyName("options")] + public Dictionary Options { get; set; } } diff --git a/CloudConvert.API/RestHelper.cs b/CloudConvert.API/RestHelper.cs index 3ceeacd..c9730ac 100644 --- a/CloudConvert.API/RestHelper.cs +++ b/CloudConvert.API/RestHelper.cs @@ -3,42 +3,41 @@ using System.Threading; using System.Threading.Tasks; -namespace CloudConvert.API +namespace CloudConvert.API; + +public class RestHelper { - public class RestHelper + private readonly HttpClient _httpClient; + + internal RestHelper() { - private readonly HttpClient _httpClient; + _httpClient = new HttpClient(new WebApiHandler(true)); + _httpClient.Timeout = System.TimeSpan.FromMilliseconds(System.Threading.Timeout.Infinite); + } - internal RestHelper() - { - _httpClient = new HttpClient(new WebApiHandler(true)); - _httpClient.Timeout = System.TimeSpan.FromMilliseconds(System.Threading.Timeout.Infinite); - } + internal RestHelper(HttpClient httpClient) + { + _httpClient = httpClient; + } - internal RestHelper(HttpClient httpClient) - { - _httpClient = httpClient; - } + internal async Task RequestAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + var response = await _httpClient.SendAsync(request, cancellationToken); + var responseRaw = await response.Content.ReadAsStringAsync(cancellationToken); - public async Task RequestAsync(HttpRequestMessage request, CancellationToken cancellationToken) + // Handle empty response body (e.g., HTTP 204 No Content) + // System.Text.Json throws when trying to deserialize an empty string + if (string.IsNullOrWhiteSpace(responseRaw) || response.StatusCode == System.Net.HttpStatusCode.NoContent) { - var response = await _httpClient.SendAsync(request, cancellationToken); - var responseRaw = await response.Content.ReadAsStringAsync(cancellationToken); - - // Handle empty response body (e.g., HTTP 204 No Content) - // System.Text.Json throws when trying to deserialize an empty string - if (string.IsNullOrWhiteSpace(responseRaw) || response.StatusCode == System.Net.HttpStatusCode.NoContent) - { - return default(T); - } - - return JsonSerializer.Deserialize(responseRaw, DefaultJsonSerializerOptions.SerializerOptions); + return default(T); } - public async Task RequestAsync(HttpRequestMessage request, CancellationToken cancellationToken) - { - var response = await _httpClient.SendAsync(request, cancellationToken); - return await response.Content.ReadAsStringAsync(cancellationToken); - } + return JsonSerializer.Deserialize(responseRaw, DefaultJsonSerializerOptions.SerializerOptions); + } + + internal async Task RequestAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + var response = await _httpClient.SendAsync(request, cancellationToken); + return await response.Content.ReadAsStringAsync(cancellationToken); } } diff --git a/CloudConvert.API/WebApiException.cs b/CloudConvert.API/WebApiException.cs index 470730b..8ff5157 100644 --- a/CloudConvert.API/WebApiException.cs +++ b/CloudConvert.API/WebApiException.cs @@ -1,23 +1,22 @@ using System; -namespace CloudConvert.API +namespace CloudConvert.API; + +public class WebApiException : Exception { - public class WebApiException : Exception + public WebApiException() { - public WebApiException() - { - } + } - public WebApiException(Exception innerException) : base(innerException.Message, innerException) - { - } + public WebApiException(Exception innerException) : base(innerException.Message, innerException) + { + } - public WebApiException(string message, Exception innerException) : base(message, innerException) - { - } + public WebApiException(string message, Exception innerException) : base(message, innerException) + { + } - public WebApiException(string message) : base(message) - { - } + public WebApiException(string message) : base(message) + { } } diff --git a/CloudConvert.API/WebApiHandler.cs b/CloudConvert.API/WebApiHandler.cs index 47cb0ca..3bc07f8 100644 --- a/CloudConvert.API/WebApiHandler.cs +++ b/CloudConvert.API/WebApiHandler.cs @@ -4,48 +4,40 @@ using System.Threading.Tasks; using CloudConvert.API.Extensions; -namespace CloudConvert.API +namespace CloudConvert.API; + +internal sealed class WebApiHandler(bool loggingEnabled) : HttpClientHandler { - internal sealed class WebApiHandler : HttpClientHandler + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { - private readonly bool _loggingEnabled; - - public WebApiHandler(bool loggingEnabled) - { - _loggingEnabled = loggingEnabled; - } + bool writeLog = loggingEnabled; - protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + try { - - bool writeLog = _loggingEnabled; - - try + if (writeLog) { - if (writeLog) - { - var requestString = request.Content != null ? await request.Content.ReadAsStringAsync(cancellationToken) : string.Empty; - } - - var response = await base.SendAsync(request, cancellationToken); - - if (writeLog) - { - string responseString = (await response.Content.ReadAsStringAsync(cancellationToken)).TrimLengthWithEllipsis(20000); - } + var requestString = request.Content is not null ? await request.Content.ReadAsStringAsync(cancellationToken) : string.Empty; + } - if ((int)response.StatusCode >= 400) - { - throw new WebApiException((await response.Content.ReadAsStringAsync(cancellationToken)).TrimLengthWithEllipsis(20000)); - } + var response = await base.SendAsync(request, cancellationToken); + await response.Content.LoadIntoBufferAsync(); - return response; + if (writeLog) + { + string responseString = (await response.Content.ReadAsStringAsync(cancellationToken)).TrimLengthWithEllipsis(20000); } - catch (Exception exc) + + if ((int)response.StatusCode >= 400) { - throw new WebApiException($"{request.Method} {request.RequestUri} failed: {exc.Message}", exc); + throw new WebApiException((await response.Content.ReadAsStringAsync(cancellationToken)).TrimLengthWithEllipsis(20000)); } + + return response; + } + catch (Exception exc) + { + throw new WebApiException($"{request.Method} {request.RequestUri} failed: {exc.Message}", exc); } } } diff --git a/CloudConvert.Test/Extensions/MockExtensions.cs b/CloudConvert.Test/Extensions/MockExtensions.cs index 9407d5e..cda6d0a 100644 --- a/CloudConvert.Test/Extensions/MockExtensions.cs +++ b/CloudConvert.Test/Extensions/MockExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Net; using System.Net.Http; @@ -8,43 +8,42 @@ using Moq.Language.Flow; using Moq.Protected; -namespace CloudConvert.Test.Extensions +namespace CloudConvert.Test.Extensions; + +public static class MockExtensions { - public static class MockExtensions + public static IReturnsResult MockResponse(this Mock mock, string endpoint, string fileName) { - public static IReturnsResult MockResponse(this Mock mock, string endpoint, string fileName) - { - return mock.Protected() - .Setup>("SendAsync", - ItExpr.Is(message => message.RequestUri.AbsolutePath.EndsWith(endpoint)), - ItExpr.IsAny()) - .ReturnsAsync(new HttpResponseMessage - { - StatusCode = HttpStatusCode.OK, - Content = new StringContent(File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Responses", fileName))) - }); - } + return mock.Protected() + .Setup>("SendAsync", + ItExpr.Is(message => message.RequestUri.AbsolutePath.EndsWith(endpoint)), + ItExpr.IsAny()) + .ReturnsAsync(new HttpResponseMessage + { + StatusCode = HttpStatusCode.OK, + Content = new StringContent(File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Responses", fileName))) + }); + } - public static IReturnsResult MockNoContentResponse(this Mock mock, string endpoint) - { - return mock.Protected() - .Setup>("SendAsync", - ItExpr.Is(message => message.RequestUri.AbsolutePath.EndsWith(endpoint)), - ItExpr.IsAny()) - .ReturnsAsync(new HttpResponseMessage - { - StatusCode = HttpStatusCode.NoContent, - Content = new StringContent(string.Empty) - }); - } + public static IReturnsResult MockNoContentResponse(this Mock mock, string endpoint) + { + return mock.Protected() + .Setup>("SendAsync", + ItExpr.Is(message => message.RequestUri.AbsolutePath.EndsWith(endpoint)), + ItExpr.IsAny()) + .ReturnsAsync(new HttpResponseMessage + { + StatusCode = HttpStatusCode.NoContent, + Content = new StringContent(string.Empty) + }); + } - public static void VerifyRequest(this Mock mock, string endpoint, Times times) - { - mock.Protected() - .Verify("SendAsync", - times, - ItExpr.Is(message => message.RequestUri.AbsolutePath.EndsWith(endpoint)), - ItExpr.IsAny()); - } + public static void VerifyRequest(this Mock mock, string endpoint, Times times) + { + mock.Protected() + .Verify("SendAsync", + times, + ItExpr.Is(message => message.RequestUri.AbsolutePath.EndsWith(endpoint)), + ItExpr.IsAny()); } } diff --git a/CloudConvert.Test/IntegrationTests.cs b/CloudConvert.Test/IntegrationTests.cs index 7953055..bd61366 100644 --- a/CloudConvert.Test/IntegrationTests.cs +++ b/CloudConvert.Test/IntegrationTests.cs @@ -14,203 +14,202 @@ using System.Text.Json; using System.Threading; -namespace CloudConvert.Test +namespace CloudConvert.Test; + +[Category("Integration")] +public class IntegrationTests { - [Category("Integration")] - public class IntegrationTests - { - const string apiKey = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjI4YmE3OGQyZjc1NWM5ZGE3Yjg1NDRhMWRkMjg2NWM4N2U0YzI5NWI0NzQ0Zjc4ZDNmMzA3OWM2NjU3ZjI0MjVhOTMyYjIxMjU5ZGU2NWQ4In0.eyJhdWQiOiIxIiwianRpIjoiMjhiYTc4ZDJmNzU1YzlkYTdiODU0NGExZGQyODY1Yzg3ZTRjMjk1YjQ3NDRmNzhkM2YzMDc5YzY2NTdmMjQyNWE5MzJiMjEyNTlkZTY1ZDgiLCJpYXQiOjE1NTkwNjc3NzcsIm5iZiI6MTU1OTA2Nzc3NywiZXhwIjo0NzE0NzQxMzc3LCJzdWIiOiIzNzExNjc4NCIsInNjb3BlcyI6WyJ1c2VyLnJlYWQiLCJ1c2VyLndyaXRlIiwidGFzay5yZWFkIiwidGFzay53cml0ZSIsIndlYmhvb2sucmVhZCIsIndlYmhvb2sud3JpdGUiXX0.IkmkfDVGwouCH-ICFAShQMHyFAHK3y90CSoissUVD8h5HFG4GqN5DEw0IFzlPr1auUKp3H1pAvPutdIQtrDMTmUUmGMUb2dRlCAuQdqxa81Q5KAmcKDgOg2YTWOWEGMy3jETTb7W6vyNGsT_3DFMapMdeOw1jdIUTMZqW3QbSCeGXj3PMRnhI7YynaDtmktjzO9IUDHbeT2HRzzMiep97KvVZNjYtZvgM-kbUjE6Mm68_kA8JMuQeor0Yg7896JPV0YM3-MnHf7elKgoCJbfBCDAbvSX_ZYsSI7IGoLLb0mgJVfFcH_HMYAHhJj5cUEJN2Iml-FkODqrRk72bVxyJs9j1GPQBl4ORXuU9yrjUgHrRaZ5YM__LwsUQB3AuB92oyQseCjULn1sWM1PzIXCcyVjKZSpn9LAAGNf9paCF-_G9ok9tZKccRouCiYl9v5XbmuxV8hXYp6fXZxyaAkj_JN2kErVSkxYzVyyZL1e220aFFnbch6nDvLFHgi-WeTQHFQDzuHsM8RKRixV8uD7pk3de4AEYg0EWqZHCr82qY7TGdSQvuAS0QIy3B89OwQW0ROW4k3Yw0XIKgKSYWyKnc7huc7yPQUIDDDAOa5OojXrVY5ZuL_hwQMIOmejcHTKFdAgzAaVnRkC8_FfVh4wHCPBaHjze9hRp5n4O1pnPFI"; - protected ICloudConvertAPI _cloudConvertAPI; + const string apiKey = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjI4YmE3OGQyZjc1NWM5ZGE3Yjg1NDRhMWRkMjg2NWM4N2U0YzI5NWI0NzQ0Zjc4ZDNmMzA3OWM2NjU3ZjI0MjVhOTMyYjIxMjU5ZGU2NWQ4In0.eyJhdWQiOiIxIiwianRpIjoiMjhiYTc4ZDJmNzU1YzlkYTdiODU0NGExZGQyODY1Yzg3ZTRjMjk1YjQ3NDRmNzhkM2YzMDc5YzY2NTdmMjQyNWE5MzJiMjEyNTlkZTY1ZDgiLCJpYXQiOjE1NTkwNjc3NzcsIm5iZiI6MTU1OTA2Nzc3NywiZXhwIjo0NzE0NzQxMzc3LCJzdWIiOiIzNzExNjc4NCIsInNjb3BlcyI6WyJ1c2VyLnJlYWQiLCJ1c2VyLndyaXRlIiwidGFzay5yZWFkIiwidGFzay53cml0ZSIsIndlYmhvb2sucmVhZCIsIndlYmhvb2sud3JpdGUiXX0.IkmkfDVGwouCH-ICFAShQMHyFAHK3y90CSoissUVD8h5HFG4GqN5DEw0IFzlPr1auUKp3H1pAvPutdIQtrDMTmUUmGMUb2dRlCAuQdqxa81Q5KAmcKDgOg2YTWOWEGMy3jETTb7W6vyNGsT_3DFMapMdeOw1jdIUTMZqW3QbSCeGXj3PMRnhI7YynaDtmktjzO9IUDHbeT2HRzzMiep97KvVZNjYtZvgM-kbUjE6Mm68_kA8JMuQeor0Yg7896JPV0YM3-MnHf7elKgoCJbfBCDAbvSX_ZYsSI7IGoLLb0mgJVfFcH_HMYAHhJj5cUEJN2Iml-FkODqrRk72bVxyJs9j1GPQBl4ORXuU9yrjUgHrRaZ5YM__LwsUQB3AuB92oyQseCjULn1sWM1PzIXCcyVjKZSpn9LAAGNf9paCF-_G9ok9tZKccRouCiYl9v5XbmuxV8hXYp6fXZxyaAkj_JN2kErVSkxYzVyyZL1e220aFFnbch6nDvLFHgi-WeTQHFQDzuHsM8RKRixV8uD7pk3de4AEYg0EWqZHCr82qY7TGdSQvuAS0QIy3B89OwQW0ROW4k3Yw0XIKgKSYWyKnc7huc7yPQUIDDDAOa5OojXrVY5ZuL_hwQMIOmejcHTKFdAgzAaVnRkC8_FfVh4wHCPBaHjze9hRp5n4O1pnPFI"; + protected ICloudConvertAPI _cloudConvertAPI; - [OneTimeSetUp] - public void Setup() - { - _cloudConvertAPI = new CloudConvertAPI(apiKey, true); - } + [OneTimeSetUp] + public void Setup() + { + _cloudConvertAPI = new CloudConvertAPI(apiKey, true); + } - [TestCase("cancellationtoken")] - public async Task CancellationToken(string streamingMethod) - { - using var cts = new CancellationTokenSource(); - var token = cts.Token; + [TestCase("cancellationtoken")] + public async Task CancellationToken(string streamingMethod) + { + using var cts = new CancellationTokenSource(); + var token = cts.Token; - cts.Cancel(); + cts.Cancel(); - try + try + { + await _cloudConvertAPI.CreateJobAsync(new JobCreateRequest { - await _cloudConvertAPI.CreateJobAsync(new JobCreateRequest - { - Tasks = new() - }, token).ConfigureAwait(false); + Tasks = new() + }, token).ConfigureAwait(false); - Assert.Fail("Expected TaskCanceledException"); - } - catch (WebApiException ex) when (ex.InnerException is TaskCanceledException) - { - } + Assert.Fail("Expected TaskCanceledException"); + } + catch (WebApiException ex) when (ex.InnerException is TaskCanceledException) + { } + } - [TestCase("stream")] - [TestCase("bytes")] - public async Task CreateJob(string streamingMethod) + [TestCase("stream")] + [TestCase("bytes")] + public async Task CreateJob(string streamingMethod) + { + var job = await _cloudConvertAPI.CreateJobAsync(new JobCreateRequest { - var job = await _cloudConvertAPI.CreateJobAsync(new JobCreateRequest + Tasks = new { - Tasks = new + import_it = new ImportUploadCreateRequest(), + export_it = new ExportUrlCreateRequest { - import_it = new ImportUploadCreateRequest(), - export_it = new ExportUrlCreateRequest - { - Input = "import_it" - } - }, - Tag = "integration-test-upload-download" - }); + Input = "import_it" + } + }, + Tag = "integration-test-upload-download" + }); - var uploadTask = job.Data.Tasks.FirstOrDefault(t => t.Name == "import_it"); + var uploadTask = job.Data.Tasks.FirstOrDefault(t => t.Name == "import_it"); - Assert.IsNotNull(uploadTask); + Assert.IsNotNull(uploadTask); - var path = AppDomain.CurrentDomain.BaseDirectory + @"TestFiles/input.pdf"; - string fileName = "input.pdf"; + var path = AppDomain.CurrentDomain.BaseDirectory + @"TestFiles/input.pdf"; + string fileName = "input.pdf"; - string result; + string result; - switch (streamingMethod) + switch (streamingMethod) + { + case "bytes": { - case "bytes": - { - byte[] file = File.ReadAllBytes(path); - result = await _cloudConvertAPI.UploadAsync(uploadTask.Result.Form.Url.ToString(), file, fileName, uploadTask.Result.Form.Parameters); - break; - } - case "stream": - { - using (var stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read)) - result = await _cloudConvertAPI.UploadAsync(uploadTask.Result.Form.Url.ToString(), stream, fileName, uploadTask.Result.Form.Parameters); - break; - } + byte[] file = File.ReadAllBytes(path); + result = await _cloudConvertAPI.UploadAsync(uploadTask.Result.Form.Url.ToString(), file, fileName, uploadTask.Result.Form.Parameters); + break; + } + case "stream": + { + using (var stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read)) + result = await _cloudConvertAPI.UploadAsync(uploadTask.Result.Form.Url.ToString(), stream, fileName, uploadTask.Result.Form.Parameters); + break; } + } - job = await _cloudConvertAPI.WaitJobAsync(job.Data.Id); + job = await _cloudConvertAPI.WaitJobAsync(job.Data.Id); - Assert.AreEqual(job.Data.Status, "finished"); + Assert.AreEqual(job.Data.Status, "finished"); - // download export file + // download export file - var exportTask = job.Data.Tasks.FirstOrDefault(t => t.Name == "export_it"); + var exportTask = job.Data.Tasks.FirstOrDefault(t => t.Name == "export_it"); - var fileExport = exportTask.Result.Files.FirstOrDefault(); + var fileExport = exportTask.Result.Files.FirstOrDefault(); - Assert.IsNotNull(fileExport); - Assert.AreEqual(fileExport.Filename, "input.pdf"); + Assert.IsNotNull(fileExport); + Assert.AreEqual(fileExport.Filename, "input.pdf"); - using var httpClient = new HttpClient(); - var fileBytes = await httpClient.GetByteArrayAsync(fileExport.Url); - await File.WriteAllBytesAsync(fileExport.Filename, fileBytes); - } + using var httpClient = new HttpClient(); + var fileBytes = await httpClient.GetByteArrayAsync(fileExport.Url); + await File.WriteAllBytesAsync(fileExport.Filename, fileBytes); + } - [Test] - public async Task CreateJobWithOptions() + [Test] + public async Task CreateJobWithOptions() + { + var job = await _cloudConvertAPI.CreateJobAsync(new JobCreateRequest { - var job = await _cloudConvertAPI.CreateJobAsync(new JobCreateRequest + Tasks = new { - Tasks = new + import_it = new ImportUploadCreateRequest(), + convert_it = new ConvertCreateRequest { - import_it = new ImportUploadCreateRequest(), - convert_it = new ConvertCreateRequest - { - Input = "import_it", - Input_Format = "pdf", - Output_Format = "jpg", - Options = new Dictionary { - { "width", 800 }, - { "height", 600 }, - { "fit", "max" } - } + Input = "import_it", + Input_Format = "pdf", + Output_Format = "jpg", + Options = new Dictionary { + { "width", 800 }, + { "height", 600 }, + { "fit", "max" } } - }, - Tag = "integration-test-convert-with-options" - }); + } + }, + Tag = "integration-test-convert-with-options" + }); - var uploadTask = job.Data.Tasks.FirstOrDefault(t => t.Name == "import_it"); + var uploadTask = job.Data.Tasks.FirstOrDefault(t => t.Name == "import_it"); - var path = AppDomain.CurrentDomain.BaseDirectory + @"TestFiles/input.pdf"; + var path = AppDomain.CurrentDomain.BaseDirectory + @"TestFiles/input.pdf"; - byte[] file = File.ReadAllBytes(path); - await _cloudConvertAPI.UploadAsync(uploadTask.Result.Form.Url.ToString(), file, "input.pdf", uploadTask.Result.Form.Parameters); + byte[] file = File.ReadAllBytes(path); + await _cloudConvertAPI.UploadAsync(uploadTask.Result.Form.Url.ToString(), file, "input.pdf", uploadTask.Result.Form.Parameters); - // get created convert task + // get created convert task - var convertTask = await _cloudConvertAPI.GetTaskAsync(job.Data.Tasks.FirstOrDefault(t => t.Name == "convert_it").Id, "payload"); - dynamic payload = JsonSerializer.Deserialize(convertTask.Data.Payload.ToString()); - Assert.IsNotNull(payload); - Assert.AreEqual(800, ((JsonElement)payload.width).GetInt32()); - Assert.AreEqual(600, ((JsonElement)payload.height).GetInt32()); - Assert.AreEqual("max", ((JsonElement)payload.fit).GetString()); + var convertTask = await _cloudConvertAPI.GetTaskAsync(job.Data.Tasks.FirstOrDefault(t => t.Name == "convert_it").Id, "payload"); + dynamic payload = JsonSerializer.Deserialize(convertTask.Data.Payload.ToString()); + Assert.IsNotNull(payload); + Assert.AreEqual(800, ((JsonElement)payload.width).GetInt32()); + Assert.AreEqual(600, ((JsonElement)payload.height).GetInt32()); + Assert.AreEqual("max", ((JsonElement)payload.fit).GetString()); - } + } - [TestCase("stream")] - [TestCase("bytes")] - public async Task CreateTask(string streamingMethod) - { - // import + [TestCase("stream")] + [TestCase("bytes")] + public async Task CreateTask(string streamingMethod) + { + // import - var reqImport = new ImportUploadCreateRequest(); + var reqImport = new ImportUploadCreateRequest(); - var importTask = await _cloudConvertAPI.CreateTaskAsync(reqImport.Operation, reqImport); + var importTask = await _cloudConvertAPI.CreateTaskAsync(reqImport.Operation, reqImport); - var path = AppDomain.CurrentDomain.BaseDirectory + @"TestFiles/input.pdf"; - string fileName = "input.pdf"; + var path = AppDomain.CurrentDomain.BaseDirectory + @"TestFiles/input.pdf"; + string fileName = "input.pdf"; - switch (streamingMethod) + switch (streamingMethod) + { + case "bytes": { - case "bytes": - { - byte[] file = File.ReadAllBytes(path); - await _cloudConvertAPI.UploadAsync(importTask.Data.Result.Form.Url.ToString(), file, fileName, importTask.Data.Result.Form.Parameters); - break; - } - case "stream": - { - using (var stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read)) - await _cloudConvertAPI.UploadAsync(importTask.Data.Result.Form.Url.ToString(), stream, fileName, importTask.Data.Result.Form.Parameters); - break; - } + byte[] file = File.ReadAllBytes(path); + await _cloudConvertAPI.UploadAsync(importTask.Data.Result.Form.Url.ToString(), file, fileName, importTask.Data.Result.Form.Parameters); + break; } + case "stream": + { + using (var stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read)) + await _cloudConvertAPI.UploadAsync(importTask.Data.Result.Form.Url.ToString(), stream, fileName, importTask.Data.Result.Form.Parameters); + break; + } + } - importTask = await _cloudConvertAPI.WaitTaskAsync(importTask.Data.Id); + importTask = await _cloudConvertAPI.WaitTaskAsync(importTask.Data.Id); - Assert.IsNotNull(importTask); - Assert.AreEqual(importTask.Data.Status, API.Models.Enums.TaskStatus.finished); + Assert.IsNotNull(importTask); + Assert.AreEqual(importTask.Data.Status, API.Models.Enums.TaskStatus.finished); - // export + // export - var reqExport = new ExportUrlCreateRequest - { - Input = importTask.Data.Id - }; + var reqExport = new ExportUrlCreateRequest + { + Input = importTask.Data.Id + }; - var exportTask = await _cloudConvertAPI.CreateTaskAsync(reqExport.Operation, reqExport); + var exportTask = await _cloudConvertAPI.CreateTaskAsync(reqExport.Operation, reqExport); - Assert.IsNotNull(exportTask); + Assert.IsNotNull(exportTask); - exportTask = await _cloudConvertAPI.WaitTaskAsync(exportTask.Data.Id); + exportTask = await _cloudConvertAPI.WaitTaskAsync(exportTask.Data.Id); - Assert.IsNotNull(exportTask); - Assert.IsTrue(exportTask.Data.Status == API.Models.Enums.TaskStatus.finished); + Assert.IsNotNull(exportTask); + Assert.IsTrue(exportTask.Data.Status == API.Models.Enums.TaskStatus.finished); - var fileExport = exportTask.Data.Result.Files.FirstOrDefault(); + var fileExport = exportTask.Data.Result.Files.FirstOrDefault(); - Assert.IsNotNull(fileExport); - Assert.AreEqual(fileExport.Filename, "input.pdf"); + Assert.IsNotNull(fileExport); + Assert.AreEqual(fileExport.Filename, "input.pdf"); - using var httpClient = new HttpClient(); - var fileBytes = await httpClient.GetByteArrayAsync(fileExport.Url); - await File.WriteAllBytesAsync(fileExport.Filename, fileBytes); - } + using var httpClient = new HttpClient(); + var fileBytes = await httpClient.GetByteArrayAsync(fileExport.Url); + await File.WriteAllBytesAsync(fileExport.Filename, fileBytes); } } diff --git a/CloudConvert.Test/ServiceCollectionExtensionsTests.cs b/CloudConvert.Test/ServiceCollectionExtensionsTests.cs new file mode 100644 index 0000000..09beddf --- /dev/null +++ b/CloudConvert.Test/ServiceCollectionExtensionsTests.cs @@ -0,0 +1,66 @@ +using System; +using CloudConvert.API; +using CloudConvert.API.Extensions; +using Microsoft.Extensions.DependencyInjection; +using NUnit.Framework; + +namespace CloudConvert.Test; + +[TestFixture] +public class ServiceCollectionExtensionsTests +{ + private ServiceProvider BuildProvider(Action configure) + { + var services = new ServiceCollection(); + services.AddCloudConvertAPI(configure); + return services.BuildServiceProvider(); + } + + [Test] + public void AddCloudConvertAPI_ValidApiKey_ResolvesICloudConvertAPI() + { + using var provider = BuildProvider(o => o.ApiKey = "test_key"); + + var api = provider.GetService(); + + Assert.IsNotNull(api); + } + + [Test] + public void AddCloudConvertAPI_ValidApiKey_ResolvesAsCloudConvertAPI() + { + using var provider = BuildProvider(o => o.ApiKey = "test_key"); + + var api = provider.GetService(); + + Assert.IsInstanceOf(api); + } + + [TestCase(null)] + [TestCase("")] + [TestCase(" ")] + public void AddCloudConvertAPI_MissingApiKey_ThrowsArgumentException(string apiKey) + { + Assert.Throws(() => + BuildProvider(o => o.ApiKey = apiKey)); + } + + [Test] + public void AddCloudConvertAPI_RegisteredAsSingleton_ReturnsSameInstance() + { + using var provider = BuildProvider(o => o.ApiKey = "test_key"); + + var first = provider.GetService(); + var second = provider.GetService(); + + Assert.AreSame(first, second); + } + + [Test] + public void AddCloudConvertAPI_DefaultOptions_IsSandboxIsFalse() + { + var options = new CloudConvertOptions(); + + Assert.IsFalse(options.IsSandbox); + } +} diff --git a/CloudConvert.Test/TestJobs.cs b/CloudConvert.Test/TestJobs.cs index 9555f78..cb30933 100644 --- a/CloudConvert.Test/TestJobs.cs +++ b/CloudConvert.Test/TestJobs.cs @@ -10,125 +10,124 @@ using Moq; using NUnit.Framework; -namespace CloudConvert.Test +namespace CloudConvert.Test; + +public class TestJobs { - public class TestJobs - { - readonly Mock _cloudConvertAPI = new Mock(); + readonly Mock _cloudConvertAPI = new Mock(); - [Test] - public async Task GetAllJobs() + [Test] + public async Task GetAllJobs() + { + try { - try - { - JobListFilter filter = new JobListFilter(); + JobListFilter filter = new JobListFilter(); - var path = @"Responses/jobs.json"; - string json = File.ReadAllText(path); - _cloudConvertAPI.Setup(cc => cc.GetAllJobsAsync(filter, default)) - .ReturnsAsync(JsonSerializer.Deserialize>(json, DefaultJsonSerializerOptions.SerializerOptions)); + var path = @"Responses/jobs.json"; + string json = File.ReadAllText(path); + _cloudConvertAPI.Setup(cc => cc.GetAllJobsAsync(filter, default)) + .ReturnsAsync(JsonSerializer.Deserialize>(json, DefaultJsonSerializerOptions.SerializerOptions)); - var jobs = await _cloudConvertAPI.Object.GetAllJobsAsync(filter); + var jobs = await _cloudConvertAPI.Object.GetAllJobsAsync(filter); - Assert.IsNotNull(jobs); - Assert.IsTrue(jobs.Data.Count >= 0); - } - catch (WebApiException ex) + Assert.IsNotNull(jobs); + Assert.IsTrue(jobs.Data.Count >= 0); + } + catch (WebApiException ex) + { + if (ex.InnerException is not null) { - if (ex.InnerException != null) - { - var error = JsonSerializer.Deserialize(ex.InnerException.Message, DefaultJsonSerializerOptions.SerializerOptions); - } - else - { - var error = ex.Message; - } + var error = JsonSerializer.Deserialize(ex.InnerException.Message, DefaultJsonSerializerOptions.SerializerOptions); } - catch (Exception ex) + else { var error = ex.Message; } } - - [Test] - public async Task CreateJob() + catch (Exception ex) { - var req = new JobCreateRequest(); + var error = ex.Message; + } + } - var path = AppDomain.CurrentDomain.BaseDirectory + @"Responses/job_created.json"; - string json = File.ReadAllText(path); - _cloudConvertAPI.Setup(cc => cc.CreateJobAsync(req, default)) - .ReturnsAsync(JsonSerializer.Deserialize>(json, DefaultJsonSerializerOptions.SerializerOptions)); + [Test] + public async Task CreateJob() + { + var req = new JobCreateRequest(); - var job = await _cloudConvertAPI.Object.CreateJobAsync(req); + var path = AppDomain.CurrentDomain.BaseDirectory + @"Responses/job_created.json"; + string json = File.ReadAllText(path); + _cloudConvertAPI.Setup(cc => cc.CreateJobAsync(req, default)) + .ReturnsAsync(JsonSerializer.Deserialize>(json, DefaultJsonSerializerOptions.SerializerOptions)); - Assert.IsNotNull(job); - Assert.IsTrue(job.Data.Tasks.Count > 0); - Assert.AreEqual(job.Data.Status, "waiting"); - } + var job = await _cloudConvertAPI.Object.CreateJobAsync(req); - [Test] - public async Task GetJob() - { - string id = "cd82535b-0614-4b23-bbba-b24ab0e892f7"; + Assert.IsNotNull(job); + Assert.IsTrue(job.Data.Tasks.Count > 0); + Assert.AreEqual(job.Data.Status, "waiting"); + } - var path = AppDomain.CurrentDomain.BaseDirectory + @"Responses/job.json"; - string json = File.ReadAllText(path); - _cloudConvertAPI.Setup(cc => cc.GetJobAsync(id, default)) - .ReturnsAsync(JsonSerializer.Deserialize>(json, DefaultJsonSerializerOptions.SerializerOptions)); + [Test] + public async Task GetJob() + { + string id = "cd82535b-0614-4b23-bbba-b24ab0e892f7"; - var job = await _cloudConvertAPI.Object.GetJobAsync(id); + var path = AppDomain.CurrentDomain.BaseDirectory + @"Responses/job.json"; + string json = File.ReadAllText(path); + _cloudConvertAPI.Setup(cc => cc.GetJobAsync(id, default)) + .ReturnsAsync(JsonSerializer.Deserialize>(json, DefaultJsonSerializerOptions.SerializerOptions)); - Assert.IsNotNull(job); - Assert.IsTrue(job.Data.Tasks.Count > 0); - Assert.AreEqual(job.Data.Status, "error"); - } + var job = await _cloudConvertAPI.Object.GetJobAsync(id); - [Test] - public async Task WaitJob() - { - string id = "1087398b-077e-4e30-8971-1be424da232a"; + Assert.IsNotNull(job); + Assert.IsTrue(job.Data.Tasks.Count > 0); + Assert.AreEqual(job.Data.Status, "error"); + } - var path = AppDomain.CurrentDomain.BaseDirectory + @"Responses/job_finished.json"; - string json = File.ReadAllText(path); - _cloudConvertAPI.Setup(cc => cc.WaitJobAsync(id, default)) - .ReturnsAsync(JsonSerializer.Deserialize>(json, DefaultJsonSerializerOptions.SerializerOptions)); + [Test] + public async Task WaitJob() + { + string id = "1087398b-077e-4e30-8971-1be424da232a"; - var job = await _cloudConvertAPI.Object.WaitJobAsync(id); + var path = AppDomain.CurrentDomain.BaseDirectory + @"Responses/job_finished.json"; + string json = File.ReadAllText(path); + _cloudConvertAPI.Setup(cc => cc.WaitJobAsync(id, default)) + .ReturnsAsync(JsonSerializer.Deserialize>(json, DefaultJsonSerializerOptions.SerializerOptions)); - Assert.IsNotNull(job); - Assert.IsTrue(job.Data.Tasks.Count > 0); - Assert.AreEqual(job.Data.Status, "finished"); - } + var job = await _cloudConvertAPI.Object.WaitJobAsync(id); - [Test] - public async Task DeleteJob() - { - string id = "cd82535b-0614-4b23-bbba-b24ab0e892f7"; + Assert.IsNotNull(job); + Assert.IsTrue(job.Data.Tasks.Count > 0); + Assert.AreEqual(job.Data.Status, "finished"); + } - _cloudConvertAPI.Setup(cc => cc.DeleteJobAsync(id, default)); + [Test] + public async Task DeleteJob() + { + string id = "cd82535b-0614-4b23-bbba-b24ab0e892f7"; - await _cloudConvertAPI.Object.DeleteJobAsync(id); - } + _cloudConvertAPI.Setup(cc => cc.DeleteJobAsync(id, default)); - [Test] - public async Task DeleteJob_WithNoContentResponse_ShouldNotThrow() - { - // This test verifies that DeleteJobAsync correctly handles HTTP 204 No Content responses - // with empty response bodies, which was broken in v1.4.0 when switching from Newtonsoft.Json to System.Text.Json - string id = "cd82535b-0614-4b23-bbba-b24ab0e892f7"; + await _cloudConvertAPI.Object.DeleteJobAsync(id); + } + + [Test] + public async Task DeleteJob_WithNoContentResponse_ShouldNotThrow() + { + // This test verifies that DeleteJobAsync correctly handles HTTP 204 No Content responses + // with empty response bodies, which was broken in v1.4.0 when switching from Newtonsoft.Json to System.Text.Json + string id = "cd82535b-0614-4b23-bbba-b24ab0e892f7"; - var httpMessageHandlerMock = new Mock(); - httpMessageHandlerMock.MockNoContentResponse($"/jobs/{id}"); + var httpMessageHandlerMock = new Mock(); + httpMessageHandlerMock.MockNoContentResponse($"/jobs/{id}"); - var httpClient = new HttpClient(httpMessageHandlerMock.Object); - var restHelper = new RestHelper(httpClient); - var cloudConvertApi = new CloudConvertAPI(restHelper, "API_KEY"); + var httpClient = new HttpClient(httpMessageHandlerMock.Object); + var restHelper = new RestHelper(httpClient); + var cloudConvertApi = new CloudConvertAPI(restHelper, "API_KEY"); - // This should not throw an exception even though the response body is empty - await cloudConvertApi.DeleteJobAsync(id); + // This should not throw an exception even though the response body is empty + await cloudConvertApi.DeleteJobAsync(id); - httpMessageHandlerMock.VerifyRequest($"/jobs/{id}", Moq.Times.Once()); - } + httpMessageHandlerMock.VerifyRequest($"/jobs/{id}", Moq.Times.Once()); } } diff --git a/CloudConvert.Test/TestSignedUrl.cs b/CloudConvert.Test/TestSignedUrl.cs index 389c1f7..d4c9642 100644 --- a/CloudConvert.Test/TestSignedUrl.cs +++ b/CloudConvert.Test/TestSignedUrl.cs @@ -6,47 +6,46 @@ using NUnit.Framework; -namespace CloudConvert.Test +namespace CloudConvert.Test; + +public class TestSignedUrl { - public class TestSignedUrl + const string apiKey = ""; + readonly ICloudConvertAPI _cloudConvertAPI = new CloudConvertAPI(apiKey, true); + + [Test] + public void Sign() { - const string apiKey = ""; - readonly ICloudConvertAPI _cloudConvertAPI = new CloudConvertAPI(apiKey, true); - [Test] - public void Sign() + string baseUrl = "https://s.cloudconvert.com/b3d85428-584e-4639-bc11-76b7dee9c109"; + string signingSecret = "NT8dpJkttEyfSk3qlRgUJtvTkx64vhyX"; + string cacheKey = "mykey"; + + JobCreateRequest job = new JobCreateRequest { - - string baseUrl = "https://s.cloudconvert.com/b3d85428-584e-4639-bc11-76b7dee9c109"; - string signingSecret = "NT8dpJkttEyfSk3qlRgUJtvTkx64vhyX"; - string cacheKey = "mykey"; - - JobCreateRequest job = new JobCreateRequest + Tasks = new { - Tasks = new + import_example_1 = new ImportUploadCreateRequest(), + convert = new ConvertCreateRequest { - import_example_1 = new ImportUploadCreateRequest(), - convert = new ConvertCreateRequest - { - Input = "import_example_1", - Input_Format = "pdf", - Output_Format = "docx" - }, - export = new ExportUrlCreateRequest - { - Input = "convert" - } + Input = "import_example_1", + Input_Format = "pdf", + Output_Format = "docx" }, - - }; + export = new ExportUrlCreateRequest + { + Input = "convert" + } + }, + + }; - string signedUrl = _cloudConvertAPI.CreateSignedUrl(baseUrl, signingSecret, job, cacheKey); + string signedUrl = _cloudConvertAPI.CreateSignedUrl(baseUrl, signingSecret, job, cacheKey); - StringAssert.StartsWith(baseUrl, signedUrl); - StringAssert.Contains("?job=", signedUrl); - StringAssert.Contains("&cache_key=mykey", signedUrl); - StringAssert.Contains("&s=81213540c2ccdf3330a0cf237642f14b381f57cf5bbffe293eb118468fde700b", signedUrl); - } + StringAssert.StartsWith(baseUrl, signedUrl); + StringAssert.Contains("?job=", signedUrl); + StringAssert.Contains("&cache_key=mykey", signedUrl); + StringAssert.Contains("&s=81213540c2ccdf3330a0cf237642f14b381f57cf5bbffe293eb118468fde700b", signedUrl); } } diff --git a/CloudConvert.Test/TestTasks.cs b/CloudConvert.Test/TestTasks.cs index 19a4826..f5d9de2 100644 --- a/CloudConvert.Test/TestTasks.cs +++ b/CloudConvert.Test/TestTasks.cs @@ -13,166 +13,165 @@ using System.Text.Json; using NUnit.Framework; -namespace CloudConvert.Test +namespace CloudConvert.Test; + +public class TestTasks { - public class TestTasks + [Test] + public async Task GetAllTasks() { - [Test] - public async Task GetAllTasks() + try { - try - { - TaskListFilter filter = new TaskListFilter(); + TaskListFilter filter = new TaskListFilter(); - var path = @"Responses/tasks.json"; - string json = File.ReadAllText(path); + var path = @"Responses/tasks.json"; + string json = File.ReadAllText(path); - var cloudConvertApi = new Mock(); - cloudConvertApi.Setup(cc => cc.GetAllTasksAsync(filter, default)) - .ReturnsAsync(JsonSerializer.Deserialize>(json, DefaultJsonSerializerOptions.SerializerOptions)); + var cloudConvertApi = new Mock(); + cloudConvertApi.Setup(cc => cc.GetAllTasksAsync(filter, default)) + .ReturnsAsync(JsonSerializer.Deserialize>(json, DefaultJsonSerializerOptions.SerializerOptions)); - var tasks = await cloudConvertApi.Object.GetAllTasksAsync(filter); + var tasks = await cloudConvertApi.Object.GetAllTasksAsync(filter); - Assert.IsNotNull(tasks); - Assert.IsTrue(tasks.Data.Count >= 0); - } - catch (WebApiException ex) + Assert.IsNotNull(tasks); + Assert.IsTrue(tasks.Data.Count >= 0); + } + catch (WebApiException ex) + { + if (ex.InnerException is not null) { - if (ex.InnerException != null) - { - var error = JsonSerializer.Deserialize(ex.InnerException.Message, DefaultJsonSerializerOptions.SerializerOptions); - } - else - { - var error = ex.Message; - } + var error = JsonSerializer.Deserialize(ex.InnerException.Message, DefaultJsonSerializerOptions.SerializerOptions); } - catch (Exception ex) + else { var error = ex.Message; } } + catch (Exception ex) + { + var error = ex.Message; + } + } - [Test] - public async Task CreateTask() + [Test] + public async Task CreateTask() + { + var req = new ConvertCreateRequest { - var req = new ConvertCreateRequest - { - Input = "9ebdb9c7-ee41-4c08-9fb7-1f342289f712", //Guid import - Input_Format = "pdf", - Output_Format = "docx", - Engine = "bcl" - }; + Input = "9ebdb9c7-ee41-4c08-9fb7-1f342289f712", //Guid import + Input_Format = "pdf", + Output_Format = "docx", + Engine = "bcl" + }; - var path = AppDomain.CurrentDomain.BaseDirectory + @"Responses/task_created.json"; - string json = File.ReadAllText(path); + var path = AppDomain.CurrentDomain.BaseDirectory + @"Responses/task_created.json"; + string json = File.ReadAllText(path); - var cloudConvertApi = new Mock(); - cloudConvertApi.Setup(cc => cc.CreateTaskAsync(req.Operation, req, default)) - .ReturnsAsync(JsonSerializer.Deserialize>(json, DefaultJsonSerializerOptions.SerializerOptions)); + var cloudConvertApi = new Mock(); + cloudConvertApi.Setup(cc => cc.CreateTaskAsync(req.Operation, req, default)) + .ReturnsAsync(JsonSerializer.Deserialize>(json, DefaultJsonSerializerOptions.SerializerOptions)); - var task = await cloudConvertApi.Object.CreateTaskAsync(req.Operation, req); + var task = await cloudConvertApi.Object.CreateTaskAsync(req.Operation, req); - Assert.IsNotNull(task); - Assert.IsTrue(task.Data.Status == API.Models.Enums.TaskStatus.waiting); - } + Assert.IsNotNull(task); + Assert.IsTrue(task.Data.Status == API.Models.Enums.TaskStatus.waiting); + } - [Test] - public async Task GetTask() - { - string id = "9de1a620-952c-4482-9d44-681ae28d72a1"; + [Test] + public async Task GetTask() + { + string id = "9de1a620-952c-4482-9d44-681ae28d72a1"; - var path = AppDomain.CurrentDomain.BaseDirectory + @"Responses/task.json"; - string json = File.ReadAllText(path); + var path = AppDomain.CurrentDomain.BaseDirectory + @"Responses/task.json"; + string json = File.ReadAllText(path); - var _cloudConvertAPI = new Mock(); - _cloudConvertAPI.Setup(cc => cc.GetTaskAsync(id, null, default)) - .ReturnsAsync(JsonSerializer.Deserialize>(json, DefaultJsonSerializerOptions.SerializerOptions)); + var _cloudConvertAPI = new Mock(); + _cloudConvertAPI.Setup(cc => cc.GetTaskAsync(id, null, default)) + .ReturnsAsync(JsonSerializer.Deserialize>(json, DefaultJsonSerializerOptions.SerializerOptions)); - var task = await _cloudConvertAPI.Object.GetTaskAsync("9de1a620-952c-4482-9d44-681ae28d72a1"); + var task = await _cloudConvertAPI.Object.GetTaskAsync("9de1a620-952c-4482-9d44-681ae28d72a1"); - Assert.IsNotNull(task); - Assert.IsTrue(task.Data.Operation == "convert"); - } + Assert.IsNotNull(task); + Assert.IsTrue(task.Data.Operation == "convert"); + } - [Test] - public async Task WaitTask() - { - string id = "9de1a620-952c-4482-9d44-681ae28d72a1"; + [Test] + public async Task WaitTask() + { + string id = "9de1a620-952c-4482-9d44-681ae28d72a1"; - var path = AppDomain.CurrentDomain.BaseDirectory + @"Responses/task.json"; - string json = File.ReadAllText(path); + var path = AppDomain.CurrentDomain.BaseDirectory + @"Responses/task.json"; + string json = File.ReadAllText(path); - var cloudConvertApi = new Mock(); - cloudConvertApi.Setup(cc => cc.WaitTaskAsync(id, default)) - .ReturnsAsync(JsonSerializer.Deserialize>(json, DefaultJsonSerializerOptions.SerializerOptions)); + var cloudConvertApi = new Mock(); + cloudConvertApi.Setup(cc => cc.WaitTaskAsync(id, default)) + .ReturnsAsync(JsonSerializer.Deserialize>(json, DefaultJsonSerializerOptions.SerializerOptions)); - var task = await cloudConvertApi.Object.WaitTaskAsync(id); + var task = await cloudConvertApi.Object.WaitTaskAsync(id); - Assert.IsNotNull(task); - Assert.IsTrue(task.Data.Operation == "convert"); - Assert.AreEqual(task.Data.Status, API.Models.Enums.TaskStatus.finished); - } + Assert.IsNotNull(task); + Assert.IsTrue(task.Data.Operation == "convert"); + Assert.AreEqual(task.Data.Status, API.Models.Enums.TaskStatus.finished); + } - [Test] - public async Task DeleteTask() - { - string id = "9de1a620-952c-4482-9d44-681ae28d72a1"; + [Test] + public async Task DeleteTask() + { + string id = "9de1a620-952c-4482-9d44-681ae28d72a1"; - var cloudConvertApi = new Mock(); - cloudConvertApi.Setup(cc => cc.DeleteTaskAsync(id, default)); + var cloudConvertApi = new Mock(); + cloudConvertApi.Setup(cc => cc.DeleteTaskAsync(id, default)); - await cloudConvertApi.Object.DeleteTaskAsync("c8a8da46-3758-45bf-b983-2510e3170acb"); - } + await cloudConvertApi.Object.DeleteTaskAsync("c8a8da46-3758-45bf-b983-2510e3170acb"); + } - [Test] - public async Task Upload() - { - var cloudConvertApi = new Mock(); - var req = new ImportUploadCreateRequest(); + [Test] + public async Task Upload() + { + var cloudConvertApi = new Mock(); + var req = new ImportUploadCreateRequest(); - var path = AppDomain.CurrentDomain.BaseDirectory + @"Responses/upload_task_created.json"; - string json = File.ReadAllText(path); - cloudConvertApi.Setup(cc => cc.CreateTaskAsync(req.Operation, req, default)) - .ReturnsAsync(JsonSerializer.Deserialize>(json, DefaultJsonSerializerOptions.SerializerOptions)); + var path = AppDomain.CurrentDomain.BaseDirectory + @"Responses/upload_task_created.json"; + string json = File.ReadAllText(path); + cloudConvertApi.Setup(cc => cc.CreateTaskAsync(req.Operation, req, default)) + .ReturnsAsync(JsonSerializer.Deserialize>(json, DefaultJsonSerializerOptions.SerializerOptions)); - var task = await cloudConvertApi.Object.CreateTaskAsync(req.Operation, req); + var task = await cloudConvertApi.Object.CreateTaskAsync(req.Operation, req); - Assert.IsNotNull(task); + Assert.IsNotNull(task); - var pathFile = AppDomain.CurrentDomain.BaseDirectory + @"TestFiles/input.pdf"; - byte[] file = File.ReadAllBytes(pathFile); - string fileName = "input.pdf"; + var pathFile = AppDomain.CurrentDomain.BaseDirectory + @"TestFiles/input.pdf"; + byte[] file = File.ReadAllBytes(pathFile); + string fileName = "input.pdf"; - cloudConvertApi.Setup(cc => cc.UploadAsync(task.Data.Result.Form.Url.ToString(), file, fileName, task.Data.Result.Form.Parameters, default)); + cloudConvertApi.Setup(cc => cc.UploadAsync(task.Data.Result.Form.Url.ToString(), file, fileName, task.Data.Result.Form.Parameters, default)); - await cloudConvertApi.Object.UploadAsync(task.Data.Result.Form.Url.ToString(), file, fileName, task.Data.Result.Form.Parameters); - } + await cloudConvertApi.Object.UploadAsync(task.Data.Result.Form.Url.ToString(), file, fileName, task.Data.Result.Form.Parameters); + } - [Test] - public async Task UploadStream() - { - var httpMessageHandlerMock = new Mock(); - httpMessageHandlerMock.MockResponse("/import/upload", "upload_task_created.json"); - httpMessageHandlerMock.MockResponse("/tasks", "tasks.json"); + [Test] + public async Task UploadStream() + { + var httpMessageHandlerMock = new Mock(); + httpMessageHandlerMock.MockResponse("/import/upload", "upload_task_created.json"); + httpMessageHandlerMock.MockResponse("/tasks", "tasks.json"); - var httpClient = new HttpClient(httpMessageHandlerMock.Object); - var restHelper = new RestHelper(httpClient); - var req = new ImportUploadCreateRequest(); - var cloudConvertApi = new CloudConvertAPI(restHelper, "API_KEY"); + var httpClient = new HttpClient(httpMessageHandlerMock.Object); + var restHelper = new RestHelper(httpClient); + var req = new ImportUploadCreateRequest(); + var cloudConvertApi = new CloudConvertAPI(restHelper, "API_KEY"); - var task = await cloudConvertApi.CreateTaskAsync(req.Operation, req); + var task = await cloudConvertApi.CreateTaskAsync(req.Operation, req); - Assert.IsNotNull(task); - httpMessageHandlerMock.VerifyRequest("/import/upload", Times.Once()); + Assert.IsNotNull(task); + httpMessageHandlerMock.VerifyRequest("/import/upload", Times.Once()); - var streamMock = new Mock(); - var fileName = "input.pdf"; + var streamMock = new Mock(); + var fileName = "input.pdf"; - await cloudConvertApi.UploadAsync(task.Data.Result.Form.Url.ToString(), streamMock.Object, fileName, task.Data.Result.Form.Parameters); + await cloudConvertApi.UploadAsync(task.Data.Result.Form.Url.ToString(), streamMock.Object, fileName, task.Data.Result.Form.Parameters); - httpMessageHandlerMock.VerifyRequest("/tasks", Times.Once()); - streamMock.Protected().Verify("Dispose", Times.Never(), args: true); - } + httpMessageHandlerMock.VerifyRequest("/tasks", Times.Once()); + streamMock.Protected().Verify("Dispose", Times.Never(), args: true); } } diff --git a/CloudConvert.Test/TestWebhook.cs b/CloudConvert.Test/TestWebhook.cs index c5eadcc..e547530 100644 --- a/CloudConvert.Test/TestWebhook.cs +++ b/CloudConvert.Test/TestWebhook.cs @@ -3,22 +3,21 @@ using CloudConvert.API; using NUnit.Framework; -namespace CloudConvert.Test +namespace CloudConvert.Test; + +public class TestWebhook { - public class TestWebhook - { - const string apiKey = ""; - readonly ICloudConvertAPI _cloudConvertAPI = new CloudConvertAPI(apiKey, true); + const string apiKey = ""; + readonly ICloudConvertAPI _cloudConvertAPI = new CloudConvertAPI(apiKey, true); - [Test] - public void Verify() - { - var path = AppDomain.CurrentDomain.BaseDirectory + @"Responses/webhook_job_created_payload.json"; - string json = File.ReadAllText(path); + [Test] + public void Verify() + { + var path = AppDomain.CurrentDomain.BaseDirectory + @"Responses/webhook_job_created_payload.json"; + string json = File.ReadAllText(path); - var result = _cloudConvertAPI.ValidateWebhookSignatures(json, "88c3103f1d64282bf963af5dd8405ef26348af25b8903e10f0c288c11f0f907b", "9E1I8fQSLM7WsH1Y2Zp0uurYfhLqdERu"); + var result = _cloudConvertAPI.ValidateWebhookSignatures(json, "88c3103f1d64282bf963af5dd8405ef26348af25b8903e10f0c288c11f0f907b", "9E1I8fQSLM7WsH1Y2Zp0uurYfhLqdERu"); - Assert.IsTrue(result); - } + Assert.IsTrue(result); } } diff --git a/README.md b/README.md index 0a33edd..ffac2f7 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,55 @@ or dotnet add package CloudConvert.API ``` +## Dependency Injection + +If your application uses the .NET dependency injection container, you can register the CloudConvert API client using the `AddCloudConvertAPI` extension method: + +```CSharp +services.AddCloudConvertAPI(options => +{ + options.ApiKey = "your_api_key"; + options.IsSandbox = false; // defaults to false +}); +``` + +You can also bind options directly from your `appsettings.json`: + +```CSharp +services.AddCloudConvertAPI(options => + builder.Configuration.GetSection("CloudConvert").Bind(options)); +``` + +```json +{ + "CloudConvert": { + "ApiKey": "your_api_key", + "IsSandbox": false + } +} +``` + +Then inject `ICloudConvertAPI` wherever you need it: + +```CSharp +public class MyService(ICloudConvertAPI cloudConvert) +{ + public async Task DoSomething(CancellationToken cancellationToken) + { + var job = await cloudConvert.CreateJobAsync(..., cancellationToken); + } +} +``` + +If you are not using dependency injection, you can instantiate the client directly: + +```CSharp +var cloudConvert = new CloudConvertAPI("your_api_key"); +``` + ## Creating Jobs -```c# +```CSharp using CloudConvert.API; using CloudConvert.API.Models.ExportOperations; using CloudConvert.API.Models.ImportOperations; @@ -27,24 +73,24 @@ using CloudConvert.API.Models.TaskOperations; var _cloudConvert = new CloudConvertAPI("api_key"); var job = await _cloudConvert.CreateJobAsync(new JobCreateRequest - { - Tasks = new - { - import_example_1 = new ImportUploadCreateRequest(), - convert = new ConvertCreateRequest - { - Input = "import_example_1", - Input_Format = "pdf", - Output_Format = "docx" - }, - export = new ExportUrlCreateRequest - { - Input = "convert", - Archive_Multiple_Files = true - } - }, - Tag = "Test" - }); +{ + Tasks = new + { + import_example_1 = new ImportUploadCreateRequest(), + convert = new ConvertCreateRequest + { + Input = "import_example_1", + Input_Format = "pdf", + Output_Format = "docx" + }, + export = new ExportUrlCreateRequest + { + Input = "convert", + Archive_Multiple_Files = true + } + }, + Tag = "Test" +}); ``` You can use the [CloudConvert Job Builder](https://cloudconvert.com/api/v2/jobs/builder) to see the available options for the various task types. @@ -53,7 +99,7 @@ You can use the [CloudConvert Job Builder](https://cloudconvert.com/api/v2/jobs/ CloudConvert can generate public URLs for using `export/url` tasks. You can use these URLs to download output files. -```c# +```CSharp var job = await _cloudConvertAPI.WaitJobAsync(job.Data.Id); // Wait for job completion // download export file @@ -70,15 +116,15 @@ Uploads to CloudConvert are done via `import/upload` tasks (see the [docs](https First create the upload job with `CreateJobAsync`: -```c# +```CSharp var job = await _cloudConvertAPI.CreateJobAsync(new JobCreateRequest - { - Tasks = new - { - upload_my_file = new ImportUploadCreateRequest() - // ... - } - }); +{ + Tasks = new + { + upload_my_file = new ImportUploadCreateRequest() + // ... + } +}); var uploadTask = job.Data.Tasks.FirstOrDefault(t => t.Name == "upload_my_file"); ``` @@ -96,7 +142,7 @@ Then upload the file the file with `UploadAsync`. This can be done two ways: using (System.IO.Stream stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read)) { - await _cloudConvertAPI.UploadAsync(uploadTask.Result.Form.Url.ToString(), stream, fileName, uploadTask.Result.Form.Parameters); + await _cloudConvertAPI.UploadAsync(uploadTask.Result.Form.Url.ToString(), stream, fileName, uploadTask.Result.Form.Parameters); } ``` @@ -114,13 +160,14 @@ Then upload the file the file with `UploadAsync`. This can be done two ways: You can pass any custom options to the task payload via the special `Options` property: -```c# +```CSharp var task = new ConvertCreateRequest { Input = "import_example_1", Input_Format = "pdf", Output_Format = "jpg", - Options = new Dictionary { + Options = new Dictionary + { { "width", 800 }, { "height", 600 }, { "fit", "max" } @@ -133,7 +180,7 @@ You can use the [Job Builder](https://cloudconvert.com/api/v2/jobs/builder) to s The .net SDK allows to verify webhook requests received from CloudConvert. -```c# +```CSharp var payloadString = "..."; // The JSON string from the raw request body. var signature = "..."; // The value of the "CloudConvert-Signature" header. var signingSecret = "..."; // You can find it in your webhook settings. @@ -146,27 +193,27 @@ var isValid = _cloudConvertAPI.ValidateWebhookSignatures(payloadString, signatur Signed URLs allow converting files on demand only using URL query parameters. The .NET SDK allows to generate such URLs. Therefore, you need to obtain a signed URL base and a signing secret on the [CloudConvert Dashboard](https://cloudconvert.com/dashboard/api/v2/signed-urls). -```c# +```CSharp var signedUrlBase = 'https://s.cloudconvert.com/...'; // You can find it in your signed URL settings. var signingSecret = '...'; // You can find it in your signed URL settings. var cacheKey = 'cache-key'; // Allows caching of the result file for 24h var job = new JobCreateRequest +{ + Tasks = new + { + import_example_1 = new ImportUploadCreateRequest(), + convert = new ConvertCreateRequest + { + Input = "import_example_1", + Input_Format = "pdf", + Output_Format = "docx" + }, + export = new ExportUrlCreateRequest { - Tasks = new - { - import_example_1 = new ImportUploadCreateRequest(), - convert = new ConvertCreateRequest - { - Input = "import_example_1", - Input_Format = "pdf", - Output_Format = "docx" - }, - export = new ExportUrlCreateRequest - { - Input = "convert" - } - }, + Input = "convert" + } + } }; string signedUrl = _cloudConvertAPI.CreateSignedUrl(baseUrl, signingSecret, job, cacheKey) @@ -177,7 +224,7 @@ string signedUrl = _cloudConvertAPI.CreateSignedUrl(baseUrl, signingSecret, job, You can use the Sandbox to avoid consuming your quota while testing your application. The .net SDK allows you to do that. -```c# +```CSharp // Pass `true` to the constructor var _cloudConvert = new CloudConvertAPI("api_key", true); ``` @@ -198,4 +245,4 @@ By default, this runs the integration tests against the Sandbox API with an offi ## Resources - [API v2 Documentation](https://cloudconvert.com/api/v2) -- [CloudConvert Blog](https://cloudconvert.com/blog) +- [CloudConvert Blog](https://cloudconvert.com/blog) \ No newline at end of file