-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2158 from andy840119/wrap-changelog-request-into-…
…request-object Wrap changelog request into request object.
- Loading branch information
Showing
13 changed files
with
338 additions
and
140 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
osu.Game.Rulesets.Karaoke/Online/API/Requests/GetChangelogBuildRequest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence. | ||
// See the LICENCE file in the repository root for full licence text. | ||
|
||
using System.Threading.Tasks; | ||
using Octokit; | ||
using osu.Game.Rulesets.Karaoke.Online.API.Requests.Responses; | ||
|
||
namespace osu.Game.Rulesets.Karaoke.Online.API.Requests; | ||
|
||
public class GetChangelogBuildRequest : GithubChangeLogAPIRequest<APIChangelogBuild> | ||
{ | ||
private readonly APIChangelogBuild originBuild; | ||
|
||
public GetChangelogBuildRequest(APIChangelogBuild originBuild) | ||
{ | ||
this.originBuild = originBuild; | ||
} | ||
|
||
protected override async Task<APIChangelogBuild> Perform(IGitHubClient client) | ||
{ | ||
string contentString = await GetChangelogContent(client, originBuild.Version).ConfigureAwait(false); | ||
return CreateBuildWithContent(originBuild, contentString); | ||
} | ||
} |
92 changes: 92 additions & 0 deletions
92
osu.Game.Rulesets.Karaoke/Online/API/Requests/GetChangelogRequest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence. | ||
// See the LICENCE file in the repository root for full licence text. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text.RegularExpressions; | ||
using System.Threading.Tasks; | ||
using Octokit; | ||
using osu.Framework.Extensions.IEnumerableExtensions; | ||
using osu.Game.Rulesets.Karaoke.Extensions; | ||
using osu.Game.Rulesets.Karaoke.Online.API.Requests.Responses; | ||
|
||
namespace osu.Game.Rulesets.Karaoke.Online.API.Requests; | ||
|
||
public class GetChangelogRequest : GithubChangeLogAPIRequest<APIChangelogIndex> | ||
{ | ||
protected override async Task<APIChangelogIndex> Perform(IGitHubClient client) | ||
{ | ||
var builds = await getAllBuilds(client).ConfigureAwait(false); | ||
var previewBuilds = (await Task.WhenAll(builds.Take(5).Select(x => createPreviewBuild(client, x))).ConfigureAwait(false)).ToList(); | ||
int[] years = generateYears(builds); | ||
|
||
return new APIChangelogIndex | ||
{ | ||
Years = years, | ||
Builds = builds, | ||
PreviewBuilds = previewBuilds, | ||
}; | ||
} | ||
|
||
private static async Task<List<APIChangelogBuild>> getAllBuilds(IGitHubClient client) | ||
{ | ||
var reposAscending = await client | ||
.Repository | ||
.Content | ||
.GetAllContents(ORGANIZATION_NAME, PROJECT_NAME, CHANGELOG_PATH) | ||
.ConfigureAwait(false); | ||
|
||
var builds = reposAscending | ||
.Reverse() | ||
.Where(x => x.Type == ContentType.Dir) | ||
.Select(createBuild) | ||
.ToList(); | ||
|
||
// adjust the mapping of previous/next versions by hand. | ||
foreach (var build in builds) | ||
{ | ||
build.Versions.Previous = builds.GetPrevious(build); | ||
build.Versions.Next = builds.GetNext(build); | ||
} | ||
|
||
return builds; | ||
} | ||
|
||
private static APIChangelogBuild createBuild(RepositoryContent content) | ||
{ | ||
return new APIChangelogBuild | ||
{ | ||
DocumentUrl = getDocumentUrl(content.Path), | ||
RootUrl = content.HtmlUrl, | ||
Version = content.Name, | ||
PublishedAt = getPublishDateFromName(content.Name), | ||
}; | ||
|
||
static DateTimeOffset getPublishDateFromName(string name) | ||
{ | ||
var regex = new Regex("(?<year>[-0-9]+).(?<month>[-0-9]{2})(?<day>[-0-9]{2})"); | ||
var result = regex.Match(name); | ||
if (!result.Success) | ||
return DateTimeOffset.MaxValue; | ||
|
||
int year = result.GetGroupValue<int>("year"); | ||
int month = result.GetGroupValue<int>("month"); | ||
int day = result.GetGroupValue<int>("day"); | ||
|
||
return new DateTimeOffset(new DateTime(year, month, day)); | ||
} | ||
|
||
string getDocumentUrl(string path) | ||
=> $"https://raw.githubusercontent.com/{ORGANIZATION_NAME}/{PROJECT_NAME}/{BRANCH_NAME}/{path}/"; | ||
} | ||
|
||
private static async Task<APIChangelogBuild> createPreviewBuild(IGitHubClient client, APIChangelogBuild originBuild) | ||
{ | ||
string contentString = await GetChangelogContent(client, originBuild.Version).ConfigureAwait(false); | ||
return CreateBuildWithContent(originBuild, contentString); | ||
} | ||
|
||
private static int[] generateYears(IEnumerable<APIChangelogBuild> builds) | ||
=> builds.Select(x => x.PublishedAt.Year).Distinct().ToArray(); | ||
} |
84 changes: 84 additions & 0 deletions
84
osu.Game.Rulesets.Karaoke/Online/API/Requests/GithubAPIRequest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence. | ||
// See the LICENCE file in the repository root for full licence text. | ||
|
||
using System; | ||
using System.Threading.Tasks; | ||
using Octokit; | ||
using osu.Game.Online.API; | ||
|
||
namespace osu.Game.Rulesets.Karaoke.Online.API.Requests; | ||
|
||
public abstract class GithubAPIRequest<T> where T : class | ||
{ | ||
protected virtual GitHubClient CreateGitHubClient() => new(new ProductHeaderValue(organizationName)); | ||
|
||
/// <summary> | ||
/// Invoked on successful completion of an API request. | ||
/// This will be scheduled to the API's internal scheduler (run on update thread automatically). | ||
/// </summary> | ||
public event APISuccessHandler<T>? Success; | ||
|
||
/// <summary> | ||
/// Invoked on failure to complete an API request. | ||
/// This will be scheduled to the API's internal scheduler (run on update thread automatically). | ||
/// </summary> | ||
public event APIFailureHandler? Failure; | ||
|
||
private readonly object completionStateLock = new(); | ||
|
||
/// <summary> | ||
/// The state of this request, from an outside perspective. | ||
/// This is used to ensure correct notification events are fired. | ||
/// </summary> | ||
public APIRequestCompletionState CompletionState { get; private set; } | ||
|
||
private readonly string organizationName; | ||
|
||
protected GithubAPIRequest(string organizationName) | ||
{ | ||
this.organizationName = organizationName; | ||
} | ||
|
||
public async Task Perform() | ||
{ | ||
var client = CreateGitHubClient(); | ||
|
||
try | ||
{ | ||
var response = await Perform(client).ConfigureAwait(false); | ||
triggerSuccess(response); | ||
} | ||
catch (Exception e) | ||
{ | ||
triggerFailure(e); | ||
} | ||
} | ||
|
||
protected abstract Task<T> Perform(IGitHubClient client); | ||
|
||
private void triggerSuccess(T response) | ||
{ | ||
lock (completionStateLock) | ||
{ | ||
if (CompletionState != APIRequestCompletionState.Waiting) | ||
return; | ||
|
||
CompletionState = APIRequestCompletionState.Completed; | ||
} | ||
|
||
Success?.Invoke(response); | ||
} | ||
|
||
private void triggerFailure(Exception e) | ||
{ | ||
lock (completionStateLock) | ||
{ | ||
if (CompletionState != APIRequestCompletionState.Waiting) | ||
return; | ||
|
||
CompletionState = APIRequestCompletionState.Failed; | ||
} | ||
|
||
Failure?.Invoke(e); | ||
} | ||
} |
51 changes: 51 additions & 0 deletions
51
osu.Game.Rulesets.Karaoke/Online/API/Requests/GithubChangeLogAPIRequest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Copyright (c) andy840119 <[email protected]>. Licensed under the GPL Licence. | ||
// See the LICENCE file in the repository root for full licence text. | ||
|
||
using System.Threading.Tasks; | ||
using Octokit; | ||
using osu.Game.Rulesets.Karaoke.Online.API.Requests.Responses; | ||
|
||
namespace osu.Game.Rulesets.Karaoke.Online.API.Requests; | ||
|
||
public abstract class GithubChangeLogAPIRequest<T> : GithubAPIRequest<T> where T : class | ||
{ | ||
protected const string ORGANIZATION_NAME = "karaoke-dev"; | ||
protected const string PROJECT_NAME = $"{ORGANIZATION_NAME}.github.io"; | ||
protected const string BRANCH_NAME = "master"; | ||
protected const string CHANGELOG_PATH = "content/changelog"; | ||
|
||
protected GithubChangeLogAPIRequest() | ||
: base(ORGANIZATION_NAME) | ||
{ | ||
} | ||
|
||
protected static async Task<string> GetChangelogContent(IGitHubClient client, string version) | ||
{ | ||
string changeLogPath = $"{CHANGELOG_PATH}/{version}/index.md"; | ||
byte[]? content = await client | ||
.Repository | ||
.Content | ||
.GetRawContent(ORGANIZATION_NAME, PROJECT_NAME, changeLogPath) | ||
.ConfigureAwait(false); | ||
|
||
// convert the content to a string | ||
return System.Text.Encoding.UTF8.GetString(content); | ||
} | ||
|
||
protected static APIChangelogBuild CreateBuildWithContent(APIChangelogBuild originBuild, string content) | ||
{ | ||
return new APIChangelogBuild | ||
{ | ||
DocumentUrl = originBuild.DocumentUrl, | ||
RootUrl = originBuild.RootUrl, | ||
Version = originBuild.Version, | ||
Content = content, | ||
Versions = | ||
{ | ||
Previous = originBuild.Versions.Previous, | ||
Next = originBuild.Versions.Next, | ||
}, | ||
PublishedAt = originBuild.PublishedAt, | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.