Skip to content

Commit

Permalink
feat: support getDownloadUrl in C# (box/box-codegen#642)
Browse files Browse the repository at this point in the history
  • Loading branch information
box-sdk-build committed Jan 17, 2025
1 parent 1108607 commit 98faee5
Show file tree
Hide file tree
Showing 19 changed files with 474 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .codegen.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{ "engineHash": "458e7a8", "specHash": "cf0a265", "version": "1.5.0" }
{ "engineHash": "553616e", "specHash": "cf0a265", "version": "1.5.0" }
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,14 @@ public async System.Threading.Tasks.Task TestDownloadFile() {
await client.Files.DeleteFileByIdAsync(fileId: uploadedFile.Id);
}

[TestMethod]
public async System.Threading.Tasks.Task TestGetDownloadUrl() {
FileFull uploadedFile = await new CommonsManager().UploadNewFileAsync();
string downloadUrl = await client.Downloads.GetDownloadFileUrlAsync(fileId: uploadedFile.Id);
Assert.IsTrue(downloadUrl != null);
Assert.IsTrue(downloadUrl.Contains("https://"));
await client.Files.DeleteFileByIdAsync(fileId: uploadedFile.Id);
}

}
}
11 changes: 11 additions & 0 deletions Box.Sdk.Gen.Tests.Integration/Test/Files/FilesManagerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,17 @@ public async System.Threading.Tasks.Task<FileFull> UploadFileAsync(string fileNa
return NullableUtils.Unwrap(uploadedFiles.Entries)[0];
}

[TestMethod]
public async System.Threading.Tasks.Task TestGetFileThumbnailUrl() {
string thumbnailFileName = Utils.GetUUID();
System.IO.Stream thumbnailContentStream = Utils.GenerateByteStream(size: 1024 * 1024);
FileFull thumbnailFile = await UploadFileAsync(fileName: thumbnailFileName, fileStream: thumbnailContentStream);
string downloadUrl = await client.Files.GetFileThumbnailUrlAsync(fileId: thumbnailFile.Id, extension: GetFileThumbnailUrlExtension.Png);
Assert.IsTrue(downloadUrl != null);
Assert.IsTrue(downloadUrl.Contains("https://"));
await client.Files.DeleteFileByIdAsync(fileId: thumbnailFile.Id);
}

