Added /resources REST Endpoints

master
Harald Wolff 2023-08-14 20:21:30 +02:00
parent 80873d4e71
commit f2ddfa350a
5 changed files with 116 additions and 2 deletions

View File

@ -96,6 +96,42 @@ namespace ln.templates.service
return HttpResponse.InternalServerError();
}
[Map(HttpMethod.GET, "/resources$")]
public HttpResponse GetResources()
{
JSONArray templates = JSONMapper.DefaultMapper.ToJson(_templateService.ListResources()) as JSONArray;
return HttpResponse.OK().Content(templates);
}
[Map(HttpMethod.GET, "/resources/(?<resourcePath>.*)$")]
public HttpResponse GetResourceFile(
[HttpArgumentSource(HttpArgumentSource.PARAMETER)]string resourcePath
)
{
var resourceStream = _templateService.GetResource(resourcePath);
if (resourceStream)
return HttpResponse.OK().Content(resourceStream.Value);
if (resourceStream.Is(out FileNotFoundException e))
return HttpResponse.NotFound().Content(e.FileName);
return HttpResponse.InternalServerError();
}
[Map(HttpMethod.POST, "/resources/(?<resourcePath>.*)$")]
public HttpResponse PostResourceFile(
[HttpArgumentSource(HttpArgumentSource.PARAMETER)]string resourcePath,
[HttpArgumentSource(HttpArgumentSource.CONTENT)]Stream postContent
)
{
var result = _templateService.StoreResource(resourcePath, postContent);
if (result)
return HttpResponse.NoContent();
if (result.Is(out FileNotFoundException e))
return HttpResponse.NotFound().Content(e.FileName);
return HttpResponse.InternalServerError().Content(e.ToString());
}
}
}

View File

@ -0,0 +1,8 @@
# ln.templates.service
command line arguments:
-s <storagepath> default: "./storage"
-p <port> default: 8890
Please see [api.REST.md](api.REST.md) for list of HTTP REST endpoints.

View File

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using Jint.Native.Object;
using ln.bootstrap;
using ln.patterns;
using ln.templates.service.render;
@ -19,6 +20,7 @@ namespace ln.templates.service
Initialize();
Resolver = new RecursiveResolver(Path.Combine(StoragePath, "templates"));
TempFileStream.DefaultPath = Path.Combine(StoragePath, "tmp");
}
private void Initialize()
@ -26,7 +28,7 @@ namespace ln.templates.service
EnsureDirectory("");
EnsureDirectory("templates");
EnsureDirectory("resources");
EnsureDirectory("spool");
EnsureDirectory("tmp");
EnsureDirectory("out");
}
@ -119,6 +121,32 @@ namespace ln.templates.service
return templateFileNames.ToArray();
}
public String[] ListResources()
{
List<string> resourceFileNames = new List<string>();
Queue<string> subdirs = new Queue<string>();
string resourcePath = Path.Combine(StoragePath, "resources");
subdirs.Enqueue(resourcePath);
while (subdirs.Count > 0)
{
string currentSubDir = subdirs.Dequeue();
foreach (var file in Directory.GetFiles(currentSubDir))
{
resourceFileNames.Add(Path.GetRelativePath(resourcePath, file));
}
foreach (var directory in Directory.GetDirectories(currentSubDir))
{
subdirs.Enqueue(directory);
}
}
return resourceFileNames.ToArray();
}
public bool RenderTemplate(string templatePath, ObjectInstance o, out Stream templateStream)
=> RenderTemplate(templatePath, o).TryGetValue(out templateStream);
@ -182,5 +210,41 @@ namespace ln.templates.service
);
}
public Optional<Stream> GetResource(string resourcePath)
{
string finalPath = Path.GetFullPath(Path.Combine(StoragePath, "resources", resourcePath));
if (finalPath.StartsWith(StoragePath))
return new FileStream(finalPath, FileMode.Open, FileAccess.Read);
return new FileNotFoundException("", resourcePath);
}
public Optional<bool> StoreResource(string resourcePath, Stream resourceStream)
{
string finalPath = Path.GetFullPath(Path.Combine(StoragePath, "resources", resourcePath));
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))
resourceStream.CopyTo(fs);
return true;
}
return new ArgumentOutOfRangeException("path","illegal path to resource file");
}
}
}

View File

@ -22,3 +22,9 @@ Optional JSON object may be posted to be used as globals for this rendering.
Renders the template identified by <template-path-and-filename> which must end in .html to PDF
Optional JSON object may be posted to be used as globals for this rendering.
### GET /resources
Retrieve JSON list of all resource files available
### GET, POST /resources/<resource-path-and-filename>
Retrieve or store resource file within resources path used for providing css etc.

View File

@ -12,7 +12,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="ln.bootstrap" Version="1.5.0-preview0" />
<PackageReference Include="ln.bootstrap" Version="1.5.0-preview1" />
<PackageReference Include="ln.http" Version="0.9.7-test0" />
<PackageReference Include="ln.json" Version="1.2.4" />
<PackageReference Include="ln.patterns" Version="0.1.0-preview6" />