diff --git a/lib/BurguillosInfo.pm b/lib/BurguillosInfo.pm index 3116104..146d862 100644 --- a/lib/BurguillosInfo.pm +++ b/lib/BurguillosInfo.pm @@ -13,6 +13,7 @@ sub startup ($self) { # $r->get('/:post')->to('Page#post'); $r->get('/<:category>.rss')->to('Page#category_rss'); $r->get('/:category')->to('Page#category'); + $r->get('/posts/<:slug>-preview.png')->to('Page#get_post_preview'); $r->get('/posts/:slug')->to('Page#post'); } diff --git a/lib/BurguillosInfo/Controller/Page.pm b/lib/BurguillosInfo/Controller/Page.pm index 8d38bbb..7784273 100644 --- a/lib/BurguillosInfo/Controller/Page.pm +++ b/lib/BurguillosInfo/Controller/Page.pm @@ -114,11 +114,12 @@ sub post { BurguillosInfo::Posts->new->Retrieve; my $categories = BurguillosInfo::Categories->new->Retrieve; my $post = $posts_slug->{$slug}; - my $current_category = $categories->{ $post->{category} }; if ( !defined $post ) { $self->render( template => '404', status => 404 ); return; } + my $current_category = $categories->{ $post->{category} }; + $self->stash(ogimage => 'https://burguillos.info/posts/'.$post->{slug}.'-preview.png'); $self->render( post => $post, current_category => $current_category ); } @@ -137,4 +138,20 @@ sub category { current_category => $current_category ); } + +sub get_post_preview { + my $self = shift; + my $slug = $self->param('slug'); + my $post_model = BurguillosInfo::Posts->new; + my ( $posts_categories, $posts_slug ) = $post_model->Retrieve; + if ( !defined $posts_slug->{$slug} ) { + $self->render( template => '404', status => 404 ); + return; + } + my $post = $posts_slug->{$slug}; + $self->render( + format => 'png', + data => $post_model->PostPreviewOg($post) + ); +} 1; diff --git a/lib/BurguillosInfo/Posts.pm b/lib/BurguillosInfo/Posts.pm index 7b389e9..42a80e7 100644 --- a/lib/BurguillosInfo/Posts.pm +++ b/lib/BurguillosInfo/Posts.pm @@ -5,12 +5,14 @@ use v5.34.1; use strict; use warnings; +use Data::Dumper; + use Const::Fast; use Mojo::DOM; use Path::Tiny; use DateTime::Format::ISO8601; - -use Data::Dumper; +use SVG; +use Capture::Tiny qw/capture/; const my $CURRENT_FILE => __FILE__; const my $POSTS_DIR => @@ -59,12 +61,96 @@ sub Retrieve { slug => $slug, content => $content, }; - $cached_posts_by_category->{$category} //= []; + $cached_posts_by_category->{$category} //= []; my $category_posts = $cached_posts_by_category->{$category}; - $cached_posts_by_slug->{$slug} = $post; - push @$category_posts, $post; + $cached_posts_by_slug->{$slug} = $post; + push @$category_posts, $post; } - return ($cached_posts_by_category, $cached_posts_by_slug); + return ( $cached_posts_by_category, $cached_posts_by_slug ); +} + +sub PostPreviewOg { + my $self = shift; + my $post = shift; + my $title = $post->{title}; + my $content = $post->{content}; + my $dom = Mojo::DOM->new($content); + $content = $dom->all_text; + + my @content_divided_in_lines = split /\n/, $content; + my @new_content; + my $n_chars_per_line = 60; + + for my $line (@content_divided_in_lines) { + if ( length($line) <= $n_chars_per_line ) { + push @new_content, $line; + next; + } + while ( $line =~ /(.{1,${n_chars_per_line}})/g ) { + my $new_line = $1; + push @new_content, $new_line; + } + } + my $svg = $self->_GenerateSVGPostPreview( $title, \@new_content ); + my ($stdout) = capture { + open my $fh, '|-', qw{convert /dev/stdin png:fd:1}; + binmode ':utf8', $fh; + print $fh $svg; + close $fh; + }; + return $stdout; +} + +sub _GenerateSVGPostPreview { + my $self = shift; + my $title = shift; + my $content = shift; + my @content = @$content; + my $svg = SVG->new( width => 1200, height => 630 ); + $svg->rect( + x => 0, + y => 0, + width => 1200, + height => 50, + style => { fill => 'blueviolet' } + ); + $svg->rect( + x => 0, + y => 50, + width => 1200, + height => 630, + style => { fill => '#F8F8FF' } + ); + + my $group = $svg->group( + id => 'group', + style => { + font => 'Arial', + 'font-size' => 30, + } + ); + $group->text( + x => 10, + y => 40, + style => { 'font-size' => 50, fill => '#f2eb8c' } + )->cdata('Burguillos.info'); + + $group->text( + x => 10, + y => 100, + style => { 'font-size' => 50 } + )->cdata($title); + + my $n = 0; + for my $line (@content) { + $group->text( + x => 10, + y => 140 + ( 30 * $n ), + style => { 'font-size' => 38 } + )->cdata($line); + $n++; + } + return $svg->xmlify; } 1; diff --git a/templates/layouts/default.html.ep b/templates/layouts/default.html.ep index 366dce8..21d87e0 100644 --- a/templates/layouts/default.html.ep +++ b/templates/layouts/default.html.ep @@ -7,7 +7,12 @@ +% my $ogimage = stash 'ogimage'; +% if (defined $ogimage) { + +% } else { +% }