]> bicyclesonthemoon.info Git - ott/bsta/blobdiff - 2words.1.pl
update static page after comment
[ott/bsta] / 2words.1.pl
index b001298aaa46cf067a8e251673edbb15ffbc3f72..3b8bdfa3b17d3c7ed5fa5384d30c6da881b03b51 100644 (file)
@@ -5,7 +5,7 @@
 #
 # The wordgame interface
 #
-# Copyright (C) 2016 - 2017, 2023  Balthasar Szczepański
+# Copyright (C) 2016, 2017, 2023, 2024  Balthasar Szczepański
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Affero General Public License as
@@ -27,39 +27,35 @@ use Encode ('encode', 'decode');
 
 ###PERL_LIB: use lib /botm/lib/bsta
 use botm_common (
+       'HTTP_STATUS',
+       'http_header_status', 'http_header_allow',
        'read_data_file', 'write_data_file',
-       'join_path',
        'merge_url',
        'read_header_env',
        'html_entity_encode_dec',
-       'url_query_decode'
+       'url_query_decode',
+       'open_encoded'
 );
 use bsta_lib (
        'STATE', 'INTF_STATE',
+       'get_id',
        'fail_method', 'fail_content_type',
        'print_html_start', 'print_html_end',
        'print_html_head_start', 'print_html_head_end',
        'print_html_body_start', 'print_html_body_end',
        'write_index',
        'get_remote_addr',
-       'merge_settings'
+       'merge_settings',
+       'ong'
 );
-use  File::Copy;
-
-###PERL_PATH_SEPARATOR:     PATH_SEPARATOR     = /
 
 ###PERL_CGI_PATH:           CGI_PATH           = /bsta/
 ###PERL_CGI_2WORDS_PATH:    CGI_2WORDS_PATH    = /bsta/2words
 
-###PERL_DATA_PATH:          DATA_PATH          = /botm/data/bsta/
-###PERL_DATA_DEFAULT_PATH:  DATA_DEFAULT_PATH  = /botm/data/bsta/default
-###PERL_DATA_LIST_PATH:     DATA_LIST_PATH     = /botm/data/bsta/list
 ###PERL_DATA_SETTINGS_PATH: DATA_SETTINGS_PATH = /botm/data/bsta/settings
 ###PERL_DATA_STATE_PATH:    DATA_STATE_PATH    = /botm/data/bsta/state
 ###PERL_DATA_STORY_PATH:    DATA_STORY_PATH    = /botm/data/bsta/story
 
-###PERL_WWW_PATH:           WWW_PATH           = /botm/www/1190/bsta/
-
 ###PERL_WEBSITE_NAME:       WEBSITE_NAME       = Bicycles on the Moon
 
 ###PERL_STORY_LENGTH:       STORY_LENGTH       = 16
@@ -77,7 +73,6 @@ my %story;
 my %new_story;
 my %settings;
 my %state;
-my %goto_list;
 
 my $time = time();
 srand ($time-$$);
@@ -89,6 +84,8 @@ my $color2;
 my $last_IP;
 my $story_id;
 my $turn;
+my $status;
+my $allow;
 my $message;
 my $first_letter;
 my $second_letter;
@@ -98,7 +95,7 @@ my $intf_pass;
 my $intf_pause;
 my $intf_mode;
 my $story_i_path;
-my $story_file;
+my $fh;
 my $story_lock;
 my @story_lines;
 my $ong_state;
@@ -113,33 +110,28 @@ delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
 if ($ENV{'REQUEST_METHOD'} =~ /^(HEAD|GET|POST)$/) {
        $method = $1;
 }
