Files
note/mysql-db/note.mysql

902 lines
20 KiB
Plaintext
Raw Normal View History

#!/usr/bin/perl
# this is the small console program "note" (MYSQL version)
# It works similar to some well known GUI note programs,
# but instead of using X11 it uses the UN*X console.
# You can edit existing notes, delete them, create new
# ones and, of course display them.
# The notes will be stored in a mysql database. Refer to
# the README of the desitribution for details about
# installation.
# It requires a configfile named .noterc in the users home.
# If it does not exist, note will create one for you, which
# you will have to edit.
#
# If you find it usefull or find a bug, please let me know:
# Thomas Linden <tom@daemon.de>
#
# note is GPL software.
use Mysql;
##################################
# define some default values.
# don't change them, instead use the config file!
$maxlen = 20;
$timelen = 22;
$date = `date +%e\".\"%m\".\"%Y\" \"%T`;
chomp $date;
$USER = getlogin || getpwuid($<);
chomp $USER;
$HOME = `echo \$HOME`;
chomp $HOME;
$CONF = $HOME . "/.noterc";
$DEFAULTDBNAME = $USER . "_note";
# database settings, override them within the config!
$dbname = "$DEFAULTDBNAME";
$dbhost = "localhost";
$dbuser = $USER;
$dbpasswd = "";
$table = "note";
$fnum = "number";
$fnote = "note";
$fdate = "date";
$COLOR = "NO";
# if $COLOR equals NO, then the following color-definitions
# will be replaced by "".
$BORDER_COLOR = "BLACK";
$NUM_COLOR = "blue";
$NOTE_COLOR = "magenta";
$TIME_COLOR = "black";
###################################
sub usage;
sub find_editor;
sub output;
sub C;
sub uen;
sub ude;
sub num_bereich;
sub new;
sub edit;
sub del;
sub display;
sub list;
sub help;
$version = "0.4 (mysql database)";
# process command line args
if($ARGV[0] eq "")
{
$mode = "new";
}
else
{
while($ARGV[0] ne "" )
{
if($ARGV[0] =~ /^\d/)
{
# first arg is a digit!
$number = $ARGV[0];
if($mode eq "")
{
# change mode only, if started with an option
# ($mode will be already set)
$mode = "display";
}
$ARGV[0] = "";
}
elsif($ARGV[0] eq "-i" || $ARGV[0] eq "--interactive")
{
$mode = "interactive";
$ARGV[0] = "";
}
elsif($ARGV[0] eq "-l" || $ARGV[0] eq "--list")
{
$mode = "list";
$ARGV[0] = "";
}
elsif($ARGV[0] eq "-L" || $ARGV[0] eq "--longlist")
{
$mode = "list";
$ListType = "LONG";
$ARGV[0] = "";
}
elsif($ARGV[0] eq "-s" || $ARGV[0] eq "--search")
{
# searching
$mode = "search";
$searchstring = $ARGV[1];
$ARGV[0] = "";
}
elsif($ARGV[0] eq "-e" || $ARGV[0] eq "--edit")
{
if($mode eq "edit")
{
# note -e -e !
&usage;
exit(1);
}
else
{
$mode = "edit";
shift;
}
}
elsif($ARGV[0] eq "-d" || $ARGV[0] eq "--delete")
{
if($mode eq "delete")
{
&usage;
exit(1);
}
else
{
$mode = "delete";
shift;
}
}
elsif($ARGV[0] eq "-D" || $ARGV[0] eq "--Dump" || $ARGV[0] eq "--dump")
{
$mode = "dump";
$dump_file = $ARGV[1];
$ARGV[0] = "";
}
elsif($ARGV[0] eq "-v" || $ARGV[0] eq "--version")
{
print "This is note $version from Thomas Linden <tom\@daemon.de>.\n";
exit(0);
}
elsif($ARGV[0] eq "-h" || $ARGV[0] eq "--help")
{
&usage;
exit(0);
}
else
{
&usage;
exit(0);
}
}
}
# open the configfile.
if(-e $CONF)
{
eval `cat $CONF`;
}
# Always interactive?
if($ALWAYS_INT eq "YES")
{
$mode = "interactive";
}
# calculate some constants...
$BORDERC = "<$BORDER_COLOR>";
$_BORDERC = "</$BORDER_COLOR>";
$NUMC = "<$NUM_COLOR>";
$_NUMC = "</$NUM_COLOR>";
$NOTEC = "<$NOTE_COLOR>";
$_NOTEC = "</$NOTE_COLOR>";
$TIMEC = "<$TIME_COLOR>";
$_TIMEC = "</$TIME_COLOR>";
$time = `date +%d\".\"%m\".\"%Y\" \"%T`;
chomp $time;
$typedef = "i a$MAX_NOTE a$MAX_TIME";
$sizeof = length pack($typedef, () );
if($ListType ne "LONG")
{
$maxlen += $timelen; # no time will be displayed!
}
# ok, if still here, we got it all, now let's connect to the database
$db = Mysql->connect($dbhost,$dbname,$dbuser,$dbpasswd)
or die "ERROR: $Mysql::dberrstr\n";
# main loop: ###############
if($mode eq "display")
{
&display;
}
elsif($mode eq "search")
{
&search;
}
elsif($mode eq "list")
{
&list;
}
elsif($mode eq "new")
{
&new;
}
elsif($mode eq "delete")
{
del;
}
elsif($mode eq "edit")
{
&edit;
}
elsif($mode eq "dump")
{
&dump;
}
elsif($mode eq "interactive")
{
&interactive;
}
else
{
#undefined :-(
}
exit(0);
################## EOP ################
############################### DISPLAY ##################################
sub display
{
# display a certain note
print "\n";
&num_bereich; # get @NumBlock from $numer
foreach $N (@NumBlock)
{
$res = $db->query("SELECT $fnote,$fdate FROM $table WHERE $fnum = $N")
or die "ERROR: $Mysql::dberrstr\n";
{
output($N, $row[0], $row[1], "SINGLE");
print "\n";
$match = 1;
}
}
if(!$match)
{
print "no note with that number found!\n";
}
}
############################### SEARCH ##################################
sub search
{
$maxlen += $timelen;
if($searchstring eq "")
{
&usage;
exit(1);
}
print "searching the database $dbname for \"$searchstring\"...\n\n";
$sqlstatement = "SELECT DISTINCT $fnum,$fnote,$fdate FROM $table WHERE "
. "$fnote LIKE '%$searchstring%'"
. " ORDER BY $fnum";
$res = $db->query($sqlstatement) or die "ERROR: $Mysql::dberrstr\n";
while(@row = $res->fetchrow)
{
output($row[0], $row[1], $row[2]);
$match = 1;
}
if(!$match)
{
print "no matching note found!\n";
}
print "\n";
}
############################### LIST ##################################
sub list
{
# list all available notes (number and firstline)
$res = $db->query("SELECT $fnum,$fnote,$fdate FROM $table ORDER BY $fnum")
or die "ERROR: $Mysql::dberrstr\n";
while(@row = $res->fetchrow)
{
output($row[0], $row[1], $row[2]);
}
print "\n";
}
############################### NEW ##################################
sub new
{
if($ALWAYS_EDIT eq "YES")
{
$TEMP = "/tmp/note.$$";
# let the user edit it...
$editor = &find_editor;
if($editor)
{
system $editor, $TEMP;
}
else
{
print "Could not find an editor to use!\n";
exit(0);
}
# read it in ($note)
$note = "";
open E, "<$TEMP" or die "Could not open $TEMP\n";
$c = 0;
while(<E>)
{
$_ =~ s/'/\\'/g;
$note = $note . $_;
}
chomp $note;
close E;
# privacy!
system "/bin/rm -f $TEMP";
}
else
{
$note = "";
local $line = "";
#local $num = 0;
# create a new note
print "enter the text of the note, end with .\n";
do
{
$line = <STDIN>;
$_ =~ s/'/\\'/g;
$note = $note . $line;
} until $line eq ".\n";
# remove the . !
chop $note;
chop $note;
}
# since we have not number, look for the next available:
$res = $db->query("SELECT max($fnum) FROM $table") or die "ERROR: $Mysql::dberrstr\n";
while(@row = $res->fetchrow)
{
$number = $row[0];
}
$number++;
$sqlstatement = "INSERT INTO $table VALUES (0,$number,'$note','$date')";
$db->query($sqlstatement)
or die "ERROR: $Mysql::dberrstr\n";
# everything ok until here!
print "note stored. it has been assigned the number $number.\n\n";
}
############################### DELETE ##################################
sub del
{
# delete a note
&num_bereich; # get @NumBlock from $number
foreach $N (@NumBlock)
{
$sqlstatement = "DELETE FROM $table WHERE $fnum = $N";
$res = $db->query($sqlstatement) or $ERR = $Mysql::dberrstr;
# do not exit if an error occurs - good for int mode!
if($ERR)
{
print "no note with number $N found!\n";
}
else
{
print "note number $N has been deleted.\n";
}
}
# recount the notenumbers:
$i = 0;
$pos = 0;
$sqlstatement = "SELECT id FROM $table ORDER BY id";
$res = $db->query($sqlstatement) or die "ERROR: $Mysql::dberrstr\n";
while(@row = $res->fetchrow)
{
$count[$i] = $row[0];
$i++;
}
#have all real id's, now recount it:
for($pos=0;$pos<$i;$pos++)
{
$setnum = $pos +1;
$sqlstatement = "UPDATE $table SET $fnum = '$setnum' WHERE id = $count[$pos]";
$db->query($sqlstatement) or die "ERROR: $Mysql::dberrstr\n";
}
}
############################### EDIT ##################################
sub edit
{
# edit a note
$sqlstatement = "SELECT $fnote FROM $table WHERE $fnum = $number";
$res = $db->query($sqlstatement) or die "ERROR: $Mysql::dberrstr\n";
while(@row = $res->fetchrow)
{
$note = $row[0];
$match = "yes";
}
if($match eq "")
{
print "no note with that number found!\n\n";
exit(0);
}
$TEMP = "/tmp/note.$USER.$$";
open NOTE,">$TEMP" or die "Could not open $TEMP\n";
select NOTE;
print $note;
close NOTE;
select STDOUT;
$editor = &find_editor;
if($editor)
{
system $editor, $TEMP;
}
else
{
print "Could not find an editor to use!\n";
exit(0);
}
$note = "";
open NOTE,"<$TEMP" or die "Could not open $TEMP\n";
$c = 0;
while(<NOTE>)
{
$_ =~ s/'/\\'/g;
$note = $note . $_;
}
chomp $note;
close NOTE;
system "/bin/rm -f $TEMP";
# we got it, now save to db
$sqlstatement = "UPDATE $table SET "
. "$fnote = '$note' "
. "WHERE $fnum = $number";
$db->query($sqlstatement) or die "ERROR: $Mysql::dberrstr\n";
print "note number $number has been changed.\n";
}
sub dump
{
# $dump_file
open (DUMP, ">$dump_file") or die "could not open $dump_file\n";
select DUMP;
$res = $db->query("SELECT $fnum,$fnote,$fdate FROM $table ORDER BY $fnum")
or die "ERROR: $Mysql::dberrstr\n";
$res = $db->query($sqlstatement) or die "ERROR: $Mysql::dberrstr\n";
print "complete dump of note database from $time.\n\n";
while(@row = $res->fetchrow)
{
print STDOUT "dumping note number $num to $dump_file\n";
print "#$num\ttime: $t\nnote:\n$n\n---------\n\n";
}
print "\n";
close(DUMP);
select STDOUT;
}
sub interactive
{
$maxlen_save = $maxlen;
# create menu:
local $B = "<blackI>";
local $BB = "</blackI>";
local $menu = "[ " . $B . "L" . $BB . " List "
. $B . "N" . $BB . " New "
. $B . "D" . $BB . " Delete "
. $B . "S" . $BB . " Search "
. $B . "E" . $BB . " Edit "
. $B . "?" . $BB . " Help "
. $B . "Q" . $BB . " Quit ] command> ";
# per default let's list all the stuff:
for(;;)
{
#&list;
$maxlen = $maxlen_save;
print "\n\n\n";
print C $menu;
# endless until user press "Q" or "q"!
$char = <STDIN>;
chomp $char;
if($char =~ /^\d+/)
{
# display notes
$maxlen += $timelen;
$number = $char;
&display;
}
elsif($char =~ /^n/i)
{
# create a new one
$time = `date +%d\".\"%m\".\"%Y\" \"%T`;
chomp $time;
&new;
}
elsif($char =~ /^l/ || $char =~ /^$/)
{
# list
print "\n";
$ListType = "";
$maxlen += $timelen;
&list;
undef $SetTitle;
}
elsif($char =~ /^L/)
{
$ListType = "LONG";
&list;
undef $SetTitle;
}
elsif($char =~ /^h/i || $char =~ /^\?/)
{
# zu dumm der Mensch ;-)
&help;
}
elsif($char =~ /^d\s+(\d+\-*\,*\d*)/i)
{
# delete one!
$number = $1;
&del;
}
elsif($char =~ /^d$/i)
{
# we have to ask her:
print "enter number(s) of note(s) you want to delete: ";
$char = <STDIN>;
chomp $char;
$number = $char;
&del;
}
elsif($char =~ /^e\s+(\d+\-*\,*\d*)/i)
{
# edit one!
$time = `date +%d\".\"%m\".\"%Y\" \"%T`;
chomp $time;
$number = $1;
&edit;
}
elsif($char =~ /^e$/i)
{
# we have to ask her:
print "enter number of the note you want to edit: ";
$char = <STDIN>;
chomp $char;
$number = $char;
&edit;
}
elsif($char =~ /^s\s+/i)
{
# she want's to search
#$maxlen += $timelen;
$searchstring = $';
chomp $searchstring;
&search;
}
elsif($char =~ /^s$/i)
{
# we have to ask her:
#$maxlen += $timelen;
print "enter the string you want to search for: ";
$char = <STDIN>;
chomp $char;
$char =~ s/^\n//;
$searchstring = $char;
&search;
}
elsif($char =~ /^q/i)
{
# schade!!!
print "\n\ngood bye\n";
exit(0);
}
else
{
# unknown
print "\nunknown command!\n";
}
}
}
sub usage
{
print qq~
usage: note [-i | --interactive] | [ options ] [ number [,number...]]
Options:
-h --help displays this help screen
-v --version displays the version number
-l --list lists all existing notes
-L --longlist the same as -l but prints also the timestamp
-s --search <string> searches for <string> trough the notes database
-e --edit <number> edit note with <number>
-d --delete <number> delete note with <number>
-D --Dump <file> dumps the notes to the textfile <file>
-i --interactive interactive mode
o if you specify only a number (i.e. "note 4"), then the note with that
number will be displayed.
o you can specify more then one number for delete and display, for example:
"note -d 3,4" deletes #3 and #4. "note 5-7" displays #5, #6 and #7.
o if you run note without any parameter and if \$ALWAYS_INT in the config is
not set, then note will create a new note and prompt you for new text.
o If it finds \~/.noterc, it will process it. Refer to the manpage for more
informations about the configuration.
o In interactive mode you can get help at any time by typing "?" or "h" at
the prompt.
This is the program note $version by Thomas Linden (c) 1999-2000. GPL.
~;
exit 1;
}
sub find_editor {
return $ENV{"VISUAL"} || $ENV{"EDITOR"} || "vim" || "vi" || "pico";
}
sub output
{
# 0 = Num, 1 = Note, 2 = Time
if($ListType ne "LONG")
{
$SSS = "-" x ($maxlen + 31 - $timelen);
}
else
{
$SSS = "-" x ($maxlen + 31);
}
local $LINE = "$BORDERC $SSS $_BORDERC\n";
local $num = $_[0];
local $note = $_[1];
local $time = $_[2];
local $TYPE = $_[3];
local $L = $BORDERC . "[" . $_BORDERC;
local $LONGSPC = " " x (22 + 3);
local $R = $BORDERC . "]" . $_BORDERC;
if($TYPE ne "SINGLE")
{
if(!$SetTitle)
{
local $SP = "";
# print only if it is the first line!
if($ListType ne "LONG")
{
$SP = " " x ($maxlen-2 - $timelen);
}
else
{
$SP = " " x ($maxlen-2);
}
print C $LINE;
print C "$L $NUMC#$_NUMC ";
if($ListType eq "LONG")
{
print C " $TIMEC" . "creation date$_TIMEC ";
}
else
{
print $LONGSPC;
}
print C $NOTEC . "note$_NOTEC$SP$R\n";
print C $LINE;
$SetTitle = 1;
}
local $title = "";
$CUTSPACE = " " x $maxlen;
$note =~ s/\n/$CUTSPACE/g;
local $len = length($note);
if($len < $maxlen-3)
{
local $diff = $maxlen - $len;
local $Space = " " x $diff;
$title = $BORDERC . $NOTEC . "\"" . $note . "\"" . $_NOTEC . $Space . "$_BORDERC";
}
else
{
$title = substr($note,0,$maxlen - 3);
$title = $BORDERC . $NOTEC . "\"" . $title . "...\"$_NOTEC$_BORDERC";
}
# $title should now look as: "A sample note "
print C "$L $NUMC$num$_NUMC $R";
if($ListType eq "LONG")
{
print C "$L$TIMEC" . $time . " $_TIMEC$R";
}
print C "$L $NOTEC" . $title . "$_NOTEC $R\n";
print C $LINE;
}
else
{
chomp $note;
local $Space = " " x ($maxlen - 16);
local $SP = " " x ($maxlen + 13);
#print C $LINE;
#print C "$L $NUMC#$_NUMC " . $TIMEC . "creation date$_TIMEC$SP$R\n";
print C $LINE;
print C "$L $NUMC$num$_NUMC $R$L$TIMEC$time$_TIMEC $Space$R\n";
print C $LINE;
print C $NOTEC . $note . $_NOTEC . "\n";
print C $LINE;
}
}
sub C
{
# \033[1m%30s\033[0m
local %Color = ( 'black' => '0;30',
'red' => '0;31',
'green' => '0;32',
'yellow' => '0;33',
'blue' => '0;34',
'magenta' => '0;35',
'cyan' => '0;36',
'white' => '0;37',
'B' => '1;30',
'BLACK' => '1;30',
'RED' => '1;31',
'GREEN' => '1;32',
'YELLOW' => '1;33',
'BLUE' => '1;34',
'MAGENTA' => '1;35',
'CYAN' => '1;36',
'WHITE' => '1;37',
'black_' => '4;30',
'red_' => '4;31',
'green_' => '4;32',
'yellow_' => '4;33',
'blue_' => '4;34',
'magenta_' => '4;35',
'cyan_' => '4;36',
'white_' => '4;37',
'blackI' => '7;30',
'redI' => '7;31',
'greenI' => '7;32',
'yellowI' => '7;33',
'blueI' => '7;34',
'magentaI' => '7;35',
'cyanI' => '7;36',
'whiteI' => '7;37'
);
$default = "\033[0m";
$S = $_[0];
foreach $Col (%Color)
{
if ($S =~ /<$Col>/g)
{
if($COLOR ne "NO")
{
$NC = "\033[" . $Color{$Col} . "m";
$S =~ s/<$Col>/$NC/g;
$S =~ s/<\/$Col>/$default/g;
}
else
{
$S =~ s/<$Col>//g;
$S =~ s/<\/$Col>//g;
}
}
}
return $S;
}
sub uen
{
local $T = pack("u", $_[0]);
chomp $T;
return $T;
}
sub ude
{
local $T = unpack("u", $_[0]);
return $T;
}
sub num_bereich
{
# $number is the one we want to delete!
# But does it contain kommas?
local $m = 0;
if($number =~ /\,/)
{
# accept -d 3,4,7
@NumBlock = split(/\,/,$number);
}
elsif($number =~ /^\d+\-\d+$/)
{
# accept -d 3-9
local @LR = split(/\-/,$number);
local @Sorted_LR = sort @LR;
for($i=$Sorted_LR[0]; $i<=$Sorted_LR[1]; $i++)
{
# from 3-6 create @NumBlock (3,4,5,6)
$NumBlock[$m] = $i;
$m++;
}
}
else
{
@NumBlock = ($number);
}
}
sub help
{
print qq~
--------------------------------------------------------------
HELP for interactive note $version
The following commands are available:
L/l List notes. L=long, with timestamp and l=short without
timestamp. You can also just hit <enter> for short list.
N Create a new note.
D Delete a note. You can either hit "d 1" or "d 1-4"
or just hit "d". If you don't specify a number, you
will be asked for.
S Search trough the notes database. Usage is similar to
Delete, use a string instead of a number to search for.
E Edit a note. Usage is similar to Delete but you can
only edit one note a time.
?/H This help screen.
Q Exit the program.
All commands except the List command are case insensitive.
---------------------------------------------------------------
~;
}