187 lines
6.6 KiB
C#
187 lines
6.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using Jint.Native.Object;
|
|
using ln.patterns;
|
|
using ln.templates.service.render;
|
|
|
|
namespace ln.templates.service
|
|
{
|
|
|
|
public class TemplateService
|
|
{
|
|
public string StoragePath { get; }
|
|
public RecursiveResolver Resolver { get; }
|
|
|
|
public TemplateService(string storagePath)
|
|
{
|
|
StoragePath = Path.GetFullPath(storagePath);
|
|
Initialize();
|
|
|
|
Resolver = new RecursiveResolver(Path.Combine(StoragePath, "templates"));
|
|
}
|
|
|
|
private void Initialize()
|
|
{
|
|
EnsureDirectory("");
|
|
EnsureDirectory("templates");
|
|
EnsureDirectory("resources");
|
|
EnsureDirectory("spool");
|
|
EnsureDirectory("out");
|
|
}
|
|
|
|
private void EnsureDirectory(string directoryName)
|
|
{
|
|
string finalPath = Path.Combine(StoragePath, directoryName);
|
|
if (!Directory.Exists(finalPath))
|
|
Directory.CreateDirectory(finalPath);
|
|
}
|
|
|
|
public bool StoreTemplate(string templatePath, Stream sourceStream)
|
|
{
|
|
string finalPath = Path.GetFullPath(Path.Combine(StoragePath, "templates", templatePath));
|
|
if (finalPath.StartsWith(StoragePath))
|
|
{
|
|
string finalDirectory = Path.GetDirectoryName(finalPath);
|
|
if (!Directory.Exists(finalDirectory))
|
|
{
|
|
Span<string> finalDirectoryParts = Path.GetRelativePath(StoragePath,finalDirectory).Split(Path.DirectorySeparatorChar);
|
|
string currentPath = StoragePath;
|
|
for (int n = 0; n < finalDirectoryParts.Length; n++)
|
|
{
|
|
currentPath = Path.Combine(currentPath, finalDirectoryParts[n]);
|
|
if (!Directory.Exists(currentPath))
|
|
Directory.CreateDirectory(currentPath);
|
|
}
|
|
}
|
|
|
|
using (FileStream fs = new FileStream(finalPath, FileMode.Create))
|
|
sourceStream.CopyTo(fs);
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public bool StoreTemplateMetadata(string templatePath, Stream sourceStream)
|
|
{
|
|
string finalPath = Path.GetFullPath(Path.Combine(StoragePath, "templates", templatePath));
|
|
if (finalPath.StartsWith(StoragePath))
|
|
{
|
|
if (File.Exists(finalPath))
|
|
{
|
|
string metaFileName = Path.Combine(Path.GetDirectoryName(finalPath), String.Format("{0}.json",Path.GetFileNameWithoutExtension(finalPath)));
|
|
using (FileStream fs = new FileStream(metaFileName, FileMode.Create))
|
|
sourceStream.CopyTo(fs);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public bool GetTemplateSource(string templatePath, out Stream sourceStream)
|
|
{
|
|
string finalPath = Path.GetFullPath(Path.Combine(StoragePath, "templates", templatePath));
|
|
if (finalPath.StartsWith(StoragePath))
|
|
{
|
|
sourceStream = new FileStream(finalPath, FileMode.Open, FileAccess.Read);
|
|
return true;
|
|
}
|
|
|
|
sourceStream = null;
|
|
return false;
|
|
}
|
|
|
|
|
|
public String[] ListTemplates()
|
|
{
|
|
List<string> templateFileNames = new List<string>();
|
|
Queue<string> subdirs = new Queue<string>();
|
|
string templatesPath = Path.Combine(StoragePath, "templates");
|
|
|
|
subdirs.Enqueue(templatesPath);
|
|
while (subdirs.Count > 0)
|
|
{
|
|
string currentSubDir = subdirs.Dequeue();
|
|
|
|
foreach (var file in Directory.GetFiles(currentSubDir, "*.html"))
|
|
{
|
|
templateFileNames.Add(Path.GetRelativePath(templatesPath, file));
|
|
}
|
|
|
|
foreach (var directory in Directory.GetDirectories(currentSubDir))
|
|
{
|
|
subdirs.Enqueue(directory);
|
|
}
|
|
}
|
|
|
|
return templateFileNames.ToArray();
|
|
}
|
|
|
|
public bool RenderTemplate(string templatePath, ObjectInstance o, out Stream templateStream)
|
|
=> RenderTemplate(templatePath, o).TryGetValue(out templateStream);
|
|
|
|
public Optional<Stream> RenderTemplate(string templatePath, ObjectInstance o)
|
|
{
|
|
if (templatePath is null)
|
|
throw new NullReferenceException();
|
|
|
|
string directoryPath = Path.GetDirectoryName(templatePath);
|
|
string templateFilename = Path.GetFileName(templatePath);
|
|
|
|
var resolver = Resolver
|
|
.FindResolver(directoryPath);
|
|
if (resolver is null)
|
|
return new FileNotFoundException("", directoryPath);
|
|
|
|
Template template = resolver.GetTemplate(templateFilename);
|
|
if (template is null)
|
|
return new FileNotFoundException("", templatePath);
|
|
|
|
TempFileStream tempFileStream = new TempFileStream(".html");
|
|
Context context = new Context(template.Resolver, new StreamWriter(tempFileStream));
|
|
try
|
|
{
|
|
template.Render(context, o);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
return e;
|
|
}
|
|
|
|
tempFileStream.Position = 0;
|
|
return tempFileStream;
|
|
}
|
|
|
|
public bool RenderPDF(string templatePath, ObjectInstance o, out Stream targetStream) =>
|
|
RenderPDF(templatePath, o).TryGetValue(out targetStream);
|
|
|
|
public Optional<Stream> RenderPDF(string templatePath, ObjectInstance o)
|
|
{
|
|
if (templatePath is null)
|
|
throw new NullReferenceException();
|
|
|
|
string directoryPath = Path.GetDirectoryName(templatePath);
|
|
string templateFilename = Path.GetFileName(templatePath);
|
|
|
|
var resolver = Resolver
|
|
.FindResolver(directoryPath);
|
|
if (resolver is null)
|
|
return new FileNotFoundException("", directoryPath);
|
|
|
|
Template template = resolver.GetTemplate(templateFilename);
|
|
if (template is null)
|
|
return new FileNotFoundException("", templatePath);
|
|
|
|
return PuppeteerRenderer.RenderTemplate(
|
|
template,
|
|
String.Format("file://{0}", Path.Combine(StoragePath, "resources/")),
|
|
o
|
|
);
|
|
}
|
|
|
|
}
|
|
}
|