2022-11-09 13:31:58 +01:00
|
|
|
package BurguillosInfo::Posts;
|
|
|
|
|
|
|
|
use v5.34.1;
|
|
|
|
|
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
|
2023-05-03 00:07:43 +02:00
|
|
|
use feature 'signatures';
|
|
|
|
|
2022-11-13 02:01:24 +01:00
|
|
|
use Data::Dumper;
|
2022-11-13 04:37:53 +01:00
|
|
|
use MIME::Base64;
|
2022-11-13 02:01:24 +01:00
|
|
|
|
2023-05-03 00:07:43 +02:00
|
|
|
use BurguillosInfo::Categories;
|
|
|
|
|
2022-11-09 13:31:58 +01:00
|
|
|
use Const::Fast;
|
|
|
|
use Mojo::DOM;
|
|
|
|
use Path::Tiny;
|
|
|
|
use DateTime::Format::ISO8601;
|
2022-11-14 02:07:13 +01:00
|
|
|
use DateTime;
|
2023-05-08 01:14:36 +02:00
|
|
|
|
|
|
|
use BurguillosInfo::Preview;
|
2022-11-09 13:31:58 +01:00
|
|
|
|
2022-11-14 00:30:05 +01:00
|
|
|
const my $CURRENT_FILE => __FILE__;
|
|
|
|
const my $ROOT_PROJECT => path($CURRENT_FILE)->parent->parent->parent;
|
|
|
|
const my $PUBLIC_DIR => $ROOT_PROJECT->child('public');
|
|
|
|
const my $POSTS_DIR => $ROOT_PROJECT->child('content/posts');
|
2022-11-09 13:31:58 +01:00
|
|
|
|
|
|
|
my $cached_posts_by_category;
|
|
|
|
my $cached_posts_by_slug;
|
|
|
|
|
|
|
|
sub new {
|
|
|
|
return bless {}, shift;
|
|
|
|
}
|
|
|
|
|
2022-11-14 02:07:13 +01:00
|
|
|
sub _ReturnCacheFilter {
|
|
|
|
my $self = shift;
|
|
|
|
my %posts_by_category_filtered;
|
|
|
|
my %posts_by_slug_filtered;
|
|
|
|
my $iso8601 = DateTime::Format::ISO8601->new;
|
|
|
|
my $current_date = DateTime->now;
|
|
|
|
for my $category ( keys %$cached_posts_by_category ) {
|
|
|
|
for my $post ( @{ $cached_posts_by_category->{$category} } ) {
|
2023-05-03 00:07:43 +02:00
|
|
|
my $date_post;
|
|
|
|
eval {
|
|
|
|
$date_post = $iso8601->parse_datetime( $post->{date} );
|
|
|
|
};
|
|
|
|
if ($@) {
|
|
|
|
print Data::Dumper::Dumper $post;
|
|
|
|
}
|
2022-11-14 02:07:13 +01:00
|
|
|
if ( $date_post > $current_date ) {
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
$posts_by_slug_filtered{ $post->{slug} } = $post;
|
|
|
|
$posts_by_category_filtered{ $post->{category} } //= [];
|
|
|
|
push @{ $posts_by_category_filtered{ $post->{category} } }, $post;
|
|
|
|
}
|
|
|
|
}
|
2022-11-19 20:00:37 +01:00
|
|
|
return ( \%posts_by_category_filtered, \%posts_by_slug_filtered );
|
2022-11-14 02:07:13 +01:00
|
|
|
}
|
|
|
|
|
2023-05-03 00:07:43 +02:00
|
|
|
sub _GeneratePostFromFile ( $self, $post_file ) {
|
|
|
|
warn "Bad file $post_file, omiting...", return
|
|
|
|
if !-f $post_file || $post_file !~ /\.xml$/;
|
|
|
|
my $dom = Mojo::DOM->new( $post_file->slurp_utf8 );
|
|
|
|
my $title = $dom->at(':root > title')->text
|
|
|
|
or die "Missing title at $post_file.";
|
|
|
|
my $author = $dom->at(':root > author')->text
|
|
|
|
or die "Missing author at $post_file.";
|
|
|
|
my $date = $dom->at(':root > date')->text
|
|
|
|
or die "Missing date at $post_file.";
|
|
|
|
my $ogdesc = $dom->at(':root > ogdesc')->text
|
|
|
|
or die "Missing ogdesc at $post_file";
|
|
|
|
my $category = $dom->at(':root > category')->text
|
|
|
|
or die "Missing category at $post_file.";
|
|
|
|
my $slug = $dom->at(':root > slug')->text
|
|
|
|
or die "Missing slug at $post_file.";
|
|
|
|
my $content = $dom->at(':root > content')->content
|
|
|
|
or die "Missing content at $post_file.";
|
|
|
|
my $image_element = $dom->at(':root > img');
|
|
|
|
my $image;
|
2023-05-03 05:30:29 +02:00
|
|
|
my $attributes = $self->_GetAttributes($post_file, $dom);
|
2023-05-03 00:07:43 +02:00
|
|
|
|
|
|
|
if ( defined $image_element ) {
|
|
|
|
$image = $image_element->attr->{src};
|
2022-11-09 13:31:58 +01:00
|
|
|
}
|
2023-05-03 00:07:43 +02:00
|
|
|
|
|
|
|
my $last_modification_date_element =
|
|
|
|
$dom->at(':root > last_modification_date');
|
|
|
|
my $last_modification_date;
|
|
|
|
if ( defined $last_modification_date_element ) {
|
|
|
|
$last_modification_date = $last_modification_date_element->content;
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
title => $title,
|
|
|
|
author => $author,
|
|
|
|
date => $date,
|
|
|
|
ogdesc => $ogdesc,
|
|
|
|
category => $category,
|
|
|
|
slug => $slug,
|
|
|
|
content => $content,
|
|
|
|
(
|
|
|
|
( defined $last_modification_date )
|
|
|
|
? ( last_modification_date => $last_modification_date )
|
|
|
|
: ()
|
|
|
|
),
|
|
|
|
( ( defined $image ) ? ( image => $image ) : () ),
|
2023-05-03 05:30:29 +02:00
|
|
|
attributes => $attributes,
|
2023-05-03 00:07:43 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2023-05-03 05:30:29 +02:00
|
|
|
sub _GetAttributes($self, $post_file, $dom) {
|
|
|
|
my $attributes_tag = $dom->at(':root > attributes');
|
|
|
|
my %attributes;
|
|
|
|
if (defined $attributes_tag) {
|
|
|
|
my @attribute_list = $attributes_tag->find('attributes > attribute')->map('text')->each;
|
|
|
|
%attributes = map {
|
|
|
|
my $identifier = $_;
|
|
|
|
($identifier => 1);
|
|
|
|
} @attribute_list;
|
|
|
|
}
|
|
|
|
return \%attributes;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-05-03 00:07:43 +02:00
|
|
|
sub _GeneratePostCache ($self) {
|
2022-11-09 13:31:58 +01:00
|
|
|
$cached_posts_by_category = {};
|
|
|
|
$cached_posts_by_slug = {};
|
2022-11-10 23:49:13 +01:00
|
|
|
for my $post_file ( sort { $b cmp $a } $POSTS_DIR->children ) {
|
2023-05-03 00:07:43 +02:00
|
|
|
my $post = $self->_GeneratePostFromFile($post_file);
|
|
|
|
if (!defined $post) {
|
|
|
|
next;
|
2023-05-02 03:23:18 +02:00
|
|
|
}
|
2023-05-03 00:07:43 +02:00
|
|
|
my $category = $post->{category};
|
2022-11-13 02:01:24 +01:00
|
|
|
$cached_posts_by_category->{$category} //= [];
|
2023-05-03 00:07:43 +02:00
|
|
|
my $slug = $post->{slug};
|
2022-11-09 13:31:58 +01:00
|
|
|
my $category_posts = $cached_posts_by_category->{$category};
|
2022-11-13 02:01:24 +01:00
|
|
|
$cached_posts_by_slug->{$slug} = $post;
|
|
|
|
push @$category_posts, $post;
|
|
|
|
}
|
2023-05-03 00:07:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
sub Retrieve {
|
|
|
|
my $self = shift;
|
|
|
|
if ( defined $cached_posts_by_category && defined $cached_posts_by_slug ) {
|
|
|
|
return $self->_ReturnCacheFilter;
|
|
|
|
}
|
|
|
|
$self->_GeneratePostCache();
|
2022-11-14 02:07:13 +01:00
|
|
|
return $self->_ReturnCacheFilter;
|
2022-11-13 02:01:24 +01:00
|
|
|
}
|
|
|
|
|
2023-05-03 00:07:43 +02:00
|
|
|
my $cache_all_post_categories = {};
|
|
|
|
sub RetrieveAllPostsForCategory ( $self, $category_name ) {
|
|
|
|
if (defined $cache_all_post_categories->{$category_name}) {
|
|
|
|
return $cache_all_post_categories->{$category_name};
|
|
|
|
}
|
|
|
|
my $categories = BurguillosInfo::Categories->new->Retrieve;
|
|
|
|
my $category = $categories->{$category_name};
|
|
|
|
my $posts = $self->RetrieveDirectPostsForCategory($category_name);
|
|
|
|
for my $child_category ( $category->{children}->@* ) {
|
|
|
|
my $child_category_name = $child_category->{slug};
|
|
|
|
push @$posts,
|
|
|
|
@{$self->RetrieveDirectPostsForCategory($child_category_name)};
|
|
|
|
}
|
|
|
|
@$posts = sort {
|
|
|
|
DateTime::Format::ISO8601->parse_datetime($b->{date}) <=>
|
|
|
|
DateTime::Format::ISO8601->parse_datetime($a->{date})
|
|
|
|
} @$posts;
|
|
|
|
$cache_all_post_categories->{$category_name} = $posts;
|
|
|
|
return $posts;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub RetrieveDirectPostsForCategory ( $self, $category_name ) {
|
|
|
|
my ($post_by_category) = $self->Retrieve;
|
|
|
|
my $categories = BurguillosInfo::Categories->new->Retrieve;
|
|
|
|
my $category = $categories->{$category_name};
|
|
|
|
if ( !defined $category ) {
|
|
|
|
die "$category_name category does not exists";
|
|
|
|
}
|
|
|
|
my $posts = $post_by_category->{$category_name};
|
|
|
|
$posts //= [];
|
|
|
|
return [@$posts];
|
|
|
|
}
|
|
|
|
|
2023-05-08 01:14:36 +02:00
|
|
|
sub PreviewOg {
|
2022-11-13 02:01:24 +01:00
|
|
|
my $self = shift;
|
|
|
|
my $post = shift;
|
|
|
|
my $title = $post->{title};
|
|
|
|
my $content = $post->{content};
|
2023-05-08 01:14:36 +02:00
|
|
|
my $image_file = $post->{image};
|
|
|
|
return BurguillosInfo::Preview->Generate($title, $content, $image_file);
|
2022-11-14 00:30:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-11-09 13:31:58 +01:00
|
|
|
|
|
|
|
1;
|