]> lifelog.hopto.org Git - LifeLog.git/commitdiff
Bug 34 fix.
authorWill Budicm <redacted>
Fri, 1 Jan 2021 15:19:13 +0000 (02:19 +1100)
committerWill Budicm <redacted>
Fri, 1 Jan 2021 15:19:13 +0000 (02:19 +1100)
Current Development Check List.md
ReleaseTestCheckupList-v-2.2.md
htdocs/cgi-bin/config.cgi
htdocs/cgi-bin/data.cgi
htdocs/cgi-bin/json.cgi
htdocs/cgi-bin/login_ctr.cgi
htdocs/cgi-bin/main.cgi
htdocs/cgi-bin/system/modules/Settings.pm
htdocs/cgi-bin/testSettings.pl
htdocs/cgi-bin/wsrc/main.js

index 33bb69d8667bd253bab32525fdcf5932add0e7df..96b3236c1cb8b5033561dd867a4e4cb784ce54ec 100644 (file)
@@ -6,7 +6,7 @@
 
 ### v.2.2 EARTH RC 1
 
-* Bug 34 - DB fix in config, removes associated RTF documents to logs, for some reason.
+* &#10004; Bug 34 - DB fix in config, removes associated RTF documents to logs, for some reason.
 * Page section plugins.
   * Configured in main.cnf.
   * Accessed via side menu to appear.
index f811f552b9f65562648fbfef6c86b545004b68b3..c82715834d341eec4c18c89f736c9cdafa4b413f 100644 (file)
@@ -39,7 +39,7 @@
 
 ### Config Page config.cgi
 
-- &#9745; Look & Feel, autonom variables, like release version showing at end of System Configuration, clustered as uneditable.
+- &#9745; Look & Feel, autonom variables, like release version showing at end of System Configuration, clustered as edit enabled.
 - &#9745; Editing and changing works.
 - &#9744; Categories, adding, deleting, renaming works.
 - &#9744; Database fixes all work.
index b63228c43faae953a329f7f1eadb86af7f912375..f18bf1b145f2c15210e306828a1d803b579acdca 100755 (executable)
@@ -13,6 +13,7 @@ use Syntax::Keyword::Try;
 
 use DateTime::Format::SQLite;
 use Date::Language;
+use Capture::Tiny ':all';
 use Text::CSV;
 use Scalar::Util qw(looks_like_number);
 use Sys::Syslog qw(:DEFAULT :standard :macros); #openLog, closelog macros
@@ -808,7 +809,6 @@ sub encryptPassw {
 }
 
 
