Browse Source

closes #456.

pull/509/head
Alper Ebicoglu 8 years ago
parent
commit
c6d130c854
  1. 2
      modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/ContentWithDetailsDto.cs
  2. 2
      modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/Document.cs
  3. 52
      modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/GithubDocumentStore.cs
  4. 3
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/en.json
  5. 3
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/tr.json
  6. 17
      modules/docs/src/Volo.Docs.Web/Formatting/MarkdownDocumentConverter.cs
  7. 7
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/HtmlNormalizer.cs
  8. 61
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml

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

@ -27,6 +27,8 @@ 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; }
} }
public class NavigationNode public class NavigationNode

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

@ -19,5 +19,7 @@ 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; }
} }
} }

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

@ -8,6 +8,7 @@ using System.Net.Sockets;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Octokit; using Octokit;
using Volo.Abp;
using Volo.Abp.Domain.Services; using Volo.Abp.Domain.Services;
using ProductHeaderValue = Octokit.ProductHeaderValue; using ProductHeaderValue = Octokit.ProductHeaderValue;
@ -17,7 +18,7 @@ namespace Volo.Docs.Documents
{ {
public const string Type = "Github"; //TODO: Convert to "github" public const string Type = "Github"; //TODO: Convert to "github"
private const bool IsOffline = true; //use it when you don't want to get from GitHub (eg: I have no internet) public const int DocumentNotFoundExceptionCode = 20181001;
public async Task<Document> FindDocumentByNameAsync(Dictionary<string, object> projectExtraProperties, string projectFormat, string documentName, string version) public async Task<Document> FindDocumentByNameAsync(Dictionary<string, object> projectExtraProperties, string projectFormat, string documentName, string version)
{ {
@ -38,62 +39,37 @@ namespace Volo.Docs.Documents
documentName.Length - documentName.LastIndexOf('/') - 1); documentName.Length - documentName.LastIndexOf('/') - 1);
} }
var content = DownloadWebContent(documentName, rawUrl); var document = new Document
return await Task.FromResult(new Document
{ {
Title = documentName, Title = documentName,
Content = content,
EditLink = editLink, EditLink = editLink,
RootUrl = rootUrl, RootUrl = rootUrl,
RawRootUrl = rawRootUrl, RawRootUrl = rawRootUrl,
Format = projectFormat, Format = projectFormat,
LocalDirectory = localDirectory, LocalDirectory = localDirectory,
FileName = fileName, FileName = fileName,
Version = version Version = version,
}); SuccessfullyRetrieved = TryDownloadWebContent(rawUrl, out var content),
Content = content
};
return await Task.FromResult(document);
} }
private string DownloadWebContent(string documentName, string rawUrl) private bool TryDownloadWebContent(string rawUrl, out string content)
{ {
using (var webClient = new WebClient()) using (var webClient = new WebClient())
{ {
try try
{ {
return webClient.DownloadString(rawUrl); content = webClient.DownloadString(rawUrl);
} return true;
catch (WebException ex)
{
Logger.LogError(ex, ex.Message);
if (ex.Status == WebExceptionStatus.ProtocolError)
{
if (ex.Response != null && ex.Response is HttpWebResponse response)
{
if (response.StatusCode == HttpStatusCode.NotFound)
{
return $"The document {documentName} not found in this version!";
}
}
}
//todo: remove it when filedocumentstore is implemented
else if (ex.InnerException is HttpRequestException &&
ex.InnerException.InnerException != null &&
ex.InnerException.InnerException is SocketException exception &&
exception.SocketErrorCode == SocketError.HostNotFound)
{
if (IsOffline)
{
return File.ReadAllText(Path.Combine(@"D:\Github\abp\docs\", documentName));
}
}
return "An error occured while getting the document " + documentName;
} }
catch (Exception ex) catch (Exception ex)
{ {
content = null;
Logger.LogError(ex, ex.Message); Logger.LogError(ex, ex.Message);
return "An error occured while getting the document " + documentName; return false;
} }
} }
} }

3
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/en.json

@ -8,6 +8,7 @@
"InThisDocument": "In this document", "InThisDocument": "In this document",
"GoToTop": "Go to top", "GoToTop": "Go to top",
"Projects": "Project(s)", "Projects": "Project(s)",
"NoProjectWarning": "There are no projects yet!" "NoProjectWarning": "There are no projects yet!",
"DocumentNotFound": "Oops, the requested document was not found!"
} }
} }

3
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/tr.json

@ -8,6 +8,7 @@
"InThisDocument": "Bu dökümanda", "InThisDocument": "Bu dökümanda",
"GoToTop": "En üste çık", "GoToTop": "En üste çık",
"Projects": "Proje(ler)", "Projects": "Proje(ler)",
"NoProjectWarning": "Hiç proje yok!" "NoProjectWarning": "Hiç proje yok!",
"DocumentNotFound": "Aradığınız döküman bulunamadı!"
} }
} }

17
modules/docs/src/Volo.Docs.Web/Formatting/MarkdownDocumentConverter.cs

