commit d4dac107014785d67b5ff7bbe4140d18b15bd876 Author: Harald Wolff Date: Tue Feb 4 21:47:37 2020 +0100 Initial Commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2452a0c --- /dev/null +++ b/.gitignore @@ -0,0 +1,43 @@ +# Autosave files +*~ + +# build +[Oo]bj/ +[Bb]in/ +packages/ +TestResults/ + +# globs +Makefile.in +*.DS_Store +*.sln.cache +*.suo +*.cache +*.pidb +*.userprefs +*.usertasks +config.log +config.make +config.status +aclocal.m4 +install-sh +autom4te.cache/ +*.user +*.tar.gz +tarballs/ +test-results/ +Thumbs.db +.vs/ + +# Mac bundle stuff +*.dmg +*.app + +# resharper +*_Resharper.* +*.Resharper + +# dotCover +*.dotCover + +ln.logging \ No newline at end of file diff --git a/ln.pdfstamp.sln b/ln.pdfstamp.sln new file mode 100644 index 0000000..2d71264 --- /dev/null +++ b/ln.pdfstamp.sln @@ -0,0 +1,35 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.pdfstamp", "ln.pdfstamp\ln.pdfstamp.csproj", "{46B56B79-78AC-44AF-A85C-B6A8E3F79420}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.http", "..\ln.http\ln.http.csproj", "{CEEEEB41-3059-46A2-A871-2ADE22C013D9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.types", "..\ln.types\ln.types.csproj", "{8D9AB9A5-E513-4BA7-A450-534F6456BF28}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.logging", "..\ln.logging\ln.logging.csproj", "{D471A566-9FB6-41B2-A777-3C32874ECD0E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {46B56B79-78AC-44AF-A85C-B6A8E3F79420}.Debug|x86.ActiveCfg = Debug|x86 + {46B56B79-78AC-44AF-A85C-B6A8E3F79420}.Debug|x86.Build.0 = Debug|x86 + {46B56B79-78AC-44AF-A85C-B6A8E3F79420}.Release|x86.ActiveCfg = Release|x86 + {46B56B79-78AC-44AF-A85C-B6A8E3F79420}.Release|x86.Build.0 = Release|x86 + {CEEEEB41-3059-46A2-A871-2ADE22C013D9}.Debug|x86.ActiveCfg = Debug|Any CPU + {CEEEEB41-3059-46A2-A871-2ADE22C013D9}.Debug|x86.Build.0 = Debug|Any CPU + {CEEEEB41-3059-46A2-A871-2ADE22C013D9}.Release|x86.ActiveCfg = Release|Any CPU + {CEEEEB41-3059-46A2-A871-2ADE22C013D9}.Release|x86.Build.0 = Release|Any CPU + {8D9AB9A5-E513-4BA7-A450-534F6456BF28}.Debug|x86.ActiveCfg = Debug|Any CPU + {8D9AB9A5-E513-4BA7-A450-534F6456BF28}.Debug|x86.Build.0 = Debug|Any CPU + {8D9AB9A5-E513-4BA7-A450-534F6456BF28}.Release|x86.ActiveCfg = Release|Any CPU + {8D9AB9A5-E513-4BA7-A450-534F6456BF28}.Release|x86.Build.0 = Release|Any CPU + {D471A566-9FB6-41B2-A777-3C32874ECD0E}.Debug|x86.ActiveCfg = Debug|Any CPU + {D471A566-9FB6-41B2-A777-3C32874ECD0E}.Debug|x86.Build.0 = Debug|Any CPU + {D471A566-9FB6-41B2-A777-3C32874ECD0E}.Release|x86.ActiveCfg = Release|Any CPU + {D471A566-9FB6-41B2-A777-3C32874ECD0E}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/ln.pdfstamp/Daemon.cs b/ln.pdfstamp/Daemon.cs new file mode 100644 index 0000000..5139b79 --- /dev/null +++ b/ln.pdfstamp/Daemon.cs @@ -0,0 +1,146 @@ +// /** +// * File: Daemon.cs +// * Author: haraldwolff +// * +// * This file and it's content is copyrighted by the Author and / or copyright holder. +// * Any use wihtout proper permission is illegal and may lead to legal actions. +// * +// * +// **/ +using System; +using ln.http; +using ln.http.router; +using System.IO; +using ln.types.net; +using ln.http.message; +using ln.types; +using iTextSharp.text.pdf; +using System.Collections.Generic; +using iTextSharp.text; +namespace ln.pdfstamp +{ + public class Daemon + { + public string SpoolPath { get; } + + HTTPServer server; + SimpleRouter router; + + public Daemon() + { + int prio = 1; + router = new SimpleRouter(); + + foreach (String p in new string[] { "www", "../../www" }) + { + if (Directory.Exists(p)) + { + StaticRouter staticRouter = new StaticRouter(p); + router.AddSimpleRoute("/*", staticRouter, prio++); + } + } + + if (Directory.Exists("/var/spool/ln.pdfstamp")) + { + SpoolPath = "/var/spool/ln.pdfstamp"; + } + else + { + SpoolPath = "./spool"; + } + + EnsureDirectory(SpoolPath); + EnsureDirectory(Path.Combine(SpoolPath, "stamps")); + EnsureDirectory(Path.Combine(SpoolPath, "stamped")); + + StaticRouter spoolRouter = new StaticRouter(SpoolPath); + router.AddSimpleRoute("/spool/*", spoolRouter); + router.AddSimpleRoute("/api/stamp/:stamp", new RouterTarget(PostPDF)); + } + + public void EnsureDirectory(string path) + { + if (!Directory.Exists(path)) + Directory.CreateDirectory(path); + } + + public void Start() + { + server = new HTTPServer(new Endpoint(IPv6.ANY, 8888), + new LoggingRouter(router) + ); + server.Start(); + } + + HttpResponse PostPDF(HttpRequest request) + { + MemoryStream pdfOutput = new MemoryStream(); + Stream pdfInput = null; + + if (request.Method.Equals("POST")) + { + switch (request.RequestHeaders["Content-Type"].Value) + { + case "application/pdf": + pdfInput = request.ContentStream; + break; + case "multipart/form-data": + pdfInput = FindMultipartPDF(request); + break; + default: + throw new NotSupportedException(); + } + } else if (request.Method.Equals("PUT")) + { + pdfInput = request.ContentStream; + } + + Stamp( + pdfInput, + request.GetParameter("stamp"), + float.Parse(request.Query.GetValue("left","20")), + float.Parse(request.Query.GetValue("top", "10")), + float.Parse(request.Query.GetValue("width", "70")), + pdfOutput + ); + + string spoolFileName = String.Format("{0}-stamped.pdf",DateTime.Now.ToString("yyyyMMdd-HHmmss")); + + pdfOutput = new MemoryStream(pdfOutput.ToArray()); + + using (FileStream pdfOutputStream = new FileStream(Path.Combine(SpoolPath, "stamped", spoolFileName), FileMode.CreateNew)) + { + pdfOutput.CopyTo(pdfOutputStream); + } + + HttpResponse response = new HttpResponse(request); + response.StatusCode = 302; + response.AddHeader("Location", String.Format("/spool/stamped/{0}",spoolFileName)); + return response; + + } + + public Stream FindMultipartPDF(HttpRequest request) + { + Message message = new Message(request.RequestHeaders, request.ContentStream.ReadToEnd()); + + foreach (Message part in message.Parts) + { + if (part.Headers["CONTENT-TYPE"].Value.Equals("application/pdf")) + return part.OpenBodyStream(); + } + + throw new KeyNotFoundException("Could not find valid PDF file to stamp"); + } + + public void Stamp(Stream pdfInput,string stampImageFileName,float left,float top,float width,Stream pdfOutput) + { + Image stampImage = Image.GetInstance(Path.GetFullPath(Path.Combine(SpoolPath, "stamps", stampImageFileName))); + PDFStamp.Stamp(pdfInput, stampImage, left, top, width, pdfOutput); + } + + + + + } +} diff --git a/ln.pdfstamp/ln.pdfstamp.csproj b/ln.pdfstamp/ln.pdfstamp.csproj new file mode 100644 index 0000000..ec5f4ab --- /dev/null +++ b/ln.pdfstamp/ln.pdfstamp.csproj @@ -0,0 +1,63 @@ + + + + Debug + x86 + {46B56B79-78AC-44AF-A85C-B6A8E3F79420} + Exe + ln.pdfstamp + ln.pdfstamp + v4.7 + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + x86 + + + true + bin\Release + prompt + 4 + x86 + + + + {8D9AB9A5-E513-4BA7-A450-534F6456BF28} + ln.types + + + {D471A566-9FB6-41B2-A777-3C32874ECD0E} + ln.logging + + + {CEEEEB41-3059-46A2-A871-2ADE22C013D9} + ln.http + + + + + + + + + + PreserveNewest + + + + + ..\packages\iTextSharp-LGPL.4.1.6\lib\iTextSharp.dll + + + + + + + + \ No newline at end of file diff --git a/ln.pdfstamp/packages.config b/ln.pdfstamp/packages.config new file mode 100644 index 0000000..b326056 --- /dev/null +++ b/ln.pdfstamp/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ln.pdfstamp/pdfstamp.cs b/ln.pdfstamp/pdfstamp.cs new file mode 100644 index 0000000..f01b8a8 --- /dev/null +++ b/ln.pdfstamp/pdfstamp.cs @@ -0,0 +1,160 @@ +// /** +// * File: pdfstamp.cs +// * Author: haraldwolff +// * +// * This file and it's content is copyrighted by the Author and / or copyright holder. +// * Any use wihtout proper permission is illegal and may lead to legal actions. +// * +// * +// **/ +using System; +using ln.types; +using iTextSharp.text.pdf; +using System.IO; +using ln.logging; +using iTextSharp.text; + +namespace ln.pdfstamp +{ + public class PDFStamp + { + public static void Main(String[] args) + { + ArgumentContainer argumentContainer = new ArgumentContainer(); + argumentContainer.Add(new Argument('x', null, "0")); + argumentContainer.Add(new Argument('y', null, "0")); + argumentContainer.Add('s', "stamp", null); + argumentContainer.Add('o', "output", "."); + argumentContainer.Add('e', "extension", ".stamped"); + argumentContainer.Add('d', "dpi", "72"); + argumentContainer.Add('w', "width", null); + argumentContainer.Add('h', "height", null); + argumentContainer.Add((char)0, "daemon"); + + argumentContainer.Parse(args); + + if (argumentContainer["daemon"].IsSet) + { + Daemon daemon = new Daemon(); + daemon.Start(); + return; + } + + + + Image stampImage = Image.GetInstance(Path.GetFullPath(argumentContainer['s'].Value)); + if (stampImage == null) + { + throw new FileNotFoundException(argumentContainer['s'].Value); + } + + float lx = (float)(argumentContainer['x'].DoubleValue / 25.4 * 72); + float ly = (float)(argumentContainer['y'].DoubleValue / 25.4 * 72); + + double stampDpiX = stampImage.DpiX == 0 ? 72 : stampImage.DpiX; // / argumentContainer['d'].DoubleValue; + double stampDpiY = stampImage.DpiY == 0 ? 72 : stampImage.DpiY; // / argumentContainer['d'].DoubleValue; + + double stampWidth = stampImage.Width / stampDpiX * 25.4; + double stampHeight = stampImage.Height / stampDpiY * 25.4; + + Logging.Log(LogLevel.DEBUG, "Stamp: {0}/{1}", stampWidth, stampHeight); + + if (argumentContainer['w'].HasValue && argumentContainer['h'].HasValue) + { + Logging.Log(LogLevel.DEBUG, "WH"); + + stampWidth = (float)argumentContainer['w'].DoubleValue; + stampHeight = (float)argumentContainer['h'].DoubleValue; + } + else if (argumentContainer['w'].HasValue && !argumentContainer['h'].HasValue) + { + Logging.Log(LogLevel.DEBUG, "W"); + + stampHeight *= argumentContainer['w'].DoubleValue / stampWidth; + stampWidth = (float)argumentContainer['w'].DoubleValue; + } + else if (!argumentContainer['w'].HasValue && argumentContainer['h'].HasValue) + { + Logging.Log(LogLevel.DEBUG, "H"); + + stampWidth *= argumentContainer['h'].DoubleValue / stampHeight; + stampHeight = (float)argumentContainer['h'].DoubleValue; + } + + stampWidth = stampWidth / 25.4 * 72.0; + stampHeight = stampHeight / 25.4 * 72.0; + + Logging.Log(LogLevel.DEBUG, "Stamp: {0}/{1}",stampWidth,stampHeight); + + foreach (string filename in argumentContainer.AdditionalArguments) + { + string outputFilename = Path.Combine( + argumentContainer['o'].Value, + string.Format("{0}{1}.pdf",Path.GetFileNameWithoutExtension(filename), argumentContainer['e'].Value) + ); + + Logging.Log(LogLevel.INFO, "{0} -> {1}", filename, outputFilename); + + using (FileStream outputStream = new FileStream(outputFilename, FileMode.Create)) + { + PdfReader pdfReader = new PdfReader(filename); + PdfStamper pdfStamper = new PdfStamper(pdfReader, outputStream); + + + for (int p = 0; p < pdfReader.NumberOfPages; p++) + { + Rectangle pageSize = pdfReader.GetPageSize(p + 1); + PdfContentByte overContent = pdfStamper.GetOverContent(p+1); + + overContent.AddImage(stampImage, (float)stampWidth, 0, 0, (float)stampHeight, lx, (float)(pageSize.Height - ly - stampHeight)); + } + + pdfStamper.Close(); + pdfReader.Close(); + + outputStream.Close(); + } + } + + + } + + public static void Stamp(Stream pdfStream,Image stampImage,float left,float top,float width,Stream outputStream) + { + float lx = (float)(left / 25.4 * 72); + float ly = (float)(top / 25.4 * 72); + + double stampDpiX = stampImage.DpiX == 0 ? 72 : stampImage.DpiX; // / argumentContainer['d'].DoubleValue; + double stampDpiY = stampImage.DpiY == 0 ? 72 : stampImage.DpiY; // / argumentContainer['d'].DoubleValue; + + double stampWidth = stampImage.Width / stampDpiX * 25.4; + double stampHeight = stampImage.Height / stampDpiY * 25.4; + + Logging.Log(LogLevel.DEBUG, "Stamp: (pre ) {0}/{1}", stampWidth, stampHeight); + + stampHeight = stampHeight * width / stampWidth; + stampWidth = width; + + stampWidth = stampWidth / 25.4 * 72.0; + stampHeight = stampHeight / 25.4 * 72.0; + + Logging.Log(LogLevel.DEBUG, "Stamp: (final) {0}/{1}", stampWidth, stampHeight); + + PdfReader pdfReader = new PdfReader(pdfStream); + PdfStamper pdfStamper = new PdfStamper(pdfReader, outputStream); + + + for (int p = 0; p < pdfReader.NumberOfPages; p++) + { + Rectangle pageSize = pdfReader.GetPageSize(p + 1); + PdfContentByte overContent = pdfStamper.GetOverContent(p + 1); + + overContent.AddImage(stampImage, (float)stampWidth, 0, 0, (float)stampHeight, lx, (float)(pageSize.Height - ly - stampHeight)); + } + + pdfStamper.Close(); + pdfReader.Close(); + } + + } +} diff --git a/ln.pdfstamp/www/index.html b/ln.pdfstamp/www/index.html new file mode 100644 index 0000000..c709da4 --- /dev/null +++ b/ln.pdfstamp/www/index.html @@ -0,0 +1,12 @@ + + + + + +
+ PDF Datei wählen: +
+ +
+ +