App-Mxpress-PDF

 view release on metacpan or  search on metacpan

lib/App/Mxpress/PDF/API.pm  view on Meta::CPAN

			$res{error} = 'Invalid password';
		} else {
			session 'logged_in' => true;
			$res{success} = 'You have logged in.';
		}
	}
	
	return encode_json(\%res);
};

post '/logout' => sub {
	app->destroy_session;
	return encode_json({ success => 'User has logged out.' });
};

get '/session' => sub {
	# check whether we have a session
	response_headers 'Token' => get_csrf_token();
	return encode_json({ 
		session => session->data->{logged_in} ? 1 : 0 
	});
};

our $generatePOD = compile_named(
	styles => Str,
	type => Enum[qw/module distribution raw/],
	name => StrMatch[ qr{([a-zA-Z0-9\-\:]+)} ],
	module => Types::Standard::Optional->of(StrMatch[ qr{([a-zA-Z0-9\-\:]*)} ]|Undef),
	distribution => Types::Standard::Optional->of(StrMatch[ qr{([a-zA-Z0-9\-\:]*)} ]|Undef),
	raw => Types::Standard::Optional->of(Str|Undef),
	save => Types::Standard::Optional->of(Any)
);

post '/generate/pod' => sub {
	if ( not session('logged_in') ) {
        	send_error("Not logged in", 401);
    	}

	my $body = $generatePOD->(
		decode_json(request->body)
	);
	
	my $styles = decode_json($body->{styles}) || {};

	my $client = MetaCPAN::Client::Pod::PDF->new();

	$client->styles({
		%{$client->styles},
		%$styles,
	});
	
	my $string;
	if ($body->{type} eq 'module') {
		$string = $client->pdf($body->{module}, 1);
	} elsif ($body->{type} eq 'distribution') {
		$string = $client->dist_pdf($body->{distribution}, 1);
	} else {
		$string = $client->raw($body->{name}, $body->{raw}, 1);
	}

	return send_file(\$string, content_disposition => 'attachment', content_type => 'application/pdf', charset => 'utf-8');
};

our $generatePDF = compile_named(
	params => HashRef,
	name => StrMatch[ qr{([a-zA-Z0-9\-\:]+)} ],
	styles => Types::Standard::Optional->of(Str),
	size => Types::Standard::Optional->of(Enum[qw/A1 A2 A3 A4 A5 A6/]),
	template => Types::Standard::Optional->of(Str)
);

post '/generate/pdf' => sub {
	if ( not session('logged_in') ) {
        	send_error("Not logged in", 401);
    	}

	my $body = $generatePDF->(
		decode_json(request->body)
	);
		
	if (!$body->{template}) {
		my $f = sprintf ("%s-%s.txt", $body->{name}, $body->{size});
		open my $fh, '<', 'filedb/styles/' . $f or die "cannot open file $f";
		$body->{styles} = do {local $/; <$fh> };
		close $fh;

		open $fh, '<', 'filedb/templates/' . $f or die "cannot open file $f";
		$body->{template} = do {local $/; <$fh> };
		close $fh;
	}

	my @matches = $body->{template} =~ m/\{([^}]+)\}/xmsg;
	for my $match (@matches) {
		(my $param = $match) =~ s/\(.*\)//;
		$match = quotemeta($match);
		$body->{template} =~ s/\{$match\}/$body->{params}->{$param}/g;
	}

	my @lines = split "\n\n", $body->{template};

	my $file = Mxpress::PDF->new_pdf($body->{name}, decode_json($body->{styles}));

	$file->page->header->add(
		show_page_num => 'left',
		page_num_text => "page {num}",
		h => $file->mmp(10),
		padding => 5
	);

	$file->page->footer->add(
		show_page_num => 'right',
		page_num_text => "page {num}",
		h => $file->mmp(10),
		padding => 5
	);

	$file->title->add(
		'Table of Contents'
	)->toc->placeholder;

	my %map = (
		'=' => ['title', sub {
			$_[0]->toc->add(title => $_[1])
		}],
		'==' => ['subtitle', sub {
			$_[0]->toc->add(subtitle => $_[1])
		}],
		'===' => ['subsubtitle', sub {
			$_[0]->toc->add(subsubtitle => $_[1])
		}],
		'=t=' => ['input', sub {
			$_[0]->input->add($_[1])
		}],
		'=a=' => ['textarea', sub {
			my ($file, $line) = @_;
			my $lines = ($line =~ s/\((\d*)\)$// && $1);
			$file->textarea->add($line, lines => $lines);
		}],
		'=i=' => ['image', sub {
			$_[0]->image->add($_[1])
		}],
		'=l=' => ['line', sub {
			$_[0]->line->add
		}],
		'=s=' => ['select', sub {
			my ($file, $line) = @_;
			my @options = split ',', ($line =~ s/\((.*)\)$// && $1);
			$file->select->add($line);
		}],
	);

	my $reg = sprintf('^(%s)', join '|', map { quotemeta($_) } sort { length $b <=> length $a } keys %map);

	$map{text} = ['text', sub {
		$_[0]->text->add($_[1])
	}];

	for my $line (@lines) {
		$line =~ s/^\n//;
		$line =~ s/$reg//;
		my $plug = $1 || 'text';
		$line =~ m/()/;
		$line = join '', split("\n", $line);
		$map{$plug}[1]->($file, $line);
	}

	my $string = $file->stringify();
	
	return send_file(\$string, content_disposition => 'attachment', content_type => 'application/pdf', charset => 'utf-8' );
};

our $createTemplate = compile_named(
	name => StrMatch[ qr{([a-zA-Z0-9\-\:]+)} ],
	styles => Str,
	size => Enum[qw/A1 A2 A3 A4 A5 A6/],
	template => Str
);

post '/create/template' => sub {
	if ( not session('logged_in') ) {
        	send_error("Not logged in", 401);
    	}

	my $body = $createTemplate->(
		decode_json(request->body)
	);
	my $file = sprintf 'filedb/templates/%s-%s.txt', $body->{name}, $body->{size};
	open my $fh, '>', $file;
	print $fh $body->{template};
	close $fh;

	my %params;
	my @matches = $body->{template} =~ m/\{([^}]+)\}/xmsg;
	for my $match (@matches) {
		$match =~ s/\((.*)\)//;
		$params{$match} = $1 || ''; 
		$match =~ m/()/;
	}
	$body->{params} = \%params;


	$file = sprintf 'filedb/styles/%s-%s.txt', $body->{name}, $body->{size};
	open $fh, '>', $file;
	print $fh $body->{styles};
	close $fh;

	$body->{saved} = 1;

	return encode_json($body);
};

our $deleteTemplate = compile_named(
	name => StrMatch[ qr{([a-zA-Z0-9\-\:]+)} ],
	size => Enum[qw/A1 A2 A3 A4 A5 A6/],
);

post '/delete/template' => sub {
	if ( not session('logged_in') ) {
        	send_error("Not logged in", 401);
    	}
	my $body = $deleteTemplate->(
		decode_json(request->body)
	);
	my $file = sprintf "filedb/templates/%s-%s.txt", $body->{name}, $body->{size};
	unlink $file or die "cannot unlink file $file";

	my $style = sprintf "filedb/styles/%s-%s.txt", $body->{name}, $body->{size};
	unlink $style or die "cannot unlink file $file";



( run in 2.805 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )