Browse Source

Refactor docs.

pull/570/head
Halil ibrahim Kalkan 8 years ago
parent
commit
f23b244a7f
  1. 2
      modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/ContentWithDetailsDto.cs
  2. 2
      modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/IDocumentAppService.cs
  3. 2
      modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/NavigationWithDetailsDto.cs
  4. 2
      modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/Document.cs
  5. 19
      modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs
  6. 4
      modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentStoreFactory.cs
  7. 57
      modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/GithubDocumentStore.cs
  8. 28
      modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/ProjectGithubExtensions.cs
  9. 23
      modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/DocumentNotFoundException.cs
  10. 5
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml
  11. 33
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs

2
modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/ContentWithDetailsDto.cs

@ -23,7 +23,5 @@ namespace Volo.Docs.Documents
public string FileName { get; set; } public string FileName { get; set; }
public ProjectDto Project { get; set; } public ProjectDto Project { get; set; }
public bool SuccessfullyRetrieved { get; set; }
} }
} }

2
modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/IDocumentAppService.cs

@ -6,6 +6,8 @@ namespace Volo.Docs.Documents
{ {
public interface IDocumentAppService : IApplicationService public interface IDocumentAppService : IApplicationService
{ {
//TODO: Create input DTOs for methods and add validation annotations.
Task<DocumentWithDetailsDto> GetByNameAsync( Task<DocumentWithDetailsDto> GetByNameAsync(
string projectShortName, string projectShortName,
string documentName, string documentName,

2
modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/NavigationWithDetailsDto.cs

@ -10,7 +10,7 @@ namespace Volo.Docs.Documents
public void ConvertItems() public void ConvertItems()
{ {
if (!SuccessfullyRetrieved || Content.IsNullOrEmpty()) if (Content.IsNullOrEmpty())
{ {
RootNode = new NavigationNode(); RootNode = new NavigationNode();
return; return;

2
modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/Document.cs

@ -19,7 +19,5 @@ namespace Volo.Docs.Documents
public string LocalDirectory { get; set; } public string LocalDirectory { get; set; }
public string FileName { get; set; } public string FileName { get; set; }
public bool SuccessfullyRetrieved { get; set; }
} }
} }

19
modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs

@ -85,16 +85,15 @@ namespace Volo.Docs.Documents
return dto; return dto;
} }
public async Task<List<VersionInfoDto>> GetVersions( public async Task<List<VersionInfoDto>> GetVersions(string projectShortName)
string projectShortName
)
{ {
var project = await _projectRepository.GetByShortNameAsync(projectShortName); //TODO: What if there is no version?
var project = await _projectRepository.GetByShortNameAsync(projectShortName);
var documentStore = _documentStoreFactory.Create(project.DocumentStoreType); var documentStore = _documentStoreFactory.Create(project.DocumentStoreType);
//TODO: Why not use GetOrAddAsync
var versions = await GetVersionsFromCache(projectShortName); var versions = await GetVersionsFromCache(projectShortName);
if (versions == null) if (versions == null)
{ {
versions = await documentStore.GetVersions(project); versions = await documentStore.GetVersions(project);
@ -125,8 +124,14 @@ namespace Volo.Docs.Documents
private async Task SetVersionsToCache(string projectShortName, List<VersionInfoDto> versions) private async Task SetVersionsToCache(string projectShortName, List<VersionInfoDto> versions)
{ {
var options = new DistributedCacheEntryOptions() { SlidingExpiration = TimeSpan.FromDays(1) }; await _distributedCache.SetAsync(
await _distributedCache.SetAsync(projectShortName, versions, options); projectShortName,
versions,
new DistributedCacheEntryOptions
{
SlidingExpiration = TimeSpan.FromDays(1)
}
);
} }
} }
} }

4
modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentStoreFactory.cs

@ -13,8 +13,10 @@ namespace Volo.Docs.Documents
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
} }
public IDocumentStore Create(string documentStoreType) public virtual IDocumentStore Create(string documentStoreType)
{ {
//TODO: Should be extensible
switch (documentStoreType) switch (documentStoreType)
{ {
case GithubDocumentStore.Type: case GithubDocumentStore.Type:

57
modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/GithubDocumentStore.cs

@ -3,13 +3,9 @@ using Octokit;
using Octokit.Internal; using Octokit.Internal;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Domain.Services; using Volo.Abp.Domain.Services;
using ProductHeaderValue = Octokit.ProductHeaderValue; using ProductHeaderValue = Octokit.ProductHeaderValue;
@ -19,27 +15,35 @@ namespace Volo.Docs.Documents
{ {
public const string Type = "Github"; //TODO: Convert to "github" public const string Type = "Github"; //TODO: Convert to "github"
public const int DocumentNotFoundExceptionCode = 20181001; public Task<Document> Find(
Projects.Project project,
public async Task<Document> Find(Volo.Docs.Projects.Project project, string documentName, string version) string documentName,
string version)
{ {
var rootUrl = project.ExtraProperties["GithubRootUrl"].ToString().Replace("_version_/", version + "/").Replace("www.", ""); var rootUrl = project.GetGithubUrl()
.Replace("_version_/", version + "/")
.Replace("www.", ""); //TODO: Can be a problem?
var token = project.ExtraProperties["GithubAccessToken"]?.ToString(); 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 rawRootUrl = rootUrl.Replace("github.com", "raw.githubusercontent.com").Replace("/tree/", "/");
var rawUrl = rawRootUrl + documentName; var rawUrl = rawRootUrl + documentName;
var editLink = rootUrl.Replace("/tree/", "/blob/") + documentName; var editLink = rootUrl.Replace("/tree/", "/blob/") + documentName;
string localDirectory = ""; var localDirectory = "";
string fileName = documentName; var fileName = documentName;
if (documentName.Contains("/")) if (documentName.Contains("/"))
{ {
localDirectory = documentName.Substring(0, documentName.LastIndexOf('/')); localDirectory = documentName.Substring(0, documentName.LastIndexOf('/'));
fileName = documentName.Substring(documentName.LastIndexOf('/') + 1, fileName = documentName.Substring(
documentName.Length - documentName.LastIndexOf('/') - 1); documentName.LastIndexOf('/') + 1,
documentName.Length - documentName.LastIndexOf('/') - 1
);
} }
var token = project.ExtraProperties["GithubAccessToken"]?.ToString(); //TODO: Define GetGithubAccessToken extension method
var document = new Document var document = new Document
{ {
Title = documentName, Title = documentName,
@ -50,34 +54,31 @@ namespace Volo.Docs.Documents
LocalDirectory = localDirectory, LocalDirectory = localDirectory,
FileName = fileName, FileName = fileName,
Version = version, Version = version,
SuccessfullyRetrieved = TryDownloadWebContent(rawUrl, token, out var content), Content = DownloadWebContent(rawUrl, token)
Content = content
}; };
return await Task.FromResult(document); return Task.FromResult(document);
} }
private bool TryDownloadWebContent(string rawUrl, string token, out string content) private string DownloadWebContent(string rawUrl, string token)
{ {
using (var webClient = new WebClient()) try
{ {
try using (var webClient = new WebClient())
{ {
if (!token.IsNullOrWhiteSpace()) if (!token.IsNullOrWhiteSpace())
{ {
webClient.Headers.Add("Authorization", "token " + token); webClient.Headers.Add("Authorization", "token " + token);
} }
content = webClient.DownloadString(rawUrl); return webClient.DownloadString(rawUrl);
return true;
}
catch (Exception ex)
{
content = null;
Logger.LogError(ex, ex.Message);
return false;
} }
} }
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<VersionInfoDto>> GetVersions(Volo.Docs.Projects.Project project) public async Task<List<VersionInfoDto>> GetVersions(Volo.Docs.Projects.Project project)

28
modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/ProjectGithubExtensions.cs

@ -0,0 +1,28 @@
using System;
using Volo.Docs.Projects;
namespace Volo.Docs.Documents
{
public static class ProjectGithubExtensions
{
public static string GetGithubUrl(this Projects.Project project)
{
CheckGithubProject(project);
return project.ExtraProperties["GithubRootUrl"] as string;
}
public static void SetGithubUrl(this Projects.Project project, string value)
{
CheckGithubProject(project);
project.ExtraProperties["GithubRootUrl"] = value;
}
private static void CheckGithubProject(Project project)
{
if (project.DocumentStoreType != GithubDocumentStore.Type)
{
throw new ApplicationException("Given project has not a Github document store!");
}
}
}
}

23
modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/DocumentNotFoundException.cs

@ -0,0 +1,23 @@
using System;
using System.Runtime.Serialization;
using Volo.Abp;
namespace Volo.Docs.Documents
{
[Serializable]
public class DocumentNotFoundException : BusinessException
{
public string DocumentUrl { get; set; }
public DocumentNotFoundException(SerializationInfo serializationInfo, StreamingContext context)
: base(serializationInfo, context)
{
}
public DocumentNotFoundException(string documentUrl)
{
DocumentUrl = documentUrl;
}
}
}

5
modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml

@ -97,7 +97,7 @@
</div> </div>
} }
@if (!Model.Navigation.SuccessfullyRetrieved || Model.Navigation.Content.IsNullOrEmpty()) @if (Model.Navigation == null || Model.Navigation.Content.IsNullOrEmpty())
{ {
<div class="text-muted p-3"> <div class="text-muted p-3">
<i class="fa fa-warning"></i> @L["NavigationDocumentNotFound"] <i class="fa fa-warning"></i> @L["NavigationDocumentNotFound"]
@ -118,9 +118,8 @@
</div> </div>
</div> </div>
@if (Model.Document.SuccessfullyRetrieved) @if (Model.Document != null)
{ {
<div class="col-md-7 docs-content bg-white"> <div class="col-md-7 docs-content bg-white">
<div class="docs-link-btns"> <div class="docs-link-btns">

33
modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs

@ -68,7 +68,15 @@ namespace Volo.Docs.Pages.Documents.Project
private async Task SetNavigationAsync() private async Task SetNavigationAsync()
{ {
Navigation = await _documentAppService.GetNavigationDocumentAsync(ProjectName, Version, false); try
{
Navigation = await _documentAppService.GetNavigationDocumentAsync(ProjectName, Version, false);
}
catch (DocumentNotFoundException) //TODO: What if called on a remote service which may return 404
{
return;
}
Navigation.ConvertItems(); Navigation.ConvertItems();
} }
@ -145,6 +153,11 @@ namespace Volo.Docs.Pages.Documents.Project
public string GetSpecificVersionOrLatest() public string GetSpecificVersionOrLatest()
{ {
if (Document?.Version == null)
{
return DocsAppConsts.LatestVersion;
}
return Document.Version == LatestVersionInfo.Version ? return Document.Version == LatestVersionInfo.Version ?
DocsAppConsts.LatestVersion : DocsAppConsts.LatestVersion :
Document.Version; Document.Version;
@ -152,15 +165,22 @@ namespace Volo.Docs.Pages.Documents.Project
private async Task SetDocumentAsync() private async Task SetDocumentAsync()
{ {
if (DocumentNameWithExtension.IsNullOrWhiteSpace()) try
{ {
Document = await _documentAppService.GetDefaultAsync(ProjectName, Version, true); if (DocumentNameWithExtension.IsNullOrWhiteSpace())
{
Document = await _documentAppService.GetDefaultAsync(ProjectName, Version, true);
}
else
{
Document = await _documentAppService.GetByNameAsync(ProjectName, DocumentNameWithExtension, Version, true);
}
} }
else catch (DocumentNotFoundException)
{ {
Document = await _documentAppService.GetByNameAsync(ProjectName, DocumentNameWithExtension, Version, true); return;
} }
var converter = _documentConverterFactory.Create(Document.Format ?? ProjectFormat); var converter = _documentConverterFactory.Create(Document.Format ?? ProjectFormat);
var content = converter.NormalizeLinks(Document.Content, Document.Project.ShortName, GetSpecificVersionOrLatest(), Document.LocalDirectory); var content = converter.NormalizeLinks(Document.Content, Document.Project.ShortName, GetSpecificVersionOrLatest(), Document.LocalDirectory);
@ -171,5 +191,6 @@ namespace Volo.Docs.Pages.Documents.Project
Document.Content = content; Document.Content = content;
} }
} }
} }
Loading…
Cancel
Save