]> lifelog.hopto.org Git - LifeLog.git/commitdiff
Developed further.
authorwbudic <redacted>
Thu, 11 Feb 2021 01:15:21 +0000 (12:15 +1100)
committerwbudic <redacted>
Thu, 11 Feb 2021 01:15:21 +0000 (12:15 +1100)
log.pl

diff --git a/log.pl b/log.pl
index fd27f2a76bc7a9cd9a64e49d7b3d0476868e0ab4..8024eab81148fc489989da857b79ded43ce33d32 100755 (executable)
--- a/log.pl
+++ b/log.pl
@@ -11,12 +11,13 @@ use feature 'switch';
 
 use warnings;
 use strict;
-no warnings 'portable';
+no warnings ('portable', 'once');
 
 use lib $ENV{'PWD'}.'/htdocs/cgi-bin/system/modules';
 
 require CNFParser;
 require Settings;
+$CGI::Carp::WRAP = 0;     
 
 use Exception::Class ('LifeLogException');
 use DBI;
@@ -25,52 +26,132 @@ use IO::Prompter [ -stdio, -style=>'bold' ];
 
 my $cnf = CNFParser->new('dbLifeLog/main.cnf');
 
+my $TITLE = "LifeLog Command Line Access Utility (".Settings::release().")";
+my $LIMIT = 100; 
+my $LIMIT_REC = Settings::viewAllLimit();
+my ($VW_NAME,$COL_NAME,$COL_TYPE, $SELECT, $INSERT);
 
 my $help = qq(
+$TITLE\n
+Syntax: $0 {-option} {value}...{-dump}={file.log} | {-dump} {dump.log}\n
+Options:
+-alias      - (Optional) alias for login into database.
+-database   - Database name (usually same as the alias).
+-system     - Use login free, system database, via <<AUTO_LOGIN</> which in main.inf must be set.
+            - Options -database and -alias are ignored if this flag is set.
+-sys_table  - Create/Use sys table, for the logs. Format: -sys_table=table_name:col_name:sql_type.
+            - i.e. -sys_table=BITCOIN:VALUE:NUMBER  or -sys_table=MESSAGES:MSG:TEXT
+            - The -system option, all previous mentioned, don't need to be set as this overrides and implies when this option is set.
+       -db_src - (Optional) Driver source, defaults to <<DBI_SOURCE<DBI:SQLite:> set in main.cnf.
+       -list       - List by category entries we are not logging. Next argument can be a single or list of catecory id's.
+                   - i.e. -list '1:6:9' or just -list to list all categories up to 10.
+       -cat_id     - (Optional) New log entry category id. Will be prompted for if not provided.
+       -log        - (Optional) Log message or text to be logged is next argument. Default is SDTIN piped in.
+       Limitations:
+           Currently date based entries are not possible to be added, and it is not recomended to use this utility for batch processing. 
+           To access any LifeLog based database, password has to be entered in the terminal. Can be bypassed with -system option flag.
+           There is a limit to log message size to $LIMIT_REC characters (can't be changed).
+           There is a limit of data presented and dumped to a \$LIMIT=$LIMIT of entries (modify in $0 to \$LIMIT=\"\"; if you want unlimited).
+           Data dumps are only by category from the latest entry as returned by the view of VW_LOG.
+    Examples:
+    ./log.pl -db_src "DBI:Pg:host=localhost;" -database lifelog -sys_table=BITCOIN:VALUE:INTEGER
 
-Syntax: $0 {_} {-vim_option}... {ext_name}...
+    echo 789 | ./log.pl -inbuilt
+
+    uvar -r LAST_MONITOR_READING | ./log.pl -system -sys_table REMOTE_MONITOR:LOG:VARCHAR(1024)
+
+    ./log.pl -database lifelog -list 01:2:3
 
 );
 
-my ($database, $alias, $db_source, $set, $cat_id, $log) = 0;
-my ($IS_PG_DB, $DSN, $DBFILE);
-my $LOG_PATH = "dbLifeLog/";
-
-my $io;
-if (!is_interactive) { 
-   #die "Input from terminal (pipe) not allowed!\n" 
-   busy {
-       $log = readline STDIN;
-       say $log;
-       open STDIN, "<", "/dev/tty" or die "IO Error @_";
-   } 
-}
+       my ($database, $alias, $passw, $db_source, $set, $table, $cat_id,$list,$log, $dump, $out) = 0;
+       my ($IS_PG_DB, $DSN, $DBFILE);
+       my $LOG_PATH = "dbLifeLog/";
+
+       my $io;
+       if (!is_interactive) { 
+          #die "Input from terminal (pipe) not allowed!\n" 
+          busy {
+              $log = readline STDIN;          
+              open STDIN, "<", "/dev/tty" or die "IO Error @_";
+          } 
+       }
 
-foreach my $arg(@ARGV){
-    #print "{{{$arg}}}"; 
-    if($arg =~ /^\-/){
-        if($arg=~/(^\-*\?)/){print $help; exit;  
-        }elsif($arg=~/(^\-*database)/){$set=1;}
-        elsif($arg=~/(^\-*alias)/){$set=2;}
-        elsif($arg=~/(^\-*db_src)/){$set=3;}
-        elsif($arg=~/(^\-*c.*)/){$set=4;}
-        elsif($arg=~/(^\-*log)/){$set=5;}
-    }elsif($arg ne $ENV{'HOME'}){           
-        if($arg=~/^\w+\./){
-            print "Ignoring -> $arg\n"; 
-            next;
+       foreach my $arg(@ARGV){
+           #print "{{{$arg}}}"; 
+           if($arg =~ /^\-/){
+                if   ($arg=~/(^\-*\?)/){print $help; exit}  
+                elsif($arg=~/(^\-*database)/){$set=1;}
+                elsif($arg=~/(^\-*alias)/){$set=2;}
+                elsif($arg=~/(^\-*db_src)/){$set=3;}
+                elsif($arg=~/(^\-*c.*)/){$set=4;}
+                elsif($arg=~/(^\-*log)/){$set=5;}
+                elsif($arg=~/(^\-*list)/){$set=6;$list=-1}
+                elsif($arg=~/(^\-*dump)/){
+                    foreach(split /=/, $arg){
+                      $dump = $_; 
+                      if($dump =~ m/^~\//) {
+                                   $dump =~ s/~/$ENV{'HOME'}/
+                      }
+                    }
+                    if($dump && $dump !~ /(^\-*dump)/){$out = "You have set log output file to -> $dump\n"}else{$set=7}
+                }
+                elsif($arg=~/(^\-*system)/){$set = 8; $passw = $database}
+                elsif($arg=~/(^\-*sys_table)/){$set = 9; foreach(split /=/, $arg){$table = $_;}
+                    if($table && $table =~ /(^\-*sys_table)/){$table = undef}
+                }
+                elsif($arg=~/(^\-*inbuilt)/){
+                    # Use Inbuild here and configurate here in perl script. Why not?
+                    # Tip - Setup main.inf and login with bellow creadentials, to create lifelog database.
+                    $db_source = "DBI:Pg:host=localhost;";
+                    $database  = "lifelog";
+                    $alias     = "lifelog";
+                    $passw     = "lifelog";
+                    $table     = "BITCOIN:VALUE:INTEGER";
+                }
+           }elsif($arg ne $ENV{'HOME'}){          
+
+                if($arg=~/^\w+\./){
+                    print "Ignoring -> $arg\n"; 
+                    next;
+                }
+                next if ! $set;
+                if   ($set == 1){undef $set; $database = $arg}
+                elsif($set == 2){undef $set; $alias = $arg}
+                elsif($set == 3){undef $set; $db_source = $arg}
+                elsif($set == 4){undef $set; $cat_id = $arg}
+                elsif($set == 5){undef $set; $log = $arg}
+                elsif($set == 6){undef $set; $list="";
+                    foreach(split /:/, $arg){$list .= "ID_CAT=$_ OR ";}
+                    if($list =~ m/ OR $/){$list =~ s/ OR $//;}else{$list.="ID_CAT=".$arg}
+                }
+                elsif($set == 7){undef $set; $dump = $arg}
+                elsif($set == 9){undef $set; $table = $arg if (!$table)}
+        }else{
+            print "<<<<<$arg>>>>\n"
         }
-        if   ($set == 1)   { undef $set; $database = $arg }
-        elsif($set == 2){ undef $set; $alias = $arg }
-        elsif($set == 3){ undef $set; $db_source = $arg }
-        elsif($set == 4){ undef $set; $cat_id = $arg }
-        elsif($set == 5){ undef $set; $log = $arg }
+       }#rof
+
+if($set && $set > 7 && !$db_source){
+    my $prp = $cnf->anons('AUTO_LOGIN', undef);
+    my @a = split('/', $prp);
+    if(@a==2){
+        $alias=$database=$a[0]; $passw=$a[1];
+    }else{
+        say "Error: Autonom property not set AUTO_LOGIN<".$prp."> in main.inf to operate system table -> $table."; exit 0;
+    }          
+    undef $set;
+}
+
+if($list){
+    if($list eq -1){
+       if($cat_id){$list = $cat_id}else{$list="<11"}
     }
+    $cat_id = $list;
 }
 
 if(!$database && !$alias){
-$database="admin";
-    #say "Error: Database -database or -alias option not set!";  exit 0;
+    say "Error: Database -database or -alias option not set!";  exit 0;
 }
 if(!$alias){$alias=$database}
 if(!$db_source){
@@ -82,25 +163,25 @@ $IS_PG_DB = 1 if(index (uc $db_source, 'DBI:PG') ==0);
 
 
 
-my $passw = prompt "Enter The Password ($database): ", -echo => '*';
-$passw = uc crypt $passw, hex Settings->CIPHER_KEY if $passw;
-
-# system ("stty -echo");  
-# my $password = <STDIN>;  
-# system ("stty echo");
+if(!$passw){$passw = prompt "\n$TITLE\nPlease enter password for database -> $database: ", -echo => '*'};
+$passw = uc crypt $passw, hex Settings->CIPHER_KEY if $passw && !$IS_PG_DB;
 
+       say "WARNING! Argument type $set, has not been provided!" if($set);
+  
 my $db = connectDB($database,$alias,$passw);
 my $st = traceDBExe("SELECT alias FROM AUTH WHERE alias='$alias' and passw='$passw';");
 my @c = $st->fetchrow_array();
 if (@c && $c[0] eq $alias) {
-    if(!$cat_id){
-        $cat_id = $cnf->anons('CAT', undef);
-        $cat_id =~ s/^.*>\n//;
-        say $cat_id;
-        $cat_id = prompt "Enter Category id (default is '01' for Unspecified): ";
-        $cat_id = '01' if ($cat_id eq ""); 
+    if($table){checkCreateTable()}
+    elsif(!$cat_id){
+            $cat_id = $cnf->anons('CAT', undef);
+            $cat_id =~ s/^.*>\n//;
+            say "Sample Categories:\n$cat_id";
+            $cat_id = prompt "Enter Category id (default is '01' for Unspecified): ";
+            $cat_id = '01' if ($cat_id eq ""); 
     }
-    if(!$log){
+    
+    if(!$log&&!$list){
         my $t = prompt "Enter Log ([enter] key quits):";
         $log = $t;
         while($t ne ""){
@@ -110,25 +191,73 @@ if (@c && $c[0] eq $alias) {
 
         say "\nLog:$log";
         if(!$log){
-            say "Aborting, no log ahas been entered."; exit;
+            say "Aborting, no log has been entered."; exit;
         }
     }
     else{
         #encode
-        $log =~ s/'/''/g;
+        $log =~ s/'/''/g if $log;
+    }
+    if($list){
+        my $fh; my $cnt = 0;        
+        if (!$SELECT){
+             $SELECT = "SELECT DATE, LOG FROM VW_LOG WHERE $list LIMIT $LIMIT_REC"; 
+        }
+        $st = traceDBExe($SELECT);
+        if ($dump){print $out if $out; open($fh, '>', $dump)}else{$fh=*STDOUT}
+        my $dot = "-" x 80;
+        print $fh $dot."\n";
+            print $fh $TITLE."\nDSN: $DSN\n"."DATE: ".gmtime()."\nSQL: $SELECT\n";
+        print $fh $dot."\n";
+        while(@c=$st->fetchrow_array()){
+            if($LIMIT && $cnt>$LIMIT){last}
+            print $fh "".$c[0]."|".$c[1]."\n"; $cnt++;
+        }
+        print $fh $dot."\n";
+        close $fh if $dump;
+        print "Done, written to dump file $cnt entries!\n" if $dump;
+    }
+    else{
+        if($INSERT){
+            # try{
+                if($log ne""){
+                    my $stamp = Settings::getCurrentSQLTimeStamp();                
+                    my $pst = $db->prepare($INSERT);                
+                    $pst->execute("$stamp", $log);
+                    say "Log issued to -> $DSN: for LifeLog.$VW_NAME";
+                }
+               
+            # }catch{                
+
+            #     # if (my $ex = $@) {
+            #     #     print STDERR "DBI Exception:\n";
+            #     #     print STDERR "  Exception Type: ", ref $ex, "\n";
+            #     #     print STDERR "  Error:          ", $ex->error, "\n";
+            #     #     print STDERR "  Err:            ", $ex->err, "\n";
+            #     #     print STDERR "  Errstr:         ", $ex->errstr, "\n";
+            #     #     print STDERR "  State:          ", $ex->state, "\n";
+            #     #     print STDERR "  Return Value:   ", ($ex->retval || 'undef'), "\n";
+            #     # } 
+
+
+            #     LifeLogException->throw(error=>"DSN: [$DSN]\nSQL:$INSERT\nError encountered -> $@", show_trace=>1);
+            # };
+        }
+        else{
+            Settings::toLog($db, $log, $cat_id);
+            say "Log issued to -> $DSN: for LifeLog.LOG";
+        }
+                
     }
-    Settings::toLog($db, $log, $cat_id);
-    say "Log issued to -> $DSN";
 }else{
     #We log failed possible intruder access.
     if(!$passw){
         say "Error: Exiting, no password has been entered for ($alias).";  exit 0;
     }
     Settings::toLog($db,"User $alias, failed to authenticate, from command line!");
-    say "Error: Get out of here! Entered password $passw doesn't match for ($alias).";  exit 0;
+    say "Error: Get out of here! Entered password doesn't match for ($alias).";  exit 0;
 }
 
-
 sub connectDB {
     my ($d,$u,$p) = @_;
     $u = $alias if(!$u);
@@ -142,22 +271,23 @@ sub connectDB {
     }else{
         $DSN = $db_source .'dbname='.$DBFILE;        
     }    
-    try{
+    try{$u=$p="lifelog";
         return DBI->connect($DSN, $u, $p, {AutoCommit => 1, RaiseError => 1, PrintError => 0, show_trace=>1});
     }catch{           
-       LifeLogException->throw(error=>"<p>Error->$@</p><br><p>$DSN</p>",  show_trace=>1);
+       LifeLogException->throw(error=>"Error->$@\n[$DSN]",  show_trace=>1);
     }
 }
 
 sub traceDBExe {
     my $sql = shift;
     try{
+        print "<<traceDBExe<$sql>>>\n" if($sql !~ /^SELECT/);
         my $st = $db->prepare($sql);
            $st -> execute() or LifeLogException->throw("Execute failed [$DBI::errstri]", show_trace=>1);
         return $st;
     }catch{
         #BUG 31 fix.
-        if(Settings::isProgressDB() &&  index($sql,Settings->VW_LOG)>0){
+        if($IS_PG_DB &&  index($sql,Settings->VW_LOG)>0){
             $db -> do(Settings::createViewLOGStmt());
             my $st = $db->prepare($sql);
                $st -> execute() or LifeLogException->throw("Execute failed [$DBI::errstri]", show_trace=>1);
@@ -167,9 +297,50 @@ sub traceDBExe {
     }
 }
 
-END {
-    $db->disconnect() if $db;
-}
 
+sub checkCreateTable {
+   my($TABLE,$col,$typ) =  split(':',$table);
+   print "$TITLE\nUsing spec -> $table\n";
+   if($TABLE && $col && $typ){
+      $TABLE = uc $TABLE;
+      $VW_NAME = "VW_$TABLE";
+      $COL_NAME = uc $col;
+      $COL_TYPE = uc $typ;
+      if($IS_PG_DB){
+          #TODO
+            my %tables = ();
+            my @tbls = $db->tables(undef, 'public');
+            foreach (@tbls){
+                my $t = uc substr($_,7);
+                $tables{$t} = 1;
+            }
+            if(!$tables{$TABLE}){
+                traceDBExe("CREATE TABLE $TABLE (DATE TIMESTAMP NOT NULL, $COL_NAME $COL_TYPE NOT NULL);");
+                traceDBExe(qq(CREATE VIEW $VW_NAME AS
+          SELECT rowid as ID,*, (select count(rowid) from LOG as recount where a.rowid >= recount.rowid) as PID
+          FROM $TABLE as a ORDER BY Date(DATE) DESC;
+));
+            }
+
+      }else{
+                my $pst = traceDBExe("SELECT count(name) FROM sqlite_master WHERE type='table' and name like '$TABLE';");
+                my @res = $pst->fetchrow_array();
+                if($res[0]==0){
+                    traceDBExe("CREATE TABLE $TABLE (DATE DATETIME NOT NULL, $COL_NAME $COL_TYPE NOT NULL);");
+                }
+                $pst = traceDBExe("SELECT count(name) FROM sqlite_master WHERE type='view' and name like '$VW_NAME';");
+                @res = $pst->fetchrow_array();
+                if($res[0]==0){
+                    traceDBExe(
+qq(CREATE VIEW $VW_NAME AS
+          SELECT rowid as ID,*, (select count(rowid) from LOG as recount where a.rowid >= recount.rowid) as PID
+          FROM $TABLE as a ORDER BY Date(DATE) DESC, Time(DATE) DESC;
+));
+                }
+       }      
+      $SELECT = "SELECT DATE, $COL_NAME FROM $VW_NAME LIMIT $LIMIT_REC;";
+      $INSERT = "INSERT INTO $TABLE(DATE, $COL_NAME) VALUES(?,?)";
+  }
+}
 
-1;
\ No newline at end of file
+END {$db->disconnect() if ($db)}
\ No newline at end of file