-
 sub processDBFix {
 
      my $rs_syst = $cgi->param("reset_syst");
@@ -822,16 +822,20 @@ sub processDBFix {
 try{
 
 
-        my %dates  = ();
-        my @dlts = ();
-        #Hash is unreliable for returning sequential order of keys so array must do.
-        my @updts = ();
-        my $cntr_del =0;
-        my $existing;
-        my @row;
+    my %dates  = ();
+    #Hash is unreliable for returning sequential order of keys so array must do.
+    my @dlts = ();    
+    my $cntr_del =0;
+    my $existing;
+    my @row;
+
+        getHeader() if(&Settings::debug);
+        print "<h3>Database Records Fix Result</h3>\n<hr>" if(&Settings::debug);
+        print "<body><pre>Started transaction!\n" if(&Settings::debug);
 
         $db->do('BEGIN TRANSACTION;');
-        #Check for duplicates, which are possible during imports or migration as internal rowid is not primary in log.
+        # Check for duplicates, which are possible during imports or migration as internal rowid is not primary in log.
+        # @TODO This should be selecting an cross SQL compatibe view.
         if(Settings::isProgressDB()){
             $dbs = Settings::selectRecords($db, 'SELECT ID, DATE FROM LOG ORDER BY DATE;');
         }else{
@@ -844,7 +848,6 @@ try{
             }
             else{
                 $dates{$row[0]} = $row[1];
-                $updts[$cntr_upd++] = $row[0];
             }
         }
 
@@ -854,29 +857,32 @@ try{
              }else{
                  $sql = "DELETE FROM LOG WHERE ID=$del;";
              }
-                    #print "$sql\n<br>";
-                    my $st_del = $db->prepare($sql);
-                    $st_del->execute();
+            print "$sql\n<br>";
+            my $st_del = $db->prepare($sql);
+            $st_del->execute();
         }
-
+        print "Doing renumerate next...\n" if(&Settings::debug);
         &renumerate;
+        print "done!\n";
+        print "Doing removeOldSessions next..." if(&Settings::debug);
         &Settings::removeOldSessions;
+        print "done!\n " if(&Settings::debug);
         &resetCategories if $rs_cats;
         &resetSystemConfiguration($db) if $rs_syst;
         &wipeSystemConfiguration if $wipe_ss;
 
-
-
-        $db->do('COMMIT;');
-        $db->disconnect();
+        $db->do('COMMIT;')if(&Settings::debug);
+        print "Commited ALL!<br>"if(&Settings::debug);
+       # $db->disconnect();
         $db  = Settings::connectDB();
-        $dbs = $db->do("VACUUM;");
-
-
+        $dbs = $db->do("VACUUM;")if(&Settings::debug);
+        print "Issued  VACUUM!<br>"if(&Settings::debug);
+        
         if($LOGOUT){
                 &logout;
         }
 
+        exit if(&Settings::debug);
 
 }
 catch{
@@ -885,6 +891,99 @@ catch{
 }
 }
 
+sub renumerate {
+
+    # NOTE: This is most likelly all performed under an transaction.
+    my $sql; 
+    # Fetch list by date identified rtf attached logs, with possibly now an old LID, to be updated to new one.    
+    if(Settings::isProgressDB()){
+        $sql = "SELECT ID, DATE FROM LOG WHERE RTF > 0;"
+    }else{
+        $sql = "SELECT rowid, DATE FROM LOG WHERE RTF > 0;"
+    }
+    my @row = Settings::selectRecords($db, $sql)->fetchrow_array();
+    my %notes  = ();
+    if (scalar @row > 0){
+        $notes{$row[1]} = $row[0]; #<- This is current LID, will change.
+        print "Expecting Note entry for  ".$row[1]."  LOG.ID[".$row[0]."]<- LID...\n";
+    }
+
+    ### RENUMERATE LOG
+    $db->do("CREATE TABLE life_log_temp_table AS SELECT * FROM LOG;");
+    if(Settings::isProgressDB()){
+        $db->do('DROP TABLE LOG CASCADE;');
+    }
+    else{
+        $db->do('DROP TABLE LOG;');
+    }
+    $db->do(&Settings::createLOGStmt);
+    $db->do(q(INSERT INTO LOG (ID_CAT, DATE, LOG, RTF, AMOUNT,AFLAG)
+                    SELECT ID_CAT, DATE, LOG, RTF, AMOUNT, AFLAG FROM life_log_temp_table ORDER by DATE;));
+    $db->do('DROP TABLE life_log_temp_table;');
+    ###
+
+    # Update  notes with new log id, if it changed.
+
+    foreach my $date (keys %notes){
+        my $old = $notes{$date};
+        #my $sql_date = DateTime::Format::SQLite->parse_datetime($date);
+        
+        if(Settings::isProgressDB()){
+            $sql = "SELECT ID FROM LOG WHERE RTF > 0 AND DATE = '".$date."';";
+        }else{
+            $sql = "SELECT rowid FROM LOG WHERE RTF > 0 AND DATE = '".$date."';";
+        }
+        print "Selecting ->  $sql\n";
+        $dbs = Settings::selectRecords($db, $sql);        
+        @row = $dbs->fetchrow_array();
+        if(scalar @row > 0){                            
+            my $new = $row[0];
+            if($new ne $old){
+               $db->do("UPDATE NOTES SET LID =$new WHERE LID=$old;");
+               print "Updated Note in LID[$old] to be LID[$new]\n";
+            }
+            else{
+               print "All fine skipping LID[$new]\n";
+            }
+        }else{
+            print "ERROR NOT FOUND: $date for LID:$old!\n";
+        }
+
+    }
+
+    # Delete Orphaned Notes entries if any?
+    if(Settings::isProgressDB()){
+        $dbs = Settings::selectRecords($db, "SELECT LID, LOG.ID from NOTES LEFT JOIN LOG ON
+                                        NOTES.LID = LOG.ID WHERE LOG.ID is NULL;");
+    }else{
+        $dbs = Settings::selectRecords($db, "SELECT LID, LOG.rowid from NOTES LEFT JOIN LOG ON
+                                        NOTES.LID = LOG.rowid WHERE LOG.rowid is NULL;");
+    }
+    if ($dbs) {  foreach (@row = $dbs->fetchrow_array()) {
+                $db->do("DELETE FROM NOTES WHERELID=$row[0];") if $row[0]; # 0 is the place keeper for the shared zero record. 
+    }}
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
 sub resetCategories {
     $db->do("DELETE FROM CAT;");
     $db->do("DROP TABLE CAT;");
@@ -1036,23 +1135,51 @@ sub backup {
     while(<$TAR>){print $_;}
     close $TAR;
     exit;
-
 }
 
+package DBMigStats {
+
+    
+    sub new {
+        my $class = shift;
+        my $self = bless {cats_ins  => 0, cats_upd  => 0, logs_ins  => 0, logs_upd  => 0, notes => 0}, $class;
+    }
+
+    sub cats_inserts(){my $s = shift;return $s->{cats_ins}}
+    sub cats_inserts_incr() {my $s = shift; $s->{cats_ins}++}
+    sub cats_updates(){my $s = shift;return $s->{cats_upd}}
+    sub cats_updates_incr() {my $s = shift; $s->{cats_upd}++}
+    
+    sub logs_inserts(){my $s = shift;return $s->{logs_ins}}
+    sub logs_inserts_incr(){my $s = shift;  $s->{logs_ins}++}
+    sub logs_updates(){my $s = shift;return $s->{logs_upd}}
+    sub logs_updates_incr(){my $s = shift;  $s->{logs_upd}++}
+    
+    sub notes()      {my $s = shift;return  $s->{notes}}
+    sub notes_incr() {my $s = shift; $s->{notes}++}
+
+}
 
 sub restore {
+
     my $file = shift;
-    my ($tar,$pipe,@br);
+    my ($tar,$pipe,@br,$stdout,$b_db);
     my $pass = Settings::pass();
     my $hndl = $cgi->param('data_bck');
     my $dbck = &Settings::logPath."bck/"; `mkdir $dbck` if (!-d $dbck);
+
     try{
         getHeader();
         print $cgi->start_html;
+
+my $stdout = capture_stdout {
+
+        print "<h3>Restore Result</h3>\n<hr>";
+        print "Restore started: ".Settings::today(), "\n";
         if($file){ #Open handle on server to backup to be restored.
             my $f = &Settings::logPath.$file;
             open($hndl, '<', $f) or die "Can't open $f: $!";            
-            print "<pre>Reading on server -> $file</pre>";
+            print "<pre>Reading on server backup file -> $file</pre>";
             $tar = $dbck.$file;
         }        
         else{
@@ -1067,72 +1194,94 @@ sub restore {
         close $pipe; close $hndl;
 
         print "<pre>\n";
+        
+
         my $m1 = "it is not permitted to restore another aliases log backup.";
         $m1= "has your log password changed?" if ($tar=~/_data_$alias/);
 
         my $cmd = `tar tvf $tar 2>/dev/null` 
          or die qq(, possible an security issue, $m1\nBACKUP FILE INVALID! $tar\nYour data alias is: <b>$alias</b>\nYour LifeLog version is:), Settings::release()."\n";
 
-        print "Contents->".$cmd."\n\n";
+        print "Contents->\n".$cmd."\n\n";
         $cmd = `tar xzvf $tar -C $dbck --strip-components 1 2>/dev/null` or die "Failed extracting $tar";
         print "Extracted->\n".$cmd."\n" or die "Failed extracting $tar";;
 
         my $b_base = $dbck.'data_'.$dbname.'_log.db'; 
         my $dsn= "DBI:SQLite:dbname=$b_base";
-        my $b_db = DBI->connect($dsn, $alias, $pass, { RaiseError => 1 }) or LifeLogException->throw(error=>"Invalid database! $dsn->$hndl [$@]", show_trace=>&Settings::debug);
+        $b_db = DBI->connect($dsn, $alias, $pass, { RaiseError => 1 }) or LifeLogException->throw(error=>"Invalid database! $dsn->$hndl [$@]", show_trace=>&Settings::debug);
         print "Connected to -> $dsn\n";
 
-        print "Merging from backup categories table...\n";
+        print "Merging from backup categories table...";
+        my $stats =  DBMigStats -> new();
         my $insCAT   = $db->prepare('INSERT INTO CAT (ID, NAME, DESCRIPTION) VALUES(?,?,?);') or die "Failed CAT prepare.";
         my $b_pst = Settings::selectRecords($b_db,'SELECT ID, NAME, DESCRIPTION FROM CAT;');
+        
         while ( @br = $b_pst->fetchrow_array() ) {
-            my $pst = Settings::selectRecords($db, "SELECT ID,NAME,DESCRIPTION FROM CAT WHERE ID=".$br[0].";");
+            my $pst = Settings::selectRecords($db, "SELECT ID, NAME, DESCRIPTION FROM CAT WHERE ID=".$br[0].";");
             my @ext = $pst->fetchrow_array();
             if(scalar(@ext)==0){
                 $insCAT->execute($br[0],$br[1],$br[2]);
-                print "Added CAT->".$br[0]."|".$br[1]."\n";
+                print "\nAdded CAT->".$br[0]."|".$br[1]; $stats->DBMigStats::cats_inserts_incr();
             }
             elsif($br[0] ne $ext[0] or $br[1] ne $ext[1]){
                 $db->do("UPDATE CAT SET NAME='".$br[1]."', DESCRIPTION='".$br[2]."' WHERE ID=$br[0];") or die "Cat update failed!";
-                print "Updated->".$br[0]."|".$br[1]."|".$br[2]."\n";
+                print "\nUpdated->".$br[0]."|".$br[1]."|".$br[2]; $stats->DBMigStats::cats_updates_incr();
             }
 
         }
+        
         print "\nFinished with merging CAT table.\n";
+        print "There where -> ". $stats->cats_inserts(). " inserts, and ". $stats->cats_updates(). " updates.\n";
 
         print "\n\nMerging from backup LOG table...\n";
-        my $insLOG   = $db->prepare('INSERT INTO LOG (ID_CAT, ID_RTF, DATE, LOG, AMOUNT, AFLAG, STICKY) VALUES(?,?,?,?,?,?,?);')or die "Failed LOG prepare.";
+        my %backupLIDS =();
+        my $insLOG   = $db->prepare('INSERT INTO LOG (ID_CAT, DATE, LOG, RTF, AMOUNT, AFLAG, STICKY) VALUES(?,?,?,?,?,?,?);')or die "Failed LOG prepare.";
 
-        $b_pst = Settings::selectRecords($b_db,'SELECT ID, ID_CAT, ID_RTF, DATE, LOG, AMOUNT, AFLAG, STICKY FROM '.Settings->VW_LOG);
+        $b_pst = Settings::selectRecords($b_db,'SELECT ID, ID_CAT, DATE, LOG, RTF, AMOUNT, AFLAG, STICKY FROM '.Settings->VW_LOG);
         while ( @br = $b_pst->fetchrow_array() ) {
-            my $pst = Settings::selectRecords($db,"SELECT DATE FROM ".Settings->VW_LOG." WHERE DATE='".$br[3]."';");
+            my $pst = Settings::selectRecords($db,"SELECT DATE FROM ".Settings->VW_LOG." WHERE DATE='".$br[2]."';");
             my @ext = $pst->fetchrow_array();
             if(scalar(@ext)==0){
                 $insLOG->execute($br[1],$br[2],$br[3],$br[4],$br[5],$br[6],$br[7]);
-                print "Added->".$br[0]."|".$br[3]."|".$br[4]."\n";
+                print "Added->".$br[0]."|".$br[2]."|".$br[3]."\n"; $stats->logs_inserts_incr();
+                if($br[5]){                    
+                    $pst = Settings::selectRecords($db, "SELECT max(id) FROM ".Settings->VW_LOG);
+                    my @r = $pst->fetchrow_array();
+                    $backupLIDS{$br[0]} = $r[0];
+                }
             }
-
         }
         print "\nFinished with merging LOG table.\n";
+        print "There where -> ". $stats->logs_inserts(). " inserts.\n";
 
-        print "\n\nMerging from backup NOTES table...\n";
-        my $insNOTES   = $db->prepare('INSERT INTO NOTES (LID, DOC) VALUES(?,?);')or die "Failed NOTESprepare.";
+        print "\nMerging from backup NOTES table...\n";
+        my $insNOTES   = $db->prepare('INSERT INTO NOTES (LID, DOC) VALUES(?,?);')or die "Failed NOTES prepare.";
         $b_pst = Settings::selectRecords($b_db,'SELECT LID, DOC FROM NOTES;');
         while ( @br = $b_pst->fetchrow_array() ) {
-            my $pst = Settings::selectRecords($db,"SELECT LID FROM NOTES WHERE LID=".$br[0].";");
-            my @ext = $pst->fetchrow_array();
-            if(@ext==0&&$br[0]&&$br[1]){
-                $insNOTES->execute($br[0], $br[1]) or die "Failed NOTES INSERT[".$br[0]."]";
-                print "Added NOTES->".$br[0]."\n";
+            my $in_id = $backupLIDS{$br[0]};
+            if($in_id){
+                my $pst = Settings::selectRecords($db,"SELECT LID FROM NOTES WHERE LID=".$br[0].";");
+                my @ext = $pst->fetchrow_array();                
+                if(@ext==0&&$br[1]){
+                   $insNOTES->execute($in_id, $br[1]) or die "Failed NOTES INSERT[".$br[0]."]";
+                    print "Added NOTES -> LID:".$br[0]."\n";
+                }
             }
-
         }
         print "\nFinished with merging NOTES table.\n";
-
-        $b_db->disconnect();
-        $db->disconnect();
+        print "Note that the merge didn't recover documents for any existing log entries.\n";
+        print "To do this, delete those log entries, then run restore again.\n";
         `rm -rf $dbck/`;
         print "Done!";
+        print "Restore ended: ".Settings::today(), "\n";
+};      print $stdout;
+
+        my $fh; open( $fh, ">>", Settings::logPath()."backup_restore.log");
+                print $fh $stdout;
+                close $fh;
+
+        $b_db->disconnect();
+        $db->disconnect();       
     }
     catch{
         $ERROR = "<font color='red'><b>Restore Failed!</b></font>hndl->$hndl $@ \n";
@@ -1260,22 +1409,22 @@ sub updateLOGDB {
     if(scalar(@fields)>6){
 
         my $i = 0;
-        my $id_cat = $fields[$i++];
-        my $id_rtf = $fields[$i++];
+        my $id_cat = $fields[$i++];        
         my $date   = $fields[$i++];
         my $log    = $fields[$i++];
+        my $rtf    = $fields[$i++];
         my $amv    = $fields[$i++];
         my $amf    = $fields[$i++];
         my $sticky = $fields[$i++];
         # Is it old pre. 1.8 format -> ID, DATE, LOG, AMOUNT, AFLAG, RTF, STICKY
-        if(!looks_like_number($id_rtf)){
+        if(!looks_like_number($rtf)){
             $i = 0;
             $id_cat = $fields[$i++];
-            $date   = $fields[$i++];
+            $rtf    = $fields[$i++];
+            $date   = $fields[$i++];            
             $log    = $fields[$i++];
             $amv    = $fields[$i++];
-            $amf    = $fields[$i++];
-            $id_rtf = $fields[$i++];
+            $amf    = $fields[$i++];            
             $sticky = $fields[$i++];
         }
         my $pdate = DateTime::Format::SQLite->parse_datetime($date);
@@ -1288,7 +1437,7 @@ sub updateLOGDB {
         my @rows = $dbs->fetchrow_array();
         if(scalar @rows == 0){
                     $dbs = $db->prepare('INSERT INTO LOG VALUES (?,?,?,?,?,?,?)');
-                    $dbs->execute($id_cat, $id_rtf, $pdate, $log, $amv, $amf, $sticky);
+                    $dbs->execute($id_cat, $pdate, $log, $rtf, $amv, $amf, $sticky);
         }
         $dbs->finish();
     }
@@ -1324,55 +1473,34 @@ sub error {
 }
 
 
-sub renumerate {
-    #Renumerate Log! Copy into temp. table.
-    my $sql;
-    $db->do("CREATE TABLE life_log_temp_table AS SELECT * FROM LOG;");
-    if(Settings::isProgressDB()){
-        $dbs = Settings::selectRecords($db, 'SELECT ID, DATE FROM LOG WHERE ID_RTF > 0 ORDER BY DATE;');
-    }else{
-        $dbs = Settings::selectRecords($db, 'SELECT rowid, DATE FROM LOG WHERE ID_RTF > 0 ORDER BY DATE;');
-    }
-    #update  notes with new log id
-    while(my @row = $dbs->fetchrow_array()) {
-        my $sql_date = $row[1];
-        if($sql_date){#could be an improperly deleted record in there? Skip if there is!
-                        #$sql_date =~ s/T/ /;
-                        $sql_date = DateTime::Format::SQLite->parse_datetime($sql_date);
-                         if(Settings::isProgressDB()){
-                            $sql = "SELECT ID, DATE FROM life_log_temp_table WHERE ID_RTF > 0 AND DATE = '".$sql_date."';";
-                         }else{
-                            $sql = "SELECT rowid, DATE FROM life_log_temp_table WHERE ID_RTF > 0 AND DATE = '".$sql_date."';";
-                         }
-                        $dbs = Settings::selectRecords($db, $sql);
-                        my @new  = $dbs->fetchrow_array();
-                        if(scalar @new > 0){
-                            $db->do("UPDATE NOTES SET LID =". $new[0]." WHERE LID==".$row[0].";");
-                        }
+    my %dates  = ();
+    #Hash is unreliable for returning sequential order of keys so array must do.
+    my @dlts = ();    
+    my $cntr_del =0;
+    my $existing;
+    my @row;
+
+        getHeader();
+        print "<body><pre>Started transaction!\n";
+
+        $db->do('BEGIN TRANSACTION;');
+        # Check for duplicates, which are possible during imports or migration as internal rowid is not primary in log.
+        # @TODO This should be done through an view?
+        if(Settings::isProgressDB()){
+            $dbs = Settings::selectRecords($db, 'SELECT ID, DATE FROM LOG ORDER BY DATE;');
+        }else{
+            $dbs = Settings::selectRecords($db, 'SELECT rowid, DATE FROM LOG ORDER BY DATE;');
+        }
+        while(@row = $dbs->fetchrow_array()) {
+            my $existing = $dates{$row[0]};
+            if($existing && $existing eq $row[1]){
+                $dlts[$cntr_del++] = $row[0];
+            }
+            else{
+                $dates{$row[0]} = $row[1];
+            }
         }
-    }
 
-    # Delete Orphaned Notes entries.
-    if(Settings::isProgressDB()){
-        $dbs = Settings::selectRecords($db, "SELECT LID, LOG.ID from NOTES LEFT JOIN LOG ON
-                                        NOTES.LID = LOG.ID WHERE LOG.ID is NULL;");
-    }else{
-    $dbs = Settings::selectRecords($db, "SELECT LID, LOG.rowid from NOTES LEFT JOIN LOG ON
-                                        NOTES.LID = LOG.rowid WHERE LOG.rowid is NULL;");
-    }
-    while(my @row = $dbs->fetchrow_array()) {
-        $db->do("DELETE FROM NOTES WHERE LID=$row[0];");
-    }
-    if(Settings::isProgressDB()){
-        $db->do('DROP TABLE LOG CASCADE;');
-    }
-    else{
-        $db->do('DROP TABLE LOG;');
-    }
-    $db->do(&Settings::createLOGStmt);
-    $db->do(q(INSERT INTO LOG (ID_CAT, ID_RTF, DATE, LOG, AMOUNT,AFLAG)
-                    SELECT ID_CAT, ID_RTF, DATE, LOG, AMOUNT, AFLAG FROM life_log_temp_table ORDER by DATE;));
-    $db->do('DROP TABLE life_log_temp_table;');
-}
+
 
 1;
\ No newline at end of file
index 67d740e6a6ab3479b2a4fa69326768409fecb2cc..f53aa0edbe5b1f375bfe740b3669484ab78809eb 100755 (executable)
@@ -19,14 +19,13 @@ require Settings;
 my $db        = Settings::fetchDBSettings();
 my $cgi       = Settings::cgi();
 my $dbname    = Settings::dbName();
-my $imgw      = 210;
-my $imgh      = 120;
 my $human     = DateTime::Format::Human::Duration->new();
 my $PRC_WIDTH = Settings::pagePrcWidth();
 my $DEBUG     = Settings::debug();
 my $today     =  Settings::today();
-my $tbl_rc =0;
-
+my $tbl_rc    = 0;
+my $imgw      = 210;
+my $imgh      = 120;
 my $opr = $cgi->param("opr");
 my $confirmed = $cgi->param('confirmed');
 if ($opr == 1){
@@ -182,7 +181,8 @@ try{
 
          my $tbl = '<a name="top"></a><form name="frm_log_del" action="data.cgi" onSubmit="return formDelValidation();">
            <table class="tbl_rem" width="'.$PRC_WIDTH.'%">
-           <tr class="hdr" style="text-align:left;"><th>Date <a href="#bottom">&#x21A1;</a></th> <th>Time</th> <th>Log</th> <th>Category</th></tr>';
+           <tr class="hdr" style="text-align:left;">
+               <th>Date <a href="#bottom">&#x21A1;</a></th> <th>Time</th> <th>Log</th> <th>Category <a href="#bottom">&#x21A1;</a></th></tr>';
 
 
         while(my @row = $st->fetchrow_array()) {
@@ -191,12 +191,13 @@ try{
             my $dt = DateTime::Format::SQLite->parse_datetime( $row[3] );
             my $log = log2html($row[4]);
 
-            $tbl = $tbl . '<tr class="r1"><td class="'.$rs.'">'. $dt->ymd . "</td>" .
+            $tbl .= '<tr class="r1"><td class="'.$rs.'">'. $dt->ymd . "</td>" .
                 '<td class="'.$rs.'">' . $dt->hms . "</td>" .
-                '<td class="'.$rs.'" style="font-weight:bold; color:maroon;">'."$log</td>\n".
+                '<td class="'.$rs.'" style="font-weight:bold; color:maroon;">
+                    <div class="log" style="overflow-x:none; max-width:600">'."$log</div></td>\n".
                 '<td class="'.$rs.'">' . $ct. '<input type="hidden" name="chk" value="'.$row[0].'"></td></tr>';
             if($rs eq "r1"){
-            $rs = "r0";
+               $rs = "r0";
             }
             else{
                 $rs = "r1";
@@ -218,7 +219,7 @@ try{
         </td></tr>
         </table><input type="hidden" name="confirmed" value="1"></form>';
 
-        print "<center><div>\n$tbl\n</div></center>";
+        print "<center><div style='background-color:".&Settings::bgcol."'>\n$tbl\n</div></center>";
 
         print $cgi->end_html();
     } 
index 8260d226cfa8ec844fb6b7393fa8dc210e88f260..2c1c2dd9e2f5a61954305903022ffe71970be9dd 100755 (executable)
@@ -23,6 +23,8 @@ use Regexp::Common qw /URI/;
 use JSON;
 use IO::Compress::Gzip qw(gzip $GzipError);
 use Compress::Zlib;
+use Crypt::Blowfish;
+use Crypt::CBC;
 
 use lib "system/modules";
 require Settings;
@@ -88,57 +90,67 @@ sub defaultJSON {
    });
 }
 
+sub cryptKey {
+    $passw    = $alias.$passw.Settings->CIPHER_KEY;
+    $passw    =~ s/(.)/sprintf '%04x', ord $1/seg;        
+   return  substr $passw.Settings->CIPHER_PADDING, 0, 58;
+}
+
 sub processSubmit {
 
      # my $date = $cgi->param('date');
-     my $st;
+     my ($st, @arr);
 
     try {
         if($action eq 'store'){
 
-           $doc = qq({
-                        "lid":"$lid",
-                        "bg":"$bg",
-                        "doc":$doc
-                 });
-           my $zip = compress($doc, Z_BEST_COMPRESSION);
-              $st = $db->prepare("SELECT LID FROM NOTES WHERE LID = $lid;");
-              $st -> execute();
-           if($st->fetchrow_array() eq undef) {
-               $st = $db->prepare("INSERT INTO NOTES(LID, DOC) VALUES (?, ?);");
-               $st->execute($lid, $zip);
-               $response = "Stored Document (id:$lid)!";
+           my $cipher = Crypt::CBC->new(-key  => cryptKey(), -cipher => 'Blowfish');
+              $doc = qq({
+                                "lid": "$lid",
+                                "bg":  "$bg",
+                                "doc": $doc
+              });           
+        
+           my  $zip = compress($cipher->encrypt($doc), Z_BEST_COMPRESSION); 
+               @arr = Settings::selectRecords($db, "SELECT LID FROM NOTES WHERE LID = $lid;")->fetchrow_array();
+           if (!@arr) {
+                        $st = $db->prepare("INSERT INTO NOTES(LID, DOC) VALUES (?, ?);");
+                        $st->execute($lid, $zip);
+                        $response = "Stored Document (id:$lid)!";
            }
            else{
-               $st = $db->prepare("UPDATE NOTES SET DOC = ? WHERE LID = $lid;");
-               $st->execute($zip);
-               $response = "Updated Document (id:$lid)!";
+                        $st = $db->prepare("UPDATE NOTES SET DOC = ? WHERE LID = $lid;");
+                        $st->execute($zip);
+                        $response = "Updated Document (id:$lid)!";
            }
            
         }
         elsif($action eq 'load'){
-           $st = $db->prepare("SELECT DOC FROM NOTES WHERE LID = $lid;");
-           $st -> execute();
-           my @arr = $st->fetchrow_array();
+              @arr = Settings::selectRecords($db, "SELECT DOC FROM NOTES WHERE LID = $lid;")->fetchrow_array();
            if(@arr eq undef){
-               $st = $db->prepare("SELECT DOC FROM NOTES WHERE LID = '0';");
-               $st -> execute();
-               @arr = $st->fetchrow_array();
+              @arr = Settings::selectRecords($db,"SELECT DOC FROM NOTES WHERE LID = '0';")->fetchrow_array();
            }
+            my $cipher = Crypt::CBC->new(-key  => cryptKey(), -cipher => 'Blowfish');
            $doc = $arr[0];
-           $doc = uncompress($doc);
-        #    print $cgi->header( -expires => "+0s", -charset => "UTF-8" );
-        #    print($doc);
-        #    exit;
+           my $d = uncompress($doc);
+           $doc = $cipher->decrypt($d);
+            # print $cgi->header( -expires => "+0s", -charset => "UTF-8" );
+            # print($doc);
+            # exit;
            $response = "Loaded Document!";
 
         }
-        else{
+        else{            
             $error = "Your action ($action) sux's a lot!";
         }
 
     }catch {
-        $error = ":LID[$lid]-> ".$_;
+        if($action eq 'load' && $@ =~ /Ciphertext does not begin with a valid header for 'salt'/){# Maybe an pre v.2.2 old document?
+            $doc = uncompress($doc);
+            $response = "Your document LID[$lid] is not secure. Please resave it.";
+            return;
+        }
+        $error = "Error on:LID[$lid]-> ".$@;
     }
 }
 
index f30b72e549488f9b3f074bc9a60a1979e9f5962e..90717ab2b4e73208ec35591fb79394bd501c2583 100755 (executable)
@@ -237,6 +237,7 @@ try{
     # We live check database for available tables now only once.
     # If brand new database, this sill returns fine an empty array.
     my %curr_tables = ();
+    #my %curr_colums = (); # %("table", @{...columns...})
 
     if(Settings::isProgressDB()){        
         $changed = checkPreparePGDB();
@@ -292,6 +293,13 @@ try{
            }
         }catch{$@.="\n$sup"; die "Failed[$@]"}
     }
+    #Is it pre or around v.2.1, where ID_RTF is instead of RTF in the LOG table?
+    if($hasLogTbl && !Settings::isProgressDB()){ 
+        $pst = Settings::selectRecords($db, "SELECT * from pragma_table_info('LOG') where name like 'ID_RTF'");        
+        if($pst->fetchrow_array()){
+            $db->do("ALTER TABLE LOG RENAME COLUMN ID_RTF TO RTF");
+        }
+    }
     #
     # From v.1.8 Log has changed, to have LOG to NOTES relation.
     #
@@ -345,7 +353,7 @@ try{
             foreach my $date (keys %notes_ids){
                 #next if(ref($notes_ids{$date}) eq 'HASH');
                 my $nid = $notes_ids{$date};
-                my $stmt= "UPDATE LOG SET ID_RTF =". $nid." WHERE DATE == '".$date."';";
+                my $stmt= "UPDATE LOG SET RTF =". $nid." WHERE DATE == '".$date."';";
                 try{
                     $db->do($stmt);
                 }
index cbd6926cb07b52678c59bc7c8dd205edeff6a0d5..e59d6bf6e6b93e9dc58728c10ef3859d29cd7524 100755 (executable)
@@ -63,7 +63,7 @@ if(Settings::anon('^PAGE_EXCLUDES')){
     }
 }
 
-my $sqlView     = 'SELECT ID, ID_CAT, ID_RTF, DATE, LOG, AMOUNT, AFLAG, STICKY, PID FROM '.$VW_PAGE;#Only to be found here, the main SQL select statement.
+my $sqlView     = 'SELECT ID, ID_CAT, DATE, LOG, RTF, AMOUNT, AFLAG, STICKY, PID FROM '.$VW_PAGE;#Only to be found here, the main SQL select statement.
 my $stmS        = $sqlView." WHERE";
 my $stmE        = ' LIMIT '.&Settings::viewAllLimit.';';
 my $stmD        = "";
@@ -264,7 +264,7 @@ qq(<FORM id="frm_log" action="data.cgi" onSubmit="return formDelValidation();">
 </tr>);
     #We use js+perl, trickery to filter by amount type, as well.
     if($prm_aa >0){my $s = $prm_aa - 1;$prm_aa = " AFLAG=$s AND";}else{$prm_aa=""}
-    if($prm_rtf){$stmS .= " ID_RTF>0 AND";}
+    if($prm_rtf){$stmS .= " RTF>0 AND";}
 
     if($isPUBViewMode){
         $sqlVWL = $stmS." ".Settings::sqlPubors().$stmE;
@@ -431,10 +431,10 @@ sub buildLog {
         my $i = 0;
         $id = $row[$i++]; #ID must be rowid in LOG.
         my $cid = $row[$i++]; #CID ID_CAT not used.
-        my $ct  = $hshCats{$cid}; #ID_CAT
-        my $rtf = $row[$i++];           #ID_RTF since v.1.8
+        my $ct  = $hshCats{$cid}; #ID_CAT        
         my $dt  = DateTime::Format::SQLite->parse_datetime( $row[$i++] ); #LOG.DATE
         my $log = $row[$i++]; #LOG.LOG
+        my $rtf = $row[$i++];     #ID_RTF since v.1.8 but just RTF from v.2.1
         my $am  = $row[$i++]; #LOG.AMOUNT
         my $af  = $row[$i++]; #AFLAG -> Asset as 0, Income as 1, Expense as 2
         my $sticky = $row[$i++]; #Sticky to top
@@ -1088,10 +1088,9 @@ try {
 #Apostroph's need to be replaced with doubles  and white space to be fixed for the SQL.
             $log =~ s/'/''/g;
 
-            if ( $edit_mode && $edit_mode != "0" ) {
-                #Update
+            if ( $edit_mode && $edit_mode != "0" ) {                
                 $date = DateTime::Format::SQLite->parse_datetime($date); $date =~ s/T/ /g;
-                $stm = qq(UPDATE LOG SET ID_CAT='$cat', ID_RTF='$rtf',
+                $stm = qq(UPDATE LOG SET ID_CAT='$cat', RTF='$rtf',
                                          DATE='$date',
                                          LOG='$log',
                                          AMOUNT=$am,
@@ -1099,9 +1098,8 @@ try {
                                          STICKY=$sticky WHERE $SQLID=$edit_mode;);
                 #
                 toBuf $stm if $DEBUG;
-                #
-
-                my $dbUpd = Settings::connectDB($alias, $passw);#@  or LifeLogException->throw("Execute failed [$DBI::errstri]");
+                #             
+                
                 traceDBExe($stm);
                 return;
             }
@@ -1159,7 +1157,7 @@ try {
                 }
                 if ($dtCur > $dt){$sticky = 1; toBuf $cgi->p("<b>Insert forced to be sticky, it is in the past!</b>");}
                 $sticky=castToBool($sticky);
-                $stm = qq(INSERT INTO LOG (ID_CAT, ID_RTF, DATE, LOG, AMOUNT, AFLAG, STICKY) VALUES ($cat,$rtf,'$date','$log',$am,$af,$sticky););
+                $stm = qq(INSERT INTO LOG (ID_CAT, DATE, LOG, RTF, AMOUNT, AFLAG, STICKY) VALUES ($cat,'$date','$log',$rtf, $am,$af,$sticky););
                 $st = traceDBExe($stm);
                 if($sssCDB){
                     #Allow further new database creation, it is not an login infinite db creation attack.
index 1832dd26b45c67257da4f7e84df6989f29656e5d..43461a2a3333cf0a89cea8b96ba1563fafc4c021 100644 (file)
@@ -8,7 +8,7 @@ package Settings;
 use v5.10;
 use strict;
 use warnings;
-use Exception::Class ('SettingsException','LifeLogException');
+use Exception::Class ('SettingsException','LifeLogException','SettingsLimitSizeException');
 use Syntax::Keyword::Try;
 use CGI;
 use CGI::Session '-ip_match';
@@ -20,8 +20,9 @@ use DateTime::Duration;
 use DBI;
 use experimental qw( switch );
 
-#This is the default developer release key, replace on istallation. As it is not secure.
+# This is the default developer release key, replace on istallation. As it is not secure.
 use constant CIPHER_KEY             => '95d7a85ba891da';
+use constant CIPHER_PADDING         => 'fe0a2b6a83e81f13a2d76ab104763773310df6b0a01c7cf9807b4b0ce2a02';
 # Default VIEW for all pages.
 use constant VW_LOG                 => 'VW_LOG';
 # Optional instructional VIEW from config file replacing above default.
@@ -191,7 +192,7 @@ sub setTimezone {
                 }
             }
             my $try = $tz_map{$TIME_ZONE};
-               $try = $tz_map{$to} if(!$try);
+               $try = $tz_map{$to} if(!$try && $to);
             if($try){
                 $TIME_ZONE = $try; #translated to mapped lib. provided zone.
                 $ret -> set_time_zone($try);
@@ -249,29 +250,30 @@ return qq(
     );
     CREATE INDEX idx_cat_name ON CAT (NAME);
 )}
-sub createLOGStmt {
-if($IS_PG_DB){
+sub createLOGStmt { 
+#ID_RTF in v.2.0 and lower is not an id, changed to byte from v.2.1.
+if($IS_PG_DB){ 
         return qq(
         CREATE TABLE LOG (
             ID INT UNIQUE GENERATED ALWAYS AS IDENTITY,
-            ID_CAT INT        NOT NULL,
-            ID_RTF INTEGER    DEFAULT 0,
+            ID_CAT INT        NOT NULL,            
             DATE TIMESTAMP    NOT NULL,
             LOG VARCHAR ($DBI_LVAR_SZ) NOT NULL,
+            RTF    BOOL       DEFAULT 0,
             AMOUNT money,
-            AFLAG  INT         DEFAULT 0,
+            AFLAG  INT        DEFAULT 0,
             STICKY BOOL       DEFAULT FALSE,
             PRIMARY KEY(ID)
         );)} 
 
   return qq(
     CREATE TABLE LOG (
-        ID_CAT INT        NOT NULL,
-        ID_RTF INTEGER    DEFAULT 0,
+        ID_CAT INT        NOT NULL,        
         DATE DATETIME     NOT NULL,
         LOG VARCHAR ($DBI_LVAR_SZ) NOT NULL,
+        RTF    BYTE       DEFAULT 0,
         AMOUNT DOUBLE,
-        AFLAG  INT         DEFAULT 0,
+        AFLAG  INT        DEFAULT 0,
         STICKY BOOL       DEFAULT 0
     );
 )}
@@ -461,12 +463,12 @@ sub renumerate {
     selectRecords($db,'CREATE TABLE life_log_temp_table AS SELECT * FROM LOG;');
     my $CI = 'rowid'; $CI = 'ID' if $IS_PG_DB;
     #update  notes table with new log id only for reference sake.
-    my $st = selectRecords($db, "SELECT $CI, DATE FROM LOG WHERE ID_RTF > 0 ORDER BY DATE;");
+    my $st = selectRecords($db, "SELECT $CI, DATE FROM LOG WHERE RTF > 0 ORDER BY DATE;");
     while(my @row =$st->fetchrow_array()) {
         my $sql_date = $row[1];
         #$sql_date =~ s/T/ /;
         $sql_date = DateTime::Format::SQLite->parse_datetime($sql_date);
-        $sql = "SELECT $CI, DATE FROM life_log_temp_table WHERE ID_RTF > 0 AND DATE = '".$sql_date."';";
+        $sql = "SELECT $CI, DATE FROM life_log_temp_table WHERE RTF > 0 AND DATE = '".$sql_date."';";
         my @new  = selectRecords($db, $sql)->fetchrow_array();
         if(scalar @new > 0){
              try{#can fail here, for various reasons.
@@ -489,23 +491,23 @@ sub renumerate {
     if($IS_PG_DB){$db->do('DROP TABLE LOG CASCADE;');}else{$db->do('DROP TABLE LOG;');}
     
     $db->do(&createLOGStmt);
-    $db->do('INSERT INTO LOG (ID_CAT, ID_RTF, DATE, LOG, AMOUNT,AFLAG,STICKY)
-                       SELECT ID_CAT, ID_RTF, DATE, LOG, AMOUNT, AFLAG, STICKY FROM life_log_temp_table ORDER by DATE;');    
+    $db->do('INSERT INTO LOG (ID_CAT, DATE, LOG, RTF ,AMOUNT, AFLAG, STICKY)
+                       SELECT ID_CAT, DATE, LOG, RTF, AMOUNT, AFLAG, STICKY FROM life_log_temp_table ORDER by DATE;');    
     $db->do('DROP TABLE life_log_temp_table;');
 }
 
 sub selectRecords {
     my ($db, $sql) = @_;
     if(scalar(@_) < 2){
-                SettingsException->throw("ERROR Argument number is wrong->db is:$db\n", show_trace=>$DEBUG);
+         die  "Wrong number of arguments, expecting Settings::selectRecords(\$db, \$sql) got Settings::selectRecords('@_').\n";
     }
     try{
-                my $pst        = $db->prepare($sql);
-                $pst->execute();
-                return 0 if(!$pst);
-                return $pst;
+        my $pst        = $db->prepare($sql);                
+        return 0 if(!$pst);
+        $pst->execute();
+        return $pst;
     }catch{
-                SettingsException->throw(error=>"Database error encountered!\n ERROR->".$@." SQL-> $sql DSN:".$DSN, show_trace=>$DEBUG);
+                SettingsException->throw(error=>"Database error encountered!\n ERROR->$@\n SQL-> $sql DSN:".$DSN, show_trace=>$DEBUG);
     };
 }
 
index 73abe977334e4cfe1c7d581511174004998da37f..39d2f45fb216cdf723db403406ea705cf9f76121 100755 (executable)
@@ -15,12 +15,30 @@ use lib $ENV{'PWD'}.'/htdocs/cgi-bin/system/modules';
 require CNFParser;
 
 
+my @set = ('0' ..'9', 'A' .. 'F');
+#@my $str = join '' => map $set[rand @set], 1 .. 56;
+#print join '' => map $set[rand @set], 1 .. 56, "\n\n";
+
+
+print cryptKey('admin','admin'), "\n";
+
+
+#B6B829430583F8C03EBEFB1677232194EEC8D211609226EC516F7BB4B
+sub cryptKey {
+    my $admin = shift;
+    my $passw = shift;
+    $passw    = $admin.$passw.Settings->CIPHER_KEY;
+    $passw    =~ s/(.)/sprintf '%04x', ord $1/seg;        
+   return  substr $passw.Settings->CIPHER_PADDING, 0, 58;
+}
+
+
 # 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 =~ /<<TIME_ZONE_MAP</){
-#             $TIME_ZONE_MAP = substr($line,16);
+#             $TIME_ZONE_MAP = substr($line,16);prin
 #                 while ($line = <$fh>) {
 #                     chomp $line;
 #                     last if($line =~ />$/);
@@ -74,76 +92,76 @@ require CNFParser;
     #     $where =~ s/\s+AND$//;
     #     return Settings::createViewLOGStmt(VW_LOG_WITH_EXCLUDES,$where);
     # }
-my $server = 'DBI:Pg:host=elite;name=android';
-
-my $v1 = $server =~ qr/:/;
-my $v2 = $`;
-my $v3 = $' =~ qr/:/;
-# $var=1
-# $`=DBI
-# $&=:
-# $'=Pg:host=elite;name=androi
-print $v2.'->'.$`,"\n";
-$v1 ="";
-
-print "[$v1]->".timeFormatValue($v1),"\n";
-$v1 ="1";
-print "[$v1]->".timeFormatValue($v1),"\n";
-$v1 ="+1m";
-print "[$v1]->".timeFormatValue($v1),"\n";
-$v1 ="+10minutes";
-print "[$v1]->".timeFormatValue($v1),"\n";
-#default
-$v1 ="+30m";
-print "[$v1]->".timeFormatValue($v1),"\n";
-
-#Let's try sneak in garbage.
-$v1 ="+20bitcons";
-print "[$v1]->".timeFormatValue($v1),"\n";
-$v1 ="+20hitcons";
-print "[$v1]->".timeFormatValue($v1),"\n";
-$v1 ="+30hr";
-print "[$v1]->".timeFormatValue($v1),"\n";
-$v1 ="+1hr";
-print "[$v1]->".timeFormatValue($v1),"\n";
-$v1 ="+8.2severe";
-print "[$v1]->".timeFormatValue($v1),"\n";
-$v1 ="+8severe";
-print "[$v1]->".timeFormatValue($v1),"\n";
-$v1 ="+2severe";
-print "[$v1]->".timeFormatValue($v1),"\n";
-$v1 ="+120severe";
-print "[$v1]->".timeFormatValue($v1),"\n";
-$v1 ="+119severe";
-print "[$v1]->".timeFormatValue($v1),"\n";
-$v1 ="+121severe";
-print "[$v1]->".timeFormatValue($v1),"\n";
-$v1 ="+280severe";
-print "[$v1]->".timeFormatValue($v1),"\n";
-$v1 ="+120";
-print "[$v1]->".timeFormatValue($v1),"\n";
-
-
-sub timeFormatValue {
-    my $v = shift;
-    my $ret = "+2m";
-    if(!$v){$v=$ret}    
-    if($v !~ /^\+/){$v='+'.$v.'m'}# Must be positive added time
-    # Find first match in whatever passed.
-    my @a = $v =~ m/(\+\d+[shm])/gis;    
-    if(scalar(@a)>0){$v=$a[0]}
-    # Test acceptable setting, which is any number from 2, having any s,m or h. 
-    if($v =~ m/(\+[2-9]\d*[smh])|(\+[1-9]+\d+[smh])/){
-        # Next is actually, the dry booger in the nose. Let's pick it out!
-        # Someone might try to set in seconds value to be under two minutes.
-        @a = $v =~ m/(\d[2-9]\d+)/gs;        
-        if(scalar(@a)>0 && int($a[0])<120){return $ret}else{return $v}
-    }
-    elsif($v =~ m/\+\d+/){# is passedstill without time unit? Minutetise!
-        $ret=$v."m"
-    }
-    return $ret;
-}
+my $server = 'DBI:Pg:host=elite;name=android';
+
+my $v1 = $server =~ qr/:/;
+my $v2 = $`;
+my $v3 = $' =~ qr/:/;
+# $var=1
+# $`=DBI
+# $&=:
+# $'=Pg:host=elite;name=androi
+print $v2.'->'.$`,"\n";
+$v1 ="";
+
+print "[$v1]->".timeFormatValue($v1),"\n";
+$v1 ="1";
+print "[$v1]->".timeFormatValue($v1),"\n";
+$v1 ="+1m";
+print "[$v1]->".timeFormatValue($v1),"\n";
+$v1 ="+10minutes";
+print "[$v1]->".timeFormatValue($v1),"\n";
+# #default
+$v1 ="+30m";
+print "[$v1]->".timeFormatValue($v1),"\n";
+
+# #Let's try sneak in garbage.
+$v1 ="+20bitcons";
+print "[$v1]->".timeFormatValue($v1),"\n";
+$v1 ="+20hitcons";
+print "[$v1]->".timeFormatValue($v1),"\n";
+$v1 ="+30hr";
+print "[$v1]->".timeFormatValue($v1),"\n";
+$v1 ="+1hr";
+print "[$v1]->".timeFormatValue($v1),"\n";
+$v1 ="+8.2severe";
+print "[$v1]->".timeFormatValue($v1),"\n";
+$v1 ="+8severe";
+print "[$v1]->".timeFormatValue($v1),"\n";
+$v1 ="+2severe";
+print "[$v1]->".timeFormatValue($v1),"\n";
+$v1 ="+120severe";
+print "[$v1]->".timeFormatValue($v1),"\n";
+$v1 ="+119severe";
+print "[$v1]->".timeFormatValue($v1),"\n";
+$v1 ="+121severe";
+print "[$v1]->".timeFormatValue($v1),"\n";
+$v1 ="+280severe";
+print "[$v1]->".timeFormatValue($v1),"\n";
+$v1 ="+120";
+print "[$v1]->".timeFormatValue($v1),"\n";
+
+
+sub timeFormatValue {
+    my $v = shift;
+    my $ret = "+2m";
+    if(!$v){$v=$ret}    
+    if($v !~ /^\+/){$v='+'.$v.'m'}# Must be positive added time
+    # Find first match in whatever passed.
+    my @a = $v =~ m/(\+\d+[shm])/gis;    
+    if(scalar(@a)>0){$v=$a[0]}
+    # Test acceptable setting, which is any number from 2, having any s,m or h. 
+    if($v =~ m/(\+[2-9]\d*[smh])|(\+[1-9]+\d+[smh])/){
+        # Next is actually, the dry booger in the nose. Let's pick it out!
+        # Someone might try to set in seconds value to be under two minutes.
+        @a = $v =~ m/(\d[2-9]\d+)/gs;        
+        if(scalar(@a)>0 && int($a[0])<120){return $ret}else{return $v}
+    }
+    elsif($v =~ m/\+\d+/){# is passedstill without time unit? Minutetise!
+        $ret=$v."m"
+    }
+    return $ret;
+}
 
 # my @AUTOWORDS = ("searchificould","itworks","funeral","gasbottle","electricitybill","ctwodaysinrow","carrego","cartwonewtires","flashlightout","test","check","tmshsample","new");
 
@@ -155,4 +173,10 @@ sub timeFormatValue {
 # }
 # print "\n";
 
+
+
+
+
+
+
 1;
\ No newline at end of file
index ef7b1f5a559a66a277883196b4ff999d9f1479f8..8fa1ae54fea617452c7b696110f39630dd2ff022 100644 (file)
@@ -1126,6 +1126,7 @@ function loadRTFResult(content, result, prms, quill) {
         var css = $("#q-scroll"+id).prop('style');
         if(css){css.backgroundColor = json.content.bg}
     }
+    display(json.response, 5);
     //alert(obj.response);
 }