MT#5879 Rework rendering PDF preview.

mr3.3.1
Andreas Granig 11 years ago
parent fdde82379b
commit fa07184a46

@ -260,6 +260,15 @@ sub edit_content :Chained('base') :PathPart('editcontent') :Args(0) {
$c->stash(template => 'invoice/template.tt');
}
sub messages_ajax :Chained('template_list') :PathPart('messages') :Args(0) {
my ($self, $c) = @_;
$c->stash(
messages => $c->flash->{messages},
template => 'helpers/ajax_messages.tt',
);
$c->detach($c->view('TT'));
}
sub get_content_ajax :Chained('base') :PathPart('editcontent/get/ajax') :Args(0) {
my ($self, $c) = @_;
my $tmpl = $c->stash->{tmpl};
@ -269,11 +278,7 @@ sub get_content_ajax :Chained('base') :PathPart('editcontent/get/ajax') :Args(0)
$content = $tmpl->base64_saved;
} else {
my $default = 'invoice/default/invoice_template_svg.tt';
my $t = Template->new({
ENCODING => 'UTF-8',
RELATIVE => 1,
INCLUDE_PATH => './share/templates:/usr/share/ngcp-panel/templates',
});
my $t = NGCP::Panel::Utils::InvoiceTemplate::get_tt();
try {
$content = $t->context->insert($default);
@ -286,6 +291,7 @@ sub get_content_ajax :Chained('base') :PathPart('editcontent/get/ajax') :Args(0)
# some part of the chain doesn't like content being encoded as utf8 at that poing
# already; decode here, and umlauts etc will be fine througout the chain.
# TODO: doesn't work when loaded from db?
use utf8;
utf8::decode($content);
@ -328,13 +334,39 @@ sub set_content_ajax :Chained('base') :PathPart('editcontent/set/ajax') :Args(0)
$c->detach($c->view('JSON'));
}
sub messages_ajax :Chained('template_list') :PathPart('messages') :Args(0) {
my ($self, $c) = @_;
$c->stash(
messages => $c->flash->{messages},
template => 'helpers/ajax_messages.tt',
);
$c->detach($c->view('TT'));
sub preview_content :Chained('base') :PathPart('editcontent/preview') :Args(0) {
my ($self, $c, @args) = @_;
my $tmpl = $c->stash->{tmpl};
my $svg = $tmpl->base64_saved;
my $pdf = '';
my $t = NGCP::Panel::Utils::InvoiceTemplate::get_tt();
my $out = '';
my $vars = {};
try {
my $no_fake = 0;
NGCP::Panel::Utils::InvoiceTemplate::preprocess_svg($no_fake, \$svg);
$t->process(\$svg, $vars, \$out) || do {
my $error = $t->error();
my $msg = "error processing template, type=".$error->type.", info='".$error->info."'";
$c->log->error($msg);
$c->response->body("500 - error creating template:\n$msg");
$c->response->status(500);
return;
};
NGCP::Panel::Utils::InvoiceTemplate::svg_pdf($c, \$out, \$pdf);
} catch($e) {
$c->log->error($e);
return;
}
$c->response->content_type('application/pdf');
$c->response->body($pdf);
return;
}

@ -1,74 +1,46 @@
package NGCP::Panel::Utils::InvoiceTemplate;
#it should be part of real model, or subcontroller
use strict;
use warnings;
#use Moose;
use Sipwise::Base;
use File::Temp qw/tempfile tempdir/;
use File::Path qw/mkpath/;
use File::Temp;
use XML::XPath;
use IPC::System::Simple qw/capturex/;
use Template;
sub svg2pdf {
my ($c,$svg_ref,$in,$out) = @_;
sub svg_pdf {
my ($c,$svg_ref,$pdf_ref) = @_;
my $svg = $$svg_ref;
my(@pages) = $svg=~/(<svg.*?(?:\/svg>))/sig;
no warnings 'uninitialized';
#$c->log->debug($svg);
my ($tempdirbase,$tempdir );
#my($fh, $tempfilename) = tempfile();
$tempdirbase = join('/',File::Spec->tmpdir,@$in{qw/provider_id tt_type tt_sourcestate/}, $out->{tt_id});
! -e $tempdirbase and mkpath( $tempdirbase, 0, 0777 );
$tempdir = tempdir( DIR => $tempdirbase , CLEANUP => 0 );
#print "tempdirbase=$tempdirbase; tempdir=$tempdir;$!;\n\n\n";
$c and $c->log->debug("tempdirbase=$tempdirbase; tempdir=$tempdir;");
#try{
#} catch($e){
# NGCP::Panel::Utils::Message->error(
# c => $c,
# error => "Can't create temporary directory at: $tempdirbase;" ,
# desc => $c->loc("Can't create temporary directory."),
# );
#}
#my $dir = File::Temp->newdir(); # cleans up automatically leaving scope
my $dir = File::Temp->newdir(undef, CLEANUP => 1);
my $tempdir = $dir->dirname;
my $pagenum = 1;
my @pagefiles;
foreach my $page (@pages){
# file consists of multiple svg tags (invald!), split them up:
my(@pages) = $svg=~/(<svg.*?(?:\/svg>))/sig;
foreach my $page(@pages) {
my $fh;
my $pagefile = "$tempdir/$pagenum.svg";
push @pagefiles, $pagefile;
open($fh,">",$pagefile);
#try{
#} catch($e){
# NGCP::Panel::Utils::Message->error(
# c => $c,
# error => "Can't create temporary page file at: $tempdirbase/$page.svg;" ,
# desc => $c->loc("Can't create temporary file."),
# );
#}
open($fh, ">", $pagefile);
binmode($fh, ":utf8");
print $fh $page;
close $fh;
$pagenum++;
}
#no unit specification in documentation. Cool!
my $cmd = "rsvg-convert -h 849 -w 600 -a -f pdf ".join(" ", @pagefiles);
#print $cmd;
#die();
$c and $c->log->debug($cmd);
#$cmd = "chmod ugo+rwx $filename";
#binmode(STDIN);
#$out->{tt_string_pdf} = `$cmd`;
{
#$cmd = "fc-list";
open B, "$cmd |";
binmode B;
local $/ = undef;
$out->{tt_string_pdf} = <B>;
$c->log->error("Pipe: close: !=$!; ?=$?;");
close B or ($? == 0 ) or $c->log->error("Error closing rsvg pipe: close: $!;");
}
my @cmd_args = (qw/-h 849 -w 600 -a -f pdf/, @pagefiles);
$$pdf_ref = capturex([0], "/usr/bin/rsvg-convert", @cmd_args);
return 1;
}
sub preprocessInvoiceTemplateSvg{
my($in,$svg_ref) = @_;
sub preprocess_svg {
my($no_fake_data, $svg_ref) = @_;
my $xp = XML::XPath->new($$svg_ref);
@ -79,7 +51,7 @@ sub preprocessInvoiceTemplateSvg{
}
}
if($in->{no_fake_data}) {
if($no_fake_data) {
my $comment = $xp->find('/comment()[contains(.,"invoice_template_lorem.tt")]');
foreach my $node($comment->get_nodelist) {
$node->getParentNode->removeChild($node);
@ -93,15 +65,9 @@ sub preprocessInvoiceTemplateSvg{
$$svg_ref = ($xp->findnodes('/'))[0]->toString();
#no warnings 'uninitialized';
##print "1.\n\n\n\n\nsvg=".$out->{tt_string_prepared}.";";
$$svg_ref=~s/(?:{\s*)?<!--{|}-->(?:\s*})?//gs;
$$svg_ref=~s/<(g .*?)(?:display\s*=\s*["']*none["'[:blank:]]+)(.*?id *=["' ]+page["' ]+)([^>]*)>/<$1$2$3>/gs;
$$svg_ref=~s/<(g .*?)(id *=["' ]+page["' ]+.*?)(?:display\s*=\s*["']*none["'[:blank:]]+)([^>]*)>/<$1$2$3>/gs;
#if($in->{no_fake_data}){
# $$svg_ref=~s/\[%[^\[\%]+lorem.*?%\]//gs;
#}
##print "\n\n2.\n\n\n\nsvg=".$out->{tt_string_prepared}.";";
}
sub sanitize_svg {
@ -120,5 +86,22 @@ sub sanitize_svg {
return 1;
}
sub get_tt {
my $tt = Template->new({
ENCODING => 'UTF-8',
RELATIVE => 1,
INCLUDE_PATH => './share/templates:/usr/share/ngcp-panel/templates',
});
$tt->context->define_vmethod(
hash => get_column => sub {
my($item,$col) = @_;
if('HASH' eq ref $item){
return $item->{$col};
}
}
);
return $tt;
}
1;
# vim: set tabstop=4 expandtab:

@ -167,24 +167,6 @@ MACRO get_page_interval(pagetype, tt_type, interval_type) BLOCK;
interval;
END ;
#MACRO pagewithblock(level) BLOCK;
# #pagesrc = titlepage([],[],1,10,10);
# pagesrc = '<svg>' _ document_header() _ titlepage() _ document_footer() _ '</svg>';
# pagesrc = pagesrc.replace('<!--{|}-->','');
# USE xpath = XML.XPath(pagesrc);
# FOREACH blockid IN xpath.find('/@id[contains(.,"block_")');
# %]
# blockid=[%blockid;%]==blockid
# [%
# FOREACH blocknode IN blockid.get_nodelist();
#
# %]
# blocknode=[%blocknode;%]==blocknode
# [%
# END;
# END;
#END;
MACRO show_pages(invoice_details_zones, invoice_details_calls, pagetype, pagenum_in) BLOCK;
#todo: remove copypast with some macro, later;
@ -298,4 +280,4 @@ MACRO show_pages(invoice_details_zones, invoice_details_calls, pagetype, pagenum
END;
output_title _ output;
END;
%]
%]

@ -15,16 +15,7 @@ function formSerialize(){
</span>
<span>
<a class="btn btn-primary btn-small" href="javascript:
var previewWindow = window.open('','_blank');
previewWindow.blur;
saveTemplate({},
function(httpResponse, q, data) {
previewWindow.location.href = uriForAction();
previewWindow.focus;
}
);
void(0);"><i class="icon-eye-open"></i> [% c.loc('Preview as PDF')%]</a>
<a class="btn btn-primary btn-small" target="_blank" href="[% c.uri_for_action('/invoicetemplate/preview_content', [ tmpl.id ]) %]"><i class="icon-eye-open"></i> [% c.loc('Preview as PDF')%]</a>
</span>
<span id="load_saved_control">

Loading…
Cancel
Save