Compare commits

...

2 Commits
master ... mojo

Author SHA1 Message Date
peteyboy c644fba146 Removed unneeded uses, removed commented out List implementation before
I used smartmatch instead.

Updated README. md specific to mojo branch
 On branch mojo
 Changes to be committed:
	modified:   README.md
	modified:   wordle-life.cgi
2022-04-20 06:37:05 +00:00
peteyboy 38585f0b71 This is copying the mojo version to just wordle-life.cgi for the mojo
branch
2022-04-20 06:10:43 +00:00
2 changed files with 92 additions and 210 deletions

View File

@ -2,8 +2,11 @@
one-page app that turns wordle shares into standard file format used in the Conway's Game of Life community and sets it up for running in embedded Lifeviewer on the same page
## Dependencies
This version was rewritten to what I meant to do in the first place, use Mojolicious Lite and take advantage of PATH_INFO routing, so it is simpler. You should be able to run it in any environment where CGI is properly passed the PATH_INFO (SDF has not configured its nginx setup to do so).
This single CGI file is expecting to be run out of the /cgi-bin directory. to change the location, you should update $ORIGIN_PAGE to what you expect. You also may need to change the path to /lv-plugin.js in the <script> tags of the html templates in the __DATA__ section.
This app is not at all packaged. You'll have to make sure all the perl modules you need are installed. If you are on a community unix server with just user rights (like, say SDF), you may need to ask an admin to install for you, or alternately, you can make a personal perl library in your user space.
Here's what I used to [install the perl module I needed with cpanm](https://stackoverflow.com/questions/2980297/how-can-i-use-cpan-as-a-non-root-user). It's just:
@ -15,13 +18,7 @@ Here's what I used to [install the perl module I needed with cpanm](https://stac
then for each package, you can run *cpanminus*:
$> cpanm CGI::Tiny
...
$> cpanm Mojo::Template
...
$> cpnam Mojo::Loader
...
$> cpanm Readonly
$> cpanm Mojolicious::Lite
...
Also, the Life Viewer is a super-cool javascript plugin app from the people at [Conwaylife.com](https://conwaylife.com) that is expected to be in the same directory as the CGI file. It is available with instructions [here](https://conwaylife.com/wiki/Tutorials/LifeViewer_JavaScript_plug-in)

View File

@ -1,102 +1,88 @@
#!/usr/pkg/bin/perl
#Above is the particular location for system binaries in SDF's metaarray, not the usual spot
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
#add my user perl library path, this is particular to each person's setup
use lib qw( /usr/pkg/lib/perl5/5.24.0 /meta/p/peteyboy/perl5/lib/perl5 );
#make request for all of the following
use CGI::Tiny;
use Mojo::Template;
use Mojo::Loader 'data_section';
#use Routes::Tiny; #don't even need
use Readonly;
use List::Util qw(first);
use Mojolicious::Lite -signatures;
use experimental 'smartmatch';
#===
# MAKE SURE ORIGIN PAGE MATCHES FILENAME (especially if you are testing changes)!
#
#===
my $ORIGIN_PAGE = "/wordle-life.cgi";
my $defaulttext = "Paste your wordle share here (replace this text)";
my $WORDLE_INPUT_PARAM = "wordle-result";
my $SHARENOTE_PARAM = "share-note";
my $ORIGIN_PAGE = "/cgi-bin/wordle-life.cgi";
my $defaulttext = "Paste your wordle share here (replace this text)";
my $PATH_PARAM = "PATH_INFO";
my $WORDLE_INPUT_PARAM = "wordle-result";
my $SHARENOTE_PARAM = "share-note";
cgi {
my $wordle;
my $rle = "";
my $isshare = 0; #flag for sharing, default false
my $sharenote = ""; #a note someone can tack onto their share
#error handler from the CGI:Tiny cookbook
my $cgi = $_;
get '/' => sub ($cgi) {
$cgi->set_error_handler(sub {
my ($cgi, $error, $rendered) = @_;
warn $error;
unless ($rendered) {
if ($cgi->response_status_code == 413) {
$cgi->render(json => {error => 'Request body limit exceeded'});
}elsif ($cgi->response_status_code == 400) {
$cgi->render(json => {error => 'Bad request'});
} else {
$cgi->render(json => {error => 'Internal server error'});
}
}
});
my $wordle;
my $method = $cgi->method;
my $rle = "";
my $isshare = 0; #flag for sharing, default false
my $sharenote = ""; #a note someone can tack onto their share
#Simple switch: make a one page app, and always go back to the same page.
#GET or HEAD loads the page blank, POST runs the Life file maker
if ($method eq 'HEAD') {
#if there are sharing query parameters put them in $wordle and activate share page logic
if (first { $_ eq $WORDLE_INPUT_PARAM } @{$cgi->req->query_params} ){
$wordle = $cgi->param($WORDLE_INPUT_PARAM);
$isshare = 1; #true
$sharenote = $cgi->param($SHARENOTE_PARAM);
}else{
$wordle = $defaulttext;
}
} elsif ($method eq 'GET') {
#TODO: if there are query parameters put them in $wordle and activate share page logic
if (first { $_ eq $WORDLE_INPUT_PARAM } @{$cgi->query_param_names} ){
$wordle = $cgi->query_param($WORDLE_INPUT_PARAM);
$isshare = 1; #true
$sharenote = $cgi->query_param($SHARENOTE_PARAM);
}else{
$wordle = $defaulttext;
}
} elsif ($method eq 'POST') {
#textarea name, pull the value from POST and reload into textarea
$wordle = $cgi->body_param($WORDLE_INPUT_PARAM);
#if input textarea not changed from default text, do nothing
unless ($wordle =~ /\Q$defaulttext\E/ or $wordle eq '') {
#[Cc] /){ #cheat, if they put in something that looks like an RLE, pass output through
if ($wordle =~ /^#[Cc] /){
my $template_name = 'index';
$cgi->stash( WORDLE_INPUT_PARAM => $WORDLE_INPUT_PARAM, ORIGIN_PAGE => $ORIGIN_PAGE, defaulttext => $defaulttext, wordle => $wordle, rle => $rle, isshare => $isshare, sharenote => $sharenote );
$cgi->render(template => $template_name);
};
get '/*path_info' => sub ($cgi) {
my $template_name = $cgi->stash("path_info");
#TODO: Check against a list of valid templates!
if ( $template_name ~~ ['about'] ) {
$cgi->stash( ORIGIN_PAGE => $ORIGIN_PAGE); #this isn't general purpose, what template needs what variables?
}else{ #TODO: fix so as not to need copied code from the else below?
$template_name = 'index';
$cgi->stash( WORDLE_INPUT_PARAM => $WORDLE_INPUT_PARAM, ORIGIN_PAGE => $ORIGIN_PAGE, defaulttext => $defaulttext, wordle => $wordle, rle => $rle, isshare => $isshare, sharenote => $sharenote );
}
$cgi->render(template => $template_name);
};
post '/' => sub($cgi) {
#textarea name, pull the value from POST and reload into textarea
$wordle = $cgi->param($WORDLE_INPUT_PARAM);
#if input textarea not changed from default text, do nothing
unless ($wordle =~ /\Q$defaulttext\E/ or $wordle eq '') {
#if they put in something that looks like an RLE, pass output through, for share or to just use the life viewer
if ($wordle =~ /^#[Cc] /){
$rle = $wordle;
#if none of that, do the thing: generate RLE
}else{
}else{
$rle = generate_rle($wordle);
}
#$sharequery= "?" . $WORDLE_INPUT_PARAM . "=" . url_escape($rle);
#$template = data_section __PACKAGE__, 'sharepage.html.ep';
#$output = $mt->render($template, { ORIGIN_PAGE =>$ORIGIN_PAGE, defaulttext => $defaulttext, wordle => $wordle, rle => $rle });
}
#$output = $mt->render($template, { WORDLE_INPUT_PARAM => $WORDLE_INPUT_PARAM, ORIGIN_PAGE => $ORIGIN_PAGE, defaulttext => $defaulttext, wordle => $wordle, rle => $rle, sharenote => $sharenote });
} else { #some other request? PUT, DELETE?
$cgi->set_response_status(405)->render;
exit;
}
die "Invalid wordle parameter" unless length $wordle;
}
}
#Load template from DATA section and output
#my $mt = Mojo::Template->new(auto_escape => 1, vars => 1);
my $mt = Mojo::Template->new(vars => 1);
my $template = data_section __PACKAGE__, 'index.html.ep';
my $output = $mt->render($template, { WORDLE_INPUT_PARAM => $WORDLE_INPUT_PARAM, ORIGIN_PAGE => $ORIGIN_PAGE, defaulttext => $defaulttext, wordle => $wordle, rle => $rle, isshare => $isshare, sharenote => $sharenote });
#my $output = $mt->render($template, { ORIGIN_PAGE =>$ORIGIN_PAGE, defaulttext => $defaulttext, wordle => $wordle, rle => $rle });
#my $output = $mt->render($template, {wordle => $wordle});
$cgi->render(html => $output );
};
$cgi->stash( WORDLE_INPUT_PARAM => $WORDLE_INPUT_PARAM, ORIGIN_PAGE => $ORIGIN_PAGE, defaulttext => $defaulttext, wordle => $wordle, rle => $rle, isshare => $isshare, sharenote => $sharenote );
$cgi->render(template =>'index');
};
app->start;
sub template_from_path_info {
my $template='';
my $path = shift;
if ($path =~ /^\//){
$template = $path;
$template =~ s/^.//;
$template =~ tr/\//./;
}
return $template;
}
#Try to Generate the RLE. Makes a lot of assumptions
sub generate_rle {
@ -177,17 +163,21 @@ __DATA__
<link rel="stylesheet" href="https://unpkg.com/some-nice-basic-css/global.css" />
<style>
.lv-rle{
.
lv-rle{
min-height:200px;
}
</style>
<meta name="LifeViewer" content="viewer textarea"> <!--required tag-->
<script src="lv-plugin.js"></script>
<script src="/lv-plugin.js"></script>
</head>
<body><h1>Wordle->Life</h1>
<body>
<p align= left> <a href="/">back to Site Home</a>
</p>
<h1>Wordle->Life</h1>
<p align= right> <a href="<%=$ORIGIN_PAGE%>/about">about</a></p>
% if ($isshare) {
<span>
@ -315,144 +305,39 @@ GRID
<p>
<p>
<p>
<hr 100%>
<em>Disclaimer: I made this! People and/or corporations may own their marks or copyrights, etc, on words mentioned on this page I don't claim to</em>
<p>
Questions, kudos or comments, mail me @sdf.org
<p>
Thanks to the community at <a href="https://conwaylife.com">conwaylife.com</a>, and the friendly folks in the forums there,
and for their <a href="https://conwaylife.com/wiki/Tutorials/LifeViewer_JavaScript_plug-in">Javascript Life Viewer</a>, which I use here.
</p>
<p>
Thanks to <a href="https://github.com/hankchizljaw/some-nice-basic-css"> hankchizljaw</a> for making his basic css publicly available
</p>
<p> Made in February 2022</p>
<p>
<center>
Hosted by SDF.org
<p><a href="https://sdf.org"><img src=https://mab.sdf.org/sdfbanner.png alt="SDF.org"></a>
</center>
</body></html>
@@ viewer.html.ep
@@ about.html.ep
<html>
<head>
<title>Play Conway's Life with your Wordle Score</title>
<link rel="stylesheet" href="https://peteyboy.freeshell.org/air.css">
<meta name="LifeViewer" content="viewer textarea"> <!--required tag-->
<script src="lv-plugin.js"></script>
<title>About Wordle-Life</title>
<link rel="stylesheet" href="https://unpkg.com/some-nice-basic-css/global.css" />
</head>
<body><h1>Wordle->Life</h1>
<p><em>Play your Wordle Share score in <a href=https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life> Conway's Life!</a></em></p>
<p>
<p> Hey, nerds, isn't it funny how the Wordle Scores can look like a glider in that old computer programming exercise, Conway's Life?</p> <img src="https://conwaylife.com/w/images/e/e2/Lwss.png" alt="Glider image from Conwaylife.org, it looks like an 8-bit staple gun" align= float />
<p> This is an about page. </p>
<ol>
<li>
<p> Paste your wordle share below and submit to convert it to a Conway's Life file so you can run it.</p>
<p> To learn more about Conway's Life, read <a href=https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life> this</a>
</li>
<p> Click <a href=<%== $ORIGIN_PAGE %>>here</a> to return to Wordle-Life page </p>
<p> Click <a href="/">here</a> to go to website Home</p>
<p>
<form id="wordle-form" name="wordle-form" action="<%== $ORIGIN_PAGE =%>" method="POST" class="flow">
<label for="wordle">Wordle Share Chart:</label>
<textarea id="wordle" name="wordle-result" rows="9" cols="50" placeholder="<%== $defaulttext =%>" style="vertical-align: middle; border:none;">
<%== $wordle %>
</textarea>
</p>
<br>
<li>
<p>Click "Submit" and and RLE format file for Conway's Game of Life will appear below.</p>
<input type="submit" value="Submit">
</li>
</ol>
<label for="life">Your wordle as Conway Life RLE file:</label>
<textarea id="life" name="Life file" rows="9" cols="50" style="vertical-align: middle; border:none;">
<%== $rle %>
</textarea>
<!--viewer container-->
<div class="viewer" class="flow">
<div class="lv-buttons">
<button onclick="document.getElementById('life').innerHTML=''">Clear</button>
<button onclick="updateMe(this)">Show in Viewer</button>
<!--the element that calls updateMe must be in the viewer container-->
</div>
<canvas height=400 width=600></canvas>
</div>
<!--end viewer container-->
</form>
</div>
<p> if there is extra text or lines in your paste, you might not get a valid file here, so look and make sure it looks like a proper RLE file, for example:
<p>
<pre code>
#C Wordle 235 3/6
x = 5,y = 3
boobo$bobbo$ooooo$
</pre code>
<p>For details about the Life RLE file format above, read <a href=https://conwaylife.com/wiki/Run_Length_Encoded>this</a>.
<p>
<strong>Next steps:</strong>
<!-- not embedded -->
<ol>
<li>copy the contents of the Conway Life box above
<li>go to a Conway's Life site, such as <a href= https://copy.sh/life/> this one at copy.sh</a> or <a href="https://lazyslug.com/lifeviewer/">this one at lazyslug.com</a> and load and run your file.</li>
<ol>
<li> specifically for the one at copy.sh:</li>
<li> Press the [Import] button at the top</li>
<li> paste in your Life file contents in the box and press [Import]</li>
<li> It will put up a box telling you it loaded your Wordle, press [OK]</li>
<li> Press the [Run] button and watch your Wordle score play LIFE!</li>
</ol>
</ol>
<p> This should work with the share/copy button in wordle, or copy/pasting your friends' wordles out of Discord or wherever as well. See whose Wordle Score looks coolest!
<p>
<p>
<p>
<hr 100%>
<em>Disclaimer: I made this! People and/or corporations may own their marks or copyrights, etc, on words mentioned on this page I don't claim to</em>
<em>Disclaimer: I made this! People and/or corporations may own their marks or copyrights, etc, on words mentioned on these pages I don't claim to</em>
<p>
Questions, kudos or comments, mail me @sdf.org
<p>
Thanks to <a href="https://github.com/hankchizljaw/some-nice-basic-css"> hankchizljaw</a> for making his basic css publicly available
<p> Made in February 2022
<p> Made in February 2022, revised April 2022 for this site, using Perl Mojolicious
<p>
<center>
Hosted by SDF.org
<p><a href="https://sdf.org"><img src=https://mab.sdf.org/sdfbanner.png alt="SDF.org"></a>
Hosted by Bisect Hosting
<p><a href="https://www.bisecthosting.com"><img src=https://www.bisecthosting.com/images/logos/logo.svg alt="bisecthosting.com" height= 10% width=auto></a>
</center>
</body></html>