mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 10:58:58 +00:00
Add attachment information to the json output
This commit is contained in:
parent
832d792e4e
commit
accb891b4f
@ -1,5 +1,8 @@
|
||||
2021-02-10 Jay Berkenbilt <ejb@ql.org>
|
||||
|
||||
* Add "attachments" as an additional json key, and add some
|
||||
information about attachments to the json output.
|
||||
|
||||
* Add new command-line arguments for operating on attachments:
|
||||
--list-attachments, --add-attachment, --remove-attachment,
|
||||
--copy-attachments-from. See --help and manual for details.
|
||||
|
@ -5104,6 +5104,19 @@ print "\n";
|
||||
than using <option>@file</option> for this purpose.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
Add some information about attachments to the json output,
|
||||
and added <literal>attachments</literal> as an additional
|
||||
json key. The information included here is limited to the
|
||||
preferred name and content stream and a reference to the
|
||||
file spec object. This is enough detail for clients to avoid
|
||||
the hassle of navigating a name tree and provides what is
|
||||
needed for basic enumeration and extraction of attachments.
|
||||
More detailed information can be obtained by following the
|
||||
reference to the file spec object.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem>
|
||||
|
44
qpdf/qpdf.cc
44
qpdf/qpdf.cc
@ -699,6 +699,22 @@ static JSON json_schema(std::set<std::string>* keys = 0)
|
||||
"filemethod",
|
||||
JSON::makeString("encryption method for attachments"));
|
||||
}
|
||||
if (all_keys || keys->count("attachments"))
|
||||
{
|
||||
JSON attachments = schema.addDictionaryMember(
|
||||
"attachments", JSON::makeDictionary());
|
||||
JSON details = attachments.addDictionaryMember(
|
||||
"<attachment-key>", JSON::makeDictionary());
|
||||
details.addDictionaryMember(
|
||||
"filespec",
|
||||
JSON::makeString("object containing the file spec"));
|
||||
details.addDictionaryMember(
|
||||
"preferredname",
|
||||
JSON::makeString("most preferred file name"));
|
||||
details.addDictionaryMember(
|
||||
"preferredcontents",
|
||||
JSON::makeString("most preferred embedded file stream"));
|
||||
}
|
||||
return schema;
|
||||
}
|
||||
|
||||
@ -1114,7 +1130,7 @@ ArgParser::initOptionTable()
|
||||
// places: json_schema, do_json, and initOptionTable.
|
||||
char const* json_key_choices[] = {
|
||||
"objects", "objectinfo", "pages", "pagelabels", "outlines",
|
||||
"acroform", "encrypt", 0};
|
||||
"acroform", "encrypt", "attachments", 0};
|
||||
(*t)["json-key"] = oe_requiredChoices(
|
||||
&ArgParser::argJsonKey, json_key_choices);
|
||||
(*t)["json-object"] = oe_requiredParameter(
|
||||
@ -4568,6 +4584,28 @@ static void do_json_encrypt(QPDF& pdf, Options& o, JSON& j)
|
||||
"filemethod", JSON::makeString(s_file_method));
|
||||
}
|
||||
|
||||
static void do_json_attachments(QPDF& pdf, Options& o, JSON& j)
|
||||
{
|
||||
JSON j_attachments = j.addDictionaryMember(
|
||||
"attachments", JSON::makeDictionary());
|
||||
QPDFEmbeddedFileDocumentHelper efdh(pdf);
|
||||
for (auto const& iter: efdh.getEmbeddedFiles())
|
||||
{
|
||||
std::string const& key = iter.first;
|
||||
auto fsoh = iter.second;
|
||||
auto j_details = j_attachments.addDictionaryMember(
|
||||
key, JSON::makeDictionary());
|
||||
j_details.addDictionaryMember(
|
||||
"filespec",
|
||||
JSON::makeString(fsoh->getObjectHandle().unparse()));
|
||||
j_details.addDictionaryMember(
|
||||
"preferredname", JSON::makeString(fsoh->getFilename()));
|
||||
j_details.addDictionaryMember(
|
||||
"preferredcontents",
|
||||
JSON::makeString(fsoh->getEmbeddedFileStream().unparse()));
|
||||
}
|
||||
}
|
||||
|
||||
static void do_json(QPDF& pdf, Options& o)
|
||||
{
|
||||
JSON j = JSON::makeDictionary();
|
||||
@ -4628,6 +4666,10 @@ static void do_json(QPDF& pdf, Options& o)
|
||||
{
|
||||
do_json_encrypt(pdf, o, j);
|
||||
}
|
||||
if (all_keys || o.json_keys.count("attachments"))
|
||||
{
|
||||
do_json_attachments(pdf, o, j);
|
||||
}
|
||||
|
||||
// Check against schema
|
||||
|
||||
|
@ -523,7 +523,7 @@ $td->runtest("page operations on form xobject",
|
||||
show_ntests();
|
||||
# ----------
|
||||
$td->notify("--- File Attachments ---");
|
||||
$n_tests += 33;
|
||||
$n_tests += 34;
|
||||
|
||||
open(F, ">auto-txt") or die;
|
||||
print F "from file";
|
||||
@ -547,6 +547,10 @@ $td->runtest("list attachments verbose",
|
||||
{$td->COMMAND => "qpdf --list-attachments --verbose a.pdf"},
|
||||
{$td->FILE => "test76-list-verbose.out", $td->EXIT_STATUS => 0},
|
||||
$td->NORMALIZE_NEWLINES);
|
||||
$td->runtest("attachments json",
|
||||
{$td->COMMAND => "qpdf --json --json-key=attachments a.pdf"},
|
||||
{$td->FILE => "test76-json.out", $td->EXIT_STATUS => 0},
|
||||
$td->NORMALIZE_NEWLINES);
|
||||
$td->runtest("remove attachment (test_driver)",
|
||||
{$td->COMMAND => "test_driver 77 test76.pdf"},
|
||||
{$td->STRING => "test 77 done\n", $td->EXIT_STATUS => 0},
|
||||
|
@ -4,6 +4,7 @@
|
||||
"hasacroform": false,
|
||||
"needappearances": false
|
||||
},
|
||||
"attachments": {},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
|
@ -385,6 +385,7 @@
|
||||
"hasacroform": true,
|
||||
"needappearances": true
|
||||
},
|
||||
"attachments": {},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
|
@ -385,6 +385,7 @@
|
||||
"hasacroform": true,
|
||||
"needappearances": true
|
||||
},
|
||||
"attachments": {},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
|
@ -4,6 +4,7 @@
|
||||
"hasacroform": false,
|
||||
"needappearances": false
|
||||
},
|
||||
"attachments": {},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
|
@ -4,6 +4,7 @@
|
||||
"hasacroform": false,
|
||||
"needappearances": false
|
||||
},
|
||||
"attachments": {},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
|
@ -4,6 +4,7 @@
|
||||
"hasacroform": false,
|
||||
"needappearances": false
|
||||
},
|
||||
"attachments": {},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
|
@ -4,6 +4,7 @@
|
||||
"hasacroform": false,
|
||||
"needappearances": false
|
||||
},
|
||||
"attachments": {},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
|
@ -4,6 +4,7 @@
|
||||
"hasacroform": false,
|
||||
"needappearances": false
|
||||
},
|
||||
"attachments": {},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
|
@ -4,6 +4,7 @@
|
||||
"hasacroform": false,
|
||||
"needappearances": false
|
||||
},
|
||||
"attachments": {},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
|
@ -4,6 +4,7 @@
|
||||
"hasacroform": false,
|
||||
"needappearances": false
|
||||
},
|
||||
"attachments": {},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
|
@ -4,6 +4,7 @@
|
||||
"hasacroform": false,
|
||||
"needappearances": false
|
||||
},
|
||||
"attachments": {},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
|
@ -4,6 +4,7 @@
|
||||
"hasacroform": false,
|
||||
"needappearances": false
|
||||
},
|
||||
"attachments": {},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
|
23
qpdf/qtest/qpdf/test76-json.out
Normal file
23
qpdf/qtest/qpdf/test76-json.out
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"attachments": {
|
||||
"att1": {
|
||||
"filespec": "4 0 R",
|
||||
"preferredcontents": "8 0 R",
|
||||
"preferredname": "att1.txt"
|
||||
},
|
||||
"att2": {
|
||||
"filespec": "5 0 R",
|
||||
"preferredcontents": "10 0 R",
|
||||
"preferredname": "att2.txt"
|
||||
},
|
||||
"att3": {
|
||||
"filespec": "6 0 R",
|
||||
"preferredcontents": "12 0 R",
|
||||
"preferredname": "π.txt"
|
||||
}
|
||||
},
|
||||
"parameters": {
|
||||
"decodelevel": "generalized"
|
||||
},
|
||||
"version": 1
|
||||
}
|
Loading…
Reference in New Issue
Block a user