From 58022b61f1b6fa7670a7b0c582ef2bb320b8743f Mon Sep 17 00:00:00 2001 From: Will Budic Date: Sat, 13 Apr 2024 09:01:52 +1000 Subject: [PATCH] dev. --- app_lifelog_settings.cnf => app_settings.cnf | 15 ++- htdocs/cgi-bin/CNFServices.cgi | 2 + htdocs/cgi-bin/kurac_login_ctr.cgi | 108 ----------------- htdocs/cgi-bin/system/modules/CNFParser.pm | 121 ++++++++++++------- 4 files changed, 90 insertions(+), 156 deletions(-) rename app_lifelog_settings.cnf => app_settings.cnf (95%) delete mode 100755 htdocs/cgi-bin/kurac_login_ctr.cgi diff --git a/app_lifelog_settings.cnf b/app_settings.cnf similarity index 95% rename from app_lifelog_settings.cnf rename to app_settings.cnf index c7eb2ea..1ee12a2 100644 --- a/app_lifelog_settings.cnf +++ b/app_settings.cnf @@ -9,10 +9,15 @@ This is an Open Source License project -> https://choosealicense.com/licenses/is /** - These are modifiable anon application settings in this config file. - These aew not reflected to the database config settings. + These are modifiable application settings in this config file. + These are not reflected to the database config settings. + They are In CNF registered as a CNF property that contains varibles. + This can be confusing a little, as APP_SETTINGS is an CNF instruction, + property names are unique, reincountered in script with same name will overwrite like anons. + Instructing with VAR instead heare will make them CNF repository anons. **/ -<<< APP_SETTINGS +<< To Enable (1), disable (0) backups to be restored from config page. @@ -20,7 +25,8 @@ This is an Open Source License project -> https://choosealicense.com/licenses/is LOGOUT_IFRAME_ENABLED = true FORCE_DEBUG_ON = 1 LOG_DATA_PATH = data - CURRENT_THEME = "default" + CURRENT_THEME = default + DATA_DIR = ../data >>> <>> @@ -78,6 +84,7 @@ This is an Open Source License project -> https://choosealicense.com/licenses/is >> <<@<@SCRIPTS_JS> + wsrc/main.js wsrc/feeds.js >> diff --git a/htdocs/cgi-bin/CNFServices.cgi b/htdocs/cgi-bin/CNFServices.cgi index 5b0f528..824c493 100755 --- a/htdocs/cgi-bin/CNFServices.cgi +++ b/htdocs/cgi-bin/CNFServices.cgi @@ -183,6 +183,8 @@ Lifehacker's is an award-winning daily blog that features tips, shortcuts, and d #`Wired Top Stories`https://www.wired.com/feed/rss` 3 business days` Your essential guide to what’s next, delivering the WIRED take on the intersection of technology, science, business, and culture.`~ + +#`Viral Now`https://viralnow.uk/feed/`3 business days`ViralNow is a dynamic online platform at the forefront of curating and delivering trending and viral content. ViralNow brings you the latest and most engaging stories, videos, and articles from around the world.~ >> < getTree('THEMES'); - our $THEME = '/'; - if(-e $path){ - open my $fh, '<', $path or return $THEME; - $THEME = <$fh>;chomp($THEME); - close($fh); - } - my $ret = $$themes -> node($THEME); - return $$themes if(!$ret); - return $ret; -} - - - -#use CGI::Session '-ip_match'; -# use Data::Section::Simple 'get_data_section'; - -# cgi { -# my $cgi = $_; - -# # from templates/ -# my $tx = Text::Xslate->new(path => ['templates']); - -# # or from __DATA__ -# my $tx = Text::Xslate->new(path => [get_data_section]); - -# my $foo = $cgi->query_param('foo'); -# $cgi->render(html => $tx->render('index.tx', {foo => $foo})); -# }; - - -use CGI; -my $cgi = CGI->new(); - - - # $cgi->set_error_handler( - # sub { - # my ($cgi, $error, $rendered) = @_; - # chomp $error; - # $cgi->render(text=>qq(You have unfortunately hit an cgi-bin::CNFHTMLServiceError - #
$error

- # - # ) - # ); - # } - # ); - -my $page = qq( - - -
-
-               

DEMO!

-

