dbpc/books.pl

244 lines
6.0 KiB
Perl
Executable File

#!/usr/bin/perl
# use cPanelUserConfig; #for cpanel servers
use 5.010;
use strict;
use warnings;
use File::Slurp; # https://metacpan.org/pod/File::Slurp
use JSON; # https://metacpan.org/pod/JSON
use Time::Piece; # https://perldoc.perl.org/Time::Piece
use DateTime;
###################################
#
# Daily Blackout Poetry Challenge
#
# This script supports the Daily Blackout Poetry Challenge
# it takes in text files of books and converts them into JSON
# splitting them up into "pages" for easier display
#
# license GPLv3.0 https://www.gnu.org/licenses/gpl-3.0.en.html
# Code repository: https://code.jacobhaddon.com/jake/dbpc
# Written by Jacob Haddon https://jacobhaddon.com
#
# This uses
# * File::Slurp - https://metacpan.org/pod/File::Slurp
# * JSON - https://metacpan.org/pod/JSON
#
# Texts are from Project Gutenburg - https://www.gutenberg.org/
#
###################################
# While these have json formatting, they are JS files
my $complete_books_js = "complete_books.js";
my $book_pages_js = "book_pages.js";
# number of lines in a page
my $number_of_lines = 31;
# how many pages do you want made?
my $number_of_pages = 365;
my @books = (
{
title => "Wuthering Heights",
author => "Emily Bronte",
url => "https://www.gutenberg.org/ebooks/768",
file => "books/wutheringheights.txt",
chapter_marker => "CHAPTER"
},
{
title => "Jane Eyre",
author => "Charlotte Bronte",
url => "https://www.gutenberg.org/ebooks/1260",
file => "books/janeeyre.txt",
chapter_marker => "CHAPTER"
},
{
title => "Agnes Grey",
author => "Anne Bronte",
url => "https://www.gutenberg.org/ebooks/767",
file => "books/agnesgrey.txt",
chapter_marker => "CHAPTER"
},
{
title => "Northanger Abbey",
author => "Jane Austen",
url => "https://www.gutenberg.org/ebooks/121",
file => "books/northangerabbey.txt",
chapter_marker => "CHAPTER"
},
{
title => "The Picture of Dorian Gray",
author => "Oscar Wilde",
url => "https://www.gutenberg.org/ebooks/174",
file => "books/doriangray.txt",
chapter_marker => "CHAPTER"
},
{
title => "The Mysteries of Udolpho",
author => "Ann Ward Radcliffe",
url => "https://www.gutenberg.org/ebooks/3268",
file => "books/udolpho.txt",
chapter_marker => "CHAPTER"
},
{
title => "The Enchanted Castle",
author => "E. Nesbit",
url => "https://www.gutenberg.org/ebooks/34219",
file => "books/enchantedcastle.txt",
chapter_marker => "CHAPTER"
},
{
title => "Frankenstein",
author => "Mary Wollstonecraft Shelley",
url => "https://www.gutenberg.org/ebooks/84",
file => "books/frankenstein.txt",
chapter_marker => "Chapter"
}
); # books hash
my $json = new JSON;
###################################
# Make the books into pages
###################################
# iterate over books
my $k = 0;
foreach (@books) {
# read in a whole file into a scalar
my $book = read_file($books[$k]{'file'});
# split the book into chapters by the appropriate marker
my @chapters = split('\n' . $books[$k]{'chapter_marker'}, $book);
# go through each chapter and make pages based on number of desired lines
#iterate over chapters
my $j = 0;
my @page_text;
foreach (@chapters) {
my @chapter_lines = split(/\r\n/, $chapters[$j]);
if ($j != 0){
$chapter_lines[0] = "<h1>CHAPTER" . $chapter_lines[0] . "</h1>\n\n<p>";
} # if j != 0
# how many lines are in the whole chapter
my $chapter_length = @chapter_lines;
my $i = 0;
# this is the starting place for the splice
my $line_number = $number_of_lines * $i;
# while the line number is still less than the number of lines in the chapter; make a page
while($line_number < $chapter_length) {
my @page = splice(@chapter_lines, 0, $number_of_lines);
# add a starting paragraph marker for the first page
$page[0] = "<p>" . $page[0];
# ad in blank space
foreach (@page) {
if ($_ eq "") {
$_ = "</p>\n\n<p>";
}
} # foreach page
# join the pages by a space into a string
$page_text[$j][$i] = join(" ", @page);
# Add trailing paragraph marker
$page_text[$j][$i] = $page_text[$j][$i] . "</p>\n\n";
#iterate
$i++;
$line_number = $number_of_lines * $i;
} # while line number
# iterate
$j++;
} # foreach chapters
$books[$k]{'pages'} = \@page_text;
# iterate
$k++;
} # foreach books
###################################
# Make a complete_books_js file
###################################
#turn the books variable into a JSON string
my $json_text = $json->pretty->encode( \@books );
# make the JSON formatted text into a Javascript object
my $js_text = "let books = " . $json_text;
# write the file
open(FH, '>', $complete_books_js) or die $!;
print FH $js_text;
close(FH);
###################################
# make a list of 365 pages
###################################
my $for = @books;
my %page_list;
my $dt = DateTime->now();
for ( my $l; $l < $number_of_pages; $l++){
# get a random book
my $book_list = int(rand($for));
# get the number of chapters in the book
my $chapter_list = @{$books[$book_list]{'pages'}};
# pull out a random chapter from that book
my $chapter_select = int(rand($chapter_list));
# pop off the last page, as it may be blank, or short
pop @{$books[$book_list]{'pages'}[$chapter_select]};
# get the number of pages in the chapter
my $page_list = @{$books[$book_list]{'pages'}[$chapter_select]};
# pull out a random page from the chapter
my $page_select = int(rand($page_list));
# get the text of that page
my $page_rand = $books[$book_list]{'pages'}[$chapter_select][$page_select];
$page_list{$dt->ymd} = {
title => $books[$book_list]{'title'},
author => $books[$book_list]{'author'},
page => $page_rand
};
$dt->add(days => 1);
} # for l
###################################
# Make a books_pages_js file
###################################
# made the page_ist into a JSON string
my $json_text2 = $json->pretty->encode( \%page_list );
# make the JSON formatted text into a Javascript object
my $js_text2 = "let book_pages = " . $json_text2;
# write the file
open(FH, '>', $book_pages_js) or die $!;
print FH $js_text2;
close(FH);
# FIN