using System; using System.Collections.Generic; using System.Net; using System.Threading; using System.Threading.Tasks; using Octokit.Internal; namespace Octokit { /// /// A connection for making API requests against URI endpoints. /// Provides type-friendly convenience methods that wrap methods. /// public class ApiConnection : IApiConnection { readonly IApiPagination _pagination; /// /// Initializes a new instance of the class. /// /// A connection for making HTTP requests public ApiConnection(IConnection connection) : this(connection, new ApiPagination()) { } /// /// Initializes a new instance of the class. /// /// A connection for making HTTP requests /// A paginator for paging API responses protected ApiConnection(IConnection connection, IApiPagination pagination) { Ensure.ArgumentNotNull(connection, "connection"); Ensure.ArgumentNotNull(pagination, "pagination"); Connection = connection; _pagination = pagination; } /// /// The underlying connection. /// public IConnection Connection { get; private set; } /// /// Gets the API resource at the specified URI. /// /// Type of the API resource to get. /// URI of the API resource to get /// Parameters to add to the API request /// The API resource. /// Thrown when an API error occurs. public async Task Get(Uri uri, IDictionary parameters) { Ensure.ArgumentNotNull(uri, "uri"); var response = await Connection.GetAsync(uri, parameters, null).ConfigureAwait(false); return response.BodyAsObject; } /// /// Gets the API resource at the specified URI. /// /// Type of the API resource to get. /// URI of the API resource to get /// Parameters to add to the API request /// Accept header to use for the API request /// The API resource. /// Thrown when an API error occurs. public async Task Get(Uri uri, IDictionary parameters, string accepts) { Ensure.ArgumentNotNull(uri, "uri"); var response = await Connection.GetAsync(uri, parameters, accepts).ConfigureAwait(false); return response.BodyAsObject; } /// /// Gets the HTML content of the API resource at the specified URI. /// /// URI of the API resource to get /// Parameters to add to the API request /// The API resource's HTML content. /// Thrown when an API error occurs. public async Task GetHtml(Uri uri, IDictionary parameters) { Ensure.ArgumentNotNull(uri, "uri"); var response = await Connection.GetHtml(uri, parameters).ConfigureAwait(false); return response.Body; } /// /// Gets all API resources in the list at the specified URI. /// /// Type of the API resource in the list. /// URI of the API resource to get /// of the The API resources in the list. /// Thrown when an API error occurs. public Task> GetAll(Uri uri) { return GetAll(uri, null, null); } /// /// Gets all API resources in the list at the specified URI. /// /// Type of the API resource in the list. /// URI of the API resource to get /// Parameters to add to the API request /// of the The API resources in the list. /// Thrown when an API error occurs. public Task> GetAll(Uri uri, IDictionary parameters) { return GetAll(uri, parameters, null); } /// /// Gets all API resources in the list at the specified URI. /// /// Type of the API resource in the list. /// URI of the API resource to get /// Parameters to add to the API request /// Accept header to use for the API request /// of the The API resources in the list. /// Thrown when an API error occurs. public Task> GetAll(Uri uri, IDictionary parameters, string accepts) { Ensure.ArgumentNotNull(uri, "uri"); return _pagination.GetAllPages(async () => await GetPage(uri, parameters, accepts) .ConfigureAwait(false), uri); } /// /// Creates a new API resource in the list at the specified URI. /// /// The API resource's type. /// URI of the API resource to get /// Object that describes the new API resource; this will be serialized and used as the request's body /// The created API resource. /// Thrown when an API error occurs. public Task Post(Uri uri, object data) { Ensure.ArgumentNotNull(uri, "uri"); Ensure.ArgumentNotNull(data, "data"); return Post(uri, data, null, null); } /// /// Creates a new API resource in the list at the specified URI. /// /// The API resource's type. /// URI of the API resource to get /// Object that describes the new API resource; this will be serialized and used as the request's body /// Accept header to use for the API request /// The created API resource. /// Thrown when an API error occurs. public Task Post(Uri uri, object data, string accepts) { return Post(uri, data, accepts, null); } /// /// Creates a new API resource in the list at the specified URI. /// /// The API resource's type. /// URI of the API resource to get /// Object that describes the new API resource; this will be serialized and used as the request's body /// Accept header to use for the API request /// Content type of the API request /// The created API resource. /// Thrown when an API error occurs. public async Task Post(Uri uri, object data, string accepts, string contentType) { Ensure.ArgumentNotNull(uri, "uri"); Ensure.ArgumentNotNull(data, "data"); var response = await Connection.PostAsync( uri, data, accepts, contentType).ConfigureAwait(false); return response.BodyAsObject; } /// /// Creates or replaces the API resource at the specified URI /// /// URI of the API resource to put /// A for the request's execution. public Task Put(Uri uri) { Ensure.ArgumentNotNull(uri, "uri"); return Connection.PutAsync(uri); } /// /// Creates or replaces the API resource at the specified URI. /// /// The API resource's type. /// URI of the API resource to create or replace /// Object that describes the API resource; this will be serialized and used as the request's body /// The created API resource. /// Thrown when an API error occurs. public async Task Put(Uri uri, object data) { Ensure.ArgumentNotNull(uri, "uri"); Ensure.ArgumentNotNull(data, "data"); var response = await Connection.PutAsync(uri, data).ConfigureAwait(false); return response.BodyAsObject; } /// /// Creates or replaces the API resource at the specified URI. /// /// The API resource's type. /// URI of the API resource to create or replace /// Object that describes the API resource; this will be serialized and used as the request's body /// The two-factor authentication code in response to the current user's previous challenge /// The created API resource. /// Thrown when an API error occurs. public async Task Put(Uri uri, object data, string twoFactorAuthenticationCode) { Ensure.ArgumentNotNull(uri, "uri"); Ensure.ArgumentNotNull(data, "data"); Ensure.ArgumentNotNullOrEmptyString(twoFactorAuthenticationCode, "twoFactorAuthenticationCode"); var response = await Connection.PutAsync(uri, data, twoFactorAuthenticationCode).ConfigureAwait(false); return response.BodyAsObject; } /// /// Updates the API resource at the specified URI. /// /// The API resource's type. /// URI of the API resource to update /// /// Object that describes the API resource; this will be serialized and used as the request's body /// The updated API resource. /// Thrown when an API error occurs. public async Task Patch(Uri uri, object data) { Ensure.ArgumentNotNull(uri, "uri"); Ensure.ArgumentNotNull(data, "data"); var response = await Connection.PatchAsync(uri, data).ConfigureAwait(false); return response.BodyAsObject; } /// /// Updates the API resource at the specified URI. /// /// The API resource's type. /// URI of the API resource to update /// Object that describes the API resource; this will be serialized and used as the request's body /// Accept header to use for the API request /// The updated API resource. /// Thrown when an API error occurs. public async Task Patch(Uri uri, object data, string accepts) { Ensure.ArgumentNotNull(uri, "uri"); Ensure.ArgumentNotNull(data, "data"); var response = await Connection.PatchAsync(uri, data, accepts).ConfigureAwait(false); return response.BodyAsObject; } /// /// Deletes the API object at the specified URI. /// /// URI of the API resource to delete /// A for the request's execution. public Task Delete(Uri uri) { Ensure.ArgumentNotNull(uri, "uri"); return Connection.DeleteAsync(uri); } /// /// Executes a GET to the API object at the specified URI. This operation is appropriate for /// API calls which queue long running calculations. /// It expects the API to respond with an initial 202 Accepted, and queries again until a /// 200 OK is received. /// /// The API resource's type. /// URI of the API resource to update /// A token used to cancel this potentially long running request /// The updated API resource. /// Thrown when an API error occurs. public async Task GetQueuedOperation(Uri uri, CancellationToken cancellationToken) { Ensure.ArgumentNotNull(uri, "uri"); var response = await Connection.GetAsync(uri, cancellationToken); if (response.StatusCode == HttpStatusCode.Accepted) { return await GetQueuedOperation(uri, cancellationToken); } if (response.StatusCode == HttpStatusCode.OK) { return response.BodyAsObject; } throw new ApiException("Queued Operations expect status codes of Accepted or OK.",response.StatusCode); } async Task> GetPage( Uri uri, IDictionary parameters, string accepts) { Ensure.ArgumentNotNull(uri, "uri"); var response = await Connection.GetAsync>(uri, parameters, accepts).ConfigureAwait(false); return new ReadOnlyPagedCollection( response, nextPageUri => Connection.GetAsync>(nextPageUri, parameters, accepts)); } } }