From: Will Budicm Date: Tue, 15 Dec 2020 14:04:38 +0000 (+1100) Subject: TZ Mapping and locale implemtation. X-Git-Url: https://lifelog.hopto.org/gitweb/?a=commitdiff_plain;h=fe4f7f47202a2da00f0eb7ca59f96ae0901586e7;p=LifeLog.git TZ Mapping and locale implemtation. --- diff --git a/Current Development Check List.md b/Current Development Check List.md index c99cd2c..9c42805 100644 --- a/Current Development Check List.md +++ b/Current Development Check List.md @@ -7,7 +7,7 @@ ### v.2.1 SUN STABLE New Features in Works * ✔ Config. page set session expires times has to be validated not to be under 2 minutes. -* Implement mapped provision of named timezones via main.inf, for towns not available in global list. +* ✔ Implement mapped provision of named timezones via main.inf, for cities not available in global zone list. * Javascript also needs to be updated to translate this properly. * ✔ PostgreSQL to be further tested. Implement server managed database. * On errors sessions appear not to be closed by driver, maybe this is required and they expire? @@ -17,15 +17,15 @@ * ✔ System configuration variables should be sorted and listed by name and grouped by type. Anons presented at the bottom. * ✔ Provide office share public link for main.inf linked categories, No login required but no log creation or search is possible. * ✔ main.inf - Make the dbname uniform across all source types with Settings, as backups use the file format, not the database name. -* Static pages setting for the pages directory. -* Search on multiple words should rank by encounter of words specified and display first. (That one is difficult) -* Provide markdown text functionality to html pages. For quick vanilla plain documentation. -* Auto collapse/expand on multi line logs by 0-none as default. Setting to 1 or more shows only that number of lines. (That one is difficult) * ✔ Edit button to show if hidden is the log entry section. * ✔ Implement title bolding on logs using markdown, so tags can be avoided, for multiline logs. * ✔ Multi db driver type support. Earth stage requires same SQL related code to work on at least one more DBMS type other than SQLight. * PostgreSQL is the candidate as MySQL is not easy to install and bulky for all systems. * Developing and adopting to MySQL or any other system is not prerogative, as it works well as it is with inbuilt simplicity. +* Static pages setting for the pages directory. +* Search on multiple words should rank by encounter of words specified and display first. (That one is difficult) +* Provide markdown text functionality to html pages. For quick vanilla plain documentation. +* Auto collapse/expand on multi line logs by 0-none as default. Setting to 1 or more shows only that number of lines. (That one is difficult) ### v.2.0 SUN RC2 Encountered diff --git a/htdocs/cgi-bin/login_ctr.cgi b/htdocs/cgi-bin/login_ctr.cgi index 3d952aa..bc40b85 100755 --- a/htdocs/cgi-bin/login_ctr.cgi +++ b/htdocs/cgi-bin/login_ctr.cgi @@ -24,13 +24,14 @@ my $cookie = $cgi->cookie(CGISESSID => $sid); my $db; my $alias = $cgi->param('alias'); my $passw = $cgi->param('passw'); -my ($debug,$frm) = ""; +my ($DBG,$frm) = ""; #Codebase release version. Release in the created db or existing one can be different, through time. my $SCRIPT_RELEASE = Settings::release(); #anons - Are parsed end obtained only here, to be transfered to the DB config. my $BACKUP_ENABLED = 0; my $AUTO_SET_TIMEZONE = 0; +my $TIME_ZONE_MAP = 0; try{ checkAutologinSet(); @@ -77,7 +78,7 @@ try{ Get latest version of this application here!
); - Settings::printDebugHTML($debug) if (Settings::debug()); + Settings::printDebugHTML($DBG) if Settings::debug(); print $cgi->end_html; } @@ -91,10 +92,10 @@ try{ my $dbg = "" ; my $pwd = `pwd`; $pwd =~ s/\s*$//; - $dbg = "--DEBUG OUTPUT--\n$debug" if $debug; + $dbg = "--DEBUG OUTPUT--\n$DBG" if Settings::debug(); print $cgi->header, "
SERVER ERROR on ".DateTime->now(). - "
".$pwd."/$0 -> &".caller." -> [\n$err]","\n$dbg
", + "
".$pwd."/$0 -> [\n$err]","\n$dbg
", $cgi->end_html; }; exit; @@ -129,18 +130,27 @@ sub checkAutologinSet { # We don't need to slurp whole file as next are expected settings in begining of the config file. open(my $fh, '<', Settings::logPath().'main.cnf' ) or LifeLogException->throw("Can't open main.cnf: $!"); while (my $line = <$fh>) { + chomp $line; + $v = Settings::parseAutonom('AUTO_LOGIN',$line); + if($v){@cre = split '/', $v; next} + $v = Settings::parseAutonom('BACKUP_ENABLED',$line); + if($v){$BACKUP_ENABLED = $v; next} + $v = Settings::parseAutonom('DBI_SOURCE',$line); + if($v){Settings::dbSrc($v); next} + $v = Settings::parseAutonom('AUTO_SET_TIMEZONE',$line); + if($v){$AUTO_SET_TIMEZONE = $v; next} + $v = Settings::parseAutonom('DBI_LOG_VAR_SIZE',$line); + if($v){Settings::dbVLSZ($v); next} + if($line =~ /<) { chomp $line; - $v = Settings::parseAutonom('AUTO_LOGIN',$line); - if($v){@cre = split '/', $v; next} - $v = Settings::parseAutonom('BACKUP_ENABLED',$line); - if($v){$BACKUP_ENABLED = $v; next} - $v = Settings::parseAutonom('DBI_SOURCE',$line); - if($v){Settings::dbSrc($v); next} - $v = Settings::parseAutonom('AUTO_SET_TIMEZONE',$line); - if($v){$AUTO_SET_TIMEZONE = $v; next} - $v = Settings::parseAutonom('DBI_LOG_VAR_SIZE',$line); - if($v){Settings::dbVLSZ($v); next} - last if Settings::parseAutonom('CONFIG',$line); #By specs the config tag, is not an autonom, if found we stop reading. So better be last one spec. in file. + last if($line =~ />$/); + $TIME_ZONE_MAP .= $line . "\n"; + } + next; + } + last if Settings::parseAutonom('CONFIG',$line); #By specs the config tag, is not an autonom, if found we stop reading. So better be last one spec. in file. } close $fh; if(@cre &&scalar(@cre)>1){ @@ -210,7 +220,7 @@ sub checkPreparePGDB { sub checkCreateTables { - my $today = Settings::today(); +try{ my ($pst, $sql,$rv, $changed) = 0; # We live check database for available tables now only once. @@ -246,8 +256,10 @@ sub checkCreateTables { # Now we got a db with CONFIG, lets get settings from there. # Default version is the scripted current one, which could have been updated. # We need to maybe update further, if these versions differ. - # Source default and the one from the CONFIG table in the (present) database. - Settings::getConfiguration($db,{backup_enabled=>$BACKUP_ENABLED,auto_set_timezone=>$AUTO_SET_TIMEZONE, db_log_var_limit=>Settings::dbVLSZ()}); + # Source default and the one from the CONFIG table in the (present) database. + Settings::getConfiguration($db,{ + backup_enabled=>$BACKUP_ENABLED,auto_set_timezone=>$AUTO_SET_TIMEZONE,TIME_ZONE_MAP=>$TIME_ZONE_MAP, db_log_var_limit=>Settings::dbVLSZ() + }); my $DB_VERSION = Settings::release(); my $hasLogTbl = $curr_tables{'LOG'}; my $hasNotesTbl = $curr_tables{'NOTES'}; @@ -261,8 +273,13 @@ sub checkCreateTables { foreach my $ana(@annons){$sql .= " NAME LIKE '$ana' OR";};$sql =~ s/OR$//; $sql .=';'; $pst = Settings::selectRecords($db, $sql); while(my @row = $pst->fetchrow_array()) { - my ($vid,$n,$sv, $dv) = ($row[0], $row[1], Settings::anon($row[1]), $row[2]); - $db->do("UPDATE CONFIG SET VALUE='$sv' WHERE ID=$vid;") if($dv ne $sv); + my ($sup,$vid,$n,$sv, $dv) = ("",$row[0], $row[1], Settings::anon($row[1]), $row[2]); + try{ + if($dv ne $sv){ + $sup = "UPDATE CONFIG SET VALUE='$sv' WHERE ID=$vid;"; + $db->do($sup); + } + }catch{$@.="\n$sup"; die "Failed[$@]"} } # # From v.1.8 Log has changed, to have LOG to NOTES relation. @@ -350,8 +367,8 @@ sub checkCreateTables { $db->do(Settings::createLOGStmt()); - my $st = $db->prepare('INSERT INTO LOG(ID_CAT,DATE,LOG) VALUES (?,?,?)'); - $st->execute( 3, $today, "DB Created!"); + my $st = $db->prepare('INSERT INTO LOG(ID_CAT,DATE,LOG) VALUES (?,?,?)'); + $st->execute( 3, Settings::today(), "DB Created!"); $session->param("cdb", "1"); } @@ -415,7 +432,7 @@ sub checkCreateTables { my $did = $r[0]; my $dnm = $r[1]; my $cmp = $dnm eq $SCRIPT_RELEASE; - $debug .= "Upgrade cmp(RELESE_VER:'$dnm' eq Settings::release:'$SCRIPT_RELEASE') == $cmp"; + $DBG .= "Upgrade cmp(RELESE_VER:'$dnm' eq Settings::release:'$SCRIPT_RELEASE') == $cmp"; #Settings::debug(1); if(!$cmp){ Settings::renumerate($db); @@ -428,9 +445,9 @@ sub checkCreateTables { else{ $pv = 0; } - &Settings::configProperty($db, 200, '^REL_RENUM',$pv); - &Settings::configProperty($db, $did>0?$did:0, 'RELEASE_VER', $SCRIPT_RELEASE); - &Settings::toLog($db, "Upgraded Life Log from v.$dnm to v.$SCRIPT_RELEASE version, this is the $pv upgrade.") if $pv; + Settings::configProperty($db, 200, '^REL_RENUM',$pv); + Settings::configProperty($db, $did>0?$did:0, 'RELEASE_VER', $SCRIPT_RELEASE); + Settings::toLog($db, "Upgraded Life Log from v.$dnm to v.$SCRIPT_RELEASE version, this is the $pv upgrade.") if $pv; } &populate($db); } @@ -442,7 +459,9 @@ sub checkCreateTables { #Then we check if we are login in intereactively back. Interective, logout should bring us to the login screen. #Bypassing auto login. So to start maybe working on another database, and a new session. return $cgi->param('autologoff') == 1; - +}catch{ + LifeLogException -> throw(error=>$@,show_trace=>1); +} } @@ -492,7 +511,7 @@ $err .= "UID{$id} taken by $vars{$id}-> $line\n"; my @arr = Settings::selectRecords($db,"SELECT ID FROM CONFIG WHERE NAME LIKE '$name';")->fetchrow_array(); $inData = 1; if(!@arr) { - $debug .= "conf.ins->".$name.",".$value.",".$tick[1]."\n"; + $DBG .= "conf.ins->".$name.",".$value.",".$tick[1]."\n"; if(Settings::isProgressDB()) {$insCnf->execute($name,$value,$tick[1])} else{$insCnf->execute($id,$name,$value,$tick[1])} } @@ -515,7 +534,7 @@ $err .= "Invalid, spec'd entry -> $line\n"; # Then check if the ID is available. If not just skip, the import. Reseting can fix that latter. if(!Settings::selectRecords($db, "SELECT ID FROM CAT WHERE NAME LIKE '$pair[1]';")->fetchrow_array()) { if(!Settings::selectRecords($db, "SELECT ID FROM CAT WHERE ID = $pair[0];")->fetchrow_array()){ - $debug .= "cat.ins->".$pair[0].",".$pair[1].",".$tick[1]."\n"; + $DBG .= "cat.ins->".$pair[0].",".$pair[1].",".$tick[1]."\n"; $insCat->execute($pair[0],$pair[1],$tick[1]); } } @@ -569,7 +588,7 @@ sub logout { my $dbg = "" ; my $pwd = `pwd`; $pwd =~ s/\s*$//; - $dbg = "--DEBUG OUTPUT--\n$debug" if $debug; + $dbg = "--DEBUG OUTPUT--\n$DBG" if Settings::debug(); print $cgi->header, "SERVER ERROR on ".DateTime->now(). "
".$pwd."/$0 -> &".caller." -> [$err]","\n$dbg
", diff --git a/htdocs/cgi-bin/main.cgi b/htdocs/cgi-bin/main.cgi index 84f095e..d7b5147 100755 --- a/htdocs/cgi-bin/main.cgi +++ b/htdocs/cgi-bin/main.cgi @@ -1332,7 +1332,7 @@ sub fetchAutocomplete { } } - if ( $aw_cnt > &Settings::autoWordLimit ) { + if ( $aw_cnt > Settings::autoWordLimit() ) { last; } } @@ -1481,7 +1481,7 @@ sub outputPage { $BUFFER = $cgi->start_html( -title => "Personal Log", -BGCOLOR => $BGCOL, - -onload => "onBodyLoad('$toggle','".&Settings::timezone."','$today','".&Settings::sessionExprs."','$rs_cur',".&Settings::dbVLSZ.");", + -onload => "onBodyLoad('$toggle','".&Settings::language."','".&Settings::timezone."','$today','".&Settings::sessionExprs."','$rs_cur',".&Settings::dbVLSZ.");", -style => [ { -type => 'text/css', -src => "wsrc/$TH_CSS" }, { -type => 'text/css', -src => 'wsrc/jquery-ui.css' }, diff --git a/htdocs/cgi-bin/system/modules/Settings.pm b/htdocs/cgi-bin/system/modules/Settings.pm index 97c1e83..cd0c4ee 100644 --- a/htdocs/cgi-bin/system/modules/Settings.pm +++ b/htdocs/cgi-bin/system/modules/Settings.pm @@ -68,6 +68,7 @@ our $DEBUG = 1; #201 -> '^EXCLUDES' : 0 (Used in main.cgi) our $SQL_PUB = undef; +our $TIME_ZONE_MAP =""; sub anons {my @ret=sort(keys %anons); return @ret;} #Check call with defined(Settings::anon('my_anon')) @@ -100,7 +101,7 @@ sub dbSrc {my $r = shift; if($r) {$DBI_SOURCE=$r; $IS_PG_DB = 1 if(inde return $DBI_SOURCE} sub dbVLSZ {my $r = shift; if(!$r){$r = $DBI_LVAR_SZ}else{$r=128 if($r<128);$DBI_LVAR_SZ=$r} return $r} sub dbFile {my $r = shift; if($r) {$DBFILE=$r} return $DBFILE} -sub dbName {return $dbname;} +sub dbName {return $dbname} sub dsn {return $DSN} sub isProgressDB {return $IS_PG_DB} sub sqlPubors {return $SQL_PUB} @@ -169,30 +170,40 @@ try { } sub today { - my $ret = DateTime->now(); - if(!$anons{'auto_set_timezone'}){ - setTimezone($ret); - } + my $ret = setTimezone(); return $ret; } +#Call after getConfig subroutine. Returns DateTime->now() set to timezone. sub setTimezone { - my $ret = shift; - my $to = shift; #optional for testing purposes. - my $v= $anons{'TIME_ZONE_MAP'}; - if($v){ - if(!%tz_map){ - %tz_map={}; chomp($v); - foreach (split('\n',$v)){ - my @p = split('=', $_); - $tz_map{trim($p[0])} = trim($p[1]); - } - } - if($to){$v = $tz_map{$to};}else{$v = $tz_map{$TIME_ZONE};} - if($v){$TIME_ZONE=$v} + my $to = shift; #optional for testing purposes. + my $ret = DateTime->now(); + if(!$anons{'auto_set_timezone'}){ + if($TIME_ZONE_MAP){ + if(!%tz_map){ + %tz_map={}; chomp($TIME_ZONE_MAP); + foreach (split('\n',$TIME_ZONE_MAP)){ + my @p = split('=', $_); + $tz_map{trim($p[0])} = trim($p[1]); + } + } + my $try = $tz_map{$TIME_ZONE}; + $try = $tz_map{$to} if(!$try); + if($try){ + $TIME_ZONE = $try; #translated to mapped lib. provided zone. + $ret -> set_time_zone($try); + } + else{ + try{#maybe current setting is valid and the actual one? + $ret -> set_time_zone($TIME_ZONE); + }catch{ + SettingsException->throw(error=>"Zone not mapped:$TIME_ZONE\nAvailable zones:\n$TIME_ZONE_MAP\n", show_trace=>$DEBUG); + } + } + } + }else{ + $ret -> set_time_zone($TIME_ZONE); } - $ret = DateTime->now() if(!$ret); - $ret -> set_time_zone($TIME_ZONE); return $ret; } @@ -201,7 +212,7 @@ sub createCONFIGStmt { CREATE TABLE CONFIG( ID INT NOT NULL UNIQUE GENERATED BY DEFAULT AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ), NAME VARCHAR(28) UNIQUE, - VALUE VARCHAR(28), + VALUE VARCHAR(128), DESCRIPTION VARCHAR(128), PRIMARY KEY(ID) ); @@ -211,7 +222,7 @@ return qq( CREATE TABLE CONFIG( ID INT PRIMARY KEY NOT NULL, NAME VCHAR(16) UNIQUE, - VALUE VCHAR(28), + VALUE VCHAR(128), DESCRIPTION VCHAR(128) ); CREATE INDEX idx_config_name ON CONFIG (NAME); @@ -332,6 +343,8 @@ return qq( sub getConfiguration { my ($db, $hsh) = @_; + my $fh; + my $ftzmap = $ENV{'PWD'}.'tz.map'; try { my $st = $db->prepare("SELECT ID, NAME, VALUE FROM CONFIG;"); $st->execute(); @@ -343,7 +356,7 @@ sub getConfiguration { when ("SESSN_EXPR") {$SESSN_EXPR = $r[2]} when ("DATE_UNI") {$DATE_UNI = $r[2]} when ("LANGUAGE") {$LANGUAGE = $r[2]} - when ("LOG_PATH") {} #ommited and code static can't change for now. + when ("LOG_PATH") {} # Ommited and code static can't change for now. when ("IMG_W_H") {$IMG_W_H = $r[2]} when ("REC_LIMIT") {$REC_LIMIT = $r[2]} when ("AUTO_WRD_LMT"){$AUTO_WRD_LMT = $r[2]} @@ -359,12 +372,22 @@ sub getConfiguration { default {$anons{$r[1]} = $r[2]} } } - #Anons are murky grounds. -- @bud + #Anons are murky grounds. -- @bud if($hsh){ + my %m = %{$hsh}; + $TIME_ZONE_MAP = $m{'TIME_ZONE_MAP'}; #This can be a large mapping we file it to tz.map, rather then keep in db. + delete($m{'TIME_ZONE_MAP'}); + if($TIME_ZONE_MAP && !(-e $ftzmap)) { + open($fh, '>', $ftzmap) or LifeLogException->throw( "Can't write to $ftzmap: $!"); + print $fh $TIME_ZONE_MAP; + close $fh; + }#else{ + # SettingsException -> throw(error=>"Missing anon TIME_ZONE_MAP! $TIME_ZONE_MAP ",show_trace=>1); + # } my $stIns = $db->prepare("INSERT INTO CONFIG (ID, NAME, VALUE, DESCRIPTION) VALUES(?,?,?,?)"); - foreach my $key (keys %{$hsh}){ + foreach my $key (keys %m){ if(index($key,'$')!=0){#per spec. anons are not prefixed with an '$' as signifier. - my $val = %{$hsh}{$key}; + my $val = $m{$key}; my $existing = $anons{$key}; #exists? Overwrite for $self config but not in DB! (dynamic code base set anon) $anons{$key} = $val; @@ -380,14 +403,20 @@ sub getConfiguration { } } } + } + elsif #At times not passing in the hash of expected anons we read in the custom tz map file if it exists. + (-e $ftzmap){ open($fh, "<:perlio", $ftzmap) or LifeLogException->throw( "Can't open $ftzmap: $!"); + read $fh, $TIME_ZONE_MAP, -s $fh; + close $fh; + } + &setTimezone; } catch { SettingsException->throw(error=>$@, show_trace=>$DEBUG); }; } - sub getTheme { given ($THEME){ when ("Sun") { $BGCOL = '#D4AF37'; $TH_CSS = "main_sun.css"; } @@ -594,8 +623,8 @@ sub connectDB { } try{ return DBI->connect($DSN, $a, $p, {AutoCommit => 1, RaiseError => 1, PrintError => 0, show_trace=>1}); - }catch{ - LifeLogException->throw(error=>"

Error->$@

", show_trace=>1); + }catch{ + LifeLogException->throw(error=>"

Error->$@

", show_trace=>1); } } diff --git a/htdocs/cgi-bin/testSettings.pl b/htdocs/cgi-bin/testSettings.pl old mode 100644 new mode 100755 index 936b844..bd9ca92 --- a/htdocs/cgi-bin/testSettings.pl +++ b/htdocs/cgi-bin/testSettings.pl @@ -14,6 +14,28 @@ require Settings; use lib $ENV{'PWD'}.'/htdocs/cgi-bin/system/modules'; require CNFParser; + +# my $TIME_ZONE_MAP =""; +# open(my $fh, '<',$ENV{'PWD'}.'/dbLifeLog/main.cnf') or LifeLogException->throw("Can't open main.cnf: $!"); +# while (my $line = <$fh>) { +# chomp $line; +# if($line =~ /<) { +# chomp $line; +# last if($line =~ />$/); +# $TIME_ZONE_MAP .= $line . "\n"; +# } +# } + +# last if Settings::parseAutonom('CONFIG',$line); #By specs the config tag, is not an autonom, if found we stop reading. So better be last one spec. in file. +# } +# close $fh; + + +# print "$TIME_ZONE_MAP\n"; + + # Settings obtains from file escalated for anons to database configuration # Currently we don't have an database set, and don't need it for this tester script. # So we read and process the main.cnf file in via parser and transfer into Settings; diff --git a/htdocs/cgi-bin/time_zones.cgi b/htdocs/cgi-bin/time_zones.cgi index 0abbde6..11ee1f9 100755 --- a/htdocs/cgi-bin/time_zones.cgi +++ b/htdocs/cgi-bin/time_zones.cgi @@ -39,43 +39,58 @@ print $cgi->start_html(-title => "Personal Log", -BGCOLOR=>"$BGCOL", #TODO -my %countries = {}; -my @states; +my %regions = {}; +my @cities; foreach my $zone (sort @zones){ $zone =~ s/\"//g; my @p = split /\//, $zone; - my $country = $p[0]; - my $city = $p[1]; - my $region = $p[2]; - - if(length($country)==0){next;} - - if($region){ - $city = "$region/$city"; + #America/Argentina/Rio_Gallegos + my $region = $p[0]; + my $country = $p[1]; + my $city = $p[2]; + if(!$city){ + $city = $country; + $country = $region; } - my $def = "$country/$city"; - - if(exists($countries{$country})){ - $states = $countries{$country}; + + if(exists($regions{$region})){ + @cities =@{ $regions{$region} }; }else{ - $states = (); - push (@{$countries{$country}}, $states); - # print "[$country] created list!\n"; + @cities = (); + $regions{$region} = \@cities; } - push @{$states}, "$country/$city"; - #print "$zone
\n"; + push @cities, "$country/$city"; } +sub trim {my $r=shift; $r=~s/^\s+|\s+$//g; return $r} print "
"; -print "

World Time Zone Strings

\n"; -foreach my $key (sort keys %countries){ - $states = $countries{$key}; - if( length($states)>0 ){ +print "

World Time Zone Strings


\n"; +my $ftzmap = $ENV{'PWD'}.'tz.map'; +if(-e $ftzmap){ + my $TIME_ZONE_MAP = ""; + open($fh, "<:perlio", $ftzmap) or LifeLogException->throw( "Can't open $ftzmap: $!"); + read $fh, $TIME_ZONE_MAP, -s $fh; + close $fh; + print "
Custom Mapped in $ftzmap
\n"; + print "
    \n"; + foreach (split('\n',$TIME_ZONE_MAP)){ + my @p = split('=', $_); + if($p[0]){ + my $mapped = trim($p[0]); + print "
  • $mapped
  • "; + } + } + print "
\n"; + print "

\n"; +} +foreach my $key (sort keys %regions){ if(!$key){next} + my @country = @{$regions{$key}}; + if( @country>0 ){ print "
$key
\n"; print "