156 lines
5.6 KiB
C#
156 lines
5.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Newtonsoft.Json.Linq;
|
|
using RudderSdk.Core.Models.Ugc;
|
|
|
|
namespace RudderSdk.Core;
|
|
|
|
/// <summary>User-generated content: upload, list, download URLs, deletion.</summary>
|
|
public sealed class UgcService
|
|
{
|
|
private readonly RudderClient _client;
|
|
|
|
internal UgcService(RudderClient client) => _client = client;
|
|
|
|
/// <summary>
|
|
/// Uploads a file in one call: pre-signed URL, PUT of the bytes, submission.
|
|
/// Requires an upload transport in <see cref="RudderClientOptions.UploadTransport"/>.
|
|
/// </summary>
|
|
public async Task<UgcSubmission> UploadAsync(
|
|
string name,
|
|
byte[] data,
|
|
string? description = null,
|
|
JToken? metadata = null,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
var uploadTransport = _client.Options.UploadTransport
|
|
?? throw new InvalidOperationException("UploadTransport is not configured.");
|
|
|
|
var upload = await GetUploadUrlAsync(name, cancellationToken).ConfigureAwait(false);
|
|
await uploadTransport.PutAsync(
|
|
upload.UploadUrl,
|
|
data ?? Array.Empty<byte>(),
|
|
GetContentType(name),
|
|
cancellationToken).ConfigureAwait(false);
|
|
|
|
return await SubmitAsync(
|
|
name,
|
|
upload.FileKey,
|
|
data?.LongLength ?? 0,
|
|
description,
|
|
metadata,
|
|
cancellationToken).ConfigureAwait(false);
|
|
}
|
|
|
|
/// <summary>Fetches one page of the player's submissions.</summary>
|
|
public Task<ListUgcResponse> ListAsync(string? status = null, int limit = 20, string? cursor = null, CancellationToken cancellationToken = default)
|
|
=> _client.SendAsync<ListUgcResponse>(
|
|
"GET",
|
|
"/sdk/v1/ugc" + Url.Query(
|
|
("status", status),
|
|
("limit", limit > 0 ? limit.ToString() : null),
|
|
("cursor", cursor)),
|
|
cancellationToken);
|
|
|
|
/// <summary>Iterates over all of the player's submissions, following the cursor pagination.</summary>
|
|
public async IAsyncEnumerable<UgcSubmission> ListAllAsync(
|
|
string? status = null,
|
|
int limit = 20,
|
|
[EnumeratorCancellation] CancellationToken cancellationToken = default)
|
|
{
|
|
string? cursor = null;
|
|
do
|
|
{
|
|
var page = await ListAsync(status, limit, cursor, cancellationToken).ConfigureAwait(false);
|
|
if (page?.Items != null)
|
|
{
|
|
foreach (var item in page.Items)
|
|
yield return item;
|
|
}
|
|
|
|
cursor = page?.NextCursor;
|
|
}
|
|
while (!string.IsNullOrEmpty(cursor));
|
|
}
|
|
|
|
/// <summary>Returns one submission.</summary>
|
|
public Task<UgcSubmission> GetAsync(string id, CancellationToken cancellationToken = default)
|
|
=> _client.SendAsync<UgcSubmission>("GET", "/sdk/v1/ugc/" + Url.Encode(id), cancellationToken);
|
|
|
|
/// <summary>Deletes a submission; returns false when the server refused.</summary>
|
|
public async Task<bool> DeleteAsync(string id, CancellationToken cancellationToken = default)
|
|
{
|
|
var response = await _client.SendAsync<DeleteUgcResponse>(
|
|
"DELETE",
|
|
"/sdk/v1/ugc/" + Url.Encode(id),
|
|
cancellationToken).ConfigureAwait(false);
|
|
|
|
return response == null || response.Success;
|
|
}
|
|
|
|
/// <summary>Requests a pre-signed upload URL.</summary>
|
|
public Task<GetUploadUrlResponse> GetUploadUrlAsync(string filename, CancellationToken cancellationToken = default)
|
|
=> _client.SendAsync<GetUploadUrlResponse>(
|
|
"GET",
|
|
"/sdk/v1/ugc/upload-url" + Url.Query(("filename", filename)),
|
|
cancellationToken);
|
|
|
|
/// <summary>
|
|
/// Resolves the download URL of a submission.
|
|
/// Throws <see cref="InvalidOperationException"/> when the server returned none.
|
|
/// </summary>
|
|
public async Task<string> GetDownloadUrlAsync(string id, CancellationToken cancellationToken = default)
|
|
{
|
|
var response = await _client.SendAsync<GetDownloadUrlResponse>(
|
|
"GET",
|
|
"/sdk/v1/ugc/" + Url.Encode(id) + "/download",
|
|
cancellationToken).ConfigureAwait(false);
|
|
|
|
if (response == null || string.IsNullOrEmpty(response.DownloadUrl))
|
|
throw new InvalidOperationException("The server returned no download URL.");
|
|
|
|
return response.DownloadUrl;
|
|
}
|
|
|
|
/// <summary>Registers an uploaded file as a submission.</summary>
|
|
public Task<UgcSubmission> SubmitAsync(
|
|
string name,
|
|
string fileKey,
|
|
long fileSize,
|
|
string? description = null,
|
|
JToken? metadata = null,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
return _client.SendAsync<SubmitUgcRequest, UgcSubmission>(
|
|
"POST",
|
|
"/sdk/v1/ugc",
|
|
new SubmitUgcRequest
|
|
{
|
|
Name = name,
|
|
FileKey = fileKey,
|
|
FileSize = fileSize,
|
|
Description = description!,
|
|
Metadata = metadata!
|
|
},
|
|
cancellationToken);
|
|
}
|
|
|
|
private static string GetContentType(string filename)
|
|
{
|
|
var ext = System.IO.Path.GetExtension(filename)?.ToLowerInvariant();
|
|
switch (ext)
|
|
{
|
|
case ".png": return "image/png";
|
|
case ".jpg":
|
|
case ".jpeg": return "image/jpeg";
|
|
case ".gif": return "image/gif";
|
|
case ".webp": return "image/webp";
|
|
case ".txt": return "text/plain";
|
|
default: return "application/octet-stream";
|
|
}
|
|
}
|
|
}
|