- -); - # $cgi-> add_response_header('Expires', '1s'); - # $cgi-> add_response_header('Cache-Control', 'no-cache'); - # $cgi->reset_response_headers(); - # $cgi-> add_response_header('Content-Encoding', 'gzip'); - # $cgi-> add_response_header('Accept-Encoding','Vary'); - # $cgi-> render(text=>gzip($page)); - - -print $cgi->header(-expires => "1s", -charset => "UTF-8", -Content_Encoding => 'gzip'); -print gzip($page); - - exit 0; - -1; - -=begin copyright -Programed by : Will Budic -EContactHash : 990MWWLWM8C2MI8K (https://github.com/wbudic/EContactHash.md) -Source : https://github.com/wbudic/LifeLog -Open Source Code License -> https://github.com/wbudic/PerlCNF/blob/master/ISC_License.md -=cut copyright diff --git a/htdocs/cgi-bin/system/modules/CNFParser.pm b/htdocs/cgi-bin/system/modules/CNFParser.pm index e5e58c8..84ea9e1 100644 --- a/htdocs/cgi-bin/system/modules/CNFParser.pm +++ b/htdocs/cgi-bin/system/modules/CNFParser.pm @@ -19,7 +19,8 @@ require CNFDateTime; ##no critic qw(Subroutines::RequireFinalReturn) ##no critic Perl::Critic::Policy::ControlStructures::ProhibitMutatingListFunctions -use constant VERSION => '3.1'; +use constant VERSION => '3.2'; +use constant APPSET => 'APP_SETTINGS'; our @files; our %lists; our %properties; @@ -157,19 +158,27 @@ sub _isTrue{ return 0 if(not $value); return ($value =~ /1|true|yes|on|t|da/i) } + ### # Post parsing instructed special item objects. They have lower priority to Order of apperance and from CNFNodes. ## package InstructedDataItem { - our $dataItemCounter = int(0); + our %counters; sub new { my ($class, $ele, $ins, $val) = @_; my $priority = ($val =~ s/$meta_has_priority/""/sexi)?2:3; $val =~ s/$meta_priority/""/sexi; $priority = $2 if $2; + my $dataItemCounter; + if(exists $counters{$ele}){ + $dataItemCounter = $counters{$ele}; + }else{ + $dataItemCounter = {aid=>int(0)}; + $counters{$ele} = $dataItemCounter; + } bless { ele => $ele, - aid => $dataItemCounter++, + aid => $dataItemCounter->{aid}++, ins => $ins, val => $val, '^' => $priority @@ -322,7 +331,7 @@ sub property { my($self, $name) = @_; if($ref eq 'ARRAY'){ return @{$ret} }elsif($ref eq 'PropertyValueStyle'){ - return ${$ret->{plugin}} if $ret->{instructor} eq 'APP_SETTINGS'; + return ${$ret->{plugin}} if $ret->{instructor} eq APPSET; return $ret; } else{ @@ -355,6 +364,18 @@ sub list { return @{$an} if defined $an; die "Error: List name '$t' not found!" } +sub listProcessed { + my $self = shift; + my $t=shift; + my @arr = @{$lists{$t}}; + if(@arr){ + foreach my$i(0..$#arr){ + my $anon_name = $arr[$i]->{ele} . $arr[$i]->{aid}; + @arr[$i]= $self->anon($anon_name); + } + } + return @arr +} # Adds a list of environment expected list of variables. # This is optional and ideally to be called before parse. @@ -408,7 +429,6 @@ sub template { my ($self, $property, %macros) = @_; #private to parser sub. sub doInstruction { my ($self,$e,$t,$v) = @_; my $DO_ENABLED = $self->{'DO_ENABLED'}; my $priority = 0; - $e = $t if not defined $e; $t = "" if not defined $t; if($t eq 'CONST' or $t eq 'CONSTANT'){#Single constant with mulit-line value; # It is NOT allowed to overwrite constant. @@ -465,7 +485,7 @@ sub doInstruction { my ($self,$e,$t,$v) = @_; } $tree = CNFNode->new({'_'=>$e,'~'=>$v,'^'=>$priority}); $tree->{DEBUG} = 1 if $self->{DEBUG}; - $instructs{$e} = $tree; + $instructs{$e} = \$tree; }elsif($t eq 'TABLE'){ # This all have now be late bound and send via the CNFSQL package. since v.2.6 # It is hardly been used. But in the future this might change. my $type = "NONE"; if ($v =~ 'AUTOINCREMENT'){$type = "AUTOINCREMENT"} @@ -545,8 +565,8 @@ sub doInstruction { my ($self,$e,$t,$v) = @_; elsif($t eq 'MACRO'){ $instructs{$e}=$v; } - elsif($t eq 'APP_SETTINGS'){ - $self->instructPlugin(InstructedDataItem -> new($e, 'APP_SETTINGS', $v)); + elsif($t eq 'APPSET'){ + $self->instructPlugin(InstructedDataItem -> new($e, APPSET, $v)); } elsif(exists $instructors{$t}){ if(not $instructors{$t}->instruct($e, $v) && $self->{STRICT}){ @@ -620,7 +640,6 @@ sub loadDataFile { my ($self,$e,$path,$v,$i)=@_; sub doDataInstruction_{ my ($self,$e,$v,$t,$d)=@_; my $add_as_SQLTable = $v =~ s/${meta('SQL_TABLE')}/""/sexi; my $isPostgreSQL = $v =~ s/${meta('SQL_PostgreSQL')}/""/sexi; - my $isConstant = $v =~ s/$meta_const//se; my $isHeader = 0; $v=~ s/^\s*//gm; foreach my $row(split(/~\s/,$v)){ @@ -666,17 +685,11 @@ sub doDataInstruction_{ my ($self,$e,$v,$t,$d)=@_; my $existing = $self->{'__DATA__'}{$e}; if(defined $existing){ - if($isConstant){ - return; #Not allowed META const protected to overwrite. - } if($isHeader){$isHeader=0;next} my @rows = @$existing; push @rows, [@a] if scalar @a >0; $self->{'__DATA__'}{$e} = \@rows }else{ - if($isConstant){ - $isConstant = 0; #These are constant to be made brand new entries. - } my @rows; push @rows, [@a]; $self->{'__DATA__'}{$e} = \@rows if scalar @a >0; } @@ -729,36 +742,40 @@ sub parse { my ($self, $cnf_file, $content, $del_keys) = @_; if($tag =~ m/^<(\w*)\s+(.*?)>*$/gs){ # Original fastest and early format: <<>> my $t = $1; my $v = $2; - if(isReservedWord($self,$t)){ + if(isReservedWord($self, $t)){ + my $isAppSts = ($t eq APPSET); my $isVar = ($t eq 'VARIABLE' || $t eq 'VAR'); - if($t eq 'CONST' or $isVar){ #constant multiple properties. + if($t eq 'CONST' or $isVar or $isAppSts){ #multiple values property. + my %app_sts; foreach my $line(split '\n', $v) { my $isMETAConst = $line =~ s/$meta_const//se; $line =~ s/^\s+|\s+$//; # strip unwanted spaces - next if $line =~ m/^[\/\#]+/; #skip this line its a comment dud. $line =~ s/\s*>$//; - $line =~ m/([\$\w]*)(\s*[=:]\s*)(.*)/g; + $line =~ m/([\$\w]*)(\s*=\s*)(.*)/g; my $name = $1; - $line = $3; - $line =~ s/\s*\#.*$//g; #strip any perl comment at end of line. - $line =~ s/^\s*(['"])(.*)\g{1}$/$2/ if $line;#strip quotes + $line = $3; $line =~ s/^\s*(['"])(.*)\g{1}$/$2/ if $line;#strip quotes if(defined $name){ - if($isVar && not $isMETAConst){ - $anons ->{$name} = $line if $line + if($isAppSts){ + $app_sts{$name} = $line if $line; + }elsif($isVar && not $isMETAConst){ + $anons -> {$name} = $line if $line }else{ $name =~ s/^\$// if $isMETAConst; # It is NOT allowed to overwrite a constant, so check an issue warning. - if(defined $line and not defined $self->{$name}){ + if(not exists($self->{$name})){ $self->{$name} = $line; }else{ my $w = "Skipping and keeping a previously set constance of -> [$name] in ". $self->{CNF_CONTENT}." the new value "; - $w .= ($line eq $self->{$name})?"matches it":"dosean't match ($.) -> $line."; $self->warn($w) + $w .= ($line eq $self->{$name})?"matches it":"dosean't match -> $line."; $self->warn($w) } } } } + if($isAppSts){ + $properties{CNFParser::APPSET} = \%app_sts + } }else{ - doInstruction($self,undef,$t,$v); + doInstruction($self,$v,$t,undef); } }else{ $v =~ s/\s*>$//; @@ -788,9 +805,9 @@ sub parse { my ($self, $cnf_file, $content, $del_keys) = @_; $v = substr $tag, length($e)+1; $v =~ s/>$// if $t ne '<<' && $tag =~ />$/ }else{ - $tag =~ m/([@%\$\.\/\w]+) ([ <>\n|^\\]{1})+ ([^<^>^^\n]+) ([<>]?) (.*)/gmxs; - $t = $3; - $v = $5; + $tag =~ m/([@%\$\.\/\w]+) ([ <>\n|^\\]{1})+ ([^<^>^^\n]+) ([<>]?) (.*)/gmxs; + $t = $3; + $v = $5; } }else{ ############################################################################# @@ -814,20 +831,22 @@ sub parse { my ($self, $cnf_file, $content, $del_keys) = @_; } if(!$v && !$RESERVED_WORDS{$t}){ - $v= $t; + $v = $t; undef $t } $v =~ s/\\/>/g;# escaped brackets from v.2.8. - #Do we have an autonumbered instructed list? - #DATA best instructions are exempted and differently handled by existing to only one uniquely named property. - #So its name can't be autonumbered. + #Do we have an autonumbered list of anons? + #Instructions like DATA can't be autonumbered properties. if ($e =~ /(.*?)\$\$$/){ $e = $1; - if($t && $t ne 'DATA'){ - my $array = $lists{$e}; - if(!$array){$array=();$lists{$e} = \@{$array};} - push @{$array}, InstructedDataItem -> new($e, $t, $v); - next + my @array = (); + if(exists $lists{$e}){ + @array = @{$lists{$e}}; + } + if(!$t or $t ne 'DATA'){ + push @array, InstructedDataItem -> new($e, $t, $v); + $lists{$e} = \@array; + next; } }elsif ($e eq '@'){#collection processing. my $isArray = $t=~ m/^@/; @@ -908,13 +927,28 @@ sub parse { my ($self, $cnf_file, $content, $del_keys) = @_; $self -> doInclude($_) if $_ && not $_->{prc_last} and not $_->{loaded} and $_->{local} eq $CUR_SCRIPT; } } + # Do those autonumbering list anons, and for pre instruction processing prepare if have it. + if(%lists){ + foreach my $arr(values %lists){ + foreach my $item(@$arr){ + my $e = $item->{ele} . $item ->{aid}; + doInstruction($self, $e, $item->{ins},$item->{val}); + } + } + undef %InstructedDataItem::counters; + } + ### Do the smart instructions and property linking. if(%instructs && not $IS_IN_INCLUDE_MODE){ my @items; foreach my $e(keys %instructs){ my $struct = $instructs{$e}; my $type = ref($struct); - if($type eq 'String'){ + if ($type eq 'REF'){ + $struct = $$struct; + $type = ref($struct); + } + if($type eq 'String'){ my $v = $struct; my @arr = ($v =~ m/(\$\$\$.+?\$\$\$)/gm); foreach my $find(@arr) {# <- MACRO TAG translate. -> @@ -1167,7 +1201,7 @@ sub doPlugin { my $pck = $plugin->{package}; my $prp = $plugin->{property}; my $sub = $plugin->{subroutine}; - if($instructor eq 'APP_SETTINGS'){ + if($instructor eq APPSET){ $pck = 'ClassicAppSettings' if ! $pck; ## no critic (RequireBarewordIncludes) require "$pck.pm"; @@ -1356,8 +1390,8 @@ sub log { my $fh = File::ReadBackwards->new($logfile) or die $!; my @buffer; $buffer[@buffer] = $fh->readline() for (1..$tail_cnt); open (my $fhTemp, ">", "/tmp/$logfile") or die $!; - foreach my $ln(reverse @buffer){ print $fhTemp $ln if $ln} - close $fhTemp; + print $fhTemp $_ foreach (reverse @buffer); + close $fhTemp; move("/tmp/$logfile",$logfile) } } @@ -1430,7 +1464,6 @@ sub addTree { } } ### Utility way to obtain CNFNodes from a configuration. -# Reference to the node is returned access like: my $tree = $cnf.getTree(..); my $attr = $$tree->{attribute}; sub getTree { my ($self, $name) = @_; return $NODES{$name} if exists $NODES{$name}; -- 2.34.1