diff --git a/Octokit/Clients/IRepositoryContentsClient.cs b/Octokit/Clients/IRepositoryContentsClient.cs index 84b7db96..c9d1978f 100644 --- a/Octokit/Clients/IRepositoryContentsClient.cs +++ b/Octokit/Clients/IRepositoryContentsClient.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Threading.Tasks; +using Octokit.Internal; namespace Octokit { @@ -46,6 +47,32 @@ namespace Octokit /// Task GetReadmeHtml(string owner, string name); + /// + /// This method will return a 302 to a URL to download a tarball or zipball archive for a repository. + /// Please make sure your HTTP framework is configured to follow redirects or you will need to use the + /// Location header to make a second GET request. + /// Note: For private repositories, these links are temporary and expire quickly. + /// + /// https://developer.github.com/v3/repos/contents/#get-archive-link + /// The owner of the repository + /// The name of the repository + /// + Task GetArchiveLink(string owner, string name); + + /// + /// This method will return a 302 to a URL to download a tarball or zipball archive for a repository. + /// Please make sure your HTTP framework is configured to follow redirects or you will need to use the + /// Location header to make a second GET request. + /// Note: For private repositories, these links are temporary and expire quickly. + /// + /// https://developer.github.com/v3/repos/contents/#get-archive-link + /// The owner of the repository + /// The name of the repository + /// The format of the archive. Can be either tarball or zipball + /// A valid Git reference. + /// + Task GetArchiveLink(string owner, string name, ArchiveFormat archiveFormat, string reference); + /// /// Creates a commit that creates a new file in a repository. /// @@ -75,4 +102,14 @@ namespace Octokit /// Information about the file to delete Task DeleteFile(string owner, string name, string path, DeleteFileRequest request); } + + public enum ArchiveFormat + { + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Tarball")] + [Parameter(Value = "tarball")] + Tarball, + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Zipball")] + [Parameter(Value = "zipball")] + Zipball + } } \ No newline at end of file diff --git a/Octokit/Clients/RepositoryContentsClient.cs b/Octokit/Clients/RepositoryContentsClient.cs index 5cf1caae..b8d95913 100644 --- a/Octokit/Clients/RepositoryContentsClient.cs +++ b/Octokit/Clients/RepositoryContentsClient.cs @@ -74,6 +74,42 @@ namespace Octokit return ApiConnection.GetHtml(ApiUrls.RepositoryReadme(owner, name), null); } + /// + /// This method will return a 302 to a URL to download a tarball or zipball archive for a repository. + /// Please make sure your HTTP framework is configured to follow redirects or you will need to use the + /// Location header to make a second GET request. + /// Note: For private repositories, these links are temporary and expire quickly. + /// + /// https://developer.github.com/v3/repos/contents/#get-archive-link + /// The owner of the repository + /// The name of the repository + /// + public Task GetArchiveLink(string owner, string name) + { + return GetArchiveLink(owner, name, ArchiveFormat.Tarball, "master"); + } + + /// + /// This method will return a 302 to a URL to download a tarball or zipball archive for a repository. + /// Please make sure your HTTP framework is configured to follow redirects or you will need to use the + /// Location header to make a second GET request. + /// Note: For private repositories, these links are temporary and expire quickly. + /// + /// https://developer.github.com/v3/repos/contents/#get-archive-link + /// The owner of the repository + /// The name of the repository + /// The format of the archive. Can be either tarball or zipball + /// A valid Git reference. + /// + public Task GetArchiveLink(string owner, string name, ArchiveFormat archiveFormat, string reference) + { + Ensure.ArgumentNotNullOrEmptyString(owner, "owner"); + Ensure.ArgumentNotNullOrEmptyString(name, "name"); + Ensure.ArgumentNotNullOrEmptyString(reference, "reference"); + + return ApiConnection.GetRedirect(ApiUrls.RepositoryArchiveLink(owner, name, archiveFormat, reference)); + } + /// /// Creates a commit that creates a new file in a repository. /// diff --git a/Octokit/Helpers/ApiUrls.cs b/Octokit/Helpers/ApiUrls.cs index fbf71833..357b66c3 100644 --- a/Octokit/Helpers/ApiUrls.cs +++ b/Octokit/Helpers/ApiUrls.cs @@ -1467,5 +1467,10 @@ namespace Octokit { return "repos/{0}/{1}/contents/{2}".FormatUri(owner, name, path); } + + public static Uri RepositoryArchiveLink(string owner, string name, ArchiveFormat archiveFormat, string reference) + { + return "repos/{0}/{1}/{2}/{3}".FormatUri(owner, name, archiveFormat.ToParameter(), reference); + } } } diff --git a/Octokit/Http/ApiConnection.cs b/Octokit/Http/ApiConnection.cs index 145ef8ab..88f968db 100644 --- a/Octokit/Http/ApiConnection.cs +++ b/Octokit/Http/ApiConnection.cs @@ -386,6 +386,20 @@ namespace Octokit return Connection.Delete(uri, data); } + public async Task GetRedirect(Uri uri) + { + Ensure.ArgumentNotNull(uri, "uri"); + var response = await Connection.GetResponse(uri); + + if (response.HttpResponse.StatusCode == HttpStatusCode.Redirect) + { + return response.HttpResponse.Headers["Location"]; + } + + throw new ApiException("Redirect Operation expect status code or Redirect.", + response.HttpResponse.StatusCode); + } + /// /// Executes a GET to the API object at the specified URI. This operation is appropriate for /// API calls which queue long running calculations. diff --git a/Octokit/Http/IApiConnection.cs b/Octokit/Http/IApiConnection.cs index 9c6fee79..6c9583bd 100644 --- a/Octokit/Http/IApiConnection.cs +++ b/Octokit/Http/IApiConnection.cs @@ -232,6 +232,8 @@ namespace Octokit /// A for the request's execution. Task Delete(Uri uri, object data); + Task GetRedirect(Uri uri); + /// /// Executes a GET to the API object at the specified URI. This operation is appropriate for /// API calls which queue long running calculations.