speedata / publisher

speedata Publisher - a professional database Publishing system
https://www.speedata.de/
GNU Affero General Public License v3.0
292 stars 36 forks source link

[draft] allow other attachments #418

Closed pr-apes closed 1 year ago

pr-apes commented 2 years ago

@pgundlach,

this is only a draft, since it has problems.

Another files than ZUGFeRD are in fact embedded with the following changes:

diff -ru ../old-spp/sw/lua/publisher/commands.lua sw/lua/publisher/commands.lua
--- ../old-spp/sw/lua/publisher/commands.lua    2022-08-25 14:39:43.000000000 +0200
+++ sw/lua/publisher/commands.lua    2022-08-26 13:24:25.625002800 +0200
@@ -184,8 +184,12 @@
     local filename = publisher.read_attribute(layoutxml,dataxml,"filename","string")
     local selection = publisher.read_attribute(layoutxml,dataxml,"select","xpathraw")
     local destfilename = publisher.read_attribute(layoutxml,dataxml,"name","string", "ZUGFeRD-invoice.xml")
+    local file_extension = filename:match("^.*%.(.+)$"):lower()
     local zugferdcontents
     local modificationtime
+    if destfilename:match("^.*%.(.+)$") == nil then
+        destfilename = string.format("%s.%s",destfilename,file_extension)
+    end
     if selection ~= nil then
         zugferdcontents = publisher.xml_to_string(selection[1],0)
         modificationtime = os.time()
@@ -205,11 +209,25 @@
     local description = publisher.read_attribute(layoutxml,dataxml,"description","string")
     local filetype = publisher.read_attribute(layoutxml,dataxml,"type","string")
     local expected = "ZUGFeRD invoice"
-    if filetype ~= expected then
-        err("AttachFile: type must be %q but got %q",expected,filetype)
-    else
-        publisher.attach_file_pdf(zugferdcontents,description,"text/xml",modificationtime,destfilename)
+    local mimetype
+    if filetype == expected then
+        mimetype = "text/xml"
+    else
+        if file_extension == "xml" then
+            mimetype = "text/xml"
+        elseif file_extension == "pdf" then
+            mimetype = "application/pdf"
+        elseif file_extension == "jpg" or file_extension == "jpeg" then
+            mimetype = "image/jpeg"
+        elseif file_extension == "png" then
+            mimetype = "image/png"
+        elseif file_extension == "svg" then
+            mimetype = "image/svg+xml"
+        elseif file_extension == "mp3" then
+            mimetype = "audio/mpeg"
+        end
     end
+    publisher.attach_file_pdf(zugferdcontents,description,mimetype,modificationtime,destfilename)
 end

 --- AtPageCreation
@@ -7131,13 +7133,15 @@

 function attach_file_pdf(zugferdcontents,description,mimetype,modificationtime,destfilename)

-    local conformancelevel = string.match(zugferdcontents, "urn:ferd:CrossIndustryDocument:invoice:1p0:(.-)<")
-    if not conformancelevel then
-        err("No ZUGFeRD contents found")
-        return
-    else
-        conformancelevel = string.upper(conformancelevel)
-    end
+    if zugferdcontents:match("urn:ferd:CrossIndustryDocument:invoice:1p0:(.-)<") ~= nil then
+        local conformancelevel = string.match(zugferdcontents, "urn:ferd:CrossIndustryDocument:invoice:1p0:(.-)<")
+        if not conformancelevel then
+            err("No ZUGFeRD contents found")
+            return
+        else
+            conformancelevel = string.upper(conformancelevel)
+        end
+    end
     local fileobjectnum = pdf.immediateobj("stream",
         zugferdcontents,
         string.format([[/Params <</ModDate (%s)>> /Subtype /%s /Type /EmbeddedFile ]],
@@ -7156,14 +7160,18 @@
   /UF %s
 >>]],utf8_to_utf16_string_pdf(description), fileobjectnum,fileobjectnum,destfilename,utf8_to_utf16_string_pdf(destfilename)))
         -- BASIC, COMFORT, EXTENDED
