From: wbudic Date: Thu, 11 Feb 2021 01:15:21 +0000 (+1100) Subject: Developed further. X-Git-Url: https://lifelog.hopto.org/gitweb/?a=commitdiff_plain;h=d4cb68813dada478dd26b2a35f810ccf68ce5451;p=LifeLog.git Developed further. --- diff --git a/log.pl b/log.pl index fd27f2a..8024eab 100755 --- 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 < 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 < 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 = ; -# 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=>"

Error->$@


$DSN

", show_trace=>1); + LifeLogException->throw(error=>"Error->$@\n[$DSN]", show_trace=>1); } } sub traceDBExe { my $sql = shift; try{ + print "<>>\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