Compare commits

...

2 Commits
master ... mojo

Author SHA1 Message Date
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
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 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 ## 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. 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: 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*: then for each package, you can run *cpanminus*:
$> cpanm CGI::Tiny $> cpanm Mojolicious::Lite
...
$> cpanm Mojo::Template
...
$> cpnam Mojo::Loader
...
$> cpanm Readonly
... ...
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) 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 #!/usr/bin/perl
#Above is the particular location for system binaries in SDF's metaarray, not the usual spot
use strict; use strict;
use warnings; use warnings;
use utf8; use utf8;
#add my user perl library path, this is particular to each person's setup use Mojolicious::Lite -signatures;
use lib qw( /usr/pkg/lib/perl5/5.24.0 /meta/p/peteyboy/perl5/lib/perl5 ); use experimental 'smartmatch';
#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);
#=== #===
# MAKE SURE ORIGIN PAGE MATCHES FILENAME (especially if you are testing changes)! # MAKE SURE ORIGIN PAGE MATCHES FILENAME (especially if you are testing changes)!
# #
#=== #===
my $ORIGIN_PAGE = "/wordle-life.cgi"; my $ORIGIN_PAGE = "/cgi-bin/wordle-life.cgi";
my $defaulttext = "Paste your wordle share here (replace this text)"; my $defaulttext = "Paste your wordle share here (replace this text)";
my $WORDLE_INPUT_PARAM = "wordle-result"; my $PATH_PARAM = "PATH_INFO";
my $SHARENOTE_PARAM = "share-note"; 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 get '/' => sub ($cgi) {
my $cgi = $_;
$cgi->set_error_handler(sub { #if there are sharing query parameters put them in $wordle and activate share page logic
my ($cgi, $error, $rendered) = @_; if (first { $_ eq $WORDLE_INPUT_PARAM } @{$cgi->req->query_params} ){
warn $error; $wordle = $cgi->param($WORDLE_INPUT_PARAM);
unless ($rendered) { $isshare = 1; #true
if ($cgi->response_status_code == 413) { $sharenote = $cgi->param($SHARENOTE_PARAM);
$cgi->render(json => {error => 'Request body limit exceeded'}); }else{
}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') {
$wordle = $defaulttext; $wordle = $defaulttext;
}
} elsif ($method eq 'GET') { my $template_name = 'index';
#TODO: if there are query parameters put them in $wordle and activate share page logic $cgi->stash( WORDLE_INPUT_PARAM => $WORDLE_INPUT_PARAM, ORIGIN_PAGE => $ORIGIN_PAGE, defaulttext => $defaulttext, wordle => $wordle, rle => $rle, isshare => $isshare, sharenote => $sharenote );
if (first { $_ eq $WORDLE_INPUT_PARAM } @{$cgi->query_param_names} ){ $cgi->render(template => $template_name);
$wordle = $cgi->query_param($WORDLE_INPUT_PARAM);
$isshare = 1; #true
$sharenote = $cgi->query_param($SHARENOTE_PARAM); };
}else{
$wordle = $defaulttext; get '/*path_info' => sub ($cgi) {
} my $template_name = $cgi->stash("path_info");
} elsif ($method eq 'POST') { #TODO: Check against a list of valid templates!
#textarea name, pull the value from POST and reload into textarea if ( $template_name ~~ ['about'] ) {
$wordle = $cgi->body_param($WORDLE_INPUT_PARAM); $cgi->stash( ORIGIN_PAGE => $ORIGIN_PAGE); #this isn't general purpose, what template needs what variables?
#if input textarea not changed from default text, do nothing }else{ #TODO: fix so as not to need copied code from the else below?
unless ($wordle =~ /\Q$defaulttext\E/ or $wordle eq '') { $template_name = 'index';
#[Cc] /){ #cheat, if they put in something that looks like an RLE, pass output through $cgi->stash( WORDLE_INPUT_PARAM => $WORDLE_INPUT_PARAM, ORIGIN_PAGE => $ORIGIN_PAGE, defaulttext => $defaulttext, wordle => $wordle, rle => $rle, isshare => $isshare, sharenote => $sharenote );
if ($wordle =~ /^#[Cc] /){ }
$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; $rle = $wordle;
#if none of that, do the thing: generate RLE #if none of that, do the thing: generate RLE
}else{ }else{
$rle = generate_rle($wordle); $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 $cgi->stash( WORDLE_INPUT_PARAM => $WORDLE_INPUT_PARAM, ORIGIN_PAGE => $ORIGIN_PAGE, defaulttext => $defaulttext, wordle => $wordle, rle => $rle, isshare => $isshare, sharenote => $sharenote );
#my $mt = Mojo::Template->new(auto_escape => 1, vars => 1); $cgi->render(template =>'index');
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 }); app->start;
#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 ); 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 #Try to Generate the RLE. Makes a lot of assumptions
sub generate_rle { sub generate_rle {
@ -177,17 +163,21 @@ __DATA__
<link rel="stylesheet" href="https://unpkg.com/some-nice-basic-css/global.css" /> <link rel="stylesheet" href="https://unpkg.com/some-nice-basic-css/global.css" />
<style> <style>
.lv-rle{ .
lv-rle{
min-height:200px; min-height:200px;
} }
</style> </style>
<meta name="LifeViewer" content="viewer textarea"> <!--required tag--> <meta name="LifeViewer" content="viewer textarea"> <!--required tag-->
<script src="lv-plugin.js"></script> <script src="/lv-plugin.js"></script>
</head> </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) { % if ($isshare) {
<span> <span>
@ -315,144 +305,39 @@ GRID
<p> <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> </body></html>
@@ viewer.html.ep @@ about.html.ep
<html> <html>
<head> <head>
<title>Play Conway's Life with your Wordle Score</title> <title>About Wordle-Life</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>
<link rel="stylesheet" href="https://unpkg.com/some-nice-basic-css/global.css" />
</head> </head>
<body><h1>Wordle->Life</h1> <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>
<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> <p> Click <a href=<%== $ORIGIN_PAGE %>>here</a> to return to Wordle-Life page </p>
<li> <p> Click <a href="/">here</a> to go to website Home</p>
<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> <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%> <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> <p>
Thanks to <a href="https://github.com/hankchizljaw/some-nice-basic-css"> hankchizljaw</a> for making his basic css publicly available 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> <p>
<center> <center>
Hosted by SDF.org Hosted by Bisect Hosting
<p><a href="https://sdf.org"><img src=https://mab.sdf.org/sdfbanner.png alt="SDF.org"></a> <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> </center>
</body></html> </body></html>