|
|
|
@ -11,6 +11,7 @@ using Volo.Docs.Documents;
|
|
|
|
|
using Volo.Docs.GitHub.Projects;
|
|
|
|
|
using Volo.Docs.Projects;
|
|
|
|
|
using ProductHeaderValue = Octokit.ProductHeaderValue;
|
|
|
|
|
using Project = Volo.Docs.Projects.Project;
|
|
|
|
|
|
|
|
|
|
namespace Volo.Docs.GitHub.Documents
|
|
|
|
|
{
|
|
|
|
@ -18,33 +19,22 @@ namespace Volo.Docs.GitHub.Documents
|
|
|
|
|
{
|
|
|
|
|
public const string Type = "GitHub";
|
|
|
|
|
|
|
|
|
|
public Task<Document> FindDocument(Docs.Projects.Project project, string documentName, string version)
|
|
|
|
|
public virtual async Task<Document> FindDocument(Project project, string documentName, string version)
|
|
|
|
|
{
|
|
|
|
|
var rootUrl = project.GetGitHubUrl()
|
|
|
|
|
.Replace("_version_/", version + "/")
|
|
|
|
|
.Replace("www.", ""); //TODO: Can be a problem?
|
|
|
|
|
|
|
|
|
|
var rawRootUrl = rootUrl
|
|
|
|
|
.Replace("github.com", "raw.githubusercontent.com")
|
|
|
|
|
.Replace("/tree/", "/"); //TODO: Replacing this can be a problem if I have a tree folder inside the repository
|
|
|
|
|
|
|
|
|
|
var rawUrl = rawRootUrl + documentName;
|
|
|
|
|
var editLink = rootUrl.Replace("/tree/", "/blob/") + documentName;
|
|
|
|
|
var rootUrl = project.GetGitHubUrl(version);
|
|
|
|
|
var rawRootUrl = CalculateRawRootUrl(rootUrl);
|
|
|
|
|
var rawDocumentUrl = rawRootUrl + documentName;
|
|
|
|
|
var editLink = rootUrl.ReplaceFirst("/tree/", "/blob/") + documentName;
|
|
|
|
|
var localDirectory = "";
|
|
|
|
|
var fileName = documentName;
|
|
|
|
|
|
|
|
|
|
if (documentName.Contains("/"))
|
|
|
|
|
{
|
|
|
|
|
localDirectory = documentName.Substring(0, documentName.LastIndexOf('/'));
|
|
|
|
|
fileName = documentName.Substring(
|
|
|
|
|
documentName.LastIndexOf('/') + 1,
|
|
|
|
|
documentName.Length - documentName.LastIndexOf('/') - 1
|
|
|
|
|
);
|
|
|
|
|
fileName = documentName.Substring(documentName.LastIndexOf('/') + 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var token = project.GetGitHubAccessTokenOrNull();
|
|
|
|
|
|
|
|
|
|
var document = new Document
|
|
|
|
|
return new Document
|
|
|
|
|
{
|
|
|
|
|
Title = documentName,
|
|
|
|
|
EditLink = editLink,
|
|
|
|
@ -54,13 +44,18 @@ namespace Volo.Docs.GitHub.Documents
|
|
|
|
|
LocalDirectory = localDirectory,
|
|
|
|
|
FileName = fileName,
|
|
|
|
|
Version = version,
|
|
|
|
|
Content = DownloadWebContent(rawUrl, token)
|
|
|
|
|
Content = await DownloadWebContentAsync(rawDocumentUrl, project.GetGitHubAccessTokenOrNull())
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Task.FromResult(document);
|
|
|
|
|
private static string CalculateRawRootUrl(string rootUrl)
|
|
|
|
|
{
|
|
|
|
|
return rootUrl
|
|
|
|
|
.Replace("github.com", "raw.githubusercontent.com")
|
|
|
|
|
.ReplaceFirst("/tree/", "/");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private string DownloadWebContent(string rawUrl, string token)
|
|
|
|
|
private async Task<string> DownloadWebContentAsync(string rawUrl, string token)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
@ -71,33 +66,28 @@ namespace Volo.Docs.GitHub.Documents
|
|
|
|
|
webClient.Headers.Add("Authorization", "token " + token);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return webClient.DownloadString(rawUrl);
|
|
|
|
|
return await webClient.DownloadStringTaskAsync(new Uri(rawUrl));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex) //TODO: Only handle when document is really not available
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
//TODO: Only handle when document is really not available
|
|
|
|
|
Logger.LogWarning(ex.Message, ex);
|
|
|
|
|
throw new DocumentNotFoundException(rawUrl);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<List<VersionInfo>> GetVersions(Volo.Docs.Projects.Project project)
|
|
|
|
|
public async Task<List<VersionInfo>> GetVersions(Project project)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var token = project.GetGitHubAccessTokenOrNull();
|
|
|
|
|
|
|
|
|
|
var gitHubClient = token.IsNullOrWhiteSpace()
|
|
|
|
|
? new GitHubClient(new ProductHeaderValue("AbpWebSite"))
|
|
|
|
|
: new GitHubClient(new ProductHeaderValue("AbpWebSite"), new InMemoryCredentialStore(new Credentials(token)));
|
|
|
|
|
|
|
|
|
|
var url = project.GetGitHubUrl();
|
|
|
|
|
var releases = await gitHubClient.Repository.Release.GetAll(
|
|
|
|
|
GetGithubOrganizationNameFromUrl(url),
|
|
|
|
|
GetGithubRepositoryNameFromUrl(url)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return releases.OrderByDescending(r => r.PublishedAt).Select(r => new VersionInfo { Name = r.TagName, DisplayName = r.TagName }).ToList();
|
|
|
|
|
return (await GetReleasesAsync(project))
|
|
|
|
|
.OrderByDescending(r => r.PublishedAt)
|
|
|
|
|
.Select(r => new VersionInfo
|
|
|
|
|
{
|
|
|
|
|
Name = r.TagName,
|
|
|
|
|
DisplayName = r.TagName
|
|
|
|
|
}).ToList();
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
@ -106,12 +96,32 @@ namespace Volo.Docs.GitHub.Documents
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static string GetGithubOrganizationNameFromUrl(string url)
|
|
|
|
|
private async Task<IReadOnlyList<Release>> GetReleasesAsync(Project project)
|
|
|
|
|
{
|
|
|
|
|
var url = project.GetGitHubUrl();
|
|
|
|
|
var ownerName = GetOwnerNameFromUrl(url);
|
|
|
|
|
var repositoryName = GetRepositoryNameFromUrl(url);
|
|
|
|
|
var gitHubClient = CreateGitHubClient(project.GetGitHubAccessTokenOrNull());
|
|
|
|
|
|
|
|
|
|
return await gitHubClient
|
|
|
|
|
.Repository
|
|
|
|
|
.Release
|
|
|
|
|
.GetAll(ownerName, repositoryName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static GitHubClient CreateGitHubClient(string token = null)
|
|
|
|
|
{
|
|
|
|
|
//TODO: Why hard-coded "abpframework"? Should be configurable?
|
|
|
|
|
return token.IsNullOrWhiteSpace()
|
|
|
|
|
? new GitHubClient(new ProductHeaderValue("abpframework"))
|
|
|
|
|
: new GitHubClient(new ProductHeaderValue("abpframework"), new InMemoryCredentialStore(new Credentials(token)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected virtual string GetOwnerNameFromUrl(string url)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var urlStartingAfterFirstSlash =
|
|
|
|
|
url.Substring(url.IndexOf("github.com/", StringComparison.OrdinalIgnoreCase) + "github.com/".Length);
|
|
|
|
|
var urlStartingAfterFirstSlash = url.Substring(url.IndexOf("github.com/",StringComparison.OrdinalIgnoreCase) + "github.com/".Length);
|
|
|
|
|
return urlStartingAfterFirstSlash.Substring(0, urlStartingAfterFirstSlash.IndexOf('/'));
|
|
|
|
|
}
|
|
|
|
|
catch (Exception)
|
|
|
|
@ -120,14 +130,12 @@ namespace Volo.Docs.GitHub.Documents
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private string GetGithubRepositoryNameFromUrl(string url)
|
|
|
|
|
protected virtual string GetRepositoryNameFromUrl(string url)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var urlStartingAfterFirstSlash =
|
|
|
|
|
url.Substring(url.IndexOf("github.com/", StringComparison.OrdinalIgnoreCase) + "github.com/".Length);
|
|
|
|
|
var urlStartingAfterSecondSlash =
|
|
|
|
|
urlStartingAfterFirstSlash.Substring(urlStartingAfterFirstSlash.IndexOf('/') + 1);
|
|
|
|
|
var urlStartingAfterFirstSlash = url.Substring(url.IndexOf("github.com/", StringComparison.OrdinalIgnoreCase) + "github.com/".Length);
|
|
|
|
|
var urlStartingAfterSecondSlash = urlStartingAfterFirstSlash.Substring(urlStartingAfterFirstSlash.IndexOf('/') + 1);
|
|
|
|
|
return urlStartingAfterSecondSlash.Substring(0, urlStartingAfterSecondSlash.IndexOf('/'));
|
|
|
|
|
}
|
|
|
|
|
catch (Exception)
|
|
|
|
|