Both SDKs provide: - Full API client for users, repositories, and releases - Chunked upload with parallel workers - Progress tracking with speed/ETA - SHA256 checksum verification - Comprehensive exception handling C# SDK (.NET 8.0): - Modern record types for models - Async/await pattern throughout - System.Text.Json serialization Java SDK (Java 17): - Standard Maven project - Jackson for JSON - HttpClient for HTTP - ExecutorService for parallel uploads 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
162 lines
5.0 KiB
C#
162 lines
5.0 KiB
C#
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
using System.Text.Json.Serialization;
|
|
|
|
namespace Gitea.SDK;
|
|
|
|
/// <summary>
|
|
/// Represents a Gitea user.
|
|
/// </summary>
|
|
public record User
|
|
{
|
|
public long Id { get; init; }
|
|
public string Login { get; init; } = string.Empty;
|
|
public string FullName { get; init; } = string.Empty;
|
|
public string Email { get; init; } = string.Empty;
|
|
public string AvatarUrl { get; init; } = string.Empty;
|
|
public bool IsAdmin { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents a Gitea repository.
|
|
/// </summary>
|
|
public record Repository
|
|
{
|
|
public long Id { get; init; }
|
|
public string Name { get; init; } = string.Empty;
|
|
public string FullName { get; init; } = string.Empty;
|
|
public User? Owner { get; init; }
|
|
public string Description { get; init; } = string.Empty;
|
|
public bool Private { get; init; }
|
|
public bool Fork { get; init; }
|
|
public string DefaultBranch { get; init; } = "main";
|
|
public int StarsCount { get; init; }
|
|
public int ForksCount { get; init; }
|
|
public string CloneUrl { get; init; } = string.Empty;
|
|
public string HtmlUrl { get; init; } = string.Empty;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents a release attachment/asset.
|
|
/// </summary>
|
|
public record Attachment
|
|
{
|
|
public long Id { get; init; }
|
|
public string Name { get; init; } = string.Empty;
|
|
public long Size { get; init; }
|
|
public long DownloadCount { get; init; }
|
|
public string BrowserDownloadUrl { get; init; } = string.Empty;
|
|
public DateTime CreatedAt { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents a Gitea release.
|
|
/// </summary>
|
|
public record Release
|
|
{
|
|
public long Id { get; init; }
|
|
public string TagName { get; init; } = string.Empty;
|
|
public string Name { get; init; } = string.Empty;
|
|
public string Body { get; init; } = string.Empty;
|
|
public bool Draft { get; init; }
|
|
public bool Prerelease { get; init; }
|
|
public DateTime PublishedAt { get; init; }
|
|
public List<Attachment> Assets { get; init; } = new();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents a chunked upload session.
|
|
/// </summary>
|
|
public record UploadSession
|
|
{
|
|
public string Id { get; init; } = string.Empty;
|
|
public string FileName { get; init; } = string.Empty;
|
|
public long FileSize { get; init; }
|
|
public long ChunkSize { get; init; }
|
|
public long TotalChunks { get; init; }
|
|
public long ChunksReceived { get; init; }
|
|
public string Status { get; init; } = "pending";
|
|
public DateTime ExpiresAt { get; init; }
|
|
public string? Checksum { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents the result of a completed upload.
|
|
/// </summary>
|
|
public record UploadResult
|
|
{
|
|
public long Id { get; init; }
|
|
public string Name { get; init; } = string.Empty;
|
|
public long Size { get; init; }
|
|
public string BrowserDownloadUrl { get; init; } = string.Empty;
|
|
public bool ChecksumVerified { get; init; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents upload progress.
|
|
/// </summary>
|
|
public record Progress
|
|
{
|
|
/// <summary>Bytes uploaded so far.</summary>
|
|
public long BytesDone { get; init; }
|
|
|
|
/// <summary>Total bytes to upload.</summary>
|
|
public long BytesTotal { get; init; }
|
|
|
|
/// <summary>Number of chunks uploaded.</summary>
|
|
public long ChunksDone { get; init; }
|
|
|
|
/// <summary>Total number of chunks.</summary>
|
|
public long ChunksTotal { get; init; }
|
|
|
|
/// <summary>Percentage complete (0-100).</summary>
|
|
public double Percent { get; init; }
|
|
|
|
/// <summary>Upload speed in bytes per second.</summary>
|
|
public double Speed { get; init; }
|
|
|
|
/// <summary>Estimated time remaining.</summary>
|
|
public TimeSpan Eta { get; init; }
|
|
|
|
/// <summary>
|
|
/// Formats the speed as a human-readable string.
|
|
/// </summary>
|
|
public string SpeedFormatted => FormatBytes((long)Speed) + "/s";
|
|
|
|
/// <summary>
|
|
/// Formats the ETA as a human-readable string.
|
|
/// </summary>
|
|
public string EtaFormatted => Eta.TotalSeconds < 60
|
|
? $"{(int)Eta.TotalSeconds}s"
|
|
: Eta.TotalMinutes < 60
|
|
? $"{(int)Eta.TotalMinutes}m{Eta.Seconds}s"
|
|
: $"{(int)Eta.TotalHours}h{Eta.Minutes}m";
|
|
|
|
private static string FormatBytes(long bytes)
|
|
{
|
|
if (bytes < 1024) return $"{bytes} B";
|
|
if (bytes < 1024 * 1024) return $"{bytes / 1024.0:F1} KB";
|
|
if (bytes < 1024 * 1024 * 1024) return $"{bytes / 1024.0 / 1024.0:F1} MB";
|
|
return $"{bytes / 1024.0 / 1024.0 / 1024.0:F1} GB";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Options for chunked uploads.
|
|
/// </summary>
|
|
public class ChunkedUploadOptions
|
|
{
|
|
/// <summary>Size of each chunk in bytes (default: 10MB).</summary>
|
|
public long ChunkSize { get; set; } = 10 * 1024 * 1024;
|
|
|
|
/// <summary>Number of parallel upload workers (default: 4).</summary>
|
|
public int Parallel { get; set; } = 4;
|
|
|
|
/// <summary>Whether to verify file checksum (default: true).</summary>
|
|
public bool VerifyChecksum { get; set; } = true;
|
|
|
|
/// <summary>Progress callback.</summary>
|
|
public Action<Progress>? OnProgress { get; set; }
|
|
}
|