@ -16,12 +16,17 @@ namespace Volo.Docs.Formatting
public string Convert(string content) public string Convert(string content)
{ {
return CommonMarkConverter.Convert(Encoding.UTF8.GetString(Encoding.Default.GetBytes(content))); return content == null ? null : CommonMarkConverter.Convert(Encoding.UTF8.GetString(Encoding.Default.GetBytes(content)));
} }
public string NormalizeLinks(string content, string projectShortName, string version, public string NormalizeLinks(string content, string projectShortName, string version,
string documentLocalDirectory) string documentLocalDirectory)
{ {
if (content == null)
{
return null;
}
return Regex.Replace(content, MarkdownLinkRegExp, delegate (Match match) return Regex.Replace(content, MarkdownLinkRegExp, delegate (Match match)
{ {
var displayText = match.Groups[1].Value; var displayText = match.Groups[1].Value;
@ -33,6 +38,11 @@ namespace Volo.Docs.Formatting
private static string RemoveFileExtensionIfLocalUrl(string documentName) private static string RemoveFileExtensionIfLocalUrl(string documentName)
{ {
if (documentName == null)
{
return null;
}
if (string.IsNullOrWhiteSpace(documentName)) if (string.IsNullOrWhiteSpace(documentName))
{ {
return documentName; return documentName;
@ -53,6 +63,11 @@ namespace Volo.Docs.Formatting
private static bool IsRemoteUrl(string url) private static bool IsRemoteUrl(string url)
{ {
if (url == null)
{
return true;
}
try try
{ {
return Regex.IsMatch(url, @"\A(https?|ftp)://(-\.)?([^\s/?\.#-]+\.?)+(/[^\s]*)?\z"); return Regex.IsMatch(url, @"\A(https?|ftp)://(-\.)?([^\s/?\.#-]+\.?)+(/[^\s]*)?\z");

7
modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/HtmlNormalizer.cs

@ -7,6 +7,11 @@ namespace Volo.Docs.Pages.Documents.Project
{ {
public static string ReplaceImageSources(string content, string documentRawRootUrl, string localDirectory) public static string ReplaceImageSources(string content, string documentRawRootUrl, string localDirectory)
{ {
if (content == null)
{
return null;
}
content = Regex.Replace(content, @"(<img\s+[^>]*)src=""([^""]*)""([^>]*>)", delegate (Match match) content = Regex.Replace(content, @"(<img\s+[^>]*)src=""([^""]*)""([^>]*>)", delegate (Match match)
{ {
var newImageSource = documentRawRootUrl.EnsureEndsWith('/') + var newImageSource = documentRawRootUrl.EnsureEndsWith('/') +
@ -22,7 +27,7 @@ namespace Volo.Docs.Pages.Documents.Project
public static string ReplaceCodeBlocksLanguage(string content, string currentLanguage, string newLanguage) public static string ReplaceCodeBlocksLanguage(string content, string currentLanguage, string newLanguage)
{ {
return content.Replace("<code class=\"" + currentLanguage + "\">", "<code class=\"" + newLanguage + "\">"); return content?.Replace("<code class=\"" + currentLanguage + "\">", "<code class=\"" + newLanguage + "\">");
} }
} }

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

@ -109,41 +109,54 @@
</div> </div>
</div> </div>
<div class="col-md-7 docs-content bg-white"> @if (Model.Document.SuccessfullyRetrieved)
{
<div class="docs-link-btns"> <div class="col-md-7 docs-content bg-white">
@if (!string.IsNullOrEmpty(Model.Document.EditLink))
{ <div class="docs-link-btns">
<a href="@Model.Document.EditLink" target="_blank"> <i class="fa fa-edit"></i> @L["Edit"]</a> @if (!string.IsNullOrEmpty(Model.Document.EditLink))
} {
</div> <a href="@Model.Document.EditLink" target="_blank"> <i class="fa fa-edit"></i> @L["Edit"]</a>
}
</div>
<div class="docs-content-field"> <div class="docs-content-field">
<div class="docs-text-field"> <div class="docs-text-field">
<div data-spy="scroll" data-target="#docs-sticky-index" data-offset="0"> <div data-spy="scroll" data-target="#docs-sticky-index" data-offset="0">
<article class="docs-body"> <article class="docs-body">
@Html.Raw(Model.Document.Content) @Html.Raw(Model.Document.Content)
</article> </article>
</div>
</div> </div>
</div> </div>
</div>
</div> </div>
<div class="col-md-2 docs-page-index position-relative bg-light"> <div class="col-md-2 docs-page-index position-relative bg-light">
<div class="docs-inner-anchors mt-2"> <div class="docs-inner-anchors mt-2">
<nav class="navbar p-0 pt-2" data-toggle="toc"> <nav class="navbar p-0 pt-2" data-toggle="toc">
<h5>@L["InThisDocument"]</h5> <h5>@L["InThisDocument"]</h5>
</nav> </nav>
<div class="row"> <div class="row">
<div class="col mt-4 p-0"> <div class="col mt-4 p-0">
<a href="javascript:;" class="scroll-top-btn"><i class="fa fa-chevron-up"></i> @L["GoToTop"]</a> <a href="javascript:;" class="scroll-top-btn"><i class="fa fa-chevron-up"></i> @L["GoToTop"]</a>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> }
else
{
<div class="col-md-9 p-5 bg-white">
<p>@L["DocumentNotFound"]</p>
<a href="#">Go to home</a>
</div>
}
</div> </div>
</div> </div>
Loading…
Cancel
Save