-    local metadataobjnum = pdf.obj({type = "stream",
+    if zugferdcontents:match("urn:ferd:CrossIndustryDocument:invoice:1p0:(.-)<") ~= nil then
+        local metadataobjnum = pdf.obj({type = "stream",
                  string = getzugferdmetadata(conformancelevel, options.documenttitle or "ZUGFeRD Rechnung",options.documentauthor or "The Author"),
                  immediate = true,
                  attr = [[  /Subtype /XML /Type /Metadata  ]],
                  compresslevel = 0,
                  })
-    local afdatanum = pdf.immediateobj( string.format("[ %d 0 R ]",filespecnum))
-    filespecnumbers[#filespecnumbers + 1] = {filespecnum,metadataobjnum,afdatanum}
+        local afdatanum = pdf.immediateobj( string.format("[ %d 0 R ]",filespecnum))
+        filespecnumbers[#filespecnumbers + 1] = {filespecnum,metadataobjnum,afdatanum}
+    end
+    local metadataobjnum = ""
+    filespecnumbers[#filespecnumbers + 1] = {filespecnum,metadataobjnum,afdatanum}
 end

 -- %a  abbreviated weekday name (e.g., Wed)
pr-apes commented 2 years ago

The main problem for me is that I don't know how to deal with metadataobjnum.

I guess it may not be required for contents other than ZUGFeRD.

But this prevents me for having filespecnumbers doing its job.

pgundlach commented 2 years ago

I'll take a look tomorrow. Thanks for all the patches, I'll reply to you as soon as possible

pr-apes commented 2 years ago

Take them with a grain of salt (or a ton, I don't know).

After all, I cannot code 😅.

pr-apes commented 1 year ago

@pgundlach,

I have included in #431 code to read the extension from filename and include it in name (if and only if name doesn't include any extension).

Unfortunately, file attachment in Publisher is mainly focused for ZUGFeRD, so including other MIME types requires having the full functionality to attach other files implemented in publisher.lua.

This would make a great new feature for version 4.11.8.

Many thanks for your help.

pgundlach commented 1 year ago

I will come back to this pull request / issue. Currently very busy, but I really want this integrated into the speedata Publisher. Sorry for the delay, but I need a quiet moment to review and think about this solution/pull request.

So: this issue is not forgotten.

pr-apes commented 1 year ago

This is great news, @pgundlach.

I'm afraid that my pull request is only the very beginning for what Publisher needs.

All code in publisher.lua for <AttachFile> is oriented to attaching a single file. This also affects /EmbeddedFiles and /Metadata from /Catalog.

Sorry, but this is too complex for me.

pr-apes commented 1 year ago

Excuse me, but I'm not sure I understand what is going on here (I'm a bit astonished).

Attachments have become a professional feature. So, I have to figure out how to compile the source directly.

I wonder (since anyone may compile the code and distribute the binaries) whether open source really makes sense to you.

pgundlach commented 1 year ago

Attachments will be in the standard plan, attaching ZUGFeRD invoices will be in the professional plan.

pgundlach commented 1 year ago

(closing the issue was a mistake)

my goal is to have only features used by professionals in the Pro plan. Since attaching invoices was the only way to use AttachFile, the whole command is now current 'Pro'. But I will implement AttachFile for the standard Plan and only have the ZUGFeRD part as a Pro feature.

(I know that the whole Pro plan can be disappointing to some people, but keeping this software up to date and maintaining it and supporting it needs a lot of time (=money) and I have not found a sustainable way yet. Having a few pro features is an experiment)

pr-apes commented 1 year ago

my goal is to have only features used by professionals in the Pro plan. Since attaching invoices was the only way to use AttachFile, the whole command is now current 'Pro'. But I will implement AttachFile for the standard Plan and only have the ZUGFeRD part as a Pro feature.

It is clear now. Fine that attaching ZUGFeRD is a Pro feature.

I thought you were going to implement all attachments in this new version.

(I know that the whole Pro plan can be disappointing to some people, but keeping this software up to date and maintaining it and supporting it needs a lot of time (=money) and I have not found a sustainable way yet. Having a few pro features is an experiment)

Also fine for me. This isn't disappointing for me (although I thought that you were making the whole <AttachFile> an exclusive Pro feature [and this was misleading to me]).

pgundlach commented 1 year ago

I am currently taking a look at file attaching. Question. Since the mime type is optional (as of the PDF spec, if I read this correctly), what do you think of asking the user to provide a mime type instead of guessing (which only handles a few cases anyway)?

pr-apes commented 1 year ago

I think that something like <AttachFile filename="doc.pdf" type="application/pdf" /> would be fine.

pr-apes commented 1 year ago

@pgundlach,

at work, I have received a question related to PDF embedding in Publisher. (I think we may end embedding also other file types in PDF documents.)

My reply was that this isn't an available option now, but I wonder whether there may be an estimate about when Publisher will contain this feature.

I hope my question is clear: there is no need to have it soon (and I don't have any problem replying that this won't be possible in the next three years [as long as it's true]), but it would be great to give an ETA.

Many thanks for your help.

pgundlach commented 1 year ago

I estimate that I've finished that at the end of this year. I have looked into this and it is slightly more complicate than I thought (especially when not forgetting PDF A compatibility).

pr-apes commented 1 year ago

Many thanks for your reply, @pgundlach.

pgundlach commented 1 year ago

Attachments will be included in the next version, which I plan to release by the end of the week or beginning of next week.

pr-apes commented 1 year ago

Many thanks for the new release.