-else{
-       exit fail_method($ENV{'REQUEST_METHOD'}, 'GET, POST, HEAD');
+else {
+       exit fail_method($ENV{'REQUEST_METHOD'}, ['GET','POST', 'HEAD']);
 }
 
 %http = read_header_env(\%ENV);
 %cgi = url_query_decode($ENV{'QUERY_STRING'});
+
 if ($method eq 'POST') {
        if ($http{'content-type'} eq 'application/x-www-form-urlencoded') {
-               my %cgi_post=url_query_decode( <STDIN> );
-               foreach my $ind (keys %cgi_post) {
-                       $cgi{$ind} = $cgi_post{$ind};
-               }
+               my %cgi_post = url_query_decode( <STDIN> );
+               %cgi = merge_settings(\%cgi, \%cgi_post);
        }
        # multipart not supported
        else{
                exit fail_content_type($method, $http{'content-type'});
        }
 }
+
 $IP = get_remote_addr();
-if ($ENV{'PATH_INFO'} =~ /^\/(.+)$/) {
-       $page=int($1);
-}
-else {
-       $page=0;
-}
+$page = get_id(\%cgi);
 if ($cgi{'words'} ne '') {
-       $words=$cgi{'words'};
+       $words = $cgi{'words'};
 }
 
 %settings = read_data_file(DATA_SETTINGS_PATH());
@@ -149,12 +141,12 @@ $cmd_clear     = $settings{'password'}.' clear';
 $cmd_clear_all = $settings{'password'}.' clearall';
 
 $story_lock=0;
-if (open ($story_file,"+<:encoding(UTF-8)",DATA_STORY_PATH())){
+if (open_encoded($fh, "+<:encoding(UTF-8)", DATA_STORY_PATH())) {
        $story_lock=1;
-       if (flock($story_file,2)) {
+       if (flock($fh,2)) {
                $story_lock=2;
        }
-       %story = read_data_file($story_file);
+       %story = read_data_file($fh);
        
        if ($story{'lastip'} =~ /^.+$/) {
                $last_IP=$&;
@@ -178,9 +170,12 @@ if (open ($story_file,"+<:encoding(UTF-8)",DATA_STORY_PATH())){
        }
        
        if (
-               ($words eq $cmd_clear) ||
-               ($words eq $cmd_clear_all) ||
-               ($intf_state < 0)
+               ($intf_state < 0) || (
+                       ($method eq 'POST') && (
+                               ($words eq $cmd_clear) ||
+                               ($words eq $cmd_clear_all)
+                       )
+               )
        ) {
                if (
                        ($words eq $cmd_clear_all) ||
@@ -203,11 +198,12 @@ if (open ($story_file,"+<:encoding(UTF-8)",DATA_STORY_PATH())){
                                0 # pause
                        );
                }
-               write_data_file($story_file, '', '', \%story);
+               write_data_file($fh, \%story);
        }
        
-       if ($words ne '') {
+       if (($words ne '') && ($method eq 'POST')) {
                if (!$turn) {
+                       $status = HTTP_STATUS->{'forbidden'};
                        $message = "It's not your turn.";
                }
                # TODO: consider allowing non-ASCII letters in words.
@@ -220,9 +216,11 @@ if (open ($story_file,"+<:encoding(UTF-8)",DATA_STORY_PATH())){
                                ($first_letter ne $last_letter) &&
                                ($last_letter ne '')
                        ) {
+                               $status = HTTP_STATUS->{'bad_request'};
                                $message = 'The first word must start with '.uc($last_letter).'.';
                        }
                        elsif ($first_letter eq $second_letter) {
+                               $status = HTTP_STATUS->{'bad_request'};
                                $message = 'The second word can\'t also start with '.uc($first_letter).'.';
                        }
                        else {
@@ -238,7 +236,7 @@ if (open ($story_file,"+<:encoding(UTF-8)",DATA_STORY_PATH())){
                                        if (split(/\r?\n/,$story{'content'}) >= (STORY_LENGTH-1)) {
                                                # store finished game
                                                $story_i_path = DATA_STORY_PATH.$story_id;
-                                               write_data_file($story_i_path, '', '', \%story);
+                                               write_data_file($story_i_path, \%story);
                                                # init new game
                                                $new_story{'id'     } = $story_id + 1;
                                                $new_story{'letter' } = '';
@@ -262,11 +260,11 @@ if (open ($story_file,"+<:encoding(UTF-8)",DATA_STORY_PATH())){
                                                        );
                                                }
                                                # save new game
-                                               write_data_file($story_file, '', '', \%new_story);
+                                               write_data_file($fh, \%new_story);
                                        }
                                        else {
                                                $message = 'To early to finish this wordgame.';
-                                               write_data_file($story_file, '', '', \%story);
+                                               write_data_file($fh, \%story);
                                        }
                                }
                                else {
@@ -296,40 +294,49 @@ if (open ($story_file,"+<:encoding(UTF-8)",DATA_STORY_PATH())){
                                                }
                                                else {
                                                        # ready to activate?
-                                                       my $frame_data_path;
-                                                       my %frame_data;
-                                                       my %default;
-                                                       my $frame_file;
-                                                       my $in_path;
-                                                       my $out_path;
-                                                       my $ext;
-                                                       
-                                                       # prepare to ONG frame 0!
-                                                       
-                                                       $frame_data_path = join_path(PATH_SEPARATOR(), DATA_PATH(), 0);
-                                                       %frame_data = read_data_file($frame_data_path);
-                                                       %default    = read_data_file(DATA_DEFAULT_PATH());
-                                                       
-                                                       $ext = (defined($frame_data{'ext'})) ?
-                                                               $frame_data{'ext'} :
-                                                               $default{'ext'};
+                                                       my $r;
                                                        
-                                                       $frame_file = sprintf($settings{'frame'}, 0, $ext);
-                                                       $in_path  = join_path(PATH_SEPARATOR(), DATA_PATH(), $frame_file);;
-                                                       $out_path = join_path(PATH_SEPARATOR(), WWW_PATH(),  $frame_file);
-                                                       
-                                                       # set ONG time of frame 0
-                                                       # NOTE: might get overwritten later if ONG not launched
-                                                       $frame_data{'ongtime'} = $time;
-                                                       $frame_data{'timer'} = 0;
-                                                       write_data_file($frame_data_path, '', '', \%frame_data);
-                                                       
-                                                       # update the GOTO list with frame 0
-                                                       $goto_list{'title-0'  } = $frame_data{'title'};
-                                                       $goto_list{'ongtime-0'} = $frame_data{'ongtime'};
-                                                       write_data_file(DATA_LIST_PATH(), '', '', \%goto_list);
-                                                       
-                                                       if(copy ($in_path, $out_path)) {
+                                                       # ONG tape interface
+                                                       $r = ong(
+                                                               'i',   # ID: tape interface
+                                                               $time, # ONG time;    not relevant
+                                                               0,     # timer;       not relevant
+                                                               0,     # update;      not relevant
+                                                               0,     # print
+                                                               \%settings,         # not relevant
+                                                               '',    # %default;    not relevant
+                                                               '',    # %frame_data; not relevant
+                                                               ''     # $goto_list;  not relevant
+                                                       );
+                                                       if ($r) {
+                                                               # ONG CFRT
+                                                               $r = ong(
+                                                                       'c',   # ID: CFRT
+                                                                       $time, # ONG time;   not relevant
+                                                                       0,     # timer;      not relevant
+                                                                       0,     # update;     not relevant
+                                                                       0,     # print
+                                                                       \%settings,
+                                                                       '',    # %default
+                                                                       '',    # %frame_data
+                                                                       ''     # $goto_list; not relevant
+                                                               );
+                                                       }
+                                                       if ($r) {
+                                                               # ONG frame 0!
+                                                               $r = ong(
+                                                                       0,     # frame ID
+                                                                       $time, # ONG time; might get overwritten later
+                                                                       0,     # timer
+                                                                       0,     # update
+                                                                       0,     # print
+                                                                       \%settings,
+                                                                       '',    # %default
+                                                                       '',    # %frame_data
+                                                                       ''     # $goto_list
+                                                               );
+                                                       }
+                                                       if($r) {
                                                                # new state of hidden interface
                                                                $intf_pass = 1;
                                                                $intf_state = INTF_STATE->{'X'};
@@ -347,11 +354,12 @@ if (open ($story_file,"+<:encoding(UTF-8)",DATA_STORY_PATH())){
                                                        }
                                                }
                                        }
-                                       write_data_file($story_file, '', '', \%story);
+                                       write_data_file($fh, \%story);
                                }
                        }
                }
                else {
+                       $status = HTTP_STATUS->{'bad_request'};
                        $message = 'Please, two words, not more, not less (some punctuation is allowed).';
                }
        }
@@ -371,17 +379,24 @@ if (open ($story_file,"+<:encoding(UTF-8)",DATA_STORY_PATH())){
                        $intf_mode,
                        $intf_pause
                );
-               write_data_file($story_file, '', '', \%story);
+               write_data_file($fh, \%story);
        }
        @story_lines = split(/\r?\n/, $story{'content'});
        if(@story_lines & 1) {
                $turn = !$turn;
        }
        
-       close($story_file);
+       close($fh);
+}
+
+if ($status ne '') {
+       print http_header_status($status);
+}
+if ($allow ne '') {
+       print http_header_allow($allow);
 }
+print "Content-type: text/html; charset=UTF-8\n\n";
 
-print "Content-type: text/html\n\n";
 if($method eq 'HEAD') {
        exit;
 }
@@ -553,7 +568,7 @@ if ($page == 0) {
                }
                print '      <input class="intx" type="text" name="words">'."\n";
                print '      <input class="inbt" type="submit" value="enter">'."\n";
-               if(@story_lines >= (STORY_LENGTH-1)) {
+               if (@story_lines >= (STORY_LENGTH-1)) {
                        print '      <input class="inbt" type="submit" name="next" value="enter and then start a new one">'."\n";
                }
                print '     </form>'."\n";
@@ -625,5 +640,5 @@ print '    </div>'."\n";
 
 print '   </div>'."\n";
 
-print_html_body_end(\*STDOUT);
+print_html_body_end(\*STDOUT, $ong_state == STATE->{'inactive'});
 print_html_end(\*STDOUT);