Series commands

This commit is contained in:
Nathan McCarty 2025-02-09 02:12:14 -05:00
parent 0571a16dab
commit d170a2fccf
3 changed files with 118 additions and 2 deletions

100
blog
View file

@ -3,6 +3,7 @@ use v6.e.PREVIEW;
use DB;
use DB::BlogMeta;
use DB::Series;
use DB::MarkdownPost;
use DB::IdrisPost;
@ -282,3 +283,102 @@ multi MAIN(
}
$db.write: $db-dir;
}
#| Create a new series
multi MAIN(
"series",
"new",
#| The path of the database file
IO::Path(Str) :$db-dir = $default-db-dir,
) {
my $db = read-db $db-dir;
say 'Series Title: ';
my $title = get;
say 'Series Description: ';
my $desc = get;
my $series = Series.new:
title => $title, desc => $desc;
my $id = $db.insert-series: $series;
say 'Series inserted with id ', $id;
$db.write: $db-dir;
}
#| Provide a table of series
multi MAIN(
"series",
"list",
#| The path of the database directory
IO::Path(Str) :$db-dir = $default-db-dir,
#| The number of items to show on a single page
Int :$per-page = 10;
#| The page number to show
Int :$page = 1;
) {
my $db = read-db $db-dir;
my @pages =
$db.series.sort(*.key).rotor($per-page, :partial);
my @page = @pages[$page - 1].flat;
my $table = Pretty::Table.new:
title => "Series (page $page/{@pages.elems})",
field-names => ["ID", "Title", "Desc"];
for @page -> $pair {
my $id = $pair.key;
my $series = $pair.value;
# TODO: Terminal aware truncation
my $title = do if $series.title.chars > 40 {
"{$series.title.substr(0, 50)}..."
} else {
$series.title
};
my $desc = do if $series.desc.chars > 40 {
"{$series.desc.substr(0, 50)}..."
} else {
$series.desc
};
$table.add-row: [$id, $title, $desc];
}
say $table;
}
#| Display the contents of a series
multi MAIN(
"series",
"info",
#| The id of the series to display
Int $id,
#| The path of the database directory
IO::Path(Str) :$db-dir = $default-db-dir,
) {
my $db = read-db $db-dir;
my $series = $db.series{$id.Int};
say 'Title: ', $series.title;
say 'Description:';
for $series.desc.lines -> $line {
say ' ', $line;
}
say 'Posts:';
for $series.post-ids -> $post-id {
my $post = $db.posts{$post-id};
say ' * ', $post-id, ': ', $post.title;
}
}
#| Add a post to a series
multi MAIN(
"series",
"add",
#| The id of the series to add to
Int $series-id,
#| The id of the post to add
Int $post-id,
#| The path of the database directory
IO::Path(Str) :$db-dir = $default-db-dir,
) {
my $db = read-db $db-dir;
my $series = $db.series{$series-id.Int};
$series.post-ids.push: $post-id.Int;
$db.write: $db-dir;
}

View file

@ -40,6 +40,15 @@ class PostDB {
}
}
#| Get the next unused series ID
method next-series-id(--> Int) {
if %!series.elems > 0 {
%!series.keys.max + 1
} else {
0
}
}
#| Insert a new post to the DB, returning its id
method insert-post(PostTypes $post --> Int) {
my $id = self.next-post-id;
@ -47,6 +56,13 @@ class PostDB {
$id
}
#| Insert a new series to the DB, returning its id
method insert-series(Series:D $series --> Int) {
my $id = self.next-series-id;
%!series{$id} = $series;
$id
}
#| Initialize a new database
method init(BlogMeta:D $meta --> PostDB:D) {
my %posts{Int} of PostTypes = %();
@ -172,7 +188,7 @@ sub read-db(IO::Path:D $dir --> PostDB:D) is export {
}
}
# Read series
my %series{Int} of PostTypes = %();
my %series{Int} of Series:D = %();
# For backwards compatability, the series directory is optional. It will be
# created on the next db operation, but we don't need it to read the site
if $series-dir.e {

View file

@ -12,4 +12,4 @@ has Str:D $.title is required;
has Str:D $.desc is required;
#| The ids of the posts in the series, in series order
has Int:D @.post-ids = [];
has Int:D @.post-ids is rw = [];