[TestMethod]
public async System.Threading.Tasks.Task TestGetFileThumbnail() {
string thumbnailFileName = Utils.GetUUID();
Expand Down
2 changes: 1 addition & 1 deletion Box.Sdk.Gen/Box/JwtAuth/JwtConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public class JwtConfig {
/// </summary>
public string? UserId { get; init; }

internal JwtAlgorithm? Algorithm { get; }
internal JwtAlgorithm? Algorithm { get; init; } = JwtAlgorithm.Rs256;

public ITokenStorage TokenStorage { get; }

Expand Down
2 changes: 1 addition & 1 deletion Box.Sdk.Gen/Client/BoxClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ public BoxClient(IAuthentication auth, NetworkSession? networkSession = default)
public async System.Threading.Tasks.Task<FetchResponse> MakeRequestAsync(FetchOptions fetchOptions) {
IAuthentication auth = fetchOptions.Auth == null ? this.Auth : NullableUtils.Unwrap(fetchOptions.Auth);
NetworkSession networkSession = fetchOptions.NetworkSession == null ? this.NetworkSession : NullableUtils.Unwrap(fetchOptions.NetworkSession);
FetchOptions enrichedFetchOptions = new FetchOptions(url: fetchOptions.Url, method: fetchOptions.Method, contentType: fetchOptions.ContentType, responseFormat: fetchOptions.ResponseFormat) { Auth = auth, NetworkSession = networkSession, Parameters = fetchOptions.Parameters, Headers = fetchOptions.Headers, Data = fetchOptions.Data, FileStream = fetchOptions.FileStream, MultipartData = fetchOptions.MultipartData };
FetchOptions enrichedFetchOptions = new FetchOptions(url: fetchOptions.Url, method: fetchOptions.Method, contentType: fetchOptions.ContentType, responseFormat: fetchOptions.ResponseFormat) { Auth = auth, NetworkSession = networkSession, Parameters = fetchOptions.Parameters, Headers = fetchOptions.Headers, Data = fetchOptions.Data, FileStream = fetchOptions.FileStream, MultipartData = fetchOptions.MultipartData, FollowRedirects = fetchOptions.FollowRedirects };
return await networkSession.NetworkClient.FetchAsync(options: enrichedFetchOptions).ConfigureAwait(false);
}

Expand Down
37 changes: 37 additions & 0 deletions Box.Sdk.Gen/Managers/Downloads/DownloadsManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,43 @@ public class DownloadsManager : IDownloadsManager {
public DownloadsManager(NetworkSession? networkSession = default) {
NetworkSession = networkSession ?? new NetworkSession();
}
/// <summary>
/// Returns the contents of a file in binary format.
/// </summary>
/// <param name="fileId">
/// The unique identifier that represents a file.
///
/// The ID for any file can be determined
/// by visiting a file in the web application
/// and copying the ID from the URL. For example,
/// for the URL `https://*.app.box.com/files/123`
/// the `file_id` is `123`.
/// Example: "12345"
/// </param>
/// <param name="queryParams">
/// Query parameters of downloadFile method
/// </param>
/// <param name="headers">
/// Headers of downloadFile method
/// </param>
/// <param name="cancellationToken">
/// Token used for request cancellation.
/// </param>
public async System.Threading.Tasks.Task<string> GetDownloadFileUrlAsync(string fileId, GetDownloadFileUrlQueryParams? queryParams = default, GetDownloadFileUrlHeaders? headers = default, System.Threading.CancellationToken? cancellationToken = null) {
queryParams = queryParams ?? new GetDownloadFileUrlQueryParams();
headers = headers ?? new GetDownloadFileUrlHeaders();
Dictionary<string, string> queryParamsMap = Utils.PrepareParams(map: new Dictionary<string, string?>() { { "version", StringUtils.ToStringRepresentation(queryParams.Version) }, { "access_token", StringUtils.ToStringRepresentation(queryParams.AccessTokenField) } });
Dictionary<string, string> headersMap = Utils.PrepareParams(map: DictionaryUtils.MergeDictionaries(new Dictionary<string, string?>() { { "range", StringUtils.ToStringRepresentation(headers.Range) }, { "boxapi", StringUtils.ToStringRepresentation(headers.Boxapi) } }, headers.ExtraHeaders));
FetchResponse response = await this.NetworkSession.NetworkClient.FetchAsync(options: new FetchOptions(url: string.Concat(this.NetworkSession.BaseUrls.BaseUrl, "/2.0/files/", StringUtils.ToStringRepresentation(fileId), "/content"), method: "GET", responseFormat: Box.Sdk.Gen.ResponseFormat.NoContent) { Parameters = queryParamsMap, Headers = headersMap, Auth = this.Auth, NetworkSession = this.NetworkSession, CancellationToken = cancellationToken, FollowRedirects = false }).ConfigureAwait(false);
if (response.Headers.ContainsKey("location")) {
return response.Headers["location"];
}
if (response.Headers.ContainsKey("Location")) {
return response.Headers["Location"];
}
throw new BoxSdkException(message: "No location header in response");
}

/// <summary>
/// Returns the contents of a file in binary format.
/// </summary>
Expand Down
40 changes: 40 additions & 0 deletions Box.Sdk.Gen/Managers/Downloads/GetDownloadFileUrlHeaders.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using Box.Sdk.Gen;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Box.Sdk.Gen.Internal;
using Box.Sdk.Gen.Schemas;

namespace Box.Sdk.Gen.Managers {
public class GetDownloadFileUrlHeaders {
/// <summary>
/// The byte range of the content to download.
///
/// The format `bytes={start_byte}-{end_byte}` can be used to specify
/// what section of the file to download.
/// </summary>
public string? Range { get; init; }

/// <summary>
/// The URL, and optional password, for the shared link of this item.
///
/// This header can be used to access items that have not been
/// explicitly shared with a user.
///
/// Use the format `shared_link=[link]` or if a password is required then
/// use `shared_link=[link]&shared_link_password=[password]`.
///
/// This header can be used on the file or folder shared, as well as on any files
/// or folders nested within the item.
/// </summary>
public string? Boxapi { get; init; }

/// <summary>
/// Extra headers that will be included in the HTTP request.
/// </summary>
public Dictionary<string, string?> ExtraHeaders { get; }

public GetDownloadFileUrlHeaders(Dictionary<string, string?>? extraHeaders = default) {
ExtraHeaders = extraHeaders ?? new Dictionary<string, string?>() { };
}
}
}
24 changes: 24 additions & 0 deletions Box.Sdk.Gen/Managers/Downloads/GetDownloadFileUrlQueryParams.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Box.Sdk.Gen;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Box.Sdk.Gen.Internal;
using Box.Sdk.Gen.Schemas;

namespace Box.Sdk.Gen.Managers {
public class GetDownloadFileUrlQueryParams {
/// <summary>
/// The file version to download
/// </summary>
public string? Version { get; init; }

/// <summary>
/// An optional access token that can be used to pre-authenticate this request, which means that a download link can be shared with a browser or a third party service without them needing to know how to handle the authentication.
/// When using this parameter, please make sure that the access token is sufficiently scoped down to only allow read access to that file and no other files or folders.
/// </summary>
public string? AccessTokenField { get; init; }

public GetDownloadFileUrlQueryParams() {

}
}
}
24 changes: 24 additions & 0 deletions Box.Sdk.Gen/Managers/Downloads/IDownloadsManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,30 @@ public interface IDownloadsManager {
/// <param name="cancellationToken">
/// Token used for request cancellation.
/// </param>
public System.Threading.Tasks.Task<string> GetDownloadFileUrlAsync(string fileId, GetDownloadFileUrlQueryParams? queryParams = default, GetDownloadFileUrlHeaders? headers = default, System.Threading.CancellationToken? cancellationToken = null) => throw new System.NotImplementedException("This method needs to be implemented by the derived class before calling it.");

/// <summary>
/// Returns the contents of a file in binary format.
/// </summary>
/// <param name="fileId">
/// The unique identifier that represents a file.
///
/// The ID for any file can be determined
/// by visiting a file in the web application
/// and copying the ID from the URL. For example,
/// for the URL `https://*.app.box.com/files/123`
/// the `file_id` is `123`.
/// Example: "12345"
/// </param>
/// <param name="queryParams">
/// Query parameters of downloadFile method
/// </param>
/// <param name="headers">
/// Headers of downloadFile method
/// </param>
/// <param name="cancellationToken">
/// Token used for request cancellation.
/// </param>
public System.Threading.Tasks.Task<System.IO.Stream?> DownloadFileAsync(string fileId, DownloadFileQueryParams? queryParams = default, DownloadFileHeaders? headers = default, System.Threading.CancellationToken? cancellationToken = null) => throw new System.NotImplementedException("This method needs to be implemented by the derived class before calling it.");

}
Expand Down
50 changes: 50 additions & 0 deletions Box.Sdk.Gen/Managers/Files/FilesManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,56 @@ public async System.Threading.Tasks.Task<FileFull> CopyFileAsync(string fileId,
return SimpleJsonSerializer.Deserialize<FileFull>(NullableUtils.Unwrap(response.Data));
}

/// <summary>
/// Retrieves a thumbnail, or smaller image representation, of a file.
///
/// Sizes of `32x32`,`64x64`, `128x128`, and `256x256` can be returned in
/// the `.png` format and sizes of `32x32`, `160x160`, and `320x320`
/// can be returned in the `.jpg` format.
///
/// Thumbnails can be generated for the image and video file formats listed
/// [found on our community site][1].
///
/// [1]: https://community.box.com/t5/Migrating-and-Previewing-Content/File-Types-and-Fonts-Supported-in-Box-Content-Preview/ta-p/327
/// </summary>
/// <param name="fileId">
/// The unique identifier that represents a file.
///
/// The ID for any file can be determined
/// by visiting a file in the web application
/// and copying the ID from the URL. For example,
/// for the URL `https://*.app.box.com/files/123`
/// the `file_id` is `123`.
/// Example: "12345"
/// </param>
/// <param name="extension">
/// The file format for the thumbnail
/// Example: "png"
/// </param>
/// <param name="queryParams">
/// Query parameters of getFileThumbnailById method
/// </param>
/// <param name="headers">
/// Headers of getFileThumbnailById method
/// </param>
/// <param name="cancellationToken">
/// Token used for request cancellation.
/// </param>
public async System.Threading.Tasks.Task<string> GetFileThumbnailUrlAsync(string fileId, GetFileThumbnailUrlExtension extension, GetFileThumbnailUrlQueryParams? queryParams = default, GetFileThumbnailUrlHeaders? headers = default, System.Threading.CancellationToken? cancellationToken = null) {
queryParams = queryParams ?? new GetFileThumbnailUrlQueryParams();
headers = headers ?? new GetFileThumbnailUrlHeaders();
Dictionary<string, string> queryParamsMap = Utils.PrepareParams(map: new Dictionary<string, string?>() { { "min_height", StringUtils.ToStringRepresentation(queryParams.MinHeight) }, { "min_width", StringUtils.ToStringRepresentation(queryParams.MinWidth) }, { "max_height", StringUtils.ToStringRepresentation(queryParams.MaxHeight) }, { "max_width", StringUtils.ToStringRepresentation(queryParams.MaxWidth) } });
Dictionary<string, string> headersMap = Utils.PrepareParams(map: DictionaryUtils.MergeDictionaries(new Dictionary<string, string?>() { }, headers.ExtraHeaders));
FetchResponse response = await this.NetworkSession.NetworkClient.FetchAsync(options: new FetchOptions(url: string.Concat(this.NetworkSession.BaseUrls.BaseUrl, "/2.0/files/", StringUtils.ToStringRepresentation(fileId), "/thumbnail.", StringUtils.ToStringRepresentation(extension)), method: "GET", responseFormat: Box.Sdk.Gen.ResponseFormat.NoContent) { Parameters = queryParamsMap, Headers = headersMap, Auth = this.Auth, NetworkSession = this.NetworkSession, CancellationToken = cancellationToken, FollowRedirects = false }).ConfigureAwait(false);
if (response.Headers.ContainsKey("location")) {
return response.Headers["location"];
}
if (response.Headers.ContainsKey("Location")) {
return response.Headers["Location"];
}
throw new BoxSdkException(message: "No location header in response");
}

/// <summary>
/// Retrieves a thumbnail, or smaller image representation, of a file.
///
Expand Down
12 changes: 12 additions & 0 deletions Box.Sdk.Gen/Managers/Files/GetFileThumbnailUrlExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.ComponentModel;
using Box.Sdk.Gen.Internal;
using Box.Sdk.Gen.Schemas;

namespace Box.Sdk.Gen.Managers {
public enum GetFileThumbnailUrlExtension {
[Description("png")]
Png,
[Description("jpg")]
Jpg
}
}
20 changes: 20 additions & 0 deletions Box.Sdk.Gen/Managers/Files/GetFileThumbnailUrlHeaders.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Box.Sdk.Gen;
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using Box.Sdk.Gen.Internal;
using Box.Sdk.Gen.Schemas;

namespace Box.Sdk.Gen.Managers {
public class GetFileThumbnailUrlHeaders {
/// <summary>
/// Extra headers that will be included in the HTTP request.
/// </summary>
public Dictionary<string, string?> ExtraHeaders { get; }

public GetFileThumbnailUrlHeaders(Dictionary<string, string?>? extraHeaders = default) {
ExtraHeaders = extraHeaders ?? new Dictionary<string, string?>() { };
}
}
}
35 changes: 35 additions & 0 deletions Box.Sdk.Gen/Managers/Files/GetFileThumbnailUrlQueryParams.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using Box.Sdk.Gen;
using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using Box.Sdk.Gen.Internal;
using Box.Sdk.Gen.Schemas;

namespace Box.Sdk.Gen.Managers {
public class GetFileThumbnailUrlQueryParams {
/// <summary>
/// The minimum height of the thumbnail
/// </summary>
public long? MinHeight { get; init; }

/// <summary>
/// The minimum width of the thumbnail
/// </summary>
public long? MinWidth { get; init; }

/// <summary>
/// The maximum height of the thumbnail
/// </summary>
public long? MaxHeight { get; init; }

/// <summary>
/// The maximum width of the thumbnail
/// </summary>
public long? MaxWidth { get; init; }

public GetFileThumbnailUrlQueryParams() {

}
}
}
37 changes: 37 additions & 0 deletions Box.Sdk.Gen/Managers/Files/IFilesManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,43 @@ public interface IFilesManager {
/// <param name="cancellationToken">
/// Token used for request cancellation.
/// </param>
public System.Threading.Tasks.Task<string> GetFileThumbnailUrlAsync(string fileId, GetFileThumbnailUrlExtension extension, GetFileThumbnailUrlQueryParams? queryParams = default, GetFileThumbnailUrlHeaders? headers = default, System.Threading.CancellationToken? cancellationToken = null) => throw new System.NotImplementedException("This method needs to be implemented by the derived class before calling it.");

/// <summary>
/// Retrieves a thumbnail, or smaller image representation, of a file.
///
/// Sizes of `32x32`,`64x64`, `128x128`, and `256x256` can be returned in
/// the `.png` format and sizes of `32x32`, `160x160`, and `320x320`
/// can be returned in the `.jpg` format.
///
/// Thumbnails can be generated for the image and video file formats listed
/// [found on our community site][1].
///
/// [1]: https://community.box.com/t5/Migrating-and-Previewing-Content/File-Types-and-Fonts-Supported-in-Box-Content-Preview/ta-p/327
/// </summary>
/// <param name="fileId">
/// The unique identifier that represents a file.
///
/// The ID for any file can be determined
/// by visiting a file in the web application
/// and copying the ID from the URL. For example,
/// for the URL `https://*.app.box.com/files/123`
/// the `file_id` is `123`.
/// Example: "12345"
/// </param>
/// <param name="extension">
/// The file format for the thumbnail
/// Example: "png"
/// </param>
/// <param name="queryParams">
/// Query parameters of getFileThumbnailById method
/// </param>
/// <param name="headers">
/// Headers of getFileThumbnailById method
/// </param>
/// <param name="cancellationToken">
/// Token used for request cancellation.
/// </param>
public System.Threading.Tasks.Task<System.IO.Stream?> GetFileThumbnailByIdAsync(string fileId, GetFileThumbnailByIdExtension extension, GetFileThumbnailByIdQueryParams? queryParams = default, GetFileThumbnailByIdHeaders? headers = default, System.Threading.CancellationToken? cancellationToken = null) => throw new System.NotImplementedException("This method needs to be implemented by the derived class before calling it.");

}
Expand Down
Loading

0 comments on commit 98faee5

Please sign in to comment.